import tensorflow as tf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import csv
from sklearn.preprocessing import MinMaxScaler
from sklearn import metrics

NUM_MODEL_RUNS = 1 #abs(int(input("Enter the number of times to train model and store metrics: ")))
NUM_EPOCHS = 100 #abs(int(input("Enter the number of epochs to run: ")))
BATCH_SIZE = 32 #abs(int(input("Enter the desired batch size: ")))

LAYER_1_NEURONS = 512 #abs(int(input("Enter the number of neurons for layer 1: ")))
LAYER_2_NEURONS = 128 #abs(int(input("Enter the number of neurons for layer 2: ")))
LAYER_3_NEURONS = 64 #abs(int(input("Enter the number of neurons for layer 3: ")))

LOOK_BACK = 3 #abs(int(input("Enter the number of previous months to use for predictions: ")))
LOOK_AHEAD = 1 #abs(int(input("Enter the number of months in the future to predict a recession at: ")))

TRAIN_PERCENTAGE = 0.7 #abs(float(input("Enter the percentage of data to use in the training set: ")))
DROPOUT_RATE = 0.1 #abs(float(input("Enter a dropout rate for regularization of the recurrent layers. Value in range [0, 1]: ")))
CLASSIFIER_THRESHOLD = [0.04] #abs(float(input("Enter threshold for classifer: ")))
TO_PRINT = False #bool(input("Would you like to print the Train/Val curve and ROC every iteration? (0=False, 1=True): "))
WRITE_METRICS = False #bool(input("Would you like to write the output metrics to Excel .csv files? (0=False, 1=True): "))
DISPLAY_MODEL = False #bool(input("Would you like to display model summary? (0=False, 1=True): "))

NUM_FEATURES = 10
SCALER = MinMaxScaler()
TO_SCALE = True
OPTIMIZER = tf.keras.optimizers.Adam()
LOSS = tf.keras.losses.BinaryCrossentropy()
DENSE_ACTIVATION = "sigmoid"
#EARLY_STOP = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=5, mode='min')
METRICS = [
      #tf.keras.metrics.TruePositives(name='tp'),
      #tf.keras.metrics.FalsePositives(name='fp'),
      #tf.keras.metrics.TrueNegatives(name='tn'),
      #tf.keras.metrics.FalseNegatives(name='fn'),
      tf.keras.metrics.BinaryAccuracy(name='accuracy'),
      #tf.keras.metrics.Precision(name='precision'),
      #tf.keras.metrics.Recall(name='recall'),
      #tf.keras.metrics.AUC(name='auc'),
]

def plot_training(model, name):

    plt.plot(model.history['loss'], label='train loss')
    plt.plot(model.history['accuracy'], label='train accuracy')

    plt.xlabel('Epoch')
    plt.ylabel('Value of Metric')
    plt.title('{} RecessionNET Training/Validation Loss and Accuracy vs Epoch'.format(name))
    plt.legend()
    plt.show()

    return(0)

def plot_predictions(actual, predictions,  name):

    plt.plot(actual, label='Actual')
    plt.plot(predictions, label='Predictions')

    plt.xlabel('Time')
    plt.ylabel('Probability of Recession')
    plt.title('{} RecessionNET Actual/Predicted vs Time'.format(name))
    plt.legend()
    plt.show()

    return(0)

def plot_out_of_sample_ROC(actual, predictions, name):

    fpr, tpr, thresholds = metrics.roc_curve(actual, predictions)
    auc = auc(fpr, tpr)

    plt.figure(1)
    plt.plot([0, 1], [0, 1], 'k--')
    plt.plot(fpr, tpr, label='Area: {:.3f})'.format(auc))
    plt.xlabel('False positive rate')
    plt.ylabel('True positive rate')
    plt.title('{} RecessionNET ROC curve'.format(name))
    plt.legend(loc='best')
    plt.show()

    return(0)

def final_metrics(actual, predictions, threshold):

    binary_predictions = np.where(predictions > threshold, 1, 0)

    accuracy = metrics.accuracy_score(actual, binary_predictions)
    auc = metrics.roc_auc_score(actual, binary_predictions)
    f1 = metrics.f1_score(actual, binary_predictions)
    recall = metrics.recall_score(actual, binary_predictions)

    if TO_PRINT:
        print("Out-of-sample Accuracy: {}".format(accuracy))
        print("Out-of-sample Area Under Receiver Operating Curve: {}".format(auc))
        print("Out-of-sample F1-Score: {}".format(f1))
        print("Out-of-sample Recall: {}\n".format(recall))

    return [accuracy, auc, f1, recall]

def make_dataset(features, responses, look_back, look_ahead):
    print("\nGenerating dataset...")
    print("Using the past {} months of data to predict a recession {} month(s) away.".format(look_back, look_ahead))

    features = np.array(features)
    responses = np.array(responses)

    # Normalize Sets Here
    if TO_SCALE:
        features = SCALER.fit_transform(features)
        responses = SCALER.fit_transform(responses)

    feature_set, response_set = [], []
    t = 0
    max_index = len(features)-1
    for t in range(max_index-look_back-look_ahead+2):
        feature_sample = features[t:t+look_back, ]
        response_sample = responses[t+look_back+look_ahead-1, ]
        feature_set.append(feature_sample)
        response_set.append(response_sample)

    print("Dataset has been made.\n")

    return np.array(feature_set), np.array(response_set)

def split_dataset(features, responses, split_ratio):
    print("\nSplitting data...\n")
    n = len(features)
    print("Length of data set {}".format(n))
    print("Length of train set {}".format(int(n*split_ratio)))
    print("Length of test set {}".format(int(n-(n*split_ratio)+1)))
    X_train = features[0:int(n * split_ratio)]
    Y_train = responses[0:int(n * split_ratio)]
    X_test = features[int(n * split_ratio)+1:]
    Y_test = responses[int(n * split_ratio)+1:]
    print("Dataset has been split into test-train sets.\n")
    return X_train, Y_train, X_test, Y_test

print("\nImporting data...\n")
macrovars = pd.read_csv("macrovars.csv")
recession = pd.read_csv("recession_state.csv")
macrovars = macrovars.rename(columns={"SP500 (Percent change from a year ago)": "SP5001YDelta",
                                      "10Y Rate - 3M TBill ": "10YR3MDelta",
                                      "10Y Rate (Percent change from a year ago": "10YR1YDelta",
                                      "3M TBill (Percent Change from a year ago)": "3M1YDelta",
                                      "3M TBill - FF ": "3MFFDelta",
                                      "6M TBill - FF": "6MFFDelta",
                                      "1Y Rate - FF": "1YRFFDelta",
                                      "5Y Rate - FF": "5YRFFDelta",
                                      "10Y Rate - FF": "10YRFFDelta",
                                      "Composite Leading Indicator": "CLI"})

macrovars = macrovars.drop(["Date"], axis = 1)
recession = recession.rename(columns={"Recession State": "Recession"})

print("Features:")
print(macrovars.head())

print("\nResponse:")
print(recession.head())

macrovars = macrovars.to_numpy()
recession = recession.to_numpy()

X, Y = make_dataset(features = macrovars, responses = recession, look_back = LOOK_BACK, look_ahead = LOOK_AHEAD)
X_train, Y_train, X_test, Y_test = split_dataset(features = X, responses = Y, split_ratio = TRAIN_PERCENTAGE)

print("X_train shape: {}".format(X_train.shape))
print("Y_train shape: {}".format(Y_train.shape))
print("\n")

###################################################################################################################################################

for j in range(len(CLASSIFIER_THRESHOLD)):

    LSTM_HISTORY = []
    GRU_HISTORY = []

    for i in range(NUM_MODEL_RUNS):

        inputs = tf.keras.Input(shape=(LOOK_BACK, NUM_FEATURES))
        inputs.shape
        lstm1 = tf.keras.layers.LSTM(units = LAYER_1_NEURONS, input_shape = (LOOK_BACK, NUM_FEATURES), return_sequences = True, dropout=DROPOUT_RATE)
        lstm2 = tf.keras.layers.LSTM(units = LAYER_2_NEURONS, input_shape = (LOOK_BACK, NUM_FEATURES), return_sequences = True, dropout=DROPOUT_RATE)
        lstm3 = tf.keras.layers.LSTM(units = LAYER_3_NEURONS, input_shape = (LOOK_BACK, NUM_FEATURES), return_sequences = False, dropout=DROPOUT_RATE)

        x = lstm1(inputs)
        x = lstm2(x)
        x = lstm3(x)
        outputs = tf.keras.layers.Dense(units = 1, activation=DENSE_ACTIVATION)(x)
        lstm_model = tf.keras.Model(inputs = inputs, outputs = outputs)

        if DISPLAY_MODEL:
            lstm_model.summary()
            tf.keras.utils.plot_model(lstm_model, show_shapes=True, to_file = "lstm_model.png")
        lstm_model.compile(loss=LOSS,
                        optimizer=OPTIMIZER,
                        metrics=METRICS)

        lstm_model_history = lstm_model.fit(x = X_train, y = Y_train, epochs = NUM_EPOCHS, verbose = 0) #validation_data = (X_test, Y_test), callbacks = [EARLY_STOP])
        lstm_model_preds = lstm_model.predict(x = X_test)

        # plot training history
        if TO_PRINT:
            plot_training(lstm_model_history, "LSTM")

        Y_predicted = lstm_model.predict(x = X_test).ravel()
        plot_predictions(Y_test, Y_predicted, "LSTM")
        oos_metrics = final_metrics(Y_test, Y_predicted, CLASSIFIER_THRESHOLD[j])
        LSTM_HISTORY.append(oos_metrics)

        if TO_PRINT:
            plot_out_of_sample_ROC(Y_test, Y_predicted, "LSTM")

        #########################################################################################################################################################################

        inputs = tf.keras.Input(shape=(LOOK_BACK, NUM_FEATURES))
        inputs.shape
        gru1 = tf.keras.layers.GRU(units = LAYER_1_NEURONS, input_shape = (LOOK_BACK, NUM_FEATURES), return_sequences = True, dropout=DROPOUT_RATE)
        gru2 = tf.keras.layers.GRU(units = LAYER_2_NEURONS, input_shape = (LOOK_BACK, NUM_FEATURES), return_sequences = True, dropout=DROPOUT_RATE)
        gru3 = tf.keras.layers.GRU(units = LAYER_3_NEURONS, input_shape = (LOOK_BACK, NUM_FEATURES), return_sequences = False, dropout=DROPOUT_RATE)

        x = gru1(inputs)
        x = gru2(x)
        x = gru3(x)
        outputs = tf.keras.layers.Dense(units = 1, activation=DENSE_ACTIVATION)(x)
        gru_model = tf.keras.Model(inputs = inputs, outputs = outputs)

        if DISPLAY_MODEL:
            gru_model.summary()
            tf.keras.utils.plot_model(gru_model, show_shapes=True, to_file = "gru_model.png")

        gru_model.compile(loss=LOSS,
                        optimizer=OPTIMIZER,
                        metrics=METRICS)

        gru_model_history = gru_model.fit(x = X_train, y = Y_train, epochs = NUM_EPOCHS, verbose = 0) #validation_data = (X_test, Y_test), callbacks = [EARLY_STOP])
        gru_model_preds = gru_model.predict(x = X_test)

        if TO_PRINT:
            plot_training(gru_model_history, "GRU")

        Y_predicted = gru_model.predict(x = X_test).ravel()
        plot_predictions(Y_test, Y_predicted, "GRU")
        oos_metrics = final_metrics(Y_test, Y_predicted, CLASSIFIER_THRESHOLD[j])
        GRU_HISTORY.append(oos_metrics)

        if TO_PRINT:
            plot_out_of_sample_ROC(Y_test, Y_predicted, "GRU")

        tf.keras.backend.clear_session()

    if WRITE_METRICS:

        LSTM_HISTORY_df = pd.DataFrame(LSTM_HISTORY, columns = ["Accuracy", "AUC", "F1-Score", "Recall"])
        GRU_HISTORY_df = pd.DataFrame(GRU_HISTORY, columns = ["Accuracy", "AUC", "F1-Score", "Recall"])

        LSTM_HISTORY_df.to_csv("LSTM_HISTORY_{}.csv".format(str(CLASSIFIER_THRESHOLD[j])))
        GRU_HISTORY_df.to_csv("GRU_HISTORY_{}.csv".format(str(CLASSIFIER_THRESHOLD[j])))

