#!/usr/bin/env python
# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration

# art-description: athenaHLT test of timeout handling
# art-type: build
# art-include: master/Athena
# Skipping art-output which has no effect for build tests.
# If you create a grid version, check art-output in existing grid tests.

from TrigValTools.TrigValSteering import Test, ExecStep, CheckSteps
from TrigP1Test.TrigP1TestSteps import TrigBSDumpGrepStep

output_name_base = 'output.test_trigP1_timeout'

ex = ExecStep.ExecStep()
ex.type = 'athenaHLT'
ex.job_options = 'TrigP1Test/testHLT_timeout.py'
ex.input = 'data'
ex.max_events = 20
ex.args = '--timeout 2000'
ex.args += ' -o ' + output_name_base

test = Test.Test()
test.art_type = 'build'
test.exec_steps = [ex]
test.check_steps = CheckSteps.default_check_steps(test)

# Use special check_log config to ignore timeout errors which are expected in this test
test.get_step('CheckLog').config_file = 'checklogTrigP1TimeoutTest.conf'

# Step checking if there is at least one event in HltTimeout debug stream
debug_count_step = TrigBSDumpGrepStep('DebugCount')
debug_count_step.args += '--stag'
debug_count_step.file_name_base = output_name_base
debug_count_step.regex = 'Stream Tags:.*debug_HltTimeout'
debug_count_step.comparator = lambda num: num > 0
test.check_steps.append(debug_count_step)

# Step checking if number of output events is equal to number of input events
event_count_step = TrigBSDumpGrepStep('EventCount')
event_count_step.file_name_base = output_name_base
event_count_step.regex = r'Global_ID'
event_count_step.comparator = lambda num: num == ex.max_events
test.check_steps.append(event_count_step)

import sys
sys.exit(test.run())


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

class SFCN(nn.Module):
    def __init__(self, channel_number=[32, 64, 128, 256, 256, 64], output_dim=40, dropout=0.5,batch_norm=True):
        '''
            channel_number - list of ints - number of channels for 3d convolutions
            output_dim - output dimension of model - e.g. for sex prediction 2 or age prediction the number of bins
            dropout - float - probability of a single node to dropout at final layer
            batch_norm - bool - indicates whether batch normalization is applied
        '''
        super(SFCN, self).__init__()
        self.n_layer = len(channel_number)
        self.output_dim=output_dim
        self.channel_number=channel_number

        #Define part 1: feature extractor
        self.feature_extractor = nn.Sequential()
        for i in range(self.n_layer):
            if i == 0:
                in_channel = 1
            else:
                in_channel = channel_number[i-1]
            out_channel = channel_number[i]
            if i < self.n_layer-1:
                self.feature_extractor.add_module('conv_%d' % i,
                                                  self.conv_layer(in_channel,
                                                                  out_channel,
                                                                  maxpool=True,
                                                                  kernel_size=3,
                                                                  padding=1,
                                                                  batch_norm=batch_norm))
            else:
                self.feature_extractor.add_module('conv_%d' % i,
                                                  self.conv_layer(in_channel,
                                                                  out_channel,
                                                                  maxpool=False,
                                                                  kernel_size=1,
                                                                  padding=0,
                                                                  batch_norm=batch_norm))
        #Define part 2: classifier
        self.classifier = nn.Sequential()
        avg_shape = [5, 6, 5]
        self.classifier.add_module('average_pool', nn.AvgPool3d(avg_shape))

        if dropout is not None:
            self.classifier.add_module('dropout', nn.Dropout(dropout))

        in_channel = channel_number[-1]
        out_channel = self.output_dim
        self.classifier.add_module('conv_%d' % self.n_layer,
                                   nn.Conv3d(in_channel, out_channel, padding=0, kernel_size=1))

    @staticmethod
    def conv_layer(in_channel, out_channel, maxpool=True, kernel_size=3, padding=0, maxpool_stride=2,batch_norm=True):
        '''
        A function to build a convolutional layer including batch normalization, pooling and ReLU activation
        Input:
            in_channel, out_channel - ints - number of in and out channels
            maxpool - bool - indicates whether max-pooling is applied
            kernel_size.padding,maxpool_stride - int - parameters for model
            batch_norm - bool - indicates whether batch norm is applied
        Output:
            torch.nn.Sequential module - layer
        '''

        if batch_norm:
            batch_norm_layer=nn.BatchNorm3d(out_channel)
        else:
            batch_norm_layer=nn.Identity()

        if maxpool is True:
            layer = nn.Sequential(
                nn.Conv3d(in_channel, out_channel, padding=padding, kernel_size=kernel_size),
                batch_norm_layer,
                nn.MaxPool3d(2, stride=maxpool_stride),
                nn.ReLU(),
            )
        else:
            layer = nn.Sequential(
                nn.Conv3d(in_channel, out_channel, padding=padding, kernel_size=kernel_size),
                batch_norm_layer,
                nn.ReLU()
            )
        return layer

    def forward(self, x):
        '''
        Input: x - torch.Tensor - shape (batch_size,1,160,192,160)
        Output: torch.Tensor - shape (batch_size,self.output_dim)
                    - Every row consists of log-probabilities of a probability distribution.
        '''
        batch_size=x.size(0)
        x_f = self.feature_extractor(x)
        x = self.classifier(x_f)
        x=x.view(batch_size,-1)
        x = F.log_softmax(x, dim=1)
        return(x)

    def set_grad_classifier(self, val):
        '''
        Function to set the gradient parameters of classifier.
        Input: val - bool - value of gradient computation of classifier
        '''
        for p in self.classifier.parameters():
            p.requires_grad=val

    def set_grad_featext(self,vals,layers):
        '''
        Function to set the gradient parameters of feature extractor.
        Input:  val - list of bools - gradient parameters
                layers - list of ints - index of layer to set gradient parameter
        '''
        if len(layers)!=len(vals):
            sys.exit("Error in set_feature_extractor: Different lengths of val and layers.")

        for it in range(len(layers)):
            for p in self.feature_extractor[layers[it]].parameters():
                p.requires_grad=vals[it]

    def train_final_layer(self):
        '''
        Function to train classifier.
        '''
        self.set_grad_classifier(True)

    def train_full_model(self):
        '''
        After calling this function, all parameters
        of the model will be trained.
        '''
        for p in self.parameters():
            p.requires_grad=True

    def train_nothing(self):
        '''
        After calling this function, no parameters
        of the model will be trained.
        '''
        for p in self.parameters():
            p.requires_grad=False

    def train_only_final_layers(self,n_train_layers:int):
        '''
        Function to train (only!) the final layers of a network.
        Input: n_train_layers - int - number of final layers to train
                                (classifier is last layer)
        '''
        #Set gradient to zero everywhere:
        self.train_nothing()

        #Set gradient to true for the final layers:
        if n_train_layers>0:
            self.set_grad_classifier(True)

        if n_train_layers>1:
            n_feature_layers=n_train_layers-1

            #Count down from the end:
            feat_layers=[self.n_layer-it-1 for it in range(n_feature_layers)]
            #Set all true:
            feat_vals=[True for _ in feat_layers]

            self.set_grad_featext(feat_vals,feat_layers)

    def reinit_classifier_pres_scale(self):
        '''
        Function to reinitialize the parameters of classifier while preserving the scaling.
        '''
        for p in self.classifier.parameters():
            p_=p.data.detach()
            p.data=p_.std()*torch.randn(size=p_.shape).to(p_.device)+p_.mean()

    def reinit_featext_pres_scale(self,layers=None):
        '''
        Function to reinitialize the parameters of feature extractor while preserving the scaling.
        Input: layers - list of ints - indices of layers to reinitalize - if None everything is reinitialized
        '''
        if layers is None:
            layers=[it for it in range(self.n_layer)]
        for layer in layers:
            for p in self.feature_extractor[layer].parameters():
                p_=p.data.detach()
                p.data=p_.std()*torch.randn(size=p_.shape).to(p_.device)+p_.mean()

    def reinit_final_layers_pres_scale(self,n_train_layers:int):
        '''
        Function to reinitialize the final layers of the network while preserving the scaling.
        Input: n_train_layers - int - number of final layers to train
        '''
        n_train_layers=min(n_train_layers,self.n_layer+1)
        #Set gradient to true for the final layers:
        if n_train_layers>0:
            print("Initialize classifier layer.")
            self.reinit_classifier_pres_scale()
        if n_train_layers>1:
            n_feature_layers=n_train_layers-1
            feat_layers=[self.n_layer-it-1 for it in range(n_feature_layers)]
            print("Reinitialize feature layers: ", feat_layers)
            self.reinit_featext_pres_scale(feat_layers)

    def reinit_full_model_pres_scale(self):
        '''
        Function to reinitialize the full model while preserving scaling.
        '''
        self.reinit_classifier_pres_scale()
        self.reinit_featext_pres_scale()

    def change_output_dim(self, new_output_dim: int):
        '''
        new_output_dim - new output dimension
        '''
        c_in = self.classifier.conv_6.in_channels
        conv_last = nn.Conv3d(c_in, new_output_dim, kernel_size=1)
        self.classifier.conv_6 = conv_last
        self.output_dim=new_output_dim

#print(sfcn.feature_extractor)
# model=SFCN(dropout=0.5)
# #for name, module in model.named_modules():
# #    print(name)
# print(list(model.feature_extractor[0].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[1].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[2].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[3].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[4].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[5].parameters())[0].flatten()[0])
# print(list(model.classifier.parameters())[0].flatten()[0])
# # print()
# model.module.train_only_final_layers(2)
# model.reinit_full_model_pres_scale()
# print(list(model.feature_extractor[0].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[1].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[2].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[3].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[4].parameters())[0].flatten()[0])
# print(list(model.feature_extractor[5].parameters())[0].flatten()[0])
# print(list(model.classifier.parameters())[0].flatten()[0])


