'''
Build a tweet sentiment analyzer
'''

from __future__ import print_function
import six.moves.cPickle as pickle
import time
from collections import OrderedDict
import sys
import time
from sys import argv
import numpy
import theano
from theano import config
import theano.tensor as tensor
from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams

import imdb
from imdb import masklist

import scipy.io as sio
datanamee = 'sat'
datasets = {datanamee: imdb.load_data}

# Set the random number generators' seeds for consistency
SEED = 123
numpy.random.seed(SEED)

def numpy_floatX(data):
    # return numpy.asarray(data, dtype=config.floatX)
    return numpy.asarray(data, dtype=config.floatX)

def get_minibatches_idx(n, minibatch_size, shuffle=False):
    """
    Used to shuffle the dataset at each iteration.
    """

    idx_list = numpy.arange(n, dtype="int32")

    if shuffle:
        numpy.random.shuffle(idx_list)

    minibatches = []
    minibatch_start = 0
    for i in range(n // minibatch_size):
        minibatches.append(idx_list[minibatch_start:
                                    minibatch_start + minibatch_size])
        minibatch_start += minibatch_size

    if (minibatch_start != n):
        # Make a minibatch out of what is left
        minibatches.append(idx_list[minibatch_start:])
    # print('minibatches', minibatches)
    return zip(range(len(minibatches)), minibatches)

def get_dataset(name):
    return datasets[name]

def zipp(params, tparams):
    """
    When we reload the model. Needed for the GPU stuff.
    """
    for kk, vv in params.items():
        tparams[kk].set_value(vv)

def unzip(zipped):
    """
    When we pickle the model. Needed for the GPU stuff.
    """
    new_params = OrderedDict()
    for kk, vv in zipped.items():
        new_params[kk] = vv.get_value()
    return new_params

def dropout_layer(state_before, use_noise, trng):
    proj = tensor.switch(use_noise,
                         (state_before *
                          trng.binomial(state_before.shape,
                                        p=0.5, n=1,
                                        dtype=state_before.dtype)),
                         state_before * 0.5)
    return proj

def _p(pp, name):
    return '%s_%s' % (pp, name)

def init_params(options):
    """
    Global (not LSTM) parameter. For the embeding and the classifier.
    """
    params = OrderedDict()
    # embedding
    # randn = numpy.random.rand(options['n_words'],
    #                          options['dim_proj'])
    # params['Wemb'] = (0.01 * randn).astype(config.floatX)
    params = get_layer(options['encoder'])[0](options,
                                              params,
                                              prefix=options['encoder'])
    # classifie
    for i in range(recyl_maxlen):
        # params for label prediction
        params['U_' + str(i)] =  (numpy.random.randn((i + 1) * options['dim_proj'],
                                                int(options['ydim'])).astype(config.floatX) /
                                                numpy.sqrt((i + 1) * options['dim_proj']))
        params['b_' + str(i)] = numpy.zeros((int(options['ydim']),)).astype(config.floatX)

        # params for modal prediction
        params['U_seq_' + str(i)] =  (numpy.random.randn( options['dim_proj'],
                                                int( options['maxlen'])).astype(config.floatX)
                                                / numpy.sqrt(options['dim_proj']))
        params['b_seq_' + str(i)] = numpy.zeros((int(options['maxlen']),)).astype(config.floatX)

    return params

def load_params(path, params):
    pp = numpy.load(path)
    for kk, vv in params.items():
        if kk not in pp:
            raise Warning('%s is not in the archive' % kk)
        params[kk] = pp[kk]

    return params

def init_tparams(params):
    tparams = OrderedDict()
    for kk, pp in params.items():
        tparams[kk] = theano.shared(params[kk], name=kk)
    return tparams

def get_layer(name):
    fns = layers[name]
    return fns

def ortho_weight(ndim):
    W = numpy.random.randn(ndim, ndim)
    u, s, v = numpy.linalg.svd(W)
    return u.astype(config.floatX)

def param_init_lstm(options, params, prefix='lstm'):
    """
    Init the LSTM parameter:

    :see: init_params
    """
    W = numpy.concatenate([ortho_weight(options['dim_proj']),
                           ortho_weight(options['dim_proj']),
                           ortho_weight(options['dim_proj']),
                           ortho_weight(options['dim_proj'])], axis=1)
    params[_p(prefix, 'W')] = W
    U = numpy.concatenate([ortho_weight(options['dim_proj']),
                           ortho_weight(options['dim_proj']),
                           ortho_weight(options['dim_proj']),
                           ortho_weight(options['dim_proj'])], axis=1)
    params[_p(prefix, 'U')] = U
    b = numpy.zeros((4 * options['dim_proj'],))
    params[_p(prefix, 'b')] = b.astype(config.floatX)

    return params

def lstm_layer(tparams, state_below, options, prefix='lstm', mask=None,h_before=None,c_before=None):
    nsteps = state_below.shape[0]
    if state_below.ndim == 3:
        n_samples = state_below.shape[1]
    else:
        n_samples = 1

    assert mask is not None

    def _slice(_x, n, dim):
        if _x.ndim == 3:
            return _x[:, :, n * dim:(n + 1) * dim]
        return _x[:, n * dim:(n + 1) * dim]

    def _step(m_, x_, h_, c_):
        preact = tensor.dot(h_, tparams[_p(prefix, 'U')])
        preact += x_

        i = tensor.nnet.sigmoid(_slice(preact, 0, options['dim_proj']))
        f = tensor.nnet.sigmoid(_slice(preact, 1, options['dim_proj']))
        o = tensor.nnet.sigmoid(_slice(preact, 2, options['dim_proj']))
        c = tensor.tanh(_slice(preact, 3, options['dim_proj']))

        c = f * c_ + i * c
        c = m_[:, None] * c + (1. - m_)[:, None] * c_

        h = o * tensor.tanh(c)
        h = m_[:, None] * h + (1. - m_)[:, None] * h_

        return h, c

    state_below = (tensor.dot(state_below, tparams[_p(prefix, 'W')]) +
                   tparams[_p(prefix, 'b')])

    dim_proj = options['dim_proj']
    [h,c] = _step(mask, state_below,h_before,c_before)
    return h,c

# ff: Feed Forward (normal neural net), only useful to put after lstm
#     before the classifier.
layers = {'lstm': (param_init_lstm, lstm_layer)}

def sgd(lr, tparams, grads, x, x3,y2, mask, y, cost,modal_cost, max_cost):
    """ Stochastic Gradient Descent

    :note: A more complicated version of sgd then needed.  This is
        done like that for adadelta and rmsprop.

    """
    # New set of shared variable that will contain the gradient
    # for a mini-batch.
    gshared = [theano.shared(p.get_value() * 0., name='%s_grad' % k)
               for k, p in tparams.items()]
    gsup = [(gs, g) for gs, g in zip(gshared, grads)]

    # Function that computes gradients for a mini-batch, but do not
    # updates the weights.
    # f_grad_shared = theano.function([idxs, x, mask, y], cost, updates=gsup,
    #                                 name='sgd_f_grad_shared')
    f_grad_shared = theano.function([mask, y, x, x3,y2, modal_cost, max_cost], cost, updates=gsup,
                                    name='sgd_f_grad_shared')

    pup = [(p, p - lr * g) for p, g in zip(tparams.values(), gshared)]

    # Function that updates the weights from the previously computed
    # gradient.
    f_update = theano.function([lr], [], updates=pup,
                               name='sgd_f_update')

    return f_grad_shared, f_update

def adadelta(lr, tparams, grads, x, x3,y2, mask, y, cost, modal_cost,max_cost):
    """
    An adaptive learning rate optimizer

    Parameters
    ----------
    lr : Theano SharedVariable
        Initial learning rate
    tpramas: Theano SharedVariable
        Model parameters
    grads: Theano variable
        Gradients of cost w.r.t to parameres
    x: Theano variable
        Model inputs
    mask: Theano variable
        Sequence mask
    y: Theano variable
        Targets
    cost: Theano variable
        Objective fucntion to minimize

    Notes
    -----
    For more information, see [ADADELTA]_.

    .. [ADADELTA] Matthew D. Zeiler, *ADADELTA: An Adaptive Learning
       Rate Method*, arXiv:1212.5701.
    """

    zipped_grads = [theano.shared(p.get_value() * numpy_floatX(0.),
                                  name='%s_grad' % k)
                    for k, p in tparams.items()]
    running_up2 = [theano.shared(p.get_value() * numpy_floatX(0.),
                                 name='%s_rup2' % k)
                   for k, p in tparams.items()]
    running_grads2 = [theano.shared(p.get_value() * numpy_floatX(0.),
                                    name='%s_rgrad2' % k)
                      for k, p in tparams.items()]

    zgup = [(zg, g) for zg, g in zip(zipped_grads, grads)]
    rg2up = [(rg2, 0.95 * rg2 + 0.05 * (g ** 2))
             for rg2, g in zip(running_grads2, grads)]

    f_grad_shared = theano.function([mask, y, x, x3, y2, modal_cost, max_cost], cost, updates=zgup + rg2up,
                                    name='adadelta_f_grad_shared', on_unused_input='ignore', allow_input_downcast=True)
    # f_grad_shared = theano.function([idxs, x, mask, y], cost, updates=zgup + rg2up,
    #                                 name='adadelta_f_grad_shared')

    updir = [-tensor.sqrt(ru2 + 1e-6) / tensor.sqrt(rg2 + 1e-6) * zg
             for zg, ru2, rg2 in zip(zipped_grads,
                                     running_up2,
                                     running_grads2)]
    ru2up = [(ru2, 0.95 * ru2 + 0.05 * (ud ** 2))
             for ru2, ud in zip(running_up2, updir)]
    param_up = [(p, p + ud) for p, ud in zip(tparams.values(), updir)]

    f_update = theano.function([lr], [], updates=ru2up + param_up,
                               on_unused_input='ignore',
                               name='adadelta_f_update', allow_input_downcast=True)

    return f_grad_shared, f_update

def rmsprop(lr, tparams, grads, x, mask, y, cost):
    """
    A variant of  SGD that scales the step size by running average of the
    recent step norms.

    Parameters
    ----------
    lr : Theano SharedVariable
        Initial learning rate
    tpramas: Theano SharedVariable
        Model parameters
    grads: Theano variable
        Gradients of cost w.r.t to parameres
    x: Theano variable
        Model inputs
    mask: Theano variable
        Sequence mask
    y: Theano variable
        Targets
    cost: Theano variable
        Objective fucntion to minimize

    Notes
    -----
    For more information, see [Hint2014]_.

    .. [Hint2014] Geoff Hinton, *Neural Networks for Machine Learning*,
       lecture 6a,
       http://cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf
    """

    zipped_grads = [theano.shared(p.get_value() * numpy_floatX(0.),
                                  name='%s_grad' % k)
                    for k, p in tparams.items()]
    running_grads = [theano.shared(p.get_value() * numpy_floatX(0.),
                                   name='%s_rgrad' % k)
                     for k, p in tparams.items()]
    running_grads2 = [theano.shared(p.get_value() * numpy_floatX(0.),
                                    name='%s_rgrad2' % k)
                      for k, p in tparams.items()]

    zgup = [(zg, g) for zg, g in zip(zipped_grads, grads)]
    rgup = [(rg, 0.95 * rg + 0.05 * g) for rg, g in zip(running_grads, grads)]
    rg2up = [(rg2, 0.95 * rg2 + 0.05 * (g ** 2))
             for rg2, g in zip(running_grads2, grads)]

    # f_grad_shared = theano.function([x, mask, y], cost,
    #                                 updates=zgup + rgup + rg2up,
    #                                 name='rmsprop_f_grad_shared')
    f_grad_shared = theano.function([mask, y, x], cost,
                                    updates=zgup + rgup + rg2up,
                                    name='rmsprop_f_grad_shared')

    updir = [theano.shared(p.get_value() * numpy_floatX(0.),
                           name='%s_updir' % k)
             for k, p in tparams.items()]
    updir_new = [(ud, 0.9 * ud - 1e-4 * zg / tensor.sqrt(rg2 - rg ** 2 + 1e-4))
                 for ud, zg, rg, rg2 in zip(updir, zipped_grads, running_grads,
                                            running_grads2)]
    param_up = [(p, p + udn[1])
                for p, udn in zip(tparams.values(), updir_new)]
    f_update = theano.function([lr], [], updates=updir_new + param_up,
                               on_unused_input='ignore',
                               name='rmsprop_f_update')

    return f_grad_shared, f_update

def build_model(tparams, options):
    '''
    x: traing data
    y: traing label
    x3: neighbor data, datanum * neighbornum * featuredim
    y2: neighbor label
    '''
    trng = RandomStreams(SEED)
    # Used for dropout.
    use_noise = theano.shared(numpy_floatX(0.))
    maskl = tensor.matrix('maskl', dtype=config.floatX)
    y = tensor.vector('y', dtype='int32')
    x = tensor.matrix('x', dtype=config.floatX)
    n_samples = x.shape[0]
    dim_proj = x.shape[1]
    maxlen = options['maxlen']
    x3 = tensor.tensor3('x3', dtype=config.floatX)
    y2 = tensor.matrix('y2', dtype='int32')
    neigh_num = x3.shape[1]
    x_nerghbors = tensor.reshape(x3, [n_samples * neigh_num, dim_proj])
    modal_cost = tensor.vector('modal_cost', dtype=config.floatX)
    max_cost = tensor.scalar('max_cost', dtype=config.floatX)
    h = tensor.alloc(numpy_floatX(0.),n_samples,dim_proj)
    c = tensor.alloc(numpy_floatX(0.),n_samples,dim_proj)
    h_n = tensor.alloc(numpy_floatX(0.),n_samples * neigh_num,dim_proj)
    c_n = tensor.alloc(numpy_floatX(0.),n_samples * neigh_num,dim_proj)
    cost = 0
    cost1_mean = []
    cost2_mean = []
    cost3_mean = []
    next_mean = []
    mask = tensor.ones_like(x[:,0], dtype= config.floatX) # maks whether instance enter the  ith iter
    mask_n = tensor.ones_like(x_nerghbors[:,0], dtype= config.floatX)
    masks = []
    projs = []
    masks.append(mask)
    next_modal = tensor.zeros_like(x[:,0], dtype= 'int32')
    next_modal_n = tensor.zeros_like(x_nerghbors[:,0], dtype= 'int32')
    # cost_vector = tensor.alloc(numpy_floatX(0.),n_samples,1)
    cost_vector = tensor.alloc(numpy_floatX(0.),1, n_samples)
    f_pred_set = []
    f_pred_seq_set = []
    f_pred_seq_prob_set = []
    f_get_fea_set = []
    f_fea_other_set = []
    def get_other3(x, next_modal):
        fea_other = tensor.tile(x,(maxlen,1))
        fea_other = x.T
        fea_single = fea_other[:,next_modal]
        return fea_other,fea_single

    def get_other(x):
        # change the feature x from dim to the form of maxlen * dim
        fea_other = []
        for i in range(maxlen):
            fea_other.append(x * maskl[i])
        return tensor.stack(fea_other)
    def get_single(x,next_modal):
        # get the current modal' feature
        fea_single = x * maskl[next_modal]
        return fea_single

    def compute_dist(neighbor, pred_neighbor, fea_single, pred, mask, y, y2):
        '''
        minimize same label neighbor's distance, maximize different label neighbor's distance
        neighbor: neighbor's feature
        pred_neighbor: neighbor's netmodal's prediction
        fea_single: current instance's feature
        pred: current instance's prediction
        mask: whether current instance stops
        y: current instance's label
        y2: neighbor instance's label
        '''
        loss = 0
        if mask:
            ifsamelabel = -1
            for i in range(3):
                if y == y2[i]:
                    ifsamelabel = 1
                else:
                    ifsamelabel = -1
                dist = tensor.dot(get_other(neighbor[i]).T, pred_neighbor[i]) - tensor.dot(get_other(fea_single).T,pred)
                loss += ifsamelabel * tensor.dot(dist , dist.T)
        return loss/3

    costs = tensor.tile(modal_cost,(n_samples,1))
    xs = []
    for i in range(recyl_maxlen):
        # set high cost for modal that has been used to prevent predict same modal
        costs = tensor.set_subtensor(costs[tensor.arange(n_samples), next_modal], 1)
        feas, update = theano.scan(fn = get_single,
                            sequences=[x, next_modal],
                            )
        fea_single_n, update_n = theano.scan(fn = get_single,
                            sequences=[x_nerghbors, next_modal_n],
                            )
        fea_single = feas
        max_coefficients_supported = 10000

        xs.append(fea_single)

        [h,c] = get_layer(options['encoder'])[1](tparams, fea_single, options,
                                                prefix=options['encoder'],
                                                mask=mask,h_before = h,c_before = c)
        [h_n,c_n] = get_layer(options['encoder'])[1](tparams, fea_single_n, options,
                                                prefix=options['encoder'],
                                                mask=mask_n,h_before = h_n,c_before = c_n)
        proj = h
        proj_n = h_n
        projs.append(proj)
        projsmatrix = tensor.stack(projs)
        proj_pred = tensor.stack(projs) * tensor.stack(masks)[:, :, None]
        proj_pred = tensor.transpose(proj_pred,(1,0,2))
        proj_pred = tensor.reshape(proj_pred,[projsmatrix.shape[1],projsmatrix.shape[0] * projsmatrix.shape[2]])
        # print('h_n.shape', h_n.shape)
        if options['use_dropout']:
            proj_pred = dropout_layer(proj_pred, use_noise, trng)
        pred = tensor.nnet.softmax(tensor.dot(proj_pred, tparams['U_' + str(i)]) + tparams['b_' + str(i)])

        print('i', i)

        f_pred_prob = theano.function([ x, maskl,modal_cost, max_cost], pred,
                                                name='f_pred_prob',on_unused_input='ignore', allow_input_downcast=True)
        f_pred = theano.function([x, maskl, modal_cost, max_cost], pred.argmax(axis=1),
                                                name='f_pred',on_unused_input='ignore', allow_input_downcast=True)
        f_pred_set.append(f_pred)

        off = 1e-8
        if pred.dtype == 'float16':
            off = 1e-6

        pred_seq = tensor.nnet.softmax(tensor.dot(proj, tparams['U_seq_' + str(i)]) + tparams['b_seq_' + str(i)])
        pred_seq_n = tensor.nnet.softmax(tensor.dot(proj_n, tparams['U_seq_' + str(i)]) + tparams['b_seq_' + str(i)])

        f_pred_seq = theano.function([x, maskl, modal_cost,max_cost], pred_seq.argmax(axis=1),
                        name='f_pred_seq',on_unused_input='ignore',allow_input_downcast=True)

        f_pred_seq_set.append(f_pred_seq)

        pred_seq_index = pred_seq.argmax(axis=1)
        next_modal = pred_seq_index
        next_modal_n = pred_seq_n.argmax(axis=1)
        next_mean.append(next_modal)
        cost1_vector = tensor.log(pred[tensor.arange(n_samples), y] + off)
        cost1 = ( cost1_vector * mask).sum() / (mask.sum() + 1)

        pred_seq_n3 = tensor.reshape(pred_seq_n, [n_samples , neigh_num, maxlen])
        result_loss2, update = theano.scan(fn = compute_dist,
                            sequences=[x3, pred_seq_n3, x, pred_seq, mask, y, y2],
                            )
        cost2 = result_loss2.mean()
        cost3 = (costs * pred_seq).mean()
        cost1_mean.append(cost1)
        cost2_mean.append(cost2)
        cost3_mean.append(cost3)
        lamda1 = 0.001
        lamda2 = 0.1
        if i == recyl_maxlen - 1:
            lamda1 = 0.000000001
            lamda2 = 0.000000001
        cost += -cost1 +  lamda1 * cost2 + lamda2 * cost3
        # cost += -cost1
        # f_fea_other = theano.function([x, x3, y, maskl, modal_cost, max_cost],[nnext, D,cost1,cost2,cost3,mask.sum(),next_modal, fea_single, fea_other, fea_single3, fea_other3], on_unused_input='ignore')
        # f_fea_other_set.append(f_fea_other)
        result, update = theano.scan(lambda b,a: a[b],
                                sequences = pred_seq_index,
                                non_sequences = modal_cost )
        if i == 0:
            cost_vector = result
        else:
            cost_vector += result
        # mask the instance if its cost larger than max_cost
        choice = tensor.nonzero(tensor.gt(-cost_vector,-max_cost))[0]
        mask = tensor.zeros_like(x[:,0], dtype = config.floatX)
        mask = theano.tensor.set_subtensor(mask[choice],1.)
        masks.append(mask)
        if i < recyl_maxlen:
            cost -= (2 * (1-mask) * cost1_vector).sum() / (mask.sum() + 1)
        else:
            cost -= cost1
    f_fea_other = theano.function([x, x3,y2, y, maskl, modal_cost, max_cost],
            [tensor.stack(cost1_mean), tensor.stack(cost2_mean), tensor.stack(cost3_mean)], on_unused_input='ignore')

    return use_noise, x,x3, y2, maskl, y, cost,modal_cost,max_cost,f_pred_set,f_pred_seq_set, f_fea_other

def pred_error(maxlen, f_pred_set,f_pred_seq_set, data, iterator,maskl, model_len, modal_cost, max_cost,verbose=False):
    """
    Just compute the error
    f_pred: Theano fct computing the prediction
    prepare_data: usual prepare_data for that dataset.
    """
    valid_err = 0
    length = 0
    meancost = 0
    for _, valid_index in iterator:
        feax = [data[0][t] for t in valid_index]
        feax = numpy.array(feax)
        targets = [data[1][t] for t in valid_index]
        n_samples = len(valid_index)
        mask = numpy.ones_like(feax[:,0], dtype= 'int32')
        next_modal = numpy.zeros_like(feax[:,0], dtype= 'int32')
        cost_vector = numpy.zeros(n_samples)
        next_modals = numpy.zeros([n_samples,maxlen])
        mask_matrix = numpy.zeros([n_samples, maxlen])
        preds_s = numpy.zeros([n_samples, maxlen])
        preds = numpy.zeros(n_samples)
        costs = numpy.tile(modal_cost,(n_samples,1))
        for i in range(recyl_maxlen):
            cost_vector += costs[range(n_samples), next_modal]
            costs[range(n_samples), next_modal] = 0
            mask_matrix[:,i] = mask
            next_modal = f_pred_seq_set[i](feax, maskl, modal_cost, max_cost)
            next_modals[:,i] = next_modal
            mask = numpy.zeros_like(feax[:,0], dtype= 'int32')
            choice = numpy.greater(-cost_vector,-max_cost)
            mask[choice] = 1
            preds_s[:,i] = f_pred_set[i](feax, maskl, modal_cost, max_cost)
        meancost += cost_vector.sum()
        for i in range(n_samples):
            prem = False
            for j in range(maxlen):
                if mask_matrix[i,j] == 0:
                    prem = True
                    preds[i] = preds_s[i, j-1]
                    break
            if prem == False:
                preds[i] =  preds_s[i, -1]
        valid_err += (preds == targets).sum()
        length += len(preds)
    valid_err = 1. - numpy_floatX(valid_err) / length

    return valid_err, meancost / length

def get_neighbor(sam_traininx, neighinx, trainx, trainy):
    neighs = []
    neiy = []
    trainy = numpy.array(trainy)
    for i in range(len(sam_traininx)):
        ninx = neighinx[sam_traininx[i]]
        neighs.append(trainx[ninx,:])
        neiy.append(trainy[ninx])
    return numpy.array(neighs), numpy.array(neiy)

def train_lstm(
    dim_proj=36,  # word embeding dimension and LSTM number of hidden units.
    patience=15,  # Number of epoch to wait before early stop if no progress
    max_epochs=5000,  # The maximum number of epoch to run
    dispFreq=10,  # Display to stdout the training progress every N updates
    decay_c=0.,  # Weight decay for the classifier applied to the U weights.
    lrate=0.01,  # Learning rate for sgd (not used for adadelta and rmsprop)
    optimizer=adadelta,  # sgd, adadelta and rmsprop available, sgd very hard to use, not recommanded (probably need momentum and decaying learning rate).
    #  optimizer = sgd,
    encoder='lstm',  # TODO: can be removed must be lstm.
    saveto='lstm_model_best.npz',  # The best model will be saved there
    validFreq=100,  # Compute the validation error after this number of update.
    saveFreq=1110,  # Save the parameters after every saveFreq updates
    maxlen=4,  # Sequence longer then this get ignored
    batch_size=64,  # The batch size during training.
    valid_batch_size=256,  # The batch size used for validation/test set.
    dataset=datanamee,
    modal_costs = [0.1, 0.1, 0.1, 0.1], # the cost for each modal
    # model_lens = model_len,
    # Parameter for extra option
    noise_std=0.,
    use_dropout=True,  # if False slightly faster, but worst test error
                       # This frequently need a bigger model.
    reload_model=None,  # Path to a saved model we want to start from.
    test_size=-1,  # If >0, we keep only this number of test example.
    max_costs = 50, # max cost for each instance to use
):

    # Model options
    model_options = locals().copy()
    print("model options", model_options)

    load_data = get_dataset(dataset)

    print('Loading data')
    train, valid, test, mask, model_len, train_n3 = load_data()
    '''
    train: (train data, train label)
    valid: (valid data, valid label)
    test: (test data, test label)
    mask: mask each modal's feature
    model_len: each model's length
    train_n3: each traing data's 3 neighbor's index
    '''
    ydim = numpy.max(train[1]) + 1
    #
    model_options['ydim'] = ydim
    print('ydim', ydim)
    print('numpy.min(train[1])', numpy.min(train[1]))
    print('Building model')
    # This create the initial parameters as numpy ndarrays.
    # Dict name (string) -> numpy ndarray
    params = init_params(model_options)
    if reload_model:
        load_params('lstm_model.npz', params)

    # This create Theano Shared Variable from the parameters.
    # Dict name (string) -> Theano Tensor Shared Variable
    # params and tparams have different copy of the weights.
    tparams = init_tparams(params)
    (use_noise, x, x3, y2, mask, y, cost,
            modal_cost,max_cost,f_pred_set, f_pred_seq_set, f_fea_other) = build_model(tparams, model_options)
    if decay_c > 0.:
        decay_c = theano.shared(numpy_floatX(decay_c), name='decay_c')
        weight_decay = 0.
        weight_decay += (tparams['U'] ** 2).sum()
        weight_decay *= decay_c
        cost += weight_decay
    print('starting compute grad...')
    print(time.asctime( time.localtime(time.time()) ) )
    grads = tensor.grad(cost, wrt=list(tparams.values()))
    f_grad = theano.function([mask, y, x,x3, y2, modal_cost,max_cost], grads, name='f_grad',on_unused_input='ignore')
    lr = tensor.scalar(name='lr')
    print('starting optimizer')
    print(time.asctime( time.localtime(time.time()) ) )
    f_grad_shared, f_update = optimizer(lr, tparams, grads,
                                        x, x3, y2, mask, y, cost, modal_cost,max_cost)
    kf_valid = get_minibatches_idx(len(valid[0]), valid_batch_size)
    kf_test = get_minibatches_idx(len(test[0]), valid_batch_size)

    print("%d train examples" % len(train[0]))
    print("%d valid examples" % len(valid[0]))
    print("%d test examples" % len(test[0]))

    history_errs = []
    best_p = None
    bad_count = 0

    if validFreq == -1:
        validFreq = len(train[0]) // batch_size
    if saveFreq == -1:
        saveFreq = len(train[0]) // batch_size

    uidx = 0  # the number of update done
    estop = False  # early stop
    start_time = time.time()
    try:
        for eidx in range(max_epochs):
            n_samples = 0

            # Get new shuffled index for the training set.
            kf = get_minibatches_idx(len(train[0]), batch_size, shuffle=False)

            for _, train_index in kf:
                feax3, feay2 = get_neighbor(train_index, train_n3, train[0], train[1])
                '''
                feax3: this mini-batch's data's feature
                feay2: this mini-batch's data's label
                '''
                uidx += 1
                use_noise.set_value(1.)

                # Select the random examples for this minibatch
                y = [train[1][t] for t in train_index]
                feax = [train[0][t] for t in train_index]
                n_samples += len(feax)
                maskl = masklist(model_len, dim_proj)

                cost = f_grad_shared(maskl, y, feax, feax3,feay2, modal_costs,max_costs)
                f_update(lrate)
                if numpy.isnan(cost) or numpy.isinf(cost):
                    print('bad cost detected: ', cost)
                    return 1., 1., 1.

                if numpy.mod(uidx, dispFreq) == 0:
                    print('Epoch ', eidx, 'Update ', uidx, 'Cost ', cost)

                if saveto and numpy.mod(uidx, saveFreq) == 0:
                    print('Saving...')

                    if best_p is not None:
                        params = best_p
                    else:
                        params = unzip(tparams)
                    numpy.savez(saveto, history_errs=history_errs, **params)
                    pickle.dump(model_options, open('%s.pkl' % saveto, 'wb'), -1)
                    print('Done')

                if numpy.mod(uidx, validFreq) == 0:
                    use_noise.set_value(0.)
                    maskls = masklist(model_len, dim_proj)
                    train_err, tracost = pred_error(maxlen, f_pred_set, f_pred_seq_set, train, kf,maskls, model_len, modal_costs, max_costs)
                    print('~~~~~~~~~~~train_err',train_err)
                    print('~~~~~~~~~~~tracost',tracost)
                    kf_valid = get_minibatches_idx(len(valid[0]), valid_batch_size)
                    kf_test = get_minibatches_idx(len(test[0]), valid_batch_size)
                    valid_err, valcost = pred_error(maxlen, f_pred_set, f_pred_seq_set, valid, kf_valid,maskls, model_len, modal_costs, max_costs)
                    test_err, tstcost = pred_error(maxlen, f_pred_set, f_pred_seq_set, test, kf_test,maskls, model_len, modal_costs, max_costs)
                    history_errs.append([valid_err, test_err, valcost, tstcost])
                    print('history_errs)', history_errs)
                    if (best_p is None or
                        valid_err <= numpy.array(history_errs)[:,
                                                               0].min()):

                        best_p = unzip(tparams)
                        bad_counter = 0

                    print( ('Train ', train_err, 'Valid ', valid_err,
                           'Test ', test_err) )
                    print( ('Traincost ', tracost, 'Validcost ', valcost,
                           'Testcost ', tstcost) )

                    if (len(history_errs) > patience and
                        valid_err >= numpy.array(history_errs)[:-patience,
                                                               0].min()):
                        bad_counter += 1
                        if bad_counter > patience:
                            print('Early Stop!')
                            estop = True
                            break

            print('Seen %d samples' % n_samples)

            if estop:
                break

    except KeyboardInterrupt:
        print("Training interupted")

    end_time = time.time()
    if best_p is not None:
        zipp(best_p, tparams)
    else:
        best_p = unzip(tparams)
    print('best valid',numpy.array(history_errs)[:,
                                           0].min())
    print('best valid',numpy.array(history_errs)[:,
                                           1].min())
    use_noise.set_value(0.)
    kf_train_sorted = get_minibatches_idx(len(train[0]), batch_size)
    train_err, tracost = pred_error(maxlen, f_pred_set, f_pred_seq_set, train, kf_train_sorted,maskls, model_len, modal_costs, max_costs)

    kf_valid = get_minibatches_idx(len(valid[0]), valid_batch_size)
    kf_test = get_minibatches_idx(len(test[0]), valid_batch_size)
    valid_err, valcost = pred_error(maxlen, f_pred_set, f_pred_seq_set, valid, kf_valid,maskls, model_len, modal_costs, max_costs)

    test_err,tstcost = pred_error(maxlen, f_pred_set, f_pred_seq_set, test, kf_test,maskls, model_len, modal_costs, max_costs)

    print( 'Train ', train_err, 'Valid ', valid_err, 'Test ', test_err )
    print( ('Traincost ', tracost, 'Validcost ', valcost,
           'Testcost ', tstcost) )
    if saveto:
        numpy.savez(saveto, train_err=train_err,
                    valid_err=valid_err, test_err=test_err,
                    history_errs=history_errs, **best_p)
    print('The code run for %d epochs, with %f sec/epochs' % (
        (eidx + 1), (end_time - start_time) / (1. * (eidx + 1))))
    print( ('Training took %.1fs' %
            (end_time - start_time)), file=sys.stderr)
    return train_err, valid_err, test_err

if __name__ == '__main__':
    # See function train for all possible parameter and there definition.
    recyl_maxlen = int(argv[1]) # the max madal can been used for one instance
    train_lstm(
        max_epochs=100,
        test_size=500,
    )


import retrogamelib as rgl
import pygame, random, sys, os
from retrogamelib.constants import *

from objects import spritesheet, flip_images

class Intro(object):

    def __init__(self):
        load_image = rgl.util.load_image
        self.oldman1 = spritesheet("data/lawn-mower.png", (96, 96))
        self.bubbman1 = spritesheet("data/bubbman.png", (24, 26))[:3]
        self.bubbman2 = flip_images(self.bubbman1)
        self.ground = spritesheet("data/grass-2.png", (24, 24))[1]
        self.fg = load_image("data/hills-front-1.png")
        self.fg2 = load_image("data/hills-back.png")
        self.bg = load_image("data/background-1.png")
        self.font_white = rgl.font.Font(NES_FONT, (255, 255, 255))
        self.font_black = rgl.font.Font(NES_FONT, (1, 1, 1))
        self.frame = 0
        self.pos = 0
        self.bpos = [200, 240-26-20]
        self.opos = [0, 240-96-20]
        self.ochasing = True
        self.run_away = False
        self.stopped = None
        self.boom = rgl.util.play_sound("data/motor.ogg", 0.5)
        self.boom.stop()

    def loop(self):
        self.running = True
        self.ypos = 256
        pygame.mixer.music.stop()
        while self.running:
            self.frame += 1
            rgl.clock.tick()
            rgl.button.handle_input()
            screen = rgl.display.get_surface()
            screen.blit(self.bg, (0, 0))
            xpos = (self.pos/4) % 256
            screen.blit(self.fg2, (xpos, 50))
            screen.blit(self.fg2, (xpos+256, 50))
            screen.blit(self.fg2, (xpos-256, 50))
            xpos = (self.pos/2) % 256
            screen.blit(self.fg, (xpos, 50))
            screen.blit(self.fg, (xpos+256, 50))
            screen.blit(self.fg, (xpos-256, 50))
            for x in range(256/24 + 2):
                p = self.pos % 256
                screen.blit(self.ground, (((x*24 - 24) + p % 24), 240-24))
            if rgl.button.is_pressed(START) or rgl.button.is_pressed(A_BUTTON):
                self.running = False
            bframe = 0
            oframe = 0
            if self.bpos[0] > 128 and not self.run_away:
                self.bpos[0] -= 3
                bframe = self.frame/4%2 + 1
            else:
                if self.stopped == None:
                    self.stopped = 60
                self.stopped -= 1
                if self.stopped == 30:
                    rgl.util.play_sound("data/yell.ogg")
                if self.stopped < 30:
                    self.render_text(screen, "Get off my lawn!!", (128+self.opos[0], 100), 1)
                if self.stopped <= 0:
                    self.run_away = True
            if self.run_away:
                self.bpos[0] += 3
                self.opos[0] += 3
                bframe = self.frame/4%2 + 1
                oframe = self.frame/4%2
                self.bubbman2 = self.bubbman1
                if not pygame.mixer.get_busy():
                    self.boom.play(-1)
            if self.opos[0] > 280:
                self.running = False
            if self.opos[0] > 270:
                self.boom.stop()
            screen.blit(self.bubbman2[bframe], self.bpos)
            screen.blit(self.oldman1[oframe], self.opos)
            rgl.display.update()
        self.boom.stop()

    def render_text(self, surface, text, pos, center=False):
        ren1 = self.font_black.render(text)
        ren2 = self.font_white.render(text)
        p = pos
        if center:
            p = (pos[0] - ren1.get_width()/2, pos[1])
        surface.blit(ren1, (p[0], p[1]+1))
        surface.blit(ren1, (p[0], p[1]-1))
        surface.blit(ren1, (p[0]+1, p[1]))
        surface.blit(ren1, (p[0]-1, p[1]))
        surface.blit(ren2, (p[0], p[1]))
        del ren1, ren2


# import the required modules and types for this example...
from typing import Any, Dict, List

# import the paginator and modal...
from discord.ext.modal_paginator import ModalPaginator, PaginatorModal

# import the discord.py module
import discord

from discord.ext import commands

bot = commands.Bot(command_prefix=commands.when_mentioned, intents=discord.Intents(guilds=True, messages=True))

# pre-defined questions and title for each modal
# this could be loaded from a json file or database
# each "modal" is a dict with the following keys:
# title: str - the title of the modal
# required: bool - whether the modal is required to be filled out before the paginator can be finished
# questions: List[str] - a list of questions to ask the user. Max 5 questions per modal.
personal_questions = {
    "title": "Personal Questions",
    "required": True,
    "questions": [
        "What is your name?",
        "What is your age?",
        "Any hobbies?",
        "Dad's name?",
        "Mom's name?",
    ],
}
misc_questions = {
    "title": "Miscellaneous Questions",
    "required": False,
    "questions": [
        "What is your favorite color?",
        "What is your favorite food?",
        "What is your favorite animal?",
        "What is your favorite movie?",
        "What is your favorite game?",
    ],
}
reason_questions = {
    "title": "Why Questions",
    "required": True,
    "questions": [
        "Why do you want to join?",
        "Why should we let you in?",
        "What do you like about the server?",
        "What do you like about the bot?",
        "What do you like about the community?",
    ],
}
# want even more control over the inputs?
# you can use the TextInput class directly
# from discord.ui import TextInput
# and then add the TextInput to the modal
# modal.add_item(TextInput(...)) instead of looping.
# see the discord.py docs for more info on the TextInput class.

# more dict like? use a dict for the questions too
# questions = [
#   {
#     "label": "What is your name?",
#     "min_length": 2,
#     "max_length": 200,
#     "required": False,
#     ...
#   },
#   ...
# ]
# etc...

# subclass the paginator to define our own on_finish method
# and to add the modals to the paginator via a custom __init__
class VerifyModal(ModalPaginator):
    def __init__(self, questions_inputs: List[Dict[str, Any]], *, author_id: int, **kwargs: Any) -> None:
        # initialize the paginator with the the author_id kwarg
        # and any other kwargs we passed to the constructor.
        # possible kwargs are as follows:
        # timeout: Optional[int] = None - the timeout for the paginator (view)
        # disable_after: bool = True - whether to disable all buttons after the paginator is finished or cancelled.
        # can_go_back: bool = True - whether the user can go back to previous modals using the "Previous" button.
        # sort_modals: bool = True - whether to sort the modals by the required kwarg.
        # See more on the class.
        super().__init__(author_id=author_id, **kwargs)
        # iterate over the questions_inputs list
        for data in questions_inputs:
            # unpack the data from the dict
            title: str = data["title"]
            required: bool = data["required"]
            questions: List[str] = data["questions"]
            # create a new modal with the title and required kwarg
            modal = PaginatorModal(title=title, required=required)
            # add the questions to the modal
            for question in questions:
                modal.add_input(
                    label=question,  # the label of the text input
                    min_length=2,  # the minimum length of the text input
                    max_length=200,  # the maximum length of the text input
                    # see the discord.py docs for more info on the other kwargs
                )

            # add the modal to the paginator
            self.add_modal(modal)

    # override the on_finish method to send the answers to the channel when the paginator is finished.
    async def on_finish(self, interaction: discord.Interaction[Any]) -> None:
        # create a list of answers
        # default format: **Modal Title**\nQuestion: Answer\nQuestion: Answer\n... etc
        answers: list[str] = []
        for modal in self.modals:
            prefix = f"**{modal.title}**\n"
            field: discord.ui.TextInput[Any]
            for field in modal.children:  # type: ignore
                prefix += f"{field.label}: {field.value}\n"

            answers.append(prefix)

        await interaction.response.send_message(f"Answers from {interaction.user.mention}:\n\n" + "\n\n".join(answers))

# define the prefix command.
@bot.command()
async def verify(ctx: commands.Context[commands.Bot]):
    # initialize the paginator with all the questions data we defined above in a list
    # and the author_id so that only the command invoker can use the paginator.
    questions_inputs = [personal_questions, misc_questions, reason_questions]
    paginator = VerifyModal(questions_inputs, author_id=ctx.author.id)

    # send the paginator to the current channel
    await paginator.send(ctx)

# run the bot
bot.run("...")

# run @bot_name verify in a channel with the bot to test the paginator


from setuptools import setup

with open("README.md", "r") as fh:
    long_description = fh.read()

setup(name='immudb-py',
      version='1.4.0',
      license="Apache License Version 2.0",
      description='Python SDK for Immudb',
      long_description=long_description,
      long_description_content_type="text/markdown",
      author='Codenotary',
      url='https://github.com/codenotary/immudb-py',
      # download_url='',
      packages=['immudb', 'immudb.database', 'immudb.embedded',
                'immudb.embedded.ahtree', 'immudb.embedded.htree', 'immudb.embedded.store',
                'immudb.grpc', 'immudb.handler', 'immudb.schema'],
      keywords=['immudb', 'immutable'],
      install_requires=[
          'grpcio>=1.31.0',
          'dataclasses>=0.6',
          'protobuf>=3.13.0,<4.0.0',
          'google-api>=0.1.12',
          'google-api-core>=1.22.1',
          'ecdsa>=0.16.1'
      ],
      classifiers=[
          'Intended Audience :: Developers',
          'Topic :: Software Development :: Build Tools',
          "License :: OSI Approved :: Apache Software License",
          "Operating System :: OS Independent",
          'Programming Language :: Python :: 3',
          'Programming Language :: Python :: 3.6',
          'Programming Language :: Python :: 3.7',
          'Programming Language :: Python :: 3.8',
      ],
      python_requires='>=3.6',
      )


import cv2
import math
import numpy as np
import pyautogui as gui

cap = cv2.VideoCapture(1)
while(cap.isOpened()):
    ret, img = cap.read()
    #cv2.resizeWindow('window1', 768,1366)
    cv2.rectangle(img, (0,0), (200,200), (0,255,0),0) ##left hand rectangle

    cv2.rectangle(img,(630,200),(430,0),(0,255,0),0) ##right hand rectangle

    crop_img = img[0:200, 0:200]
    crop_img2=img[0:200,430:630]

    grey = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY) ## converted it to the grey scale image
    grey2 = cv2.cvtColor(crop_img2,cv2.COLOR_BGR2GRAY)

    value = (35, 35)
    blurred = cv2.GaussianBlur(grey, value, 0)
    blurred2 = cv2.GaussianBlur(grey2,value,0)
    _, thresh1 = cv2.threshold(blurred, 127, 255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    _, thresh2 = cv2.threshold(blurred2, 127, 255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    cv2.imshow('Thresholded', thresh1)
    cv2.imshow('Thresholded2', thresh2)

    # check OpenCV version to avoid unpacking error
    (version, _, _) = cv2.__version__.split('.')

    if version == '3':
        image, contours, hierarchy = cv2.findContours(thresh1.copy(), \
               cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    elif version == '2':
        contours, hierarchy = cv2.findContours(thresh1.copy(),cv2.RETR_TREE, \
               cv2.CHAIN_APPROX_NONE)
    else:
        contours,hierarchy=cv2.findContours(thresh1.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
        contours2,hierarchy1=cv2.findContours(thresh2.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

    # find contour with max area
    cnt = max(contours, key = lambda x: cv2.contourArea(x))
    cnt2= max(contours2, key = lambda x: cv2.contourArea(x))

    x, y, w, h = cv2.boundingRect(cnt)
    x2, y2, w2, h2 = cv2.boundingRect(cnt2)
    M = cv2.moments(cnt)
    M2 = cv2.moments(cnt2)
    cx = int(M['m10']/M['m00'])
    cx2 = int(M2['m10']/M2['m00'])
    cy = int(M['m01']/M['m00'])
    cy2 = int(M2['m01']/M2['m00'])

    cv2.circle(crop_img,(cx,cy),1,(255,0,0),6)
    cv2.circle(crop_img2,(cx2,cy2),1,(255,0,0),6)
    cv2.rectangle(crop_img, (x, y), (x+w, y+h), (0, 0, 255), 0)

    cv2.rectangle(crop_img2, (x2, y2), (x2+w2, y2+h2), (0, 0, 255), 0)

    # finding convex hull
    hull = cv2.convexHull(cnt)

    hull2= cv2.convexHull(cnt2)

    drawing = np.zeros(crop_img.shape,np.uint8)
    drawing2 = np.zeros(crop_img2.shape,np.uint8)
    cv2.drawContours(drawing, [cnt], 0, (0, 255, 0), 0)
    cv2.drawContours(drawing, [hull], 0,(0, 0, 255), 0)

    cv2.drawContours(drawing2, [cnt2], 0, (0, 255, 0), 0)
    cv2.drawContours(drawing2, [hull2], 0,(0, 0, 255), 0)

    hull = cv2.convexHull(cnt, returnPoints=False)
    hull2 = cv2.convexHull(cnt2, returnPoints=False)
    defects = cv2.convexityDefects(cnt, hull)
    defects2 = cv2.convexityDefects(cnt2, hull2)
    count_defects = 0
    count_defects2=0
    cv2.drawContours(thresh1, contours, -1, (0, 255, 0), 3)
    # applying Cosine Rule to find angle for all defects (between fingers)
    # with angle > 90 degrees and ignore defects

    ##LeftWindow
    for i in range(defects.shape[0]):
        s,e,f,d = defects[i,0]

        start = tuple(cnt[s][0])
        end = tuple(cnt[e][0])
        far = tuple(cnt[f][0])

        # find length of all sides of triangle
        a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
        b = math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
        c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)

        # apply cosine rule here
        angle = math.acos((b**2 + c**2 - a**2)/(2*b*c)) * 57

        # ignore angles > 90 and highlight rest with red dots
        if angle <= 90:
            count_defects += 1
            cv2.circle(crop_img, far, 1, [0,0,255], -1)

        cv2.line(crop_img,start, end, [0,255,0], 2)

        if count_defects == 1:
            #cv2.putText(img,"I am Vipul", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, 2)
            gui.moveTo(cx,cy)
        elif count_defects == 2:
            str = "This is a basic hand gesture recognizer"
            #gui.getWindow("Files").maximize()
        elif count_defects == 3:
            cv2.putText(img,"This is 4 :P", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, 2)
        elif count_defects == 4:
            cv2.putText(img,"Hi!!!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, 2)
        else:
            cv2.putText(img,"Hello World!!!", (50, 50),cv2.FONT_HERSHEY_SIMPLEX, 2, 2)

    cv2.drawContours(thresh2, contours2, -1, (255, 0, 0), 3)
    ##Right window
    for i in range(defects2.shape[0]):
        s2,e2,f2,d2 = defects2[i,0]

        start2 = tuple(cnt2[s2][0])
        end2 = tuple(cnt2[e2][0])
        far2 = tuple(cnt2[f2][0])

        # find length of all sides of triangle
        a2 = math.sqrt((end2[0] - start2[0])**2 + (end2[1] - start2[1])**2)
        b2 = math.sqrt((far2[0] - start2[0])**2 + (far2[1] - start2[1])**2)
        c2 = math.sqrt((end2[0] - far2[0])**2 + (end2[1] - far2[1])**2)

        # apply cosine rule here
        angle2 = math.acos((b2**2 + c2**2 - a2**2)/(2*b2*c2)) * 57

        # ignore angles > 90 and highlight rest with red dots
        if angle2 <= 90:
            count_defects2 += 1
            cv2.circle(crop_img2, far2, 1, [0,0,255], -1)

        cv2.line(crop_img2,start2, end2, [0,255,0], 2)

        if count_defects2 == 1:
            cv2.putText(img,"I am Vipul", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, 2)
            #gui.moveTo(cx,cy)
        elif count_defects2 == 2:
            str = "This is a basic hand gesture recognizer"
            #gui.getWindow("Files").maximize()
        elif count_defects2 == 3:
            cv2.putText(img,"This is 4 :P", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, 2)
        elif count_defects2 == 4:
            cv2.putText(img,"Hi!!!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, 2)
        else:
            cv2.putText(img,"Hello World!!!", (50, 50),cv2.FONT_HERSHEY_SIMPLEX, 2, 2)

    #cv2.namedWindow('window1',cv2.WINDOW_NORMAL)
    cv2.imshow('window1',img)
    cv2.resizeWindow('window1',(600,600))

    k = cv2.waitKey(10)
    if k == 27:
        break


import logging
import os
from pprint import pprint
from gensim import corpora, models, similarities
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

if (os.path.exists("tmp/mesh.dict")):
   dictionary = corpora.Dictionary.load('tmp/mesh.dict')
   corpus = corpora.MmCorpus('tmp/corpus.mm')
   print("Used files generated from dict_corpus")
else:
   print("Please run dict_corpus.py to generate data set")

if (os.path.exists("tmp/model.tfidf")):
    tfidf = models.TfidfModel.load('tmp/model.tfidf')
    lsi = models.LsiModel.load('tmp/model.lsi')
    lda = models.LdaModel.load('tmp/model.lda')

new_doc = open('sample.txt', 'r', encoding = 'utf-8').read()
print(new_doc)

new_vec = dictionary.doc2bow(new_doc.lower().split())
pprint(new_vec)

vec_tfidf = tfidf[new_vec]
pprint(vec_tfidf)

vec_lsi = lsi[new_vec]
pprint(vec_lsi)

vec_lda = lda[new_vec]
pprint(vec_lda)


from rest_framework import serializers

from .models import RedditPost, RedditPostSnapshot

class RedditPostSerializer(serializers.HyperlinkedModelSerializer):
    # snapshots = serializers.HyperlinkedRelatedField(
    #     many=True,
    #     read_only=True,
    #     view_name='reddit_post_snapshots'
    # )
    class Meta:
        model = RedditPost
        fields = (
            'submission_id',
            'image_similarity',
            'image_url',
            'title',
            'subreddit',
            'subreddit_id',
            'permalink',
            'submission_created',
            'author',
            # 'snapshots',
        )

class RedditPostSnapshotSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = RedditPostSnapshot
        fields = '__all__'


import copy
import os

import numpy as np

from metadrive.manager.base_manager import BaseManager
from metadrive.scenario.scenario_description import ScenarioDescription as SD, MetaDriveType
from metadrive.scenario.utils import read_scenario_data, read_dataset_summary

class ScenarioDataManager(BaseManager):
    DEFAULT_DATA_BUFFER_SIZE = 100
    PRIORITY = -10

    def __init__(self):
        super(ScenarioDataManager, self).__init__()
        from metadrive.engine.engine_utils import get_engine
        engine = get_engine()

        self.store_data = engine.global_config["store_data"]
        self.directory = engine.global_config["data_directory"]
        self.num_scenarios = engine.global_config["num_scenarios"]
        self.start_scenario_index = engine.global_config["start_scenario_index"]

        # for multi-worker
        self.worker_index = self.engine.global_config["worker_index"]
        self.available_scenario_indices = [
            i for i in range(
                self.start_scenario_index + self.worker_index, self.start_scenario_index +
                self.num_scenarios, self.engine.global_config["num_workers"]
            )
        ]
        self._scenarios = {}

        # Read summary file first:
        self.summary_dict, self.summary_lookup, self.mapping = read_dataset_summary(self.directory)
        self.summary_lookup[:self.start_scenario_index] = [None] * self.start_scenario_index
        end_idx = self.start_scenario_index + self.num_scenarios
        self.summary_lookup[end_idx:] = [None] * (len(self.summary_lookup) - end_idx)

        # sort scenario for curriculum training
        self.scenario_difficulty = None
        self.sort_scenarios()

        # existence check
        assert self.start_scenario_index < len(self.summary_lookup), "Insufficient scenarios!"
        assert self.start_scenario_index + self.num_scenarios <= len(self.summary_lookup), \
            "Insufficient scenarios! Need: {} Has: {}".format(self.num_scenarios,
                                                              len(self.summary_lookup) - self.start_scenario_index)

        for p in self.summary_lookup[self.start_scenario_index:end_idx]:
            p = os.path.join(self.directory, self.mapping[p], p)
            assert os.path.exists(p), "No Data at path: {}".format(p)

        # stat
        self.coverage = [0 for _ in range(self.num_scenarios)]

    @property
    def current_scenario_summary(self):
        return self.current_scenario[SD.METADATA]

    def _get_scenario(self, i):
        assert i in self.available_scenario_indices, \
            "scenario index exceeds range, scenario index: {}, worker_index: {}".format(i, self.worker_index)
        assert i < len(self.summary_lookup)
        scenario_id = self.summary_lookup[i]
        file_path = os.path.join(self.directory, self.mapping[scenario_id], scenario_id)
        ret = read_scenario_data(file_path)
        assert isinstance(ret, SD)
        self.coverage[i - self.start_scenario_index] = 1
        return ret

    def before_reset(self):
        if not self.store_data:
            assert len(self._scenarios) <= 1, "It seems you access multiple scenarios in one episode"
            self._scenarios = {}

    def get_scenario(self, i, should_copy=False):

        _debug_memory_leak = False

        if i not in self._scenarios:

            if _debug_memory_leak:
                # inner psutil function
                def process_memory():
                    import psutil
                    import os
                    process = psutil.Process(os.getpid())
                    mem_info = process.memory_info()
                    return mem_info.rss

                cm = process_memory()

            # self._scenarios.clear_if_necessary()

            if _debug_memory_leak:
                lm = process_memory()
                print("{}:  Reset! Mem Change {:.3f}MB".format("data manager clear scenario", (lm - cm) / 1e6))
                cm = lm

            ret = self._get_scenario(i)
            self._scenarios[i] = ret

            if _debug_memory_leak:
                lm = process_memory()
                print("{}:  Reset! Mem Change {:.3f}MB".format("data manager read scenario", (lm - cm) / 1e6))
                cm = lm

        else:
            ret = self._scenarios[i]
            # print("===Don't need to get new scenario. Just return: ", i)

        if should_copy:
            return copy.deepcopy(self._scenarios[i])

        # Data Manager is the first manager that accesses  data.
        # It is proper to let it validate the metadata and change the global config if needed.

        return ret

    def get_metadata(self):
        state = super(ScenarioDataManager, self).get_metadata()
        raw_data = self.current_scenario
        state["raw_data"] = raw_data
        return state

    def transform_coordinate(self, scenario):
        raise ValueError("Deprecated now as all coordinates is right-handed now")
        if not self.engine.global_config["allow_coordinate_transform"]:
            assert scenario[SD.METADATA][SD.COORDINATE] == MetaDriveType.COORDINATE_METADRIVE, \
                "Only support MetaDrive coordinate!"
        else:
            # It supports loading WaymoData or exported data in two coordinates
            if scenario[SD.METADATA][SD.COORDINATE] == MetaDriveType.COORDINATE_WAYMO:
                self._coordinate_transform = True
            elif scenario[SD.METADATA][SD.COORDINATE] == MetaDriveType.COORDINATE_METADRIVE:
                self._coordinate_transform = False
            else:
                raise ValueError()

    @property
    def current_scenario_length(self):
        return self.current_scenario[SD.LENGTH]

    @property
    def current_scenario(self):
        return self.get_scenario(self.engine.global_random_seed)

    def sort_scenarios(self):
        """
        TODO(LQY): consider exposing this API to config
        Sort scenarios to support curriculum training. You are encouraged to customize your own sort method
        :return: sorted scenario list
        """
        if self.engine.max_level == 0:
            raise ValueError("Curriculum Level should be greater than 1")
        elif self.engine.max_level == 1:
            return

        def _score(scenario_id):
            file_path = os.path.join(self.directory, self.mapping[scenario_id], scenario_id)
            scenario = read_scenario_data(file_path)
            obj_weight = 0

            # calculate curvature
            ego_car_id = scenario[SD.METADATA][SD.SDC_ID]
            state_dict = scenario["tracks"][ego_car_id]["state"]
            valid_track = state_dict["position"][np.where(state_dict["valid"].astype(int))][..., :2]

            dir = valid_track[1:] - valid_track[:-1]
            dir = np.arctan2(dir[..., 1], dir[..., 0])
            curvature = sum(abs(dir[1:] - dir[:-1]) / np.pi) + 1

            sdc_moving_dist = SD.sdc_moving_dist(scenario)
            num_moving_objs = SD.num_moving_object(scenario, object_type=MetaDriveType.VEHICLE)
            return sdc_moving_dist * curvature + num_moving_objs * obj_weight

        start = self.start_scenario_index
        end = self.start_scenario_index + self.num_scenarios
        id_scores = [(s_id, _score(s_id)) for s_id in self.summary_lookup[start:end]]
        id_scores = sorted(id_scores, key=lambda scenario: scenario[-1])
        self.summary_lookup[start:end] = [id_score[0] for id_score in id_scores]
        self.scenario_difficulty = {id_score[0]: id_score[1] for id_score in id_scores}

    def clear_stored_scenarios(self):
        self._scenarios = {}

    @property
    def current_scenario_difficulty(self):
        return self.scenario_difficulty[self.summary_lookup[self.engine.global_random_seed]
                                        ] if self.scenario_difficulty is not None else 0

    @property
    def current_scenario_id(self):
        return self.current_scenario_summary["scenario_id"]

    @property
    def current_scenario_file_name(self):
        return self.summary_lookup[self.engine.global_random_seed]

    @property
    def data_coverage(self):
        return sum(self.coverage) / len(self.coverage) * self.engine.global_config["num_workers"]


"""
    1. Imports and definitions
"""

# i) imports

import matplotlib.pyplot as plt
import torch
import pyro
import pyro.distributions as dist
from pyro.infer import SVI, Trace_ELBO
from pyro.optim import Adam
import seaborn as sns

"""
    2. Data & stochastic model
"""

# i) Generate data

true_mean = torch.tensor(4.0)
data = dist.Normal(true_mean, 1).sample([100])

# ii) Construct stochastic model

prior_dist = dist.Normal(0., 3.)
def model(data = None):
    # Prior over the mean
    mu = pyro.sample("mu", prior_dist)
    # Likelihood
    len_data = len(data) if data is not None else 1
    with pyro.plate("data", len_data):
        obs = pyro.sample("obs", dist.Normal(mu, 1), obs=data)
    return obs

# iii) construct variational distribution

def guide(data = None):
    # Variational parameters
    mu_loc = pyro.param("mu_loc", torch.tensor(0.))
    mu_scale = pyro.param("mu_scale", torch.tensor(1.), constraint=dist.constraints.positive)
    # Variational distribution over the mean
    mu_sample = pyro.sample("mu", dist.Normal(mu_loc, mu_scale))
    return mu_sample

"""
    3. SVI inference
"""

# i) Perform inference

pyro.clear_param_store()
svi = SVI(model, guide, Adam({"lr": 0.01}), loss=Trace_ELBO())
for _ in range(1000):
    svi.step(data)

# ii) Print out parameters and uncertainties

for name, param in pyro.get_param_store().items():
    print('{} : {}'.format(name, param))

"""
    4. Plots and illustrations
"""

# i) Sample from the prior and the posterior

prior_samples = torch.tensor([prior_dist.sample() for _ in range(1000)])
posterior_samples = torch.tensor([guide().detach() for _ in range(1000)])

#  ii) Sample from the model, from model with posterior swapped in

model_samples = torch.tensor([model().detach() for _ in range(1000)])

def model_with_posterior():
    # Posterior over the mean
    mu = guide()
    # Likelihood
    obs = pyro.sample("obs", dist.Normal(mu, 1))
    return obs
ppd_samples = torch.tensor([model_with_posterior().detach() for _ in range(1000)])

# iv) Plotting empirical distributions

fig, axs = plt.subplots(3, 2, figsize=(10, 15))  # 3x2 grid of Axes

# data
sns.histplot(data, ax=axs[0, 0], kde=True)
axs[0, 0].set_title('Actual data')
# model
sns.histplot(model_samples, ax=axs[1, 0], kde=True)
axs[1, 0].set_title('Model samples of data using prior distribution')
# ppd
sns.histplot(ppd_samples, ax=axs[1, 1], kde=True)
axs[1, 1].set_title('Model samples of data using posterior distribution (ppd)')
# mu prior
sns.histplot(prior_samples, ax=axs[2, 0], kde=True)
axs[2, 0].set_title('Prior samples of mu')
# mu posterior
sns.histplot(posterior_samples, ax=axs[2, 1], kde=True)
axs[2, 1].set_title('Posterior samples of mu given data')

plt.tight_layout()
plt.show()

predictive = pyro.infer.Predictive(model = model, guide = guide, num_samples = 1000)
predictive_samples = predictive(())

# v) Use predictive functionality to produce values for all sample sites based
# on the posterior density encoded in guide i.e. p(z|x) (samples of mu) and
# p(x'|x) = int p(x'|z)p(z|x) dz (samples of new obs).

fig, axs = plt.subplots(2, 2, figsize=(10, 10))  # 3x2 grid of Axes

# predictive mu
sns.histplot(predictive_samples['mu'], ax=axs[0, 0], kde=True)
axs[0, 0].set_title('Predictive samples mu')
# predictive obs
sns.histplot(predictive_samples['obs'], ax=axs[0, 1], kde=True)
axs[0, 1].set_title('Predictive samples obs')

plt.tight_layout()
plt.show()


import spacy
import json
nlp = spacy.load('en')
json_data = open('Book_Data_Set.json',encoding="utf8")
data = json.load(json_data)
title = ""
for i in range (0, 10):
	doc = nlp(data[i]['description'])
	for np in doc:
		if np.pos_ == "NOUN" or np.pos_ == "PROPN":
			print (np.text,end='****')
	print()


# -*- coding: utf-8 -*-
import asyncio

from playwright.async_api import async_playwright

from cf_clearance import async_retry, stealth_async

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False, proxy={"server": "socks5://localhost:7890"}, args=[
            "--disable-gpu",
            '--no-sandbox',
            '--disable-dev-shm-usage',
            '--no-first-run',
            '--no-service-autorun',
            '--no-default-browser-check',
            '--password-store=basic',
            '--start-maximized',
        ])
        content = await browser.new_context(no_viewport=True)
        page = await content.new_page()
        await stealth_async(page)
        await page.goto('https://nowsecure.nl')
        res = await async_retry(page)
        if res:
            cppkies = await page.context.cookies()
            for cookie in cppkies:
                if cookie.get('name') == 'cf_clearance':
                    print(cookie.get('value'))
            ua = await page.evaluate('() => {return navigator.userAgent}')
            print(ua)
        else:
            print("获取失败")
        await browser.close()

asyncio.get_event_loop().run_until_complete(main())


from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm  # 비어있는 폼 제공
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout

# Create your views here.
def login(request):
    if request.method == 'POST':  # 로그인폼을 입력하고 로그인을 누르는 것
        # 로그인 처리를 해줌
        # 1) 입력한 아이디와 패스워드가 일치하는지 검사
        # 2) 일치하면 session table가서 session 만들고,
        # 3) 쿠키에 session id 담아서 전송
        # => django에서 가지고 있다.
        form = AuthenticationForm(request, request.POST)  # (요청들어온 곳에 쿠키 담아서 보냄)
        if form.is_valid():
            auth_login(request, form.get_user())
            # 응답
            return redirect('articles:index')

    else:
        # 비어있는 로그인 페이지를 제공 -> 이미 가지고 있음
        form = AuthenticationForm()
    context = {'form' : form}
    return render(request, 'accounts/login.html', context)

def logout(request):
    # 현재 request로 들어왔는데,
    # 요청에 있는 쿠키를 열어서 session id가 있으면 꺼내서
    # db의 session table과 비교해서 있으면 로그아웃
    auth_logout(request)
    return redirect('articles:index')


"""
Microdeploy Configuration manager.
"""

import yaml
import glob
import re
import os

class Config(object):

    # config = None

    def __init__(self, config_filename=None, default_baudrate=115200, override={}):

        if config_filename:
            try:
                with open(config_filename) as config_file:
                    config_yaml = yaml.load(config_file.read(), yaml.Loader)
            except FileNotFoundError as e:
                raise FileNotFoundError(f"Config file not found: '{config_filename}'")
            except yaml.scanner.ScannerError as e:
                message = str(f'\t{e}').replace('\n', '\n\t')  # indent message from ScannerError
                raise yaml.scanner.ScannerError(f"Error in config file: {config_filename}\n\n{message}")
        else:
            config_file = None
            config_yaml = {}

        self.config = {
            'packages': config_yaml.get('packages', {}),
            'device': config_yaml.get('device', {}),
            'default': {
                # 'destination': config_yaml.get('default', {}).get('destination') or '/' or None,  # default path of destination for put files to MCU
                'baudrate': config_yaml.get('default', {}).get('baudrate') or default_baudrate}}

        dict_update(self.config, override)
        self.config_filename = config_filename

    def device(self) -> dict:
        """Return device configuration, applying `*overrides`."""
        device = self.config.get('device', {})
        device = dict(device)
        return {
            'port': device.get('port'),
            'baudrate': device.get('baudrate', self.config['default']['baudrate'])}

    def package(self, name: str) -> dict:
        """Return package configuration dict."""
        try:
            package = self.config.get('packages', {})[name]
        except KeyError as e:
            KeyError(f"Package not found: {name}  - packages available: {', '.join(self.config.get('packages', {}).keys())}")

        try:
            ignore = set()
            for package_to_include in package.get('include', []):
                to_ignore = self.config.get('packages', {})[package_to_include].get('ignore', [])
                if to_ignore:
                    ignore.update(to_ignore)
                    package['ignore'] = list(ignore)
        except KeyError as e:
            raise KeyError(f'Package not found: {package_to_include} - in {name}.include')

        return package

    def package_files(self, name: str) -> list:
        """Return list of files in package having `name` (processing includes)."""
        try:
            package_config = self.package(name)
        except KeyError as e:
            raise ValueError(f"Package not found: {name}  - packages available: {', '.join(self.config.get('packages', {}).keys())}")

        def ignore(filename):
            return any(re.search(ignored, filename) for ignored in package_config.get('ignore', []))

        package_files = []
        for file_desc in package_config.get('files', []):
            if type(file_desc) is not str and not len(file_desc) == 2:
                raise ValueError("File definition must be string or tuple, eg. 'main.py' or ('source.py', 'destination.py')")
            source, destination = [file_desc, None] if type(file_desc) is str else file_desc
            source_relative = self.make_relative_to_configfile(source)
            if ignore(source_relative):
                continue
            if '*' not in source_relative:
                package_files.append((source_relative, destination or source))
            else:
                for source_file in glob.iglob(source_relative, recursive=True):  # Note: this allows wildcards in source files, eg. 'tests/*.py' or 'tests/**/*.py``
                    if os.path.isdir(source_file):
                        continue
                    if ignore(source_file):
                        continue
                    if destination is not None:
                        destination_file = destination
                    else:
                        relative_path = os.path.relpath(os.path.dirname(self.config_filename) or '.')
                        destination_file = source_file[1+len(relative_path):]
                    package_files.append((source_file, destination_file))

        for package_to_include in package_config.get('include', []):
            try:
                package_files = self.package_files(package_to_include) + package_files
            except ValueError as e:
                raise KeyError(f'Package not found: {package_to_include} - in {name}.include')

        return package_files

    def make_relative_to_configfile(self, filename):
        """Return `filename` made relative to config file path."""
        return os.path.join(os.path.relpath(os.path.dirname(self.config_filename) or '.'), filename)

class Configurable(object):
    """
    Abstract class base for components (ie. device, package).
    """
    def __init__(self, config: Config):
        self.config = config

# Helpers

def dict_update(d1, d2):
    """
    Update `d1` with `d2` deeply.
    """
    for k in d2:
        if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
            dict_update(d1[k], d2[k])
        else:
            d1[k] = d2[k]


from django.conf.urls import url

from .views import (
    get_articles_list,
    home,
    search_articles,
)

urlpatterns = [
    # url(r'^create$', collection_create, name="create"),
    # url(r'^(?P<slug>[\w-]+)/add$', link_add, name='add'),
    # url(r'^(?P<slug>[\w-]+)(?:/(?P<tag>[\w-]+))?/$', collection_detail, name='detail'),
    # url(r'^(?P<slug>[\w-]+)/search$', search_link, name="search_link"),
    # url(r'^(?P<slug>[\w-]+)/edit$', collection_update, name='update'),
    # url(r'^(?P<slug>[\w-]+)/delete$', collection_delete, name='delete'),
    url(r'^$', home, name='home'),
    url(r'^api/v1/get-articles-list$', get_articles_list, name='get_articles_list'),
    url(r'^api/v1/search-articles$', search_articles, name='search_articles'),
    # url(r'^about$', about, name='about'),
    # url(r'^link/(?P<id>\d+)/delete$', link_delete, name='link_delete' ),
    # url(r'^(?P<slug>[\w-]+)/delete$', collection_delete, name='collection_delete'),
    # url(r'^link/(?P<id>\d+)/edit$', link_edit, name='link_edit' ),
]


import os
import cv2 as cv
import numpy as np

imagedb_train = ('imagedb_train')

sift = cv.xfeatures2d_SIFT.create()
folders = os.listdir(imagedb_train)

def extract_local_features(path):
    img = cv.imread(path)

    kp = sift.detect(img)
    desc = sift.compute(img, kp)
    desc = desc[1]
    return desc

train_descs = np.zeros((0, 128), dtype=np.float32)

for folder in folders:
    current_folder = os.path.join(imagedb_train, folder)
    print(current_folder)  #gia na vlepw se poio simio ine o kodikas
    files = os.listdir(current_folder)
    for file in files:
        current_file = os.path.join(current_folder, file)
        desc = extract_local_features(current_file)
        train_descs = np.concatenate((train_descs, desc), axis=0)

# Create vocabulary
print("K-Means Calculating...")  #gia na vlepw se poio simio ine o kodikas

term_crit = (cv.TERM_CRITERIA_EPS, 50, 0.1)
loss, assignments, vocabulary = cv.kmeans(train_descs.astype(np.float32), 50, None, term_crit, 1, 0)
np.save('vocabulary.npy', vocabulary)

#vocabulary = np.load('vocabulary.npy')

# Create Histograms
current_label = np.full((1, 1), 1, dtype=int)
train_class_labels = np.zeros((0, 1), dtype=int)

def getBovwDescriptor(desc, vocabulary):
    bow_desc = np.zeros((1, vocabulary.shape[0]), dtype=np.float32)
    for d in range(desc.shape[0]):
        distances = desc[d, :] - vocabulary
        distances = np.abs(distances)
        distances = np.sum(distances, axis=1)
        mini = np.argmin(distances)
        bow_desc[0, mini] += 1
    return bow_desc

bow_descs = np.zeros((0, vocabulary.shape[0]), dtype=np.float32)
for folder in folders:
    current_folder = os.path.join(imagedb_train, folder)
    print(current_folder)
    files = os.listdir(current_folder)
    for file in files:
        current_file = os.path.join(current_folder, file)
        print(current_file)
        desc = extract_local_features(current_file)
        bow_desc = getBovwDescriptor(desc, vocabulary)
        bow_descs = np.concatenate((bow_descs, bow_desc), axis=0)
        train_class_labels=np.concatenate((train_class_labels,current_label), axis=0)
    current_label[0] = current_label[0] + 1

np.save('bow_descs.npy', bow_descs)
np.save('train_class_labels.npy', train_class_labels)


#!/usr/bin/env python
import unittest
import os
import shutil
import multiprocessing
import glob
from matador.scrapers.castep_scrapers import res2dict

ROOT_DIR = os.getcwd()
REAL_PATH = "/".join(os.path.realpath(__file__).split("/")[:-1]) + "/"
TEST_DIR = REAL_PATH + "/tmp_test"
NUM_CORES = multiprocessing.cpu_count()

if os.uname()[1] == "cluster2":
    NUM_CORES -= 2

def hull_test(self):
    """ Perform a test run of Ilustrado with dummy DFT,
    on all cores of current machine.
    """
    from matador.hull import QueryConvexHull
    from ilustrado.ilustrado import ArtificialSelector

    res_files = glob.glob(REAL_PATH + "/data/hull-KP-KSnP_pub/*.res")
    cursor = [res2dict(_file, db=True)[0] for _file in res_files]

    # prepare best structures from hull as gene pool
    hull = QueryConvexHull(
        cursor=cursor,
        elements=["K", "P"],
        subcmd="hull",
        no_plot=True,
        source=True,
        summary=True,
        hull_cutoff=0,
    )

    cursor = hull.hull_cursor[1:-1]

    print("Running on {} cores on {}.".format(NUM_CORES, os.uname()[1]))

    minsep_dict = {("K", "K"): 2.5}

    ArtificialSelector(
        gene_pool=cursor,
        hull=hull,
        debug=False,
        fitness_metric="hull",
        nprocs=NUM_CORES,
        check_dupes=0,
        check_dupes_hull=False,
        sandbagging=True,
        minsep_dict=minsep_dict,
        ncores=1,
        testing=True,
        mutations=["nudge_positions", "permute_atoms", "random_strain", "vacancy"],
        max_num_mutations=1,
        max_num_atoms=50,
        mutation_rate=0.5,
        crossover_rate=0.5,
        num_generations=3,
        population=15,
        num_survivors=10,
        elitism=0.5,
        loglevel="debug",
    )

    run_hash = glob.glob("*.json")[0].split("-")[0]

    new_life = ArtificialSelector(
        gene_pool=cursor,
        hull=hull,
        debug=False,
        fitness_metric="hull",
        recover_from=run_hash,
        load_only=True,
        check_dupes=0,
        check_dupes_hull=False,
        minsep_dict=minsep_dict,
        mutations=["nudge_positions", "permute_atoms", "random_strain", "vacancy"],
        sandbagging=True,
        nprocs=NUM_CORES,
        ncores=1,
        testing=True,
        max_num_mutations=1,
        max_num_atoms=50,
        mutation_rate=0.5,
        crossover_rate=0.5,
        num_generations=10,
        population=15,
        num_survivors=10,
        elitism=0.5,
        loglevel="debug",
    )
    self.assertTrue(len(new_life.generations[-1]) >= 15)
    self.assertTrue(len(new_life.generations[-1].bourgeoisie) >= 10)

    new_life.start()

    self.assertTrue(os.path.isdir(new_life.run_hash + "-results"))
    num_structures = len(glob.glob(new_life.run_hash + "-results/*.res"))
    self.assertTrue(num_structures > 5)

class MatadorHullUnitTest(unittest.TestCase):
    """ Tests matador hull init of ilustrado. """

    def setUp(self):
        if os.path.isdir(TEST_DIR):
            shutil.rmtree(TEST_DIR)
        os.makedirs(TEST_DIR, exist_ok=True)
        os.chdir(TEST_DIR)

    def tearDown(self):
        os.chdir(ROOT_DIR)
        shutil.rmtree(TEST_DIR)

    def testIlustradoFromHull(self):
        # if main throws an error, so will unit test
        print(os.getcwd())
        hull_test(self)

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


import colors as c
from utils import ask

intro = c.orange + '''
Welcome to the orange quiz game!!!!!!
'''  + c.reset

def q1():
    color = ask(c.yellow + 'What is the color of an orange?' + c.reset)
    if color == 'orange':
        return True
    print(c.red + 'You have failed' + c.reset)
    return False

def q2():
    peel = ask(c.green + 'What is the correct way to eat an orange?' + c.reset)
    if peel.startswith("peel"):
        return True
    print(c.red + "You have failed" + c.reset)
    return False

def q3():
    type = ask(c.blue + 'Am I refferring to the fruit or color?' + c.reset)
    if type == ("fruit"):
        return True
    print (c.red + 'You have failed' + c.reset)
    return False
questions = [q1,q2,q3]


# -*- mode: python ; coding: utf-8 -*-
from PyInstaller.utils.hooks import collect_submodules

hiddenimports = ['scipy.spatial.transform._rotation_groups', 'sqlalchemy.sql.default_comparator', 'sklearn.metrics._pairwise_distances_reduction._datasets_pair', 'sklearn.neighbors._partition_nodes', 'sklearn.metrics._pairwise_distances_reduction._datasets_pair', 'cmath']
hiddenimports += collect_submodules('sklearn.utils')

block_cipher = None

a = Analysis(
    ['run.py'],
    pathex=['/opt/homebrew/Caskroom/miniforge/base/envs/scope2screen2'],
    binaries=[],
    datas=[('minerva_analysis/client', 'minerva_analysis/client'), ('minerva_analysis/__init__.py', 'minerva_analysis/'), ('minerva_analysis/server', 'minerva_analysis/server'), ('/opt/homebrew/Caskroom/miniforge/base/envs/scope2screen2/lib/python3.8/site-packages/xmlschema/schemas', 'xmlschema/schemas')],
    hiddenimports=hiddenimports,
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='scope2screen_mac',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)


# -*-coding: utf-8 -*-
# Python 3.6
# Author:Zhang Haitao
# Email:13163385579@163.com
# TIME:2018-08-15  16:04
# NAME:zht-wind_api.py
import datetime
import multiprocessing
import pickle

from WindPy import w
from utils.dateu import get_today
import numpy as np

DIR=r'e:\tmp_wind'

w.start()

import pandas as pd
import os

DATE_FORMAT='%Y-%m-%d'

def multi_task(func, args_iter, n=8):
    pool=multiprocessing.Pool(n)
    results=pool.map(func, args_iter)
    pool.close()#trick: close the processing every time the pool has finished its task, and pool.close() must be called before pool.join()
    pool.join()
    #refer to https://stackoverflow.com/questions/38271547/when-should-we-call-multiprocessing-pool-join
    return results

def get_stkcd_list():
    today = get_today(DATE_FORMAT)
    path=os.path.join(DIR,'stkcd_list_{}.pkl'.format(today))
    if os.path.exists(path):
        return pickle.load(open(path,'rb'))
    else:
        codes=w.wset("SectorConstituent",u"date={};sector=全部A股".format(today)).Data[1]
        f=open(path,'wb')
        pickle.dump(codes,f)
        return codes

def get_ann_dt():
    today=get_today(DATE_FORMAT)
    path=os.path.join(DIR,'ann_dt_{}.pkl'.format(today))
    if os.path.exists(path):
        return pickle.load(open(path,'rb'))
    else:
        codes=get_stkcd_list()
        result=w.wsd(','.join(codes), "stm_issuingdate", "ED-5Q", get_today(), "Period=Q;Days=Alldays")
        ann_dt=pd.DataFrame(result.Data,index=result.Codes,columns=result.Times).T
        f=open(path,'wb')
        pickle.dump(ann_dt,f)
        return ann_dt

def get_last_ann_dt():
    anns=[an for an in os.listdir(os.path.join(DIR)) if an.startswith('ann_dt') and an[7:-4] !=get_today()]
    anns=sorted(anns,key=lambda x:pd.to_datetime(x[7:-4]))
    return pd.read_pickle(os.path.join(DIR,anns[-1]))

def get_data_for_one_stk(args):
    stkcd, rpdate, indicators=args
    data = w.wsd(stkcd, ','.join(indicators), rpdate, rpdate, "unit=1;rptType=1;Period=Q;Days=Alldays").Data
    s = pd.Series([d[0] for d in data], index=indicators)
    s.fillna(value=np.nan, inplace=True)
    s.name=stkcd
    print('Getting data for {}-----{}'.format(rpdate,stkcd))
    return s

def get_new_df():
    ann_dt=get_ann_dt()
    last_ann_dt=get_last_ann_dt()

    new_index=ann_dt.index.union(last_ann_dt.index)
    new_column=ann_dt.columns.union(last_ann_dt.columns)

    ann_dt=ann_dt.reindex(index=new_index,columns=new_column)
    last_ann_dt=last_ann_dt.reindex(index=new_index,columns=new_column)
    new_df=ann_dt[ann_dt!=last_ann_dt]
    return new_df

def get_new_data(ann_dt_df):
    name_df = pd.read_excel(os.path.join(DIR,r'indicators_name.xlsx'), sheet_name='financial')
    dfs = []
    for date, row in ann_dt_df.iterrows():
        row = row.dropna()
        row = row.apply(lambda x: x.strftime(DATE_FORMAT))
        rpdate = row.name.strftime(DATE_FORMAT)
        stkcds = row.index.tolist()
        indicators = name_df['wind_name'].tolist()
        # _df=pd.concat(multi_task(get_data_for_one_stk,((stkcd, rpdate, indicators) for stkcd in stkcds)),axis=1).T
        _df = pd.concat([get_data_for_one_stk((stkcd, rpdate, indicators)) for stkcd in stkcds], axis=1).T
        _df['rpdate'] = rpdate
        _df.set_index('rpdate', append=True, inplace=True)
        _df.index.names = ['stkcd', 'rpdate']
        # df.to_pickle(os.path.join(DIR,'data_{}.pkl'.format(get_today())))
        dfs.append(_df)
    df = pd.concat(dfs)
    return df

# today_updated.to_pickle(os.path.join(DIR, 'today_updated_{}.pkl'.format(get_today())))

#TODO: how to combine the old and the new dataframe

# codes = get_stkcd_list()
# result = w.wsd(','.join(codes), "stm_issuingdate", "ED-5Q", get_today(), "Period=Q;Days=Alldays")
# ann_dt = pd.DataFrame(result.Data, index=result.Codes, columns=result.Times).T
#
# ann_dt.to_pickle(os.path.join(DIR,'ann_dt_{}.pkl'.format(get_today())))
#
# test_ann_dt=ann_dt.iloc[:,30]
#
# df=get_new_data(ann_dt)

def test():
    ann_dt=pd.read_pickle(os.path.join(DIR,'ann_dt_{}.pkl'.format(get_today())))
    test_ann_dt=ann_dt.iloc[:,:30]
    df=get_new_data(test_ann_dt)
    df.to_pickle('test_df.pkl')

if __name__ == '__main__':
    test()

#TODO: logger and multiprocessing


#!./icao-venv/bin/python3

# needs:    opencv2-python
#           opencv2-contrib-python
#           dlib

import os
from pathlib import Path
import sys
import cv2
import dlib
import numpy as np
import json

show_rectangle = False

# set here, where to look for pretrained models:
datadir = Path("data")

# following files should be present in the datadir:
needed_files = {
    "shape_predictor_68_face_landmarks.dat":
        "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2"
}

def check_for_needed_files(datadir: Path):
    from urllib import request

    if not datadir.is_dir():
        datadir.mkdir()

    # Downloading needed Files
    for filename, url in needed_files.items():
        file = datadir.joinpath(filename)
        newfile = dlfile = file.parent.joinpath(Path(url).name)

        if not file.exists():
            print(
                "Downloading  " + url,
                file=sys.stderr
            )
            request.urlretrieve(
                url,
                filename=dlfile,
                reporthook=lambda blocks, blocksize, fullsize:
                    print(str((blocks * blocksize * 100) /
                              fullsize)[:5] + "%" + "\033[F", file=sys.stderr)
            )
            print("Done" + (" " * 12), file=sys.stderr)

            # decompress BZ2 files
            if dlfile.suffix == ".bz2":
                import bz2
                newfile = dlfile.parent.joinpath(dlfile.stem)
                if not newfile.exists():
                    print("Decompressing " + str(dlfile), file=sys.stderr)
                    newfile.write_bytes(bz2.decompress(dlfile.read_bytes()))
                    dlfile.unlink()

            # mv file to desired name
            if newfile.resolve() != file.resolve():
                newfile.rename(file)

class Face:
    pass

class image_analyzer:
    def __init__(self, image_path: str,
                 pretrained_predictor: str =
                 datadir.joinpath("shape_predictor_68_face_landmarks.dat"),
                 upsample_num_times: int = 1
                 ):
        self._path = Path(image_path)
        if self._path.exists():
            self._img = cv2.imread(str(self._path.resolve()))
            if(self._img is None):
                raise ValueError(
                    "OpenCV can't read Imagefile: " + str(self._path))
        else:
            raise FileNotFoundError("Imagefile not found: " + str(self._path))
        self._pretrained_predictor = Path(pretrained_predictor)
        self._upsample_num_times = upsample_num_times

    def img(self):
        return self._img

    def width(self):
        return len(self._img[0])

    def height(self):
        return len(self._img)

    def image_ratio(self):
        return len(self._img[0]) / len(self._img)

    def check_image_ratio(self, min: float=0.74, max: float=0.80):
        return (min <= self.image_ratio() <= max)

    def face_detector(self):
        # get static face detector
        if not hasattr(image_analyzer, '_face_detector') or image_analyzer._face_detector is None:
            image_analyzer._face_detector = dlib.get_frontal_face_detector()
        return image_analyzer._face_detector

    def shape_predictor(self):
        # load static shape predictor:
        if not hasattr(self, '_shape_predictor') or self._shape_predictor is None:
            self._shape_predictor = dlib.shape_predictor(
                str(self._pretrained_predictor)
            )
        return self._shape_predictor

    def face_rectangles(self):
        # check if image changed:
        if not hasattr(self, '_face_rectangles') or self._face_rectangles is None:
            self._face_rectangles = self.face_detector()(
                image=self._img,
                upsample_num_times=self._upsample_num_times
            )
        return self._face_rectangles

    def shape_of_face(self, face: dlib.full_object_detection):
        return self.shape_predictor()(self._img, face)

    def shapes(self):
        # generator for facial landmarks
        for face in self.face_rectangles():
            yield self.shape_of_face(face)

    def faces(self):
        for face in self.face_rectangles():
            yield Face(face, self)

class Face:
    def __init__(self,
                 rectangle: dlib.full_object_detection,
                 analyzer: image_analyzer):
        self._rect = rectangle
        self._img = analyzer.img()
        self._shape = [np.array([p.x, p.y])
                       for p in analyzer.shape_of_face(rectangle).parts()]

    def shape(self):
        return self._shape

    def rect(self):
        return self._rect

    def eye_left(self):
        return (self._shape[36] + self._shape[39]) / 2

    def eye_right(self):
        return (self._shape[42] + self._shape[45]) / 2

    def eye_center(self):
        return (self.eye_left() + self.eye_right()) / 2

    def mouth_center(self):
        return np.sum(self._shape[48:60], axis=0) / 12

def main(argv):
    if len(argv) < 2:
        print("missing image file", file=sys.stderr)
        print("run: $ python3 geometry_check.py /path/to/image/file", file=sys.stderr)
        return 1

    if not hasattr(cv2, 'face'):
        print("you need to install opencv2-contrib-python", file=sys.stderr)
        print("$ pip install opencv2-contrib-python", file=sys.stderr)
        return 1

    checks = dict({
        "ratio_correct": False,
        "face_detected": False,
        "single_face": False,
        "h_line_almost_horizontal": False,
        "h_line_rotation": None,
        "v_line_almost_vertical": False,
        "v_line_rotation": None,
        "midpoint_in_vertical_center": False,
        "midpoint_in_upper_half": False,
        "midpoint": None,
        "head_width_correct": False,
        "head_width_ratio": None
    })

    # CHECKS STARTING HERE:
    analyzer = image_analyzer(argv[1])
    checks["ratio_correct"] = bool(
        analyzer.check_image_ratio(min=0.74, max=0.80))
    faces = [f for f in analyzer.faces()]
    checks["face_detected"] = bool(len(faces) > 0)
    if len(faces) == 1:
        checks["single_face"] = True
        face = faces[0]
        #   I: H line almost horizontal:
        #      (f.eye_left()-f.eye_right())[1] rund 0
        #          abs( -||- / ana.height() ) < 0.01 # weniger als 1% rotation
        h_rotation = (face.eye_left() - face.eye_right()
                      )[1] / analyzer.height()
        checks["h_line_almost_horizontal"] = bool(abs(h_rotation) < 0.01)
        checks["h_line_rotation"] = float(h_rotation)

        #  II: V line almost vertical,
        #      H line is more important, because V and H don't need to be perpendicular
        #       (f.eye_center()-f.mouth_center())[0] rund 0
        #          abs( -||- / ana.width() ) < 0.05 # weniger als 5% rotation
        v_rotation = (face.eye_center() - face.mouth_center()
                      )[0] / analyzer.width()
        checks["v_line_almost_vertical"] = bool(abs(v_rotation) < 0.05)
        checks["v_line_rotation"] = float(v_rotation)

        # III: Midpoint M needs to be in horizontal center and vertically 30%-50% from top
        #      f.eye_center()/[ana.width(),ana.height()] = [ 0.45 <= x <= 0.55 , 0.30 <= y <= 0.50 ]
        m_rel = face.eye_center() / [analyzer.width(), analyzer.height()]
        checks["midpoint_in_vertical_center"] = bool(
            (m_rel[0] >= 0.45) and (m_rel[0] <= 0.55))
        checks["midpoint_in_upper_half"] = bool(
            (m_rel[1] >= 0.30) and (m_rel[1] <= 0.50))
        checks["midpoint"] = [float(d) for d in m_rel]

        #  IV: Headwith ratio
        head_width_ratio = face.rect().width() / analyzer.width()
        checks["head_width_correct"] = bool(
            (head_width_ratio >= 0.5) and (head_width_ratio <= 0.75))
        checks["head_width_ratio"] = float(head_width_ratio)

        if show_rectangle:
            img = analyzer.img()
            cv2.namedWindow("Bild", cv2.WND_PROP_FULLSCREEN)
            cv2.setWindowProperty("Bild", cv2.WND_PROP_FULLSCREEN,
                                  cv2.WINDOW_FULLSCREEN)
            rect = face.rect()
            cv2.rectangle(img, (rect.left(), rect.top()),
                          (rect.right(), rect.bottom()),  (0, 255, 255))
            cv2.imshow("Bild", img)
            while(1):
                k = cv2.waitKey(33)
                if k == 27 or k == ord('q'):    # Esc key or q to stop
                    cv2.destroyAllWindows()
                    break

    return checks

if __name__ == '__main__':
    check_for_needed_files(datadir)
    result = main(sys.argv)
    print(json.dumps(result))
    sys.exit(0)