import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
from sklearn import metrics, tree
from sklearn.metrics import accuracy_score, classification_report, f1_score, confusion_matrix, precision_score, recall_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.utils import shuffle

def load_data():
    path = "dataset/"
    benign = pd.read_csv(path + "benign_traffic.csv")

    mirai_scan = pd.read_csv(path + "scan1.csv")
    mirai_syn = pd.read_csv(path + "syn.csv")
    mirai_ack = pd.read_csv(path + "ack.csv")
    mirai_udp = pd.read_csv(path + "udp1.csv")
    mirai_udpplain = pd.read_csv(path + "udpplain.csv")
    gafgyt_junk = pd.read_csv(path + "junk.csv")
    gafgyt_scan = pd.read_csv(path + "scan.csv")
    gafgyt_tcp = pd.read_csv(path + "tcp.csv")
    gafgyt_udp = pd.read_csv(path + "udp.csv")

    malicious_gafgyt_list = [gafgyt_junk, gafgyt_scan, gafgyt_tcp, gafgyt_udp]
    malicious_mirai_list = [mirai_scan, mirai_syn, mirai_ack, mirai_udp, mirai_udpplain]
    malicious_gafgyt_concat = pd.concat(malicious_gafgyt_list)
    malicious_mirai_concat = pd.concat(malicious_mirai_list)

    malicious_mirai_concat['Detection'] = "mirai"
    malicious_gafgyt_concat['Detection'] = "gafgyt"
    benign['Detection'] = "benign"

    combine_data = pd.concat([benign, malicious_mirai_concat, malicious_gafgyt_concat], axis=0)
    combine_data = shuffle(combine_data)

    return combine_data

def preprocess_data(comb_data):
    labels = comb_data.iloc[:, -1]
    labels = np.array(labels).flatten()

    no_labels_data = comb_data.iloc[:, :28]

    scale = StandardScaler()
    scale.fit(no_labels_data)
    scale.transform(no_labels_data)

    X_train, X_test, y_train, y_test = train_test_split(no_labels_data, labels, test_size=0.25, shuffle=True)
    return X_train, X_test, y_train, y_test

def DTmodel():
    print('Decision Tree Model:')
    def create_and_train_model():
        decision_tree_classifier = DecisionTreeClassifier()
        return decision_tree_classifier.fit(X_train, np.ravel(y_train))

    def predict_model():
        return decision_tree_model.predict(X_test)

    def evaluate_metrics():
        acc = accuracy_score(y_test, decision_tree_predictions)
        print("\nAccuracy score of decision tree: %.5f" % acc)

        print("\nClassification Report of decision tree:\n",
              classification_report(y_test, decision_tree_predictions, zero_division=0))

    def plot_observation():
        y_test_predict = y_test[:100]
        decision_tree_predict = decision_tree_predictions[:100]
        plt.xlabel('X(Time->)')
        plt.ylabel('0 for Benign Traffic(LOW) and 1 for Malicious Traffic(HIGH)')
        plt.plot(y_test_predict, c='g', label="Benign data")
        plt.plot(decision_tree_predict, c='b', label="Malicious data")
        plt.legend(loc='upper left')
        plt.savefig('Decision Tree.png')

        classes = np.unique(y_test)
        fig, ax = plt.subplots(figsize=(7, 4))
        cm = metrics.confusion_matrix(y_test, decision_tree_predictions, labels=classes)
        sns.heatmap(cm, annot=True, fmt='d', cmap=plt.cm.Blues, cbar=False)
        ax.set(xlabel="Predicted", ylabel="True", title="Confusion matrix")
        ax.set_yticklabels(labels=classes, rotation=0)
        plt.savefig('Confusion_DT.png')

    if __name__ == '__main__':
        comb_data = load_data()

        X_train, X_test, y_train, y_test = preprocess_data(comb_data)

        decision_tree_model = create_and_train_model()

        decision_tree_predictions = predict_model()

        evaluate_metrics()

        plot_observation()

def KNNmodel():
    print('K-Nearest Neighbour Model:')
    def create_and_train_model():
        knn_classifier = KNeighborsClassifier(n_neighbors=5)
        return knn_classifier.fit(X_train, np.ravel(y_train))

    def predict_model():
        return knn_model.predict(X_test)

    def evaluate_metrics():
        acc = accuracy_score(y_test, knn_predictions)
        print("\nAccuracy score of KNN: %.5f" % acc)

        print("\nClassification Report of KNN:\n",
              classification_report(y_test, knn_predictions, zero_division=0))

    def plot_observation():
        y_test_predict = y_test[:100]
        knn_predict = knn_predictions[:100]
        plt.xlabel('X(Time->)')
        plt.ylabel('0 for Benign Traffic(LOW) and 1 for Malicious Traffic(HIGH)')
        plt.plot(y_test_predict, c='g', label="Benign data")
        plt.plot(knn_predict, c='b', label="Malicious data")
        plt.legend(loc='upper left')
        plt.savefig('KNN.png')

        classes = np.unique(y_test)
        fig, ax = plt.subplots(figsize=(7, 4))
        cm = metrics.confusion_matrix(y_test, knn_predictions, labels=classes)
        sns.heatmap(cm, annot=True, fmt='d', cmap=plt.cm.Blues, cbar=False)
        ax.set(xlabel="Predicted", ylabel="True", title="Confusion matrix")
        ax.set_yticklabels(labels=classes, rotation=0)
        plt.savefig('Confusion_KNN.png')

    if __name__ == '__main__':
        comb_data = load_data()

        X_train, X_test, y_train, y_test = preprocess_data(comb_data)

        knn_model = create_and_train_model()

        knn_predictions = predict_model()

        evaluate_metrics()

        plot_observation()

def LRmodel():
    print('Logistic Regression Model:')
    def create_and_train_model():
        lr_classifier = LogisticRegression(solver='lbfgs', max_iter=1000)
        return lr_classifier.fit(X_train, np.ravel(y_train))

    def predict_model():
        return lr_model.predict(X_test)

    def evaluate_metrics():
        acc = accuracy_score(y_test, lr_predictions)
        print("\nAccuracy score of logistic regression: %.5f" % acc)

        print("\nClassification Report of logistic regression:\n",
              classification_report(y_test, lr_predictions, zero_division=0))

    def plot_observation():
        y_test_predict = y_test[:100]
        lr_predict = lr_predictions[:100]
        plt.xlabel('X(Time->)')
        plt.ylabel('0 for Benign Traffic(LOW) and 1 for Malicious Traffic(HIGH)')
        plt.plot(y_test_predict, c='g', label="Benign data")
        plt.plot(lr_predict, c='b', label="Malicious data")
        plt.legend(loc='upper left')
        plt.savefig('Logistic Regression.png')

        classes = np.unique(y_test)
        fig, ax = plt.subplots(figsize=(7, 4))
        cm = metrics.confusion_matrix(y_test, lr_predictions, labels=classes)
        sns.heatmap(cm, annot=True, fmt='d', cmap=plt.cm.Blues, cbar=False)
        ax.set(xlabel="Predicted", ylabel="True", title="Confusion matrix")
        ax.set_yticklabels(labels=classes, rotation=0)
        plt.savefig('Confusion_LR.png')

    if __name__ == '__main__':
        comb_data = load_data()

        X_train, X_test, y_train, y_test = preprocess_data(comb_data)

        lr_model = create_and_train_model()

        lr_predictions = predict_model()

        evaluate_metrics()

        plot_observation()

def RFmodel():
    print('Ramdom Forest Model:')
    def create_and_train_model():
        rf_classifier = RandomForestClassifier()
        return rf_classifier.fit(X_train, np.ravel(y_train))

    def predict_model():
        return rf_model.predict(X_test)

    def evaluate_metrics():
        acc = accuracy_score(y_test, rf_predictions)
        print("\nAccuracy score of random forest: %.5f" % acc)

        print("\nClassification Report of random forest:\n",
              classification_report(y_test, rf_predictions, zero_division=0))

    def plot_observation():
        y_test_predict = y_test[:100]
        rf_predict = rf_predictions[:100]
        plt.xlabel('X(Time->)')
        plt.ylabel('0 for Benign Traffic(LOW) and 1 for Malicious Traffic(HIGH)')
        plt.plot(y_test_predict, c='g', label="Benign data")
        plt.plot(rf_predict, c='b', label="Malicious data")
        plt.legend(loc='upper left')
        plt.savefig('Random Forest.png')

        classes = np.unique(y_test)
        fig, ax = plt.subplots(figsize=(7, 4))
        cm = metrics.confusion_matrix(y_test, rf_predictions, labels=classes)
        sns.heatmap(cm, annot=True, fmt='d', cmap=plt.cm.Blues, cbar=False)
        ax.set(xlabel="Predicted", ylabel="True", title="Confusion matrix")
        ax.set_yticklabels(labels=classes, rotation=0)
        plt.savefig('Confusion_RF.png')

    if __name__ == '__main__':
        comb_data = load_data()

        X_train, X_test, y_train, y_test = preprocess_data(comb_data)

        rf_model = create_and_train_model()

        rf_predictions = predict_model()

        evaluate_metrics()

        plot_observation()