import numpy as np
from keras import layers
from keras.layers import Input, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D
from keras.layers import AveragePooling2D, MaxPooling2D, Dropout, GlobalMaxPooling2D, GlobalAveragePooling2D
from keras.utils import np_utils, print_summary
from keras.models import Sequential
from keras.callbacks import ModelCheckpoint
import pandas as pd
from sklearn.model_selection import train_test_split

import keras.backend as K

def keras_model(image_x, image_y):
    num_of_classes = 2
    model = Sequential()
    model.add(Conv2D(32, (5, 5), input_shape=(image_x, image_y, 1), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), padding='same'))
    model.add(Conv2D(64, (5, 5), activation='sigmoid'))
    model.add(MaxPooling2D(pool_size=(5, 5), strides=(5, 5), padding='same'))
    model.add(Flatten())
    model.add(Dense(1024, activation='relu'))
    model.add(Dropout(0.6))
    model.add(Dense(num_of_classes, activation='softmax'))

    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    filepath = "emojinator.h5"
    checkpoint1 = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True, mode='max')
    callbacks_list = [checkpoint1]

    return model, callbacks_list

def main():
    dataset = pd.read_csv("train_foo.csv")
    # Normalizing the training dataset (train.csv file)# Norma
    dataset = dataset.sample(frac=1)
    X = dataset.iloc[:,1:]
    Y = np.array(dataset.iloc[:,0])
    X = X/255.                      # for normalizing the inputs
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=123, train_size = 0.8)

    #X_train = X_train.T
    #X_test = X_test.T
    print(Y_train.shape[0])
    Y_train = Y_train.reshape(Y_train.shape[0],1)
    Y_test = Y_test.reshape(-1,1)
    # Reshape
    print("number of training examples = " + str(X_train.shape[0]))
    print("number of test examples = " + str(X_test.shape[0]))
    print("X_train shape: " + str(X_train.shape))
    print("Y_train shape: " + str(Y_train.shape))
    print("X_test shape: " + str(X_test.shape))
    print("Y_test shape: " + str(Y_test.shape))
    image_x = 50
    image_y = 50

    import ipdb
    #ipdb.set_trace()
    train_y = np_utils.to_categorical(Y_train)
    test_y = np_utils.to_categorical(Y_test)
    train_y = train_y.reshape(train_y.shape[0], train_y.shape[1])
    test_y = test_y.reshape(test_y.shape[0], test_y.shape[1])
    X_train = np.array(X_train)
    X_train = X_train.reshape(X_train.shape[0], 50, 50, 1)
    X_test = np.array(X_test)
    X_test = X_test.reshape(X_test.shape[0], 50, 50, 1)
    print("X_train shape: " + str(X_train.shape))
    print("X_test shape: " + str(X_test.shape))

    model, callbacks_list = keras_model(image_x, image_y)
    model.fit(X_train, train_y, validation_data=(X_test, test_y), epochs=10, batch_size=64,
              callbacks=callbacks_list)
    scores = model.evaluate(X_test, test_y, verbose=0)
    print("CNN Error: %.2f%%" % (100 - scores[1] * 100))
    print_summary(model)

    model.save('emojinator.h5')

main()


import functools
import os
import numpy as np
import tensorflow as tf

def build_model_specification(inputs, model_fn, loss_fn, optimizer, reuse=False):
    specification = inputs

    with tf.variable_scope('model', reuse=reuse):
        logits = model_fn(specification['images'])

    loss = loss_fn(specification['labels'], logits)
    l2_loss = tf.losses.get_regularization_loss()
    loss += l2_loss

    if optimizer:
        with tf.variable_scope('optimizer'):
            with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):
                train_op = get_train_op(optimizer, loss, tf.train.create_global_step())
                specification['train_op'] = train_op

    metrics = get_metrics(specification['labels'], logits, loss)

    specification['pred'] = tf.argmax(logits, axis=1)
    specification['conf'] = tf.confusion_matrix(specification['labels'], tf.argmax(logits, axis=1))
    specification['metrics'] = metrics
    specification['summary_op'] = get_summary_op(metrics)
    specification['metrics_init_op'] = get_metrics_init_op()
    specification['update_metrics_op'] = get_update_metrics_op(metrics)

    return specification

build_eval_model_specification = functools.partial(build_model_specification, optimizer=None, reuse=True)

def get_summary_op(metrics):
    return tf.summary.merge([tf.summary.scalar(name, metric[0]) for name, metric in metrics.items()])

def get_train_op(optimizer, loss, global_step):

    return optimizer.minimize(loss, global_step)

def get_update_metrics_op(metrics):
    return tf.group(*[op for _, op in metrics.values()])

def get_metrics(labels, logits, loss):
    with tf.variable_scope("metrics"):
        return {'accuracy': tf.metrics.accuracy(labels, tf.argmax(logits, axis=1)),
                'loss': tf.metrics.mean(loss)}

def get_metrics_init_op():
    return tf.variables_initializer(tf.get_collection(tf.GraphKeys.LOCAL_VARIABLES, scope="metrics"))

def build_model(inputs):
    out = inputs

    with tf.variable_scope('fc_1'):
        out = tf.layers.dense(out, 5)

    with tf.variable_scope('fc_2'):
        out = tf.layers.dense(out, 3)

    return out

def build_inputs(features, targets, batch_size):
    dataset = tf.data.Dataset.from_tensor_slices((features, targets))
    dataset = dataset.shuffle(buffer_size=50000)
    dataset = dataset.batch(batch_size)
    dataset = dataset.prefetch(1)

    iterator = dataset.make_initializable_iterator()
    irises, labels = iterator.get_next()
    iterator_init_op = iterator.initializer

    return {'samples': irises, 'labels': labels, 'iterator_init_op': iterator_init_op}

def get_savers(best_max_to_keep, last_max_to_keep):
    with tf.variable_scope('savers'):
        last_saver = tf.train.Saver(max_to_keep=last_max_to_keep, name='last_saver')
        best_saver = tf.train.Saver(max_to_keep=best_max_to_keep, name='best_saver')

    return best_saver, last_saver

def get_summary_writers(sess, model_dir):
    train_writer = tf.summary.FileWriter(os.path.join(model_dir, 'train_summaries'), sess.graph)
    eval_writer = tf.summary.FileWriter(os.path.join(model_dir, 'eval_summaries'), sess.graph)

    return train_writer, eval_writer

def train(train_spec, eval_spec, model_dir, epochs, train_steps_per_epoch, eval_steps_per_epoch):
    global_step = tf.train.get_global_step()
    global_step_val = None
    best_eval_accuracy = 0.0
    best_saver, last_saver = get_savers(1, 5)
    begin_at_epoch = 0

    with tf.Session() as sess:
        train_writer, eval_writer = get_summary_writers(sess, model_dir)
        sess.run(tf.global_variables_initializer())

        for epoch in range(begin_at_epoch, begin_at_epoch + epochs):
            sess.run(train_spec['iterator_init_op'])
            sess.run(train_spec['metrics_init_op'])

            for step in range(train_steps_per_epoch):
                _, global_step_val, _ = sess.run([train_spec['train_op'], global_step, train_spec['update_metrics_op']])

            train_writer.add_summary(sess.run(train_spec['summary_op']), global_step_val)
            last_saver.save(sess, os.path.join(model_dir, 'last_weights', 'after-epoch'), epoch + 1)

            sess.run(eval_spec['iterator_init_op'])
            sess.run(eval_spec['metrics_init_op'])

            for _ in range(eval_steps_per_epoch):
                sess.run(eval_spec['update_metrics_op'])

            # eval_writer.add_summary(sess.run(eval_spec['summary_op']), global_step_val)

            eval_metrics = eval_spec['metrics']
            metrics_values = {k: v[0] for k, v in eval_metrics.items()}
            metrics_val = sess.run(metrics_values)

            # Add summaries manually to writer at global_step_val
            global_step_val = sess.run(global_step)
            for tag, val in metrics_val.items():
                summ = tf.Summary(value=[tf.Summary.Value(tag=tag, simple_value=val)])
                eval_writer.add_summary(summ, global_step_val)

            eval_accuracy = sess.run(eval_spec['metrics']['accuracy'][0])

            # if epoch > 0 and epoch % 10 == 0:
            print("Epoch {}, accuracy = {}".format(epoch, eval_accuracy))
            if eval_accuracy >= best_eval_accuracy:
                best_eval_accuracy = eval_accuracy
                best_saver.save(sess, os.path.join(model_dir, 'best_weights', 'after-epoch'), epoch + 1)

        matrix = np.zeros((10, 10), dtype=np.int)

        sess.run(eval_spec['iterator_init_op'])
        sess.run(eval_spec['metrics_init_op'])

        for _ in range(eval_steps_per_epoch):
            matrix += sess.run(eval_spec['conf'])

        print(matrix)
        print(np.sum(matrix))
        print(np.trace(matrix))


# -*- coding: utf-8 -*-
'''
Created on 07.12.2017

@author: yu03
'''
import visa
import numpy as np
# import time

class RigolScope():
    '''

    '''
    def __init__(self,info):
        '''
            needs the string from Ultra Sigma
        'USB0::0x1AB1::0x04B1::DS4A140800046::INSTR'
        '''
        self.rm = visa.ResourceManager()
        self.dev = self.rm.open_resource(info)
        return

#     def Read_ID(self):
#         return self.dev.query('*IDN?')

    def Read_ID(self):
        self.dev.write('*IDN?')
        self.r = self.dev.read()
        return self.r

    def Write_AUToscale(self):
        self.dev.write(':AUToscale')
        return

    def Write_Run(self):
        self.dev.write(':RUN')
        return

    def Write_Stop(self):
        self.dev.write(':STOP')
        return

    def Write_Single(self):
        self.dev.write(':SINGLE')
        return

    def Read_WavFormat(self):
        '''
            Queries the return format of the waveform data
        '''
        self.dev.write(':WAVeform:FORMat?')
