from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
import cv2
import math
from sklearn.preprocessing import LabelEncoder
import sys
import os
import random
#os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
import logging
import seaborn as sns
from tensorflow.python.tools import inspect_checkpoint as chkp

sys.path.append('CNN')
import deepletters_cnn as model
#tf.logging.set_verbosity(tf.logging.ERROR)

class CNN():
    def __init__(self, absolute_root, learning_rate, resume, momentum, batch_size, start_epoch, epochs):
        self.glr = 0

        self.momentum = momentum

        self.learning_rate = learning_rate

        self.absolute_root = absolute_root

        self.resume = resume
        #/model/deephand_mean.npy
        self.mean_image = np.resize(np.load(absolute_root + '/CNN/mean_image.npy'), [227,227,3])

        self.log = logging.getLogger()
        self.log.setLevel(logging.DEBUG)

        self.batch_size = batch_size

        self.start_epoch = start_epoch

        self.epochs = epochs
        #self.secondary_lr = secondary_lr

    def create_graph(self, learning_rate=1e-2, mode="testing"):

        X = tf.placeholder(tf.float32, shape=(None, 227, 227, 3), name='inputs')
        y = tf.placeholder(tf.int64, [None], name='labels')

        dropout = tf.placeholder(tf.float32, shape=(), name='dropout')

        loss3_SLclassifier_1, loss2_SLclassifier_1, loss1_SLclassifier_1 = model.KitModel(weight_file = self.absolute_root + '/auto_gen/weights.npy',
                                                                                X=X, mode=mode)
        #mean_loss = tf.losses.softmax_cross_entropy(tf.one_hot(y, 24), y_out)

        values, indices = tf.nn.top_k(loss3_SLclassifier_1, 24)

        real_loss = tf.losses.softmax_cross_entropy(tf.one_hot(y, 24), loss3_SLclassifier_1)
        aux_loss2 = tf.losses.softmax_cross_entropy(tf.one_hot(y, 24), loss2_SLclassifier_1)
        aux_loss1 = tf.losses.softmax_cross_entropy(tf.one_hot(y, 24), loss1_SLclassifier_1)

        total_loss = real_loss + .3 * aux_loss2 + .3 * aux_loss1

        # vars = tf.trainable_variables()
        # vars = [v for v in vars if 'bias' not in v.name ]
        #
        # lossL2 = tf.add_n([ tf.nn.l2_loss(v) for v in vars
        #               if 'bias' not in v.name ]) * 0.005

        # l1_regularizer = tf.contrib.layers.l1_regularizer(
        #    scale=0.001, scope=None)
        # weights = tf.trainable_variables() # all vars of your graph
        # lossl1 = tf.contrib.layers.apply_regularization(l1_regularizer, vars)

        #total_loss = total_loss + lossL2
        #optimzer = tf.train.AdamOptimizer(learning_rate=learning_rate)
    #optimzer = tf.train.MomentumOptimizer(learning_rate=learning_rate, momentum=self.momentum, use_nesterov=True)
        # have tensorflow compute accuracy
        correct_prediction = tf.equal(tf.argmax(loss3_SLclassifier_1, 1), y)
        top_5_corr = tf.nn.in_top_k(predictions=loss3_SLclassifier_1, targets=y, k=5)

        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
        top_5_acc = tf.metrics.mean(top_5_corr)

        confusion = tf.confusion_matrix(labels=y, predictions=tf.argmax(loss3_SLclassifier_1, 1), num_classes=24)

        extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
        with tf.control_dependencies(extra_update_ops):
            #Get only the last layers to train
            # FC1 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_4c/FC')
            # FC2 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'incpetion_5a/FC')
            # FC3 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5b/FC')
            # loss1_fc_1 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'loss1/fc_1')
            # loss2_fc_1 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'loss2/fc_1')
            # inception_5a_5x5 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5a/5x5')
            # inception_5a_3x3 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5a/3x3')
            # inception_5b_3x3_reduce = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5b/3x3_reduce')
            # inception_5b_5x5_reduce = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5b/5x5_reduce')
            # inception_5b_1x1 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5b/1x1')
            # inception_5b_pool_proj = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5b/pool_proj')
            # inception_5b_3x3 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5b/3x3')
            # inception_5b_5x5 = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'inception_5b/5x5')
            #
            # var_list=[FC1, FC2, FC3, loss1_fc_1, loss2_fc_1, inception_5a_5x5, inception_5a_3x3, inception_5b_3x3_reduce,
            #                                inception_5b_5x5_reduce, inception_5b_1x1, inception_5b_pool_proj, inception_5b_3x3, inception_5b_5x5]

            # vars_to_remove = ['inception_4c/FC/kernel:0', 'inception_4c/FC/bias:0', 'incpetion_5a/FC/kernel:0', 'incpetion_5a/FC/bias:0', 'loss1/fc_1/kernel:0', 'loss1/fc_1/bias:0', 'loss2/fc_1/kernel:0','loss2/fc_1/bias:0' ,'inception_5b/3x3_reduce_weight:0', 'inception_5b/3x3_reduce_bias:0',
            #                   'inception_5b/5x5_reduce_weight:0', 'inception_5b/5x5_reduce_bias:0', 'inception_5b/1x1_weight:0', 'inception_5b/1x1_bias:0', 'inception_5b/pool_proj_weight:0',
            #                   'inception_5b/pool_proj_bias:0', 'inception_5b/3x3_weight:0', 'inception_5b/3x3_bias:0', 'inception_5b/5x5_weight:0', 'inception_5b/5x5_bias:0', 'inception_5b/FC/kernel:0', 'inception_5b/FC/bias:0']
            # trainable_variables = tf.get_collection_ref(tf.GraphKeys.TRAINABLE_VARIABLES)
            # #self.log.info(tf.trainable_variables())
            # #self.log.info(trainable_variables)
            # for var in trainable_variables:
            #     #self.log.info('Var name: ' + var.name)
            #
            #     if var.name in vars_to_remove:
            #         trainable_variables.remove(var)
            #         #self.log.info("REMOVED VARIABLE: " + var.name)

            # train_step = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(total_loss, var_list=trainable_variables)
            # upper_train_step = tf.train.AdamOptimizer(learning_rate=.0001).minimize(total_loss, var_list=var_list)
            train_step = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(total_loss)
            upper_train_step = tf.constant([1])

        return loss3_SLclassifier_1, total_loss, train_step, correct_prediction, accuracy, X, y, top_5_corr, top_5_acc, confusion, upper_train_step, dropout
    def get_pictures(self, Xd, location):
        images = np.empty((Xd.shape[0], 227, 227, 3))
        #print(Xd)
        #print(location)
        for i in range(Xd.shape[0]):
            im = cv2.imread(location[i] + "/" + Xd[i])
            # x = random.randint(0, 256 - 227)
            # im = im[x:x+227, x:x+227]
            #
            # if random.random() < .5:
            #     im = cv2.flip(im, 0)
            #print(location[i] + "/" + Xd[i])
            images[i] = im
        assert not np.any(np.isnan(images))
        images = images - self.mean_image
        return images

    def run_model(self, session, predict, loss_val, Xd, yd,
                  epochs=1, batch_size=64, print_every=100,
                  training=None, plot_losses=False,
                  correct_prediction=None, accuracy=None, X=None, y=None, location=None, X_val=None, y_val=None, val_loc=None,
                  saver=None, top_5_correct_prediction=None, top_5_accuracy=None, confusion=None, classes=None, upper_train_step=None, dropout=None, dropout_val=1):

        val_losses = []
        val_accuracies = []
        overall_train_losses = []

        relative_root = None

        # shuffle indicies
        train_indicies = np.arange(Xd.shape[0])
        np.random.shuffle(train_indicies)

        training_now = training is not None

        # setting up variables we want to compute (and optimizing)
        # if we have a training function, add that to things we compute
        variables = [loss_val, correct_prediction, confusion, top_5_correct_prediction, top_5_accuracy]
        if training_now:
            variables[-1] = training
            if self.resume:
                pass
                #overall_train_losses = np.load(self.absolute_root + "/CNN/trained_networks/static_v2_lr-" + str(glr) + "/epoch-" + str(self.start_epoch) + "/static_v2_lr-" + str(glr) + "-overall_train_losses.npy").tolist()
                #overall_train_losses = np.load("C:/Riley/DeepLetters/CNN/trained_networks/one opt/static_v2_lr-1e-06/epoch-7/static_v2_lr-1e-06-overall_train_losses.npy").tolist()
                #val_losses = np.load("C:/Riley/DeepLetters/CNN/trained_networks/one opt/static_v2_lr-1e-06/epoch-7/static_v2_lr-1e-06-val_losses.npy").tolist()

                #val_losses = np.load(self.absolute_root + "/CNN/trained_networks/static_v2_lr-" + str(glr) + "/epoch-" + str(self.start_epoch) + "/static_v2_lr-" + str(glr) + "-val_losses.npy").tolist()

        #else:
           # variables.append(confusion)

        # counter
        iter_cnt = 0

        for e in range(self.start_epoch, epochs):
            # keep track of losses and accuracy
            correct = 0
            tot_top_5_correct = 0
            losses = []
            top_5_accuracies = []
            confusion_matricies = []
            # make sure we iterate over the dataset once
            for i in range(int(math.ceil(Xd.shape[0] / batch_size))):
                # generate indicies for the batch
                start_idx = (i * batch_size) % Xd.shape[0]
                idx = train_indicies[start_idx:start_idx + batch_size]

                # create a feed dictionary for this batch
                feed_dict = {X: self.get_pictures(Xd[idx], location[idx]),
                             y: yd[idx],
                             dropout: dropout_val}
                # get batch size
                actual_batch_size = yd[idx].shape[0]

                # print(actual_batch_size)confusion
                # have tensorflow compute loss and correct predictions
                # and (if given) perform a training step
                loss, corr, confusion_matrix, top_5_corr, top_5_acc = session.run(variables, feed_dict=feed_dict)
               # else:
                #    loss, corr, _, top_5_corr, top_5_acc, batch_confusion = session.run(variables, feed_dict=feed_dict)
                confusion_matricies.append(confusion_matrix)

                # aggregate performance stats
                losses.append(loss * actual_batch_size)

                correct += np.sum(corr)
                tot_top_5_correct += np.sum(top_5_corr)
                # print every now and then
                if training_now and (iter_cnt % print_every) == 0:
                    self.log.info("Iteration " + str(iter_cnt) + ": with minibatch training loss = " + str(loss) + ", an accuracy of " + str(np.sum(corr) / actual_batch_size) + " and a top-5 accuracy of " + str(np.sum(top_5_corr) / actual_batch_size))

                iter_cnt += 1

            relative_root = self.absolute_root + "/CNN/trained_networks/static_v2_lr-" + str(glr) + "/epoch-" + str(e + 1)

            confusion_matricies = np.array(confusion_matricies)
            if training_now:
                pass
                total_correct = correct / (Xd.shape[0]+1)
                epoch_loss = np.sum(losses) / (Xd.shape[0]+1)
                overall_train_losses.append(epoch_loss)
                epoch_top_5_acc = tot_top_5_correct / (Xd.shape[0]+1)
                total_confusion_matrix = np.sum(confusion_matricies) / (Xd.shape[0]+1)

                self.log.info("Epoch " + str(e + 1) + ", Overall loss = " + str(epoch_loss) + ", an accuracy of " + str(total_correct) + " and a top-5 accuracy of " + str(epoch_top_5_acc))
            else:
                total_correct = correct / Xd.shape[0]
                epoch_loss = np.sum(losses) / Xd.shape[0]
                overall_train_losses.append(epoch_loss)
                epoch_top_5_acc = tot_top_5_correct / Xd.shape[0]
                total_confusion_matrix = np.sum(confusion_matricies, axis=0)
                print(confusion_matricies[0])
                print(total_confusion_matrix.shape)

            if plot_losses and training_now is True:
                self.log.info('Validation-------------------------')
                os.mkdir(relative_root)

                cur_val_loss, cur_val_correct = self.run_model(session, predict=predict, loss_val=loss_val, Xd=X_val, yd=y_val,
                                  epochs=self.start_epoch+1, batch_size=self.batch_size, print_every=10000, training=None, plot_losses=True,
                                  correct_prediction=correct_prediction, accuracy=accuracy, X=X, y=y, location=val_loc, top_5_correct_prediction=top_5_correct_prediction,
                                  top_5_accuracy=top_5_accuracy, confusion=confusion, classes=classes, dropout=dropout, dropout_val=1)
                val_losses.append(cur_val_loss)
                val_accuracies.append(cur_val_correct)

                saver.save(session, relative_root + "/static_v2_lr-" + str(glr) + ".ckpt")

                plt.plot(overall_train_losses)
                plt.grid(True)
                plt.title('Epoch {} Loss'.format(e + 1))
                plt.xlabel('Epoch number')
                plt.ylabel('Epoch Loss')

                np.save(relative_root +"/static_v2_lr-" + str(glr) +"-overall_train_losses.npy", overall_train_losses)
                plt.savefig(relative_root +"/static_v2_lr-" + str(glr) +"-TRAIN.png")

                plt.clf()
                plt.plot(val_losses)
                plt.grid(True)
                plt.title('Epoch {} Loss'.format(e + 1))
                plt.xlabel('Validation run')
                plt.ylabel('Loss')

                np.save(relative_root +"/static_v2_lr-" + str(glr) +"-val_losses.npy", val_losses)
                plt.savefig(relative_root +"/static_v2_lr-" + str(glr) + "-VAL.png")
                plt.clf()

                #plt.show()
            if not training_now:
                self.log.info("Validation, Overall loss = " + str(epoch_loss) + ", an accuracy of " + str(total_correct)+ " and a top-5 accuracy of " + str(epoch_top_5_acc))
                total_confusion_matrix = pd.DataFrame(total_confusion_matrix, columns=classes, index=classes)
                total_confusion_matrix = total_confusion_matrix.div(total_confusion_matrix.sum(axis=1), axis=0)
                heatmap = sns.heatmap(total_confusion_matrix, cmap="Blues")
                heatmap.set_title('Test Confusion Matrix')
                heatmap.set_xlabel('Predicted Label')
                heatmap.set_ylabel('True Label')
                heatmap.set_yticklabels(heatmap.get_yticklabels(), rotation=0)
                heatmap = heatmap.get_figure()
                heatmap.savefig(relative_root +"/static_v2_lr-" + str(glr) + "-confusion_matrix.png")
                plt.clf()

        return overall_train_losses, total_correct

    def train(self):

                # tf.train.write_graph(sess.graph_def, 'CNN',
                #          'saved_model.pbtxt', as_text=True)
                # sess.run(tf.global_variables_initializer())
                #
                # tensor_info_x = tf.saved_model.utils.build_tensor_info(X)
                # tensor_info_y = tf.saved_model.utils.build_tensor_info(loss3_SLclassifier_1)
                #
                # table = tf.contrib.lookup.index_to_string_table_from_tensor(
                #     tf.constant(np.array(list('abcdefghiklmnopqrstuvwxy'))))
                #
                # classification_inputs = tf.saved_model.utils.build_tensor_info(
                #       X)
                # classification_outputs_classes = tf.saved_model.utils.build_tensor_info(
                #       table.lookup(tf.to_int64(indices)))
                # classification_outputs_scores = tf.saved_model.utils.build_tensor_info(values)
                #
                # classification_signature = (
                #     tf.saved_model.signature_def_utils.build_signature_def(
                #     inputs={
                #     tf.saved_model.signature_constants.CLASSIFY_INPUTS:
                #           classification_inputs
                #   },
                #   outputs={
                #       tf.saved_model.signature_constants.CLASSIFY_OUTPUT_CLASSES:
                #           classification_outputs_classes,
                #       tf.saved_model.signature_constants.CLASSIFY_OUTPUT_SCORES:
                #           classification_outputs_scores
                #   },
                #   method_name=tf.saved_model.signature_constants.CLASSIFY_METHOD_NAME))
                #
                # prediction_signature = (
                #       tf.saved_model.signature_def_utils.build_signature_def(
                #           inputs={'images': tensor_info_x},
                #           outputs={'scores': tensor_info_y},
                #           method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))
                #
                #
                # builder = tf.saved_model.builder.SavedModelBuilder('CNN/saved_model_v2.pb')
                # builder.add_meta_graph_and_variables(
                # sess,
                # [tf.saved_model.tag_constants.SERVING],
                # signature_def_map= {
                #     'train':
                #         prediction_signature,
                #     tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
                #         classification_signature,
                #     },
                # main_op=tf.tables_initializer(),
                # strip_default_attrs=True)
                #
                # builder.save()
        data = pd.read_csv(self.absolute_root + '/227X227_new_images.csv')
        # idx = []
        # for index, row in data.iterrows():
        #     if 'Outside' not in row['file_name']:
        #         idx.append(index)
        #
        # data = data.drop(idx)
        #
        # data.reset_index(drop=True, inplace=True)

        print(data)

        X_data = np.array(data['file_name'])
        y_data = np.array(data['Letter'])
        location = np.array(data['dir_name'])

        label_encoder = LabelEncoder()
        #'Part5', 'Part2', 'Part3', 'part4','Part1'
        #'C', 'B', 'D', 'A', 'Part5', 'Part2', 'Part3', 'part4', 'user_3', 'user_4', 'user_5', 'user_6', 'user_7', 'user_9', 'user_10', 'Part1'
        train_signers = []
        test_signers = ['cropped_test']

        X_train = data.loc[data['dir_name'].isin(train_signers)]['file_name'].values
        y_train = data.loc[data['dir_name'].isin(train_signers)]['Letter'].values
        y_train = label_encoder.fit_transform(y_train)
        train_loc = data.loc[data['dir_name'].isin(train_signers)]['root'].values

        X_val = data.loc[data['dir_name'].isin(test_signers)]['file_name'].values
        y_val = data.loc[data['dir_name'].isin(test_signers)]['Letter'].values
        y_val = label_encoder.fit_transform(y_val)
        val_loc = data.loc[data['dir_name'].isin(test_signers)]['root'].values

        print(dict(zip(label_encoder.classes_, label_encoder.transform(label_encoder.classes_))))

        print(X_val)
        print(val_loc)
        #print(X_train)
        # X_train = np.concatenate((X_data[:26445], X_data[39838:67209]))
        #
        # label_encoder = LabelEncoder()
        # y_train = label_encoder.fit_transform(np.concatenate((y_data[:26445], y_data[39838:67209])))
        # train_loc = np.concatenate((location[:26445], location[39838:67209]))
        #
        # #65773
        # X_val = np.concatenate((X_data[26445:39838], X_data[67209:]))
        # y_val = label_encoder.fit_transform(np.concatenate((y_data[26445:39838], y_data[67209:])))
        # val_loc = np.concatenate((location[26445:39838],location[67209:]))

        for lr in self.learning_rate:
            with tf.Session(config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)) as sess:

                with tf.device("/device:GPU:0"):  # "/cpu:0" or "/gpu:0"
                    global glr
                    relative_root = self.absolute_root + "/CNN/trained_networks/static_v2_lr-" + str(lr)

                    glr = lr
                    if self.resume is False:
                        os.mkdir(relative_root)
                    if self.resume and os.path.isdir(relative_root) is False:
                        os.mkdir(relative_root)

                    fileh = logging.FileHandler(relative_root + "/static_v2_lr-" + str(lr) + ".txt", "a+")
                    fileh.setFormatter(logging.Formatter("%(asctime)-15s %(levelname)-8s %(message)s"))
                    fileh.setLevel(logging.INFO)

                    self.log.handlers = [fileh]
                    #log.addHandler(fileh)
                    #log.info('test')

                    with tf.variable_scope(tf.get_variable_scope(), reuse=tf.AUTO_REUSE) as scope:

                        loss3_SLclassifier_1, total_loss, train_step, correct_prediction, accuracy, X, y, top_5_corr, top_5_acc, confusion, upper_train_step, dropout = self.create_graph(lr, mode="training")

                        saver = tf.train.Saver()

                        sess.run(tf.local_variables_initializer())

                        if self.resume:
                            self.log.info("ENTERED RESUME")
                            saver.restore(sess=sess, save_path="CNN/trained_networks/OG CNN/one opt/static_v2_lr-1e-06/epoch-7/static_v2_lr-1e-06.ckpt")
                            #chkp.print_tensors_in_checkpoint_file(relative_root + "/epoch-20/static_v2_lr-" + str(lr) + ".ckpt", tensor_name='', all_tensors=True)

                            # reader = tf.train.NewCheckpointReader(relative_root + "/epoch-20/static_v2_lr-" + str(lr) + ".ckpt")
                            # restore_dict = dict()
                            # for v in tf.trainable_variables():
                            #   tensor_name = v.name.split(':')[0]
                            #   if reader.has_tensor(tensor_name):
                            #     self.log.info('has tensor ', tensor_name)
                            #     restore_dict[tensor_name] = v
                            #
                            # saver = tf.train.Saver(restore_dict)
                            # sess.run(tf.local_variables_initializer())
                            # saver.restore(sess=sess, save_path=relative_root + "/epoch-50/static_v2_lr-" + str(lr) + ".ckpt")
                            #
                            # is_not_initialized   = sess.run([tf.is_variable_initialized(var) for var in tf.global_variables()])
                            # not_initialized_vars = [v for (v, f) in zip(tf.global_variables(), is_not_initialized) if not f]
                            # self.log.info("NON INITIALIZED VARIABLES" + str(not_initialized_vars))
                            # sess.run(tf.initialize_variables(not_initialized_vars))

                        else:
                            sess.run(tf.global_variables_initializer())

                        self.log.info('Training')

                        self.run_model(sess, predict=loss3_SLclassifier_1, loss_val=total_loss, Xd=X_train, yd=y_train,
                                  epochs=self.start_epoch + self.epochs, batch_size=self.batch_size, print_every=100, training=train_step, plot_losses=True,
                                  correct_prediction=correct_prediction, accuracy=accuracy, X=X, y=y, location=train_loc, X_val=X_val, y_val=y_val, val_loc=val_loc, saver=saver,
                                  top_5_correct_prediction=top_5_corr, top_5_accuracy=top_5_acc, confusion=confusion, classes=list(label_encoder.classes_), upper_train_step=upper_train_step, dropout=dropout)

                        #self.run_model(sess, loss3_SLclassifier_1, total_loss, X_train, y_train, 500, 128, 100, train_step, True, correct_prediction, accuracy, X, y, train_loc)

                        #saver.save(sess, relative_root + "/final/static_v2_lr-" + str(lr) + ".ckpt")

                        #self.log.info('Validation')
                        #loss3_SLclassifier_1, total_loss, train_step, correct_prediction, accuracy, X, y = create_graph(lr, False)
                        #scope.reuse_variables()