def NBmodel():
    print('Naive Bayes Model:')
    def create_and_train_model():
        nb_classifier = GaussianNB()
        return nb_classifier.fit(X_train, np.ravel(y_train))

    def predict_model():
        return nb_model.predict(X_test)

    def evaluate_metrics():
        acc = accuracy_score(y_test, nb_predictions)
        print("\nAccuracy score of naive bayes: %.5f" % acc)

        print("\nClassification Report of naive bayes:\n",
              classification_report(y_test, nb_predictions, zero_division=0))

    def plot_observation():
        y_test_predict = y_test[:100]
        nb_predict = nb_predictions[:100]
        plt.xlabel('X(Time->)')
        plt.ylabel('0 for Benign Traffic(LOW) and 1 for Malicious Traffic(HIGH)')
        plt.plot(y_test_predict, c='g', label="Benign data")
        plt.plot(nb_predict, c='b', label="Malicious data")
        plt.legend(loc='upper left')
        plt.savefig('Naive Bayes.png')

        classes = np.unique(y_test)
        fig, ax = plt.subplots(figsize=(7, 4))
        cm = metrics.confusion_matrix(y_test, nb_predictions, labels=classes)
        sns.heatmap(cm, annot=True, fmt='d', cmap=plt.cm.Blues, cbar=False)
        ax.set(xlabel="Predicted", ylabel="True", title="Confusion matrix")
        ax.set_yticklabels(labels=classes, rotation=0)
        plt.savefig('Confusion_NB.png')

    if __name__ == '__main__':
        comb_data = load_data()

        X_train, X_test, y_train, y_test = preprocess_data(comb_data)

        nb_model = create_and_train_model()

        nb_predictions = predict_model()

        evaluate_metrics()

        plot_observation()

def MenuSet():
    print("Detection of IOT Botnet using Machine Learning\n")
    print('1. Decision Tree Model')
    print('2. K-Nearest Neighbour Model')
    print('3. Logistic Regression Model')
    print('4. Random Forest Model')
    print('5. Naive Bayes Model')

    try:
        userInput = int(input("\nSelect An Above Option: "))

    except ValueError:
        exit("\nThat's Not a Number!!")

    else:
        print("\n")

    if (userInput == 1):
        DTmodel()
    elif (userInput == 2):
        KNNmodel()
    elif (userInput == 3):
        LRmodel()
    elif (userInput == 4):
        RFmodel()
    elif (userInput == 5):
        NBmodel()
    else:
        print("Enter Correct Choice. . . ")

MenuSet()


from __future__ import print_function
import caffe
import numpy as np
from caffe import layers as L, params as P, to_proto
from caffe.proto import caffe_pb2

class MinecraftNet:

    def __init__(self):
        #self.train_net, self.test_net = self.make_nets()
        caffe.set_mode_cpu()
        self.solver = caffe.SGDSolver('minecraft_solver.prototxt')
        #self.default_data_init()
        #print (self.solver.net.blobs['data'].shape[0])
        #print([(k, v.data.shape) for k, v in self.solver.net.blobs.items()])

    def default_data_init(self):
        inp = np.ones((32, 1, 84, 84), dtype=np.float32)
        lab = np.ones((32,), dtype=np.float32)
        self.set_input_data(inp, lab)

    def load_model(self, path_to_model):
        #print ("loading model: ", path_to_model)
        self.solver.net.copy_from(path_to_model)

    def train(self, itrs):
        print("BEFORE STEP DATA:", self.solver.net.blobs['data'].data[...])
        print("BEFORE STEP LABELS:", self.solver.net.blobs['label'].data[...])

        self.solver.step(itrs)
        print("DONE")
        print("AFTER STEP:", self.solver.net.blobs['label'].data[...])

    def forwardBACKUP(self, data):
        data = np.array(data)
        print ("data1: ", data.shape)
        data = data.reshape((84, 84))
        print ("data2: ", data.shape)
        data_input = data[np.newaxis, np.newaxis, :]
        print ("data input shape", data_input.shape)
        self.solver.test_nets[0].blobs['data'].data[...] = data_input
        # out = self.solver.net.forward()
        out = self.solver.test_nets[0].forward()
        return out
        #output[it] = solver.test_nets[0].blobs['ip2'].data[:8]

    def forwardbackup2(self, data):
        data = np.array(data)
        data = data.reshape((84,84))
        self.solver.net.blobs['data'].data[...] = data

        out = self.solver.net.forward()
        #print("RESULT:", out)
        just_array = self.solver.net.blobs['ip2'].data[...][0]  # HACK
        print(just_array)
        return just_array

    def forward(self, data):
        print("FORWARD DATA:", data)
        self.set_input_data(data)
        out = self.solver.net.forward()
        forward_input = self.solver.net.blobs['data'].data[...]
        print("FORWARD INPUT:", forward_input)
        output_array = self.solver.net.blobs['final_output'].data[...][0]  # HACK
        return output_array

        #out = self.solver.test_nets[0].forward()
        #print("RESULT:", out)
        #just_array = self.solver.test_nets[0].blobs['final_output'].data[...][0]  # HACK
        #print("FORWARD OUTPUT:", just_array)
        #return just_array

    def get_combined_array(self, orig_input, orig_labels):
        # each orig_input[i].toCNNInput should already be a 1-D vector of length 7056
        inputs = []
        for i in range(len(orig_input)):
            curr_input = np.array(orig_input[i].toCNNInput(), dtype=np.float32)
            curr_input *= (1/255.)  # Scale separately so labels aren't scaled in Caffe
            curr_input = np.append(curr_input, orig_labels[i])
            inputs.append(curr_input)

        combined_array = np.array(inputs, dtype=np.float32)
        input_array = combined_array[:, np.newaxis, np.newaxis, :]
        input_array = np.array(input_array, dtype=np.float32)

        print("COMBINED SHAPE:", input_array.shape)
        return input_array

    def set_input_data(self, inputs, labels=None):

        # If labels are provided, then assume inputs is 32 input patterns
        if labels != [] and labels != None:
            print("SETTING INPUT DATA *WITH* LABELS")
            # We have to make fake labels since the real labels
            # are stuck on the end of the inputs
            fake_labels = np.array([[[[1]]]]*32, dtype=np.float32)
            print("FAKE:", fake_labels.shape)

            # Append the labels on each of the input vectors
            # Each pattern is size (1, 1, 1, 7120)  which is 84*84+64
            input_array = self.get_combined_array(inputs, labels)
            # input_array should be (32, 1, 1, 7120)

            print("SETTING DATA:", input_array, fake_labels)

            self.solver.net.set_input_arrays(input_array, fake_labels)
            self.solver.test_nets[0].set_input_arrays(input_array, fake_labels)

            print("SET DATA:", self.solver.net.blobs['data'].data[...])
            print("SET LABELS:", self.solver.net.blobs['label'].data[...])

        else:
            print("SETTING INPUT DATA *WITHOUT* LABELS")

            # No labels provided, so caller just wants to forward
            # something through the network.
            # Make some a fake label on the end of the input
            # so Caffe doesn't complain
            # We have to make fake labels since the real labels
            # are stuck on the end of the inputs
            fake_labels = np.array([[[[1]]]], dtype=np.float32)

            unused_labels = np.array([[[[1]*64]]], dtype=np.float32)
            input_array = np.array(inputs)
            input_array *= (1/255.)  # Scale separately so labels aren't scaled in Caffe
            input_array = np.append(input_array, unused_labels)
            input_array = input_array[np.newaxis, np.newaxis, np.newaxis, :]

            # input_array should be (1, 1, 1, 7120)
            print(input_array)
            print(fake_labels)
            print(input_array.shape)
            print(fake_labels.shape)

            self.solver.net.set_input_arrays(input_array, fake_labels)
            self.solver.test_nets[0].set_input_arrays(input_array, fake_labels)

    # helper function for common structures
    def conv_relu(self, bottom, ks, nout, stride=1, pad=0, group=1):
        conv = L.Convolution(bottom, kernel_size=ks, stride=stride,
                                    num_output=nout, pad=pad, group=group)
        return conv, L.ReLU(conv, in_place=True)

    def ip_relu(self, bottom, nout):
        ip = L.InnerProduct(bottom, num_output=nout)
        return ip, L.ReLU(ip, in_place=True)

    def max_pool(self, bottom, ks, stride=1):
        return L.Pooling(bottom, pool=P.Pooling.MAX, kernel_size=ks, stride=stride)

    def caffenet(self, lmdb, batch_size=32, include_acc=False):
        print ("building net")

        data, label = L.Data(source=lmdb, backend=P.Data.LMDB, batch_size=batch_size, ntops=2,
                             transform_param=dict(crop_size=84, mirror=True))

        # the net itself
        conv1, relu1 = self.conv_relu(data, 8, 32, stride=4)
        conv2, relu2 = self.conv_relu(relu1, 4, 16, stride=2)
        ip, relu3 = self.ip_relu(relu2, 256)
        ip2 = L.InnerProduct(relu3, num_output=64)
        loss = L.SoftmaxWithLoss(ip2, label)

        if include_acc:
            acc = L.Accuracy(ip2, label)
            return to_proto(loss, acc)
        else:
            return to_proto(loss)

    def make_nets(self):
        with open('train.prototxt', 'w') as f:
            f.write(str(self.caffenet('train_lmdb')))

        train_net = caffe.Net("train.prototxt", caffe.TRAIN)

        with open('test.prototxt', 'w') as f:
            f.write(str(self.caffenet('test_lmdb', batch_size=32, include_acc=True)))

        test_net = caffe.Net("test.prototxt", caffe.TEST)

        return train_net, test_net