#         return self.dev.query(':WAVeform:FORMat?')
        return self.dev.read()

    def Write_WavFormat_Word(self):
        '''
            Sets the return format of the waveform data to be 'WORD'
        '''
        self.dev.write(':WAVeform:FORMat WORD')
        return

    def Write_WavFormat_Byte(self):
        '''
            Sets the return format of the waveform data to be 'BYTE'
        '''
        self.dev.write(':WAVeform:FORMat BYTE')
        return

    def Write_WavFormat_Ascii(self):
        '''
            Sets the return format of the waveform data to be 'ASCII'
        '''
        self.dev.write(':WAVeform:FORMat ASCii')
#         return

    def Read_WavMode(self):
        '''
            Queries the reading mode of the waveform data
        '''
        return self.dev.query(':WAVeform:MODE?',delay=0.1)

    def Write_WavMode_Norm(self):
        '''
            Sets the reading mode of the waveform data to be 'NORMAL'
        '''
        self.dev.write(':WAVeform:MODE NORMal')
        return

    def Write_WavMode_Raw(self):
        '''
            Sets the reading mode of the waveform data to be 'RAW'
        '''
        self.dev.write(':WAVeform:MODE RAW')
        return

    def Write_WavMode_Max(self):
        '''
            Sets the reading mode of the waveform data to be 'MAXIMUM'
        '''
        self.dev.write(':WAVeform:MODE MAXimum')
        return

    def Read_WavPoints(self):
        '''
            Queries the number of the waveform points to be read
        '''
        return self.dev.query(':WAVeform:POINts?',delay=0.1)

    def Write_WavPoints(self,Setvalue):
        '''
            Sets the number of the waveform points to be read
            NORMal mode: 1 to 1400
            RAW mode: 1 to the current maximum memory depth
            MAXimum mode: 1 to the number of effective points currently on the screen
        '''
        self.dev.write(':WAVeform:POINts %i'%Setvalue)
        return

    def Read_WavSource(self):
        '''
            Queries the source channel of waveform data reading
        '''
        return self.dev.query(':WAVeform:SOURce?',delay=0.1)

    def Write_WavSource_CHAN1(self):
        '''
            Sets the source channel of waveform data reading to be 'CHANNEL 1'
        '''
        self.dev.write('WAVeform:SOURce CHANnel1')
        return

    def Write_WavSource_CHAN2(self):
        '''
            Sets the source channel of waveform data reading to be 'CHANNEL 2'
        '''
        self.dev.write('WAVeform:SOURce CHANnel2')
        return

    def Write_WavSource_CHAN3(self):
        '''
            Sets the source channel of waveform data reading to be 'CHANNEL 3'
        '''
        self.dev.write('WAVeform:SOURce CHANnel3')
        return

    def Write_WavSource_CHAN4(self):
        '''
            Sets the source channel of waveform data reading to be 'CHANNEL 4'
        '''
        self.dev.write('WAVeform:SOURce CHANnel4')
        return

    def Write_WavSource_Math(self):
        '''
            Sets the source channel of waveform data reading to be 'MATH'
        '''
        self.dev.write('WAVeform:SOURceMATH')
        return

    def Write_WavSource_FFT(self):
        '''
            Sets the source channel of waveform data reading to be 'FFT'
        '''
        self.dev.write('WAVeform:SOURce FFT')
        return

    def Read_WavData(self):
        '''
            Queries the waveform data in the buffer
        '''
        return self.dev.query(':WAVeform:DATA?',delay=0.1)

    def Read_WavPreSet(self):
        '''
            Queries the waveform parameter settings related to the waveform data reading
        '''
        return self.dev.query(':WAVeform:PREamble?',delay=0.1)

    def Get_WavData_ASC(self):
        '''
            Get Waveform Data Reading (ASCII) into self.Result[] (float)
        '''
        self.DATA = self.Read_WavData()

        self.DataLen = self.DATA.count(',')
        self.Result=list(range(self.DataLen))
        self.k = 0
        for self.i in range(self.DataLen):
            if self.DATA[self.k] == '-':
                if self.DATA[self.k+7] == '-':
                    self.Result[self.i] = float(self.DATA[self.k:self.k+11])
                    self.k = self.k+12
                    self.i += 1
#                     print self.Result[1]
                else:
                    self.Result[self.i] = float(self.DATA[self.k:self.k+10])
                    self.k = self.k+11
                    self.i += 1
            else:
                if self.DATA[self.k+6] == '-':
                    self.Result[self.i] = float(self.DATA[self.k:self.k+10])
                    self.k = self.k+11
                    self.i += 1
                else:
                    self.Result[self.i] = float(self.DATA[self.k:self.k+9])
                    self.k = self.k+10
                    self.i += 1
        self.Y_Increment = float(self.Read_Y_Increment())
        self.Y_Origin = float(self.Read_Y_Origin())
        self.Y_Ref = self.Read_Y_Reference()
        return self.Result

    def Read_Channel_1_Scale(self):
        '''
            Queries the vertical scale of the specified analog channel.
            The unit is related to the current amplitude unit of the specified analog channel.
            The default unit is V/div.
        '''
        return float(self.dev.query(':CHANnel1:SCALe?',delay=0.1))

    def Read_Y_Increment(self):
        '''
            Queries the unit voltage value of the current source channel (refer to the :WAVeform:SOURce command) in the Y direction.
            The unit (V) is the same as the current amplitude unit of the source channel.
            YINCrement=Vertical Scale/32
        '''
        return float(self.dev.query(':WAVeform:YINCrement?',delay=0.1))

    def Read_Y_Origin(self):
        '''
            Queries the vertical position relative to the vertical reference position (refer to the :WAVeform:YREFerence?command)
            of the current source channel (refer to the :WAVeform:SOURce command) in the Y direction.
        '''
        return float(self.dev.query(':WAVeform:YORigin?',delay=0.1))

    def Read_Y_Reference(self):
        '''
            Queries the vertical reference position of the current source channel (refer to the :WAVeform:SOURcecommand) in the Y direction.
        '''
        return float(self.dev.query(':WAVeform:YREFerence?',delay=0.1))

    def Read_Channel_1_Offset(self):
        '''
            Queries the vertical position of channel_1
        '''
        return float(self.dev.query(':CHANnel1:OFFSet?',delay=0.1))

    def Get_WavData_AllChannel(self):
        '''
            Get Waveform Data Reading (ASCII) for each Channel into self.Result_1-4[] (float)
        '''

        self.Write_WavSource_CHAN1()
        self.Result_Ch1 = self.Get_WavData_ASC()
        self.Y_Scale_1 = self.Read_Y_Increment()*32
        self.Y_Origin_1 = self.Read_Y_Origin()
        self.Result_test = self.Result_Ch1

        self.Write_WavSource_CHAN2()
        self.Result_Ch2 = self.Get_WavData_ASC()
        self.Y_Scale_2 = self.Read_Y_Increment()*32
        self.Y_Origin_2 = self.Read_Y_Origin()

        self.Write_WavSource_CHAN3()
        self.Result_Ch3 = self.Get_WavData_ASC()
        self.Y_Scale_3 = self.Read_Y_Increment()*32
        self.Y_Origin_3 = self.Read_Y_Origin()

#         self.Write_WavSource_CHAN4()
#         self.Result_Ch4 = self.Get_WavData_ASC()
#         self.Y_Scale_4 = self.Read_Y_Increment()*32
#         self.Y_Origin_4 = self.Read_Y_Origin()

# #         self.Result_Ch1 = [(x+self.Y_Scale_2*(self.Y_Origin_2/self.Y_Scale_2-self.Y_Origin_1/self.Y_Scale_1))  for x in self.Result_Ch1]
#         self.Result_Ch1 = [(x)  for x in self.Result_Ch1]
#         self.Result_Ch2 = [(x)  for x in self.Result_Ch2]
#         self.Result_Ch3 = [(x+self.Y_Scale_4*(self.Y_Origin_4/self.Y_Scale_4-self.Y_Origin_3/self.Y_Scale_3))  for x in self.Result_Ch3]
#         self.Result_Ch4 = [(x+self.Y_Scale_1*(self.Y_Origin_1/self.Y_Scale_1-self.Y_Origin_4/self.Y_Scale_4))  for x in self.Result_Ch4]

        return self.Result_Ch1, self.Result_Ch2, self.Result_Ch3

    def Read_X_Increment(self):
        '''
            Queries the time difference (the default unit is s) between two neighboring points
            of the current source channel in the X direction
            XINCrement = TimeScale/100
            !!!Wrong Return!!!
        '''
        return float(self.dev.query(':WAVeform:XINCrement?',delay=0.1))

    def Read_Sample_Rate(self):
        '''
            Queries the current sample rate of the oscilloscope. The default unit is Sa/s.
        '''
        return float(self.dev.query(':ACQuire:SRATe?',delay=0.1))

    def Read_Memory_Depth(self):
        '''
            Queries the current sample rate of the oscilloscope. The default unit is Sa/s.
        '''
        return int(self.dev.query(':ACQuire:MDEPth?',delay=0.1))

    def Write_WavReading_Reset(self):
        '''
            Resets the waveform data reading.
            This command is only applicable to reading waveform data in the internal memory
        '''
        self.dev.write(':WAVeform:RESet')
        return

    def Write_WavReading_Begin(self):
        '''
            Starts the waveform data reading.
            This command is only applicable to reading waveform data in the internal memory
        '''
        self.dev.write(':WAVeform:BEGin')
        return

    def Read_WavReading_Status(self):
        '''
            Queries the current status of waveform data reading.
            IDLE,<n>: indicates that the waveform data reading thread finishes; <n> is the number of waveform points that have been read.
            READ,<n>: indicates that the waveform data reading thread is running; <n> is the number of waveform points that have currently been read
        '''
        return self.dev.query(':WAVeform:STATus?',delay=0.1)

    def Write_WavReading_End(self):
        '''
            Stops the waveform data reading.
            This command is only applicable to reading waveform data in the internal memory
        '''
        self.dev.write(':WAVeform:END')
        return

    def Get_Buffer_Ch1(self):
        '''
            Queries waveform data (and points number) of Channel 1 from the internal memory
        '''
        self.Write_Stop()

        self.Scale_1 = float(self.dev.query(':CHANnel1:SCALe?'))