"""
Analytical solution for the debris avalanche problem.
Input: X is the one-dimensional domain (grids);
       t is the time.
Output: u is the velocity in the x-direction;
        h is the height of the fluid;
        w is the stage that is w=h+z, where
        z is the one-dimensional topography;
        mom is the momentum in the x-direction.
Parameters: g is the gravity acceleration;
            h_0 is the constant initial height of fluid;
            c0 is square root of g*h_0;
            m is -g*tan(theta) + g*cos(theta)*cos(theta)*tan(delta), where
            theta is the topography angle and delta is the friction angle.
            Usually, tan(theta) and tan(delta) are given.
            Here, tan(theta) is the topography slope called bed slope.
Ref.: Mungkasi and Roberts, 2011, ANZIAM Journal Vol.52: C349--363,
      "A new analytical solution for testing debris avalanche numerical models".
"""
def analytical_solution(t):
    N = 100                        # number of cells
    X = linspace(-1000.,1000.,N+1) # vertices of cells
    dx = 2000./N                   # uniform cell width
    C = zeros(N,float)
    for i in range(N):
        C[i] = -1000. + (i+0.5)*dx # centroids of cells

        g = 9.81                       # gravity
        h_0 = 20.                      # initial fluid height
        c0 = sqrt(g*h_0)               # wave speed relating to h_0
        bed_slope = 0.1                # put 0 for classical dam break problem
        m = -g*bed_slope #+F ,         no friction
        #t_stop =15.                    # time to look at

        N = len(X)
        u = zeros(N,float)
        h = zeros(N,float)
        w = zeros(N,float)
        z = zeros(N,float)
        mom = zeros(N,float)
        for i in range(N):
            # Calculate Analytical Solution at time t > 0
            if X[i] <= -2.0*c0*t + 0.5*m*t**2:
                u[i] = 0.0
                h[i] = 0.0
            elif X[i] <= c0*t + 0.5*m*t**2:
                u[i] = 2.0/3.0 * (X[i]/t - c0 + m*t)
                h[i] = 1.0/(9.0*g) * (X[i]/t + 2.0*c0 - 0.5*m*t)**2
            else:
                u[i] = m*t
                h[i] = h_0

            z[i] = bed_slope*X[i]
            w[i] = h[i] + z[i]
            mom[i] = u[i]*h[i]


