import os
import sys
import time
import getopt
import shutil
import tempfile

from .src import parser
from .src import proxy
from .src import generator
from .src import env_clear
from .src import process
from .src import env_parser, env_inspect
from .utils import log, utils
from .utils.log import priorinit_logger
from .src.log_generator import LogGenerator
from .src.activityfilter import Filter
from .src.casecfgcheck import CaseCfgCheck

def usage():
    print("Usage: libvirt-test-api <OPTIONS> <ARGUMENTS>")
    print("\noptions: -h, --help : Show this help message and exit"
          "\n         -c, --casefile: Specify testsuite configuration file"
          "\n         -k, --configfile: Specify environment configfile"
          "\n         -t, --template: Print testcase config file template"
          "\n         -f, --logxml: Specify log file with type xml,"
          "\n                       defaults to log.xml in current directory"
          "\n         -l, --log-level: 0 or 1 or 2"
          "\n         -d, --delete-log: Delete log items"
          "\n         -m, --merge: Merge two log xmlfiles"
          "\n         -r, --rerun: Rerun one or more testsuites")

    print("example:"
          "\n         libvirt-test-api -l 0|1|2 -c TEST.CONF"
          "\n         libvirt-test-api -c TEST.CONF -k /home/test/global.cfg -f TEST.XML"
          "\n         libvirt-test-api -t repos/domain/start.py ..."
          "\n         libvirt-test-api -m TESTONE.XML TESTTWO.XML"
          "\n         libvirt-test-api -d TEST.XML TESTRUNID TESTID"
          "\n         libvirt-test-api -d TEST.XML TESTRUNID"
          "\n         libvirt-test-api -d TEST.XML all"
          "\n         libvirt-test-api -f TEST.XML"
          "\n         libvirt-test-api -r TESTRUNID TESTID ...")

class Main(object):

    """ The class provides methods to run a new test and manage
        testing log and records
    """

    def __init__(self, casefile, logxml, loglevel, configfile):
        self.casefile = casefile
        self.logxml = logxml
        self.loglevel = loglevel
        self.configfile = configfile

    def run(self, activities_options_list=None):
        """ Run a test instance """
        # generate testrunid from time point runing a testrun
        testrunid = time.strftime("%Y%m%d%H%M%S")
        while os.path.exists('log/%s' % testrunid):
            testrunid = str(int(testrunid) + 1)
        os.makedirs('log/%s' % testrunid)

        log_xml_parser = LogGenerator(self.logxml)

        # If the specified log xmlfile exists, then append the testrun
        # item of this time to the file, if not, create a new log xmlfile
        # named with the name and add the item
        if os.path.exists(self.logxml):
            log_xml_parser.add_testrun_xml(testrunid)
        else:
            log_xml_parser.generate_logxml()
            log_xml_parser.add_testrun_xml(testrunid)

        logfile = None
        logname = log.Log.get_log_name()
        if "AUTODIR" in os.environ:
            autotest_testdir = os.path.join(os.environ['AUTODIR'], 'tests/libvirt_test_API')
            logfile = os.path.join('%s/src/log/%s' % (autotest_testdir, testrunid), logname)
        else:
            logfile = os.path.join('log/%s' % testrunid, logname)
        envlog = log.EnvLog(logfile, self.loglevel)
        env_logger = envlog.env_log()
        caselog = log.CaseLog(logfile, self.loglevel)
        case_logger = caselog.case_log()
        start_time = time.strftime("%Y-%m-%d %H:%M:%S")
        env_logger.info("\nStarted test at :%s", start_time)
        env_logger.info("    Case File: %s\n" % self.casefile)
        env_logger.info("    Log File: %s\n" % logfile)
        env_logger.info("Checking Testing Environment... ")
        base_path = utils.get_base_path()
        if os.path.exists(self.configfile):
            cfg_file = self.configfile
        else:
            cfg_file = os.path.join(base_path, 'config', 'global.cfg')
        env = env_parser.Envparser(cfg_file)
        envck = env_inspect.EnvInspect(env, env_logger)
        if envck.env_checking() == 1:
            sys.exit(1)

        # if it's a new test, parsing the case configuration file to generate
        # a list of activities and options for the test instance.
        if activities_options_list is None:
            case_logger.debug('Parser the case configuration file to generate a data list')
            activities_options_list = parser.CaseFileParser(self.casefile, cfg_file, int(self.loglevel), case_logger).get_list()

        if "options" in activities_options_list[-1][0]:
            activities_list = activities_options_list[:-1]
            options_list = activities_options_list[-1]
        else:
            activities_list = activities_options_list
            options_list = [{'options': {}}]

        # multiply the activities list if option "times" given
        if "times" in options_list[0]['options']:
            times = int(options_list[0]['options']["times"])
            activities_list = activities_list * times

        filterobj = Filter(activities_list)

        unique_testcases = filterobj.unique_testcases()

        # __import__ TESTCASE.py once for duplicate testcase names
        proxy_obj = proxy.Proxy(unique_testcases)

        # check the options to each testcase in case config file
        casechk = CaseCfgCheck(proxy_obj, activities_list, case_logger)
        if casechk.check():
            return 1

        # get a list of unique testcase
        # with 'clean' flag appended to its previous testcase
        unique_testcase_keys = filterobj.unique_testcase_cleansuffix()
        cases_func_ref_dict = proxy_obj.get_func_call_dict(unique_testcase_keys)

        # get check function reference if that is defined in testcase file
        cases_checkfunc_ref_dict = proxy_obj.get_optionalfunc_call_dict('check')

        # create a null list, then, initilize generator to
        # get the callable testcase function
        # and put it into procs list for running.
        procs = []
        lockfile = tempfile.NamedTemporaryFile()
        testid = int(logname[-3:])-1
        for activity in activities_list:
            testid = testid+1
            log_xml_parser.add_test_xml(testrunid, str(testid))
            procs.append(generator.FuncGen(cases_func_ref_dict,
                                           cases_checkfunc_ref_dict,
                                           proxy_obj,
                                           activity, logfile,
                                           testrunid,
                                           testid,
                                           log_xml_parser,
                                           lockfile,
                                           env_logger, case_logger)
                         )

        totalnum = len(procs)
        passnum = 0
        failnum = 0
        testrunstart_time = time.strftime("%Y-%m-%d %H:%M:%S")

        # if the value of option multiprocess is enable,
        # will call the module process to run the testcases
        # which stored in the list of procs, if disable,
        # will call them one by one
        if "multiprocess" in options_list[0]['options']:
            if options_list[0]['options']["multiprocess"] == "enable":
                proc = process.Process(procs)
                proc.fork()
                passnum, failnum = proc.wait()

            elif options_list[0]['options']["multiprocess"] == "disable":
                for i in procs:
                    ret = i()
                    if ret:
                        failnum += 1
                    else:
                        passnum += 1

        else:
            for i in procs:
                ret = i()
                if ret:
                    failnum += 1
                else:
                    passnum += 1

        testrunend_time = time.strftime("%Y-%m-%d %H:%M:%S")
        # close hypervisor connection
        envck.close_hypervisor_connection()
        # after running a testrun , add the summary of
        # the testrun in the format of xml into xmlfile
        log_xml_parser.add_testrun_summary(testrunid,
                                           passnum,
                                           failnum,
                                           totalnum,
                                           testrunstart_time,
                                           testrunend_time)

        lockfile.close()

        if "cleanup" in options_list[0]['options']:
            if options_list[0]['options']["cleanup"] == "enable":
                env_logger.info("Clean up Testing Environment...")
                cases_clearfunc_ref_dict = proxy_obj.get_optionalfunc_call_dict('clean')
                logname = log.Log.get_log_name()
                logfile = os.path.join('log/%s' % testrunid, logname)
                for activity in activities_list:
                    env_clear.EnvClear(cases_clearfunc_ref_dict, activity, logfile, self.loglevel)()
                env_logger.info("Done")
            elif options_list[0]['options']["cleanup"] == "disable":
                pass
            else:
                pass

        if failnum:
            return 1
        return 0

    @staticmethod
    def print_casefile(testcases):
        """print testcase file template"""
        modcasename = []
        for case in testcases:
            if not os.path.isfile(case) or not case.endswith('.py'):
                priorinit_logger.error("testcase %s couldn't be recognized" % case)
                return 1

            paths = case.split('/')
            modcasename.append(paths[2] + ':' + paths[3][:-3])

        proxy_obj = proxy.Proxy(modcasename)
        case_params = proxy_obj.get_params_variables()

        string = ("# the file is generated automatically, please\n"
                  "# make some modifications before the use of it\n"
                  "# params in [] are optional to its testcase\n")
        for key in modcasename:
            string += "%s\n" % key
            required_params, optional_params = case_params[key]
            for p in required_params:
                string += " " * 4 + p + "\n"
                string += " " * 8 + p.upper() + "\n"
            for p in optional_params:
                string += " " * 4 + "[" + p + "]\n"
                string += " " * 8 + str(optional_params[p]) + "\n"

            if proxy_obj.has_clean_function(key):
                string += "clean\n"

            string += "\n"

        priorinit_logger.info(string)
        return 0

    @staticmethod
    def remove_log(logxml, testrunid, testid=None):
        """  to remove log item in the log xmlfile """
        log_xml_parser = LogGenerator(logxml)

        # remove a test in a testrun
        if testrunid and testid:
            priorinit_logger.info("testrunid is %s" % testrunid)
            priorinit_logger.info("testid is %s" % testid)
            log_xml_parser.remove_test_xml(testrunid, testid)
            os.remove("log/%s/libvirt_test%s" % (testrunid, testid))
            priorinit_logger.info("Item testid %s in testrunid %s deleted successfully" %
                  (testid, testrunid))

        # delete all of records in a log xmlfile
        elif testrunid == "all" and not testid:
            testrunids = log_xml_parser.remove_alltestrun_xml()
            for testrunid in testrunids:
                shutil.rmtree("log/%s" % testrunid)
            priorinit_logger.info("All testruns deleted successfully")

        # delete record of a whole testrun
        elif testrunid.startswith("2") and not testid:
            priorinit_logger.info("testrunid is %s" % testrunid)
            log_xml_parser.remove_testrun_xml(testrunid)
            shutil.rmtree("log/%s" % testrunid)
            priorinit_logger.info("Testrun with testrunid %s deleted successfully" % testrunid)

        # report error if arguments given wrong
        else:
            priorinit_logger.info("Arguments error")
            usage()
            sys.exit(0)

    @staticmethod
    def merge_logxmls(logxml_one, logxml_two):
        """ to merge two log xml files of log into one"""
        log_xml_parser = LogGenerator(logxml_one)
        log_xml_parser.merge_xmlfiles(logxml_two)
        priorinit_logger.info("Merge the second log xml file %s to %s successfully " %
              (logxml_two, logxml_one))

    def rerun(self, testrunid, testid_list):
        """ rerun a specific test or a set of tests """
        caseinfo_file = "log" + "/" + str(testrunid) + "/" + "caseinfo"
        CASEINFO = open(caseinfo_file, "r")
        activities_list = []
        for testid in testid_list:
            activities = eval(CASEINFO.readlines()[testid - 1])
            activities_list.append(activities)

        self.run(activities_list)

def main():

    casefile = "case.conf"
    configfile = "global.cfg"
    logxml = "log.xml"
    loglevel = 0

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hc:k:tf:l:dmr",
                                   ["help", "casefile=", "configfile=", "template", "logxml=", "log-level=",
                                    "delete-log", "merge", "rerun"])
    except getopt.GetoptError as err:
        priorinit_logger.error(str(err))
        usage()
        sys.exit(2)

    for o, v in opts:
        if o == "-h" or o == "--help":
            usage()
            sys.exit(0)
        if o == "-c" or o == "--casefile":
            casefile = v
        if o == "-k" or o == "--configfile":
            configfile = v
        if o == "-t" or o == "--template":
            if len(args) <= 0:
                usage()
                sys.exit(1)
            if Main.print_casefile(args):
                sys.exit(1)
            sys.exit(0)
        if o == "-f" or o == "--logxml":
            logxml = v
        if o == "-l" or o == "--log-level":
            loglevel = v
        if o == "-d" or o == "--delete-log":
            if len(args) == 1:
                usage()
                sys.exit(1)
            if len(args) == 2:
                logxml = args[0]
                testrunid = args[1]
                testid = None
            if len(args) == 3:
                logxml, testrunid, testid = args[0], args[1], args[2]
            if len(args) > 3:
                usage()
                sys.exit(1)
            Main.remove_log(logxml, testrunid, testid)
            sys.exit(0)
        if o == "-m" or o == "--merge":
            if len(args) == 2:
                logxml_one = args[0]
                logxml_two = args[1]
                Main.merge_logxmls(logxml_one, logxml_two)
                sys.exit(0)
            else:
                usage()
                sys.exit(1)
        if o == "-r" or o == "--rerun":
            if len(args) <= 1:
                usage()
                sys.exit(1)
            if len(args) >= 2:
                testid_list = []
                testrunid = args[0]
                for testid in args[1:]:
                    testid = int(testid)
                    testid_list.append(testid)
                maincase = Main(casefile, logxml, loglevel)
                maincase.rerun(testrunid, testid_list)
                sys.exit(0)

    maincase = Main(casefile, logxml, loglevel, configfile)
    if maincase.run():
        sys.exit(1)
    sys.exit(0)