if __name__ == '__main__':
    mnet = MinecraftNet()
    #mnet.load_model('snapshots/minecraft/snapshots_iter_5.caffemodel')
    #mnet.train(5)


# The network design is based on Tinghui Zhou & Clement Godard's works:
# https://github.com/tinghuiz/SfMLearner/blob/master/nets.py
# https://github.com/mrharicot/monodepth/blob/master/monodepth_model.py
import tensorflow as tf
import tensorflow.contrib.slim as slim
import numpy as np
from models.geonet.inception_v4 import inception_v4_base

# Range of disparity/inverse depth values
DISP_SCALING_RESNET50 = 5
DISP_SCALING_VGG = 10
FLOW_SCALING = 0.1

def disp_net(opt, dispnet_inputs):
    is_training = opt.mode == 'train_rigid'
    if opt.feat_net == 'vgg':
        return build_vgg(dispnet_inputs, get_disp_vgg, is_training, 'depth_net')
    elif opt.feat_net == 'resnet50':
        return build_resnet50(dispnet_inputs, get_disp_resnet50, is_training, 'depth_net')
    elif opt.feat_net == 'inceptionv4':
        return build_inceptionv4(dispnet_inputs, get_disp_resnet50, is_training, 'depth_net')

def flow_net(opt, flownet_inputs):
    is_training = opt.mode == 'train_flow'
    return build_resnet50(flownet_inputs, get_flow, is_training, 'flow_net')

def pose_net(opt, posenet_inputs):
    is_training = opt.mode == 'train_rigid'
    batch_norm_params = {'is_training': is_training}
    with tf.variable_scope('pose_net') as sc:
        with slim.arg_scope([slim.conv2d],
                            normalizer_fn=slim.batch_norm,
                            normalizer_params=batch_norm_params,
                            weights_regularizer=slim.l2_regularizer(0.0001),
                            activation_fn=tf.nn.relu):
            conv1  = slim.conv2d(posenet_inputs, 16,  7, 2)
            conv2  = slim.conv2d(conv1, 32,  5, 2)
            conv3  = slim.conv2d(conv2, 64,  3, 2)
            conv4  = slim.conv2d(conv3, 128, 3, 2)
            conv5  = slim.conv2d(conv4, 256, 3, 2)
            conv6  = slim.conv2d(conv5, 256, 3, 2)
            conv7  = slim.conv2d(conv6, 256, 3, 2)
            pose_pred = slim.conv2d(conv7, 6*opt.num_source, 1, 1,
                                    normalizer_fn=None, activation_fn=None)
            pose_avg = tf.reduce_mean(pose_pred, [1, 2])
            pose_final = 0.01 * tf.reshape(pose_avg, [-1, opt.num_source, 6])
            return pose_final

def pose_net_inceptionv4(opt, posenet_inputs):
    with tf.variable_scope('pose_net') as sc:
        net, endpoints = inception_v4_base(posenet_inputs)
        print("==========build posenet by inception v4")
        pose_pred = slim.conv2d(net, 6 * opt.num_source, 1, 1,
                                normalizer_fn=None, activation_fn=None)
        pose_avg = tf.reduce_mean(pose_pred, [1, 2])
        pose_final = 0.01 * tf.reshape(pose_avg, [-1, opt.num_source, 6])
        return pose_final

def build_vgg(inputs, get_pred, is_training, var_scope):
    batch_norm_params = {'is_training': is_training}
    H = inputs.get_shape()[1].value
    W = inputs.get_shape()[2].value
    with tf.variable_scope(var_scope) as sc:
        with slim.arg_scope([slim.conv2d, slim.conv2d_transpose],
                            normalizer_fn=slim.batch_norm,
                            normalizer_params=batch_norm_params,
                            weights_regularizer=slim.l2_regularizer(0.0001),
                            activation_fn=tf.nn.relu):
            # ENCODING
            conv1  = slim.conv2d(inputs, 32,  7, 2)
            conv1b = slim.conv2d(conv1,  32,  7, 1)
            conv2  = slim.conv2d(conv1b, 64,  5, 2)
            conv2b = slim.conv2d(conv2,  64,  5, 1)
            conv3  = slim.conv2d(conv2b, 128, 3, 2)
            conv3b = slim.conv2d(conv3,  128, 3, 1)
            conv4  = slim.conv2d(conv3b, 256, 3, 2)
            conv4b = slim.conv2d(conv4,  256, 3, 1)
            conv5  = slim.conv2d(conv4b, 512, 3, 2)
            conv5b = slim.conv2d(conv5,  512, 3, 1)
            conv6  = slim.conv2d(conv5b, 512, 3, 2)
            conv6b = slim.conv2d(conv6,  512, 3, 1)
            # revise from GeoNet: to upconv only 6 levels: stride=1
            conv7  = slim.conv2d(conv6b, 512, 3, 1)
            conv7b = slim.conv2d(conv7,  512, 3, 1)

            features = [conv1b, conv2b, conv3b, conv4b, conv5b, conv7b]
            return make_scaled_depth_preds(features, get_pred)

def build_resnet50(inputs, get_pred, is_training, var_scope):
    batch_norm_params = {'is_training': is_training}
    with tf.variable_scope(var_scope) as sc:
        with slim.arg_scope([slim.conv2d, slim.conv2d_transpose],
                            normalizer_fn=slim.batch_norm,
                            normalizer_params=batch_norm_params,
                            weights_regularizer=slim.l2_regularizer(0.0001),
                            activation_fn=tf.nn.relu):
            conv1 = conv(inputs, 64, 7, 2) # H/2  -   64D
            pool1 = maxpool(conv1,           3) # H/4  -   64D
            conv2 = resblock(pool1,      64, 3) # H/8  -  256D
            conv3 = resblock(conv2,     128, 4) # H/16 -  512D
            conv4 = resblock(conv3,     256, 6) # H/32 - 1024D
            conv5 = resblock(conv4,     512, 3) # H/64 - 2048D
            features = [conv1, pool1, conv2, conv3, conv4, conv5]
            for i, feat in enumerate(features):
                print("``````````resnet50 features:", i, feat.get_shape())

            return make_scaled_depth_preds(features, get_pred)

def build_inceptionv4(inputs, get_pred, is_training, var_scope):
    batch_norm_params = {'is_training': is_training}
    with tf.variable_scope(var_scope) as sc:
        net, endpoints = inception_v4_base(inputs)
        features = list()
        features.append(endpoints["Conv2d_2b_3x3"])
        features.append(endpoints["Mixed_3a"])
        features.append(endpoints["Mixed_4a"])
        features.append(endpoints["Mixed_5e"])
        features.append(endpoints["Mixed_6h"])
        features.append(endpoints["Mixed_7d"])
        for i, feat in enumerate(features):
            print("``````````inception v4 features:", i, feat.get_shape())

        with slim.arg_scope([slim.conv2d, slim.conv2d_transpose],
                            normalizer_fn=slim.batch_norm,
                            normalizer_params=batch_norm_params,
                            weights_regularizer=slim.l2_regularizer(0.0001),
                            activation_fn=tf.nn.relu):
            return make_scaled_depth_preds(features, get_pred)

def make_scaled_depth_preds(features, get_pred):
    # DECODING
    upconv6 = upconv(features[5], 512, 3, 2)  # H/32
    upconv6 = resize_like(upconv6, features[4])
    concat6 = tf.concat([upconv6, features[4]], 3)
    iconv6 = conv(concat6, 512, 3, 1)

    upconv5 = upconv(iconv6, 256, 3, 2)  # H/16
    upconv5 = resize_like(upconv5, features[3])
    concat5 = tf.concat([upconv5, features[3]], 3)
    iconv5 = conv(concat5, 256, 3, 1)

    upconv4 = upconv(iconv5, 128, 3, 2)  # H/8
    upconv4 = resize_like(upconv4, features[2])
    concat4 = tf.concat([upconv4, features[2]], 3)
    iconv4 = conv(concat4, 128, 3, 1)
    pred4 = get_pred(iconv4)
    upred4 = upsample_nn(pred4, 2)

    upconv3 = upconv(iconv4, 64, 3, 2)  # H/4
    concat3 = tf.concat([upconv3, features[1], upred4], 3)
    iconv3 = conv(concat3, 64, 3, 1)
    pred3 = get_pred(iconv3)
    upred3 = upsample_nn(pred3, 2)

    upconv2 = upconv(iconv3, 32, 3, 2)  # H/2
    concat2 = tf.concat([upconv2, features[0], upred3], 3)
    iconv2 = conv(concat2, 32, 3, 1)
    pred2 = get_pred(iconv2)
    upred2 = upsample_nn(pred2, 2)

    upconv1 = upconv(iconv2, 16, 3, 2)  # H
    concat1 = tf.concat([upconv1, upred2], 3)
    iconv1 = conv(concat1, 16, 3, 1)
    pred1 = get_pred(iconv1)

    return [pred1, pred2, pred3, pred4]

def conv(x, num_out_layers, kernel_size, stride, activation_fn=tf.nn.relu, normalizer_fn=slim.batch_norm):
    p = np.floor((kernel_size - 1) / 2).astype(np.int32)
    p_x = tf.pad(x, [[0, 0], [p, p], [p, p], [0, 0]])
    return slim.conv2d(p_x, num_out_layers, kernel_size, stride, 'VALID', activation_fn=activation_fn, normalizer_fn=normalizer_fn)