import math
from decimal import *
import numpy as np
from collections import deque, Counter
import itertools

if __name__ == '__main__':
    n,k,q = map(int,input().split())
    a = []
    for i in range(q):
        a.append(int(input()))
    member = [0] * n
    min_ans = q - k
    for i in a:
        member[i-1] += 1

    for i in member:
        if i - min_ans >0:
            print('Yes')
        else:
            print('No')


import sqlite3

DATABASE = 'data/data.db'

def setup_db():
  """Creates database if it has not already been set up."""
  db = sqlite3.connect(DATABASE)
  cur = db.cursor()

  # Create the table if it doesn't exist.
  cur.execute("CREATE TABLE IF NOT EXISTS mytable(id INTEGER PRIMARY KEY, name TEXT)")
  db.commit()

  # Insert some dummy data if the table is empty.
  cur.execute("SELECT COUNT(*) FROM mytable")
  if cur.fetchall()[0][0] == 0:
    cur.execute('INSERT INTO mytable(name) VALUES("Ian")')
    cur.execute('INSERT INTO mytable(name) VALUES("Tom")')
    cur.execute('INSERT INTO mytable(name) VALUES("Barry")')
    db.commit()

if __name__ == "__main__":
  setup_db()


# Time Complexity : O(n(log(n)))
# Space Complexity : O(n)
# Did this code successfully run on Leetcode : Yes
# Any problem you faced while coding this : No problem

# Given an array of strings, group anagrams together.
# Example: Input: ["eat", "tea", "tan", "ate", "nat", "bat"], Output: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ]
# Note: All inputs will be in lowercase. The order of your output does not matter.

class Solution(object):
    def groupAnagrams(self, strings):
        """
        create a hashmap with key as sorted string and value as a list of values
        when a new string comes, check whether it exists in the hashmap or not, if it exists add the values to the list of the values for that hashed string
        """

        lookup = {} # {sorted_string1: (string1, string2), sorted_string2: (string3)}
        retList = []
        for string in strings:
            sorted_string = ''.join(sorted(string))
            if sorted_string in lookup:
                lookup[sorted_string].append(string)
            else:
                lookup[sorted_string] = [string]

        for val in lookup.values():
            retList.append(val)

        return retList

obj = Solution()
strings = ["eat", "tea", "tan", "ate", "nat", "bat"]
print(obj.groupAnagrams(strings))


from pprint import pprint
from pymongo import MongoClient
from datetime import datetime
from bson.objectid import ObjectId

client = MongoClient()
db = client.pchome
coll = db.products

##MONGODB EXAMPLE