#         print self.Scale_1
        self.Offset_1 = float(self.dev.query(':CHANnel1:OFFSet?'))
        self.Scale_2 = float(self.dev.query(':CHANnel2:SCALe?'))
        self.Offset_2 = float(self.dev.query(':CHANnel2:OFFSet?'))
        self.dev.write(':CHANnel1:SCALe %f'%self.Scale_1)

        self.Write_WavSource_CHAN1()
        self.Write_WavMode_Raw()
        self.MemDep = self.Read_Memory_Depth()
        self.Write_WavPoints(self.MemDep)
#         self.Write_WavPoints(100)
        self.Write_WavReading_Reset()
        self.Write_WavReading_Begin()
        self.BufData_Ch1 = list()
        self.BufLen_Ch1 = 0
        self.count = 0

        status,remain_cnt = self.Read_WavReading_Status().split(',')

#         while status[0:4]!='READ':
        while remain_cnt[0] == '0':
            status,remain_cnt = self.Read_WavReading_Status().split(',')
        print ('CHANNEL_1 start reading')
        while status[0:4] == 'READ':
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch1 = self.BufData_Ch1 + tmp
            self.count += 1
            print (self.count)
            status,remain_cnt = self.Read_WavReading_Status().split(',')

        if (int(remain_cnt)>0):
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch1 = self.BufData_Ch1 + tmp
            self.count += 1
            print (self.count)

        if status!='IDLE':
            print ('Unexpected status %s'%status)

        self.Write_WavReading_End()
        self.BufData_Ch1_RealV = [(x + self.Offset_2)/self.Scale_2*self.Scale_1 - self.Offset_1 for x in self.BufData_Ch1] #####Function from test, differ from expected
        print ('finish reading')
        print ('Data Size:', len(self.BufData_Ch1))
        return self.BufData_Ch1_RealV

    def Get_Buffer_Ch2(self):
        '''
            Queries waveform data (and points number) of Channel 2 from the internal memory
        '''
        self.Write_Stop()

        self.Scale_2 = float(self.dev.query(':CHANnel2:SCALe?'))
        self.Offset_2 = float(self.dev.query(':CHANnel2:OFFSet?'))
        self.Scale_3 = float(self.dev.query(':CHANnel3:SCALe?'))
        self.Offset_3 = float(self.dev.query(':CHANnel3:OFFSet?'))
        self.dev.write(':CHANnel2:SCALe %f'%self.Scale_2)

        self.Write_WavSource_CHAN2()
        self.Write_WavMode_Raw()
        self.MemDep = self.Read_Memory_Depth()
        self.Write_WavPoints(self.MemDep)
#         self.Write_WavPoints(100)
        self.Write_WavReading_Reset()
        self.Write_WavReading_Begin()

        self.BufData_Ch2 = list()
        self.BufLen_Ch2 = 0
        self.count = 0

        status,remain_cnt = self.Read_WavReading_Status().split(',')

#         while status[0:4]!='READ':
        while remain_cnt[0] == '0':
            status,remain_cnt = self.Read_WavReading_Status().split(',')

        print ('CHANNEL_2 start reading')

        while status[0:4] == 'READ':
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch2 = self.BufData_Ch2 + tmp
            self.count += 1
            print (self.count)
            status,remain_cnt = self.Read_WavReading_Status().split(',')

        if (int(remain_cnt)>0):
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch2 = self.BufData_Ch2 + tmp
            self.count += 1
            print (self.count)

        if status!='IDLE':
            print ('Unexpected status %s'%status)

        self.Write_WavReading_End()
        self.BufData_Ch2_RealV = [(x + self.Offset_3)/self.Scale_3*self.Scale_2 - self.Offset_2 for x in self.BufData_Ch2] #####Function from test, differ from expected
        print ('finish reading')
        print ('Data Size:', len(self.BufData_Ch2))
        return self.BufData_Ch2_RealV

#     def Get_Buffer_Ch2(self):
#         '''
#             Queries waveform data (and points number) of Channel 2 from the internal memory
#         '''
#         self.Write_Stop()
#         self.Write_WavSource_CHAN2()
#         self.Write_WavMode_Raw()
#         self.MemDep = self.Read_Memory_Depth()
#         self.Write_WavPoints(self.MemDep)
# #         self.Write_WavPoints(100)
#         self.Write_WavReading_Reset()
#         self.Write_WavReading_Begin()
#         time.sleep(2)
#         self.BufData_Ch2 = list()
#         self.BufLen_Ch2 = 0
#         self.count = 0
#         while self.Read_WavReading_Status()[0:4] == 'READ':
# #             time.sleep(0.1)
#             self.BufData_Ch2 = self.BufData_Ch2 + self.Get_WavData_ASC()
#             self.BufLen_Ch2 = self.BufLen_Ch2 + self.DataLen
#             self.count += 1
# #             time.sleep(1)
#             print self.count
#         else:
# #             time.sleep(0.1)
#             self.BufData_Ch2 = self.BufData_Ch2 + self.Get_WavData_ASC()
#             self.BufLen_Ch2 = self.BufLen_Ch2 + self.DataLen
#             self.count += 1
#             print self.count
#         print self.Read_WavReading_Status()
#         self.Write_WavReading_End()
#         return self.BufData_Ch2, self.BufLen_Ch2

    def Get_Buffer_Ch3(self):
        '''
            Queries waveform data (and points number) of Channel 3 from the internal memory
        '''
        self.Write_Stop()

        self.Scale_3 = float(self.dev.query(':CHANnel3:SCALe?'))
        self.Offset_3 = float(self.dev.query(':CHANnel3:OFFSet?'))
        self.Scale_4 = float(self.dev.query(':CHANnel4:SCALe?'))
        self.Offset_4 = float(self.dev.query(':CHANnel4:OFFSet?'))
        self.dev.write(':CHANnel3:SCALe %f'%self.Scale_3)

        self.Write_WavSource_CHAN3()
        self.Write_WavMode_Raw()
        self.MemDep = self.Read_Memory_Depth()
        self.Write_WavPoints(self.MemDep)
#         self.Write_WavPoints(100)
        self.Write_WavReading_Reset()
        self.Write_WavReading_Begin()
#         time.sleep(2)
        self.BufData_Ch3 = list()
        self.BufLen_Ch3 = 0
        self.count = 0

        status,remain_cnt = self.Read_WavReading_Status().split(',')

#         while status[0:4]!='READ':
        while remain_cnt[0] == '0':
            status,remain_cnt = self.Read_WavReading_Status().split(',')
        print ('CHANNEL_3 start reading')
        while status[0:4] == 'READ':
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch3 = self.BufData_Ch3 + tmp
            self.count += 1
            print (self.count)
            status,remain_cnt = self.Read_WavReading_Status().split(',')

        if (int(remain_cnt)>0):
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch3 = self.BufData_Ch3 + tmp
            self.count += 1
            print (self.count)

        if status!='IDLE':
            print ('Unexpected status %s'%status)

        self.Write_WavReading_End()
        self.BufData_Ch3_RealV = [((x+self.Offset_4)/self.Scale_4)*self.Scale_3-self.Offset_3 for x in self.BufData_Ch3]#####Function from test, differ from expected
        print ('finish reading')
        print ('Data Size:', len(self.BufData_Ch3))
        return self.BufData_Ch3_RealV

    def Get_Buffer_Ch4(self):
        '''
            Queries waveform data (and points number) of Channel 4 from the internal memory
        '''
        self.Write_Stop()

        self.Scale_4 = float(self.dev.query(':CHANnel4:SCALe?'))
        self.Offset_4 = float(self.dev.query(':CHANnel4:OFFSet?'))
        self.Scale_1 = float(self.dev.query(':CHANnel1:SCALe?'))
        self.Offset_1 = float(self.dev.query(':CHANnel1:OFFSet?'))
        self.dev.write(':CHANnel4:SCALe %f'%self.Scale_4)

        self.Write_WavSource_CHAN4()
        self.Write_WavMode_Raw()
        self.MemDep = self.Read_Memory_Depth()
        self.Write_WavPoints(self.MemDep)
#         self.Write_WavPoints(100)
        self.Write_WavReading_Reset()
        self.Write_WavReading_Begin()
#         time.sleep(2)
        self.BufData_Ch4 = list()
        self.BufLen_Ch4 = 0
        self.count = 0

        status,remain_cnt = self.Read_WavReading_Status().split(',')

#         while status[0:4]!='READ':
        while remain_cnt[0] == '0':
            status,remain_cnt = self.Read_WavReading_Status().split(',')
        print ('CHANNEL_4 start reading')
        while status[0:4] == 'READ':
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch4 = self.BufData_Ch4 + tmp
            self.count += 1
            print (self.count)
            status,remain_cnt = self.Read_WavReading_Status().split(',')

        if (int(remain_cnt)>0):
            tmp = [float(i) for i in self.Read_WavData().strip().split(',')[:-1]]
            self.BufData_Ch4 = self.BufData_Ch4 + tmp
            self.count += 1
            print (self.count)

        if status!='IDLE':
            print ('Unexpected status %s'%status)

        self.Write_WavReading_End()
        self.BufData_Ch4_RealV = [((x+self.Offset_1)/self.Scale_1)*self.Scale_4-self.Offset_4 for x in self.BufData_Ch4]#####Function from test, differ from expected
        print ('finish reading')
        print ('Data Size:', len(self.BufData_Ch4))
        return self.BufData_Ch4_RealV

    def Read(self):
        '''
            scope.Read_Ch1, scope.Read_Ch2, scope.Read_Ch3, scope.Read_Ch4
        '''
        print(self.Read_ID())
        self.Write_WavFormat_Ascii()
        print('Start Reading')
        self.Read_Ch1 = np.array(self.Get_Buffer_Ch1())
        self.Read_Ch2 = np.array(self.Get_Buffer_Ch2())