def maxpool(x, kernel_size):
    p = np.floor((kernel_size - 1) / 2).astype(np.int32)
    p_x = tf.pad(x, [[0, 0], [p, p], [p, p], [0, 0]])
    return slim.max_pool2d(p_x, kernel_size)

def get_disp_vgg(x):
    disp = DISP_SCALING_VGG * slim.conv2d(x, 1, 3, 1, activation_fn=tf.nn.sigmoid, normalizer_fn=None) + 0.01
    return disp

def get_disp_resnet50(x):
    disp = DISP_SCALING_RESNET50 * conv(x, 1, 3, 1, activation_fn=tf.nn.sigmoid, normalizer_fn=None) + 0.01
    return disp

def get_flow(x):
    # Output flow value is normalized by image height/width
    flow = FLOW_SCALING * slim.conv2d(x, 2, 3, 1, activation_fn=None, normalizer_fn=None)
    return flow

def resize_like(inputs, ref):
    iH, iW = inputs.get_shape()[1], inputs.get_shape()[2]
    rH, rW = ref.get_shape()[1], ref.get_shape()[2]
    if iH == rH and iW == rW:
        return inputs
    return tf.image.resize_nearest_neighbor(inputs, [rH.value, rW.value])

def upsample_nn(x, ratio):
    h = x.get_shape()[1].value
    w = x.get_shape()[2].value
    return tf.image.resize_nearest_neighbor(x, [h * ratio, w * ratio])

def upconv(x, num_out_layers, kernel_size, scale):
    upsample = upsample_nn(x, scale)
    cnv = conv(upsample, num_out_layers, kernel_size, 1)
    return cnv

def resconv(x, num_layers, stride):
    # Actually here exists a bug: tf.shape(x)[3] != num_layers is always true,
    # but we preserve it here for consistency with Godard's implementation.
    do_proj = tf.shape(x)[3] != num_layers or stride == 2
    shortcut = []
    conv1 = conv(x,         num_layers, 1, 1)
    conv2 = conv(conv1,     num_layers, 3, stride)
    conv3 = conv(conv2, 4 * num_layers, 1, 1, None)
    if do_proj:
        shortcut = conv(x, 4 * num_layers, 1, stride, None)
    else:
        shortcut = x
    return tf.nn.relu(conv3 + shortcut)

def resblock(x, num_layers, num_blocks):
    out = x
    for i in range(num_blocks - 1):
        out = resconv(out, num_layers, 1)
    out = resconv(out, num_layers, 2)
    return out


import unittest

from spn.algorithms.Inference import likelihood, log_likelihood
from spn.structure.Base import Context
from spn.structure.StatisticalTypes import MetaType
from spn.structure.leaves.histogram.Histograms import create_histogram_leaf
from spn.structure.leaves.histogram.Inference import add_histogram_inference_support
from spn.structure.leaves.parametric.Parametric import *
import numpy as np

class TestParametric(unittest.TestCase):
    def setUp(self):
        add_histogram_inference_support()

    def test_Histogram_discrete_inference(self):
        data = np.array([1, 1, 2, 3, 3, 3]).reshape(-1, 1)
        ds_context = Context([MetaType.DISCRETE])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=False)
        prob = np.exp(log_likelihood(hist, data))

        self.assertAlmostEqual(float(prob[0]), 2 / 6)
        self.assertAlmostEqual(float(prob[1]), 2 / 6)
        self.assertAlmostEqual(float(prob[2]), 1 / 6)
        self.assertAlmostEqual(float(prob[3]), 3 / 6)
        self.assertAlmostEqual(float(prob[4]), 3 / 6)
        self.assertAlmostEqual(float(prob[5]), 3 / 6)

        data = np.array([1, 1, 2, 3, 3, 3]).reshape(-1, 1)
        ds_context = Context([MetaType.DISCRETE])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=True)
        # print(np.var(data.shape[0]))
        prob = np.exp(log_likelihood(hist, data))
        self.assertAlmostEqual(float(prob[0]), 3 / 9)
        self.assertAlmostEqual(float(prob[1]), 3 / 9)
        self.assertAlmostEqual(float(prob[2]), 2 / 9)
        self.assertAlmostEqual(float(prob[3]), 4 / 9)
        self.assertAlmostEqual(float(prob[4]), 4 / 9)
        self.assertAlmostEqual(float(prob[5]), 4 / 9)

    def test_spike(self):
        np.random.seed(17)
        data = np.random.normal(10, 0.01, size=200).tolist() + np.random.normal(30, 10, size=200).tolist()
        data = np.array(data).reshape((-1, 1))
        ds_context = Context([MetaType.REAL])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=False, hist_source="kde")
        x = np.linspace(0, 60, 1000).tolist() + data[:, 0].tolist()
        x = np.sort(x)
        from scipy.stats import norm

        y = 0.5 * norm.pdf(x, 10, 0.01) + 0.5 * norm.pdf(x, 30, 10)
        ye = likelihood(hist, x.reshape((-1, 1)))
        error = np.sum(np.abs(ye[:, 0] - y))
        self.assertLessEqual(error, 900)
        # print(error)

        # import matplotlib.pyplot as plt
        # fig, ax = plt.subplots()
        # ax.plot(x, y, color="r", label="real", linestyle='--', dashes=(5, 1))
        # ax.plot(x, ye, color="b", label="estimated", linestyle='--', dashes=(5, 1))
        # plt.legend()
        # plt.show()

    def test_mixture_gaussians(self):
        np.random.seed(17)
        data = np.random.normal(10, 1, size=200).tolist() + np.random.normal(30, 1, size=200).tolist()
        data = np.array(data).reshape((-1, 1))
        ds_context = Context([MetaType.REAL])
        ds_context.add_domains(data)
        hist = create_histogram_leaf(data, ds_context, [0], alpha=False, hist_source="kde")
        x = np.linspace(0, 60, 1000).tolist() + data[:, 0].tolist()
        x = np.sort(x)
        from scipy.stats import norm

        y = 0.5 * norm.pdf(x, 10, 1) + 0.5 * norm.pdf(x, 30, 1)
        ye = likelihood(hist, x.reshape((-1, 1)))
        error = np.sum(np.abs(ye[:, 0] - y))
        # print(error)
        self.assertLessEqual(error, 7)

    def test_valid_histogram(self):
        np.random.seed(17)
        data = [1] + [5] * 20 + [7] + [10] * 50 + [20] + [30] * 10
        data = np.array(data).reshape((-1, 1))
        ds_context = Context([MetaType.REAL])
        ds_context.add_domains(data)

        hist = create_histogram_leaf(data, ds_context, [0], alpha=False, hist_source="kde")
        self.assertGreater(len(hist.bin_repr_points), 1)

if __name__ == "__main__":
    unittest.main()


'Use <m> or <message> to retrieve the data transmitted by the scanner.'
'Use <t> or <terminal> to retrieve the running terminal browse record.'
'Put the returned action code in <act>, as a single character.'
'Put the returned result or message in <res>, as a list of strings.'
'Put the returned value in <val>, as an integer'

from odoo.addons.aop_interface.controllers.api_interface import ApiInterface

api = ApiInterface()

data = []

vin_code = terminal.get_tmp_value('vin_code', False)
picking_type_name = terminal.get_tmp_value('picking_type_name', False)
warehouse_code = terminal.get_tmp_value('warehouse_code', False)
warehouse_name = terminal.get_tmp_value('warehouse_name', False)
brand_name = terminal.get_tmp_value('brand_name', False)
product_name = terminal.get_tmp_value('product_name', False)
from_location_name = terminal.get_tmp_value('from_location_name', False)

# lines = [
#     "{0}={1}".format('仓库', warehouse_name),
#     "{0}={1}".format('操作', picking_type_name),
#     "{0}={1}".format('VIN码', vin_code),
#     "{0}={1}".format('品牌', brand_name),
#     "{0}={1}".format('车型', product_name),
#     "{0}={1}".format('车辆来自', from_location_name),
#   ]

# for line in lines:
#     res.append(line)

act = 'M'
res = [
    '|提交结果页:',
    '',
    '提交的信息是:',
    '',

]

params = terminal.get_tmp_value('into_warehouse_params', False)

if params:
  #
  for key in sorted(params.keys()):
      val = params.get(key, '')
      res.append("{0},{1},{2}".format(key, val.get('brand_name', ''), val.get('product_name', '')))

      # 准备提交给接口的数据
      tml = {'brand_model_name': '', 'product_color': '', 'product_model': '', 'state_flag': 'T',
           'vin': '', 'warehouse_code': warehouse_code, 'warehouse_name': warehouse_name}

      tml['vin'] = key
      tml['brand_model_name'] = val.get('from_warehouse_code', False)
      tml['product_model'] = val.get('product_model', False)

      # 如果有'入库'步骤的任务，需要把task_id传到接口。仅仅接车操作，task_id不会有值
      task_id = val.get('task_id', False)
      if task_id:
        tml['task_id'] = task_id

      data.append(tml)

res.append('')
res.append('')

# 打印接口数据
# res.append(str(data))
response = api._done_picking(data)
# 打印返回数据
# res.append(str(response))

val = terminal.get_tmp_value('warehouse_id', False)