table=db.example
table.insert_many([
 	{ "_id" : 1, "name" : "xPhone", "price" : 799, "releaseDate" : 'ISODate("2011-05-14T00:00:00Z")', "spec" : { "ram" : 4, "screen" : 6.5, "cpu" : 2.66 }, "color" : [ "white", "black" ], "storage" : [ 64, 128, 256 ] },
 	{ "_id" : 2, "name" : "xTablet", "price" : 899, "releaseDate" : 'ISODate("2011-09-01T00:00:00Z")', "spec" : { "ram" : 16, "screen" : 9.5, "cpu" : 3.66 }, "color" : [ "white", "black", "purple" ], "storage" : [ 128, 256, 512 ] },
 	{ "_id" : 3, "name" : "SmartTablet", "price" : 899, "releaseDate" :  'ISODate("2015-01-14T00:00:00Z")', "spec" : { "ram" : 12, "screen" : 9.7, "cpu" : 3.66 }, "color" : [ "blue" ], "storage" : [ 16, 64, 128 ] },
 	{ "_id" : 4, "name" : "SmartPad", "price" : 699, "releaseDate" :  'ISODate("2020-05-14T00:00:00Z")', "spec" : { "ram" : 8, "screen" : 9.7, "cpu" : 1.66 }, "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256, 1024 ] },
 	{ "_id" : 5, "name" : "SmartPhone", "price" : 599, "releaseDate" : 'ISODate("2022-09-14T00:00:00Z")', "spec" : { "ram" : 4, "screen" : 9.7, "cpu" : 1.66 }, "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256 ] },
 	{ "_id" : 6, "name" : "xWidget", "spec" : { "ram" : 64, "screen" : 9.7, "cpu" : 3.66 }, "color" : [ "black" ], "storage" : [ 1024 ] }
])
table.insert_one({ "_id" : 7, "name" : "xReader","price": 'null', "spec" : { "ram" : 64, "screen" : 6.7, "cpu" : 3.66 }, "color" : [ "black", "white" ], "storage" : [ 128 ] })
table.insert_many(([
 	{  "name" : "xPhone", "price" : 799, "releaseDate" : 'ISODate("2011-05-14T00:00:00Z")', "spec" : { "ram" : 4, "screen" : 6.5, "cpu" : 2.66 }, "color" : [ "white", "black" ], "storage" : [ 64, 128, 256 ] },
 	{"name" : "xTablet", "price" : 899, "releaseDate" : 'ISODate("2011-09-01T00:00:00Z")', "spec" : { "ram" : 16, "screen" : 9.5, "cpu" : 3.66 }, "color" : [ "white", "black", "purple" ], "storage" : [ 128, 256, 512 ] },
 	{  "name" : "SmartTablet", "price" : 899, "releaseDate" : 'ISODate("2015-01-14T00:00:00Z")', "spec" : { "ram" : 12, "screen" : 9.7, "cpu" : 3.66 }, "color" : [ "blue" ], "storage" : [ 16, 64, 128 ] },
 	{ "name" : "SmartPad", "price" : 699, "releaseDate" : 'ISODate("2020-05-14T00:00:00Z")', "spec" : { "ram" : 8, "screen" : 9.7, "cpu" : 1.66 }, "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256, 1024 ] },
 	{"name" : "SmartPhone", "price" : 599, "releaseDate" : 'ISODate("2022-09-14T00:00:00Z")', "spec" : { "ram" : 4, "screen" : 9.7, "cpu" : 1.66 }, "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256 ] }
]))
table.insert_one({  "name" : "xPhone", "price" : 799, "releaseDate" : datetime.strptime("2011-05-14 00:00:00", '%Y-%m-%d %H:%M:%S'), "spec" : { "ram" : 4, "screen" : 6.5, "cpu" : 2.66 }, "color" : [ "white", "black" ], "storage" : [ 64, 128, 256 ] })
table.update_one({'releaseDate':{'$type':['date']}},{'$set':{'releaseDate':datetime.strptime("2011-09-01 00:00:00",'%Y-%m-%d %H:%M:%S')}})
table.insert_one({  "name" : "SmartPhone", "price" : [599,699,799,999],"releaseDate": datetime.strptime("2011-05-14 00:00:00", '%Y-%m-%d %H:%M:%S'), "spec" : { "ram" : 4, "screen" : 5.7, "cpu" : 1.66 },"color":["white","orange","gold","gray"],"storage":[128,256]})
table.update_one({"_id":ObjectId('611a9ef95dd672085faa3087')}, {'$max': { 'price': 799}})
table.update_many({}, {'$unset': {'releaseDate': "",'spec.ram': "",'storage.0':""}})
table.update_many({ '_id': 6 },{ '$set': {'price': 999} },upsert=True)
table.delete_one({'_id':ObjectId('611a9ef95dd672085faa3087')})
table.delete_many({'spec.cpu':3.66})

for idx,db in enumerate(table.find({'releaseDate':{'$type':'string'}},{'releaseDate':1,'_id':False})):
    if idx % 3 == 0:
        table.update_one(db,{'$set':{'releaseDate':datetime.strptime("2011-01-14 00:00:00",'%Y-%m-%d %H:%M:%S')}})
    elif idx % 3 == 1:
        table.update_one(db,{'$set':{'releaseDate':datetime.strptime("2011-05-14 00:00:00",'%Y-%m-%d %H:%M:%S')}})
    else:
        table.update_one(db,{'$set':{'releaseDate':datetime.strptime("2011-09-14 00:00:00",'%Y-%m-%d %H:%M:%S')}})

pprint(list(table.find({'releaseDate':{'$type':['date']}},{'releaseDate':1})))
pprint(list(table.find({"_id":ObjectId('611a9ef95dd672085faa3087')})))
pprint(list(table.find()))
pprint(list(table.find({},{'name': 1,'price': 1},skip=2,limit=3).sort([('price', -1),('name',1)])))
pprint(list(table.find({'price': {'$exists': True,'$gt': 699}}, {'name': 1,'price': 1})))
pprint(list(table.find(  { 'name':{'$not': {'$regex':'^Smart.+'}}}, {'name': 1})))
pprint(list(table.find({
    'storage': {
        '$gte': 64,
        '$lte': 128
    }
}, {
    'name': 1,
    'storage': 1
})))

##PCHOME

print(coll.count())
pprint.pprint(list(coll.find({'price': 13999},{'_id':0,'name':1,'price':1})))
pprint.pprint(coll.find())

# name containing asus
name_condition = {'name': {'$regex': '.*三星.*', '$options': 'i'}}
data = coll.find(name_condition)
for d in data :
    print(d)

price_condition = {'price': {'$gt': 10000}}
# data = coll.find(price_condition)

# and operator example
data = coll.find({'$and': [name_condition, price_condition]})
for d in data:
    print(d['name'], d['price'])

coll.update_one({'name': 'ASUS XG32VQR(低藍光+不閃屏)'}, {'$set': {'price': 8000}}, upsert=True )

#upsert example (insert if not exist)
coll.update_one({'name': 'Allen'}, {'$set': {'name': 'Allen'}}, upsert=True)

#delete example
coll.delete_one({'name': 'Allen'})


from django.shortcuts import render, redirect, HttpResponse

# Create your views here.
from math import radians, cos, sin, asin, sqrt
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import *
from .forms import *

@csrf_exempt
def distance(request):
    # The math module contains a function named
    # radians which converts from degrees to radians.
    if request.is_ajax and request.method == "POST":
        data = request.POST
        lat1 = float(data.get('lat1', None))
        lon1 = float(data.get('lon1', None))#data['lon1']
        lat2 = float(data.get('lat2', None))#data['lat2']
        lon2 = float(data.get('lon2', None))
        print(lat1,lon1,lat2,lon2)#data['lon2']
        lon1 = radians(lon1)
        lon2 = radians(lon2)
        lat1 = radians(lat1)
        lat2 = radians(lat2)
        print(lat1, lon1, lat2, lon2)
        # Haversine formula
        dlon = lon2 - lon1
        dlat = lat2 - lat1
        print(dlon, dlat)
        a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2

        c = 2 * asin(sqrt(a))
        print(c)

        # Radius of earth in kilometers. Use 3956 for miles
        r = 6371
        data = {
            'dist': str(c * r)
        }
        # calculate the result
        #print(JsonResponse(data))
        return JsonResponse(data)
    else:
        return redirect('home')

def store_page(request):
    books = Book.objects.filter(sold=False)
    return render(request, 'ManyBooks.html', {'books': books})

def render_single(request,uid):
    book = Book.objects.filter(uid=uid)
    if book:
        book = book[0]
        return render(request, 'OneBook.html', {'book': book})
    return HttpResponse('Bad Request')

def product_creation_page(request):
    if request.method == 'POST':

        formset = ImageForm(request.POST, request.FILES)
        postForm = BookForm(request.POST)
        # formset = ImageFormSet(request.POST, request.FILES,
        #                        queryset=Images.objects.none())
        if not postForm.is_valid():
            print('invalid 1')
        if not formset.is_valid():
            print('invalid 2')
        if postForm.is_valid() and formset.is_valid():
            name = postForm.cleaned_data['name']
            isbn = postForm.cleaned_data['isbn']
            location = str(postForm.cleaned_data['location'])
            #print(eval(location))
            book = Book(seller=request.user, name=name, isbn=isbn, location=location)
            book.save()

            # for form in formset.cleaned_data:
            #     # this helps to not crash if the user
            #     # do not upload all the photos
            #     if form:
            image = formset.cleaned_data['image']
            caption = formset.cleaned_data['caption']
            photo = ImageBook(book=book, image=image, caption=caption)
            photo.save()
            # use django messages framework
            # messages.success(request,
            #                  "Yeeew, check it out on the home page!")
            return redirect("store")

    else:
        postForm = BookForm()
        formset = ImageForm()
    return render(request, 'list_book.html',
                  {'postForm': postForm, 'formset': formset})


#!/usr/bin/env python3
import asyncio, aiohttp
import concurrent.futures
import random, struct
import argparse, logging
import dns.message
import dns.resolver
import time
import requests
import hyper
import urllib.parse
import aioh2
import ssl

# Attempt to use uvloop if installed for extra performance
try:
	import uvloop
	asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
except ImportError:
	pass

# Handle command line arguments
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--listen-address', default='127.0.0.1',
					help='address to listen on for DNS over HTTPS requests (default: %(default)s)')
parser.add_argument('-p', '--listen-port', type=int, default=53,
					help='port to listen on for DNS over HTTPS requests (default: %(default)s)')
parser.add_argument('-u', '--upstreams', nargs='+', default=['https://1.1.1.1/dns-query', 'https://1.0.0.1/dns-query'],
					help='upstream servers to forward DNS queries and requests to (default: %(default)s)')
parser.add_argument('-t', '--tcp', action='store_true', default=False,
					help='serve TCP based queries and requests along with UDP (default: %(default)s)')
parser.add_argument('--no-cache', action='store_true', default=False,
					help='don\'t cache answers from upstream servers (default: %(default)s)')
parser.add_argument('--active-cache', action='store_true', default=False,
					help='actively replace expired entries by making autonomous requests to the upstream servers (default: %(default)s)')
args = parser.parse_args()

host = args.listen_address
port = args.listen_port
upstreams = args.upstreams
headers = {'accept': 'application/dns-message', 'content-type': 'application/dns-message'}

def main():
	# Setup logging
	logging.basicConfig(level='INFO', format='[%(levelname)s] %(message)s')

	# Setup event loop
	loop = asyncio.get_event_loop()
	# executor = concurrent.futures.ProcessPoolExecutor(max_workers=4)
	# executor = concurrent.futures.ThreadPoolExecutor(max_workers=1000)
	# loop.set_default_executor(executor)

	# Connect to upstream servers
	logging.info('Connecting to upstream servers: %r' % (upstreams))
	resolver = DohResolver(cache=dns.resolver.LRUCache(50000))
	# resolver.connect([(upstream, headers) for upstream in upstreams])
	loop.run_until_complete(resolver.connect([(upstream, headers) for upstream in upstreams]))

	# Setup UDP server
	logging.info('Starting UDP server listening on: %s#%d' % (host, port))
	udp_listen = loop.create_datagram_endpoint(lambda: UdpDohProtocol(resolver), local_addr = (host, port))
	udp, protocol = loop.run_until_complete(udp_listen)

	# Setup TCP server
	if args.tcp:
		logging.info('Starting TCP server listening on %s#%d' % (host, port))
		tcp_listen = loop.create_server(lambda: TcpDohProtocol(resolver), host, port)
		tcp = loop.run_until_complete(tcp_listen)

	# Setup cache worker
	if args.active_cache:
		asyncio.ensure_future(resolver.worker(10))

	# Serve forever
	try:
		loop.run_forever()
	except (KeyboardInterrupt, SystemExit):
		pass

	# Close upstream connections
	# resolver.close()
	loop.run_until_complete(resolver.close())

	# Close listening servers and event loop
	udp.close()
	if args.tcp:
		tcp.close()

	loop.close()

class UdpDohProtocol(asyncio.DatagramProtocol):
	"""
	DNS over HTTPS UDP protocol to use with asyncio.
	"""

	def __init__(self, resolver):
		self.resolver = resolver
		self.loop = asyncio.get_event_loop()
		super().__init__()

	def connection_made(self, transport):
		self.transport = transport

	def datagram_received(self, data, addr):
		asyncio.ensure_future(self.process_packet(data, addr))

	def error_received(self, exc):
		logging.warning('Minor transport error')

	async def process_packet(self, query, addr):
		# Await upstream forwarding coroutine
		# answer = await self.loop.run_in_executor(None, self.resolver.forward, query)
		# answer = self.resolver.resolve(query)
		# answer = await self.loop.run_in_executor(None, forward, 'https://1.1.1.1/dns-query', query, headers)
		answer = await self.resolver.resolve(query)

		# TODO: try loop.run_in_executor(ProcessPool, resolver, query)

		# Send DNS packet to client
		self.transport.sendto(answer, addr)

def forward(upstream, query, headers):
	while True:
		response = requests.post(upstream, data=query, headers=headers)
		if response.status_code == 200:
			return response.content

class TcpDohProtocol(asyncio.Protocol):
	"""
	DNS over HTTPS TCP protocol to use with asyncio.
	"""

	def __init__(self, resolver):
		self.resolver = resolver
		super().__init__()

	def connection_made(self, transport):
		self.transport = transport

	def data_received(self, data):
		asyncio.ensure_future(self.process_packet(data))

	def eof_received(self):
		if self.transport.can_write_eof():
			self.transport.write_eof()

	def connection_lost(self, exc):
		self.transport.close()

	async def process_packet(self, query):
		# Await upstream forwarding coroutine (remove 16-bit length prefix)
		answer = await self.resolver.resolve(query[2:])

		# Send DNS packet to client (add 16-bit length prefix)
		self.transport.write(struct.pack('! H', len(data)) + data)

class DohConnAioh2:
	def __init__(self, upstream, headers):
		self.url = urllib.parse.urlparse(upstream)
		self.headers = headers
		self.conn = None
		self.rtt = None

	async def connect(self):
		self.conn = await aioh2.open_connection(self.url.netloc, 443, ssl=ssl.create_default_context(), functional_timeout=0.2)
		await asyncio.sleep(0.2)
		print(self.conn._transport)

	async def close(self):
		self.conn.close_connection()
		await asyncio.sleep(0.1)

	async def request(self, data, headers=None, end_stream=False):
		if not headers:
			headers = {':method': 'POST', ':path': self.url.path}

		self.rtt = await self.conn.wait_functional()
		sid = await self.conn.start_request({**self.headers, **headers})
		await self.conn.send_data(sid, data, end_stream=end_stream)
		return sid

class DohConn:
	"""
	DNS over HTTPS upstream connection class.
	"""

	def __init__(self, upstream, headers):
		self.url = urllib.parse.urlparse(upstream)
		self.headers = headers
		self.conn = None

	def connect(self):
		self.conn = hyper.HTTP20Connection(self.url.netloc, port=443, secure=True)
		self.conn.connect()

	def close(self):
		self.conn.close()

	def request(self, method, body=None, headers=None):
		if not headers:
			headers = self.headers

		return self.conn.request(method, self.url.path, body=body, headers=headers)

	def response(self, sid=None):
		return self.conn.get_response(stream_id=sid)

class DohResolver:
	"""
	DNS over HTTPS resolver class.
	"""

	def __init__(self, cache=None):
		self.conns = []
		self.cache = cache

	async def connect(self, upstreams):
		"""
		Prepare connection object corresponding to upstream servers.
		"""

		for (url, headers) in upstreams:
			# connection = DohConn(url, headers)
			# connection.connect()
			connection = DohConnAioh2(url, headers)
			await connection.connect()
			self.conns.append(connection)

	async def close(self):
		"""
		Close connection to upstream server.
		"""

		for conn in self.conns:
			# conn.close()
			await conn.close()

	async def resolve(self, query, update=False):
		"""
		Resolve a DNS query using a cache or upstream server.

		Params:
			query  - normal wireformat DNS query
			update - only update cache entry for this query

		Returns:
			A normal wireformat DNS answer.
		"""

		# Check cache if necessary
		if self.cache and not update:
			# Convert wireformat to message object
			request = dns.message.from_wire(query)
			id = request.id
			request = request.question[0]
			request = (request.name, request.rdtype, request.rdclass)

			# Return cached entry if possible
			cached = self.cache.get(request)
			if cached:
				cached.response.id = id
				answer = cached.response.to_wire()
				return answer

		# Resolve via upstream server
		# answer = self.forward(query)
		answer = await self.forward_aioh2(query)

		# Add answer to cache if necessary
		if self.cache:
			if update:
				# Convert wireformat to message object
				request = dns.message.from_wire(query)
				id = request.id
				request = request.question[0]
				request = (request.name, request.rdtype, request.rdclass)

			response = dns.message.from_wire(answer)
			response = dns.resolver.Answer(*request, response, False)
			self.cache.put(request, response)

		return answer

	def forward(self, query):
		"""
		Perform DNS over HTTPS lookup using POST method.

		Params:
			query - normal wireformat DNS query

		Returns:
			A normal wireformat DNS answer.

		Notes:
			Using DNS over HTTPS POST format as described here:
			https://tools.ietf.org/html/draft-ietf-doh-dns-over-https-12
			https://developers.cloudflare.com/1.1.1.1/dns-over-https/wireformat/
		"""

		# Await upstream response
		index = 0
		while True:
			sid = self.conns[index].request('POST', body=query)
			http = self.conns[index].response(sid=sid)

			if http.status == 200:
				return http.read()

			index = (index + 1) % len(self.conns)

	async def forward_aioh2(self, query):
		index = 0
		while True:
			conn = self.conns[index]
			sid = await conn.request(query, end_stream=True)
			http = await conn.conn.recv_response(sid)
			print(http)
			return await conn.conn.read_stream(sid, -1)

	async def worker(self, period, max=1000):
		"""
		Worker to process cache entries and preemptively replace expiring entries.

		Params:
			period - time to wait between cache scans (in seconds)
			max    - maximum number of concurrent autonomous requests (0 means unlimited)

		"""

		while True:
			expiring = 0

			for request, response in self.cache.data.items():
				if response.value.expiration > (time.time() + period):
					continue

				query = dns.message.make_query(*request).to_wire()
				asyncio.ensure_future(self.resolve(query, True))
				expiring += 1

				if max and expiring >= max:
					break

			if expiring > 0:
				logging.info('Cache, updating %d/%d' % (expiring, len(self.cache.data)))

			await asyncio.sleep(period)

if __name__ == '__main__':
	main()


import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt

"""This is a program that takes a filename as a  parameter containing information
   about albums. It should prompt the user for a filename, read the information into
   lines, extract the information into a library and then print it in a formatted
   table.
   Author: Rachel Hodgson
   Date: 25-05-2019
"""
import os.path #used to check the validity of the filename when prompted
import matplotlib.pyplot as plt

class Album:
    """Stores the information about an album"""
    def __init__(self, album_id, name, band, cost):
        """The data that forms an album, note that:
        - album_id is a int
        - cost is a float
        - the rest are strings
        """
        self.album_id = album_id
        self.name = name
        self.band = band
        self.cost = cost
        self.total_sold = 0
        self.certificate = ""

    def add_to_sold(self, count):
        """Adds to the internal album counter of the album"""
        if count >= 0:
            self.total_sold += count
            return self.total_sold
        else:
            template = "Attempt to add {} to Album: {}. VALUE MUST NOT BE NEGATIVE"
            raise ValueError(template.format(count, self.album_id))

    def add_certificate(self):
        """Taks the total sold and returns a status level"""
        status = int(self.total_sold)
        if status < 50000:
            self.certificate = ""
        elif status >= 50000 and status < 100000:
            self.certificate = "Gold"
        elif status >= 100000 and status < 500000:
            self.certificate = "Platinum"
        elif status >= 500000:
            self.certificate = "Diamond"

    def __repr__(self):
        """Creates the string function needed to return the correct values to
           the function by making it a string so it can be represented, in this
           case it is only the name because that is all required so far"""
        return ("{:<5}{:<30}{:>10}{:>15}".format(self.album_id, self.name, self.total_sold,
                                                 self.certificate))

def get_filename():
    """Asks user for the filename"""
    filename = None
    while filename is None:
        filename = input("Enter a data file name: ")
        if not os.path.isfile(filename): #if the file doesn't exist
            print("Invalid File Name Entered!")
            filename = None

    infile = open(filename)
    lines = infile.readlines()
    infile.close()
    return (lines, filename)

def extract_album(lines, index):
    """Takes a set of lines as a parameter and an index for the lines and returns
       the information in the lines on an album using the __str__ function in Album"""
    for line in lines[index:]:
        line = line.strip()
        albumid = int((lines[index + 1]).strip())
        name = (lines[index + 2]).strip()
        band = (lines[index + 3]).strip()
        cost = float((lines[index + 4]).strip())
        return Album(albumid, name, band, cost) #makes all info possible class attributes

def extract_all_albums(lines):
    """Takes a list of lines as a parameter containing information on an album.
       Returns the album information as a dictionary comparing the album id to
       the relveant information on the albums."""
    album_dict = {}
    for index, line in enumerate(lines):
        if line.startswith("<a"):
            line_index = int(index)
            line = line.strip()
            albumid = int((lines[index + 1]).strip())
            album_classed = extract_album(lines, line_index)
            album_dict[albumid] = album_classed #assigns the key(id) to the values
    return album_dict

def read_sales(lines, albums):
    """Reads the sales files and runs the add_to_sold function on the album data
       that has ahd sales as shown in the sales tags. Then returns the albums
       dictionary again with the updated sales ready to print the table"""
    start_index = None
    end_index = None
    for line in lines:
        if line.startswith("<s"):
            start_index = int(lines.index(line)) #finding the start and end indexes
        elif line.startswith("</s"):
            end_index = int(lines.index(line))
    if start_index == None and end_index == None:
        pass
    elif start_index != None and end_index != None:
        sales_lines = lines[start_index + 1:end_index]
        for line in sales_lines:
            _, albumid, sold = line.split(",") #splits up the data lines
            for album_id, albuminfo in albums.items():
                if int(album_id) == int(albumid):
                    albuminfo.add_to_sold(int(sold)) #adds all the sold amounts of albums
                albuminfo.add_certificate() #adds the certificate based on the totals
    return albums

def total_sold(album):
    """Helper function that returns total_sold to enable the sort key which
       has to be a function"""
    return album.total_sold

def print_graph(sorted_albums, total_sales):
    """Prints our the sales bar graph portion of the program"""
    for album in sorted_albums:
        percentage = (100 / int(total_sales)) * int(album.total_sold)
        percentage = int(percentage)
        lines = "=" * int(percentage)
        print("{:>4}{:>5}% {}".format(album.album_id, percentage, lines))

def print_matplotlib(sorted_albums, total_sales):
    total_sales = int(total_sales)
    data = []
    for album in sorted_albums:
        percentage = (100 / int(total_sales)) * int(album.total_sold)
        album_id = album_id # Some random numbers for testing
        data.append(percentage)

    axes = plt.axes()
    axes.bar(range(total_sales), data, tick_label=album_id)
    axes.set_title("Album Sales Summary 'filename'")
    axes.set_xlabel("Album ID")
    axes.set_ylabel("Percent of Total Sales")
    plt.show()

def print_table(album_dict, filename):
    """Prints the information from the functions into a formatted table"""
    print()
    print("Album Catalogue Summary")
    print("-" * 60)
    print('{:<5}{:<30}{:>10}{:>15}'.format("ID", "ALBUM NAME", "# SOLD", "CERTIFICATE"))
    sorted_albums = sorted(album_dict.values(), key=total_sold, reverse=True)
    for album in sorted_albums:
        print(album)
    print()
    print("Sales Bar Graph")
    print("-" * 30)
    print("  {:<4}{:>5}".format("ID", "Freq Graph"))
    total_sales = 0
    for album in sorted_albums:
        total_sales += int(album.total_sold)
    print_graph(sorted_albums, total_sales)
    make_barchart(album_dict, sorted_albums, filename, total_sales)

def make_barchart(album_dict, sorted_albums, filename, total_sales):
    albumids = []
    for albumid, albums in album_dict:
        albums.append(albumid)

    albumids = tuple(albumids)
    y_pos = np.arange(len(albumids))
    percentage = []

    for album in sorted_albums:
        percent = (100 / int(total_sales)) * int(album.total_sold)
        percent = int(percent)
        percentage.append(percent)

    plt.bar(y_pos, percentage, align='center', alpha=0.5)
    plt.xticks(y_pos, albumids)
    plt.ylabel('Percentage of total sales')
    plt.xlabel('Album ID')
    plt.title('Album sales summary ({})'.format(filename))

    plt.show()

def main():
    """Runs the main code"""
    lines, filename = get_filename()
    album_dictionary = extract_all_albums(lines)
    album_dictionary = read_sales(lines, album_dictionary)
    print_table(album_dictionary, filename)

main()


import json
import requests

octopus_server_uri = 'https://your.octopus.app/api'
octopus_api_key = 'API-YOURAPIKEY'
headers = {'X-Octopus-ApiKey': octopus_api_key}

def get_octopus_resource(uri):
    response = requests.get(uri, headers=headers)
    response.raise_for_status()

    return json.loads(response.content.decode('utf-8'))

space_name = 'Default'
azure_account_name = 'Your Azure Account Name'
environment_names = ['Development', 'Test']
roles = ['your-product-web']

spaces = get_octopus_resource('{0}/spaces/all'.format(octopus_server_uri))
space = next((x for x in spaces if x['Name'] == space_name), None)

azure_accounts = get_octopus_resource('{0}/{1}/accounts/all'.format(octopus_server_uri, space['Id']))
azure_account = next((x for x in azure_accounts if x['Name'] == azure_account_name), None)

environments = get_octopus_resource('{0}/{1}/environments/all'.format(octopus_server_uri, space['Id']))
environment_ids = [e['Id'] for e in environments if e['Name'] in environment_names]

azure_web_app = {
    'Name': 'New Azure Web App',
    'EndPoint': {
        'CommunicationStyle': 'AzureWebApp',
        'AccountId': azure_account['Id'],
        'ResourceGroupName': 'Your Resource Group',
        'WebAppName': 'Your Web App'
    },
    'Roles': roles,
    'EnvironmentIds': environment_ids
}

uri = '{0}/{1}/machines'.format(octopus_server_uri, space['Id'])
response = requests.post(uri, headers=headers, json=azure_web_app)
response.raise_for_status()


from playground.network.packet import PacketType
import playground, time
import getpass, os, asyncio
import sys

from autograder_ex8_packets import *
from escape_room_packets import *
from payProcedure import *

class EchoClientProtocol(asyncio.Protocol):
    def __init__(self):
        self.flag = 0
        self.loop = asyncio.get_event_loop()
        self.deserializer = PacketType.Deserializer()
        self.command_list = ["look mirror", "get hairpin", "unlock chest with hairpin", "open chest",
                             "get hammer in chest", "hit flyingkey with hammer", "get key", "unlock door with key",
                             "open door"]

    def connection_made(self, transport):
        self.transport = transport
        packetClient = AutogradeStartTest()
        packetClient.name = "Tianshi Feng"
        packetClient.team = 4
        packetClient.email = "tfeng7@jhu.edu"
        packetClient.port = 1026
        # with open("escape_room_packets.py", "rb") as f:
        #     packetClient.packet_file = f.read()
        self.transport.write(packetClient.__serialize__())

        user_packet = create_game_init_packet("tfeng7")
        self.transport.write(user_packet.__serialize__())

    def data_received(self, data):
        self.deserializer.update(data)
        print(data)
        for clientPacket in self.deserializer.nextPackets():
            if isinstance(clientPacket, AutogradeTestStatus):
                print(clientPacket.submit_status)
                print(clientPacket.client_status)
                print(clientPacket.server_status)
                print(clientPacket.error)

            if isinstance(clientPacket, GameRequirePayPacket):
                unique_id, account, amount = process_game_require_pay_packet(clientPacket)
                print(unique_id)
                print(account)
                print(amount)
                self.loop.create_task(self.CreatePayment(account, amount, unique_id))

            if isinstance(clientPacket, GameResponsePacket):
                res_temp = clientPacket.response
                print(clientPacket.response)
                if self.flag <= len(self.command_list) - 1:
                    if res_temp.split()[-1] == "wall" or res_temp.split()[-1] == "floor" or res_temp.split()[-1] == "ceiling":
                        continue
                    if res_temp == "You can't hit that!":
                        self.flag = self.flag - 1
                        command = create_game_command(self.command_list[self.flag])
                        self.transport.write(command.__serialize__())
                        print(self.command_list[self.flag])
                        self.flag = self.flag + 1
                    else:
                        command = create_game_command(self.command_list[self.flag])
                        self.transport.write(command.__serialize__())
                        print(self.command_list[self.flag])
                        self.flag = self.flag + 1
                time.sleep(1)

    async def CreatePayment(self, account, amount, unique_id):
        result = await paymentInit("tfeng7_account", account, amount, unique_id)
        print(result)
        receipt, receipt_sig = result
        game_packet = create_game_pay_packet(receipt, receipt_sig)
        self.transport.write(game_packet.__serialize__())

    def connection_lost(self, exc):
        print('The server closed the connection')
        print('Stop the event loop')
        self.loop.stop()

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.set_debug(enabled=True)
    from playground.common.logging import EnablePresetLogging, PRESET_DEBUG

    EnablePresetLogging(PRESET_DEBUG)
    coro = playground.create_connection(lambda: EchoClientProtocol(), '20194.0.0.19000', 19008)

    # coro = loop.create_connection(lambda: EchoClientProtocol(loop), 'localhost', 1024)
    loop.run_until_complete(coro)
    loop.run_forever()
    loop.close()


from abc import ABC, abstractmethod

from parsers import *

class Provider(ABC):
    def parser(self, parsers, payload):
        aggregator = payload

        for parser in parsers:
            [unpack] = list(parser.items())
            name, expression = unpack

            aggregator = globals()[name.capitalize()](
                aggregator, expression
            ).parser()

        return aggregator


#!usr/bin/env python

"""
This module deals with kpoints.
"""

from aiida.engine import calcfunction
from aiida.orm import Bool, Dict, StructureData
from twinpy.interfaces.aiida.base import get_cell_from_aiida
from twinpy.common.kpoints import Kpoints
from twinpy.structure.lattice import CrystalLattice

@calcfunction
def fix_kpoints(calculator_settings:Dict,
                structure:StructureData,
                kpoints_conf:Dict,
                is_phonon:Bool) -> Dict:
    """
    Fix kpoints using kpoints interval.

    Args:
        calculator_settings: Calculator settings for relax or phonon.
        structure: Original structure.
        kpoints_conf: Kpoints configuration. All keys are parsed to
                      twinpy.common.kpoints.Kpoints.
                      For more detailed information,
                      see Examples and def get_mesh_offget_auto
                      in twinpy.common.kpoints.Kpoints class.
        is_phonon: Input calculator_settings are for relax or phonon.

    Examples:
        Example of kpoints_conf is as bellow.

        >>> kpoints_conf = Dict(dict={
        >>>     'interval': 0.15,
        >>>     'decimal_handling': 'round',
        >>>     'use_symmetry': True,
        >>>     })

    Returns:
        Dict: Fixed calculator settings.
    """
    lattice = get_cell_from_aiida(structure)[0]
    if is_phonon:
        run_mode = 'phonon'
        dim = calculator_settings[run_mode]['phonon_conf']['supercell_matrix']
        input_lattice = CrystalLattice(lattice).get_expanded_lattice(dim)
    else:
        run_mode = 'relax'
        input_lattice = lattice

    twinpy_kpt = Kpoints(lattice=input_lattice)
    mesh, offset = twinpy_kpt.get_mesh_offset_auto(**kpoints_conf)
    kpoints = {'mesh': mesh, 'offset': offset}
    calc_settings = calculator_settings.get_dict()
    calc_settings[run_mode]['kpoints'] = kpoints
    return_vals = {}
    return_vals['calculator_settings'] = Dict(dict=calc_settings)

    return return_vals


from flask import Flask
from flask import render_template, redirect,request
import os,random
from datetime import datetime
import time
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
#主页面
@app.route('/')
def show():
    #获取图片存储的路径下的所有文件
    fileslist=os.walk(basedir+'/static/')
    #定义一个列表
    list=[]
    #将所有文件进行遍历，存入列表中
    for root,dir,i in fileslist:
        list.extend(i)
    #如果有图片则返回第一张
    if len(list)!=0:
        image=list[0]
    else:
        #没有则返回none
        image=None
    return render_template('index.html',str=image,index=0)
#上下跳转
@app.route('/nextprev')
def nextprev():
    #获取文件夹路径
    fileslist = os.walk(basedir + '/static/')
    #跟上面的方式一样读出所有文件
    list = []
    for root, dir, i in fileslist:
        list.extend(i)
    #获取是上一张还是下一张（0为上一张，1为下一张）
    type = request.args.get('type')
    #获取文件的下标id
    id = request.args.get('id')
    #如果为上一张请求
    if int(type) == 0:
        #判断id是不是0，为0则是第一张，无法完成上一张请求，如果不是第一张，则id值减一
        if int(id) != 0:
            id = int(id) - 1

    else:
        #如果是下一张请求，判断是不是id值等于所有的图片数和减一，如果是，则是最后一张，不是则加一
        if int(id) != len(list) - 1:
            id = int(id) + 1
    image = list[int(id)]

    return render_template('index.html', str=image, index=id)

#添加一张
@app.route('/option',methods=['POST'])
def optionfile():
    #post请求
    if request.method=='POST':
        #获取图片文件
        img =request.files.get('upiamge')
        id =request.form.get('id')

        name2=str(img)
        print(name2)
        if 'jpg' in name2 or 'png' in name2 or 'jpeg' in name2 or 'gif' in name2:
            #获取时间戳作为图片名
            now=int(time.time()*1000)
            name=str(now)
        #定义保存地址
            path=basedir+'/static/'+name+'.png'
            #保存图片
            img.save(path)
            image=name+'.png'
            fileslist = os.walk(basedir + '/static/')
            # 跟上面的方式一样读出所有文件
            list = []
            #获取所有的图片
            for root, dir, i in fileslist:
                list.extend(i)

            return render_template('index.html',str=image,index=len(list)-1)
        else:

            return  '上传失败'
@app.route('/del',methods=['GET'])
def delfile():
    #获取图片名
    image=request.args.get('name')
    id=request.args.get('id')
    #拼接路径
    path=basedir+'/static/'+image
    #删除文件
    os.remove(path)
    fileslist = os.walk(basedir + '/static/')
    # 跟上面的方式一样读出所有文件
    list = []
    # 获取所有的图片
    for root, dir, i in fileslist:
        list.extend(i)
    #获取上一张图片地址
    #如果图片id不为0，则id减一获取上一张图片
    if int(id)!=0:
        img =list[int(id)-1]
        id=int(id)-1
        #如果为0则说明是第一张图片
    else:
        #判断是否只有一张图片，如果只有一张图片，删除后无数据显示
        if len(list)==0:
            img=None
            id=0
        #有其他图片，则显示下一张图片
        else:
            img=list[int(id)]
            id=id

    return render_template('index.html',str=img,index=int(id))
if __name__ == '__main__':
    app.run()


"""OxygenC v0.1.0

usage:
    oxygenc compile [-ldo FILE] <file>
    oxygenc run [-td] <file>
    oxygenc [-hv]

options:
    -h, --help                  Shows this help menu
    -v, --version               Shows the version
    -l, --llvm                  Emit llvm code
    -o FILE, --output FILE      Output file
    -t, --timer                 Time the execution
    -d, --debug                 Debug mode
"""

import os
from typing import Dict, Any

from docopt import docopt
from oxygen.compiler.code_generator import OxyCodeGenerator
from oxygen.lexer import Lexer
from oxygen.parser import Parser
from oxygen.type_checker import Preprocessor
from oxygen.utils import error

def process_file(oxy_file: str) -> OxyCodeGenerator:
    if not os.path.isfile(oxy_file):
        error(oxy_file + " is not a valid file")

    code = open(oxy_file, encoding="utf8").read()
    lexer = Lexer(code, oxy_file)
    parser = Parser(lexer)
    prog = parser.parse()
    symtab_builder = Preprocessor(oxy_file)
    symtab_builder.check(prog)

    generator = OxyCodeGenerator(oxy_file)
    generator.generate_code(prog)

    return generator

def _run(arg_list: Dict[str, Any]) -> None:
    oxy_file: str = arg_list['<file>']
    timer: bool = arg_list['--timer']
    debug: bool = arg_list['--debug']

    generator = process_file(oxy_file)
    generator.evaluate(not debug, debug, timer)

def _compile(arg_list: Dict[str, Any]) -> None:
    oxy_file: str = arg_list['<file>']
    output: str = arg_list['--output']
    emit_llvm: bool = arg_list['--llvm']
    debug: bool = arg_list['--debug']

    generator = process_file(oxy_file)
    generator.compile(oxy_file, not debug, output, emit_llvm)

if __name__ == "__main__":
    args: Dict[str, Any] = docopt(__doc__, version='v0.4.1')

    if args['compile']:
        _compile(args)
    elif args['run']:
        _run(args)
    else:
        exit(__doc__)


# -*- coding: utf-8 -*-
"""
Created on Tue Aug 25 20:49:28 2020

@author: esmos
"""

# -*- coding: utf-8 -*-
"""
Created on Mon Jul 20 21:28:24 2020

@author: Mostafa
"""
import numpy as np
import copy
import time

#this function sorts matrix m (m must be in row format) in descending order and matrix B according to it
def sortindesorder(m,B):
    num_columns=len(m)
    for i in range(num_columns-1):
        for j in range (i+1, num_columns):
            if (m[j] > m[i] ):
                x=m[i]
                m[i]=m[j]
                m[j]=x
                B[[i,j]] = B[[j,i]]
    return m , B

#this function returns TRUE if k is in the set A (A has to be in the form of a row matrix)
def iskinset(A,k):
    num_columns=len(A)
    for i in range(num_columns):
        if (A[i] == k):
            return True
    return False

#this function finds the intraset difference of elements in set A (A has to be in the form of a row matrix)
#with a number m
def findintrasetdiff(A,m):
    num_columns=len(A)
    intradiff=np.zeros(num_columns)
    for i in range(num_columns):
        intradiff[i]=abs(A[i]-m)
    intradiff=intradiff.astype(int)
    return intradiff

#this function returns TRUE if the intersect of two sets A & B (given in row matrix format)
#is null
def isintersectnull(A, B):
    num_col_A=len(A)
    num_col_B=len(B)
    for i in range(num_col_A):
        for j in range(num_col_B):
            if (B[j] == A[i]):
                return False
    return True

#this function does Gauss-Jordan row operations on a binary rectangular matrix to
#put it into RREF. That is, a matrix with the unit matrix on the left hand side. The output
#is two matrices. The first is the input matrix in RREF. The second is a hard copy of the input
# for purposes where the non-RREF is needed.
def rref(A):
    num_rows=len(A)
    num_columns=len(A[0])
    copy_of_A=copy.deepcopy(A)
    for i in range(num_rows):
        if (A[i][i] != 1): #check if the element on the diagonal is one
            for k in range(i+1,num_columns):#if it isnt change that column with a column that has a one in that row
                if (A[i][k] == 1):
                    A[:,[i, k]]=A[:,[k, i]]
                    copy_of_A[:,[i, k]]=copy_of_A[:,[k,i]]
                    break
        for j in range(num_rows):
            if (j==i):
                continue
            if (A[j][i] == 1):
                A[j]=(A[i]+A[j])%2
    return A, copy_of_A

#this function finds the inverse of  a square binary matrix. This is done by concatenating it with
#an identity matrix on the right hand side and performing Gauss-Jordan elimination
#to put it into RREF. The output is the binary inverse of the input.
def inverse(A):
    num_rows=len(A)
    inv=np.concatenate((A, np.identity(num_rows, dtype=int)), axis=1)
    for i in range(num_rows):
        if (inv[i][i] != 1):
            for k in range(i+1, num_rows):
                if (inv[k][i] == 1):
                    inv[[i,k]]=inv[[k,i]]
                    break
        for j in range(num_rows):
            if (i == j):
                continue
            else:
                if (inv[j][i] == 1):
                    inv[j]=(inv[j]+inv[i])%2
    X=inv[:,num_rows:2*num_rows]
    return X

#this function finds the right inverse of a parity check matrix in systematic form.
def rightinverse(systematic_parity_check):
    num_rows=len(systematic_parity_check)
    num_columns=len(systematic_parity_check[0])
    B_prime=systematic_parity_check[:,num_rows:num_columns]
    right_inverse_matrix=np.zeros((num_columns, num_rows), dtype=int)
    A_prime=np.random.randint(2, size=(num_columns-num_rows, num_rows))
    right_inverse_matrix[num_rows:num_columns,:]=A_prime
    A=(np.identity(num_rows, dtype=int)+B_prime.dot(A_prime))%2
    right_inverse=np.vstack((A, A_prime))
    return right_inverse

#this function signs a document and returns the signature along with the syndrome used in
#signing the document. This signature scheme is based on a code-based PKC.
def signature(document, generator_matrix_systematic, parity_check, inverse_parity_check):
    num_rows=len(generator_matrix_systematic)
    num_columns=len(generator_matrix_systematic[0])
    syndrome=document.dot(parity_check.transpose())%2
    sign_generator_matrix=(document+syndrome.dot(inverse_parity_check.transpose()))%2
    sign=sign_generator_matrix[:,num_columns-num_rows:num_columns]
    return sign, syndrome

#this function verifies the signature of a document. If the signature is valid, the function returns TRUE
#otherwise it returns FALSE
def verify(sign, syndrome, document, generator_matrix, inverse_parity_check):
    if (document.all() == ((sign.dot(generator_matrix) + syndrome.dot(inverse_parity_check.transpose()))%2).all()):
        return True
    else:
        return False

#This is for generating etended difference families. The families are given in
#a mtrix called ext_diff_fam where each row is a set and each column is a member
#of the corresponding set.
t=input('Enter the number of sets in EDF ') #t is the number of sets B_t
omega=input('Enter the number of elements in each set ') #omega is the number of elements in each B_t
# start_time_1=time.process_time_ns()
start_time_1=time.process_time()
t=int(t)
omega=int(omega)
ext_diff_fam = np.zeros((t,omega), dtype=int) #the rows are B_t's and the columns are the elements in each set
distance = np.zeros(t, dtype=int) #this is the set of distances
m=np.arange(1,t+1, dtype=int)
for i in range(1,t+1):
    ext_diff_fam[i-1][1]=i
    distance[i-1]=i
m,ext_diff_fam = sortindesorder(m,ext_diff_fam)
count=2 #count counts the number of elements in B_t
while (count<omega):
    for w in range(t):
        j=t+1 #finding smallest positive integer not in distance starting from t+1 (since distance already has 1 to t)
        while (j>0):
            if (iskinset(distance,j) == False): #check if new distance is within the distance set
                candidate=m[w]+j #find the new candidate=m+j
                new_distances=abs(candidate-ext_diff_fam[w]) #compute the new distances of candidate and the corresponding set B_w
                if (isintersectnull(new_distances,distance) == True): #check if the intesect of the new distances does not overlap the previous ones
                    ext_diff_fam[w][count]=candidate #set the new element in B_w to j
                    distance=np.hstack((distance, new_distances)) #update the distance set
                    distance=np.unique(distance) #remove repetitive numbers from distance set
                    m[w]=candidate #update m_l=c
                    break #get out of loop and move onto next set
                else:
                    j=j+1 #if distances overlap find next distance
            else:
                j=j+1
    m,ext_diff_fam = sortindesorder(m,ext_diff_fam)
    count=count+1
#This part generates the first column of each circulant matrix based on the extended difference families.
#The output is a matrix called
#first_column where each column is the first column of the corresponding circulant
print("The maximum intraset distance is", distance[-1])
round_1_time=time.process_time()-start_time_1
# round_1_time=time.process_time_ns()-start_time_1
prime_field=input('Enter the order of the prime field to generate parity check matrix ') #enter order of prime field Z_prime
# start_time_2=time.process_time_ns()
start_time_2=time.process_time()
prime_field=int(prime_field)
circulants_first_row=np.zeros((1,prime_field), dtype=int) #first row of circulant from each row of ext_diff_fam
parity_check=np.zeros((1,prime_field), dtype=int) #allocating space for the first row of the parity check matrix
for j in range(omega):
    circulants_first_row[0][ext_diff_fam[t-1][j]]=1 #generate the first row of the parity check matrix from B_1
parity_check=circulants_first_row #enter the first row into the parity check matrix
for k in range(1,prime_field):
    parity_check=np.vstack((parity_check,np.roll(circulants_first_row,k)))# add rows from the first row by circular shifting
for i in range(t-1): #generate the first row from each extended diff family B_i
    circulants_first_row=np.zeros((1,prime_field), dtype=int) #reset the first row of circulants for corresponding B_i
    for j in range(omega):
        circulants_first_row[0][ext_diff_fam[t-2-i][j]]=1 #generate the first row of the circulant corresponding to B_i
    for k in range(prime_field):
        parity_check=np.vstack((parity_check,np.roll(circulants_first_row,k))) #add the circulant and shifted versions of it to the previous parity check matrix
parity_check=parity_check.transpose() #transpose the parity check matrix to put it in conventional format

#This part finds a generator matrix from the parity check matrix by first
#changing the obtained parity check matrix to a systematic parity check matrix

parity_check, official_parity_check = rref(parity_check)
P=parity_check[:,prime_field:prime_field*t] #take the parity check sub-matrix of the obtained systematic parity check matrix
#concatenate the transpose of the parity check submatrix with an identity matrix to obtain a systematic generator matrix
generator_matrix=np.concatenate((P.transpose(), np.identity(prime_field*(t-1), dtype=int)), axis=1)

#this part finds a right inverse of the systematic parity check matrix using the
#rightinverse function.
right_inverse=rightinverse(parity_check)
round_2_time=time.process_time()-start_time_2
# round_2_time=time.process_time_ns()-start_time_2
print('Total key generation time is', round_1_time + round_2_time, 'seconds')

#this part signs a random document and verifies the signature.
rounds=input("Enter how many times you would like to run the signing and verifying process ")
rounds=int(rounds)
sign_and_verification_time=time.process_time()
for i in range(rounds):
    document=np.random.randint(2, size=(1,prime_field*t))
    sign, syndrome = signature(document, generator_matrix, parity_check, right_inverse)
    ver=verify(sign, syndrome, document, generator_matrix, right_inverse)
    if (ver == False):
        print("Signature verification failed")
        break
sign_and_verification_time=time.process_time()-sign_and_verification_time
print("The signing and verification time is", sign_and_verification_time/rounds, "seconds")

Signature scheme with inverse parity check.py


from control import*
from matplotlib import*
from pylab import*
from math import*
from numpy import*
from IPython.html.widgets import*
def pole_zero(TF):
    poles = pole(TF)
    zeros = zero(TF)
    plot(real(zeros),imag(zeros),'o',label = "Zeros")
    plot(real(poles),imag(poles),'x',label = "Poles")
    title("Zero-Pole Map")
    xlabel("Real")
    ylabel("Imaginary")
    axhline(0,0,1)
    axvline(0,0,1)
def bode_magnitude(wout,mag):
    semilogx(wout,mag)
    title("Bode-Magnitude")
    xlabel("w[rad/s]")
    ylabel("Magnitude")
def bode_phase(wout,phase):
    semilogx(wout,phase)
    title("Bode-Phase")
    xlabel("w[rad/s]")
    ylabel("Phase")


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('advt', '0002_auto_20160602_2036'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='company',
            options={'verbose_name': '\u041a\u0430\u043c\u043f\u0430\u043d\u0438\u044f', 'verbose_name_plural': '\u041a\u0430\u043c\u043f\u0430\u043d\u0438\u0438'},
        ),
        migrations.AddField(
            model_name='company',
            name='source_id',
            field=models.CharField(default=12, max_length=255, verbose_name=b'ID \xd0\xbc\xd0\xbe\xd0\xb4\xd0\xb5\xd0\xbb\xd0\xb8 \xd0\xb8\xd1\x81\xd1\x82\xd0\xbe\xd1\x87\xd0\xbd\xd0\xb8\xd0\xba\xd0\xb0'),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='company',
            name='account_leadr',
            field=models.CharField(max_length=255, verbose_name=b'\xd0\x90\xd0\xba\xd0\xba \xd0\xb2 \xd1\x81\xd0\xb8\xd1\x81\xd1\x82\xd0\xb5\xd0\xbc\xd0\xb5 lead-R'),
        ),
        migrations.AlterField(
            model_name='company',
            name='source',
            field=models.SmallIntegerField(default=0, verbose_name=b'\xd0\x98\xd1\x81\xd1\x82\xd0\xbe\xd1\x87\xd0\xbd\xd0\xb8\xd0\xba', choices=[(0, b'VK Ads'), (1, b'Yandex Metrika'), (2, b'Google Adwords'), (3, b'My Target')]),
        ),
        migrations.AlterField(
            model_name='offer',
            name='budget',
            field=models.DecimalField(default=0.0, verbose_name=b'\xd0\x91\xd1\x8e\xd0\xb4\xd0\xb6\xd0\xb5\xd1\x82', max_digits=10, decimal_places=2),
        ),
        migrations.AlterField(
            model_name='offer',
            name='geo',
            field=models.CharField(default=b'\xd0\xa0\xd0\xa4', max_length=20, verbose_name=b'\xd0\x9b\xd0\xbe\xd0\xba\xd0\xb0\xd1\x86\xd0\xb8\xd1\x8f'),
        ),
    ]


# -*- coding: utf-8 -*-
u"""由于有NG3.x 版本SAEGW的AS/SAB存在内存泄露的问题，导致发生终端用户上网困难等多种症状非常多样，
需要对SAE经常检查内存是否泄露。
"""
import re
from libs.checker import CheckStatus,ResultInfo
from libs.flexing import get_ng_version
from libs.tools import MessageBuffer

## Mandatory variables
##--------------------------------------------
module_id = 'NG20150518.01'
name      = "FlexiNG(NG3.x) AS/SAB Memory leak Check"
version   = '1.0'
desc      = __doc__
tags      = ['flexing','china']
priority  = 'critical'

mem_threshold = {'AS':110,'SAB':500}  #MB
criteria      = u"""正常的内存利益率: AS < %(AS)sMB or SAB < %(SAB)sMB

解决方案：
  1. 有条件关闭 hicut 的项目就关闭（因为关闭 hitcut 会导致 Node 负荷小幅增加，需要提前检查 CPU 使用情况）。
  2. 没有条件关 hitcut 的项目，必需要把检查内存利用率的操作列入日常的维护计划
""" % mem_threshold

## Optional variables
pat_memfail = re.compile("ssh ([\w\d-]+) showstat\|.*?mem_alloc_failed_for_linear_filters = (\d+)",re.DOTALL)
pat_memallo = re.compile("info ([\w\d-]+) featuremem.*FASTPATH_MALLOC dynamic allocated bytes \[chunks\]: (\d+)/(\d+)")

logline_format = "    - %s"
##

def check_memory_fail_counter(loglines):
    _logblk=''.join(loglines)
    status = CheckStatus.UNKNOWN
    info = MessageBuffer(lineformat=logline_format)
    error = ''

    _results = pat_memfail.findall(_logblk)
    for node,cnt in set(_results):
        if int(cnt) > 0:
            status = CheckStatus.FAILED
            info.append("** %s has %s times memory failed." % (node,cnt))

    return status,info.buffer,error

def check_memory_allocation(loglines):
    status = CheckStatus.UNKNOWN
    flag_fail = False
    flag_passed = False
    info = MessageBuffer(lineformat=logline_format)
    error = ''
    _mem = {'AS':[],'SAB':[]}

    for line in loglines:
        r2 = pat_memallo.search(line)
        if r2:
            mem = int(r2.groups()[1])/1024.0/1024.0
            node = r2.groups()[0]
            node_type = re.sub('[\d+-]','',node)
            _mem[node_type].append((node,mem))
            #print "mem allocated!",node,mem,node_type,mem_threshold[node_type]
            if mem > mem_threshold[node_type]:
                flag_fail = CheckStatus.FAILED
                info.append('%s memory is closing to full: %.5s MB\n' %(node, mem))
            else:
                flag_passed = CheckStatus.PASSED
                info.append("%s memory: %s\n" %(node,mem))

    status = (flag_fail or flag_passed) or CheckStatus.UNKNOWN

    if status == CheckStatus.UNKNOWN:
        info.append("Can't found the memory usage info.")
    if status !=CheckStatus.FAILED:
        for ntype,memlist in _mem.items():
            if len(memlist) == 0: continue
            maxmem=sorted(memlist,key=lambda x:x[1],reverse=True)[0]
            info.append('%s has a max memory %.6s MB\n' % maxmem)

    return status,info.buffer,error

## Mandatory function: run
def run(logfile, *args,**kwargs):
    "this function execute the check steps and return "
    loglines = file(logfile).readlines()
    result = ResultInfo(name)
    info = []
    error = ''

    # check the NG version first.
    ngversion=get_ng_version(logfile)

    if not ngversion:  # not version info found.
        #status = CheckStatus.UNKNOWN
        info.append("    - NG version can't be determindated.")
        #error = "NG version is not found."

    elif ngversion[0][:3] == '3.2':
        status,info,error = check_memory_fail_counter(loglines)
        if status == CheckStatus.FAILED and len(info)>0:
            result.status = status

    ## check function 2
    status,_info,error = check_memory_allocation(loglines)

    info.append(''.join(_info))
    #result.status = status

    result.update(status=status,info=info,error=error)
    return result


import time
import socket
HOST = "localhost"
PORT = 8888

def to_html_test(numbers):

    width_of_box = len(numbers)*100
    width_of_box = str(width_of_box)

    result = '\n'
    result = '\n'
    result += '\n'
    result += '\n'
    result += '\n'
    result += '
\n'
    for i in range(len(numbers)):
        result += ""
    result += '
\n'
    result += "\n"
    result += "\n"
    return result

def response():
    t = time.strftime("%H%M")
    z = to_html_test(t)
    return z

def worker(sck):
    s = response()
    sck.send(bytes("HTTP/1.1 200 OK\r\n", "UTF-8"))
    sck.send(bytes("Content-Type: html\r\n", "UTF-8"))
    sck.send(bytes("Content-Length: " + str(len(s)) + "\r\n",'UTF-8'))
    sck.send(bytes("Connection: Keep-alive\r\n", 'UTF-8'))
    sck.send(bytes("Cache-Control: no-cache\r\n", 'UTF-8'))
    sck.send(bytes("Server: Damilolas-MacBook-Pro.local\r\n", 'UTF-8'))
    sck.send(bytes('\r\n', 'UTF-8'))
    sck.send(bytes(str(s), "UTF-8"))
    sck.send(bytes())
    sck.close()

ssck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssck.bind((HOST, PORT))
ssck.listen(1)
while True:
    sck, addr = ssck.accept()
    worker(sck)