#         self.Read_Ch3 = np.array(self.Get_Buffer_Ch3())
#         self.Read_Ch4 = np.array(self.Get_Buffer_Ch4())
        self.Memory_Depth = self.Read_Memory_Depth()
        self.Sample_Rate = self.Read_Sample_Rate()
        print('Finish Reading')
        return self.Read_Ch1, self.Read_Ch2, self.Memory_Depth, self.Sample_Rate
#         return self.Read_Ch1, self.Read_Ch2, self.Read_Ch3, self.Read_Ch4, self.Memory_Depth, self.Sample_Rate


"""
Valid Parenthesis String
https://leetcode.com/problems/valid-parenthesis-string/

Time O(n)
Space O(1)
"""
class Solution:
    def checkValidString(self, s: str) -> bool:
        balance = self.calcBalance(s, ")")
        if balance < 0:
            return False
        if balance == 0:
            return True
        return self.calcBalance(reversed(s), "(") >= 0

    def calcBalance(self, s, bracket) -> int:
        balance = 0
        for ch in s:
            if ch == bracket:
                balance -= 1
            else:
                balance += 1
            if balance < 0:
                return balance
        return balance


from datetime import datetime
from flask import render_template, flash, redirect, url_for, request
from werkzeug.urls import url_parse
from app import app, db
from flask_login import current_user, login_user, logout_user, login_required
from app.forms import LoginForm, RegistrationForm, EventForm, EventDetailsForm, DatePickerExample
from app.models import User, Event
from app.google_calendar import create_event

@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@login_required
def index():
    form = EventForm()
    print(form.errors)

    if form.is_submitted():
        print('form submitted')

    if form.validate():
        print('valid')

    print(form.errors)

    if form.validate_on_submit():
        event = Event(event_name=form.event_name.data, promoter_name=form.promoter_name.data,
                      event_date=form.event_date.data, event_type=form.event_type.data,
                      event_manager=form.event_manager.data, deposit_amount=form.deposit_amount.data,
                      guest_count=form.guest_count.data, bar_min=form.bar_min.data,
                      other_notes=form.other_notes.data, booked=form.booked.data,
                      tsl_approved=form.tsl_approved.data, balance_paid=form.balance_paid.data,
                      contract_sent=form.contract_sent.data, cleaning=form.cleaning.data,
                      deposit_paid=form.deposit_paid.data, bar=form.bar.data)

        db.session.add(event)
        db.session.commit()
        # function for writing to google calendar.
        # add script to project and import here
        event_date = str(event.event_date)
        event_name = event.event_name

        create_event(event_date, event_name)

        flash('Your event has been added!')
        return redirect(url_for('index'))
    return render_template('index.html', title='Home', form=form, events=events)

@app.route('/calendar')
def calendar():
    return render_template('datepicker.html')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user is None or not user.check_password(form.password.data):
            flash('Invalid username or password')
            return redirect(url_for('/login'))
        login_user(user, remember=form.remember_me.data)
        next_page = request.args.get('next')
        if not next_page or url_parse(next_page).netloc != '':
            next_page = url_for('index')
        return redirect(next_page)
    return render_template('login.html', title='Sign In', form=form)

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('login'))

@app.route('/events', methods=['GET'])
def events():
    form = EventForm()
    events = Event.query.all()
    return render_template('events.html', form=form, events=events)
    # events.get sqlalchemy syntax

@app.route('/delete_event', methods=['GET', 'POST'])
@login_required
def delete_event():
    args = request.args
    print(args)

    id = args['id']
    print(id)

    event_data = Event.query.get(id)
    db.session.delete(event_data)
    db.session.commit()
    flash('Your event has been deleted.')
    return redirect(url_for('events'))

# This is the endpoint with the unresponsive modal
@app.route('/event_details', methods=['GET', 'POST'])
@login_required
def event_details():
    args = request.args
    print(args)

    id = args['id']
    print(id)

    form = EventDetailsForm()
    print("errors: ")
    print(form.errors)

    if form.validate_on_submit():
        print('second')
        event_data = Event.query.get(id)
        event_data.event_name = form.event_name.data
        event_data.promoter_name = form.promoter_name.data
        event_data.event_date = form.event_date.data
        event_data.event_type = form.event_type.data
        event_data.event_manager = form.event_manager.data
        event_data.deposit_amount = form.deposit_amount.data
        event_data.guest_count = form.guest_count.data
        event_data.bar_min = form.bar_min.data
        event_data.other_notes = form.other_notes.data
        event_data.booked = form.booked.data
        event_data.tsl_approved = form.tsl_approved.data
        event_data.balance_paid = form.balance_paid.data
        event_data.contract_sent = form.contract_sent.data
        event_data.cleaning = form.cleaning.data
        event_data.deposit_paid = form.deposit_paid.data
        event_data.bar = form.bar.data
        db.session.commit()
        flash('Your changes have been saved.')
        return redirect(url_for('events'))

    elif request.method == 'GET':
        print('first')
        event_data = Event.query.get(id)
        form.event_name.data = event_data.event_name
        form.promoter_name.data = event_data.promoter_name
        form.event_date.data = event_data.event_date
        form.event_type.data = event_data.event_type
        form.event_manager.data = event_data.event_manager
        form.deposit_amount.data = event_data.deposit_amount
        form.guest_count.data = event_data.guest_count
        form.bar_min.data = event_data.bar_min
        form.other_notes.data = event_data.other_notes
        form.booked.data = event_data.booked
        form.tsl_approved.data = event_data.tsl_approved
        form.balance_paid.data = event_data.balance_paid
        form.contract_sent.data = event_data.contract_sent
        form.cleaning.data = event_data.cleaning
        form.deposit_paid.data = event_data.deposit_paid
        form.bar.data = event_data.bar
        form.id.data = event_data.id

    return render_template('event_details.html', title='Event Details',
                           form=form)

@app.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('index'))
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Congratulations, you are now a registered user!')
        return redirect(url_for('login'))
    return render_template('register.html', title='Register', form=form)


from bs4 import BeautifulSoup
from lxml import etree
import urllib
import urllib.request as rqt
import urllib.parse as pr
from datetime import datetime
from writeLog import myPrint
import time
import random