# terminal.clean_tmp_values(['vin_code', 'product_name', 'brand_name', 'from_location_id', 'from_location_name', 'task_id', 'into_warehouse_params'])

result = '失败'
if all(x.state == 'done' for x in response):
  result = '成功'
  res.append('提交结果:{0}'.format(result))

else:
  act = 'E'
  res = [
      '',
      '',
  ]
  val = True

  res.append('提交结果:{0}'.format(result))


import pygame
import standard_colors

class Game:

    def __init__(self):
        pygame.init()
        pygame.display.set_caption('Pygame window')
        dimensions = 640, 360
        self.application_surface = pygame.display.set_mode(dimensions)
        self.background_color = standard_colors.YELLOW

        self.running = True
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        self.running = False
                    elif event.key == pygame.K_r:
                        self.background_color = standard_colors.RED
                    elif event.key == pygame.K_g:
                        self.background_color = standard_colors.GREEN

            self.application_surface.fill(self.background_color)
            pygame.display.update()

if __name__ == "__main__":
    Game()


# 📌Создайте класс Архив, который хранит пару свойств. Например, число и строку.
# 📌При нового экземпляра класса, старые данные из ранее созданных экземпляров
# сохраняются в пару списковархивов
# 📌list-архивы также являются свойствами экземпляра

class Archive:
    """Строка документации для класса Архив, которая хранит пару свойств,
            а также Архив предыдущих значений"""

    _instance = None
    _archive = []

    def __new__(cls, name: str, age: int):
        instance = super().__new__(cls)
        if cls._instance:
            cls._archive.append(cls._instance)
        cls._instance = instance
        instance.archive = cls._archive.copy()
        return cls._instance

    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

    def __repr__(self):
        """дандер-метод __repr__ - печать объекта Archive"""
        return f'{self.name} {self.age}'

def main():
    player1 = Archive('STONE', 39)
    player2 = Archive('Karina', 18)
    player3 = Archive('Misha', 25)
    player4 = Archive('Dima', 38)
    print(player1)
    print(player1.archive)
    print(player2)
    print(player2.archive)
    print(player3)
    print(player3.archive)
    print(player4)
    print(player4.archive)

    # Вывод документации
    print('Документация класса MyString')
    print(Archive.__doc__)
    print('Документация объекта класса MyString')
    print(player1.__doc__)
    print('Документация метода объекта __new__ класса MyString')
    print(player1.__repr__.__doc__)

if __name__ == '__main__':
    main()


# We need word parsers(tokenizer) to tokenize the sentences that contains ASCII characters(such as celsius)
# in fact, only 3 questions has ASCII char that need to take care of.
# e.g: 'The human body has an average, normal temperature of about 98.6\xc2\xb0F'
import numpy as np
import re
from NLPUtils import AsciiConvertor, SpecialWords

class WordParser(object):
    '''
    WordParser - base class for parsers
    '''
    def __init__(self, min_word_length=2, max_word_length=25, ascii_conversion=True):
        """
        :param min_word_length: a word is treat as a word if it is at least 2 char long
        :param max_word_length: a word is treat as a word if it is at most 25 char long
        :param ascii_conversion: whether we first transfer all char to utf-8
        :return:
        """
        self.min_word_length = min_word_length
        self.max_word_length = max_word_length
        self.ascii_conversion = ascii_conversion
    def filter_words_by_length(self, words):
        return [word for word in words if len(word) >= self.min_word_length and len(word) <= self.max_word_length]
    def convert_ascii(self, text):
        if self.ascii_conversion:
            return AsciiConvertor.convert(text)
        return text
    def parse(self, text):
        # this is the key function to be implemented by subclass
        return text

class SimpleWordParser(WordParser):
    '''
    SimpleWordParser - supports tuples
    e.g parser = SimpleWordParser(tuples = [1,2])
    parser.parse('today is a beautiful sunny day') ->
    ['today',
     'beautiful',
     'sunny',
     'day',
     'today beautiful',
     'beautiful sunny',
     'sunny day']
    '''
    def __init__(self, stop_regexp = '[\-\+\*_\.\:\,\;\?\!\'\"\`\\\/\)\]\}]+ | [\*\:\;\'\"\`\(\[\{]+|[ \t\r\n\?]',
                 min_word_length = 2, word_func = None, tolower = True, ascii_conversion = True,
                 ignore_special_words = True, split_words_regexp = None, tuples = [1]):
        """
        :param stop_regexp: word tokenizer
        :param min_word_length: a word is treat as a word if it is at least 2 char long
        :param word_func: the function applied to each word, e.g stemmer function
        :param tolower: whether we first lower all the words, this is always set True
        :param ascii_conversion: whether we convert all char to utf-8, always set True, refer to NLPUtils.Ascii.Converter
        :param ignore_special_words: whether we skip all special words, refer to NLPUtils.SpecialWords
        :param split_words_regexp: within each word, if you still wants to split, mostly set to None
        :param tuples:  if [1], we get single words
                        if [1,2], we get single words + 2-gram
                        ...
        :return:
        """
        self.stop_regexp = re.compile(stop_regexp)
        self.word_func = word_func
        self.tolower = tolower
        self.ignore_special_words = ignore_special_words
        self.split_words_regexp = None if split_words_regexp is None else re.compile(split_words_regexp)
        self.tuples = tuples
        assert set([1,2,3,4]).issuperset(self.tuples)
        WordParser.__init__(self, min_word_length=min_word_length, ascii_conversion=ascii_conversion)

    def parse(self, text, calc_weights=False):
        if self.tolower:
            text = text.lower()
        text = ' ' + text.strip() + ' ' # add ' ' at the beginning and at the end so that, eg, a '.' at the end of the text will be removed, and "'''" at the beginning will be removed
        text = self.convert_ascii(text)
        words = re.split(self.stop_regexp, text)
        if self.split_words_regexp is not None:
            swords = []
            for word in words:
                w_words = re.split(self.split_words_regexp, word)
                if len(w_words) == 1:
                    swords.append(w_words[0])
                else:
                    if np.all([len(w)>=self.min_word_length for w in w_words]):
                        swords += w_words
                    else:
                        swords.append(word) # don't split - some parts are too short
            words = swords
        if self.ignore_special_words:
            words = SpecialWords.filter(words)
        if self.word_func is not None:
            fwords = []
            for word in words:
                try:
                    fword = str(self.word_func(word))
                except UnicodeDecodeError:
                    fword = word
                fwords.append(fword)
            words = fwords
        words = self.filter_words_by_length(words)
        ret_words = []
        if 1 in self.tuples:
            ret_words += words
        if 2 in self.tuples:
            ret_words += ['%s %s'%(words[i],words[i+1]) for i in range(len(words)-1)]
        if 3 in self.tuples:
            ret_words += ['%s %s %s'%(words[i],words[i+1],words[i+2]) for i in range(len(words)-2)]
            if 2 in self.tuples:
                ret_words += ['%s %s'%(words[i],words[i+2]) for i in range(len(words)-2)]
        if 4 in self.tuples:
            ret_words += ['%s %s %s %s'%(words[i],words[i+1],words[i+2],words[i+3]) for i in range(len(words)-3)]
            if 3 in self.tuples:
                ret_words += ['%s %s %s'%(words[i],words[i+2],words[i+3]) for i in range(len(words)-3)]
                ret_words += ['%s %s %s'%(words[i],words[i+1],words[i+3]) for i in range(len(words)-3)]
            if 2 in self.tuples:
                ret_words += ['%s %s'%(words[i],words[i+3]) for i in range(len(words)-3)]
                if 3 not in self.tuples:
                    ret_words += ['%s %s'%(words[i],words[i+2]) for i in range(len(words)-2)]
        if calc_weights:
            return ret_words, {}
        else:
            return ret_words


"""
.. topic:: objetos (views)

    Os objetos são objetos que a coordenação necessita de um registro mínimo para referência em demandas.

    Um objeto tem atributos que são registrados no momento de sua criação. Todos são obrigatórios:

    * Título
    * Contraparte
    * Número do processo SEI
    * Data de início
    * Data de término
    * Valor associado
    * Descrição

.. topic:: Ações relacionadas aos objetos

    * Listar objetos: lista_objetos
    * Atualizar/visualizar dados de um objeto: update
    * Registrar um objeto no sistema: cria_objeto
    * Listar demandas de um determinado objeto: objeto_demandas

"""

# views.py na pasta objetos

from flask import render_template,url_for,flash, redirect,request,Blueprint, abort
from flask_login import current_user,login_required
from sqlalchemy import func, distinct, cast, Integer
from sqlalchemy.sql import label
from project import db
from project.models import User, Demanda, Coords, Objeto
from project.objetos.forms import objetoForm, ListaForm
from project.demandas.views import registra_log_auto

import locale
from datetime import datetime, date
from dateutil.rrule import rrule, MONTHLY

objetos = Blueprint('objetos',__name__,
                            template_folder='templates/objetos')

#
def none_0(a):
    '''
    DOCSTRING: Transforma None em 0.
    INPUT: campo a ser trandormado.
    OUTPUT: 0, se a entrada for None, caso contrário, a entrada.
    '''
    if a == None:
        a = 0
    return a