print("RecessionNET has completed running.")
print("All output metrics have been written into the current working directory.")


import warnings
from collections import Iterable, OrderedDict
from functools import partial

import torch
import torchvision
from torch import nn

from neuralpredictors import regularizers
from neuralpredictors.layers.activations import AdaptiveELU
from neuralpredictors.layers.affine import Bias2DLayer, Scale2DLayer
from neuralpredictors.layers.attention import AttentionConv
from neuralpredictors.layers.conv import DepthSeparableConv2d

from .base import Core

# logger = logging.getLogger(__name__)

class Stacked2dCore(Core, nn.Module):
    """
    An instantiation of the Core base class. Made up of layers layers of nn.sequential modules.
    Allows for the flexible implementations of many different architectures, such as convolutional layers,
    or self-attention layers.
    """

    def __init__(
        self,
        input_channels,
        hidden_channels,
        input_kern,
        hidden_kern,
        layers=3,
        gamma_hidden=0,
        gamma_input=0.0,
        skip=0,
        stride=1,
        final_nonlinearity=True,
        scale=None,
        elu_shift=(0, 0),
        bias=True,
        momentum=0.1,
        pad_input=True,
        hidden_padding=None,
        batch_norm=True,
        batch_norm_scale=True,
        independent_bn_bias=True,
        hidden_dilation=1,
        laplace_padding=0,
        input_regularizer="LaplaceL2",
        stack=None,
        use_avg_reg=True,
        depth_separable=False,
        attention_conv=False,
        linear=False,
    ):
        """
        Args:
            input_channels:     Integer, number of input channels as in
            hidden_channels:    Number of hidden channels (i.e feature maps) in each hidden layer
            input_kern:     kernel size of the first layer (i.e. the input layer)
            hidden_kern:    kernel size of each hidden layer's kernel
            layers:         number of layers
            gamma_hidden:   regularizer factor for group sparsity
            gamma_input:    regularizer factor for the input weights (default: LaplaceL2, see neuralpredictors.regularizers)
            skip:           Adds a skip connection
            stride:         stride of the 2d conv layer.
            final_nonlinearity: Boolean, if true, appends an ELU layer after the last BatchNorm (if BN=True)
            elu_shift: a tuple to shift the elu in the following way: Elu(x - elu_xshift) + elu_yshift
            bias:           Adds a bias layer.
            momentum:       momentum in the batchnorm layer.
            pad_input:      Boolean, if True, applies zero padding to all convolutions
            hidden_padding: int or list of int. Padding for hidden layers. Note that this will apply to all the layers
                            except the first (input) layer.
            batch_norm:     Boolean, if True appends a BN layer after each convolutional layer
            batch_norm_scale: If True, a scaling factor after BN will be learned.
            independent_bn_bias:    If False, will allow for scaling the batch norm, so that batchnorm
                                    and bias can both be true. Defaults to True.
            hidden_dilation:    If set to > 1, will apply dilated convs for all hidden layers
            laplace_padding: Padding size for the laplace convolution. If padding = None, it defaults to half of
                the kernel size (recommended). Setting Padding to 0 is not recommended and leads to artefacts,
                zero is the default however to recreate backwards compatibility.
            input_regularizer:  String that must match one of the regularizers in ..regularizers
            stack:        Int or iterable. Selects which layers of the core should be stacked for the readout.
                            default value will stack all layers on top of each other.
                            Implemented as layers_to_stack = layers[stack:]. thus:
                                stack = -1 will only select the last layer as the readout layer.
                                stack of -2 will read out from the last two layers.
                                And stack of 1 will read out from layer 1 (0 indexed) until the last layer.
            use_avg_reg:    bool. Whether to use the averaged value of regularizer(s) or the summed.
            depth_separable: Boolean, if True, uses depth-separable convolutions in all layers after the first one.
            attention_conv: Boolean, if True, uses self-attention instead of convolution for all layers after the first one.
            linear:         Boolean, if True, removes all nonlinearities

            To enable learning batch_norms bias and scale independently, the arguments bias, batch_norm and batch_norm_scale
            work together: By default, all are true. In this case there won't be a bias learned in the convolutional layer, but
            batch_norm will learn both its bias and scale. If batch_norm is false, but bias true, a bias will be learned in the
            convolutional layer. If batch_norm and bias are true, but batch_norm_scale is false, batch_norm won't have learnable
            parameters and a BiasLayer will be added after the batch_norm layer.
        """

        if depth_separable and attention_conv:
            raise ValueError("depth_separable and attention_conv can not both be true")

        super().__init__()
        regularizer_config = (
            dict(padding=laplace_padding, kernel=input_kern)
            if input_regularizer == "GaussianLaplaceL2"
            else dict(padding=laplace_padding)
        )
        self._input_weights_regularizer = regularizers.__dict__[input_regularizer](**regularizer_config)
        self.num_layers = layers
        self.gamma_input = gamma_input
        self.gamma_hidden = gamma_hidden
        self.input_channels = input_channels
        self.hidden_channels = hidden_channels
        self.skip = skip
        self.stride = stride
        self.use_avg_reg = use_avg_reg
        if use_avg_reg:
            warnings.warn("The averaged value of regularizer will be used.", UserWarning)
        self.hidden_padding = hidden_padding
        self.input_kern = input_kern
        self.hidden_kern = hidden_kern
        self.laplace_padding = laplace_padding
        self.hidden_dilation = hidden_dilation
        self.final_nonlinearity = final_nonlinearity
        self.elu_xshift, self.elu_yshift = elu_shift
        self.bias = bias
        self.momentum = momentum
        self.pad_input = pad_input
        self.batch_norm = batch_norm
        self.batch_norm_scale = batch_norm_scale
        self.independent_bn_bias = independent_bn_bias
        if stack is None:
            self.stack = range(self.num_layers+1)
        else:
            self.stack = [*range(self.num_layers+1)[stack:]] if isinstance(stack, int) else stack
        self.linear = linear

        if depth_separable:
            self.conv_layer_name = "ds_conv"
            self.ConvLayer = DepthSeparableConv2d
            self.ignore_group_sparsity = True
        elif attention_conv:
            # TODO: check if name attention_conv is backwards compatible
            self.conv_layer_name = "attention_conv"
            self.ConvLayer = self.AttentionConvWrapper
            self.ignore_group_sparsity = True
        else:
            self.conv_layer_name = "conv"
            self.ConvLayer = nn.Conv2d
            self.ignore_group_sparsity = False

        if (self.ignore_group_sparsity) and (gamma_hidden > 0):
            warnings.warn(
                "group sparsity can not be calculated for the requested conv type. Hidden channels will not be regularized and gamma_hidden is ignored."
            )
        self.set_batchnorm_type()
        self.features = nn.Sequential()
        self.add_scale_layer()
        self.add_first_layer()
        self.add_subsequent_layers()
        self.initialize()

    def set_batchnorm_type(self):
        self.batchnorm_layer_cls = nn.BatchNorm2d
        self.bias_layer_cls = Bias2DLayer
        self.scale_layer_cls = Scale2DLayer

    def add_bn_layer(self, layer):
        if self.batch_norm:
            if self.independent_bn_bias:
                layer["norm"] = self.batchnorm_layer_cls(self.hidden_channels, momentum=self.momentum)
            else:
                layer["norm"] = self.batchnorm_layer_cls(
                    self.hidden_channels, momentum=self.momentum, affine=self.bias and self.batch_norm_scale
                )
                if self.bias:
                    if not self.batch_norm_scale:
                        layer["bias"] = self.bias_layer_cls(self.hidden_channels)
                elif self.batch_norm_scale:
                    layer["scale"] = self.scale_layer_cls(self.hidden_channels)

    def add_activation(self, layer):
        if self.linear:
            return
        if len(self.features) < self.num_layers - 1 or self.final_nonlinearity:
            layer["nonlin"] = AdaptiveELU(self.elu_xshift, self.elu_yshift)

    def add_first_layer(self):
        layer = OrderedDict()
        layer["conv"] = nn.Conv2d(
            self.hidden_channels//4,
            self.hidden_channels,
            self.input_kern,
            padding=self.input_kern // 2 if self.pad_input else 0,
            bias=self.bias and not self.batch_norm,
        )
        layer["norm"] = nn.BatchNorm2d(self.hidden_channels, momentum=self.momentum)
        self.add_activation(layer)
        self.features.add_module("layer0", nn.Sequential(layer))

    def add_subsequent_layers(self):
        if not isinstance(self.hidden_kern, Iterable):
            self.hidden_kern = [self.hidden_kern] * (self.num_layers - 1)

        for l in range(1, self.num_layers):
            layer = OrderedDict()
            if self.hidden_padding is None:
                self.hidden_padding = ((self.hidden_kern[l - 1] - 1) * self.hidden_dilation + 1) // 2
            layer[self.conv_layer_name] = self.ConvLayer(
                in_channels=self.hidden_channels*2 if l > 1 else self.hidden_channels,
                out_channels=self.hidden_channels*2,
                kernel_size=self.hidden_kern[l - 1],
                stride=self.stride,
                padding=self.hidden_padding,
                dilation=self.hidden_dilation,
                bias=self.bias,
            )
            layer["norm"] = nn.BatchNorm2d(self.hidden_channels*2, momentum=self.momentum)
            self.add_activation(layer)
            self.features.add_module("layer{}".format(l), nn.Sequential(layer))

    def add_scale_layer(self):
        layer = OrderedDict()
        layer["scale"] = nn.Conv2d(
            in_channels=self.input_channels,
            out_channels=self.hidden_channels//4,
            kernel_size=4,
            stride=4,
            bias=self.bias)
        layer["norm"] = nn.BatchNorm2d(self.hidden_channels//4, momentum=self.momentum)
        self.add_activation(layer)
        self.features.add_module("layer-1", nn.Sequential(layer))

    class AttentionConvWrapper(AttentionConv):
        def __init__(self, dilation=None, **kwargs):
            """
            Helper class to make an attention conv layer accept input args of a pytorch.nn.Conv2d layer.
            Args:
                dilation: catches this argument from the input args, and ignores it
                **kwargs:
            """
            super().__init__(**kwargs)

    def forward(self, input_):
        ret = []
        for l, feat in enumerate(self.features):
            # print("call:", feat)
            do_skip = l >= 1 and self.skip > 1
            input_ = feat(input_ if not do_skip else torch.cat(ret[-min(self.skip, l) :], dim=1))
            # print("out shape:", input_.size())
            ret.append(input_)
        # print([e.size() for e in ret])
        # print([ret[-1].size()])
        # print((torch.cat([ret[-1]], dim=1)).size())
        return torch.cat([ret[ind] for ind in self.stack], dim=1)

    def laplace(self):
        """
        Laplace regularization for the filters of the first conv2d layer.
        """
        reg_scale = self._input_weights_regularizer(self.features[0].scale.weight, avg=self.use_avg_reg)
        reg_first_conv = self._input_weights_regularizer(self.features[1].conv.weight, avg=self.use_avg_reg)
        return reg_scale

    def group_sparsity(self):
        """
        Sparsity regularization on the filters of all the conv2d layers except the first one.
        """
        ret = 0
        if self.ignore_group_sparsity:
            return ret

        for feature in self.features[1:]:
            ret = ret + feature.conv.weight.pow(2).sum(3, keepdim=True).sum(2, keepdim=True).sqrt().mean()
        return ret / ((self.num_layers - 1) if self.num_layers > 1 else 1)

    def regularizer(self):
        return self.group_sparsity() * self.gamma_hidden + self.gamma_input * self.laplace()

    @property
    def outchannels(self):
        return len(self.features) * self.hidden_channels


import json
import datetime
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core import serializers
from django.http import JsonResponse
from django.shortcuts import render
from django.utils import timezone
from django.views.decorators.clickjacking import xframe_options_exempt

from account.models import ArticleViewHistory, CommentMessage, SectionViewHistory, SectionMessage
from account.views import imgSave
from blog.models import Category, Tag, Article, Note, Section, Catalogue
from management.models import About, WebsiteConfig, ImagesConfig, Info, Carousel, Link
from management.tools import AliyunSDK, BaiduApi

@login_required()
# 后台管理模块
def management(request):
    model = "management"
    return render(request, 'layui-mini/base.html', locals())

# 后台管理首页
@xframe_options_exempt
@login_required()
def dashboard(request):
    # 流量统计比较
    api = BaiduApi()
    count = api.countToday()
    today = count[0]
    compare = count[2]
    today_pv = today[1]
    today_uv = today[2]
    today_time = today[3]
    today_page = today[4]
    compare_pv = compare[1]
    compare_uv = compare[2]
    compare_time = compare[3]
    compare_page = compare[4]
    # 主机性能
    cpu = AliyunSDK("CPUUtilization")
    cpu_rate = round(cpu.metricInfo(), 2)
    memory = AliyunSDK("memory_usedutilization")
    memory_rate = round(memory.metricInfo(), 2)
    disk = AliyunSDK("diskusage_utilization")
    disk_rate = round(disk.metricInfo(), 2)
    load = AliyunSDK("load_15m")
    load_rate = round(load.metricInfo() * 100, 2)
    return render(request, 'layui-mini/management/index.html', locals())

# 文章列表
@xframe_options_exempt
@login_required()
def articleList(request):
    return render(request, 'layui-mini/management/articleList.html', locals())

# 文章分类
@xframe_options_exempt
@login_required()
def articleCategory(request):
    return render(request, 'layui-mini/management/articleCategory.html', locals())

# 文章标签
@xframe_options_exempt
@login_required()
def articleTag(request):
    return render(request, 'layui-mini/management/articleTag.html', locals())

# 文章评论
@xframe_options_exempt
@login_required()
def articleComment(request):
    return render(request, 'layui-mini/management/articleComment.html', locals())

# 笔记名称
@xframe_options_exempt
@login_required()
def sectionNote(request):
    return render(request, 'layui-mini/management/sectionNote.html', locals())

# 笔记评论
@xframe_options_exempt
@login_required()
def sectionComment(request):
    return render(request, 'layui-mini/management/sectionComment.html', locals())

# 笔记目录编排
@xframe_options_exempt
@login_required()
def sectionCatalog(request):
    note_all = Note.objects.all()
    return render(request, 'layui-mini/management/sectionCatalog.html', locals())

# 文章列表
@xframe_options_exempt
@login_required()
def sectionList(request):
    return render(request, 'layui-mini/management/sectionList.html', locals())

# 网站关于
@xframe_options_exempt
@login_required()
def websiteAbout(request):
    if request.method == "POST":
        try:
            about = About.objects.get(id=1)
            about.body = request.POST.get("content")
            about.save()
            result = {
                "code": "1",
                "msg": "修改成功!",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "修改失败!",
            }
        return JsonResponse(result)
    else:
        about = About.objects.get(id=1)
        body = about.body
        time = about.time
        return render(request, 'layui-mini/management/websiteAbout.html', locals())

# 网站配置
@xframe_options_exempt
@login_required()
def websiteConfig(request):
    if request.method == "POST":
        website = WebsiteConfig.objects.get(id=1)
        website.name = request.POST.get('sitename')
        website.domain = request.POST.get('domain')
        website.index_title = request.POST.get('title')
        website.keywords = request.POST.get('keywords')
        website.descript = request.POST.get('descript')
        website.copyright = request.POST.get('copyright')
        images = ImagesConfig.objects.get(id=1)
        images.foreground = request.POST.get('foreground')[6:]
        images.background = request.POST.get('background')[6:]
        images.icon = request.POST.get('icon')[6:]
        images.photo = request.POST.get('photo')[6:]
        images.cover = request.POST.get('cover')[6:]
        images.pay = request.POST.get('pay')[6:]
        try:
            website.save()
            images.save()
            result = {
                "code": "1",
                "msg": "修改成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "修改成功！",
            }
        return JsonResponse(result)
    else:
        website = WebsiteConfig.objects.get(id=1)
        images = ImagesConfig.objects.get(id=1)
        return render(request, 'layui-mini/management/websiteConfig.html', locals())

# 博主信息
@xframe_options_exempt
@login_required()
def BloggerInfo(request):
    if request.method == 'POST':
        info = Info.objects.get(id=1)
        info.position = request.POST.get('position')
        info.company = request.POST.get('company')
        info.location = request.POST.get('location')
        info.email = request.POST.get('email')
        info.csdn = request.POST.get('csdn')
        info.github = request.POST.get('github')
        info.qq = request.POST.get('qq')[6:]
        info.weixin = request.POST.get('weixin')[6:]
        try:
            info.save()
            result = {
                "code": "1",
                "msg": "修改成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "修改失败！",
            }
        return JsonResponse(result)
    else:
        info = Info.objects.get(id=1)
        return render(request, 'layui-mini/management/bloggerInfo.html', locals())

# 留言管理
@xframe_options_exempt
@login_required()
def websiteLeaveMessage(request):
    return render(request, 'layui-mini/management/websiteLeaveMessage.html', locals())

# 轮播图管理
@xframe_options_exempt
@login_required()
def websiteCarousel(request):
    return render(request, 'layui-mini/management/websiteCarousel.html', locals())

# 新增轮播图
@xframe_options_exempt
@login_required()
def carouselAdd(request):
    if request.method == 'POST':
        carousel = Carousel()
        carousel.info = request.POST.get('info')
        carousel.url = request.POST.get('url')
        carousel.img = request.POST.get('img')[6:]
        carousel.is_show = request.POST.get('is_show')
        try:
            carousel.save()
            result = {
                "code": "1",
                "msg": "添加成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "添加失败！",
            }
        return JsonResponse(result)
    else:
        return render(request, 'layui-mini/management/carouselAdd.html', locals())

# 友情链接管理
@xframe_options_exempt
@login_required()
def websiteLink(request):
    return render(request, 'layui-mini/management/websiteLink.html', locals())

# 新增友情链接
@xframe_options_exempt
@login_required()
def linkAdd(request):
    if request.method == 'POST':
        link = Link()
        link.name = request.POST.get('name')
        link.url = request.POST.get('url')
        link.logo = request.POST.get('img')[6:]
        link.describe = request.POST.get('describe')
        link.type = request.POST.get('type')
        try:
            link.save()
            result = {
                "code": "1",
                "msg": "添加成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "添加失败！",
            }
        return JsonResponse(result)
    else:
        return render(request, 'layui-mini/management/linkAdd.html', locals())

# 用户管理
@xframe_options_exempt
@login_required()
def managementUser(request):
    return render(request, 'layui-mini/management/managementUser.html', locals())

# ajax 文章封面图片上传
def coverUpload(request):
    if request.method == "POST":
        dir = 'cover/'
        file = request.FILES.get('file')
        filename = "%s.%s" % (timezone.now().strftime('%Y_%m_%d_%H_%M_%S_%f'), file.name.split('.')[-1])
        filepath = 'media/' + dir + filename
        # 图片资源写入服务器
        code = imgSave(file, filepath)
        if (code == 1):
            result = {
                "code": "1",
                "msg": "上传成功!",
                "src": filepath,
            }
            return JsonResponse(result)
        else:
            result = {
                "code": "0",
                "msg": "上传失败!",
                "src": None,
            }
        return JsonResponse(result)

# 新增文章
@xframe_options_exempt
@login_required()
def articleAdd(request):
    if request.method == "POST":
        title = request.POST.get("title")
        category_id = request.POST.get("category_id")
        excerpt = request.POST.get("excerpt")
        tags = request.POST.get("tags")
        cover_img = request.POST.get("cover_img")
        img = str(cover_img).split("media/")[1]
        content = request.POST.get("content")
        article_type = request.POST.get("type")
        recommended = request.POST.get("recommended")
        try:
            article = Article()
            article.title = title
            article.excerpt = excerpt
            article.img = img
            article.body = content
            article.author_id = request.user.id
            article.category_id = category_id
            article.is_recommend = recommended
            if article_type == 'release':
                article.is_release = 1
            elif article_type == 'save':
                article.is_release = 0
            article.save()
            article.tags.add(*list(Tag.objects.filter(id__in=tags.split(','))))
            result = {
                "code": "1",
                "msg": "提交成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "提交失败！",
            }
        return JsonResponse(result)
    else:
        category_all = Category.objects.all()
        tag_all = Tag.objects.all()
        return render(request, 'layui-mini/management/articleAdd.html', locals())

# ajax删除文章
def articleDel(request):
    article_id = request.GET.get("del_id")
    article_arr = request.GET.get("delidArr")
    if article_id:
        Article.objects.get(id=article_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif article_arr:
        article_list = article_arr.split(',')
        for i in article_list:
            Article.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# ajax文章修改
@xframe_options_exempt
@login_required()
def articleEdit(request, article_id):
    if request.method == "POST":
        article_id = request.POST.get("id")
        title = request.POST.get("title")
        category_id = request.POST.get("category_id")
        excerpt = request.POST.get("excerpt")
        tags = request.POST.get("tags")
        cover_img = request.POST.get("cover_img")
        img = str(cover_img).split("media/")[1]
        content = request.POST.get("content")
        article_type = request.POST.get("type")
        recommended = request.POST.get("recommended")
        try:
            article = Article.objects.get(id=article_id)
            article.title = title
            article.excerpt = excerpt
            article.img = img
            article.body = content
            article.author_id = request.user.id
            article.category_id = category_id
            article.is_recommend = recommended
            if article_type == 'release':
                article.is_release = 1
            elif article_type == 'save':
                article.is_release = 0
            article.save()
            article.tags.clear()
            article.tags.add(*list(Tag.objects.filter(id__in=tags.split(','))))
            result = {
                "code": "1",
                "msg": "提交成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "提交失败！",
            }
        return JsonResponse(result)
    else:
        article = Article.objects.get(id=article_id)
        category_all = Category.objects.all()
        tag_all = Tag.objects.all()
        tags = list(article.tags.values_list('id', flat=True))
        return render(request, 'layui-mini/management/articleEdit.html', locals())

# ajax删除文章分类
def categoryDel(request):
    category_id = request.GET.get("del_id")
    category_arr = request.GET.get("delidArr")
    if category_id:
        Category.objects.get(id=category_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif category_arr:
        category_list = category_arr.split(',')
        for i in category_list:
            Category.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# ajax修改文章分类
def categoryEdit(request):
    if request.method == "POST":
        category_id = request.POST.get("category_id")
        name = request.POST.get("name")
        try:
            category = Category.objects.get(id=category_id)
            category.name = name
            category.save()
            result = {
                "code": "1",
                "msg": "修改成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "修改失败！",
            }
        return JsonResponse(result)

# ajax新增文章分类
def categoryAdd(request):
    if request.method == "POST":
        name = request.POST.get("name")
        try:
            category = Category()
            category.name = name
            category.save()
            result = {
                "code": "1",
                "msg": "添加成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "添加失败！",
            }
        return JsonResponse(result)

# ajax添加文章标签
def tagAdd(request):
    if request.method == "POST":
        name = request.POST.get("name")
        try:
            tag = Tag()
            tag.name = name
            tag.save()
            result = {
                "code": "1",
                "msg": "添加成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "添加失败！",
            }
        return JsonResponse(result)

# ajax 修改文章标签
def tagEdit(request):
    if request.method == "POST":
        tag_id = request.POST.get("tag_id")
        name = request.POST.get("name")
        try:
            tag = Tag.objects.get(id=tag_id)
            tag.name = name
            tag.save()
            result = {
                "code": "1",
                "msg": "修改成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "修改失败！",
            }
        return JsonResponse(result)

# ajax删除标签
def tagDel(request):
    tag_id = request.GET.get("del_id")
    tag_arr = request.GET.get("delidArr")
    if tag_id:
        Tag.objects.get(id=tag_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif tag_arr:
        tag_list = tag_arr.split(',')
        for i in tag_list:
            Tag.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# ajax新增笔记名称
def noteAdd(request):
    if request.method == "POST":
        name = request.POST.get("name")
        try:
            note = Note()
            note.name = name
            note.save()
            result = {
                "code": "1",
                "msg": "添加成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "添加失败！",
            }
        return JsonResponse(result)

# ajax删除笔记名
def noteDel(request):
    note_id = request.GET.get("del_id")
    note_arr = request.GET.get("delidArr")
    if note_id:
        Note.objects.get(id=note_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif note_arr:
        note_list = note_arr.split(',')
        for i in note_list:
            Note.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# ajax修改笔记名
def noteEdit(request):
    if request.method == "POST":
        note_id = request.POST.get("note_id")
        name = request.POST.get("name")
        try:
            note = Note.objects.get(id=note_id)
            note.name = name
            note.save()
            result = {
                "code": "1",
                "msg": "修改成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "修改失败！",
            }
        return JsonResponse(result)

# ajax删除轮播图
def carouselDel(request):
    tag_id = request.GET.get("del_id")
    tag_arr = request.GET.get("delidArr")
    if tag_id:
        Carousel.objects.get(id=tag_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif tag_arr:
        tag_list = tag_arr.split(',')
        for i in tag_list:
            Carousel.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# ajax编辑轮播图
@xframe_options_exempt
@login_required()
def carouselEdit(request, carousel_id):
    if request.method == "POST":
        carousel = Carousel.objects.get(id=carousel_id)
        carousel.info = request.POST.get('info')
        carousel.url = request.POST.get('url')
        carousel.img = request.POST.get('img')[6:]
        carousel.is_show = request.POST.get('is_show')
        try:
            carousel.save()
            result = {
                "code": "1",
                "msg": "提交成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "提交失败！",
            }
        return JsonResponse(result)
    else:
        carousel = Carousel.objects.get(id=carousel_id)
        return render(request, 'layui-mini/management/carouselEdit.html', locals())

# ajax友链删除
def linkDel(request):
    tag_id = request.GET.get("del_id")
    tag_arr = request.GET.get("delidArr")
    if tag_id:
        Link.objects.get(id=tag_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif tag_arr:
        tag_list = tag_arr.split(',')
        for i in tag_list:
            Link.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# ajax 编辑友链
@xframe_options_exempt
@login_required()
def linkEdit(request, link_id):
    if request.method == "POST":
        link = Link.objects.get(id=link_id)
        link.name = request.POST.get('name')
        link.url = request.POST.get('url')
        link.logo = request.POST.get('img')[6:]
        link.describe = request.POST.get('describe')
        link.type = request.POST.get('type')
        try:
            link.save()
            result = {
                "code": "1",
                "msg": "提交成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "提交失败！",
            }
        return JsonResponse(result)
    else:
        link = Link.objects.get(id=link_id)
        return render(request, 'layui-mini/management/linkEdit.html', locals())

# ajax 删除用户
def userDel(request):
    tag_id = request.GET.get("del_id")
    tag_arr = request.GET.get("delidArr")
    if tag_id:
        User.objects.get(id=tag_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif tag_arr:
        tag_list = tag_arr.split(',')
        for i in tag_list:
            User.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# 新增笔记内容
@xframe_options_exempt
@login_required()
def sectionAdd(request):
    if request.method == "POST":
        title = request.POST.get("title")
        note_id = request.POST.get("note_id")
        father_id = request.POST.get("father_id")
        body = request.POST.get("body")
        type = request.POST.get("type")
        try:
            section = Section()
            section.title = title
            section.note_id = note_id
            section.body = body
            section.author_id = request.user.id
            if type == "release":
                section.is_release = 1
            else:
                section.is_release = 0
            section.save()
            catalogue = Catalogue()
            catalogue.note_id = note_id
            catalogue.father = father_id
            catalogue.name = title
            catalogue.section = Section.objects.get(id=section.id)
            catalogue.save()
            result = {
                "code": "1",
                "msg": "提交成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "提交失败！",
            }
        return JsonResponse(result)
    else:
        note_all = Note.objects.all()
        return render(request, 'layui-mini/management/sectionAdd.html', locals())

# ajax删除笔记内容
def sectionDel(request):
    section_id = request.GET.get("del_id")
    section_arr = request.GET.get("delidArr")
    if section_id:
        Section.objects.get(id=section_id).delete()
        result = {"code": 1, "msg": "删除成功!"}
    elif section_arr:
        section_list = section_arr.split(',')
        for i in section_list:
            Section.objects.get(id=i).delete()
        result = {"code": 1, "msg": "删除成功!"}
    else:
        result = {"code": 0, "msg": "删除失败!"}
    return JsonResponse(result)

# ajax修改笔记内容
@xframe_options_exempt
@login_required()
def sectionEdit(request, section_id):
    if request.method == "POST":
        section_id = request.POST.get("id")
        title = request.POST.get("title")
        note_id = request.POST.get("note_id")
        father_id = request.POST.get("father_id")
        body = request.POST.get("content")
        section_type = request.POST.get("type")
        try:
            section = Section.objects.get(id=section_id)
            section.title = title
            section.body = body
            section.author_id = request.user.id
            section.note_id = note_id
            if section_type == 'release':
                section.is_release = 1
            elif section_type == 'save':
                section.is_release = 0
            section.save()
            catalogue = Catalogue.objects.filter(section=section.id)[0]
            catalogue.note_id = note_id
            catalogue.father = father_id
            catalogue.name = title
            catalogue.section = Section.objects.get(id=section.id)
            catalogue.save()
            result = {
                "code": "1",
                "msg": "提交成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "提交失败！",
            }
        return JsonResponse(result)
    else:
        section = Section.objects.get(id=section_id)
        note_all = Note.objects.all()
        father_all = Catalogue.objects.filter(level=1)
        return render(request, 'layui-mini/management/sectionEdit.html', locals())

# ajax 修改目录结构
def catalogEdit(request):
    if request.method == 'POST':
        note_id = request.POST.get('note_id')
        catalog_data = request.POST.get('catalog_data')
        data_json = json.loads(catalog_data)
        try:
            if len(data_json) == Catalogue.objects.filter(note=note_id).filter(level=1).count():
                # 移动节点，未新增
                for i in range(len(data_json)):
                    father = Catalogue.objects.get(id=data_json[i]['id'])
                    father.name = data_json[i]['label']
                    father.save()
                    if 'children' in data_json[i].keys():
                        for j in range(len(data_json[i]['children'])):
                            children = Catalogue.objects.get(id=data_json[i]['children'][j]['id'])
                            children.order = j + 1
                            children.father = father.id
                            children.save()
            elif len(data_json) > Catalogue.objects.filter(note=note_id).filter(level=1).count():
                # 新增节点,有则改，无则加
                father_list = []
                father_all = Catalogue.objects.filter(note=note_id).filter(level=1)
                for i in father_all:
                    father_list.append(i.id)
                for i in range(len(data_json)):
                    if data_json[i]['id'] in father_list:
                        father = Catalogue.objects.get(id=data_json[i]['id'])
                        father.name = data_json[i]['label']
                        father.save()
                    else:
                        father = Catalogue()
                        father.note_id = note_id
                        father.name = data_json[i]['label']
                        father.order = i + 1
                        father.level = 1
                        father.father = None
                        father.section = None
                        father.save()
                        print(data_json[i])
                    if 'children' in data_json[i].keys():
                        for j in range(len(data_json[i]['children'])):
                            children = Catalogue.objects.get(id=data_json[i]['children'][j]['id'])
                            children.order = j + 1
                            children.father = father.id
                            children.save()
            else:
                # 删除节点,有则改，无则减
                father_list = []
                for i in range(len(data_json)):
                    father_list.append(data_json[i]['id'])
                father_all = Catalogue.objects.filter(note=note_id).filter(level=1)
                for i in father_all:
                    if i.id not in father_list:
                        father = Catalogue.objects.get(id=i.id)
                        father.delete()
                    else:
                        for j in data_json:
                            if i.id == j['id']:
                                father = Catalogue.objects.get(id=i.id)
                                father.name = j['label']
                                father.save()
            result = {
                "code": "1",
                "msg": "提交成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "提交失败！",
            }
    else:
        note_id = request.GET.get("note_id")
        note = Note.objects.get(id=note_id)
        first_catalogue = Catalogue.objects.filter(note=note.id).filter(level=1)
        try:
            father_list = []
            for i in first_catalogue:
                father_dict = {}
                father_dict['id'] = i.id
                father_dict['name'] = i.name
                father_list.append(father_dict)
            catalogue_list = []
            for i in first_catalogue:
                catalogue_dict = {}
                catalogue_dict["id"] = i.id
                catalogue_dict["label"] = i.name
                catalogue_dict["isOpen"] = True
                children_list = []
                catalogue_dict["children"] = children_list
                second_catalogue = Catalogue.objects.filter(father=i.id)
                for j in second_catalogue:
                    children_dict = {}
                    children_dict["label"] = j.section.title
                    children_dict["id"] = j.id
                    children_list.append(children_dict)
                catalogue_list.append(catalogue_dict)
            result = {
                "father": father_list,
                "data": catalogue_list,
                "code": "1",
                "msg": "加载成功！",
            }
        except Exception as e:
            print(e)
            result = {
                "code": "0",
                "msg": "加载失败！",
            }
    return JsonResponse(result)

# echarts数据接口
def echartsData(request):
    datatype = request.GET.get("type")
    api = BaiduApi()
    # 近7天流量分析
    if datatype == "trend":
        data = {}
        trend = api.countTrend()
        trend_xAxis = trend["items"][0]
        xAxis = []
        for i in reversed(trend_xAxis):
            xAxis.append(i[0])
        data['xAxis'] = xAxis
        trend_data = trend["items"][1]
        pv = []
        uv = []
        add_user = []
        ip = []
        time = []
        page = []
        for i in reversed(trend_data):
            pv.append(i[0])
            uv.append(i[1])
            add_user.append(i[2])
            ip.append(i[3])
            time.append(i[4])
            page.append(i[5])
        data['pv'] = pv
        data['uv'] = uv
        data['add_user'] = add_user
        data['ip'] = ip
        data['time'] = time
        data['page'] = page
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    # 受访页面统计
    elif datatype == 'page':
        data = {}
        page = api.countPage()
        page_xAxis = page["items"][0]
        xAxis = []
        for i in page_xAxis:
            if i[0]['name'][27:] == '':
                xAxis.append("/")
            else:
                xAxis.append(i[0]['name'][27:])
        data['xAxis'] = xAxis
        trend_data = page["items"][1]
        pv = []
        uv = []
        in_count = []
        time = []
        for i in trend_data:
            pv.append(i[0])
            uv.append(i[1])
            in_count.append(i[2])
            time.append(i[3])
        data['pv'] = pv
        data['uv'] = uv
        data['in_count'] = in_count
        data['time'] = time
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    # 访客设备统计
    elif datatype == 'device':
        device = api.countDevice()
        data = {}
        data['pc'] = device['pc']
        data['mobile'] = device['mobile']
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    # 访客区域统计
    elif datatype == 'map':
        map = api.countMap()
        data_count = []
        # data_rate = []
        pv_max = 0
        for i in range(len(map['items'][0])):
            pv_count = {}
            pv_count['name'] = map['items'][0][i][0]['name']
            pv_count['value'] = map['items'][1][i][0]
            if pv_max < map['items'][1][i][0]:
                pv_max = map['items'][1][i][0]
            data_count.append(pv_count)
            # pv_rate = {}
            # pv_rate['name'] = map['items'][0][i][0]['name']
            # pv_rate['value'] = map['items'][1][i][1]
            # data_rate.append(pv_rate)
        data = {}
        data['count'] = data_count
        data['pv_max'] = pv_max
        # data['rate'] = data_rate
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    # 用户浏览趋势
    elif datatype == 'view':
        date_list = []
        for i in range(6, 0, -1):
            date_list.append((datetime.datetime.now() - datetime.timedelta(days=i)).strftime("%Y-%m-%d"))
        date_list.append(datetime.datetime.now().strftime("%Y-%m-%d"))
        article_view = []
        article_like = []
        article_comment = []
        section_view = []
        section_like = []
        section_comment = []
        for date in date_list:
            article_view.append(ArticleViewHistory.objects.filter(user=request.user).filter(time__date=date).count())
            article_like.append(
                ArticleViewHistory.objects.filter(user=request.user).filter(time__date=date).filter(is_like=1).count())
            article_comment.append(CommentMessage.objects.filter(user=request.user).filter(time__date=date).count())
            section_view.append(SectionViewHistory.objects.filter(user=request.user).filter(time__date=date).count())
            section_like.append(
                SectionViewHistory.objects.filter(user=request.user).filter(time__date=date).filter(is_like=1).count())
            section_comment.append(SectionMessage.objects.filter(user=request.user).filter(time__date=date).count())
        data = {}
        data['xAxis'] = date_list
        data['article_view'] = article_view
        data['article_like'] = article_like
        data['article_comment'] = article_comment
        data['section_view'] = section_view
        data['section_like'] = section_like
        data['section_comment'] = section_comment
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    # 用户浏览文章分类统计
    elif datatype == 'category':
        category_list = []
        data = {}
        end_date = datetime.datetime.now().strftime("%Y-%m-%d") + ' 23:59:59'
        start_date = ((datetime.datetime.now() - datetime.timedelta(days=6)).strftime("%Y-%m-%d")) + ' 00:00:01'
        series = []
        for i in Category.objects.all():
            category_list.append(i.name)
            info = {}
            info['value'] = ArticleViewHistory.objects.filter(user=request.user).filter(time__range=[start_date, end_date]).filter(
                category=i).count()
            info['name'] = i.name
            series.append(info)
        data["legend"] = category_list
        data["series"] = series
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    # 用户浏览笔记统计
    elif datatype == 'note':
        indicator = []
        serise = []
        data = {}
        end_date = datetime.datetime.now().strftime("%Y-%m-%d") + ' 23:59:59'
        start_date = ((datetime.datetime.now() - datetime.timedelta(days=6)).strftime("%Y-%m-%d")) + ' 00:00:01'
        for i in Note.objects.all():
            info = {}
            info['name'] = i.name
            info['max'] = 50
            indicator.append(info)
            serise.append(SectionViewHistory.objects.filter(user=request.user).filter(time__range=[start_date, end_date]).filter(
                note=i).count())
        data['indicator'] = indicator
        data['serise'] = serise
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    # 用户浏览时间统计
    elif datatype == 'time':
        data = {}
        article_sum = []
        section_sum = []
        for i in range(6, -1, -1):
            if i == 6:
                # print("第一天")
                day = (datetime.datetime.now() - datetime.timedelta(days=i)).strftime("%Y-%m-%d")
                for j in range(0, 24, 2):
                    start_time = day + " " + str(j) + ":00:01"
                    end_time = day + " " + str(int(j) + 1) + ":59:59"
                    article_count = ArticleViewHistory.objects.filter(user=request.user).filter(
                        time__range=[start_time, end_time]).count()
                    section_count = SectionViewHistory.objects.filter(user=request.user).filter(
                        time__range=[start_time, end_time]).count()
                    article_sum.append(article_count)
                    section_sum.append(section_count)
            else:
                # print("不是第一天")
                day = (datetime.datetime.now() - datetime.timedelta(days=i)).strftime("%Y-%m-%d")
                for j in range(12):
                    start_time = day + " " + str(j * 2) + ":00:01"
                    end_time = day + " " + str(j * 2 + 1) + ":59:59"
                    article_count = ArticleViewHistory.objects.filter(user=request.user).filter(
                        time__range=[start_time, end_time]).count()
                    section_count = SectionViewHistory.objects.filter(user=request.user).filter(
                        time__range=[start_time, end_time]).count()
                    article_sum[j] = article_sum[j] + article_count
                    section_sum[j] = section_sum[j] + section_count
        data["article"] = article_sum
        data["section"] = section_sum
        result = {
            "data": data,
            "code": "1",
            "msg": "加载成功！",
        }
    return JsonResponse(result)


from tkinter import *
from tkinter import ttk, messagebox, filedialog as fd
from tkinter.ttk import Combobox
import requests

window = Tk()
window.title("Шишкин Кирилл Сергеевич")
window.geometry('700x700')

tab_control = ttk.Notebook(window)

# Калькулятор

tab_calc = ttk.Frame(tab_control)
tab_control.add(tab_calc, text="Калькулятор")
tab_control.pack(expand=True, fill='both')

entry1 = Entry(tab_calc, text="Первое число")
entry1.pack()

sign_combo = Combobox(tab_calc)
sign_combo['values'] = ["+", "-", "*", "/"]
sign_combo.current(0)
sign_combo.pack()

entry2 = Entry(tab_calc, text="Второе число")
entry2.pack()

def calc():
    global sum_text
    a = int(entry1.get())
    b = int(entry2.get())

    sign = sign_combo.get()

    if sign == "+":
        sum_text.set(a + b)
    if sign == "-":
        sum_text.set(a - b)
    if sign == "*":
        sum_text.set(a * b)
    if sign == "/":
        sum_text.set(a / b)
calc_btn = Button(tab_calc, command=calc, text="Вычислить")
calc_btn.pack()

sum_text = StringVar()
entry_sum = Entry(tab_calc, textvariable=sum_text)
entry_sum.pack()

# Чекбоксы

tab_checkbox = ttk.Frame(tab_control)
tab_control.add(tab_checkbox, text="Чекбоксы")
tab_control.pack(expand=True, fill='both')

var = IntVar()
var.set(1)
rd1 = Radiobutton(tab_checkbox, text="Первый вариант", variable=var, value=1)
rd1.pack()
rd2 = Radiobutton(tab_checkbox, text="Второй вариант", variable=var, value=2)
rd2.pack()
rd3 = Radiobutton(tab_checkbox, text="Третий вариант", variable=var, value=3)
rd3.pack()

def rd_btn_click():
    messagebox.showinfo("Сообщение", f"Выбран вариант №{var.get()}")

rd_btn = Button(tab_checkbox, text="Сообщение", command=rd_btn_click)
rd_btn.pack()

# Текст

tab_text = ttk.Frame(tab_control)
tab_control.add(tab_text, text="Текст")
tab_control.pack(expand=True, fill='both')

def file_upload_clicked():
    global text_data
    filename = fd.askopenfilename()
    text_data.delete(1.0, END)
    with open(filename, "r") as f:
        text_data.insert(END, f.read())

menu = Menu(window)
window.config(menu=menu)
file_upload = Menu(menu)
file_upload.add_command(label='Открыть', command=file_upload_clicked)
menu.add_cascade(label='Файл', menu=file_upload)

text_data = Text(tab_text)
text_data.pack()

# Github

tab_github = ttk.Frame(tab_control)
tab_control.add(tab_github, text="Github")
tab_control.pack(expand=True, fill='both')

label = ttk.Label(tab_github, text="Вводить в формате автор/репозиторий\nНапример: kubernetes/kubernetes")
label.pack()

repo_name_entry = Entry(tab_github, text="Название репозитория")
repo_name_entry.pack()

def load_info():
    url = f"https://api.github.com/repos/{repo_name_entry.get()}"

    response = requests.get(url)

    if response.status_code == 200:
        data = response.json()
        keys = ['company', 'created_at', 'email', 'id', 'name', 'url']
        filtered_data = {k: data[k] if k in data else None for k in keys}

        with open("filtered_data.txt", "w") as f:
            f.write(str(filtered_data))

        messagebox.showinfo("Успешно", "Информация загружена")
    else:
        messagebox.showerror("Ошибка", f"Ошибка при загрузке информации: {response.reason}")

load_info_btn = ttk.Button(tab_github, command=load_info, text="Загрузить информацию")
load_info_btn.pack()

window.mainloop()


#!/usr/bin/env python
# coding: utf-8

# In[168]:

import matplotlib.pyplot as plt
import numpy as np
import random
from cat import Cat

# In[169]:

MAXROW = 20
MAXCOL = 30

# In[170]:

def processline(linelist):
    newlist = [(int(l.split(",")[0]),int(l.split(",")[1])) for l in linelist[1:]]
    return newlist

def read_data(filename):
    file = open(filename,'r')
    data = file.readlines()
    lists = []
    for line in data:
        new_list = processline(line.split(":"))
        lists.append(new_list)
    foodlist = lists [0]
    waterlist = lists [1]
    bedlist = lists [2]
    boxlist = lists [3]
    return foodlist, waterlist, bedlist, boxlist

def move_em(current, moves):
    nextgrid = np.zeros(current.shape, dtype="int16")

    for row in range(MAXROW):
        for col in range(MAXCOL):
            for g in range(current[row,col]):
                nextrow = row + random.choice(moves)
                nextcol = col + random.choice(moves)
                if nextrow < 0:
                    nextrow = 0
                if nextcol < 0:
                    nextcol = 0
                if nextrow >= MAXROW:
                    nextrow = MAXROW - 1
                if nextcol >= MAXCOL:
                    nextcol = MAXCOL - 1
                nextgrid[nextrow, nextcol] += 1
    return nextgrid

def rule1(pop, datalist, marksList):
    for row in range(MAXROW):
        for col in range(MAXCOL):
            if (row, col) in datalist:
                for g in range(pop[row,col]):
                    pop[row, col] -= 1
                    marksList.append(-5)
                    print("CAT KILLED")

def rule2(pop, datalist, marksList):
    for row in range(MAXROW):
        for col in range(MAXCOL):
            if (row, col) in datalist:
                for g in range(pop[row,col]):
                    marksList.append(10)
                    print("CAT GET ENERGY")

def rule3(array1, array2, marksList):
    for row in range(MAXROW):
        for col in range(MAXCOL):
            if array1[row,col]>0 and array2[row,col]>0:
                for k in range(array1[row,col]):
                    array1[row, col] += 1
                    array2[row,col] -= 1
                    print("CAT PERSONALITY CHANGE")

def make_feature_scatter_boost(itemlist, colour, plotData):
    xlist = []
    ylist = []
    for r,c in itemlist:
        ylist.append(MAXROW - r - 1)
        xlist.append(c)
    plotData.append([ str(xlist), str(ylist), '^'])
    plt.scatter(xlist,ylist,color=colour, marker='^')

def make_feature_scatter_barriers(itemlist, colour, plotData):
    xlist = []
    ylist = []
    for r,c in itemlist:
        ylist.append(MAXROW - r - 1)
        xlist.append(c)
    plotData.append([ str(xlist), str(ylist), 'X'])
    plt.scatter(xlist,ylist,color=colour, marker='X')

def make_my_scatter(pop, colour, plotData):
    xlist = []
    ylist = []
    slist = []
    for row in range(MAXROW):
        for col in range(MAXCOL):
            if pop[row,col] > 0:
                ylist.append(MAXROW - row - 1)
                xlist.append(col)
                slist.append(pop[row,col]*20)
    plotData.append([ str(xlist), str(ylist), 'o'])
    plt.scatter(xlist,ylist,s=slist,color=colour, marker='o')

# In[171]:

def ask_questions(questions):
    FriendlyCats = []
    AggressiveCats = []
    answerList=[]

    try:
        for question in questions:
            answer = input(question)
            answerList.append(answer)

        q1 = int(answerList[0])
        q2 = answerList[1]
        q3 = int(answerList[2])
        q4 = int(answerList[3])

        for a in range(q3):
            if(q1==1):
                FriendlyCats.append(Cat("Male", q2, "Friendly"))
            elif(q1==2):
                FriendlyCats.append(Cat("Female", q2, "Friendly"))
            else:
                print("OUT OF RANGE")

        for b in range(q4):
            if(q1==1):
                AggressiveCats.append(Cat("Male", q2, "Aggressive"))
            elif(q1==2):
                AggressiveCats.append(Cat("Female", q2, "Aggressive"))
            else:
                print("OUT OF RANGE")

        return FriendlyCats, AggressiveCats

    except:
        print("An exception occurred")

# In[172]:

def main():
    print("\n**********WELCOME TO GAME OF CATS (VILLAGE)**********\n ")

    questions = [
     "Cats gender?\n(1) Male \n(2) Female\n",
     "Cats age group?\n(Kitten, Junior, Prime, Mature, Senior)\n",
     "Friendly Cats Count?\n",
     "Aggressive Cats Count?\n"
    ]

    friendlyCartList, aggressiveCartList = ask_questions(questions)

    pointsList = []
    plotData = []

    friendlyArray = np.zeros((MAXROW,MAXCOL), dtype="int16")
    aggressiveArray = np.zeros((MAXROW,MAXCOL), dtype="int16")

    food, water, bed, boxes = read_data("cat.txt")

    moves  = [-1,0,1]
#     moves  = [-2,-1,0,1,2]
    print("--- CAT VILLAGE ---")
    for friendlyCart in friendlyCartList:
        print(friendlyCart)
        friendlyArray[random.randint(0,MAXROW-1),random.randint(0,MAXCOL-1)] += 1

    for aggressiveCart in aggressiveCartList:
        print(aggressiveCart)
        aggressiveArray[random.randint(0,MAXROW-1),random.randint(0,MAXCOL-1)] += 1

    # Simulation
    for t in range(10): # Simulation Time 10s
        try:
            friendlynext = move_em(friendlyArray, moves)
            aggressivenext = move_em(aggressiveArray, moves)

            rule1(friendlynext, bed, pointsList)
            rule1(friendlynext, boxes, pointsList)
            rule2(friendlynext, food, pointsList)
            rule2(friendlynext, water, pointsList)
            rule3(friendlynext, aggressivenext, pointsList)

            rule1(aggressivenext, bed, pointsList)
            rule1(aggressivenext, boxes, pointsList)
            rule2(aggressivenext, food, pointsList)
            rule2(aggressivenext, water, pointsList)
            rule3(aggressivenext, friendlynext, pointsList)

            friendlyArray = friendlynext
            aggressiveArray = aggressivenext

            make_my_scatter(friendlyArray, "b", plotData)
            make_my_scatter(aggressiveArray, "r", plotData)

            make_feature_scatter_boost(food, "#f0ad4e", plotData)
            make_feature_scatter_boost(water, "#5bc0de", plotData)

            make_feature_scatter_barriers(bed, "#d9534f", plotData)
            make_feature_scatter_barriers(boxes, "#f7f7f7", plotData)

            plt.title("Cat Simulation (time = " + str(t) + ")")
            plt.rcParams['axes.facecolor']='black'
            plt.xlabel("Columns")
            plt.ylabel("Rows")
            plt.xlim(-1,MAXCOL)
            plt.ylim(-1,MAXROW)
            plt.savefig('Cat_Simulation.png')
            plt.pause(1)
            plt.clf()

            print("Score {}".format(sum(pointsList)))
        except:
              print("An exception occurred")

    print("Friendly Cats Count {}".format(len(friendlyArray)))
    print("Aggressive Cats Count {}".format(len(aggressiveArray)))

    plotToCSV = np.array(plotData)
    np.savetxt('plotData.csv', plotToCSV, fmt="%s", delimiter=',')

    if(sum(pointsList)>0):
        print("GAME WON")
    elif(sum(pointsList)==0):
        print("GAME DRAW")
    else:
        print("GAME LOSE")

# In[173]:

if __name__ == "__main__":
    main()

# In[ ]:


import json

from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt

from rouge import Rouge
from datasets import load_metric

# Create your views here.

def index(request):
    return render(request, 'main/index.html')

i = 2

def demo(request):
    global i
    i = (i + 1) % 3
    return render(request, f'main/demo{i}.html')

rouge = Rouge()
bertscore_metric = load_metric('bertscore')

@csrf_exempt
def submit(request):
    jsonObject = json.loads(request.body)
    q1_reference = "Why don't you call back later this afternoon?"
    q2_reference = "I never trust those stupid doctors."
    q3_reference = "I was really sad too, but at least I can still listen to their Cds."
    q_reference = [q1_reference, q2_reference, q3_reference]
    rouge_scores = [[0.316, 0.0, 0.095], [0.333, 0, 0], [0.250, 0.095, 0.080]]
    bert_scores = [[0.919, 0.853, 0.847], [0.917, 0.882, 0.871], [0.918, 0.861, 0.861]]

    # Calculate score
    rouge_l_f1 = 0.0
    bertscore_f1 = 0.0
    quiz = jsonObject.get('quiz') -1
    op = int(jsonObject.get('op')) -1
    if op == 3:
        answer = jsonObject.get('answer')
        score = rouge.get_scores(answer, q_reference[quiz])
        rouge_l_f1 = score[0]["rouge-l"]["f"]
        bert_score = bertscore_metric.compute(predictions=[answer], references=[q_reference[quiz]], lang="en")
        bertscore_f1 = bert_score["f1"][0]
    else:
        rouge_l_f1 = rouge_scores[quiz][op]
        bertscore_f1 = bert_scores[quiz][op]

    response = {"rouge_score": round(rouge_l_f1*100), "bert_score": round(bertscore_f1*100)}
    return JsonResponse(response)


# -*-coding: utf-8 -*-
from openerp import api, models
from datetime import date
from dateutil.relativedelta import relativedelta

from openerp.exceptions import Warning

PAS_DE_BULLETIN = 'AUCUN BULLETIN DE PAIE NE CORRESPOND A VOTRE RECHERCHE'

def format_float(value, force_zero=False):
    if value != 0:
        return '{:,.2f}'.format(value).replace(',', ' ')
    else:
        return "" if not force_zero else "0"

class EtatCotisationReport(models.AbstractModel):
    _name = 'report.corpe_paie.etat_cotisation_template'

    @api.multi
    def render_html(self, data=None):
        report_obj = self.env['report']
        report = report_obj._get_report_from_name(
            'corpe_paie.etat_cotisation_template')

        debut = data['debut']
        fin = data['fin']
        date_impression = data['date_impression']
        heure_impression = data['heure_impression']
        categorie_regle_sal = data['categorie_regle_sal']
        categorie_regle_pat = data['categorie_regle_pat']
        regle_sal_assiette = data['regle_sal_assiette']
        all_categories = [categorie_regle_sal, categorie_regle_pat]

        payslip_obj = self.env['hr.payslip']
        bulls = payslip_obj.search([
            ('date_from', '>=', debut),
            ('date_to', '<=', fin)])

        if data['code_centre']:
            bulls = bulls.filtered(
                lambda x: x.employee_id and x.employee_id.centre_rh_id and
                x.employee_id.centre_rh_id.code == data['code_centre'])

        if not bulls:
            raise Warning(PAS_DE_BULLETIN)

        result = []
        totaux = {}
        infos = {}

        infos['date_impression'] = date_impression
        infos['heure_impression'] = heure_impression
        infos['imprime_par'] = self.env.user.login
        infos['debut'] = "%s/%s/%s" % (debut[8:10], debut[5:7], debut[:4])
        infos['fin'] = "%s/%s/%s" % (fin[8:10], fin[5:7], fin[:4])
        if data['code_centre']:
            infos['entete_tableau'] = " " + data['code_centre'] + " CAMLAIT " + data['nom_centre']
        else:
            infos['entete_tableau'] = " CAMLAIT SA"

        totaux_salarial = 0
        totaux_patronal = 0
        totaux_global = 0

        lines_bulls = bulls.mapped('details_by_salary_rule_category').sorted(
            key=lambda r: r.sequence).filtered(
            lambda x: x.category_id.id in all_categories)
        lines_assiette = bulls.mapped('line_ids').filtered(
            lambda x: x.code == regle_sal_assiette)
        all_sequences = lines_bulls.mapped('sequence')
        for sequence in list(set(all_sequences)):
            lines_sequence = lines_bulls.filtered(
                lambda x: x.sequence == sequence)
            nbre_bulls = len(lines_sequence.mapped('slip_id'))
            employes = lines_sequence.mapped('slip_id.employee_id')

            nbre_hommes = len(employes.filtered(
                lambda x: x.gender == 'male'))
            nbre_femmes = len(employes.filtered(
                lambda x: x.gender == 'female'))

            if not lines_sequence:
                continue

            ligne_salarial = lines_sequence.filtered(
                lambda x: x.category_id.id == categorie_regle_sal)
            ligne_patronal = lines_sequence.filtered(
                lambda x: x.category_id.id == categorie_regle_pat)
            lignes_assiettes = lines_assiette.filtered(
                lambda x: x.slip_id.employee_id.id in employes.ids)

            taux_salarial = sum(ligne_salarial.mapped(
                'rate')) / nbre_bulls if nbre_bulls else 0
            taux_patronal = sum(ligne_patronal.mapped(
                'rate')) / nbre_bulls if nbre_bulls else 0
            taux_general = taux_salarial + taux_patronal

            assiette = sum(lignes_assiettes.mapped('total'))
            montant_salarial = sum(ligne_salarial.mapped('total'))
            montant_patronal = sum(ligne_patronal.mapped('total'))
            montant_general = montant_salarial + montant_patronal

            totaux_salarial += montant_salarial
            totaux_patronal += montant_patronal
            totaux_global += montant_general

            line = {}
            line['sequence'] = sequence
            line['rubrique'] = lines_sequence[0].name
            line['taux_sal'] = format_float(taux_salarial)
            line['taux_pat'] = format_float(taux_patronal)
            line['taux_gen'] = format_float(taux_general)
            line['assiette'] = format_float(assiette)
            line['base'] = format_float(sum(ligne_salarial.mapped('amount')))
            line['montant_salarial'] = format_float(montant_salarial)
            line['montant_patronal'] = format_float(montant_patronal)
            line['montant_global'] = format_float(montant_general)
            line['nbre_hommes'] = nbre_hommes
            line['nbre_femmes'] = nbre_femmes
            result.append(line)

        totaux['totaux_salarial'] = format_float(totaux_salarial)
        totaux['totaux_patronal'] = format_float(totaux_patronal)
        totaux['totaux_global'] = format_float(totaux_global)

        datas = {}
        datas['result'] = result
        datas['totaux'] = totaux
        datas['infos'] = infos

        docargs = {
            'doc_ids': self._ids,
            'doc_model': report.model,
            'docs': self,
            'data': datas
        }

        return report_obj.render(
            'corpe_paie.etat_cotisation_template', docargs)


from setuptools import setup, Extension
from setuptools.command.install import install
from codecs import open
import os, os.path, struct, re, platform

import numpy

try:
    from setuptools._distutils import _msvccompiler
    _msvccompiler.PLAT_TO_VCVARS['win-amd64'] = 'amd64'
except:
    pass

if os.environ.get('TOMOTOPY_CPU_ARCH'):
    tomotopy_cpu_arch = os.environ['TOMOTOPY_CPU_ARCH']
else:
    try:
        import platform
        tomotopy_cpu_arch = platform.machine()
    except:
        tomotopy_cpu_arch = 'x86_64'

from sysconfig import get_platform
fd = get_platform().split('-')
if fd[0] == 'macosx':
    if os.environ.get('MACOSX_DEPLOYMENT_TARGET'):
        from distutils import sysconfig
        cfg_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or ''
        if cfg_target.startswith('10.'):
            cfg_target = list(map(int, cfg_target.split('.')))
            cur_target = list(map(int, os.environ['MACOSX_DEPLOYMENT_TARGET'].split('.')))
            target = max(cfg_target, cur_target)
            if target != cur_target:
                print(f"MACOSX_DEPLOYMENT_TARGET={'.'.join(map(str, cur_target))} is not supported. MACOSX_DEPLOYMENT_TARGET={'.'.join(map(str, target))} is used instead.")
            os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(map(str, target))
        fd[1] = os.environ['MACOSX_DEPLOYMENT_TARGET']
    os.environ['_PYTHON_HOST_PLATFORM'] = '-'.join(fd[:-1] + [tomotopy_cpu_arch])

exec(open('tomotopy/_version.py').read())

here = os.path.abspath(os.path.dirname(__file__))

long_description = ''
for line in open(os.path.join(here, 'tomotopy/documentation.rst'), encoding='utf-8'):
    long_description += re.sub(r'^<.+>\s*$', '', line)

sources = []
for f in os.listdir(os.path.join(here, 'src/python')):
    if f.endswith('.cpp') and not f.endswith('py_rt.cpp'): sources.append('src/python/' + f)
for f in os.listdir(os.path.join(here, 'src/TopicModel')):
    if f.endswith('.cpp'): sources.append('src/TopicModel/' + f)
for f in os.listdir(os.path.join(here, 'src/Labeling')):
    if f.endswith('.cpp'): sources.append('src/Labeling/' + f)

largs = []
arch_levels = {'':'', 'sse2':'-msse2', 'avx':'-mavx', 'avx2':'-mavx2 -mfma'}
if platform.system() == 'Windows':
    cargs = ['/O2', '/MT', '/Gy', '/D__SSE2__']
    arch_levels = {'':'', 'sse2':'/arch:SSE2', 'avx':'/arch:AVX', 'avx2':'/arch:AVX2'}
elif platform.system() == 'Darwin':
    cargs = ['-std=c++1y', '-O3', '-fpermissive', '-stdlib=libc++', '-Wno-unused-variable', '-Wno-switch']
    largs += ['-stdlib=libc++']
    if 'many' in os.environ.get('AUDITWHEEL_PLAT', ''): cargs.append('-g0')
    if tomotopy_cpu_arch == 'arm64':
        arch_levels = {'': ''}
        cargs += ['-DTOMOTOPY_ISA=arm64', '-arch', 'arm64']
        largs += ['-arch', 'arm64']
    else:
        if 'many' not in os.environ.get('AUDITWHEEL_PLAT', ''): arch_levels = {'':'-msse2'}
        cargs += ['-arch', 'x86_64']
        largs += ['-arch', 'x86_64']
elif 'many' in os.environ.get('AUDITWHEEL_PLAT', ''):
    cargs = ['-std=c++1y', '-O3', '-fpermissive', '-g0', '-Wno-unused-variable', '-Wno-switch']
    if tomotopy_cpu_arch in ('arm64', 'aarch64'):
        arch_levels = {'': ''}
        cargs += ['-DTOMOTOPY_ISA=arm64']
else:
    cargs = ['-std=c++1y', '-O3', '-fpermissive', '-Wno-unused-variable', '-Wno-switch']
    arch_levels = {'': '-march=native'}

if struct.calcsize('P') < 8: arch_levels = {k:v for k, v in arch_levels.items() if k in ('', 'sse2')}
else: arch_levels = {k:v for k, v in arch_levels.items() if k not in ('sse2',)}

lang_macro = []
if os.environ.get('TOMOTOPY_LANG') == 'kr': lang_macro = [('DOC_KO', '1')]

modules = []
if len(arch_levels) > 1:
    modules.append(Extension('_tomotopy',
        libraries=[],
        include_dirs=['include', numpy.get_include()],
        sources=['src/python/py_rt.cpp'],
        extra_compile_args=cargs, extra_link_args=largs))

for arch, aopt in arch_levels.items():
    if len(arch_levels) > 1:
        module_name = '_tomotopy_' + (arch or 'none')
    else:
        module_name = '_tomotopy'
    modules.append(Extension(module_name,
                    libraries=[],
                    include_dirs=['include', numpy.get_include()],
                    sources=sources,
                    define_macros=[('MODULE_NAME', 'PyInit_' + module_name)] + lang_macro,
                    extra_compile_args=cargs + (aopt.split(' ') if aopt else []), extra_link_args=largs))

setup(
    name='tomotopy',

    version=__version__,

    description='Tomoto, Topic Modeling Tool for Python',
    long_description=long_description,

    url='https://github.com/bab2min/tomotopy',

    author='bab2min',
    author_email='bab2min@gmail.com',

    license='MIT License',

    classifiers=[
        'Development Status :: 3 - Alpha',

        "Intended Audience :: Information Technology",
        "Intended Audience :: Science/Research",
        "Topic :: Software Development :: Libraries",
        "Topic :: Text Processing :: Linguistic",
        "Topic :: Scientific/Engineering :: Information Analysis",

        "License :: OSI Approved :: MIT License",

        'Programming Language :: Python :: 3',
        'Programming Language :: C++',
        "Operating System :: Microsoft :: Windows :: Windows Vista",
        "Operating System :: Microsoft :: Windows :: Windows 7",
        "Operating System :: Microsoft :: Windows :: Windows 8",
        "Operating System :: Microsoft :: Windows :: Windows 8.1",
        "Operating System :: Microsoft :: Windows :: Windows 10",
        "Operating System :: POSIX",
        "Operating System :: MacOS"
    ],
    install_requires=['numpy>=1.11.0'],
    keywords='NLP,Topic Model',

    packages=['tomotopy'],
    include_package_data=True,
    ext_modules=modules
)


'''
from function.rigging.skeleton import replaceTmpJnt as rtj
reload(rtj)
'''
from function.framework.reloadWrapper import reloadWrapper as reloader

from function.rigging.autoRig.base import core
reloader(core)

from function.rigging.autoRig.base import rigTools
reloader( rigTools )

from function.pipeline import logger
reloader(logger)

class utilLogger(logger.MayaLogger):
	LOGGER_NAME = "replaceTmpJnt"

def replaceTmpJnt(			nameSpace = '',
							tmpJnt = (	'tail01_tmpJnt' ,
										'tail02_tmpJnt' ,
										'tail03_tmpJnt' ,
										'tail04_tmpJnt'	)		,
							side = ''							,
							extName = 'bJnt'):

	""" Replace template joint with new ext name

	Args:
		nameSpace: name space if have.
		tmpJnt: The first parameter.
		side: side
		extName = name of last name

	Returns:
		List of the new joint

	"""

	# make raw name
	rawName = []
	for each in tmpJnt:
		if side:
			tmp = each.split('_')[0][:-3]
		else:
			tmp = each.split('_')[0]
		rawName.append(tmp)

	bJnts_list = []

	for num in range(0,len(tmpJnt)):
		tmp = core.Dag( tmpJnt[num] )
		bJnt = rigTools.jointAt( tmp )

		bJnt.name = "{0}{1}{2}_{3}".format(nameSpace,rawName[num],side,extName )
		# bJnt.name = nameSpace + rawName[num] + side + '_' + extName

		bJnts_list.append( bJnt.name  )

		if not  num == 0:
			bJnt.parent( bJnts_list[ num -1] )

	utilLogger.info('End of the replaceTmpJnt function.')
	return bJnts_list


class Node:
    def __init__(self,info,link= None,random = None):
        self.info = info
        self.link = link
        self.random = None

class LinkedList:
    def __init__(self):
        self.head = None
        self.tail = None
        self.current_ptr = None         # maintain a current pointer
        self.size = 0

    def add_item_at_rear(self,item):
        if self.head == None:           # list initially empty ?
            newNode = Node(item)
            self.head = newNode
            self.tail = newNode
            self.size += 1
        else:
            newNode = Node(item)
            self.tail.link = newNode
            self.tail = newNode
            self.size += 1
        return newNode

ll = LinkedList()
n1 = ll.add_item_at_rear(7)
n2 = ll.add_item_at_rear(13)
n3 = ll.add_item_at_rear(11)
n4 = ll.add_item_at_rear(10)
n5 = ll.add_item_at_rear(1)
n1.random = None
n2.random = n1
n3.random = n5
n4.random = n3
n5.random = n1

input_list = [[7,None],[13,0],[11,4],[10,2],[1,0]]

"""-------------- Approach 1 (INEFFICIENT since it requires 2 passes over the given Linked List)-------------"""
class Solution1:
    def Copy_List(self,head):
        curr_ptr = head
        new_ll = LinkedList()
        while curr_ptr != None:
            new_ll.add_item_at_rear(curr_ptr.info)
            curr_ptr = curr_ptr.link
        curr_old = head
        curr_new = new_ll.head
        while curr_old != None:
            curr_new.random = curr_old.random
            curr_old = curr_old.link
            curr_new = curr_new.link
        return new_ll

#s1 = Solution1()
#s1.Copy_List(n1)

"""------------------- Approach 2 from Leetcode Solution (EFFICIENT)-------------------"""
class Solution2:

    def __init__(self):
        self.visited_dict = {}

    def GetClonedNode(self,node):
        if node:
            if node in self.visited_dict:
                return self.visited_dict[node]
            else:
                new_Node = Node(node.info,None,None)
                self.visited_dict[node] = new_Node
                return self.visited_dict[node]
        else:
            return None

    def Copy_List_Approach_2(self,head):
        curr_ptr = head
        if head == None:
            return None
        new_Node = Node(curr_ptr.info,None,None)
        self.visited_dict[curr_ptr] = new_Node
        while curr_ptr != None:
            # Get clones of nodes referenced by next and random pointers
            # If they dont exist then GetClonedNode method inserts those nodes in visited dictionary
            new_Node.random = self.GetClonedNode(curr_ptr.random)
            new_Node.link = self.GetClonedNode(curr_ptr.link)

            # Move the pointers to next node
            curr_ptr = curr_ptr.link
            new_Node = new_Node.link
        return self.visited_dict[head]

    """--------------------- Approach 3 (Self) ---------------------------"""
    """Check if curr_ptr in visited dict, if yes then take the new node corresponding to that curr_ptr
    else create a new node. Then iterate over original list and everytime check if a new node exists
    corresponding to the old node(curr_ptr). If not then create one"""
    def Copy_List_Approach_3(self,head):
        curr_ptr = head

        while curr_ptr != None:
            if curr_ptr not in self.visited_dict:           # If current node does not exist in hashtable
                new_Node = Node(curr_ptr.info,None,None)    # create it and store in hashtable
                self.visited_dict[curr_ptr] = new_Node
            else:
                new_Node = self.visited_dict[curr_ptr]      # Else takt the existing node and make it new_node
            if curr_ptr.link:
                if curr_ptr.link in self.visited_dict:      # check if curr_ptr.link exists in hashtable
                    new_Node.link = self.visited_dict[curr_ptr.link]   # If yes then make it as link of new node
                else:
                    new_link_Node = Node(curr_ptr.link.info,None,None)  # if link of current pointer does not exist in hashtable then create one
                    self.visited_dict[curr_ptr.link] = new_link_Node    # Store the newly created link in hashtable
                    new_Node.link = self.visited_dict[curr_ptr.link]    # Set that link to be the link of new node
            else:
                new_Node.link = None

            if curr_ptr.random:                                         # Repeat the above steps for node corresponding to curr_ptr.random
                if curr_ptr.random in self.visited_dict:
                    new_Node.random = self.visited_dict[curr_ptr.random]
                else:
                    new_random_Node = Node(curr_ptr.random.info,None,None)
                    self.visited_dict[curr_ptr.random] = new_random_Node
                    new_Node.random = self.visited_dict[curr_ptr.random]
            else:
                new_Node.random = None
            curr_ptr = curr_ptr.link
        return self.visited_dict[head]

s2 = Solution2()
s2.Copy_List_Approach_3(n1)


#import libraries
import os
import zipfile
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix

# Define the name of the zip file and the folder where the data files will be extracted
DATA_ZIP = "EyeT.zip"
DATA_DIR = "EyeT"

# Preprocessing the data
# Define a function to preprocess the eye tracker data
def preprocess(data_dir):
    # Get a list of all CSV files in the directory
    csv_files = [os.path.join(data_dir, f) for f in os.listdir(data_dir) if f.endswith(".csv")]
    # Read the eyetracker data from files
    data_files = ['data1.csv', 'data2.csv', 'data3.csv']
    df_list = []
    for file in data_files:
        with open(file, 'r') as f:
          df_list.append(pd.read_csv(f))
    df = pd.concat(df_list)

   # Close the files
    for file in df_list:
     file.close()

    # Read the data from all CSV files into a single DataFrame
    df = pd.concat([pd.read_csv(f) for f in csv_files])

    # Calculate the saccades, pupil dilation, blink rate, gaze duration, and fixation
    # Columns in the data are: timestamp, x, y, pupil_dilation, saccade, blink, fixation
    df['duration'] = df.groupby('fixation')['timestamp'].diff().fillna(0)
    df['fixation_count'] = df.groupby('fixation')['timestamp'].transform('count')
    df['blink_rate'] = df['blink'] / df['duration']
    df['gaze_duration'] = df['duration'] / df['fixation_count']
    df = df[['pupil_dilation', 'saccade', 'blink_rate', 'gaze_duration', 'fixation']]

    return df

# Create the empathy measurement model
# The target variable is 'empathy', and it is based on the other features
X = df.drop('empathy', axis=1)
y = df['empathy']
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Define a function to train the empathy model
def train(df):
    # Extract the relevant features from the DataFrame
    X = df[["saccades", "pupil_dilation", "blink_rate", "gaze_duration", "fixation"]]
    # Extract the empathy score from the DataFrame
    y = df["empathy_score"]

    # Train a linear regression model
    model = LinearRegression()
    model.fit(X, y)

    return model

# Function to evaluate the empathy model
def evaluate(model, test_data):
    # Extract relevant features from the test data
    X_test = test_data[["saccades", "pupil_dilation", "blink_rate", "gaze_duration", "fixation"]]
    # Extract the true empathy score from the EyeT data
    y_test = test_data["empathy_score"]

    # Use the trained model to predict the empathy score for the test data
    y_pred = model.predict(X_test)

    # Calculate the mean squared error of the predictions
    mse = ((y_pred - y_test) ** 2).mean()

    return mse

if __name__ == "__main__":
    # Extract the data files from the zip archive
    with zipfile.ZipFile(DATA_ZIP, "r") as zip_ref:
        zip_ref.extractall(DATA_DIR)

    # Preprocess the data
    df = preprocess(DATA_DIR)

    # Split the data into training and test sets
    train_data = df.sample(frac=0.8, random_state=42)
    test_data = df.drop(train_data.index)

    # Train the model
    model = train(train_data)

    # Evaluate the model on the test data
    mse = evaluate(model, test_data)

    # Print the mean squared error of the predictions
    print(f"Mean squared error: {mse}")

    # Remove the extracted data directory
    os.remove(DATA_ZIP)
    os.rmdir(DATA_DIR)


from collections import defaultdict

#inp = [l.strip() for l in open('dec22ex.txt')]
inp = [l.strip() for l in open('22.txt')]
#print(inp)

m = defaultdict(int)

def coord(x, y): return "{};{}".format(x, y)

CLEAN = 0
WEAKENED = 1
INFECTED = 2
FLAGGED = 3

for y in range(len(inp)):
    for x in range(len(inp[y])):
        if inp[y][x] == "#":
            m[coord(x, y)] = INFECTED

x = y = len(inp) // 2
print(x, y)
UP = [0,-1]; DOWN = [0,1]; LEFT = [-1, 0]; RIGHT = [1, 0]
directions = [UP, RIGHT, DOWN, LEFT]
d = infected = 0

turnmap = { CLEAN: 3, WEAKENED: 0, INFECTED: 1, FLAGGED: 2}
transitionmap = {CLEAN: WEAKENED, WEAKENED: INFECTED, INFECTED: FLAGGED, FLAGGED: CLEAN}

for i in range(10000000):
    if i % 10000 == 0: print(i)
    c = coord(x,y)
    d = (d + turnmap[m[c]]) % 4
    m[c] = transitionmap[m[c]]
    if m[c] == INFECTED:
        infected += 1

    x += directions[d][0]
    y += directions[d][1]

print(infected)

#Answer: 5259


import numpy as np

from tensorflow.keras import models

import fhnwtoys.training as fh

def main(verification=fh.Verification.TRAINING, config=fh.DatasetConfig.ALL):
    # Test labels
    test_labels = np.load(fh.dir_test_dataset / f'{fh.test_labels_name}.npy')

    if verification == fh.Verification.TRAINING:
        model = models.load_model(fh.dir_model) # load from tf-model

        model.summary()

        # load test dataset
        if config == fh.DatasetConfig.ALL:
            test_dataset = fh.Dataset_Generator(fh.test_frames_name, fh.test_labels_name, fh.dir_test_dataset, 1050, 32)
        elif config == fh.DatasetConfig.FULLY_VISIBLE_ONLY:
            test_dataset = fh.Dataset_Generator(fh.test_frames_name, fh.test_labels_name, fh.dir_test_dataset, 394, 32)
        else: # fh.DatasetConfig.PARTIALLY_VISIBLE_ONLY
            raise ValueError('This configuration has no use case!')

        # predict only a single image
        # test_frames, test_labels = test_dataset[0] # first batch
        # test_dataset = test_frames[0][np.newaxis, ...] # first frame
        # test_labels = test_labels[0][np.newaxis, ...] # first label

        predictions = model.predict(x=test_dataset)
    else: # fh.Verification.INFERENCE
        if config == fh.DatasetConfig.ALL:
            predictions = np.load(fh.dir_verification / f'{fh.inference_predictions_name}.npy')
        elif config == fh.DatasetConfig.FULLY_VISIBLE_ONLY:
            predictions = np.load(fh.dir_verification / f'{fh.inference_fvo_predictions_name}.npy')
        else: # fh.DatasetConfig.PARTIALLY_VISIBLE_ONLY
            raise ValueError('This configuration has no use case!')

    # Top K accuracy (overall)
    num_objects = fh.num_objects
    num_frames = len(test_labels)

    top_k = fh.top_k(predictions, test_labels, num_objects)
    print(f'Top K (overall): {top_k}')

    # Top K accuracies with K = 1..5 (per object)
    top_k_objects = np.zeros((num_objects, num_objects), dtype=np.float64)
    for idx in range(num_objects):
        indices = np.asarray(test_labels == idx).nonzero()[0]
        predictions_object = predictions[indices, ...]
        labels_object = test_labels[indices, ...]

        top_k_objects[idx] = fh.top_k(predictions_object, labels_object, num_objects)

    objects = fh.objects

    mmax = 0
    for obj in objects:
        if len(obj) > mmax:
            mmax = len(obj)

    for idx, obj in enumerate(top_k_objects):
        print(f'{objects[idx]}:{" "*(mmax - len(objects[idx]))} Top1: {obj[0]:.3f} / Top2: {obj[1]:.3f} / Top3: {obj[2]:.3f} / Top4: {obj[3]:.3f} / Top5: {obj[4]:.3f}')

if __name__ == '__main__':
    # Settings
    verification = fh.verification
    dataset_config = fh.dataset_config

    main(verification, dataset_config)