def getStock(pg,_insSISQL,_delSQL,_insSQL): #查詢股票資訊
    quote_exp = ['0000','000-']
    _dataDate=[]
    _today=[]
    _today.append((datetime.now().strftime("%Y-%m-%d")))

    try:
        #可能為指數類的...
        if pg in quote_exp:
            K5= K10= K20= K60= K120= K240= BLup= BLdown= _price =0
            _open=_high=_low=PBRv = PERv= PBRHigh= PBRLow=None
            with rqt.urlopen('https://www.wantgoo.com/global/stockindex?StockNo=' + pg) as url:
                page = url.read()
            soup = BeautifulSoup(page, 'lxml') #'html.parser')
            name_box = soup.find('h3', attrs={'class': 'idx-name'})
            price_box = soup.find('span', attrs={'class':'price'})
            _price = float(price_box.text)
            op_box = soup.find('ul', attrs={'class':'idx-data-pri'})
            for o in op_box:
                if '開盤' in o:
                    _open = float(o.contents[1].text)
                if '最高' in o:
                    _high = float(o.contents[1].text)
                if '最低' in o:
                    _low = float(o.contents[1].text)

            dt_box=soup.find('time', attrs={'class': 'i redate'})
            try:
                _dataDate.append((datetime.strptime(dt_box.text.strip(), '%Y/%m/%d %H:%M:%S').strftime("%Y-%m-%d")))
            except ValueError:
                _dataDate.append((datetime.strptime(dt_box.text.strip() + ':00', '%Y/%m/%d %H:%M:%S').strftime("%Y-%m-%d")))
            _desc=PBRs=_biz=''
            Vol=0

            li_vol = soup.find_all('li')
            try:
                for s in li_vol:
                    if '成交量' in s.contents[0]:
                        Vol = int(s.contents[1].text.strip().replace('成交量','')) * 100000  #該網站值為0.1M
                        break
            except:
                myPrint('*****get 成交量 err '+pg)
        else:
            K5= K10= K20= K60= K120= K240= BLup= BLdown =0
            with rqt.urlopen('https://www.wantgoo.com/stock/' + pg) as url:
                page = url.read()
            soup = BeautifulSoup(page, 'lxml') #'html.parser')
            name_box = soup.find('h3', attrs={'class': 'idx-name'})

            #取得goodinfo PBR
            time.sleep(random.randint(9,18))   #避免太密集被goodinfo封鎖
            gurl = 'https://goodinfo.tw/StockInfo/StockDetail.asp?STOCK_ID=' + pg
            user_agent = 'Mozilla/5.0 (Windows NT 6.2; Win64; x64)'
            values = {'name': 's'}
            headers = {'User-Agent': user_agent}
            data = pr.urlencode(values).encode('utf-8')
            req = rqt.Request(gurl, data, headers)
            with rqt.urlopen(req) as response:
                the_page = response.read().decode('utf-8')
                so = BeautifulSoup(the_page, 'lxml')
                _desc=PBRs=_biz=''
                PBRHigh= PBRLow= _price= PERv= PBRv= _open=_high=_low= 0
                _td = so.find_all('td')
                try:
                    for s in _td:
                        if '地址' in s:
                            _desc=s.parent.nextSibling.nextSibling.nextSibling.nextSibling.text
                            break
                except:
                    myPrint('get _desc err '+pg)

                td_Pbr = so.find_all('nobr')
                try:
                    for s in td_Pbr:
                        if '昨日張數' in s.contents[0]:
                            tdn=s.parent.parent.previousSibling.previousSibling
                            Vol = int(tdn.contents[1].text.strip().replace(',', ''))
                            PERv= float(tdn.contents[10].text.strip().replace('N/A', '0'))
                            PBRv = float(tdn.contents[12].text.strip().replace('N/A', '0'))
                            tdv=tdn.previousSibling.previousSibling.previousSibling.previousSibling
                            _price = float(tdv.contents[1].text.strip().replace(',', ''))
                            _open = float(tdv.contents[9].text.strip().replace(',', ''))
                            _high = float(tdv.contents[11].text.strip().replace(',', ''))
                            _low = float(tdv.contents[13].text.strip().replace(',', ''))
                        if '產業別' in s.contents[0]:
                            _biz=s.parent.parent.contents[3].text
                except:
                    myPrint('*****get 昨日張數 產業別 err '+pg)

                try:
                    for s in td_Pbr:
                        if '資料日期:' in s.contents[0]:
                            _dataDate.append((datetime.strptime(str(datetime.today().year) + '/' + s.contents[0].replace('資料日期:','').strip(), '%Y/%m/%d').strftime("%Y-%m-%d")))
                            break
                except:
                    myPrint('*****get 資料日期 err '+pg)
                    _dataDate.append((datetime.today().strftime("%Y-%m-%d")))

                try:
                    if pg.startswith('00', 0):
                        pass
                    elif _today[0]>_dataDate[0] or datetime.now().strftime("%H:%M:%S")>='15:30:00':
                        try:
                            for s in td_Pbr:
                                if 'PBR' in s.contents[0]:
                                    PBRs = s.attrs['title'].strip().replace('PBR','').replace('歷年','').replace('平均值','均值').replace('平均','')
                                    PBRHigh=float(PBRs[PBRs.find('(最高:')+4:PBRs.find('倍')])
                                    PBRLow=float(PBRs[PBRs.find('最低:')+3:PBRs.find('倍)')])
                                    break
                        except:
                            myPrint('** PBR err '+ pg)
                    else:
                        Vol= PBRv= PERv= _price=0
                        _biz=''
                except Exception as e:
                    myPrint('******** failed : '+ str(e))

        if _price == 0 or _open == 0 or _low == 0 or _high == 0:
            myPrint('!!!!!!!!!!!!!!! price == 0 !!!')
        sname = name_box.contents[0].strip()
        _insSISQL.append((pg,sname,_biz,_desc))
        _delSQL.append((_dataDate[0],pg))
        if _today[0]==_dataDate[0]:
            _insSQL.append((_dataDate[0],datetime.now().strftime("%H:%M:%S"),pg,_price,PBRv,PBRs,PERv,Vol,PBRLow,PBRHigh,K5, K10, K20, K60, K120, K240,BLup, BLdown,_open,_high,_low))
        else:
            _insSQL.append((_dataDate[0],'23:59:59',pg,_price,PBRv,PBRs,PERv,Vol,PBRLow,PBRHigh,K5, K10, K20, K60, K120, K240,BLup, BLdown,_open,_high,_low))

    except urllib.error.URLError as e:
        myPrint('*****(error)'+pg+'=>' + str(e.reason))
    except IndexError:
        myPrint('*****(error)=>' +'('+ pg + ') '+ str(IndexError))
    except ValueError:
        myPrint('*****(error)=>' +'('+ pg + ') '+ str(ValueError))
    except AttributeError:
        myPrint('*****(error)=>' +'('+ pg + ') '+ str(AttributeError))
        time.sleep(15*60)   #避免太密集被goodinfo封鎖


# stdlib imports
import os.path
import glob
import json
from collections import OrderedDict
import shutil
import logging
import argparse
import inspect

# third party imports
from shapely.geometry import MultiLineString
from shapely.geometry import mapping
import fiona
import numpy as np
from skimage import measure
from scipy.ndimage.filters import median_filter
from shakelib.utils.containers import ShakeMapOutputContainer
from shakelib.utils.imt_string import oq_to_file

# local imports
from .base import CoreModule
from shakemap.utils.config import get_config_paths, get_logging_config
from impactutils.colors.cpalette import ColorPalette

FORMATS = {
    'geojson': ('GeoJSON', 'json')
}

DEFAULT_FILTER_SIZE = 10

class ContourModule(CoreModule):
    """
    contour -- Generate contours of all IMT values from the
                     shake_result.hdf output file.
    """

    command_name = 'contour'

    # supply here a data structure with information about files that
    # can be created by this module.
    contour_page = {'title': 'Ground Motion Contours', 'slug': 'contours'}
    contents = OrderedDict.fromkeys(['miContour', 'pgaContour', 'pgvContour',
                                     'psa[PERIOD]Contour'])
    contents['miContour'] = {'title': 'Intensity Contours',
                             'caption': 'Contours of macroseismic intensity.',
                             'page': contour_page,
                             'formats': [{'filename': 'cont_*MMI.json',
                                         'type': 'application/json'}
                                        ]
    }
    contents['pgaContour'] = {'title': 'PGA Contours',
                              'caption': 'Contours of [COMPONENT] peak '\
                                         'ground acceleration (%g).',
                              'page': contour_page,
                              'formats': [{'filename': 'cont_*PGA.json',
                                          'type': 'application/json'}
                                         ]
    }
    contents['pgvContour'] = {'title': 'PGV Contours',
                              'caption': 'Contours of [COMPONENT] peak '\
                                         'ground velocity (cm/s).',
                              'page': contour_page,
                              'formats': [{'filename': 'cont_*PGV.json',
                                          'type': 'application/json'}
                                         ]
    }
    psacap = 'Contours of [COMPONENT] [FPERIOD] sec 5% damped '\
             'pseudo-spectral acceleration(%g).'
    contents['psa[PERIOD]Contour'] = {
            'title': 'PSA[PERIOD] Contour',
            'page': contour_page,
            'caption': psacap,
            'formats': [{'filename':'cont_*PSA[0-9]p[0-9].json',
                         'type':'application/json'}
                       ]
    }

    def __init__(self, eventid, filter=None):
        """
        Instantiate a ContourModule class with an event ID.
        """
        self._eventid = eventid
        log_config = get_logging_config()
        log_name = log_config['loggers'].keys()[0]
        self.logger = logging.getLogger(log_name)
        if filter is not None:
            self.filter_size = filter
        else:
            self.filter_size = DEFAULT_FILTER_SIZE

    def execute(self):
        """
        Create contour files for all configured IMT values.

        Raises:
            NotADirectoryError: When the event data directory does not exist.
            FileNotFoundError: When the the shake_result HDF file does not
                exist.
        """
        install_path, data_path = get_config_paths()
        datadir = os.path.join(data_path, self._eventid, 'current', 'products')
        if not os.path.isdir(datadir):
            raise NotADirectoryError('%s is not a valid directory.' % datadir)
        datafile = os.path.join(datadir, 'shake_result.hdf')
        if not os.path.isfile(datafile):
            raise FileNotFoundError('%s does not exist.' % datafile)

        # Open the ShakeMapOutputContainer and extract the data
        container = ShakeMapOutputContainer.load(datafile)

        if container.getDataType() != 'grid':
            raise NotImplementedError('contour module can only contour '
                                      'gridded data, not sets of points')

        # create contour files
        self.logger.debug('Contouring to files...')
        contour_to_files(container, datadir, self.logger, self.filter_size)

    def parseArgs(self, arglist):
        """
        Set up the object to accept the --filter flag.
        """
        parser = argparse.ArgumentParser(prog=self.__class__.command_name,
                    description=inspect.getdoc(self.__class__))
        parser.add_argument('-f', '--filter', help='Specify the filter '
                            'size (in grid points) for smoothing the '
                            'grids before contouring. Must be a positive'
                            'integer (default=10; use 0 to disable '
                            'filtering).', type=int)
        #
        # This line should be in any modules that overrides this
        # one. It will collect up everything after the current
        # modules options in args.rem, which should be returned
        # by this function. Note: doing parser.parse_known_args()
        # will not work as it will suck up any later modules'
        # options that are the same as this one's.
        #
        parser.add_argument('rem', nargs=argparse.REMAINDER,
                            help=argparse.SUPPRESS)
        args = parser.parse_args(arglist)
        if args.filter is None:
            self.filter_size = DEFAULT_FILTER_SIZE
        else:
            self.filter_size = args.filter
        return args.rem