@objetos.route('/<lista>/<coord>/lista_objetos', methods=['GET', 'POST'])
def lista_objetos(lista,coord):
    """
    +---------------------------------------------------------------------------------------+
    |Apresenta uma lista dos objetos.                                                       |
    |                                                                                |
    |O objeto é algo tratado pela área técnica que justifica um registro específico.        |
    |Um contratao é um exemplo de objeto.                                                   |
    |                                                                                |
    |No topo da tela há a opção de se inserir um novo objeto e o número sequencial          |
    |de cada objeto (#), ao ser clicado, permite que seus dados possam ser editados.        |
    |                                                                                |
    +---------------------------------------------------------------------------------------+
    """

    hoje = datetime.today().date()

    form = ListaForm()

    coords = db.session.query(Coords.id,Coords.sigla)\
                       .order_by(Coords.sigla).all()
    lista_coords = [(c.id,c.sigla) for c in coords]
    lista_coords.insert(0,('',''))

    form.coord.choices = lista_coords

    if form.validate_on_submit():

        coord = form.coord.data

        if coord == '' or coord == None:
            coord = '*'

        return redirect(url_for('objetos.lista_objetos',lista=lista,coord=coord))

    else:

        if coord == '*':

            form.coord.data = ''

            coordenacao = db.session.query(Coords.id,
                                           Coords.sigla)\
                                    .subquery()

        else:

            form.coord.data = coord

            coordenacao = db.session.query(Coords.id,
                                           Coords.sigla)\
                                    .filter(Coords.id == cast(coord,Integer))\
                                    .subquery()

        if lista == 'todos':
            objetos_v = db.session.query(Objeto.id,
                                         Objeto.coord,
                                         Objeto.nome,
                                         Objeto.contraparte,
                                         Objeto.sei,
                                         Objeto.descri,
                                         Objeto.data_inicio,
                                         Objeto.data_fim,
                                         Objeto.valor,
                                         coordenacao.c.sigla)\
                                  .join(coordenacao, coordenacao.c.id == cast(Objeto.coord,Integer))\
                                  .order_by(Objeto.nome).all()

        elif lista == 'em execução':
            objetos_v = db.session.query(Objeto.id,
                                              Objeto.coord,
                                              Objeto.nome,
                                              Objeto.contraparte,
                                              Objeto.sei,
                                              Objeto.descri,
                                              Objeto.data_inicio,
                                              Objeto.data_fim,
                                              Objeto.valor,
                                              coordenacao.c.sigla)\
                                       .join(coordenacao, coordenacao.c.id == cast(Objeto.coord,Integer))\
                                       .filter(Objeto.data_fim >= hoje,
                                               Objeto.data_inicio <= hoje)\
                                       .order_by(Objeto.data_fim,Objeto.nome).all()

        quantidade = len(objetos_v)

        return render_template('lista_objetos.html', objetos=objetos_v,quantidade=quantidade,lista=lista,form=form)

### ATUALIZAR objeto

@objetos.route("/<int:objeto_id>/update", methods=['GET', 'POST'])
@login_required
def update(objeto_id):
    """
    +---------------------------------------------------------------------------------------+
    |Permite atualizar os dados de um objeto selecionado na tela de consulta.          |
    |                                                                                |
    |Recebe o ID do objeto como parâmetro.                                             |
    +---------------------------------------------------------------------------------------+
    """

    objeto = Objeto.query.get_or_404(objeto_id)

    form = objetoForm()

    if form.validate_on_submit():

        objeto.coord       = form.coord.data
        objeto.nome        = form.nome.data
        objeto.sei         = form.sei.data
        objeto.contraparte = form.contraparte.data
        objeto.data_inicio = form.data_inicio.data
        objeto.data_fim    = form.data_fim.data
        objeto.valor       = float(form.valor.data.replace('.','').replace(',','.'))
        objeto.descri      = form.descri.data

        db.session.commit()

        registra_log_auto(current_user.id,None,'itm')

        flash('objeto atualizado!')
        return redirect(url_for('objetos.lista_objetos',lista='todos',coord = '*'))
    # traz a informação atual do objeto
    elif request.method == 'GET':
        form.coord.data        = objeto.coord
        form.nome.data         = objeto.nome
        form.sei.data          = objeto.sei
        form.contraparte.data  = objeto.contraparte
        form.data_inicio.data  = objeto.data_inicio
        form.data_fim.data     = objeto.data_fim
        form.valor.data        = locale.currency( objeto.valor, symbol=False, grouping = True )
        form.descri.data       = objeto.descri

    return render_template('add_objeto.html', title='Update',
                           form=form, id=objeto_id)

### CRIAR objeto

@objetos.route("/criar", methods=['GET', 'POST'])
@login_required
def cria_objeto():
    """
    +---------------------------------------------------------------------------------------+
    |Permite registrar os dados de um objeto.                                               |
    +---------------------------------------------------------------------------------------+
    """

    form = objetoForm()

    coords = db.session.query(Coords.id,Coords.sigla)\
                       .order_by(Coords.sigla).all()
    lista_coords = [(c.id,c.sigla) for c in coords]
    lista_coords.insert(0,('',''))

    form.coord.choices = lista_coords

    if form.validate_on_submit():
        objeto = Objeto(coord       = form.coord.data,
                        nome        = form.nome.data,
                        contraparte = form.contraparte.data,
                        sei         = form.sei.data,
                        data_inicio = form.data_inicio.data,
                        data_fim    = form.data_fim.data,
                        valor       = float(form.valor.data.replace('.','').replace(',','.')),
                        descri      = form.descri.data)

        db.session.add(objeto)
        db.session.commit()

        registra_log_auto(current_user.id,None,'Objeto registrado!')

        flash('Objeto registrado!')
        return redirect(url_for('objetos.lista_objetos',lista='todos',coord = '*'))

    return render_template('add_objeto.html', form=form, id=0 )

# lista das demandas relacionadas a um objeto

@objetos.route('/<objeto_id>/objeto_demandas')
def objeto_demandas (objeto_id):
    """+--------------------------------------------------------------------------------------+
       |Mostra as demandas relacionadas a um objeto quando seu NUP é selecionado em uma  |
       |lista de objetos.                                                                |
       |Recebe o id do objeto como parâmetro.                                            |
       +--------------------------------------------------------------------------------------+
    """

    objeto_SEI = db.session.query(Objeto.sei,Objeto.nome).filter_by(id=objeto_id).first()

    SEI = objeto_SEI.sei
    SEI_s = str(SEI).replace('/','_')

    demandas_count = Demanda.query.filter(Demanda.sei.like('%'+SEI+'%')).count()

    demandas = Demanda.query.filter(Demanda.sei.like('%'+SEI+'%'))\
                            .order_by(Demanda.data.desc()).all()

    autores=[]
    for demanda in demandas:
        autores.append(str(User.query.filter_by(id=demanda.user_id).first()).split(';')[0])

    dados = [objeto_SEI.nome,SEI_s,'0','0']

    return render_template('SEI_demandas.html',demandas_count=demandas_count,demandas=demandas,sei=SEI, autores=autores,dados=dados)

#
#removendo uma atividade do plano de trabalho

@objetos.route('/<int:objeto_id>/delete', methods=['GET','POST'])
@login_required
def delete_objeto(objeto_id):
    """+----------------------------------------------------------------------+
       |Permite que o chefe, se logado, a remova um um objeto.           |
       |                                                                      |
       |Recebe o ID do objeto como parâmetro.                            |
       +----------------------------------------------------------------------+

    """
    if current_user.ativo != 1 or current_user.despacha != 1 or current_user.role != 'admin':
        abort(403)

    objeto = Objeto.query.get_or_404(objeto_id)

    nome = objeto.nome

    db.session.delete(objeto)
    db.session.commit()

    registra_log_auto(current_user.id,None,'Objeto ' + nome + ' excluído.')

    flash ('objeto ' + nome + ' excluído!','sucesso')

    return redirect(url_for('objetos.lista_objetos',lista='todos',coord = '*'))


from collections import defaultdict
from classes import Star, Plus, Optional, Sequence

def split_grammar(grammar):
    no_cycle_grammar = defaultdict(list)
    leftover_grammar = defaultdict(list)
    for nonterminal, alternatives in grammar.items():
        for alternative in alternatives:
            if not isinstance(alternative, Sequence):
                alternative = Sequence( [alternative] )

            multiple_options = False
            new_alternative = []

            for element in alternative.get_arg():
                if isinstance(element, Optional) or isinstance(element, Star):
                    multiple_options = True

                elif isinstance(element, Plus):
                    multiple_options = True
                    new_alternative.append(element.get_arg())

                else:
                    new_alternative.append(element)

            if multiple_options:
                if True:
                    new_alternative = Sequence( new_alternative )
                    if not new_alternative.contains_cycle(nonterminal, [], grammar):
                        no_cycle_grammar[nonterminal].append(new_alternative)
                    else:
                        leftover_grammar[nonterminal].append(new_alternative)
                leftover_grammar[nonterminal].append(alternative)
            else:
                if alternative.contains_cycle(nonterminal, [], grammar):
                    leftover_grammar[nonterminal].append(alternative)
                else:
                    no_cycle_grammar[nonterminal].append(alternative)

    return no_cycle_grammar, leftover_grammar


import sys
input = sys.stdin.readline

while 1:
    arr = list(map(int, input().split()))
    if arr[0] == -1:
        exit(0)
    else:
        arr.pop()
        answer = 0
        for i in range(len(arr)):
            if arr[i] * 2 in arr:
                answer += 1
        print(answer)