import numpy as np
from scipy.io import savemat
import scipy.io
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from Neural_Decoding.decoders import KalmanFilterDecoder
def cal_cc(y,y1):
    ccx = np.corrcoef(y1[:,0],y[:,0])[0,1]
    ccy = np.corrcoef(y1[:,1],y[:,1])[0,1]
    return (ccx+ccy)/2
def accumulate(v,pos0,dt):
    """
    v: T*2
    pos0: 1*2
    """
    pos = np.zeros_like(v)
    pos[0,:] = pos0
    for i in range(pos.shape[0]-1):
        pos[i+1,:] = pos[i,:] + v[i,:]*dt
    return pos
def kf_prediction(X_train, Y_train, X_test, Y_test, dt, use=None,pqr = None):
    # use -> list:
    # T*...
    #preprocess train
    #lag=0
    if use is None:
        use = [0]
    pos_y_train = Y_train
    print(pos_y_train.shape)
    temp=np.diff(pos_y_train,axis=0)/dt
    vels_binned=np.concatenate((temp,temp[-1:,:]),axis=0)
    temp=np.diff(vels_binned,axis=0)/dt
    acc_binned=np.concatenate((temp,temp[-1:,:]),axis=0)
    l = [pos_y_train,vels_binned,acc_binned]
    y_train_kf = None
    if len(use)==1:
        y_train_kf=l[use[0]]
    elif len(use)==2:
        y_train_kf=np.concatenate((l[use[0]],l[use[1]]),axis=1)
    elif len(use)==3:
        y_train_kf=np.concatenate((pos_y_train,vels_binned,acc_binned),axis=1)

    pos_y_test = Y_test
    temp=np.diff(pos_y_test,axis=0)/dt
    vels_binned=np.concatenate((temp,temp[-1:,:]),axis=0)
    temp=np.diff(vels_binned,axis=0)/dt
    acc_binned=np.concatenate((temp,temp[-1:,:]),axis=0)
    y_test_kf = None
    l = [pos_y_test,vels_binned,acc_binned]
    if len(use)==1:
        y_test_kf=l[use[0]]
    elif len(use)==2:
        y_test_kf=np.concatenate((l[use[0]],l[use[1]]),axis=1)
    elif len(use)==3:
        y_test_kf=np.concatenate((pos_y_test,vels_binned,acc_binned),axis=1)

    # num_examples=X_kf.shape[0]
    # #Re-align data to take lag into account
    # if lag<0:
    #     y_kf=y_kf[-lag:,:]
    #     X_kf=X_kf[0:num_examples+lag,:]
    # if lag>0:
    #     y_kf=y_kf[0:num_examples-lag,:]
    #     X_kf=X_kf[lag:num_examples,:]

    # Z-score inputs
    X_kf_train_mean=np.nanmean(X_train,axis=0)
    X_kf_train_std=np.nanstd(X_train,axis=0)
    X_train=(X_train-X_kf_train_mean)/X_kf_train_std
    X_test=(X_test-X_kf_train_mean)/X_kf_train_std

    #Zero-center outputs
    y_kf_train_mean=np.nanmean(y_train_kf,axis=0)
    y_train_kf=y_train_kf-y_kf_train_mean
    y_test_kf=y_test_kf-y_kf_train_mean

    model_kf=KalmanFilterDecoder(C=1)
    model_kf.fit(X_train,y_train_kf)
    my_P=None
    print("Q")
    print(model_kf.model[1])
    print("R")
    print(model_kf.model[3])
    if pqr is not None:
        if pqr == 'Q':
            model_kf.model[1] = np.zeros_like(model_kf.model[1])
        elif pqr == 'R':
            model_kf.model[3] = np.zeros_like(model_kf.model[3])
        elif pqr == 'P':
            my_P = np.eye(2)*100
    y_predicted_kf=model_kf.predict(X_test,y_test_kf,my_P)
    return y_predicted_kf+y_kf_train_mean,y_test_kf+y_kf_train_mean
def pos2bin(x, win_size):
    bin_num = x.shape[0]//win_size
    channel = x.shape[1]
    input_records = np.zeros((bin_num, channel))
    for win in range(bin_num):
        start_T = win_size * win
        end_T = win_size * (win + 1)
        spike_train = x[start_T:end_T, :]
        inp = np.mean(spike_train, axis=0)
        input_records[win] = inp
    return input_records

def spikes2bin(x, win_size):
    bin_num = x.shape[0]//win_size
    channel = x.shape[1]
    input_records = np.zeros((bin_num, channel))
    for win in range(bin_num):
        start_T = win_size * win
        end_T = win_size * (win + 1)
        spike_train = x[start_T:end_T, :]
        inp = np.sum(spike_train, axis=0)
        input_records[win] = inp
    return input_records

p = "./data/indy_20160407_02.mat"
data = scipy.io.loadmat(p)
xy_pos = data['xy_pos']
spks_mat = data['spks_mat']
xy_pos = xy_pos[:200000,:]
spks_mat = spks_mat[:200000,:]