def contour(container, imtype, component, filter_size):
    """
    Generate contours of a specific IMT and return as a Shapely
    MultiLineString object.

    Args:
        container (ShakeMapOutputContainer): ShakeMapOutputContainer
            with ShakeMap output data.
        imtype (str): String containing the name of an Intensity
            Measure Type found in container.
        component (str): Intensity Measure component found in container.
        filter_size (int): Integer filter (see
            https://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.ndimage.filters.median_filter.html)
    Returns:
        list: List of dictionaries containing two fields

                - geometry: GeoJSON-like representation of one of the objects
                  in https://toblerity.org/fiona/manual.html#geometry-types
                - properties: Dictionary of properties describing that
                  feature.

    Raises:
        NotImplementedError -- if the user attempts to contour a data file
            with sets of points rather than grids.
    """  # noqa
    intensity_colormap = ColorPalette.fromPreset('mmi')
    imtdict = container.getIMTGrids(imtype, component)
    gridobj = imtdict['mean']
    grid = gridobj.getData()
    metadata = gridobj.getGeoDict().asDict()
    if imtype == 'MMI':
        sgrid = grid
        units = 'mmi'
    elif imtype == 'PGV':
        sgrid = np.exp(grid)
        units = 'cms'
    else:
        sgrid = np.exp(grid) * 100.0
        units = 'pctg'
    if filter_size > 0:
        fgrid = median_filter(sgrid, size=filter_size)
    else:
        fgrid = sgrid

    interval_type = 'log'
    if imtype == 'MMI':
        interval_type = 'linear'
    intervals = getContourLevels(
        np.min(fgrid), np.max(fgrid), itype=interval_type)

    lonstart = metadata['xmin']
    latstart = metadata['ymin']
    lonspan = np.abs(metadata['xmax'] - lonstart)
    latspan = np.abs(metadata['ymax'] - latstart)
    nlon = metadata['nx']
    nlat = metadata['ny']

    line_strings = []  # dictionary of MultiLineStrings and props

    for cval in intervals:
        contours = measure.find_contours(fgrid, cval)
        #
        # Convert coords to geographic coordinates; the coordinates
        # are returned in row, column order (i.e., (y, x))
        #
        new_contours = []
        plot_contours = []
        for ic, coords in enumerate(contours):  # coords is a line segment
            if len(coords) <= 20:  # skipping little contour islands?
                continue

            mylons = coords[:, 1] * lonspan / nlon + lonstart
            mylats = (nlat - coords[:, 0]) * latspan / nlat + latstart
            contours[ic][:, 0] = mylons[:]
            contours[ic][:, 1] = mylats[:]
            plot_contours.append(contours[ic])
            new_contours.append(contours[ic].tolist())

        if len(new_contours):
            mls = MultiLineString(new_contours)
            props = {
                'value': cval,
                'units': units
            }
            if imtype == 'MMI':
                color_array = np.array(intensity_colormap.getDataColor(cval))
                color_rgb = np.array(
                    color_array[0:3] * 255, dtype=int).tolist()
                props['color'] = '#%02x%02x%02x' % tuple(color_rgb)
                if (cval * 2) % 2 == 1:
                    props['weight'] = 4
                else:
                    props['weight'] = 2
            line_strings.append(
                {
                    'geometry': mapping(mls),
                    'properties': props
                }
            )
    return line_strings

def contour_to_files(container, output_dir, logger,
                     filter_size=DEFAULT_FILTER_SIZE):
    """
    Generate contours of all IMT values.

    Args:
      container (ShakeMapOutputContainer): ShakeMapOutputContainer with
          ShakeMap output data.
      output_dir (str): Path to directory where output files will be written.
      logger (logging.Logger): Python logging Logger instance.

    Raises:
        LookupError: When configured file format is not supported
    """

    imtlist = container.getIMTs()

    # Right now geojson is all we support; if that changes, we'll have
    # to add a configuration or command-line option
    file_format = 'geojson'
    # open a file for writing
    driver, extension = FORMATS[file_format]
    sa_schema = {
        'geometry': 'MultiLineString',
        'properties': {
            'value': 'float',
            'units': 'str'
        }
    }
    mmi_schema = {
        'geometry': 'MultiLineString',
        'properties': {
            'value': 'float',
            'units': 'str',
            'color': 'str',
            'weight': 'int'
        }
    }
    crs = {
        'no_defs': True,
        'ellps': 'WGS84',
        'datum': 'WGS84',
        'proj': 'longlat'
    }

    for imtype in imtlist:
        fileimt = oq_to_file(imtype)
        component = container.getComponents(imtype)[0]
        if component == 'GREATER_OF_TWO_HORIZONTAL':
            fname = 'cont_%s.%s' % (fileimt, extension)
        else:
            fname = 'cont_%s_%s.%s' % (fileimt, component, extension)
        filename = os.path.join(output_dir, fname)
        if os.path.isfile(filename):
            fpath, fext = os.path.splitext(filename)
            flist = glob.glob(fpath + '.*')
            for fname in flist:
                os.remove(fname)

        # fiona spews a warning here when driver is geojson
        # this warning appears to be un-catchable using
        # with warnings.catch_warnings()
        # or
        # logging.captureWarning()
        # or
        # even redirecting stderr/stdout to IO streams
        # not sure where the warning is coming from,
        # but there appears to be no way to stop it...
        with fiona.drivers():
            if imtype == 'MMI':
                selected_schema = mmi_schema
            else:
                selected_schema = sa_schema
            vector_file = fiona.open(
                filename, 'w',
                driver=driver,
                schema=selected_schema,
                crs=crs
            )

            line_strings = contour(
                container,
                imtype,
                component,
                filter_size
            )

            for feature in line_strings:
                vector_file.write(feature)

                # Grab some metadata
            meta = container.getMetadata()
            event_info = meta['input']['event_information']
            mdict = {
                'eventid': event_info['event_id'],
                'longitude': float(event_info['longitude']),
                'latitude': float(event_info['latitude'])
            }

            logger.debug('Writing contour file %s' % filename)
            vector_file.close()

            # Get bounds
            tmp = fiona.open(filename)
            bounds = tmp.bounds
            tmp.close()

            # Read back in to add metadata/bounds
            data = json.load(open(filename))
            data['metadata'] = mdict
            data['bbox'] = bounds
            with open(filename, 'w') as outfile:
                json.dump(data, outfile)

            #####################################
            # Make an extra version of the MMI contour file
            # so that the current web rendering code can find it.
            # Delete this file once everyone has moved to new version
            # of ComCat code.

            if imtype == 'MMI':
                old_file = os.path.join(output_dir, 'cont_mi.json')
                shutil.copy(filename, old_file)
            #####################################

def getContourLevels(dmin, dmax, itype='log'):
    """
    Get contour levels given min/max values and desired IMT.

    Use itype='log' for any IMT that is logarithmically distributed, such as
    PGA, PGV, and Sa. Linear for MMI.

    Args:
        dmin (float): Minimum value of data to contour.
        dmax (float): Maximum value of data to contour.
        itype (str): Interval type; default is 'log', anythign else
            indicates linear intervals.

    Returns:
        ndarray: Numpy array of contour levels.

    """
    if itype == 'log':
        # Within-decade label values
        dec_inc = np.array([1, 2, 5], dtype=float)

        # Upper and lower decades
        lower_dec = np.floor(np.log10(dmin))
        upper_dec = np.ceil(np.log10(dmax))

        # Array of decades
        decades = np.arange(lower_dec, upper_dec + 1)

        # Construct levels
        levels = np.concatenate([np.power(10, d) * dec_inc for d in decades])
        levels = levels[(levels < dmax) & (levels > dmin)]
    else:
        # MMI contours are every 0.5 units
        levels = np.arange(
            np.ceil(dmin * 2) / 2,
            np.floor(dmax * 2) / 2 + 0.5,
            0.5
        )
    return levels


"""
Displays an 100GB zarr file of lattice light sheet data
"""

import numpy as np
from napari import Viewer
from napari.util import app_context
import dask.array as da
from timeit import timeit
from pandas import DataFrame
from dask.cache import Cache

cache = Cache(2e9)  # Leverage two gigabytes of memory

base_name = '/Users/nicholassofroniew/Documents/DATA-imaging/zarr_benchmarks/'

image_sizes = [2**x for x in range(8, 13)]
chunk_sizes = [2**x for x in range(4)]
locations = ['local', 'in-memory']
clim_range = [0, 1.0]
opp_caching = ['off', 'on']

df = DataFrame()

def update(ind):
    if ind is None:
        pass
    else:
        viewer.dims.indices[2] = ind
    layer.refresh()

with app_context():

    for N in image_sizes:
        for loc in locations:
            if loc == 'in-memory':
                chunk_sizes_used = [chunk_sizes[0]]
                opp_caching_used = [opp_caching[0]]
            else:
                chunk_sizes_used = chunk_sizes
                opp_caching_used = opp_caching
            for c in chunk_sizes_used:

                file_name = base_name + 'image_' + str(N) + '_chunk_' + str(c) + '.zarr'

                data = da.from_zarr(file_name)
                if loc == 'local':
                    print('local zarr')
                    pass
                elif loc == 'in-memory':
                    print('convert to in memory')
                    data = np.asarray(data)
                else:
                    raise ValueError('Unrecognized location')

                print(data.shape)

                for opc in opp_caching_used:
                    if opc == 'off':
                        try:
                            cache.unregister()
                        except:
                            pass
                    else:
                        cache.register()

                    d = {'N': N, 'c': c, 'shape': data.shape, 'location': loc, 'opp_caching': opc}

                    # create an empty viewer
                    viewer = Viewer()
                    layer = viewer.add_image(data, rgb=False, name='zarr benchmarks',
                                             clim_range=clim_range)

                    # Start profiling - do one refresh without measuring to blank
                    update_cmd = 'update(ind)'
                    glbls = {'update': update, 'ind': None}
                    result = timeit(update_cmd, number=1, globals=glbls)

                    glbls = {'update': update, 'ind': 0}
                    result = timeit(update_cmd, number=1, globals=glbls)
                    print(glbls['ind'], result)
                    d['refresh_time'] = result

                    glbls = {'update': update, 'ind': 1}
                    result = timeit(update_cmd, number=1, globals=glbls)
                    print(glbls['ind'], result)
                    d['move_in_time'] = result

                    glbls = {'update': update, 'ind': 8}
                    result = timeit(update_cmd, number=1, globals=glbls)
                    print(glbls['ind'], result)
                    d['move_new_time'] = result

                    glbls = {'update': update, 'ind': 1}
                    result = timeit(update_cmd, number=1, globals=glbls)
                    print(glbls['ind'], result)
                    d['move_back_time'] = result

                    df = df.append(d, ignore_index=True)

    df.to_csv('data/benchmarks/zarr_3D_dask.csv')


# We want to define a read-only attribute as property attribute method
# It only compute when being accessed.
# But when we accessed it, we hope it save the value in buffer, so that it won't recalculate.

# use descriptor class

# if we think of the variability, use another type, but it will discount efficiency
def lazyproperty(func):
	name = '_lazy_' + func.__name__
	@property
	def lazy(self):
		if hasattr(self, name):
			return getattr(self, name)

		else:
			value = func(self)
			setattr(self, name, value)
			return value
	return lazy