import logging
import os
import shutil
import html
from os import path

from fetcherd.settings import Settings
from fetcherd.util import get_path, get_path_regex, load_source, load_providers

class Fetcherd:

    def __init__(self, args, config):
        self.logger = logging.getLogger('fetcherd')
        self.args = args
        self.config = config
        self.fetch_lock = False
        self.sort_lock = False

        loaded_source = load_source(config.source['modules_path'],
                                    config.source['class'])
        self.source = loaded_source(config.source['settings'])
        self.logger.info("Current source {}"
                         .format(self.config.source['class']))

        self.providers = load_providers(self.config.providers['modules_path'])

    def sort(self, source=None):
        if source is None:
            source = self.source

        logger = logging.getLogger('sort')

        if self.sort_lock:
            raise Exception("Sort is already in use")

        try:
            self.sort_lock = True

            for series in source.get_series():
                logger.info('Sorting {}'.format(series['title']))
                base_save_path = get_path(series['media_type'],
                                          self.config.sort['save_paths'],
                                          default=self.config.sort['save_path_default'])

                os.makedirs(base_save_path, exist_ok=True)

                search_title = series['title']
                if 'search_title' in series:
                    if series['search_title'] != '':
                        search_title = series['search_title']

                save_path = series['title']
                if 'save_path' in series:
                    if series['save_path'] != '':
                        save_path = series['save_path']

                save_path = path.join(base_save_path,
                                      save_path)

                for search_path in self.config.sort['search_paths']:
                    logger.info("Searching in {}".format(search_path))

                    for root, dirs, files in os.walk(search_path):
                        for f in files:
                            if search_title in f:
                                os.makedirs(save_path, exist_ok=True)
                                if not path.isfile(path.join(save_path, f)):
                                    logger.info('Found {}'.format(f))

                                    if 'providers_to_move' in self.config.sort \
                                       and series['provider'] in self.config.sort['providers_to_move']:
                                        shutil.move(path.join(root, f), save_path)
                                        op = 'Moving '
                                    else:
                                        shutil.copy(path.join(root, f), save_path)
                                        op = 'Copying'

                                    logger.info('{} {} to {}'
                                                .format(op, f, save_path))

        except Exception as e:
            logging.error('Error: {}'.format(str(e)))
        finally:
            self.sort_lock = False

    def fetch(self, source=None, base_providers=None):
        if source is None:
            source = self.source

        if base_providers is None:
            base_providers = self.providers

        if self.fetch_lock:
            raise Exception("Fetch is already in use")

        try:
            self.fetch_lock = True
            providers = {}
            logger = logging.getLogger('fetcher')

            for prov in source.get_base_providers():
                if prov['name'] not in base_providers:
                    logger.warning('Unsupported Base Provider: {0}'.format(prov['name']))
                else:
                    logger.info('Loaded {}'.format(prov['name']))

            for prov in source.get_providers():
                if prov['base_provider'] in base_providers:
                    providers.update({prov['id']:
                                      base_providers[prov['base_provider']](prov)})
                    logger.info('Loaded {} with options {}'
                                .format(prov['name'],
                                        prov['base_provider_options']))
                else:
                    logger.warning('Unsupported Base Provider \"{0}\" used by {1}'
                                    .format(prov['base_provider'], prov['name']))

            for series in source.get_series():
                if series['provider_id'] in providers:
                    logger.info("Fetching {}"
                                .format(html.unescape(series['title'])))
                    provider = providers[series['provider_id']]
                    current = series['current_count']

                    for ep in provider.fetch(series):
                        numb, link, title = ep
                        current = max(numb, current)
                        if numb > series['current_count']:
                            logger.info('Downloading {}'.format(title))
                            (dwn, name) = provider.download(link, self.config)
                            self.download(dwn, name)

                    if current > series['current_count']:
                        logging.info('Updating {} to episode count {}'
                                     .format(series['title'], current))
                        source.post_update_episode_count(series['id'], current)

                else:
                    logger.warning("Unsupported provider id: {}"
                                   .format(series['provider_id']))
        except Exception as e:
            logging.error('Error: {}'.format(str(e)))
        finally:
            self.fetch_lock = False

    def download(self, stream, filename):
        logger = logging.getLogger('downloads')
        path = get_path_regex(filename, self.config.fetch['save_paths'],
                              default=self.config.fetch['save_path_default'])

        logger.info("Downloading {} to {}".format(filename, path))

        with open(os.path.join(path, filename), 'wb') as f:
            for chunk in stream:
                if chunk:
                    f.write(chunk)
                    f.flush()

    def start(self):
        if self.config.webui['enable']:
            logging.debug("Setting up WebUI")
            from fetcherd.webui import WebUI
            self.webui = WebUI(self, self.config)
            logging.debug("Starting WebUI")
            self.webui.run()

    def reload_providers(self):
        self.logger.info("Reloading proivders")
        self.providers = load_providers(self.config.providers['modules_path'])

    def reload_source(self):
        self.logger.info("Reloading source")

        loaded_source = load_source(self.config.source['modules_path'],
                                    self.config.source['class'])
        self.source = loaded_source(self.config.source['settings'])
        self.logger.info("Current source {}"
                         .format(self.config.source['class']))

    def reload_config(self):
        self.logger.info("Reloading config")

        self.config = Settings(self.args['--config'])


import os
import numpy as np
from gym import utils, spaces
from gym.envs.mujoco import mujoco_env
from mujoco_py.builder import MujocoException

from .assets import kuka_asset_dir
from gym_kuka_mujoco.controllers import controller_registry

class KukaEnv(mujoco_env.MujocoEnv, utils.EzPickle):
    default_info = dict()
    def __init__(self,
                 controller,
                 controller_options,
                 model_path='full_kuka_no_collision_no_gravity.xml',
                 frame_skip=20,
                 time_limit=3.,
                 timestep=0.002,
                 random_model = False,
                 random_target = False,
                 quadratic_pos_cost = True,
                 quadratic_vel_cost = False):
        '''
        Constructs the file, sets the time limit and calls the constructor of
        the super class.
        '''
        self.random_model = random_model
        self.random_target = random_target
        self.quadratic_pos_cost = quadratic_pos_cost
        self.quadratic_vel_cost = quadratic_vel_cost

        utils.EzPickle.__init__(self)

        full_path = os.path.join(kuka_asset_dir(), model_path)

        self.time_limit = time_limit

        # Parameters for the cost function
        self.state_des = np.zeros(14)
        self.Q_pos = np.diag([1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.])
        self.Q_vel = np.diag([0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.])

        # Call the super class
        self.initialized = False
        mujoco_env.MujocoEnv.__init__(self, full_path, frame_skip)
        self.model.opt.timestep = timestep
        self.initialized = True

        # Create the desired controller.
        controller_cls = controller_registry[controller]
        self.controller = controller_cls(sim=self.sim, **controller_options)

        # Take the action space from the controller.
        self.action_space = self.controller.action_space

        self.last_action = None

    def viewer_setup(self):
        '''
        Overwrites the MujocoEnv method to make the camera point at the base.
        '''
        self.viewer.cam.trackbodyid = 0

    '''
    Step and helper methods. Only overwrite the helpers in the subclasses.
    '''
    def step(self, action, render=False):
        '''
        Simulate for `self.frame_skip` timesteps. Calls _update_action() once
        and then calls _get_torque() repeatedly to simulate a low-level
        controller.
        Optional argument render will render the intermediate frames for a smooth animation.
        '''
        # Hack to return an observation during the super class __init__ method.
        if not self.initialized:
            return self._get_obs(), 0, False, {}

        # Set the action to be used for the simulation.
        self._update_action(action)
        self.last_action = action

        # Get the reward from the state and action.
        state = np.concatenate((self.sim.data.qpos[:], self.sim.data.qvel[:]))

        # Simulate the low level controller.
        dt = self.sim.model.opt.timestep

        try:
            total_reward = 0
            total_reward_info = dict()
            for _ in range(self.frame_skip):
                torque = self._get_torque()
                self.sim.data.ctrl[:] = np.clip(torque, -300, 300)
                self.sim.data.qfrc_applied[:] = self._get_random_applied_force()
                self.sim.step()
                if not np.all(np.isfinite(self.sim.data.qpos)):
                    print("Warning: simulation step returned inf or nan.")
                reward, reward_info = self._get_reward(state, action)
                total_reward += reward*dt
                for k, v in reward_info.items():
                    if 'reward' in k:
                        total_reward_info[k] = total_reward_info.get(k,0) + v*dt
                if render:
                    self.render()

            # Get observation and check finished
            done = (self.sim.data.time > self.time_limit) or self._get_done()
            obs = self._get_obs()
            info = self._get_info()
            info.update(total_reward_info)
        except MujocoException as e:
            print(e)
            reward = 0
            obs = np.zeros_like(self.observation_space.low)
            done = True
            info = self.default_info

        return obs, total_reward, done, info

    def _update_action(self, a):
        '''
        This function is called once per step.
        '''
        self.controller.set_action(a)

    def _get_torque(self):
        '''
        This function is called multiple times per step to simulate a
        low-level controller.
        '''
        return self.controller.get_torque()

    def _get_obs(self):
        '''
        Return the full state as the observation
        '''

        if self.random_target:
            return np.concatenate((self._get_state_obs(), self._get_target_obs()))
        else:
            return self._get_state_obs()

    def _get_state_obs(self):
        '''
        Return the observation given by the state.
        '''
        if not self.initialized:
            return np.zeros(14)

        return np.concatenate([self.sim.data.qpos[:], self.sim.data.qvel[:]])

    def _get_target_obs(self):
        '''
        Return the observation given by the goal for the episode.
        '''
        return self.state_des[:7]

    def _get_reward(self, state, action):
        '''
        Compute single step reward.
        '''
        # quadratic cost on the state error
        reward_info = dict()
        reward = 0.

        err = self.state_des - state
        if self.quadratic_pos_cost:
            reward_info['quadratic_pos_cost'] = -err.dot(self.Q_pos).dot(err)
            reward += reward_info['quadratic_pos_cost']

        if self.quadratic_vel_cost:
            reward_info['quadratic_vel_cost'] = -err.dot(self.Q_vel).dot(err)
            reward += reward_info['quadratic_vel_cost']

        return reward, reward_info

    def _get_done(self):
        '''
        Check the termination condition.
        '''
        return False

    def _get_info(self):
        '''
        Get any additional info.
        '''
        q_err = self.state_des[:7] - self.sim.data.qpos
        v_err = self.state_des[7:] - self.sim.data.qvel
        dist = np.sqrt(q_err.dot(q_err))
        velocity = np.sqrt(v_err.dot(v_err))
        return {
            'distance': dist,
            'velocity': velocity
        }

    def _get_random_applied_force(self):
        return np.zeros(self.model.nv)

    '''
    Reset and helper methods. Only overwrite the helper methods in subclasses.
    '''
    def reset_model(self):
        '''
        Overwrites the MujocoEnv method to reset the robot state and return the observation.
        '''
        while(True):
            try:
                if self.random_model:
                    self._reset_model_params()
                if self.random_target:
                    self._reset_target()
                self._reset_state() # Always reset the state after the target is reset.
                self.sim.forward()
            except MujocoException as e:
                print(e)
                continue
            break

        return self._get_obs()

    def _reset_state(self):
        '''
        Reset the state of the model (i.e. the joint positions and velocities).
        '''
        qpos = 0.1*self.np_random.uniform(low=self.model.jnt_range[:,0], high=self.model.jnt_range[:,1], size=self.model.nq)
        qvel = np.zeros(7)
        self.set_state(qpos, qvel)

    def _reset_target(self):
        '''
        Reset the goal parameters. Target pose for the base environment, but may change with subclasses.
        '''
        self.state_des[:7] = self.np_random.uniform(self.model.jnt_range[:,0], self.model.jnt_range[:,1])

    def _reset_model_params(self):
        '''
        TODO: implement this for domain randomization.
        '''
        raise NotImplementedError


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