bin_size = 100 #ms
origin_bin_size = 4 #ms
x_binned = spikes2bin(spks_mat,bin_size//origin_bin_size)
y_binned = pos2bin(xy_pos,bin_size//origin_bin_size)

# print(x_binned.shape)
# print(y_binned.shape)

#前60%作为训练,后30%作为预测
n_train = int(x_binned.shape[0] * 0.6)
n_test = int(x_binned.shape[0] * 0.3)
train_begin = 0
train_end = train_begin + n_train
test_begin = train_end
test_end = test_begin + n_test
x_train,x_test = x_binned[train_begin:train_end,:],x_binned[test_begin:test_end,:]
y_train,y_test = y_binned[train_begin:train_end,:],y_binned[test_begin:test_end,:]

res_p = []

#只使用位置解码
y_pred,y = kf_prediction(x_train,y_train,x_test,y_test,dt=bin_size/1000,use=[0],pqr='Q')
ccx = np.corrcoef(y_pred[:,0],y[:,0])[0,1]
ccy = np.corrcoef(y_pred[:,1],y[:,1])[0,1]
res_p.append(cal_cc(y_pred,y))

y_pred,y = kf_prediction(x_train,y_train,x_test,y_test,dt=bin_size/1000,use=[0],pqr='R')
ccx = np.corrcoef(y_pred[:,0],y[:,0])[0,1]
ccy = np.corrcoef(y_pred[:,1],y[:,1])[0,1]
print("??")
print(y_pred,y)
res_p.append(cal_cc(y_pred,y))

y_pred,y = kf_prediction(x_train,y_train,x_test,y_test,dt=bin_size/1000,use=[0],pqr='P')
ccx = np.corrcoef(y_pred[:,0],y[:,0])[0,1]
ccy = np.corrcoef(y_pred[:,1],y[:,1])[0,1]
res_p.append(cal_cc(y_pred,y))
# size = len(res_p)
# x = np.arange(size)+1

# total_width, n = 0.8, 3
# width = total_width / n
# x = x - (total_width - width) / 2
print(res_p)
x = np.arange(1,4)
plt.bar(x, res_p,width=0.3,label='cc')
for i, count in enumerate(res_p):
    plt.text(x[i], count + 0.01, str(count)[:4], ha='center', va='bottom')
plt.xticks(x,["P=0","Q=0","R=100*E"])
plt.legend()
plt.show()


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.interpolate import CubicSpline
from scipy.signal import argrelextrema

def local_extrema(S):
    local_maxima = argrelextrema(S, comparator=np.greater_equal)[0]
    local_minima = argrelextrema(S, comparator=np.less_equal)[0]
    return local_minima, local_maxima

def cubic_spline(S, local_extrema):
    x = local_extrema
    y = S[x]
    return CubicSpline(x, y, bc_type='natural')  # 2nd  order cubic spline

def SD(h0, h1):
    # Standard deviation between h0 and h1
    SD = 0
    for t in range(len(h0)):
        SD += (h0[t] - h1[t]) ** 2 / h0[t] ** 2
    return SD

def is_monotonic(S):
    return (all(S[i] <= S[i + 1] for i in range(len(S) - 1)) or
            all(S[i] >= S[i + 1] for i in range(len(S) - 1)))

class EMD:
    def __init__(self, S, num_sifts=10):
        self.T = np.arange(len(S))
        self.S = S
        self.num_sifts = num_sifts

    def __call__(self, criterion=0.2):
        self.criterion = criterion
        imf_list = []

        c = self.IMF(self.S)
        imf_list.append(c)
        r = self.S - c
        while not is_monotonic(r):
            c = self.IMF(r)
            imf_list.append(c)
            r = r - c
        imf_list.append(r)
        # Note this residue is not an IMF but the baseline trend of original signal
        return np.asarray(imf_list)

    def sift(self, S):
        S_min, S_max = local_extrema(S)
        # checks to see if any extrema have been found - if none then creates a zero array to allow further arithmetic operations
        max_envelope =  np.asarray(cubic_spline(S, S_max)(self.T))
        min_envelope =  np.asarray(cubic_spline(S, S_min)(self.T))
        # np.zeros(len(self.T)) if len(S_max) <= 1 else
        # np.zeros(len(self.T)) if len(S_min) <= 1 else
        m = (max_envelope + min_envelope) / 2.0
        h = S - m
        return h

    def IMF(self, S):
        h = self.sift(S)
        if len(h.shape) > 1:
            h = h[0, :]
        for i in range(self.num_sifts - 1):
            h = self.sift(h)
            if len(h.shape) > 1:
                h = h[0, :]
        return h

def fn(t):
    return np.cos(3/30 * np.pi * t) + np.cos(2/34 * np.pi * t)

if __name__ == '__main__':
    t = np.arange(0, 540)
    s = fn(t)

    emd = EMD(s)
    imf = emd.sift(s.copy())
    plt.plot(s)
    plt.plot(imf)
    plt.show()


# version 1.0

# Includes
# filtfilt
# smooth

# Hz
# filterhum50

import scipy as sp

from scipy import *
from scipy import signal

def lowpass(s,f,order=2,fs=1000.0):
    b,a=signal.butter(order,f/fs)
    return signal.lfilter(b,a,s)

def highpass(s,f,order=2,fs=1000.0):
    b,a=signal.butter(order,f/fs,btype='highpass')
    return signal.lfilter(b,a,s)

def bandpass(s,f1,f2,order=2,fs=1000.0):
    b,a=signal.butter(order,[f1/fs,f2/fs],btype='bandpass')
    return signal.lfilter(b,a,s)

def bandstop(s,f1,f2,order=2,fs=1000.0):
    b,a=signal.butter(order,[f1/fs,f2/fs],btype='bandstop')
    return signal.lfilter(b,a,s)

def point(x,y,color='r',ims=15):
    plot([x],[y],color=color,ms=ims,marker='.')

def plotfft(s,fmax,doplot=True):
    fs=abs(fft(s))
    f=linspace(0,fmax/2,len(s)/2)
    if doplot:
        plot(f[1:len(s)/2],fs[1:len(s)/2])
    return f,fs,

from numpy import vstack, hstack, eye, ones, zeros, linalg, \
newaxis, r_, flipud, convolve, matrix, array
from scipy.signal import lfilter

def lfilter_zi(b,a):
    #compute the zi state from the filter parameters. see [Gust96].

    #Based on:
    # [Gust96] Fredrik Gustafsson, Determining the initial states in forward-backward
    # filtering, IEEE Transactions on Signal Processing, pp. 988--992, April 1996,
    # Volume 44, Issue 4

    n=max(len(a),len(b))

    zin = (  eye(n-1) - hstack( (-a[1:n,newaxis],
                                 vstack((eye(n-2), zeros(n-2))))))

    zid=  b[1:n] - a[1:n]*b[0]

    zi_matrix=linalg.inv(zin)*(matrix(zid).transpose())
    zi_return=[]

    #convert the result into a regular array (not a matrix)
    for i in range(len(zi_matrix)):
      zi_return.append(float(zi_matrix[i][0]))

    return array(zi_return)

def filtfilt(b,a,x):
    #For now only accepting 1d arrays
    ntaps=max(len(a),len(b))
    edge=ntaps*3

    if x.ndim != 1:
        raise(ValueError, "Filiflit is only accepting 1 dimension arrays.")

    #x must be bigger than edge
    if x.size < edge:
        raise(ValueError, "Input vector needs to be bigger than 3 * max(len(a),len(b).")

    if len(a)!=len(b):
        b=r_[b,zeros(len(a)-len(b))]

    zi=lfilter_zi(b,a)

    #Grow the signal to have edges for stabilizing
    #the filter with inverted replicas of the signal
    s=r_[2*x[0]-x[edge:1:-1],x,2*x[-1]-x[-1:-edge:-1]]
    #in the case of one go we only need one of the extrems
    # both are needed for filtfilt

    (y,zf)=lfilter(b,a,s,-1,zi*s[0])

    (y,zf)=lfilter(b,a,flipud(y),-1,zi*y[-1])

    return flipud(y[edge-1:-edge+1])

def Hz(f,FS=1000.0):
	return f/FS*2.0

def filterhum50(s, filter_order=2):

    hum_notch50=array([0.95,1.05])*Hz(50)
    hum_notch100=hum_notch50*2

    [b,a]=signal.butter(filter_order, hum_notch50, btype="bandstop")
    fdata=signal.lfilter(b, a, s)

    [b,a]=signal.butter(filter_order, hum_notch100, btype="bandstop")
    fdata=signal.lfilter(b, a, fdata)
    return fdata

import numpy

def smooth(x,window_len=10,window='hanning'):
    """smooth the data using a window with requested size.

    This method is based on the convolution of a scaled window with the signal.
    The signal is prepared by introducing reflected copies of the signal
    (with the window size) in both ends so that transient parts are minimized
    in the begining and end part of the output signal.

    input:
        x: the input signal
        window_len: the dimension of the smoothing window
        window: the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'
            flat window will produce a moving average smoothing.

    output:
        the smoothed signal

    example:

    t=linspace(-2,2,0.1)
    x=sin(t)+randn(len(t))*0.1
    y=smooth(x)

    see also:

    numpy.hanning, numpy.hamming, numpy.bartlett, numpy.blackman, numpy.convolve
    scipy.signal.lfilter

    TODO: the window parameter could be the window itself if an array instead of a string
    """

    if x.ndim != 1:
        raise(ValueError, "smooth only accepts 1 dimension arrays.")

    if x.size < window_len:
        raise(ValueError, "Input vector needs to be bigger than window size.")

    if window_len<3:
        return x

    if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:
        raise(ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'")

    s=numpy.r_[2*x[0]-x[window_len:1:-1],x,2*x[-1]-x[-1:-window_len:-1]]
    #print(len(s))
    if window == 'flat': #moving average
        w=ones(window_len,'d')
    else:
        w=eval('numpy.'+window+'(window_len)')

    y=numpy.convolve(w/w.sum(),s,mode='same')
    return y[window_len-1:-window_len+1]

from numpy import *
from pylab import *

def smooth_demo():

    t=linspace(-4,4,100)
    x=sin(t)
    xn=x+randn(len(t))*0.1
    y=smooth(x)

    ws=31

    subplot(211)
    plot(ones(ws))

    windows=['flat', 'hanning', 'hamming', 'bartlett', 'blackman']

    hold(True)
    for w in windows[1:]:
        eval('plot('+w+'(ws) )')

    axis([0,30,0,1.1])

    legend(windows)
    title("The smoothing windows")
    subplot(212)
    plot(x)
    plot(xn)
    for w in windows:
        plot(smooth(xn,10,w))
    l=['original signal', 'signal with noise']
    l.extend(windows)

    legend(l)
    title("Smoothing a noisy signal")
    show()

# Todo compose a demo and test files

if __name__=='__main__':

    from scipy.signal import butter
    from scipy import sin, arange, pi, randn

    from pylab import plot, legend, show, hold

    t=arange(-1,1,.01)
    x=sin(2*pi*t*.5+2)
    #xn=x + sin(2*pi*t*10)*.1
    xn=x+randn(len(t))*0.05

    [b,a]=butter(3,0.05)

    z=lfilter(b,a,xn)
    y=filtfilt(b,a,xn)

    plot(x,'c')
    hold(True)
    plot(xn,'k')
    plot(z,'r')
    plot(y,'g')

    legend(('original','noisy signal','lfilter - butter 3 order','filtfilt - butter 3 order'))
    hold(False)
    show()

def peakDetectPos(x,tol):

    b=+x
    b[b<tol]=0
    return find((diff(numpy.sign(diff(b))))==-2)+1

def priorPeak(V,Vprior):
    return numpy.array([Vprior[find(Vprior<i)][-1] for i in V])

def postPeak(V,Vpost):
    return numpy.array([Vpost[find(Vpost>i)][-1] for i in V])


# -*- coding: utf-8 -*-

""" Minor Project -
Our main objective in this project is to develop a Machine Learning model that
will be predicting the cost of the food served by the restaurants across
different cities in India and to investigate the factors that really affect
the cost.

Size of training set: 12,690 records

Size of test set: 4,231 records

Columns:

TITLE: The feature of the restaurant which can help identify what and for
whom it is suitable for.

RESTAURANT_ID: A unique ID for each restaurant.

CUISINES: The variety of cuisines that the restaurant offers.

TIME: The open hours of the restaurant.

CITY: The city in which the restaurant is located.

LOCALITY: The locality of the restaurant.

RATING: The average rating of the restaurant by customers.

VOTES: The overall votes received by the restaurant.

COST: The average cost of a two-person meal.

"""

# Data Preprocessing and Visualization Modules
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Loading the training and testing dataset
train_data = pd.read_excel("Data_Train.xlsx")
test_data = pd.read_excel("Data_Test.xlsx")

# Extracting the features and labels from training data
features = train_data.iloc[:,:-1]
labels = train_data.iloc[:,-1].values.reshape(-1,1)

# Fetching the datatypes of each column
column_df = test_data.dtypes.reset_index()
# Renaming the columns
column_df.columns = ['features', 'datatypes']
from sklearn.feature_extraction import FeatureHasher
h = FeatureHasher(n_features=8, input_type="string")
features = h.transform(features).toarray()
test_data = h.transform(test_data).toarray()
labels = h.transform(labels).toarray()
from sklearn.linear_model import LinearRegression
lin  = LinearRegression()
lin.fit(features, labels)
features.iloc[:,2].nunique()


# -*- coding: utf-8 -*-

# @Time    : 2019/12/2 19:21
# @Email   : 986798607@qq.com
# @Software: PyCharm
# @License: BSD 3-Clause
import numpy as np
from numpy.linalg import matrix_rank
from sklearn.utils import check_array

from featurebox.combination.dim import Dim

def dimension_check(x, y=None):
    if y is not None:
        x.append(y)
    x = np.array(x).T
    x = check_array(x, ensure_2d=True)
    x = x.astype(np.float64)
    det = matrix_rank(x)
    che = []
    for i in range(x.shape[1]):
        x_new = np.delete(x, i, 1)
        det2 = matrix_rank(x_new)
        che.append(det - det2)
    sum(che)

    if sum(che) == 0:
        return 1
    else:
        return 0


from ast import parse

with open('modules.py') as f:
    source = f.read()

ast = parse(source)
print(f'ast = {ast!r}')

code = compile(ast, 'modules.py', mode='exec')
print(f'code = {code!r}')
print(code.co_code)

namespace = {}
exec(code, namespace)
print(f'namespace = {namespace.keys()}')

# construct module
class mod:
    def __init__(self, name, bases, body):
        self.name, self.base = name, bases
        self.__dict__.update(body)

module = mod('module', (), namespace)
print(f'module = {dir(module)!r}')

f = module.f
print(f'f(1,2) = {f()}')

import threading
import time

class MyThread(threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter

    def run(self):
        print("Starting " + self.name)
        # f()
        print_time(self.name, 5, self.counter)
        print("Exiting " + self.name)

exitFlag = 0

def print_time(threadName, counter, delay):
    while counter:
        f()
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# Create new threads
thread1 = MyThread(1, "Thread-1", 1)
thread2 = MyThread(2, "Thread-2", 2)

# Start new Threads
thread1.start()
thread2.start()


# Implement a macro glog_library() that the BUILD file can load.

# By default, glog is built with gflags support.  You can change this behavior
# by using glog_library(with_gflags=0)
#
# This file is inspired by the following sample BUILD files:
#       https://github.com/google/glog/issues/61
#       https://github.com/google/glog/files/393474/BUILD.txt

def glog_library(namespace='google', with_gflags=1):
    if native.repository_name() != '@':
        gendir = '$(GENDIR)/external/' + native.repository_name().lstrip('@')
    else:
        gendir = '$(GENDIR)'

    native.cc_library(
        name = 'glog',
        visibility = [ '//visibility:public' ],
        srcs = [
            ':config_h',
            'src/base/commandlineflags.h',
            'src/base/googleinit.h',
            'src/base/mutex.h',
            'src/demangle.cc',
            'src/demangle.h',
            'src/logging.cc',
            'src/raw_logging.cc',
            'src/signalhandler.cc',
            'src/stacktrace.h',
            'src/stacktrace_generic-inl.h',
            'src/stacktrace_libunwind-inl.h',
            'src/stacktrace_powerpc-inl.h',
            'src/stacktrace_windows-inl.h',
            'src/stacktrace_x86-inl.h',
            'src/stacktrace_x86_64-inl.h',
            'src/symbolize.cc',
            'src/symbolize.h',
            'src/utilities.cc',
            'src/utilities.h',
            'src/vlog_is_on.cc',
        ],
        hdrs = [
            ':logging_h',
            ':raw_logging_h',
            ':stl_logging_h',
            ':vlog_is_on_h',
            'src/glog/log_severity.h',
        ],
        strip_include_prefix = 'src',
        copts = [
            # Disable warnings that exists in glog.
            '-Wno-sign-compare',
            '-Wno-unused-function',
            '-Wno-unused-local-typedefs',
            '-Wno-unused-variable',
            "-DGLOG_BAZEL_BUILD",
            # Inject a C++ namespace.
            "-DGOOGLE_NAMESPACE='%s'" % namespace,
            # Allows src/base/mutex.h to include pthread.h.
            '-DHAVE_PTHREAD',
            # Allows src/logging.cc to determine the host name.
            '-DHAVE_SYS_UTSNAME_H',
            # For src/utilities.cc.
            '-DHAVE_SYS_SYSCALL_H',
            '-DHAVE_SYS_TIME_H',
            '-DHAVE_STDINT_H',
            '-DHAVE_STRING_H',
            # Enable dumping stacktrace upon sigaction.
            '-DHAVE_SIGACTION',
            # For logging.cc.
            '-DHAVE_PREAD',

            # Include generated header files.
            '-I%s/glog_internal' % gendir,
        ] + [
            # Use gflags to parse CLI arguments.
            '-DHAVE_LIB_GFLAGS',
        ] if with_gflags else [],
        deps = [
            '@com_github_gflags_gflags//:gflags',
        ] if with_gflags else [],
    )

    native.genrule(
        name = 'gen_sh',
        outs = [
            'gen.sh',
        ],
        cmd = r'''\
#!/bin/sh
cat > $@ <<"EOF"
sed -e 's/@ac_cv_cxx_using_operator@/1/g' \
    -e 's/@ac_cv_have_unistd_h@/1/g' \
    -e 's/@ac_cv_have_stdint_h@/1/g' \
    -e 's/@ac_cv_have_systypes_h@/1/g' \
    -e 's/@ac_cv_have_libgflags_h@/1/g' \
    -e 's/@ac_cv_have_uint16_t@/1/g' \
    -e 's/@ac_cv_have___builtin_expect@/1/g' \
    -e 's/@ac_cv_have_.*@/0/g' \
    -e 's/@ac_google_start_namespace@/namespace google {/g' \
    -e 's/@ac_google_end_namespace@/}/g' \
    -e 's/@ac_google_namespace@/google/g' \
    -e 's/@ac_cv___attribute___noinline@/__attribute__((noinline))/g' \
    -e 's/@ac_cv___attribute___noreturn@/__attribute__((noreturn))/g' \
    -e 's/@ac_cv___attribute___printf_4_5@/__attribute__((__format__ (__printf__, 4, 5)))/g'
EOF
''',
    )

    native.genrule(
        name = 'config_h',
        srcs = [
            'src/config.h.cmake.in',
        ],
        outs = [
            'glog_internal/config.h',
        ],
        cmd = "awk '{ gsub(/^#cmakedefine/, \"//cmakedefine\"); print; }' $< > $@",
    )

    [native.genrule(
        name = '%s_h' % f,
        srcs = [
            'src/glog/%s.h.in' % f,
        ],
        outs = [
            'src/glog/%s.h' % f,
        ],
        cmd = '$(location :gen_sh) < $< > $@',
        tools = [':gen_sh'],
    ) for f in [
            'vlog_is_on',
            'stl_logging',
            'raw_logging',
            'logging',
        ]
    ]


n = int(input())
num = int(input())

x = list(map(int, input().split()))

ans = []
cut = []

for i in x:
    swich = True
    for j in range(len(ans)):
         if i == ans[j]:
             cut[j] += 1
             swich = False
             break

    # 현재 후보자가 아닌 사람을 추천한 경우
    if swich and (len(ans) == n):
        mins = min(cut)
        for j in range(n):
            # 첫번째로 만나는 최솟값이
            # 가장 오래된 후보 = 제거될 대상
            if (mins == cut[j]):
                del cut[j]
                del ans[j]
                # 가장 오래된 후보가 앞에 있는 이유는
                # 새로운 후보 등록을 뒤에서 넣기 때문(큐)
                #ans.append(i)
                #cut.append(1)
                break
    if swich:
        ans.append(i)
        cut.append(1)

# 리스트를 한번에 출력하는 방법
print(*sorted(ans))


# Set Cell Color

# pip install pywin32
import win32com.client

# Initialize the Excel Application object
exApplication = win32com.client.Dispatch("Excel.Application")

# Set Visible property to true
exApplication.Visible = True

# Open Workbook
exWorkbook = exApplication.Workbooks.Open(r"c:\Work\test2.xlsx")

# Set cell color
exWorksheet = exWorkbook.ActiveSheet
exWorksheet.Range("A1:B1").Interior.ColorIndex = 10
exWorksheet.Range("A2:B3").Interior.ColorIndex = 27

# Release resources
exWorkbook.Close(True) # True : save changes
exApplication.Quit()


# Ignore all below...

n, m = map(int, input().split())

nodes = {}
node_dangerous = {}

for i in range(1, n + 1):
    nodes[i] = []
    node_dangerous[i] = True

for _ in range(m):
    n1, n2, dangerous = map(int, input().split())

    if n1 == n2:
        continue

    if not dangerous:
        node_dangerous[n1] = False
        node_dangerous[n2] = False

    nodes[n1].append((n2, dangerous))
    nodes[n2].append((n1, dangerous))

def bfs():
    q = [(1, 0, 0)]  # Node, level, dangerousness so far
    ans = []  # level, dangerousness so far
    visited = [1]

    while q:
        curr_r, level, dangerous_so_far = q.pop(0)

        if curr_r == n:
            ans.append((level, dangerous_so_far))
            return ans

        for adj, dangerous_new in nodes[curr_r]:

            if node_dangerous[curr_r] is True and adj not in visited:
                q.append((adj, level + 1, dangerous_so_far + dangerous_new))
                visited.append(adj)

            elif node_dangerous[curr_r] is False and dangerous_new == 0 and adj not in visited:

                q.append((adj, level + 1, dangerous_so_far))
                visited.append(adj)

ans = bfs()

if ans is None:
    print(-1)
else:
    print(ans[0][1], ans[0][0])

#-----------------------------------------------------------------------------------------------------------------------

from heapq import heappop, heappush

n, m = map(int, input().split())

class Node:
    def __init__(self, value):
        self.value = value
        self.min_distance = float('inf')
        self.min_only_distance = float('inf')
        self.predecessor = None
        self.adjacent = []

    def __lt__(self, other):
        return self.min_distance < other.min_distance

    def __repr__(self):
        return f'Node(value={self.value}, min_distance={self.min_distance}, only_distance={self.min_only_distance})'

nodes = {}

for i in range(1, n + 1):
    nodes[i] = Node(value=i)

nodes[1].min_distance = 0
nodes[1].min_only_distance = 0

for _ in range(m):
    n1, n2, dangerous = map(int, input().split())

    if n1 == n2:
        continue

    nodes[n1].adjacent.append((nodes[n2], dangerous))

    nodes[n2].adjacent.append((nodes[n1], dangerous))

def dijkstra():
    q = []
    heappush(q, (nodes[1], 0))

    while q:
        curr_r, current_only_distance = heappop(q)

        for adj, dangerous_ in curr_r.adjacent:

            if adj.min_distance > curr_r.min_distance + dangerous_:
                adj.predecessor = curr_r
                adj.min_distance = curr_r.min_distance + dangerous_
                adj.min_only_distance = curr_r.min_only_distance + 1
                heappush(q, (adj, curr_r.min_only_distance + 1 + 1))

dijkstra()

if nodes[n].min_distance == float('inf'):
    print(-1)
else:
    print(nodes[n].min_distance, nodes[n].min_only_distance)

#-----------------------------------------------------------------------------------------------------------------------

n, m = map(int, input().split())

nodes = {}

for i in range(1, n + 1):
    nodes[i] = []

for _ in range(m):
    n1, n2, dangerous = map(int, input().split())

    if n1 == n2:
        continue

    nodes[n1].append((n2, dangerous))

    nodes[n2].append((n1, dangerous))

def dijkstra():
    danger_dists = [float('inf')] * (len(nodes) + 1)
    normal_dists = [float('inf')] * (len(nodes) + 1)
    danger_dists[1] = 0
    normal_dists[1] = 0

    q = [1]

    while q:
        curr_r = q.pop(0)
        for adj, dangerous_ in nodes[curr_r]:

            if adj.min_distance > curr_r.min_distance + dangerous_:
                adj.predecessor = curr_r
                adj.min_distance = curr_r.min_distance + dangerous_
                adj.min_only_distance = curr_r.min_only_distance + 1
                heappush(q, (adj, curr_r.min_only_distance + 1 + 1))

            if danger_dists[adj] > danger_dists[curr_r] + dangerous_:
                danger_dists[adj] = danger_dists[curr_r] + dangerous_
                normal_dists[adj] = normal_dists[curr_r] + 1
                q.append(adj)

    return danger_dists, normal_dists

danger_dists, normal_dists = dijkstra()

print(danger_dists[n], normal_dists[n])


import logging
import os
from utils.logger import create_loggers_helper

def create_logger():
    _logger = logging.getLogger(__name__)
    _logger.setLevel(logging.DEBUG)
    return create_loggers_helper(_logger)

logger = create_logger()

def serialization_object_decorate(
        serialize_function, deserialize_function):
    def serialization_with_arguments(func):
        def func_wrapper(*args, **kwargs):
            model_filename = kwargs["model_file_name"]
            overwrite_model = kwargs["overwrite"]
            if os.path.exists(model_filename) and overwrite_model is False:
                return deserialize_function(file_name=model_filename)
            result = func(*args, **kwargs)
            serialize_function(model_filename, result)
            return result

        return func_wrapper

    return serialization_with_arguments


import numpy as np
import pytest
from pytest import approx

from desdeov2.solver.ASF import (
    ASFError,
    AugmentedGuessASF,
    MaxOfTwoASF,
    PointMethodASF,
    ReferencePointASF,
    SimpleASF,
    StomASF,
)

def test_simple_init():
    weights_1 = np.array([1, 2, 3])
    simple_asf = SimpleASF(weights_1)
    weights_tmp = weights_1
    weights_1 = np.array([1, 2, 4])

    assert np.all(np.isclose(simple_asf.weights, weights_tmp))
    assert not np.all(np.isclose(simple_asf.weights, weights_1))

def test_simple_setter():
    weights_1 = np.array([1, 2, 3])
    simple_asf = SimpleASF(weights_1)
    weights_2 = np.array([1, 2, 4])

    assert np.all(np.isclose(simple_asf.weights, weights_1))
    assert not np.all(np.isclose(simple_asf.weights, weights_2))

    simple_asf.weights = weights_2

    assert np.all(np.isclose(simple_asf.weights, weights_2))
    assert not np.all(np.isclose(simple_asf.weights, weights_1))

def test_simple_call():
    weights = np.array([3, 4, 2])
    simple_asf = SimpleASF(weights)

    objective = np.array([1, 1, 2.5])
    reference = np.array([0.5, -2, 1.5])

    res = simple_asf(objective, reference)

    assert res == approx(12.0)

def test_simple_non_matching_shapes():
    weights = np.ones(3)
    simple_asf = SimpleASF(weights)

    objective = np.array([1, 1, 2.5])
    reference = np.array([0.5, -2, 1.5])

    objective2d = np.array([[1, 1, 1], [2, 2, 2]])
    reference2d = np.array([[1, 1, 1], [2, 2, 2]])

    with pytest.raises(ASFError):
        simple_asf(objective[:1], reference)

    with pytest.raises(ASFError):
        simple_asf(objective2d, reference)

    with pytest.raises(ASFError):
        simple_asf(objective, reference2d)

def test_reference_point_init():
    pref_facs = np.array([0.25, 0.5, 0.33, 0.4])
    nadir = np.array([50, 20, 30, 50])
    utopian = np.array([1.5, 8, 3, 7.2])

    asf = ReferencePointASF(pref_facs, nadir, utopian)

    assert np.all(np.isclose(asf.preferential_factors, pref_facs))
    assert np.all(np.isclose(asf.nadir, nadir))
    assert np.all(np.isclose(asf.utopian_point, utopian))

    assert asf.rho == approx(0.1)

    asf.rho = 5
    assert asf.rho == approx(5)

def test_reference_point_call():
    pref_facs = np.array([0.25, 0.5, 0.33, 0.4])
    nadir = np.array([50, 20, 30, 50])
    utopian = np.array([1.5, 8, 3, 7.2])
    rho = 0.2

    asf = ReferencePointASF(pref_facs, nadir, utopian, rho=rho)
    objective = np.array([10, 12, 15, 22])
    reference = np.array([22, 13, 20, 33])

    max_term = np.max(pref_facs * (objective - reference))
    sum_term = rho * np.sum((objective - reference) / (nadir - utopian))
    expected = max_term + sum_term

    res = asf(objective, reference)

    assert res == approx(expected)

def test_maxoftwo(four_dimenional_data_with_extremas):
    _, fs, nadir, ideal = four_dimenional_data_with_extremas
    reference = np.array([5.2, 0.5, 8.5, 2.3])
    asf = MaxOfTwoASF(nadir, ideal, [2, 3], [1])

    res = asf(fs, reference)
    assert np.all(
        np.isclose(res, [1.07353, 0.32653076, 0.93877678, 0.91176686])
    )

    res_single = asf(fs[1], reference)
    assert np.isclose(res_single, 0.32653076)

def test_stom(four_dimenional_data_with_extremas):
    _, fs, _, ideal = four_dimenional_data_with_extremas
    reference = np.array([5.2, 0.5, 8.5, 2.3])
    asf = StomASF(ideal)

    res = asf(fs, reference)
    assert np.all(
        np.isclose(res, [1.00000067, 1.52381026, 4.38095575, 1.76923358])
    )

    res_single = asf(fs[3], reference)
    assert np.isclose(res_single, 1.76923358)

def test_point_method(four_dimenional_data_with_extremas):
    _, fs, nadir, ideal = four_dimenional_data_with_extremas
    reference = np.array([5.2, 0.5, 8.5, 2.3])
    asf = PointMethodASF(nadir, ideal)

    res = asf(fs, reference)
    assert np.all(
        np.isclose(
            res,
            [7.53767183e-07, 1.12245068e-01, 7.24491094e-01, 4.02012319e-01],
        )
    )

    res_single = asf(fs[2], reference)
    assert np.isclose(res_single, 7.24491094e-01)

def test_augmented_guess(four_dimenional_data_with_extremas):
    xs, fs, nadir, ideal = four_dimenional_data_with_extremas
    reference = np.array([5.2, 0.5, 8.5, 2.3])
    asf = AugmentedGuessASF(nadir, ideal, [1, 3])

    res = asf(fs, reference)
    assert np.all(
        np.isclose(res, [-1.00001815, 11.79999576, 13.59999945, 1.1999892])
    )

    res_single = asf(fs[0], reference)
    assert np.isclose(res_single, -1.00001815)


__author__ = 'christopher simmons'
import numpy as np
from classes import Predictor

class MC_Perceptron(Predictor):
    def __init__(self, instances, high_idx):
        self.instances = instances
        self.high_idx = high_idx
        self.labels = []
        self.get_labels()
        self.weights = {k: [0 for _ in range(self.high_idx)] for k in self.labels}

    def train(self, instances):
        for instance in instances:
            input_x = self.get_feat_vec(instance._feature_vector.features)
            actual_lab = instance._label.label
            arg_max, pred_lab = 0, self.labels[0]
            for c in self.labels:
                act = np.dot(input_x, self.weights[c])
                if act > arg_max:
                    arg_max, pred_lab = act, c

            #print "Best Label", pred_lab, "Arg_Max", arg_max, "Actual", actual_lab
            #quit()
            if not(actual_lab == pred_lab):
                self.weights[actual_lab] = np.add(self.weights[actual_lab], input_x)
                neg = np.dot(-1, input_x)
                self.weights[pred_lab] = np.add(self.weights[pred_lab], neg)

    def predict(self, instance):
        #print "Weights", self.weights, "updated"
        #quit()
        input_x = self.get_feat_vec(instance._feature_vector.features)
        actual_lab = instance._label.label

        arg_max, pred_lab = 0, self.labels[0]
        for c in self.labels:
            act = np.dot(input_x, self.weights[c])
            if act >= arg_max:
                arg_max, pred_lab = act, c

        #print "pred_lab", pred_lab, "actual", actual_lab
        #quit()

        return pred_lab

    def get_labels(self):
        for instance in self.instances:
            actual_lab = instance._label.label
            if actual_lab not in self.labels: self.labels.append(actual_lab)

        self.labels = sorted(self.labels)
        #print "Labels", self.labels
        #quit()

    def get_feat_vec(self,feat_vec):
        x = [ 0 for j in range(self.high_idx)]
        for i in feat_vec: x[i-1] = feat_vec[i]
        return x


import numpy as np
import matplotlib.pyplot as plt
from numpy import pi
from scipy import interpolate,integrate
from tqdm import tqdm

class spectrum:
    def __init__(self, KT = [0.05, 2000], \
                 U10 = 5, x = 20170, spectrum_type = 'Karaev'):
        # ускорение свободного падения.
        self.g = 9.81
        # скорость ветра на высоте 10 м над уровнем моря.
        self.U10 = U10
        # коэффициент gamma (см. спектр JONSWAP)
        self.gamma = self.Gamma(x)
        # коэффициент alpha (см. спектр JONSWAP)
        self.alpha = self.Alpha(x)
        # координата пика спектра по частоте
        self.omega_m = self.Omega(x) * self.g/self.U10
        # координата пика спектра по волновому числу
        self.k_m = self.k_max( self.omega_m )
        # массив с границами моделируемого спектра.
        self.KT = np.array([self.k_m/4,self.k_m*500])
        KT = self.KT
        # k0 -- густая сетка, нужна для интегрирования и интерполирования
        self.k0= np.logspace(np.log10(self.KT[0]), np.log10(self.KT[-1]), 10**4)

        # интерполируем смоделированный спектр
        self.spectrum = self.interpolate()
        self.sigma_sqr = integrate.quad(self.spectrum, KT[0],KT[-1])[0]

    def find_decision(self,omega):
        P = 9.8 * 1000.0/0.074
        Q = -1000.0*omega**2/0.074
        x1= -Q/2.0 + np.sqrt( (Q/2)**2 + (P/3)**3)
        x2= -Q/2.0 - np.sqrt( (Q/2)**2 + (P/3)**3)
        k=x1**(1/3)-(-x2)**(1/3)
        return k

    def det(self,k):
    #        Функция возвращает Якобиан при переходе от частоты к
    #    волновым числам по полному дисперсионному уравнению
        det=(self.g+3*k**2*0.074/1000)/(2*np.sqrt(self.g*k+k**3*0.074/1000) )
        return det

    def k_max(self,omega_max):
        # k_max -- координата пика спектра
        k_max=omega_max**2/self.g
        return k_max

    def omega_k(self,k):
        #    Пересчет волнового числа в частоту по полному дисперсионному
        # уравнению
        omega_k=(self.g*k+0.074*k**3/1000)**(1/2)
        return omega_k

    def JONSWAP(self,k):
        if k<=self.k_m:
            sigma=0.074
        else:
            sigma=0.09
        Sw=(
            self.alpha/2*k**(-3)*np.exp(-1.25*(self.k_m/k)**2 )*
            self.gamma**(np.exp(- ( np.sqrt(k/self.k_m)-1)**2 / (2*sigma**2) ))
           )
        return Sw

    # Безразмерный коэффициент Gamma
    def Gamma(self,x):
        if x>=20170:
            return 1
        gamma = (
               +5.253660929
               +0.000107622*x
               -0.03778776*np.sqrt(x)
               -162.9834653/np.sqrt(x)
               +253251.456472*x**(-3/2)
                )
        return gamma

    # Безразмерный коэффициент Alpha
    def Alpha(self,x):
        if x >= 20170:
            return 0.0081
        alpha = np.array( [],dtype = 'float64')
        alpha = [(
               +0.0311937
               -0.00232774 * np.log(x)
               -8367.8678786/x**2
               +4.5114599e+300*np.exp(-x)*1e+300*1e+17
    #            +4.5114599e+17*exp(-x)
              )]
        return alpha[0]

    #Вычисление безразмерной частоты Omega по безразмерному разгону x
    def Omega(self,x):
        if x>=20170:
            return 0.835
        omega_tilde=(0.61826357843576103
                     + 3.52883010586243843e-06*x
                     - 0.00197508032233982112*np.sqrt(x)
                     + 62.5540113059129759/np.sqrt(x)
                     - 290.214120684236224/x
        )
        return omega_tilde

    def spectrum0(self,n,k,spectrum_type = 'Karaev'):
        if spectrum_type == 'Karaev':
            power = [0,4,5,2.7,5]
        if n==0:
            return self.JONSWAP(k)
        else:
            omega0 = self.omega_k(self.limit_k[n-1])
            beta0  = self.spectrum0(n-1,self.limit_k[n-1]) * \
                        omega0**power[n]/self.det(self.limit_k[n-1])
            omega0 = self.omega_k(k)
            return beta0/omega0**power[n]*self.det(k)

    def full_spectrum(self,k,x=20170):
        #    Спектр JONSWAP.
        #    По совместительству, граница моделируюмого спектра #0
        # 0< omega < 1.2*omega_max
        # См. функции spectrum_{1-4}(k).
        # limit_{1-4} -- это соответствующие границы
        self.limit_1 = 1.2
        self.limit_2 =(
                 + 0.371347584096022408
                 + 0.290241610467870486 * self.U10
                 + 0.290178032985796564 / self.U10
                     )
        self.limit_3 = self.omega_k(270.0)
        self.limit_4 = self.omega_k(1020.0)
        self.limit_k = np.zeros(4)
        self.limit_k[0] = self.find_decision(self.limit_1 * self.omega_m)
        self.limit_k[1] = self.find_decision(self.limit_2 * self.omega_m)
        self.limit_k[2] = 270.0
        self.limit_k[3] = 1020.0
        try:
            full_spectrum = np.zeros(len(k))
        except:
            full_spectrum = [0]
            k = [k]

        for i in range(len(k)):
            if k[i] <= self.limit_k[0]:
                full_spectrum[i] =  self.spectrum0(0,k[i])
            elif k[i] <= self.limit_k[1]:
                full_spectrum[i] = self.spectrum0(1,k[i])
            elif k[i] <= self.limit_k[2]:
                full_spectrum[i] = self.spectrum0(2,k[i])
            elif k[i] <= self.limit_k[3]:
                full_spectrum[i] = self.spectrum0(3,k[i])
            else:
                full_spectrum[i] = self.spectrum0(4,k[i])
        return full_spectrum

    def interpolate(self):
        # Интерполируем наш спектр.
        # Позволяет не думать над различными размерами массивов при счете
        full_spectrum = interpolate.interp1d(self.k0,
                                             self.full_spectrum(self.k0))
        return full_spectrum

class whitening():
# Экспериментальный способ. Метод <<отбеливания>> спектра
    def interspace(self, k, N, power=2):
        #     Функция разбивает заданный k-интервал на N участков, в каждом
        # из которых интеграл по спектру принимает одно и тоже значение.
        full_spectrum=self.get_full_spectrum()
        y = lambda k: full_spectrum(k)*k**power
        sigma = self.sigma_sqr
        b0 = sigma/(N)
        k_new = k[0]
        k_end = k[-1]
        k = np.zeros(N+1)
        k[0] = k_new
#        err = np.zeros(N)
        epsabs = 1.49e-8
#        epsrel = 1.49e-8
        progress_bar = tqdm(total = N-1 )
        for i in range(N-1):
            integral = 0
            n = 1
            m = 1
            while integral < b0:
                k_new*= 1 + 10**(-m)
                integral,error = integrate.quad(y, k[i], k_new)
                if integral> b0 and abs(integral-b0) > epsabs:
                    k_new*= 1 - 10**(-m)
                    m+= 1
                    integral, error = integrate.quad(y, k[i], k_new)
                n+= 1
            progress_bar.update(1)
            k[i+1] = k_new
        k = k[0:N+1]
        k[-1] = k_end
        # Возвращает k размерности N+1, т.о. имеем как раз N интервалов.
        # err -- ошибка вычисения интегралов
        progress_bar.close()
        return k

    def nodes(self,ki, power=2):
        # Функции interspace и nodes используются последовательно.
        # Первая возвращает интервалы, а вторая вычисляет в возвращенных
        # интервалах координаты узлов
        sigma = self.sigma_sqr
        b0 = sigma/(N)
        progress_bar = tqdm(total = len(ki)-1)
        full_spectrum=self.get_full_spectrum()

        y=lambda k: k**(2+power)*full_spectrum(k)

        nodes=np.zeros(len(ki))
        A=np.sqrt(2*b0)

        for i in range(1,len(ki)):
            integral,error=integrate.quad(y,ki[i-1],ki[i])
            B=(np.sqrt(integral/A**2))
            nodes[i-1]=B
            progress_bar.update(1)

        return nodes[:-1]

class surface:
    def __init__(self,N=256, M=80, space='log',phi_optimize=0,
                 random_phases = 1):
#        water()
        self.M = M
        self.N = N
        KT = self.KT
        if space =='log':
            self.k_log = np.logspace(np.log10(KT[0]), np.log10(KT[-1]),N)
            self.k = self.k_log
        elif space =='lin':
            self.k_lin = np.linspace(KT[0], KT[-1], N)
            self.k = self.k_lin
#        elif space=='white':
#            ki,b0=self.interspace(self.k0,N)
#            self.k=nodes(ki,b0)

        if phi_optimize == 0:
            self.M = M
            self.phi=np.linspace(-pi,pi,self.M)

        # случайные фазы
        if random_phases == 0:
            self.psi = np.array([
                    [0 for m in range(self.M) ] for n in range(self.N) ])
        elif random_phases == 1:
            self.psi = np.array([
                [ np.random.uniform(0,2*pi) for m in range(self.M)]
                            for n in range(self.N) ])
        # массив с амплитудами i-ой гармоники
        self.A = self.amplitude(self.k)
        # угловое распределение
        self.F = self.angle(self.k,self.phi)

        water.k = self.k
    def B(self,k):
          def b(k):
              b=(
                  -0.28+0.65*np.exp(-0.75*np.log(k/self.k_m))
                  +0.01*np.exp(-0.2+0.7*np.log10(k/self.k_m))
                )
              return b
          B=10**b(k)
          return B
    # Перепиши ради христа эту фигню. Не читабельно
    def Phi(self,k,phi):
        # Функция углового распределения
        N = self.N
        M = self.M
        normalization = lambda B: B/np.arctan(np.sinh(2*pi*B))
        B0 = self.B(k)
        A0 = normalization(B0)
        try:
            Phi = [[ A0[i]/np.cosh(2*B0[i]*phi[j]) for j in range(M) ] for i in range(N)]
            Phi=np.array(Phi)
        except:
            Phi = A0/np.cosh(2*B0*phi)
        return Phi

    def angle(self,k,phi):
        N, M = self.N, self.M
        Phi = self.Phi(k,phi)
        dphi = np.array([phi[j] - phi[j-1]  for j in range(1,M) ] )
        dF = np.delete(Phi,0,1)
        F = ([ [np.sqrt(dF[n][m]*dphi[m]) for m in range(M-1)]
                                            for n in range(N) ])
        for i in range(N):
                F[i].append(0)
        F=np.array(F)
        return F

    def amplitude(self, k):
        N = len(k)
        S = self.spectrum
        integral = np.array([ integrate.quad(S,k[i-1],k[i])[0] for i in range(1,N) ])
        print(integral)
        amplitude = np.sqrt(2 *integral )
        amplitude = np.concatenate((amplitude,[0]))
        return amplitude

    def model(self, k, phi,time=[0]):
        def water(r,t):
            N = self.N
            M = self.M

            A = self.A
            F = self.F
            psi = self.psi
            self.surface = 0
            progress_bar = tqdm( total = N*int(np.mean(M)),  leave = False )
#            progress_bar.set_description("Processing %s" % t)
            for n in range(N):
                for m in range(M):
                  self.surface += A[n] * \
                  np.cos(
                      +k[n]*(r[0]*np.cos(phi[m])+r[1]*np.sin(phi[m]))
                      +psi[n][m]
                      +self.omega_k(k[n])*t) \
                      * F[n][m]
                  progress_bar.update(1)
            progress_bar.close()
            progress_bar.clear()

            return self.surface
        return water

class correlation:
    def angles(self,rho):
        try:
            return self.correlation_slopes(rho)
        except:
            progress_bar=tqdm(total = len(rho) + 1)
            progress_bar.set_description("Вычисление функции корреляции")
            k= np.logspace(np.log10(self.KT[0]), np.log10(self.KT[-1]), 5*10**5)
            integral=np.zeros(len(rho))
            y=lambda k: k**2*self.spectrum(k)
            for i in range(len(rho)):
                integral[i]=np.trapz(y(k)*np.cos(k*rho[i]),x=k)
                progress_bar.update(1)
            progress_bar.set_description("Сохранение функции корреляции")
            self.correlation_slopes = interpolate.interp1d(rho,integral)
            progress_bar.update(1)
            progress_bar.close()
            return integral

    def angles_sum(self,k,rho):
        f=0
        A=self.amplitude(k)
        f=np.zeros(len(rho))
        for j in range(len(rho)):
                f[j]=sum( k**2*A**2/2*np.cos(k*rho[j]) )
        return f

    def height_restore(self, rho, k, fourier = 'real'):
        if fourier == 'real':
            self.K=self.height(rho,k)
            integral=np.zeros(len(k))
            for i in range(len(k)):
                integral[i]=integrate.simps(self.K*np.cos(k[i]*rho),x=rho)
            return integral/np.sqrt(np.pi)

        elif fourier == 'complex':
            self.K=self.height(rho,k,'complex')
            integral=np.fft.ifft(self.K,n=k.size)
            return integral.real

    def height(self,rho,k, fourier = 'real'):
        if fourier == 'real':
            S=self.spectrum(k)
            integral=np.zeros(len(rho))
            for i in range(len(rho)):
                integral[i]=np.trapz(S*np.cos(k*rho[i]),x=k)
            self.correlation_height = interpolate.interp1d(rho,integral)
            return integral/max(integral)

        if fourier == 'complex':
            S=self.spectrum(k)
            integral=np.fft.fft(S,n=k.size)
            return integral
    def height_sum(self,k,rho):
        f=0
        A=self.amplitude(k)
        f=np.zeros(len(rho))
        for j in range(len(rho)):
                f[j]=sum( A**2/2*np.cos(k*rho[j]) )
        return f

    def height_sum1(self,k,rho):
        f=0
        A=self.amplitude(k)
        f=np.zeros(len(rho))
        for j in range(len(rho)):
                f[j]=sum(A)/2*sum( A*np.cos(k*rho[j]) )
        return f
    ################################################3
    def sigma(self,k,phi):
        F = self.spectrum(k) *  self.Phi(k,phi)
        return F

    def sigma_xx(self,k,phi):
        pass
        F = self.spectrum(k) * ( k*np.cos(phi) )**2 * self.Phi(k,phi)
        return F

    def sigma_yy(self,k,phi):
        pass
        F = self.spectrum(k) * ( k*np.cos(phi) )**2 * self.Phi(k,phi)
        return F

    def sigma_ttx(self,k,phi):
        pass
        F = self.spectrum(k) * ( self.omega_k(k) * np.cos(phi) )**2 * self.Phi(k,phi)
        return F
    def sigma_tty(self,k,phi):
        pass
        F = self.spectrum(k) * ( self.omega_k(k) * np.sin(phi) )**2 * self.Phi(k,phi)
        return F
    def sigma_tt(self,k,phi):
        pass
        F = self.spectrum(k) * ( self.omega_k(k) )**2 * self.Phi(k,phi)
        return F
    def sigma_tx(self,k,phi):
        pass
        F = self.spectrum(k) * ( self.omega_k(k) * k* np.cos(phi) ) * self.Phi(k,phi)
        return F
    def sigma_ty(self,k,phi):
        pass
        F = self.spectrum(k) * ( self.omega_k(k) * k* np.sin(phi) ) * self.Phi(k,phi)
        return F

    def sigma_xy(self,k,phi):
        pass
        F = self.spectrum(k) *  k**2 * np.sin(phi) * np.cos(phi)  * self.Phi(k,phi)
        return F
    ###################################################
    #
class water(spectrum,correlation,surface):
    # Этот класс содержит некоторые инструменты для работы с моделью
    def __init__(self,N=256, M = 256, KT=[0.05,2000]):
        self.x=np.linspace(0,200,200)
        self.x0 = np.linspace(0,2000,10**5)
        self.y=np.linspace(0,200,200)
        self.y0 = [0]
        self.t=np.array([0])
        self.N=N
        self.M=M
        self.KT=np.array(KT)
        spectrum.__init__(self,KT=self.KT)
        surface.__init__(self,N=self.N,M=self.M)
        self.rho=np.linspace(0,100,1000)
        self.rho0=np.linspace(0,100,self.k0.size)

    def plot(self,fig):
        plt.figure()
        if fig=='slopes' or fig=='s':
            self.plot_slopes(self.k0)
        elif fig=='heights' or fig=='h':
            self.plot_heights(self.k0)
        elif fig=='correlation slopes' or fig=='cs':
            self.plot_correlation_slopes(self.rho)
        elif fig=='correlation heights' or fig=='ch':
            self.plot_correlation_heights(self.rho)
        elif fig=='surface':
            self.plot_surface(self.x,self.y,self.t)

    def plot_correlation_slopes(self,rho):
        plt.plot(self.rho,self.angles(self.rho))
        plt.ylabel(r'$K_q(\rho)$',fontsize=16)
        plt.xlabel(r'$\rho$',fontsize=16)

    def plot_correlation_heights(self,rho):
        plt.plot(self.rho,self.height(self.rho,self.k0))
        plt.ylabel(r'$K(\rho)$',fontsize=16)
        plt.xlabel(r'$\rho$',fontsize=16)

    def plot_heights(self,k):
        plt.loglog(self.k0,self.spectrum(self.k0))
        plt.ylabel(r'$S_q(k)=S(k)k^2$',fontsize=16)
        plt.xlabel(r'$k$',fontsize=16)

    def plot_slopes(self,k):
        plt.loglog(self.k0,self.k0**2*self.spectrum(self.k0))
        plt.ylabel(r'$S(k)$',fontsize=16)
        plt.xlabel(r'$k$',fontsize=16)

    def plot_sigma(self):
        phi=np.linspace(-pi,pi,10*3)
        plt.polar(phi, self.sigma(self.k0[9000],phi))

    def plot_surface(self, x , y, t):
        surface = self.model(self.k, self.phi, t)
        x, y = np.meshgrid(x, y)
        self.z=surface([x,y],t)
        from matplotlib.cm import winter
        plt.contourf(self.z,100,cmap=winter)
        plt.colorbar()
        plt.ylabel(r'Y, \text{м}',fontsize=16)
        plt.xlabel(r'X, \text{м}',fontsize=16)

    def plot_restore(self,fourier='real'):
        rho=self.rho
        k=self.k0
        plt.loglog(k,self.spectrum(k),label='Исходный спектр')
        plt.loglog(self.k,self.height_restore(rho,self.k,fourier),label='Восстановленный спектр')
        plt.legend()
#    def plot_restore1(self):
#        rho=self.rho0
#        k=self.k0
#        plt.plot(rho,self.height(rho,k,'real'),label='Вещественный')
#        plt.plot(rho,self.height(rho,k,'complex'),label='Комплексный')
#        plt.legend()
        #   savefig(path.abspath('..'+'\\water\\anim\\'+'water'+str(i)+'.png'),
        #             pdi=10**6,bbox_inches='tight')
#        show()
# plt.loglog(water.k0,water.full_spectrum(water.k0))
water = water()
water.plot('surface')
plt.show()


# -*- coding: utf-8 -*-

from __future__ import absolute_import
from quixote.errors import TraversalError
from vilya.models.project import CodeDoubanProject

class ArchiveUI(object):
    _q_exports = []

    def __init__(self, proj_name):
        project = CodeDoubanProject.get_by_name(proj_name)
        self.project = project

    def _q_lookup(self, request, part):
        repo = self.project.repo
        sha = repo.sha(part)
        if not sha:
            raise TraversalError
        ext = request.get_form_var('ext')
        if ext == 'tar':
            request.response.set_content_type("application/x-tar")
            request.response.set_header("Content-Disposition",
                                        "filename=%s.tar" % part)
            return repo.archive(part, ref=sha, ext=ext)
        elif ext == 'tar.gz':
            request.response.set_content_type("application/x-gzip")
            request.response.set_header("Content-Disposition",
                                        "filename=%s.tar.gz" % part)
            return repo.archive(part, ref=sha)
        request.response.set_content_type("application/x-gzip")
        request.response.set_header("Content-Disposition",
                                    "filename=%s.tar.gz" % part)
        return repo.archive(part, ref=sha)


from django.urls import path
from station import views

urlpatterns = [
    path('list',views.StationView.as_view(),name='station_home'),
    path('upload_file',views.model_form_upload,name='upload_file'),
    path('audio_list',views.StationAudioView.as_view(),name='station_audio_home'),
    path('upload_audio_list',views.model_form_audio_upload,name='upload_audio_file'),
]


from src.persons import (
    get_persons,
    post_persons,
    get_person,
    delete_persons,
)
from src.vaccines import (
    get_vaccines,
    post_vaccines,
    patch_vaccines,
    delete_vaccine,
)
from src.models import Person, Vaccine

def main():
    scores = []

    persons = [
        Person('Javier Fernandez'),
        Person('Laura Alcocer'),
    ]

    vaccines = [
        Vaccine('SINOVAC', '2022-01-20'),
        Vaccine('SINOVAC', '2022-07-20'),
        Vaccine('Pfizer', '2022-05-09'),
    ]

    update = [
        {'vaccine': {'vaccine_date': '2022-01-01'}}
    ]

    # 1
    scores.append(delete_persons())

    # 2
    scores.append(post_persons(persons[0]))

    # 3
    scores.append(post_persons(persons[1]))

    # 4
    scores.append(get_persons(persons))

    # 5
    scores.append(get_person(persons[0]))

    # 6
    scores.append(get_person(persons[1]))

    # 7
    scores.append(post_vaccines(persons[0], vaccines[0]))

    # 8
    scores.append(post_vaccines(persons[0], vaccines[1]))

    # 9
    scores.append(post_vaccines(persons[1], vaccines[2]))

    # 10
    scores.append(get_vaccines(persons[0]))

    # 11
    scores.append(get_vaccines(persons[1]))

    # 12
    scores.append(patch_vaccines(
        persons[0],
        persons[0].vaccines[0],
        update[0]
    ))

    # 13
    scores.append(delete_vaccine(persons[0], persons[0].vaccines[0]))

    # Score
    for i, score in enumerate(scores):
        print(f'{i + 1:02d} - {score}/3')

    print(f'Total: {sum(scores)}/{len(scores) * 3}')

if __name__ == '__main__':
    main()


import logging
import time

import boto3
from botocore.config import Config
from crhelper import CfnResource

helper = CfnResource(json_logging=False, log_level="INFO", boto_level="ERROR", sleep_on_delete=0)
logger = logging.getLogger(__name__)
boto3_config = Config(retries={"max_attempts": 60})

@helper.create
@helper.delete
def no_op(_, __):
    pass

@helper.update
def update(event, _):
    updated_config_version = event["ResourceProperties"]["ConfigVersion"]
    logging.info("Updated config version: %s", updated_config_version)
    table_name = event["ResourceProperties"]["DynamoDBTable"]
    dynamodb_table = boto3.resource("dynamodb").Table(table_name)
    current_config_version = None
    while updated_config_version != current_config_version:
        try:
            logging.info("Waiting for config version to be updated")
            cluster_config_item = dynamodb_table.get_item(ConsistentRead=True, Key={"Id": "CLUSTER_CONFIG"})
            if cluster_config_item and "Item" in cluster_config_item:
                current_config_version = cluster_config_item["Item"].get("Version")
                logger.info("Current config version: %s", current_config_version)
            time.sleep(30)
        except Exception as e:
            logging.exception(e)

def handler(event, context):
    helper(event, context)


class Solution:
    def minimumRecolors(self, blocks: str, k: int) -> int:
        n = len(blocks)
        res = float('inf')
        for i in range(n - k + 1):
            ctr = 0
            for j in range(i, i + k):
                if blocks[j] == "W":
                    ctr += 1
            res = min(res, ctr)
        return res


import mxnet as mx
import numpy as np
from mxnet import gluon
from mxnet.gluon import data as gdata, loss as gloss, nn
from mxnet.gluon import nn, Block, HybridBlock, Parameter
import mxnet.ndarray as F
import utilities
import os

class LossNet(Block):
    def __init__(self, vgg, content_weight, style_weight, batch_size, loss=gluon.loss.L2Loss()):
        super(LossNet, self).__init__()
        self.vgg = vgg
        self.content_weight = content_weight
        self.style_weight = style_weight
        self.batch_size = batch_size
        self.loss = loss

    def forward(self, original_img, generated_img):
        # normalization:
        x = utils.subtract_img_mean_batch(original_img)
        y = utils.subtract_img_mean_batch(generated_img)

        features_x = self.vgg(x)
        features_y = self.vgg(y)

        gram_style = [self.gram_matrix(feature) for feature in featured_x]

        # compute content loss:
        vgg_x = features_x[1]
        content_loss = self.content_weight * self.loss(features_y[1], vgg_x)

        # compute style loss:
        style_loss = 0.0
        for m in range(len(features_y)):
            gram_y = self.gram_matrix(features_y[m])
            _, C, _ = gram_y[m].shape
            gram_s = F.expand_dims(gram_style[m], 0).broadcast_to((self.batch_size, 1, C, C))
            style_loss += self.style_weight * self.loss(gram_y, gram_s[:self.batch_size, :, :])
        return content_loss + style_loss

    def gram_matrix(self, x):
        (b, ch, h, w) = x.shape
        features = x.reshape((b, ch, w*h))
        return F.batch_dot(features, features, transpose_b=True) / (ch*h*w)

class Vgg16(Block):
    def __init__(self):
        super(Vgg16, self).__init__()
        self.conv1_1 = nn.Conv2D(in_channels=3, channels=64, kernel_size=3, strides=1, padding=1)
        self.conv1_2 = nn.Conv2D(in_channels=64, channels=64, kernel_size=3, strides=1, padding=1)

        self.conv2_1 = nn.Conv2D(in_channels=64, channels=128, kernel_size=3, strides=1, padding=1)
        self.conv2_2 = nn.Conv2D(in_channels=128, channels=128, kernel_size=3, strides=1, padding=1)

        self.conv3_1 = nn.Conv2D(in_channels=128, channels=256, kernel_size=3, strides=1, padding=1)
        self.conv3_2 = nn.Conv2D(in_channels=256, channels=256, kernel_size=3, strides=1, padding=1)
        self.conv3_3 = nn.Conv2D(in_channels=256, channels=256, kernel_size=3, strides=1, padding=1)

        self.conv4_1 = nn.Conv2D(in_channels=256, channels=512, kernel_size=3, strides=1, padding=1)
        self.conv4_2 = nn.Conv2D(in_channels=512, channels=512, kernel_size=3, strides=1, padding=1)
        self.conv4_3 = nn.Conv2D(in_channels=512, channels=512, kernel_size=3, strides=1, padding=1)

        self.conv5_1 = nn.Conv2D(in_channels=512, channels=512, kernel_size=3, strides=1, padding=1)
        self.conv5_2 = nn.Conv2D(in_channels=512, channels=512, kernel_size=3, strides=1, padding=1)
        self.conv5_3 = nn.Conv2D(in_channels=512, channels=512, kernel_size=3, strides=1, padding=1)

        self.dense1 = nn.Dense()

    def forward(self, X):
        h = F.Activation(self.conv1_1(X), act_type='relu')
        h = F.Activation(self.conv1_2(h), act_type='relu')
        relu1_2 = h
        h = F.Pooling(h, pool_type='max', kernel=(2, 2), stride=(2, 2))

        h = F.Activation(self.conv2_1(h), act_type='relu')
        h = F.Activation(self.conv2_2(h), act_type='relu')
        relu2_2 = h
        h = F.Pooling(h, pool_type='max', kernel=(2, 2), stride=(2, 2))

        h = F.Activation(self.conv3_1(h), act_type='relu')
        h = F.Activation(self.conv3_2(h), act_type='relu')
        h = F.Activation(self.conv3_3(h), act_type='relu')
        relu3_3 = h
        h = F.Pooling(h, pool_type='max', kernel=(2, 2), stride=(2, 2))

        h = F.Activation(self.conv4_1(h), act_type='relu')
        h = F.Activation(self.conv4_2(h), act_type='relu')
        h = F.Activation(self.conv4_3(h), act_type='relu')
        relu4_3 = h

        return [relu1_2, relu2_2, relu3_3, relu4_3]

    def init_vgg_params(self, model_folder, ctx, fixed_params=True):
        if not os.path.exists(os.path.join(model_folder, 'mxvgg.params')):
            os.system('wget https://www.dropbox.com/s/7c92s0guekwrwzf/mxvgg.params?dl=1 -O' + os.path.join(model_folder,
                                                                                'mxvgg.params'))
        self.collect_params().load(os.path.join(model_folder, 'mxvgg.params'), ctx=ctx)
        for param in self.collect_params().values():
            if fixed_params:
                param.grad_req = 'null'
            else:
                param.grad_req = 'write'


import os
import subprocess

from parameterized import parameterized
from sflkitlib.events import event

from sflkit import instrument_config
from sflkit.config import Config
from sflkit.mapping import EventMapping
from utils import BaseTest

class EventTests(BaseTest):
    def test_lines(self):
        config = Config.create(
            path=os.path.join(self.TEST_RESOURCES, self.TEST_LINES),
            language="python",
            events="line",
            working=self.TEST_DIR,
        )
        instrument_config(config)

        subprocess.run([self.PYTHON, self.ACCESS], cwd=self.TEST_DIR)

        events = event.load(
            os.path.join(self.TEST_DIR, self.TEST_PATH),
            EventMapping.load(config).mapping,
        )
        self.assertEqual(3, len(events))
        for i, e in enumerate(events):
            self.assertIsInstance(e, event.LineEvent, f"{e} is not a line event")
            self.assertEqual(self.ACCESS, e.file, f"{e} has not correct file")
            self.assertEqual(i + 1, e.line, f"{e} has not correct line")

    def test_branches(self):
        config = Config.create(
            path=os.path.join(self.TEST_RESOURCES, self.TEST_BRANCHES),
            language="python",
            events="line,branch",
            working=self.TEST_DIR,
        )
        instrument_config(config)

        subprocess.run([self.PYTHON, self.ACCESS], cwd=self.TEST_DIR)

        events = event.load(
            os.path.join(self.TEST_DIR, self.TEST_PATH),
            EventMapping.load(config).mapping,
        )
        self.assertEqual(5, len(events))
        lines = [1, 4, 5]
        line_i = 0
        first_branch = True
        branch_lines = [1, 4]
        branch_i = 0
        for e in events:
            if e.event_type == event.EventType.LINE:
                self.assertIsInstance(e, event.LineEvent, f"{e} is not a line event")
                self.assertEqual(self.ACCESS, e.file, f"{e} has not correct file")
                self.assertEqual(lines[line_i], e.line, f"{e} has not correct line")
                line_i += 1
            elif e.event_type == event.EventType.BRANCH:
                self.assertIsInstance(
                    e, event.BranchEvent, f"{e} is not a condition event"
                )
                e: event.BranchEvent
                self.assertEqual(self.ACCESS, e.file, f"{e} has not correct file")
                self.assertEqual(
                    branch_lines[branch_i], e.line, f"{e} has not correct line"
                )
                if first_branch:
                    self.assertGreater(
                        e.then_id, e.else_id, f"{e} has not correct branch ids"
                    )
                else:
                    self.assertLess(
                        e.then_id, e.else_id, f"{e} has not correct branch ids"
                    )
                first_branch = False
                branch_i += 1

    @staticmethod
    def _test_events(events):
        config = Config.create(
            path=os.path.join(BaseTest.TEST_RESOURCES, "test_events"),
            language="python",
            events=events,
            working=BaseTest.TEST_DIR,
        )
        instrument_config(config)

        subprocess.run([BaseTest.PYTHON, BaseTest.ACCESS], cwd=BaseTest.TEST_DIR)
        return event.load(
            os.path.join(BaseTest.TEST_DIR, BaseTest.TEST_PATH),
            EventMapping.load(config).mapping,
        )

    def test_function(self):
        events = self._test_events("function_enter,function_exit")
        self.assertEqual(24, len(events))
        function_enter = list(
            zip(
                [9, 2, 9, 2, 5, 5, 5, 5, 5, 9, 2, 5],
                [
                    "a",
                    "__init__",
                    "a",
                    "__init__",
                    "a",
                    "a",
                    "a",
                    "a",
                    "a",
                    "a",
                    "__init__",
                    "a",
                ],
            )
        )
        function_enter_i = 0
        function_exit = list(
            zip(
                [2, 13, 2, 6, 6, 6, 6, 6, 13, 2, 6, 13],
                [
                    "__init__",
                    "a",
                    "__init__",
                    "a",
                    "a",
                    "a",
                    "a",
                    "a",
                    "a",
                    "__init__",
                    "a",
                    "a",
                ],
                [None, 0, None, 8, 12, 16, 20, 24, 24, None, 2, 2],
            )
        )
        function_exit_i = 0
        for e in events:
            if e.event_type == event.EventType.FUNCTION_ENTER:
                line, function = function_enter[function_enter_i]
                self.assertIsInstance(
                    e, event.FunctionEnterEvent, f"{e} is not a line event"
                )
                e: event.FunctionEnterEvent
                self.assertEqual(BaseTest.ACCESS, e.file, f"{e} has not correct file")
                self.assertEqual(line, e.line, f"{e} has not correct line")
                self.assertEqual(function, e.function, f"{e} has not correct function")
                function_enter_i += 1
            elif e.event_type == event.EventType.FUNCTION_EXIT:
                line, function, value = function_exit[function_exit_i]
                self.assertIsInstance(
                    e, event.FunctionExitEvent, f"{e} is not a line event"
                )
                e: event.FunctionExitEvent
                self.assertEqual(BaseTest.ACCESS, e.file, f"{e} has not correct file")
                self.assertEqual(line, e.line, f"{e} has not correct line")
                self.assertEqual(function, e.function, f"{e} has not correct function")
                self.assertEqual(value, e.return_value, f"{e} has not correct function")
                function_exit_i += 1

    def test_branch(self):
        events = self._test_events("branch")
        self.assertEqual(12, len(events))
        branches = list(
            zip(
                [11, 16, 11, 11, 11, 11, 11, 11, 11, 11, 18, 25],
                [1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 0],
            )
        )
        branches_i = 0
        for e in events:
            if e.event_type == event.EventType.BRANCH:
                line, mod = branches[branches_i]
                self.assertIsInstance(e, event.BranchEvent, f"{e} is not a line event")
                e: event.BranchEvent
                self.assertEqual(BaseTest.ACCESS, e.file, f"{e} has not correct file")
                self.assertEqual(line, e.line, f"{e} has not correct line")
                if mod < 0:
                    self.assertLess(
                        e.then_id,
                        e.else_id,
                        f"{e} has not correct branch ids",
                    )
                elif mod > 0:
                    self.assertGreater(
                        e.then_id,
                        e.else_id,
                        f"{e} has not correct branch ids",
                    )
                else:
                    self.assertEqual(-1, e.else_id, f"{e} has not correct branch ids")
                    self.assertLessEqual(
                        0, e.then_id, f"{e} has not correct branch ids"
                    )
                branches_i += 1

    def test_loop(self):
        events = self._test_events("loop_begin,loop_hit,loop_end")
        self.assertEqual(12, len(events))
        expected_loop = [
            (event.EventType.LOOP_BEGIN, 11),
            (event.EventType.LOOP_END, 11),
            (event.EventType.LOOP_BEGIN, 11),
            (event.EventType.LOOP_HIT, 11),
            (event.EventType.LOOP_HIT, 11),
            (event.EventType.LOOP_HIT, 11),
            (event.EventType.LOOP_HIT, 11),
            (event.EventType.LOOP_HIT, 11),
            (event.EventType.LOOP_END, 11),
            (event.EventType.LOOP_BEGIN, 11),
            (event.EventType.LOOP_HIT, 11),
            (event.EventType.LOOP_END, 11),
        ]
        for e, expected in zip(events, expected_loop):
            type_, line = expected
            self.assertEqual(type_, e.event_type, f"{e} is not of type {type_}")
            self.assertIsInstance(
                e,
                event.event_mapping[type_],
                f"{e} is not a {event.event_mapping[type_]}",
            )
            self.assertEqual(BaseTest.ACCESS, e.file, f"{e} has not correct file")
            self.assertEqual(line, e.line, f"{e} has not correct line")
            # noinspection PyUnresolvedReferences
            self.assertEqual(0, e.loop_id, f"{e} has not correct loop id")

    def test_def_use(self):
        events = self._test_events("def,use")
        loop = [
            # loop
            (event.EventType.DEF, 11, "i", None),
            (event.EventType.USE, 12, "b", None),
            (event.EventType.USE, 12, "d", None),
            (event.EventType.USE, 12, "d.a", None),
            # A.a
            (event.EventType.DEF, 5, "b", None),
            (event.EventType.USE, 6, "self", None),
            (event.EventType.USE, 6, "self.b", None),
            (event.EventType.USE, 6, "b", None),
            (event.EventType.DEF, 12, "d.b", None),
        ]

        def get_a(b, c, result):
            return (
                [
                    # a
                    (event.EventType.DEF, 9, "b", b),
                    (event.EventType.DEF, 9, "c", c),
                    (event.EventType.USE, 10, "b", None),
                    (event.EventType.USE, 10, "A", None),
                    # A.__init__
                    (event.EventType.DEF, 2, "b", b),
                    (event.EventType.USE, 3, "b", None),
                    (event.EventType.DEF, 3, "self.b", b),
                    (event.EventType.DEF, 10, "d", None),
                    (event.EventType.USE, 11, "c", None),
                    (event.EventType.USE, 11, "range", None),
                ]
                + loop * c
                + [
                    (event.EventType.USE, 13, "d", result),
                    (event.EventType.USE, 13, "d.b", result),
                ]
            )

        expected_def_uses = (
            [(event.EventType.USE, 16, "a", None)]
            + get_a(0, 0, 0)
            + [
                (event.EventType.USE, 18, "a", None),
            ]
            + get_a(4, 5, 24)
            + get_a(1, 1, 2)
            + [
                (event.EventType.USE, 19, "print", None),
                (event.EventType.USE, 24, "ValueError", None),
                (event.EventType.USE, 26, "print", None),
            ]
        )
        self.assertEqual(len(expected_def_uses), len(events))  # defs + uses
        for e, expected in zip(events, expected_def_uses):
            type_, line, var, val = expected
            self.assertEqual(
                type_, e.event_type, f"{e} is not of type {type_}, expected {expected}"
            )
            self.assertIsInstance(
                e,
                event.event_mapping[type_],
                f"{e} is not a {event.event_mapping[type_]}, expected {expected}",
            )
            self.assertEqual(
                BaseTest.ACCESS,
                e.file,
                f"{e} has not correct file, expected {expected}",
            )
            self.assertEqual(
                line, e.line, f"{e} has not correct line, expected {expected}"
            )
            if isinstance(var, list):
                self.assertIn(
                    e.var, var, f"{e} has not correct var, expected {expected}"
                )
            else:
                self.assertEqual(
                    var, e.var, f"{e} has not correct var, expected {expected}"
                )
            if type_ == event.EventType.DEF and val:
                if isinstance(val, list):
                    self.assertIn(
                        e.value, val, f"{e} has not correct value, expected {expected}"
                    )
                else:
                    self.assertEqual(
                        val, e.value, f"{e} has not correct value, expected {expected}"
                    )

    def test_condition(self):
        events = self._test_events("condition")
        self.assertEqual(4, len(events))
        expected_conditions = [
            (event.EventType.CONDITION, 16, "a(0, 0)", False),
            (event.EventType.CONDITION, 18, "a(4, 5)", True),
            (event.EventType.CONDITION, 18, "a(1, 1)", True),
            (event.EventType.CONDITION, 18, "a(4, 5) and a(1, 1)", True),
        ]
        for e, expected in zip(events, expected_conditions):
            type_, line, exp, ev = expected
            self.assertEqual(e.event_type, type_, f"{e} is not of type {type_}")
            self.assertIsInstance(
                e,
                event.event_mapping[type_],
                f"{e} is not a {event.event_mapping[type_]}",
            )
            self.assertEqual(BaseTest.ACCESS, e.file, f"{e} has not correct file")
            self.assertEqual(line, e.line, f"{e} has not correct line")
            self.assertEqual(ev, e.value, f"{e} has not correct value")
            self.assertEqual(exp, e.condition, f"{e} has not correct condition")

    def test_len(self):
        config = Config.create(
            path=os.path.join(self.TEST_RESOURCES, self.TEST_LEN),
            language="python",
            events="len",
            working=self.TEST_DIR,
        )
        instrument_config(config)

        subprocess.run(
            [self.PYTHON, self.ACCESS, "a", "b", "c"],
            cwd=self.TEST_DIR,
        )

        events = event.load(
            os.path.join(self.TEST_DIR, self.TEST_PATH),
            EventMapping.load(config).mapping,
        )
        self.assertEqual(2, len(events))
        for i, a, l, e in zip([4, 5], ["args", "a"], [3, 1], events):
            self.assertIsInstance(e, event.LenEvent, f"{e} is not a line event")
            self.assertEqual(self.ACCESS, e.file, f"{e} has not correct file")
            self.assertEqual(i, e.line, f"{e} has not correct line")
            self.assertEqual(a, e.var, f"{e} has not correct var")
            self.assertEqual(l, e.length, f"{e} has not correct length")

class SerializeEventsTest(BaseTest):
    @parameterized.expand(map(lambda x: (str(x), x), BaseTest.EVENTS))
    def test_serialize(self, _, e):
        self.assertEqual(e, event.deserialize(event.serialize(e)))

    @parameterized.expand(map(lambda x: (str(x), x), BaseTest.EVENTS))
    def test_load(self, _, e):
        self.assertEqual(e, event.load_event(e.dump(), {e.event_id: e}))


from flask import jsonify

def book_serializer(bookinfo):
    book_list = []
    for book in bookinfo:
        booktest_dict = {
            'book_title': book.book_title,
            'content_validity': book.content_validity,
            'author': book.author,
            'author_introduction': book.author_introduction,
            'press': book.press,
            'pubyear': book.pubyear,
            'pages': book.pages,
            'label': book.label,
            'ISBN': book.ISBN,
            'TSBH': book.TSBH,
            'db_id': book.db_id,
            'set_id': book.set_id,
            'book_id': book.book_id,
            'menu': book.menu
        }
        if book.rating:
            booktest_dict['rating'] = book.rating
            booktest_dict['half_rating'] = str(round(float(book.rating)/2,1))
        else:
            booktest_dict['rating'] = 0
            booktest_dict['half_rating'] = 0
        if book.image_address:
            booktest_dict['image_address'] = 'https://images.weserv.nl/?url=' + book.image_address[7:]
        else:
            # 赋值为空
            booktest_dict['image_address'] = book.image_address
        book_list.append(booktest_dict)
    return jsonify({'book_list': book_list, "status": 1})

def label_serializer(bookinfo):
    label_list = []
    for book in bookinfo:
        label_dict = {
            'label': book.label,
        }
        label_list.append(label_dict)
    return jsonify({'label_list': label_list, "status": 1})


"""
liber_primus_to_primes.py

    Translator Class for LP Anglo Saxon Runic to Primes per the Cicada Gematria

@author: Doug Daly
@date: 4/8/2017
"""
#
#   Imports
#
from .base import Translator

#
#   Class Definition
#

class LiberPrimusToPrimes(Translator):
    """
    Converts LP Runes to Their Prime Values
    """

    def _generate_translation_dict(self):
        """ Generates the Translation Dictionary Needed

        :return: Translation Dictionary
        :rtype: dict

        """
        runes = ['ᚠ', 'ᚢ', 'ᚦ', 'ᚩ', 'ᚱ', 'ᚳ', 'ᚷ', 'ᚹ', 'ᚻ', 'ᚾ', 'ᛁ', 'ᛄ',
                 'ᛇ', 'ᛈ', 'ᛉ', 'ᛋ', 'ᛏ', 'ᛒ', 'ᛖ', 'ᛗ', 'ᛚ', 'ᛝ', 'ᛟ', 'ᛞ',
                 'ᚪ', 'ᚫ', 'ᚣ', 'ᛡ', 'ᛠ']
        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
                  59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109]
        ret_dict = dict(zip(runes, primes))

        return ret_dict


import cadquery as cq
from math import sin, cos, pi

def makeLeg(
        r_up: float = 80,
        r_down: float = 120,
        h: float = 350,
        k: float = 3, # k-parabola form
        ) -> cq.Workplane:
    sweep = (
            cq.Workplane()
            .parametricCurve(
                #lambda x: (x,0,-h*sin(0.5*pi*x/r_down)),
                lambda x: (x,0, -h*((x)/r_down)**2),
                N = 100,
                start = 0,
                stop = r_down,
                )
            )
    debug (sweep)
    res_sine = (
            cq.Workplane()
            .rect(-40,21,centered = (False,True,False))
            .sweep(sweep,multisection=True)
            )
    res_parabola = (
            cq.Workplane("YZ")
            .rect(21,-40)
            .sweep(sweep)
            )
    # dimentions on zaxis
    top = res_parabola.val().BoundingBox().zmax
    zmin = res_parabola.val().BoundingBox().zmin
    cut_plane = (
            cq.Workplane(origin=(0,0,-(h-top)))
            .rect(r_down+50,50,centered=(False,True,True))
            .extrude((h-top+zmin))
            )
    #debug(cut_plane)
    # Cutoff extra
    res_parabola = res_parabola.cut(cut_plane)

    print(f'Zlen -> {res_parabola.val().BoundingBox().zlen} mm')
    return res_parabola

show_object(makeLeg())