import math
class Circle:
	def __init__(self, radius):
		self.radius = radius

	@lazyproperty
	def area(self):
		print ('Computing area')
		return math.pi * self.radius ** 2

	@lazyproperty
	def perimeter(self):
		print ('Computing perimeter')
		return 2 * math.pi * self.radius
# set won't work

# test

c = Circle(4.0)
print (c.area)
print (c.area)
c.area = 33


#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-21 21:20
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='ActiveBroker',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('timestamp', models.BigIntegerField(db_index=True)),
            ],
        ),
        migrations.CreateModel(
            name='Broker',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('url', models.URLField(db_index=True)),
            ],
        ),
        migrations.CreateModel(
            name='Bundle',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('timestamp', models.BigIntegerField(db_index=True)),
                ('range', models.CharField(max_length=200)),
                ('broker', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Broker')),
            ],
        ),
        migrations.CreateModel(
            name='Cluster',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=200, unique=True)),
                ('serviceUrl', models.URLField()),
            ],
        ),
        migrations.CreateModel(
            name='Consumer',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('timestamp', models.BigIntegerField(db_index=True)),
                ('address', models.CharField(max_length=64, null=True)),
                ('availablePermits', models.IntegerField(default=0)),
                ('connectedSince', models.DateTimeField(null=True)),
                ('consumerName', models.CharField(max_length=64, null=True)),
                ('msgRateOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgRateRedeliver', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgThroughputOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('unackedMessages', models.BigIntegerField(default=0)),
                ('blockedConsumerOnUnackedMsgs', models.BooleanField(default=False)),
            ],
        ),
        migrations.CreateModel(
            name='LatestTimestamp',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=10, unique=True)),
                ('timestamp', models.BigIntegerField(default=0)),
            ],
        ),
        migrations.CreateModel(
            name='Namespace',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=200, unique=True)),
                ('clusters', models.ManyToManyField(to='stats.Cluster')),
            ],
        ),
        migrations.CreateModel(
            name='Property',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=200, unique=True)),
            ],
            options={
                'verbose_name_plural': 'properties',
            },
        ),
        migrations.CreateModel(
            name='Replication',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('timestamp', models.BigIntegerField(db_index=True)),
                ('msgRateIn', models.DecimalField(decimal_places=1, max_digits=12)),
                ('msgThroughputIn', models.DecimalField(decimal_places=1, max_digits=12)),
                ('msgRateOut', models.DecimalField(decimal_places=1, max_digits=12)),
                ('msgThroughputOut', models.DecimalField(decimal_places=1, max_digits=12)),
                ('msgRateExpired', models.DecimalField(decimal_places=1, max_digits=12)),
                ('replicationBacklog', models.BigIntegerField(default=0)),
                ('connected', models.BooleanField(default=False)),
                ('replicationDelayInSeconds', models.IntegerField(default=0)),
                ('inboundConnectedSince', models.DateTimeField(null=True)),
                ('outboundConnectedSince', models.DateTimeField(null=True)),
                ('local_cluster', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Cluster')),
                ('remote_cluster', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='remote_cluster', to='stats.Cluster')),
            ],
        ),
        migrations.CreateModel(
            name='Subscription',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=200)),
                ('timestamp', models.BigIntegerField(db_index=True)),
                ('msgBacklog', models.BigIntegerField(default=0)),
                ('msgRateExpired', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgRateOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgRateRedeliver', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgThroughputOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('subscriptionType', models.CharField(choices=[('N', 'Not connected'), ('E', 'Exclusive'), ('S', 'Shared'), ('F', 'Failover')], default='N', max_length=1)),
                ('unackedMessages', models.BigIntegerField(default=0)),
                ('namespace', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Namespace')),
            ],
        ),
        migrations.CreateModel(
            name='Topic',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(db_index=True, max_length=1024)),
                ('timestamp', models.BigIntegerField(db_index=True)),
                ('averageMsgSize', models.IntegerField(default=0)),
                ('msgRateIn', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgRateOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgThroughputIn', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('msgThroughputOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('pendingAddEntriesCount', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('producerCount', models.IntegerField(default=0)),
                ('subscriptionCount', models.IntegerField(default=0)),
                ('consumerCount', models.IntegerField(default=0)),
                ('storageSize', models.BigIntegerField(default=0)),
                ('backlog', models.BigIntegerField(default=0)),
                ('localRateIn', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('localRateOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('localThroughputIn', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('localThroughputOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('replicationRateIn', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('replicationRateOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('replicationThroughputIn', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('replicationThroughputOut', models.DecimalField(decimal_places=1, default=0, max_digits=12)),
                ('replicationBacklog', models.BigIntegerField(default=0)),
                ('active_broker', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.ActiveBroker')),
                ('broker', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Broker')),
                ('bundle', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Bundle')),
                ('cluster', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Cluster')),
                ('namespace', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Namespace')),
            ],
        ),
        migrations.AddField(
            model_name='subscription',
            name='topic',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Topic'),
        ),
        migrations.AddField(
            model_name='replication',
            name='topic',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Topic'),
        ),
        migrations.AddField(
            model_name='namespace',
            name='property',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Property'),
        ),
        migrations.AddField(
            model_name='consumer',
            name='subscription',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Subscription'),
        ),
        migrations.AddField(
            model_name='bundle',
            name='cluster',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Cluster'),
        ),
        migrations.AddField(
            model_name='bundle',
            name='namespace',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Namespace'),
        ),
        migrations.AddField(
            model_name='broker',
            name='cluster',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Cluster'),
        ),
        migrations.AddField(
            model_name='activebroker',
            name='broker',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='stats.Broker'),
        ),
        migrations.AlterIndexTogether(
            name='topic',
            index_together=set([('name', 'cluster', 'timestamp')]),
        ),
    ]


from html.parser import HTMLParser

class RTFFieldMixin(object):
    def __init__(self, *args, show_as_plain_text=False, plain_text_lines=3, plain_text_line_length=40, **kwargs):
        super().__init__(*args, **kwargs)
        self.parse = show_as_plain_text or False
        self.max_lines = plain_text_lines
        self.max_line_length = plain_text_line_length
        self.parser = RTFFieldHTMLParser(max_lines=self.max_lines, max_line_length=self.max_line_length)

    def to_representation(self, instance, row_data=None):
        self.style.update(input_type="input")
        if not self.parent.is_filter:
            self.render_params["form_component_name"] = "DCKEditor"
            self.style.update({"base_template": "rtf_field.html"})

        return super().to_representation(instance, row_data)

    def render_to_table(self, value, row_data):
        if not self.parent.is_filter and self.parse:
            self.parser.feed(value)
            instance = self.parser.to_string()
            self.parser.reset()
            return instance
        return value

class RTFFieldHTMLParser(HTMLParser):
    def __init__(self, max_lines, max_line_length):
        self.text = []
        self.curr_line_count = 1
        self.curr_line = ""
        self.max_lines = max_lines
        self.max_line_length = max_line_length
        super(RTFFieldHTMLParser, self).__init__()

    def handle_data(self, data):
        text = data.strip()
        if self.curr_line_count <= self.max_lines:
            if len(text) > 0:
                self.curr_line += " " + text
                line = self.curr_line[0 : self.max_line_length - 3]
                if len(self.curr_line) >= self.max_line_length - 3:
                    line += "..."
                line += "<br>"
                self.text.append(line)
                self.curr_line = ""
                self.curr_line_count += 1

    def reset(self):
        self.text = []
        self.curr_line_count = 1
        self.curr_line = ""
        super(RTFFieldHTMLParser, self).reset()

    def to_string(self):
        return "".join(self.text).strip()


import sys
from PyQt5 import QtWidgets
import modelStreet
import api
import sqlite3

conn = sqlite3.connect('PhoneBookDB.db')
cursor = conn.cursor()

class ExampleName(QtWidgets.QMainWindow, modelStreet.Ui_MainWindow):
    currentItemRow = None
    currentItemColumn = None
    currentItemText = None
    deleteIndex = None
    searchText = None
    updateFlag = 0
    newItemText = None
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.Load_but.clicked.connect(self.loadData)
        self.Delete_but.clicked.connect(self.Delete)
        self.Search_but.clicked.connect(self.Search)
        self.Update_but.clicked.connect(self.Update)
        self.Table.clicked.connect(self.onClickTable)
        self.Search_t.textChanged.connect(self.onTextSearch)
        self.Table.itemChanged.connect(self.cellChangedTable)

    def cellChangedTable(self, item):
        if self.updateFlag == 1:
            self.updateFlag = 0
            self.newItemText = item.text()
            id = str(self.SearchIndexInTable(item.row()))
            api.windowStreetUpdate(self.newItemText,id)
        else:
            return
    def onClickTable(self, item):
        self.currentItemRow = item.row()
        self.currentItemColumn = item.column()
        self.deleteIndex = self.SearchIndexInTable(item.row(), item.column())
        self.currentItemText = self.Table.item(item.row(),item.column()).text()
    def SearchIndexInTable(self,row,column = None):
        index_row = row
        index_column = 0
        return(self.Table.item(index_row, index_column).text())

    def Delete(self):
        api.windowStreetDelete(self.deleteIndex)
    def Update(self):
        self.updateFlag = 1
    def loadData(self,name = False):
        if name is not False:
            sql = api.windowStreetLoadTable(name)
            res = conn.execute(sql)
        else:
            sql = api.windowStreetLoadTable()
            res = conn.execute(sql)
        self.Table.setRowCount(0)
        for row_number, row_data in enumerate(res):
            self.Table.insertRow(row_number)
            for colum_number , data in enumerate(row_data):
                self.Table.setItem(row_number,colum_number,QtWidgets.QTableWidgetItem(str(data)))

    def onTextSearch(self, text):
        self.searchText = text
    def Search(self):
        self.loadData(self.searchText)

def main():
        app = QtWidgets.QApplication(sys.argv)
        Street = ExampleName()
        Street.show()
        Street.loadData()
        app.exec_()

if __name__ == '__main__':
        main()