# In[2]:

import pandas as pd

# In[3]:

data = [['Jon','car',10000]
        ,['Jon','car',150]
        ,['Jon','house',150000]
        ,['Alex','house',12000]
        ,['Alex','house',50000]
        ,['Steve','house',180000]
        ,['Jon','car',20000]
        ,['Jon','piano',2000]
       ]

# Create the pandas DataFrame
df = pd.DataFrame(data, columns = ['Name','Item','price'])
df.head(10)

# In[10]:

df['count_by_person']=df.groupby('Name').cumcount()+1
df['count_by_item']=df.groupby('Item').cumcount()+1
df['count_by_both']=df.groupby(['Name','Item']).cumcount()+1

# In[11]:

df

# In[ ]:


import numpy as np
import matplotlib.pyplot as plt

fig, ax1 = plt.subplots()

r2 = 0.05
r3 = 0.0075
r4 = 0.0025

i = np.linspace(0, 20, 20)
iQuadrat = np.square(i)

p2 = iQuadrat*r2
p3 = iQuadrat*r3
p4 = iQuadrat*r4

u2 = i*r2*1000
u3 = i*r3*1000
u4 = i*r4*1000

color = 'tab:red'
ax1.set_xlabel('Strom [A]')
ax1.set_ylabel('Verlustleistung [W]', color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax1.set_ylim(0,2)

ax1.plot(i, p2, marker='x', color=color, label='0.05 $\Omega$')
ax1.plot(i, p3, marker='^', color=color, label='0.0075 $\Omega$')
ax1.plot(i, p4, marker='s', color=color, label='0.0025 $\Omega$')

plt.legend(loc='upper left')

ax2 = ax1.twinx()

color = 'tab:blue'
ax2.set_ylabel('Spannungsfall [mV]', color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax2.set_ylim(0,200)

ax2.plot(i, u2, marker='x', color=color, label='0.05 $\Omega$')
ax2.plot(i, u3, marker='^', color=color, label='0.0075 $\Omega$')
ax2.plot(i, u4, marker='s', color=color, label='0.0025 $\Omega$')

plt.legend(loc='upper right')

plt.tight_layout()

#plt.show()

plt.savefig('results/shunt_loss.svg', format='svg', dpi=1200)
plt.clf()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
易盾反垃圾云服务图片结果查询接口python示例代码
接口文档: http://dun.163.com/api.html
python版本：python3.7
运行:
    1. 修改 SECRET_ID,SECRET_KEY,BUSINESS_ID 为对应申请到的值
    2. $ python image_query.py
"""
__author__ = 'yidun-dev'
__date__ = '2019/11/27'
__version__ = '0.2-dev'

import hashlib
import time
import random
import urllib.request as urlrequest
import urllib.parse as urlparse
import json
from gmssl import sm3, func

class ImageQueryByTaskIdsDemo(object):
    """易盾图片离线查询结果获取接口示例代码"""

    API_URL = "http://as.dun.163.com/v1/image/query/task"
    VERSION = "v1"

    def __init__(self, secret_id, secret_key, business_id):
        """
        Args:
            secret_id (str) 产品密钥ID，产品标识
            secret_key (str) 产品私有密钥，服务端生成签名信息使用
            business_id (str) 业务ID，易盾根据产品业务特点分配
        """
        self.secret_id = secret_id
        self.secret_key = secret_key
        self.business_id = business_id

    def gen_signature(self, params=None):
        """生成签名信息
        Args:
            params (object) 请求参数
        Returns:
            参数签名md5值
        """
        buff = ""
        for k in sorted(params.keys()):
            buff += str(k) + str(params[k])
        buff += self.secret_key
        if "signatureMethod" in params.keys() and params["signatureMethod"] == "SM3":
            return sm3.sm3_hash(func.bytes_to_list(bytes(buff, encoding='utf8')))
        else:
            return hashlib.md5(buff.encode("utf8")).hexdigest()

    def query(self, params):
        """请求易盾接口
        Args:
            params (object) 请求参数
        Returns:
            请求结果，json格式
        """
        params["secretId"] = self.secret_id
        params["businessId"] = self.business_id
        params["version"] = self.VERSION
        params["timestamp"] = int(time.time() * 1000)
        params["nonce"] = int(random.random() * 100000000)
        # params["signatureMethod"] = "SM3"  # 签名方法，默认MD5，支持SM3
        params["signature"] = self.gen_signature(params)

        try:
            params = urlparse.urlencode(params).encode("utf8")
            request = urlrequest.Request(self.API_URL, params)
            content = urlrequest.urlopen(request, timeout=10).read()
            return json.loads(content)
        except Exception as ex:
            print("调用API接口失败:", str(ex))

if __name__ == "__main__":
    """示例代码入口"""
    SECRET_ID = "your_secret_id"  # 产品密钥ID，产品标识
    SECRET_KEY = "your_secret_key"  # 产品私有密钥，服务端生成签名信息使用，请严格保管，避免泄露
    BUSINESS_ID = "your_business_id"  # 业务ID，易盾根据产品业务特点分配
    api = ImageQueryByTaskIdsDemo(SECRET_ID, SECRET_KEY, BUSINESS_ID)

    # 私有请求参数
    taskIds: list = ['093238e25fa54a3993849e72eb6040af', '8d26fded48d74263a9ad30e8199fdac7']  # 查询参数taskIds
    params = {
        "taskIds": taskIds
    }

    ret = api.query(params)

    code: int = ret["code"]
    msg: str = ret["msg"]
    if code == 200:
        resultArray: list = ret["result"]
        for result in resultArray:
            name: str = result.get("name", "")
            taskId: str = result["taskId"]
            status: int = result["status"]
            labelArray: list = result["labels"]
            print("taskId: %s, status: %s, name: %s, labels: %s" % (taskId, status, name, labelArray))
            maxLevel: int = -1
            # 产品需根据自身需求，自行解析处理，本示例只是简单判断分类级别
            for labelItem in labelArray:
                label: int = labelItem["label"]
                level: int = labelItem["level"]
                rate: float = labelItem["rate"]
                print("label: %s, level: %s, rate: %s" % (label, level, rate))
                maxLevel = level if level > maxLevel else maxLevel
            if maxLevel == 0:
                print("#图片查询结果: 最高等级为\"正常\"\n")
            elif maxLevel == 1:
                print("#图片查询结果: 最高等级为\"嫌疑\"\n")
            elif maxLevel == 2:
                print("#图片查询结果: 最高等级为\"确定\"\n")
    else:
        print("ERROR: code=%s, msg=%s" % (ret["code"], ret["msg"]))