#!/usr/bin/env python
from __future__ import print_function
import csv
import json
import requests
import os
import os.path
from argparse import ArgumentParser
from utils import login, get, post

def add_device(dnac, name, serial, pid):
    payload = [{
	"deviceInfo": {
		"name": name,
		"serialNumber": serial,
		"pid": pid,
		"sudiRequired": False,
		"userSudiSerialNos": [],
		"stack": False,
		"aaaCredentials": {
			"username": "",
			"password": ""
		}
	}
}]
    device = post(dnac, "onboarding/pnp-device/import", payload)
    try:
        deviceId = device.json()['successList'][0]['id']
    except IndexError as e:
        print ('##SKIPPING device:{},{}:{}'.format(name, serial, device.json()['failureList'][0]['msg']))
        deviceId = None

    return deviceId

def claim_device(dnac,deviceId, configId, workflowId, params):
    payload = {
	"deviceClaimList": [{
		"deviceId": deviceId,
		"configList": [{
			"configId": configId,
			"configParameters": params
		}]
	}],
	"projectId": None,
	"workflowId": workflowId,
	"configId": None,
	"imageId": None,
	"populateInventory": True
}
    #print json.dumps(payload, indent=2)

    claim = post(dnac,"onboarding/pnp-device/claim", payload)
    return claim.json()['message']

def get_workflow(dnac,workflowName):
    response = get (dnac, "onboarding/pnp-workflow")
    for workflow in response.json():
        if workflow['name'] == workflowName:
            workflowId = workflow['id']
            #print json.dumps(workflow, indent=4)
            for tasks in workflow['tasks']:
                configId = tasks['configInfo']['configId']
            return workflowId, configId

    raise ValueError("Cannot find template:{}".format(workflowName))

def get_template(dnac, configId, supplied_params):
    params=[]
    response = get(dnac, "template-programmer/template/{}".format(configId))
    for vars in response.json()['templateParams']:
        name = vars['parameterName']
        params.append({"key": name, "value": supplied_params[name]})
    #print params
    return params

def create_and_upload(dnac, devices):

    f = open(devices, 'rt')
    try:
        reader = csv.DictReader(f)
        for device_row in reader:
            #print ("Variables:",device_row)

            try:
                workflowId, configId = get_workflow(dnac, device_row['workflow'])
            except ValueError as e:
                print("##ERROR {},{}: {}".format(device_row['name'],device_row['serial'], e))
                continue

            params = get_template(dnac, configId, device_row)

            deviceId = add_device(dnac, device_row['name'], device_row['serial'], device_row['pid'])
            if deviceId is not None:
                #claim
                claim_status = claim_device(dnac, deviceId, configId, workflowId, params)
                if "Claimed" in claim_status:
                    status = "PLANNED"
                else:
                    status = "FAILED"
                print ('Device:{} name:{} workflow:{} Status:{}'.format(device_row['serial'],
                                                                    device_row['name'],
                                                                    device_row['workflow'],
                                                                    status))
    finally:
        f.close()

if __name__ == "__main__":
    parser = ArgumentParser(description='Select options.')
    parser.add_argument( 'devices', type=str,
            help='device inventory csv file')
    args = parser.parse_args()

    dnac = login()
    print ("Using device file:", args.devices)

    print ("##########################")
    create_and_upload(dnac, devices=args.devices)


import subprocess
import re
import socket
import fcntl
import struct
import time
import traceback

def _cmd(cmd, ctype="ip"):

    try:
        _ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd="/home/firefly", timeout=5)

        if ctype == "ip":
            ip_list = []
            if _ret.returncode == 0:
                ip_list = re.findall(r'[0-9]+(?:\.[0-9]+){3}', _ret.stdout.decode('utf-8').strip())

            return True if ip_list else False

        if ctype == "super":
            if "FATAL" in _ret.stdout.decode('utf-8'):
                c = 0
                while c < 3:
                    time.sleep(2)
                    _ret1 = subprocess.run("sudo supervisorctl -u user -p 123456 restart all", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd="/home/firefly", timeout=10)
                    if ("mipi:mipi0: started" in _ret1.stdout.decode('utf-8')) and ("reqrep:reqrep0: started" in _ret1.stdout.decode('utf-8')):
                        break
                    else:
                        c += 1
                        continue
    except Exception as e:
        print(traceback.print_exc())

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    inet = fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', bytes(ifname[:15], 'utf-8')))
    return socket.inet_ntoa(inet[20:24])

while True:
    time.sleep(2)
    try:
        ip = get_ip_address("usb0")
        print("usb0 ip: ", ip)
    except:
        print("usb0 ip get_ip_address error")
        _cmd("sudo udhcpc -i usb0", "ip")
        continue
    else:
        if re.match("[0-9]+(?:\.[0-9]+){3}", ip):
            print("ip ok: ", ip)
            _cmd("sudo supervisorctl -u user -p 123456 status", ctype="super")
        else:
            print("no usb0 ip: err")
            continue


""" The ``wex`` command extracts data from HTTP-like responses.
These responses can come from files, directories or URLs specified on the
command line.  The command calls any :mod:`extractors <wex.extractor>` that have
been :mod:`registered <wex.entrypoints>` and writes any data extracted
as :mod:`output <wex.output>`.

The output and input can be saved, using the ``--save`` or ``--save-dir``
command line arguments.  This is useful for
`regression testing <http://en.wikipedia.org/wiki/Regression_testing>`_.
existing extractor functions.
The test are run using :mod:`py.test <wex.pytestplugin>`.

For the complete list of command line arguments run:

.. code-block:: shell

    $ wex --help

"""
from __future__ import absolute_import, unicode_literals, print_function
import errno
import argparse
import logging.config
from multiprocessing import cpu_count
from pkg_resources import resource_filename, EntryPoint
from .readable import readables_from_paths
from .response import Response
from .processpool import do
from .output import StdOut, TeeStdOut
from .value import Value
from .entrypoints import extractor_from_entry_points

default_logging_conf = resource_filename(__name__, 'logging.conf')

argparser = argparse.ArgumentParser()

argparser.add_argument(
    'paths',
    metavar='path',
    nargs='+',
    help="file, directory or url from which to extract"
)

def label_func(spec):
    ep = EntryPoint.parse('ep = {}'.format(spec))
    func = ep.load(require=False)
    if not callable(func):
        raise ValueError("'%s' is not callable" % spec)
    return func

argparser.add_argument(
    '-l',
    '--label',
    dest='label_funcs',
    type=label_func,
    action='append',
    default=[],
    help="function to generate a label",
)

argparser.add_argument(
    '--log-debug',
    action='append',
    default=[],
    help="set debug level on this logger"
)

save_group = argparser.add_argument_group("Save extraction input and output")

save_excl_group = save_group.add_mutually_exclusive_group()

save_excl_group.add_argument(
    '-s', '--save',
    action='store_const',
    dest='save_dir',
    const='saved',
    default=False,
    help="into directory 'saved'",
)

save_excl_group.add_argument(
    '--save-dir',
    dest='save_dir',
    metavar="DIR",
    help="into directory DIR",
)

process_pool_size_group = argparser.add_argument_group('Parallel processing using multiprocessing.Pool')

process_pool_size = process_pool_size_group.add_mutually_exclusive_group()

process_pool_size.add_argument(
    '-P',
    dest='process_pool_size',
    action="store_const",
    const=cpu_count(),
    default=1,
    help="with default pool size (default: %s)" % cpu_count(),
)

process_pool_size.add_argument(
    '--process-pool',
    dest='process_pool_size',
    metavar='N',
    type=int,
    default=1,
    help="with a pool size of N",
)

on_exc_group = argparser.add_argument_group("When an exception occurs")
on_exc = on_exc_group.add_mutually_exclusive_group()

on_exc.add_argument(
    '-x', '--exit-on-exc',
    action="store_true",
    default=False,
    help="exit with a traceback",
)

on_exc.add_argument(
    '-d', '--debug-on-exc',
    action="store_true",
    default=False,
    help="start the debugger",
)

class WriteExtractedValues(object):

    def __init__(self, stdout, extract, label_funcs=()):
        self.stdout = stdout
        self.extract = extract
        self.label_funcs = label_funcs

    def __call__(self, readable):

        retval = None
        try:

            with self.stdout(readable) as writer:
                for value in Response.values_from_readable(self.extract,
                                                           readable,
                                                           self.label_funcs):
                    for line in value.text():
                        writer.write(line)

        except IOError as exc:

            # when we get an IOError it means we need to stop extracting
            # so we *return* an exception so that the processpool.do can
            # finish doing work.

            if exc.errno == errno.EPIPE:
                # unix convention is that exit code 0 is correct for a broken pipe
                retval = SystemExit(0)
            else:
                logging.getLogger(__name__).exception('reading %r', readable)
                retval = SystemExit(exc)

        except Exception as exc:
            logging.getLogger(__name__).exception('while extracting from %r', readable)
            raise

        return retval

def main():

    logging.config.fileConfig(default_logging_conf,
                              disable_existing_loggers=False)

    args = argparser.parse_args()

    for logger_name in args.log_debug:
        logging.getLogger(logger_name).setLevel(logging.DEBUG)

    extract = extractor_from_entry_points()
    if args.save_dir:
        func = WriteExtractedValues(TeeStdOut, extract, args.label_funcs)
    else:
        func = WriteExtractedValues(StdOut, extract, args.label_funcs)
    Value.exit_on_exc = args.exit_on_exc
    Value.debug_on_exc = args.debug_on_exc

    readables = readables_from_paths(args.paths, args.save_dir)
    do(func, readables, pool_size=args.process_pool_size)


import taichi as ti

ti.init(debug=True)

dt = 1e-5
planets_limit = 128

num_planets = ti.field(ti.i32, shape=())

x = ti.Vector.field(2, ti.f32, shape=planets_limit, needs_grad=True)
v = ti.Vector.field(2, ti.f32, shape=planets_limit)
potential = ti.field(ti.f32, shape=(), needs_grad=True)

@ti.kernel
def compute_potential(n: ti.i32):
    for i, j in ti.ndrange(n, n):
        dist = (x[i] - x[j]).norm(1e-3)
        potential[None] += -1 / dist

@ti.kernel
def update():
    for i in range(num_planets[None]):
        v[i] += dt * -x.grad[i]

    for i in range(num_planets[None]):
        x[i] += dt * v[i]

def step():
    with ti.Tape(potential):
        compute_potential(num_planets[None])

    update()

def make_planet(pos_x: ti.i32, pos_y: ti.i32):
    new_id = num_planets[None]
    num_planets[None] += 1

    x[new_id] = [pos_x, pos_y]

gui = ti.GUI('Gravity', res=(720, 720), background_color=0x000000)

while gui.running:
    for e in gui.get_events(ti.GUI.PRESS):
        if e.key in [ti.GUI.ESCAPE, ti.GUI.EXIT]:
            exit()
        elif e.key == ti.GUI.LMB and num_planets[None] < planets_limit:
            make_planet(e.pos[0], e.pos[1])

    for i in range(50):
        step()
    gui.circles(x.to_numpy(), radius=3)
    gui.show()


n=int(input())
arr=[]
arr.append(0)
arr.append(1)
for i in range(2,n+1):
	arr.append(arr[i-1]+arr[i-2])
print(arr[n])

"""
fibonacci sum squares
def fibsum(n):
	arr=[0]*(n+1)
	if(n<=1):
		return n
	arr[0]=0
	arr[1]=1
	sum=(arr[0]*arr[0])+(arr[1]*arr[1])
	for i in range(2,n+1):
		arr[i]=arr[i-1]+arr[i-2]
		sum+=arr[i]*arr[i]
	return(sum)
n=int(input())
print(fibsum(n)%10)
"""


from app.main import main
from app.main import multiThreadRequest
import json
import time
# from .utils import *
from flask import current_app, make_response, request, make_response, \
    jsonify, redirect, current_app, abort

from config import *
from ..models import Idataset
from .utils import inference
# @main.before_app_request
# def request_images_from_heycloud():
#     json = jsonify(request.get_json('test'))
#     return None

@main.route('/detection/aircraft', methods=['POST'])
def info():
    if request.content_type == 'application/json':
        args = dict(request.get_json(force=True))
    else:
        args = {
            key: value[0] if len(value) == 1 else value
            for key, value in request.form.items()
        }
        args['bbox'] = [float(el) for el in args['bbox'][1:-1].split(',')]

    SLICE_HEIGHT = args['height'] if args.get('height') is not None else 608
    SLICE_WIDTH = args['width'] if args.get('width') is not None else 608
    SP_SLICE_HEIGHT = SLICE_HEIGHT * SP_RES
    SP_SLICE_WIDTH = SLICE_WIDTH * SP_RES

    cfg = current_app.config
    width_min = args['bbox'][0]
    height_min = args['bbox'][1]
    width_max = args['bbox'][2]
    height_max = args['bbox'][3]
    post_params = {
        "bbox": [],
        "bands": [0,1,2],
        "height": SLICE_HEIGHT,
        "width": SLICE_WIDTH

    }

    headers = cfg['IMAGE_REQUEST_HEADERS']
    request_url = cfg['IMAGE_REQUEST_HOST'] +  \
                '/heycloud/api/data/idataset' + \
                '/37605aef-913e-40b6-8859-822e72a51a19' + \
                '/extract'

    # threads = multiThreadRequest(INFER_IMAGE_PATH,
    #                     height_min,
    #                     width_min,
    #                     height_max,
    #                     width_max,
    #                     SLICE_HEIGHT,
    #                     SLICE_WIDTH,
    #                     SP_SLICE_HEIGHT,
    #                     SP_SLICE_WIDTH,
    #                     IMAGE_HEIGHT,
    #                     IMAGE_WIDTH,
    #                     SLICE_OVERLAP,
    #                     post_params,
    #                     request_url,
    #                     headers
    #                     )
    start = time.time()

    # for th in threads:
    #     th.setDaemon(True)
    #     th.start()
    # for t in threads:
    #     t.join()
    print("\n[INFO] total request time: %ss\n" % round(time.time()-start, 2))

    json = inference(NET_CONFIG_FILE,
              INFER_DATA_FILE,
              WEIGHTS, BATCH_SIZE,
              IMAGE_PATH_TXT,
              INFER_RES_TXT,
              CONF_THRESH,
              SP_RES,
              args['bbox'],
              NMS_THRESH,
              INFER_RES_PATH)

    return json

@main.route('/test', methods=['POST'])
def test():
    if request.content_type == 'application/json':
        args = dict(request.get_json(force=True))
    else:
        args = {
            key: value[0] if len(value) == 1 else value
            for key, value in request.form.items()
        }
        args['bbox'] = [float(el) for el in args['bbox'][1:-1].split(',')]

    # peter = Idataset.query.filter_by(id='test').first_or_404(description='There is no data with {}'.format('test'))
    # print(Idataset.file)
    abort(404)
    return str(request.accept_mimetypes.accept_json)


def dist_abs(self, src, tar):
        """Return the MRA comparison rating of two strings.

        Parameters
        ----------
        src : str
            Source string for comparison
        tar : str
            Target string for comparison

        Returns
        -------
        int
            MRA comparison rating

        Examples
        --------
        >>> cmp = MRA()
        >>> cmp.dist_abs('cat', 'hat')
        5
        >>> cmp.dist_abs('Niall', 'Neil')
        6
        >>> cmp.dist_abs('aluminum', 'Catalan')
        0
        >>> cmp.dist_abs('ATCG', 'TAGC')
        5

        """
        if src == tar:
            return 6
        if src == '' or tar == '':
            return 0
        src = list(mra(src))
        tar = list(mra(tar))

        if abs(len(src) - len(tar)) > 2:
            return 0

        length_sum = len(src) + len(tar)
        if length_sum < 5:
            min_rating = 5
        elif length_sum < 8:
            min_rating = 4
        elif length_sum < 12:
            min_rating = 3
        else:
            min_rating = 2

        for _ in range(2):
            new_src = []
            new_tar = []
            minlen = min(len(src), len(tar))
            for i in range(minlen):
                if src[i] != tar[i]:
                    new_src.append(src[i])
                    new_tar.append(tar[i])
            src = new_src + src[minlen:]
            tar = new_tar + tar[minlen:]
            src.reverse()
            tar.reverse()

        similarity = 6 - max(len(src), len(tar))

        if similarity >= min_rating:
            return similarity
        return 0


"""
Attempt at answering initial EDA questions on the Grocery dataset
"""
import pandas as pd

#Load in csvs as dataframes
data = pd.read_csv('sales_data_2017_2018.csv')
print(data.dtypes)
#print(data.head())

#Get percent of dataset with null values for each column for restaurants data:
for columnName in data.columns.values:
    null_list = data[columnName].isnull()
    COUNTNULL = 0
    COUNTNOTNULL = 0
    for isratingnull in null_list:
        if isratingnull is True:
            COUNTNULL += 1
        else:
            COUNTNOTNULL += 1
    print("For", columnName, COUNTNULL, "/", COUNTNULL+COUNTNOTNULL,
          COUNTNULL/(COUNTNULL+COUNTNOTNULL))


import argparse, math, random, sys
import numpy as np

from utils.util_functions import read_plain_file
from evaluation.constants import *
from utils.constants import *

from evaluation.utils_functions import read_file, load_explainer_checkpoint, get_weights_from_explainer

def split_src_by_category(src):
    # split the train src according to predicted label
    src_map = dict()
    for i, x in enumerate(src):
        predicted_label = x[0][5:-1]
        try:
            previous_src = src_map[predicted_label]
            previous_src.append(i)

        except KeyError:
            src_map[predicted_label] = [i]

    return src_map

def remove_long_doc(src, tgt, max_length):
    new_src, new_tgt = [], []

    for i, doc in enumerate(src):
        if len(doc) <= max_length:
            new_src.append(doc)
            new_tgt.append(tgt[i])
    return np.array(new_src), np.array(new_tgt)

def set_model_parameters():
    parser = argparse.ArgumentParser(description='Compare Variance Parser')
    parser.add_argument('--data', type=str, default='path to data')
    parser.add_argument('--dataset', type=str, choices=[SST, COLA, AGNEWS, IMDB_R])
    parser.add_argument('--doc-num', type=int, help='number of documents selected for evaluation')
    parser.add_argument('--categorize-type', type=str, choices=[RANK, MULTILABEL],
                        help='the categorization type in explainer target')
    parser.add_argument('--original-explainer', nargs='+',
                        default=[KERNEL_SHAP, DEEP_SHAP, OCCLUSION, GRADIENT, LIME, LRP])
    parser.add_argument('--ratio', type=float, default=0.3, help='the ratio to mask when explainer type is RANK')
    parser.add_argument('--similarity-metric', type=str, choices=[BERT_COS, N_GRAM],
                        help='the similarity file collected by find_similar_documents')

    args, _ = parser.parse_known_args(sys.argv)

    args.similarity_file = '%s/fairseq/%s/%s' % (args.data, args.dataset,
                                                 'test_' + args.similarity_metric + '_similarity.txt')
    args.debug_log_file = '%s/fairseq/%s/%s_%s_%s_variance_log_file.txt' % (args.data, args.dataset, args.dataset,
                                                                            args.categorize_type, args.similarity_metric)
    args.explainer_parameters = []
    args.explainer_checkpoint_path = []
    args.test_src_file = []
    args.test_tgt_file = []

    args.test_index_mapping_file = []
    args.save_log_file = []
    for each in args.original_explainer:
        nsample = 'auto' if each in [OCCLUSION, GRADIENT, LRP] else '1000'
        args.explainer_parameters.append('%s/fairseq/%s/%s/%s/explainer_parameters_%s' %
                                         (args.data, args.dataset, each, nsample, args.categorize_type))
        args.explainer_checkpoint_path.append('%s/fairseq/%s/%s/%s/%s_%s/%s' %
                                              (args.data, args.dataset, each, nsample,
                                               'checkpoints', args.categorize_type, 'checkpoint_best.pt'))
        args.test_src_file.append('%s/fairseq/%s/%s/%s/test_src.exp' % (args.data, args.dataset, each, nsample))
        args.test_tgt_file.append('%s/fairseq/%s/%s/%s/test_tgt.exp' % (args.data, args.dataset, each, nsample))

        args.test_index_mapping_file.append('%s/fairseq/%s/%s/%s/test_index.txt' % (args.data, args.dataset, each, nsample))

        args.save_log_file.append('%s/fairseq/%s/%s/%s/%s_%s_exp_variance_log.txt' % (args.data, args.dataset, each,
                                                                                nsample, args.categorize_type,
                                                                                args.similarity_metric))
    return args

def get_similar_doc(args, nn):
    similar_docs = read_plain_file(args.similarity_file)
    test_similar_doc_map = dict()
    for each in similar_docs:
        seq = each.strip().split(":::")
        test_idx = int(seq[0])
        similar_train_docs = [int(i) for i in seq[1].split(',')]
        test_similar_doc_map[test_idx] = similar_train_docs[:nn]

    return test_similar_doc_map

def get_index_mapping(args, idx):
    # original ::: exp
    mappings = read_plain_file(args.test_index_mapping_file[idx])
    exp_to_original = dict()
    original_to_exp = dict()
    for each in mappings:
        seq = each.strip().split(":::")
        original_index = int(seq[0])
        exp_index = int(seq[1])

        exp_to_original[exp_index] = original_index
        original_to_exp[original_index] = exp_index
    return exp_to_original, original_to_exp

def filter_long_doc(src, max_len):
    avail_src = []
    for i in range(len(src)):
        if 3 < len(src[i]) <= max_len:  # must have at least one word and lower than what BERT allows
            avail_src.append(1)
        else:
            avail_src.append(0)
    return [i/sum(avail_src) for i in avail_src]

def print_log(log_file, doc, compare_tuple, formulation=MULTILABEL, nn=False):
    if not nn:
        log_file.write('-------------------------------------------------------------------\n')
        log_file.write("##### Current document:\n")
    else:
        log_file.write('------------------\n')
        log_file.write("##### Neighbor documents:\n")
    log_file.write(" ".join(doc) + "\n")
    log_file.write("##### Our Explanation (Pos):\n")
    log_file.write(" ".join(compare_tuple[OUR_EXP_POS]) + "\n")
    log_file.write("##### Base Explanation (Pos):\n")
    log_file.write(" ".join(compare_tuple[BASE_EXP_POS]) + "\n")
    log_file.write("##### Random Explanation (Pos):\n")
    log_file.write(" ".join(compare_tuple[RANDOM_EXP_POS]) + "\n")

    if formulation == MULTILABEL:
        log_file.write("##### Our Explanation (Neg):\n")
        log_file.write(" ".join(compare_tuple[OUR_EXP_NEG]) + "\n")
        log_file.write("##### Base Explanation (Neg):\n")
        log_file.write(" ".join(compare_tuple[BASE_EXP_NEG]) + "\n")
        log_file.write("##### Random Explanation (Neg):\n")
        log_file.write(" ".join(compare_tuple[RANDOM_EXP_NEG]) + "\n")

def compute_iou(current_compare_tuple, neighbor_compare_tuple, formulation=MULTILABEL):
    # UNION
    our_exp_pos_union = list(set(current_compare_tuple[OUR_EXP_POS] + neighbor_compare_tuple[OUR_EXP_POS]))
    our_exp_neg_union = list(set(current_compare_tuple[OUR_EXP_NEG] + neighbor_compare_tuple[OUR_EXP_NEG]))

    base_exp_pos_union = list(set(current_compare_tuple[BASE_EXP_POS] + neighbor_compare_tuple[BASE_EXP_POS]))
    base_exp_neg_union = list(set(current_compare_tuple[BASE_EXP_NEG] + neighbor_compare_tuple[BASE_EXP_NEG]))

    random_exp_pos_union = list(
        set(current_compare_tuple[RANDOM_EXP_POS] + neighbor_compare_tuple[RANDOM_EXP_POS]))
    random_exp_neg_union = list(
        set(current_compare_tuple[RANDOM_EXP_NEG] + neighbor_compare_tuple[RANDOM_EXP_NEG]))

    # INTERSECT
    our_exp_pos_intersect = list(set(current_compare_tuple[OUR_EXP_POS]) & set(neighbor_compare_tuple[OUR_EXP_POS]))
    our_exp_neg_intersect = list(set(current_compare_tuple[OUR_EXP_NEG]) & set(neighbor_compare_tuple[OUR_EXP_NEG]))

    base_exp_pos_intersect = list(set(current_compare_tuple[BASE_EXP_POS]) & set(neighbor_compare_tuple[BASE_EXP_POS]))
    base_exp_neg_intersect = list(set(current_compare_tuple[BASE_EXP_NEG]) & set(neighbor_compare_tuple[BASE_EXP_NEG]))

    random_exp_pos_intersect = list(
        set(current_compare_tuple[RANDOM_EXP_POS]) & set(neighbor_compare_tuple[RANDOM_EXP_POS]))
    random_exp_neg_intersect = list(
        set(current_compare_tuple[RANDOM_EXP_NEG]) & set(neighbor_compare_tuple[RANDOM_EXP_NEG]))

    # IOU: denominator
    our_exp_denominator = len(our_exp_pos_union) + len(our_exp_neg_union) \
        if formulation == MULTILABEL else len(our_exp_pos_union)
    base_exp_denominator = len(base_exp_pos_union) + len(base_exp_neg_union) \
        if formulation == MULTILABEL else len(base_exp_pos_union)
    random_exp_denominator = len(random_exp_pos_union) + len(random_exp_neg_union) \
        if formulation == MULTILABEL else len(random_exp_pos_union)

    # IOU : numerator
    our_exp_numerator = len(our_exp_pos_intersect) + len(our_exp_neg_intersect) \
        if formulation == MULTILABEL else len(our_exp_pos_intersect)
    base_exp_numerator = len(base_exp_pos_intersect) + len(base_exp_neg_intersect) \
        if formulation == MULTILABEL else len(base_exp_pos_intersect)
    random_exp_numerator = len(random_exp_pos_intersect) + len(random_exp_neg_intersect) \
        if formulation == MULTILABEL else len(random_exp_pos_intersect)

    our_iou = 0.0 if our_exp_denominator == 0 else our_exp_numerator / our_exp_denominator
    base_iou = 0.0 if base_exp_denominator == 0 else base_exp_numerator / base_exp_denominator
    random_iou = 0.0 if random_exp_denominator == 0 else random_exp_numerator / random_exp_denominator

    return our_iou, base_iou, random_iou

def main():
    args = set_model_parameters()
    max_len = 100
    nearest_neighbors = 3
    random.seed(1234)

    # read nearest neighbor from file: original test ::: original trains
    similar_doc_map = get_similar_doc(args, nearest_neighbors)

    debug_log_file = open(args.debug_log_file, 'w')

    # load data and base exp
    test_src, test_tgt = read_file(args.test_src_file[0], " "), read_file(args.test_tgt_file[0], ",")
    prob = filter_long_doc(test_src, max_len)
    selected = random.choices(range(len(test_src)), weights=prob, k=args.doc_num)

    for idx in range(len(args.original_explainer)):
        variance_log_file = open(args.save_log_file[idx], 'w')
        # Debug info
        debug_log_file.write('================' + args.original_explainer[idx] + '================' + "\n")
        exp_to_original, original_to_exp = get_index_mapping(args, idx)

        if idx != 0:
            test_src, test_tgt = read_file(args.test_src_file[idx], " "), read_file(args.test_tgt_file[idx], ",")

        # get weights from the trained explanation model
        trainer = load_explainer_checkpoint(args.explainer_parameters[idx], args.explainer_checkpoint_path[idx])

        # check explanation intersection / union in those documents
        for i in selected:

            doc = test_src[i]
            base_weight = test_tgt[i]
            current_compare_tuple = get_exp_tuple(args, doc, base_weight, trainer,
                                                  lrp=args.original_explainer[idx] == LRP)
            # find neighbors
            try:
                # in case the mappings are not finalised by find_neighbours.py yet
                neighbors_indices = [original_to_exp[each] for each in similar_doc_map[exp_to_original[i]]]
            except KeyError:
                continue

            # print debug info
            print_log(debug_log_file, doc, current_compare_tuple, formulation=args.categorize_type)

            our_exp_var = 0.0
            base_exp_var = 0.0
            random_exp_var = 0.0

            for neighbor in neighbors_indices:
                neighbor_src = test_src[neighbor]
                neighbor_tgt = test_tgt[neighbor]

                neighbor_compare_tuple = get_exp_tuple(args, neighbor_src, neighbor_tgt, trainer,
                                                       lrp=args.original_explainer[idx]==LRP)

                print_log(debug_log_file, neighbor_src, neighbor_compare_tuple,
                          formulation=args.categorize_type, nn=True)

                # accumulate IOU value
                our_iou, base_iou, random_iou = compute_iou(current_compare_tuple, neighbor_compare_tuple,
                                                            formulation=args.categorize_type)
                our_exp_var += our_iou
                base_exp_var += base_iou
                random_exp_var += random_iou

            variance_log_file.write("In %s -th instance: the average similarity of base explanation is %.2f%%, "
                                    "the random explanation is %.2f%%, "
                                    "our explanation is %.2f%%.\n" %
                                    (i, base_exp_var / len(neighbors_indices) * 100,
                                     random_exp_var / len(neighbors_indices) * 100,
                                     our_exp_var / len(neighbors_indices) * 100))

            debug_log_file.write("In %s -th instance: the average similarity of base explanation is %.2f%%, "
                                 "the random explanation is %.2f%%, "
                                 "our explanation is %.2f%%.\n" %
                                 (i, base_exp_var / len(neighbors_indices) * 100,
                                  random_exp_var / len(neighbors_indices) * 100,
                                  our_exp_var / len(neighbors_indices) * 100))
            debug_log_file.write('\n')

def get_exp_tuple(args, src, base_weight, explainer, lrp=False):

    our_weight = get_weights_from_explainer(explainer, src, output_dim=5 if args.categorize_type == MULTILABEL else 1).squeeze(0).tolist()

    def sort_base_weight(i):
        return base_weight[i]
    order = sorted(range(len(base_weight)), key=lambda i: sort_base_weight(i), reverse=True)

    if args.categorize_type == RANK:
        def sort_out_weight(i):
            return our_weight[i]
        if not isinstance(our_weight, list):
            print('stop.')
            our_weight = [our_weight]
        interval = math.ceil(len(our_weight) * args.ratio)
        sorted_our_weight = sorted(range(len(our_weight)), key=lambda i: sort_out_weight(i), reverse=True)

        our_exp_pos = [src[i + 1] for i in sorted_our_weight[:interval]]
        our_exp_neg = [src[i + 1] for i in sorted_our_weight[-interval:]]

        # when it's ranking, the base explanation does not need to care if it's > or < 0
        base_exp_pos = list(filter(None, [src[i + 1] if i in order[:interval] else None
                                          for i in range(len(base_weight))]))
        base_exp_neg = list(filter(None, [src[i + 1] if i in order[-interval:] else None
                                          for i in range(len(base_weight))]))

        pos_idx = random.sample(range(1, len(src)-1), interval)
        random_exp_pos = [src[i] for i in pos_idx]
        neg_idx = random.sample(range(1, len(src)-1), interval)
        random_exp_neg = [src[i] for i in neg_idx]
    else:
        # multilabel - non lrp
        if not lrp:
            # 0: high neg; 1: low neg; 2: neutral; 3: low pos; 4: high pos
            pos_interval = sum([1 if x == 3 or x == 4 else 0 for x in our_weight])
            neg_interval = sum([1 if x == 0 or x == 1 else 0 for x in our_weight])

            our_exp_pos = list(filter(None, [src[i + 1] if our_weight[i] == 3 or our_weight[i] == 4 else None
                                             for i in range(len(our_weight))]))
            our_exp_neg = list(filter(None, [src[i + 1] if our_weight[i] == 0 or our_weight[i] == 1 else None
                                             for i in range(len(our_weight))]))

            if pos_interval != 0:
                base_exp_pos = list(filter(None, [src[i + 1] if i in order[:pos_interval] and base_weight[i] > 0.0 else None
                                                  for i in range(len(base_weight))]))
                pos_idx = random.sample(range(1, len(src)-1), pos_interval)
                random_exp_pos = [src[i] for i in pos_idx]
            else:
                base_exp_pos = []
                random_exp_pos = []
            if neg_interval != 0:
                base_exp_neg = list(filter(None, [src[i + 1] if i in order[-neg_interval:] and base_weight[i] < 0.0
                                                  else None for i in range(len(base_weight))]))
                neg_idx = random.sample(range(1, len(src)-1), neg_interval)
                random_exp_neg = [src[i] for i in neg_idx]
            else:

                base_exp_neg = []
                random_exp_neg = []
        else:
            # multilabel - lrp (only pos)
            # 0: high pos; 1: medium pos; 2: low pos
            our_exp_pos, our_exp_neg, base_exp_pos, base_exp_neg, random_exp_pos, random_exp_neg = \
                [], [], [], [], [], []
            pos_interval = sum([1 if x == 0 or x == 1 else 0 for x in our_weight])
            our_exp_pos = list(filter(None, [src[i + 1] if our_weight[i] == 0 or our_weight[i] == 1 else None
                                             for i in range(len(our_weight))]))

            if pos_interval != 0:
                mean_base_weight = np.mean(base_weight)
                std_base_weight = np.std(base_weight)
                base_exp_pos = list(
                    filter(None, [src[i + 1] if i in order[:pos_interval]
                                  and base_weight[i] > mean_base_weight - std_base_weight
                                  else None for i in range(len(base_weight))]))
                pos_idx = random.sample(range(1, len(src) - 1), pos_interval)
                random_exp_pos = [src[i] for i in sorted(pos_idx)]
            else:
                base_exp_pos = []
                random_exp_pos = []

    compare_tuple = {OUR_EXP_POS: our_exp_pos, OUR_EXP_NEG: our_exp_neg,
                     BASE_EXP_POS: base_exp_pos, BASE_EXP_NEG:base_exp_neg,
                     RANDOM_EXP_POS: random_exp_pos, RANDOM_EXP_NEG: random_exp_neg}
    return compare_tuple

if __name__ == "__main__":
    main()


# product_operations_helper_functions.py
# Python File containing helper functions for products
# Includes wrapper function, add, remove, print and update
"""
product_operations_helper_functions.py
"""
from err_catching_helper_functions import options_selector, get_non_negative_int

def products_list_add(products_list, item):
    '''
    Appends item to list only if the item isn't in the list already
    '''
    # Function to add an item to update/add an item to the products list
    # Args:
    # products_list = list of strings, current products_list to be updated
    # item = string, item to be added to product list
    if item in products_list:
        print(f"Item {item} is already in the products_list product list")
        print("Aborting products_list_add() operation")
    else:
        products_list.append(item)
    return products_list

def product_selector_add(items_list:list, out_dict:dict, key_names=("Items", "Quantity")):
    '''
    Recursively gets user input for product to add to an order dictionary until user chooses to stop.\n
    If product already in order, increments quantity instead.
    Returns updated order dictionary
    '''
    # Function to obtain user input for order choice
    carryOn = True
    while carryOn:
        pick = options_selector(items_list, "Please select the desired product: ")
        chosen_item = items_list[pick]
        quantity = get_non_negative_int(
            f"Enter quantity of {items_list[pick]} desired: "
        )
        prior_items = out_dict.get(key_names[0])
        if chosen_item in prior_items:
            # Item exists, add to quantity in corresponding index instead
            print(f"Item {chosen_item} has already been selected")
            idx = prior_items.index(chosen_item)
            existing_quantity = out_dict.get(key_names[1])[idx]
            print(
                f"Adding {quantity} to existing total {existing_quantity} = {quantity+existing_quantity}"
            )
            out_dict[key_names[1]][idx] = quantity + existing_quantity
        else:
            out_dict[key_names[0]].append(chosen_item)
            out_dict[key_names[1]].append(quantity)
        usr_continue = input("Add another item? (y/n): ")
        if usr_continue.lower() != "y":
            carryOn = False
    return out_dict

def product_selector_remove(out_dict, key_names=("Items", "Quantity")):
    '''
    Recursively gets user input for product to remove to an order dictionary until user chooses to stop.\n
    If the order dictionary is empty, returns the last modified version before attempting a removal.
    Returns updated order dictionary
    '''
    # Function to obtain user input for order item removal
    carryOn = True
    while carryOn:
        if not out_dict[key_names[0]]:
            # Empty Dictionaries evaluate to False
            # Dictionary empty, abort removal
            print(f"Nothing to remove from {out_dict}")
            print("Aborting removal operation")
            carryOn = False
        else:
            pick = options_selector(
                out_dict.get(key_names[0]), "Please select the product to remove: "
            )
            print(out_dict)
            for key in key_names:
                del out_dict[key][pick]
            usr_continue = input("Remove another item? (y/n): ")
            if usr_continue.lower() != "y":
                carryOn = False
    return out_dict

def product_selector_amend(out_dict, key_names=("Items", "Quantity")):
    '''
    Recursively gets user input for product to amend and new quantity to update order dictionary until user chooses to stop.\n
    Returns updated order dictionary
    '''
    # Function to obtain user input for order item quantity amendment choice
    carryOn = True
    while carryOn:
        pick = options_selector(
            out_dict.get(key_names[0]), "Please select the product to amend: "
        )
        print(f"Quantity: {out_dict[key_names[1]][pick]}")
        quantity = get_non_negative_int(
            f"Enter New quantity of {out_dict.get(key_names[0])[pick]} desired: "
        )
        out_dict[key_names[1]][pick] = quantity
        usr_continue = input("Amend another item? (y/n): ")
        if usr_continue.lower() != "y":
            carryOn = False
    return out_dict

def product_selector(option:int, items_list, dict_out, key_names=("Items", "Quantity")):
    '''
    Product Selection Operations Mini Menu for alterations to items on an order dictionary\n
    Returns unaltered order dictionary for option out of range\n
    Returns updated order dictionary based on optional function.
    '''
    if option == 0:
        # Cancel, abort operation
        print("Abort Product Select Operation Menu")
    elif option == 1:
        # Add to items to order
        dict_out = product_selector_add(items_list, dict_out, key_names)
    elif option == 2:
        # Remove items from order
        dict_out = product_selector_remove(dict_out, key_names)
    elif option == 3:
        # Amend Count of an item
        dict_out = product_selector_amend(dict_out, key_names)
    else:
        # Out of range, abort
        print("Index not in range, aborting product_selector operation")
    return dict_out


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from xlsxwriter import Workbook
import ibm_db_dbi as db2

cur = db2.connect().cursor()
cur.execute("select cusnum, lstnam, cdtlmt, baldue, cdtdue from qiws.qcustcdt")

headers = [desc[0] for desc in cur.description]

with Workbook('qcustcdt_format.xlsx') as workbook:
    fmt = workbook.add_format({'font_size': 20})

    hdr_fmt = workbook.add_format({'font_size': 20, 'align':'center', 'border':1})
    red_fmt = workbook.add_format({'font_size': 20, 'bg_color': '#FF0000'})

    ws = workbook.add_worksheet()

    ws.conditional_format("D2:D13", {'type': 'cell',
                                     'criteria': '>',
                                     'value': 'C2*0.5',
                                     'format': red_fmt})

    ws.set_column(0, len(headers)-1, 20)

    ws.write_row('A1', headers, hdr_fmt)
    ws.set_row(0, 22)

    for rownum, row in enumerate(cur, start=1):
        ws.write_row(rownum, 0, row)
        ws.set_row(rownum, 22, fmt)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Dec 21 13:52:42 2020

@author: jonasg
"""

# NOTE: these were extracted from one of the NetCDF files, quite a few site
# locations do not contain obsdata (only NaNs), I added a print below in
# case you choose one of such sites accidentally =)
ALL_SITES = ['ATHENS-NOA' 'Agoufou' 'Alta_Floresta' 'Appledore_Island' 'Arcachon'
             'Arica' 'Aubiere_LAMP' 'Autilla' 'Avignon' 'BONDVILLE' 'Bac_Lieu'
             'Bach_Long_Vy' 'Baengnyeong' 'Bambey-ISRA' 'Bandung' 'Banizoumbou'
             'Barcelona' 'Beijing' 'Beijing_RADI' 'Belsk' 'Billerica' 'Blida'
             'Bonanza_Creek' 'Bratts_Lake' 'Brussels' 'Bucharest_Inoe' 'Burjassot'
             'CARTEL' 'CCNY' 'CEILAP-BA' 'CLUJ_UBB' 'COVE_SEAPRISM' 'CRPSM_Malindi'
             'CUIABA-MIRANDA' 'Cabauw' 'Cabo_da_Roca' 'Caceres' 'Cairo_EMA_2'
             'CalTech' 'Camaguey' 'Campo_Grande_SONDA' 'Cape_San_Juan' 'Capo_Verde'
             'Carpentras' 'Cart_Site' 'Chapais' 'Chen-Kung_Univ' 'Chiang_Mai_Met_Sta'
             'Chilbolton' 'Cordoba-CETT' 'DMN_Maine_Soroa' 'Dakar' 'Dayton' 'Dhadnah'
             'Dongsha_Island' 'Dunkerque' 'Dushanbe' 'EPA-NCU' 'Easton_Airport'
             'Eforie' 'Egbert' 'Ersa' 'Evora' 'Fresno' 'GSFC' 'Gandhi_College'
             'Granada' 'Guadeloup' 'Gual_Pahari' 'Gustav_Dalen_Tower' 'Gwangju_GIST'
             'Halifax' 'Hamburg' 'Harvard_Forest' 'Helgoland' 'Helsinki'
             'Hong_Kong_Hok_Tsui' 'Hong_Kong_PolyU' 'Huelva' 'Hyytiala' 'IER_Cinzana'
             'IMS-METU-ERDEMLI' 'Irkutsk' 'Ispra' 'Jaipur' 'Ji_Parana_SE' 'KONZA_EDC'
             'Kanpur' 'Karachi' 'Karlsruhe' 'Kellogg_LTER' 'Kelowna_UAS' 'Kuopio'
             'Kuwait_University' 'Kyiv' 'LISCO' 'LSU' 'La_Laguna' 'La_Parguera'
             'Laegeren' 'Lahore' 'Lake_Argyle' 'Lampedusa' 'Lecce_University'
             'Leipzig' 'Lille' 'London-UCL-UAO' 'MCO-Hanimaadhoo' 'MD_Science_Center'
             'MVCO' 'Mainz' 'Malaga' 'Manila_Observatory' 'Messina' 'Mezaira' 'Minsk'
             'Modena' 'Moldova' 'Moscow_MSU_MO' 'Munich_University' 'Mussafa'
             'NCU_Taiwan' 'NGHIA_DO' 'Nes_Ziona' 'Noto' 'Oostende' 'Osaka' 'Palaiseau'
             'Paris' 'Pickle_Lake' 'Pokhara' 'Pune' 'Ragged_Point' 'Red_River_Delta'
             'Resolute_Bay' 'Rio_Branco' 'Rome_Tor_Vergata' 'SAGRES'
             'SANTA_CRUZ_UTEPSA' 'SEDE_BOKER' 'SERC' 'Saada' 'Santa_Cruz_Tenerife'
             'Sao_Martinho_SONDA' 'Sao_Paulo' 'Saturn_Island' 'Sevastopol' 'Seysses'
             'Shirahama' 'Silpakorn_Univ' 'Singapore' 'Skukuza' 'Solar_Village'
             'Songkhla_Met_Sta' 'TUBITAK_UZAY_Ankara' 'Taihu' 'Taipei_CWB'
             'Thessaloniki' 'Thompson_Farm' 'Tomsk' 'Toravere' 'Toulon' 'UMBC'
             'Ubon_Ratchathani' 'Univ_of_Houston' 'Univ_of_Lethbridge' 'Ussuriysk'
             'Venise' 'Vientiane' 'Villefranche' 'Wallops' 'WaveCIS_Site_CSI_6'
             'Xanthi' 'XiangHe' 'Xinglong' 'Yekaterinburg' 'Zinder_Airport']
result = []

import glob, os
import numpy as np
import pandas as pd
import xarray as xr

data_dir = '/lustre/storeA/project/aerocom/aerocom-users-database/PYAEROCOM_COLDATA/WEB_EVAL/aerocom/AP3-abs'
var_mask = 'abs550' # there is also some called abs550csaer or abs550aercs
exp = '25COV'

# INSERT HERE THE SITES THAT YOU ARE INTERESTED IN
sitenames = ['Alta_Floresta', 'Dakar']

result = {}
for mod in os.listdir(data_dir):
    print(mod)
    files = glob.glob(f'{data_dir}/{mod}/{var_mask}*{exp}*.nc')
    if not len(files) > 0: # ignore folders without data
        print(f'Skip {mod}')
        continue

    # make sure only one filematch
    assert len(files) == 1
    file = files[0]
    var_name = os.path.basename(files[0]).split('_')[0]
    data = xr.open_dataset(file)[var_name]

    print(data.station_name.data)

    #make sure this is in monthly resolution
    assert data.ts_type == 'monthly'

    result[mod] = {}

    timestamps = data.time.data

    for i, site in enumerate(sitenames):
        result[mod][site] = {}
        # get plot axes for this site

        sitedata = data.sel(station_name=site)
        obs_numpy = sitedata.data[0]
        if all(np.isnan(obs_numpy)):
            print(f'No obsdata available at {site}')

        mod_numpy = sitedata.data[1]

        obs_ts = pd.Series(obs_numpy, timestamps)
        mod_ts = pd.Series(obs_numpy, timestamps)

        result[mod][site]['obs'] = obs_ts
        result[mod][site]['mod'] = mod_ts


#!/usr/bin/python
# -*- coding: UTF-8 -*-
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-i', type=str, required=True)
parser.add_argument('-o', type=str, required=True)

def majority(input, output):
	out = open(output,"w")
	with open(input) as f:
		lines = f.readlines()
		for _ in range(len(lines)):
			out.write("0\n")

def main(args):
	majority(args.i, args.o)

if __name__ == '__main__':
	args = parser.parse_args()
	main(args)


import os
from unittest.mock import patch

import numpy as np
import pandas as pd
from numpy.testing import assert_allclose, assert_almost_equal

from autumn.core import db
from autumn.calibration import Calibration, CalibrationMode
from autumn.calibration.utils import (
    sample_starting_params_from_lhs,
    specify_missing_prior_params,
)
from tests.utils import get_mock_model

def test_sample_starting_params_from_lhs__with_lognormal_prior_and_one_sample():
    priors = [
        {
            "param_name": "ice_cream_sales",
            "distribution": "lognormal",
            "distri_params": [-1, 1],
        }
    ]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=1)
    assert_almost_equal(params[0]['ice_cream_sales'],  0.36787944117144233)

def test_sample_starting_params_from_lhs__with_beta_prior_and_one_sample():
    priors = [
        {
            "param_name": "ice_cream_sales",
            "distribution": "beta",
            "distri_mean": 0.05,
            "distri_ci": [0.01, 0.1],
        }
    ]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=1)
    assert_almost_equal(params[0]['ice_cream_sales'],  0.04680260472064115)

def test_sample_starting_params_from_lhs__with_gamma_prior_and_one_sample():
    priors = [
        {
            "param_name": "ice_cream_sales",
            "distribution": "gamma",
            "distri_mean": 5.0,
            "distri_ci": [3.0, 7.0],
        }
    ]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=1)
    assert_almost_equal(params[0]['ice_cream_sales'],  4.932833078981056)

def test_sample_starting_params_from_lhs__with_uniform_prior_and_one_sample():
    priors = [{"param_name": "ice_cream_sales", "distribution": "uniform", "distri_params": [1, 5]}]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=1)
    assert _prepare_params(params) == _prepare_params([{"ice_cream_sales": 3.0}])

def test_sample_starting_params_from_lhs__with_uniform_priors_and_one_sample():
    priors = [
        {"param_name": "ice_cream_sales", "distribution": "uniform", "distri_params": [1, 5]},
        {"param_name": "air_temp", "distribution": "uniform", "distri_params": [1, 10]},
    ]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=1)
    assert _prepare_params(params) == _prepare_params([{"ice_cream_sales": 3.0, "air_temp": 5.5}])

def test_sample_starting_params_from_lhs__with_uniform_prior_and_two_samples():
    priors = [{"param_name": "ice_cream_sales", "distribution": "uniform", "distri_params": [1, 5]}]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=2)
    assert _prepare_params(params) == _prepare_params(
        [{"ice_cream_sales": 2.0}, {"ice_cream_sales": 4.0}]
    )

def test_sample_starting_params_from_lhs__with_uniform_priors_and_two_samples():
    priors = [
        {"param_name": "ice_cream_sales", "distribution": "uniform", "distri_params": [1, 5]},
        {"param_name": "air_temp", "distribution": "uniform", "distri_params": [1, 10]},
    ]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=2)
    assert _prepare_params(params) == _prepare_params(
        [{"ice_cream_sales": 2.0, "air_temp": 3.25}, {"ice_cream_sales": 4.0, "air_temp": 7.75}],
    ) or _prepare_params(params) == _prepare_params(
        [{"ice_cream_sales": 4.0, "air_temp": 3.25}, {"ice_cream_sales": 2.0, "air_temp": 7.75}],
    )

def test_sample_starting_params_from_lhs__with_uniform_prior_and_four_samples():
    priors = [{"param_name": "ice_cream_sales", "distribution": "uniform", "distri_params": [1, 5]}]
    specify_missing_prior_params(priors)
    params = sample_starting_params_from_lhs(priors, n_samples=4)
    assert _prepare_params(params) == _prepare_params(
        [
            {"ice_cream_sales": 1.5},
            {"ice_cream_sales": 2.5},
            {"ice_cream_sales": 3.5},
            {"ice_cream_sales": 4.5},
        ],
    )

def _prepare_params(l):
    return set([tuple(sorted(ps.items())) for ps in l])

from autumn.calibration.priors import UniformPrior
from autumn.calibration.targets import PoissonTarget
from autumn.core.project import Project, ParameterSet, Params

def test_calibrate_autumn_mcmc(temp_data_dir):
    priors = [UniformPrior("ice_cream_sales", [1, 5])]
    target_outputs = [
        PoissonTarget(
            pd.Series(
                [3, 6, 9, 12, 15], [2000, 2001, 2002, 2003, 2004], name="shark_attacks"
            )
        ),
    ]
    calib = Calibration(priors, target_outputs, seed=0)
    calib._no_pickle = True
    params = ParameterSet(Params({"ice_cream_sales": 0, "time": {"start": 2000}}))
    project = Project("hawaii", "sharks", _build_mock_model, params, calib)
    calib.run(project, 1, 1, 1)

    app_dir = os.path.join(temp_data_dir, "outputs", "calibrate", "sharks", "hawaii")
    run_dir = os.path.join(app_dir, os.listdir(app_dir)[0])
    db_paths = db.load.find_db_paths(run_dir)
    assert len(db_paths) == 1
    out_db = db.get_database(db_paths[0])
    assert set(out_db.table_names()) == {
        "derived_outputs",
        "mcmc_run",
        "mcmc_params",
    }
    mcmc_runs = out_db.query("mcmc_run")
    mcmc_params = out_db.query("mcmc_params")
    mle_params = db.process.find_mle_params(mcmc_runs, mcmc_params)
    ice_cream_sales_mle = mle_params["ice_cream_sales"]
    # +++FIXME Should be deterministic now
    assert 2.9 < ice_cream_sales_mle < 3.1

def _build_mock_model(params, build_options=None):
    """
    Fake model building function where derived output "shark_attacks"
    is influenced by the ice_cream_sales input parameter.
    """
    ice_cream_sales = params["ice_cream_sales"]
    vals = [0, 1, 2, 3, 4, 5]
    mock_model = get_mock_model(
        times=np.array([1999, 2000, 2001, 2002, 2003, 2004]),
        outputs=[
            [300.0, 300.0, 300.0, 33.0, 33.0, 33.0, 93.0, 39.0],
            [271.0, 300.0, 271.0, 62.0, 33.0, 62.0, 93.0, 69.0],
            [246.0, 300.0, 246.0, 88.0, 33.0, 88.0, 93.0, 89.0],
            [222.0, 300.0, 222.0, 111.0, 33.0, 111.0, 39.0, 119.0],
            [201.0, 300.0, 201.0, 132.0, 33.0, 132.0, 39.0, 139.0],
            [182.0, 300.0, 182.0, 151.0, 33.0, 151.0, 39.0, 159.0],
        ],
        derived_outputs={
            "shark_attacks": np.array([ice_cream_sales * i for i in vals]),
        },
    )
    return mock_model


import torch
import numpy as np
print("aa")

def gmm_covar(X, means, resps, n_clusters = 2):
    """

    Parameters
    ----------
    X shape (n_samples, n_features).

    resp shape (n_samples, n_clusters).

    means shape (n_classes, n_features).

    n_clusters (default 2).

    Returns
    -------
    Covariance matrix shape (n_features, n_features);
    """
    n_samples = len(X)
    covar_list = []
    for i in range(n_clusters):
        resp = resps[:,i]#.reshape(1, n_samples)
        mean = means[i]
        m = np.sum(resp)
        mean_calculated =  (1/m)*((resp.reshape(n_samples, 1)*X).sum(axis = 0))
        ratio_means = mean/mean_calculated
        print(ratio_means)
        print(ratio_means/X.std(axis = 0))
        print(ratio_means/X.mean(axis = 0))
        print(ratio_means.mean(), ratio_means.std())
        # print(resp.shape, m)
        print(np.exp(mean), mean_calculated)
        a = resp * ((X - mean_calculated).T) # Element wise multiplication  # Shape (n_samples, n_features)
        covar = np.dot(a, (X - mean_calculated))                       # Shape (n_features, n_features)
        covar_list.append(covar)
        covar /= m
    return np.asarray(covar_list)


import ply.lex as lex

# Tokens so small that don't deserve a unique rule (at least they have a good personality)
literals = [',','{','}','=','\'','[',']','.']

# List of token names
tokens = [
    'DATETIME',
    'TIME',
    'HEX',
    'OCT',
    'BIN',
    'FLOAT',
    'INT',
    'INFINITY',
    'NAN',
    'BOOL',
    'WORD',
    'LITERALMULT',
    'QUOTEMULT',
    'LITERALS',
    'STRING',
]

t_WORD = r'[a-zA-Z_\-0-9]+'

def t_LITERALMULT(t):
    r"'''.*'''"
    t.value = str(t.value)[3:-3]
    return t

def t_QUOTEMULT(t):
    r'""".*"""'
    t.value = str(t.value)[3:-3]
    return t

def t_STRING(t):
    r'"[^"]*"'
    t.value = str(t.value)[1:-1]
    return t

def t_LITERALS(t):
    r"'[^']*'"
    t.value = str(t.value)[1:-1]
    return t

def t_DATETIME(t):
    r'\d{4}-\d{2}-\d{2}([Tt]\d{2}:\d{2}:\d{2}([Zz]|(\.\d{6})?((\+|-)\d{2}:\d{2})?))?' # as said in RFC3339 "NOTE: Per [ABNF] and ISO8601, the "T" and "Z" characters in this syntax may alternatively be lower case "t" or "z" respectively."
    t.value = str(t.value).replace("T"," ").replace("Z","+00:00")
    return t

def t_TIME(t):
    r'\d{2}:\d{2}:\d{2}([Zz]|(\.\d{6})?((\+|-)\d{2}:\d{2})?)' #isto depois tem de ser convertido em string para o json
    t.value = str(t.value).replace("T"," ").replace("Z","+00:00")
    return t

def t_BOOL(t):
    r'(true|false)'
    if t.value == "true":
        t.value = bool(True)
    elif t.value == "false":
        t.value = bool(False)
    return t

def t_OCT(t):
    r'0o[0-7_]+'
    filtered = ''.join((filter(lambda x: x != '_', t.value)))
    t.value = int(filtered,8)
    return t

def t_BIN(t):
    r'0b[01_]+'
    filtered = ''.join((filter(lambda x: x != '_', t.value)))
    t.value = int(filtered,2)
    return t

def t_HEX(t):
    r'0x[A-Fa-f0-9_]+'
    filtered = ''.join((filter(lambda x: x != '_', t.value)))
    t.value = int(filtered,16)
    return t

def t_FLOAT(t):
    r'(\+|-)?((\d+_?)+([eE](\+|-)?(\d+_?)+)|(\d+_?)+\.(\d+_?)+([eE](\+|-)?(\d+_?)+)?)'
    t.value = float(str(t.value).replace("_",""))
    return t

def t_INT(t):
    r'(\+|-)?\d+'
    t.value = int(t.value)
    return t

def t_INFINITY(t):
    r'(\+|-)?inf'
    t.value = float(t.value)
    return t

def t_NAN(t):
    r'(\+|-)?nan'
    t.value = float(t.value)
    return t

t_ignore  = ' \t'

def t_ignore_COMMENT(t):
    r'\#.*\n'
    pass

def t_error(t):
    t.lexer.skip(1)

lexer = lex.lex()


import wx, wx.grid
import widget_properties
from widget_properties import GridProperty
from xml.sax.saxutils import escape, quoteattr

class CodeProperty(widget_properties.TextProperty):
    def __init__(self, owner, name='extracode'):
        setattr(owner, name, "")
        def get(): return getattr(owner, name)
        def set(val): return setattr(owner, name, val)
        owner.access_functions[name] = (get, set)
        widget_properties.TextProperty.__init__(self, owner, name, None,
                                                True, multiline=True)

    def _show(self, notebook, label=_('Code')):
        panel, new = _find_or_create_page(notebook, label)
        self.display(panel)
        szr = wx.BoxSizer(wx.VERTICAL)
        szr.Add(self.panel, 1, wx.EXPAND)
        if new:
            panel.SetSizerAndFit(szr)
            notebook.AddPage(panel, label)
        else:
            sizer = panel.GetSizer()
            sizer.Add(szr, 1, wx.EXPAND)
            panel.Layout()

    def display(self, parent):
        self.id = wx.NewId()
        val = self.get_value()
        val = val.replace('\\n', '\n')

        sb = wx.StaticBox(parent, -1, "")

        label = widget_properties.wxGenStaticText(parent, -1,
                                                  _('Extra code for this widget'))
        self._enabler = wx.CheckBox(parent, self.id+1, '')
        tooltip = """\
You can use this property to add some extra code to that generated by wxGlade.

Please note that you should use this ability only if you have the \
"Overwrite existing sources" option set.

NOTE: at the moment, this property is supported only by the following code \
generators:
    Python C++ XRC"""
        style = wx.TE_MULTILINE|wx.HSCROLL
        self.text = wx.TextCtrl(parent, self.id, val, style=style, size=(1, -1))
        font = wx.Font(12, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
                       wx.FONTWEIGHT_NORMAL)
        self.text.SetFont(font)

        label.SetToolTip(wx.ToolTip(tooltip))
        wx.EVT_CHECKBOX(self._enabler, self.id+1,
                        lambda event: self.toggle_active(event.IsChecked()))
        self.text.Enable(self.is_active())
        self._enabler.SetValue(self.is_active())
        self._target = self.text
        szr = wx.BoxSizer(wx.HORIZONTAL)
        szr.Add(label, 1, wx.ALL|wx.EXPAND, 3)
        szr.Add(self._enabler, 0, wx.ALL|wx.EXPAND, 3)
        sizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
        sizer.Add(szr, 0, wx.EXPAND)
        sizer.Add(self.text, 1, wx.ALL|wx.EXPAND, 3)
        h = self.text.GetCharHeight()
        sizer.SetItemMinSize(self.text, -1, h*3)
        self.panel = sizer
        self.bind_event(self.on_change_val)
        wx.EVT_CHAR(self.text, self.on_char)

# end of class CodeProperty

class ExtraPropertiesProperty(GridProperty):
    def __init__(self, owner):
        setattr(owner, 'extraproperties', [])
        def get(): return getattr(owner, 'extraproperties')
        def set(val): return setattr(owner, 'extraproperties', val)
        owner.access_functions['extraproperties'] = (get, set)

        cols = [(_('Property'), GridProperty.STRING),
                (_('Value'), GridProperty.STRING)]
        self.label = _('Extra properties for this widget')
        GridProperty.__init__(self, owner, 'extraproperties', None, cols,
                              can_insert=False)

    def write(self, outfile, tabs):
        if self.getter:
            props = self.getter()
        else:
            props = self.owner[self.name][0]()
        if props:
            written = False
            write = outfile.write
            stab = '    ' * (tabs+1)
            for name, value in props:
                if value:
                    if not written:
                        written = True
                        write('    ' * tabs + '<extraproperties>\n')
                    write('%s<property name=%s>%s</property>\n' %
                          (stab, quoteattr(name), escape(value.strip())))
            if written:
                write('    ' * tabs + '</extraproperties>\n')

    def display(self, panel):
        GridProperty.display(self, panel)
        self.btn.Hide()
        wx.grid.EVT_GRID_CELL_CHANGE(self.grid, self.on_change_val)
        tooltip = """\
You can use this property to add some extra custom properties to this widget.

For each property "prop" with value "val", wxGlade will generate a \
"widget.SetProp(val)" line (or a "<prop>val</prop>" line for XRC).

NOTE: at the moment, this property is supported only by the following code \
generators:
    Python C++ XRC Perl"""
        self.grid.SetToolTip(wx.ToolTip(tooltip))

    def add_row(self, event):
        GridProperty.add_row(self, event)
        self.on_change_val(event)

    def remove_row(self, event):
        GridProperty.remove_row(self, event)
        self.on_change_val(event)

    def set_value(self, val):
        if isinstance(val, dict):
            val = [[k, val[k]] for k in sorted(val.keys())]
        GridProperty.set_value(self, val)

    def _show(self, notebook, label=_('Code')):
        panel, new = _find_or_create_page(notebook, label)
        self.display(panel)
        szr = wx.BoxSizer(wx.VERTICAL)
        szr.Add(self.panel, 1, wx.EXPAND)
        if new:
            panel.SetSizerAndFit(szr)
            notebook.AddPage(panel, _('Code'))
        else:
            sizer = panel.GetSizer()
            sizer.Add(szr, 1, wx.EXPAND)
            sizer.Layout()

# end of class ExtraPropertiesProperty

class ExtraPropertiesPropertyHandler(object):
    def __init__(self, owner):
        self.owner = owner
        self.props = {}
        self.prop_name = None
        self.curr_prop = []

    def start_elem(self, name, attrs):
        if name == 'property':
            self.prop_name = attrs['name']

    def end_elem(self, name):
        if name == 'property':
            if self.prop_name and self.curr_prop:
                self.props[self.prop_name] = ''.join(self.curr_prop)
            self.prop_name = None
            self.curr_prop = []
        elif name == 'extraproperties':
            self.owner.properties['extraproperties'].set_value(self.props)
            val = [[k, self.props[k]] for k in sorted(self.props.keys())]
            self.owner.extraproperties = val
            return True # to remove this handler

    def char_data(self, data):
        data = data.strip()
        if data:
            self.curr_prop.append(data)

# end of class ExtraPropertiesPropertyHandler

def _find_or_create_page(notebook, label):
    """\
    Searches the given notebook for a page whose label is "label".
    """
    for i in xrange(notebook.GetPageCount()):
        if notebook.GetPageText(i) == label:
            return notebook.GetPage(i), False
    return wx.Panel(notebook, -1, style=wx.TAB_TRAVERSAL), True


import yfinance as yf
import sys

import tensorflow as tf

from sklearn.metrics import accuracy_score, mean_squared_error, mean_absolute_percentage_error

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

def prediction(model, original, X_test, scaler, loss = 'mse'):

  prediction = model.predict(X_test)
  prediction = prediction.reshape(prediction.shape[0],1)
  prediction_copies_array = np.repeat(prediction, X_test.shape[2], axis=-1) #change this one

  pred = scaler.inverse_transform(np.reshape(prediction_copies_array,(len(prediction), X_test.shape[2])))[:,3]
  #pred = np.reshape(pred, (len(prediction), X_test.shape[2]))[:, 3]
  if loss == 'mse':
    testScore = mean_squared_error(original, pred)
  if loss == 'mape':
    testScore = mean_absolute_percentage_error(original, pred)

  return pred, testScore

def classification(data, data_main, change):
    if change == 'no change':

        data['Actual_change'] = np.where(data['Close_actual_change'] < data['Close_actual_change'].shift(1), 0, 1)
        data['Pred_change'] = np.where(data['Close_actual_change'] > data['Close_prediction_change'].shift(-1), 0, 1)
        data['Pred_change'] = data.Pred_change.shift(1)
        data = data[1:]
        data['Pred_change'] = data['Pred_change'].astype(int)
        classification_accuracy = len(data[(data.Actual_change == data.Pred_change)]) / len(data)

    elif change == 'absolute':

        data['Actual_change'] = np.where(data['Close_actual_change'] < 0, 0, 1)
        data['Pred_change'] = np.where(data['Close_prediction_change'] < 0, 0, 1)
        data = data[1:]
        data['Pred_change'] = data['Pred_change'].astype(int)
        data['Close_actual'] = data_main.loc['2021-01-01':, 'Close'][30:]
        # data['Close_prediction'] = dataset_test['Close'].shift(1) + data.Close_prediction_change
        classification_accuracy = len(data[(data.Actual_change == data.Pred_change)]) / len(data)

    return data, classification_accuracy

# def plot_results(ticker, df, data, data_tr, pred, change):
#     plt.figure(figsize=(12, 6))
#     y_test_change = data_tr.loc['2021-01-01':]
#     y_test_change = np.array(y_test_change.iloc[30:, 3]) #takes only Close value
#     plt.plot(y_test_change, color='green', label='Real Price')
#     plt.plot(pred, color='purple', label='Predicted Price')
#     plt.title(f'{ticker}')
#     plt.xlabel('Time')
#     plt.ylabel('Price')
#     plt.legend()
#     plt.show()
#
#     if change == 'absolute':
#
#         pd.concat([data.loc['2021-01-01':]['Close'], pd.DataFrame(data.loc['2021-01-01':]['Close'].shift(1) + df.Close_prediction_change)], axis=1)[31:].plot(figsize=(12, 8))
#         plt.title('Close Absolute Change Prediction')
#
#         pd.concat([data.loc['2021-01-01':]['Close'][31:], pd.DataFrame(data.loc['2021-01-01':]['Close'][31] + df.Close_prediction_change)], axis=1).plot(figsize=(12, 8))
#         plt.title('Close Absolute Change Prediction (only adding changes)')
#
#     else:
#         pass


import asyncio
import logging
import selectors
from collections import defaultdict
from dataclasses import dataclass, field
from typing import ClassVar, List, Tuple, Type

import arrow
import requests
from django.apps import apps
from django.conf import settings
from django.utils.encoding import force_text
from prometheus_client.parser import text_string_to_metric_families
from prometheus_client.samples import Sample

from bkmonitor.utils.consul import BKConsul
from bkmonitor.utils.custom_report_tools import custom_report_tool
from metadata.models import DataSource

logger = logging.getLogger(__name__)

GlobalConfig = apps.get_model("bkmonitor.GlobalConfig")

@dataclass
class Deformer:
    """Transfer 原生指标转换器"""

    KEY: ClassVar[str]

    sample: Sample

    def get_dimensions(self) -> dict:
        raise NotImplementedError

@dataclass
class PipelineBackendHandledTotal(Deformer):
    """transfer_pipeline_backend_handled_total"""

    KEY = "transfer_pipeline_backend_handled_total"

    def get_dimensions(self) -> dict:
        """ """
        return {"data_id": self.sample.labels.get("id"), "pipeline": self.sample.labels.get("pipeline")}

@dataclass
class PipelineFrontendHandledTotal(Deformer):
    """transfer_pipeline_frontend_handled_total"""

    KEY = "transfer_pipeline_frontend_handled_total"

    def get_dimensions(self) -> dict:
        """ """
        return {"data_id": self.sample.labels.get("id"), "pipeline": self.sample.labels.get("pipeline")}

DEFAULT_DEFORMERS = [PipelineBackendHandledTotal, PipelineFrontendHandledTotal]

@dataclass
class TransferMetricHelper:
    """Transfer 指标小助手"""

    consul_client: BKConsul = field(default_factory=BKConsul)
    # transfer 运营指标变形器列表，由运营侧指定其关注内容
    deformers: List[Type["Deformer"]] = field(default_factory=lambda: DEFAULT_DEFORMERS)
    metrics: list = field(default_factory=list)

    TARGET_HOST_TERM: ClassVar[str] = "service_host"
    TARGET_PORT_TERM: ClassVar[str] = "service_port"
    KEY_PREFIX: ClassVar[str] = f"{settings.APP_CODE}_{settings.PLATFORM}_{settings.ENVIRONMENT}/service/v1/"
    TARGET_LABEL: ClassVar[str] = "transfer_cluster"

    def __post_init__(self):
        self.deformers_map = {x.KEY: x for x in self.deformers}

    def ingest_keys(self, _prefix: str, keys: List[str]) -> List[Tuple[str, str]]:
        """消化原始 keys 提供 session 级的 transfer 实例数据"""
        targets = defaultdict(dict)
        for key in keys:
            parts = key[len(_prefix) :].split("/")
            parts = [x for x in parts if x]

            # 存在 data_id\influx_db 等其他 key 内容，忽略
            if not parts or not parts[1] == "session":
                continue

            transfer_cluster_name = parts[0]
            session = parts[2]
            _field = parts[3]
            if _field not in [self.TARGET_HOST_TERM, self.TARGET_PORT_TERM]:
                continue

            targets[f"{transfer_cluster_name}:{session}"][_field] = key

        """
        返回值示例
            [
               (
                   "bkmonitorv3_ieod_production/service/v1/foo/session/bar/service_host",
                   "bkmonitorv3_ieod_production/service/v1/foo/session/bar/service_port"
               ),
               (
                   "bkmonitorv3_ieod_production/service/v1/foo/session/baz/service_host",
                   "bkmonitorv3_ieod_production/service/v1/foo/session/baz/service_port"
               ),
            ]
        """
        return [(x[self.TARGET_HOST_TERM], x[self.TARGET_PORT_TERM]) for x in targets.values()]

    def fetch_target_url(self, key_pair: Tuple[str, str]) -> str:
        """通过 consul key 组装成采集目标 URL"""
        value_pair = []
        # key_pair: (xxx/service_host, xxxx/service_port)
        for key in key_pair:
            _, result = self.consul_client.kv.get(key)
            value_pair.append(force_text(result["Value"]))

        target_url = f"http://{':'.join(value_pair)}/metrics"
        return target_url

    def get_coarse_keys(self):
        """拉取所需的粗粒度 key"""

        # Q: 为什么不逐级拉取 transfer cluster 的数据？
        # A: 首先，Consul.kv.get() 中 recurse 参数无法在此处生效(原因未知)
        #    其次，一口气拉取所有可能的 key，统一在内存中处理可以减少和 consul 的交互次数(有 cluster 和 session 两级)
        _, coarse_keys = self.consul_client.kv.get(self.KEY_PREFIX, keys=True)
        coarse_keys = coarse_keys or []

        logger.debug("Got %s keys", len(coarse_keys))
        return coarse_keys

    async def fetch_metrics(self, _target_url: str):
        """拉取各个节点的 metrics 数据"""

        _metrics = defaultdict(list)
        logger.debug(_target_url)
        with requests.get(_target_url) as resp:
            for family in text_string_to_metric_families(resp.text):
                for sample in family.samples:
                    # 仅保留我们关心的运营指标，其余内容忽略
                    if sample.name not in self.deformers_map.keys():
                        continue

                    _metrics[sample.name].append(sample)

        return _metrics

    async def _fetch(self, loop, target_keys: list):
        tasks = []

        for _target in target_keys:
            target_url = self.fetch_target_url(_target)

            task = loop.create_task(self.fetch_metrics(target_url))
            tasks.append(task)

        if not tasks:
            logger.warning("Failed to get target key from consul[%s]", self.KEY_PREFIX)
            return

        finished, _ = await asyncio.wait(tasks)
        timestamp = arrow.now().timestamp * 1000
        for metrics in finished:
            result = metrics.result()
            if result:
                self.metrics.extend(self._transfer(timestamp, result.values()))

    def _transfer(self, timestamp: int, samples_list: List[Sample]) -> List[dict]:
        """将 Prometheus Sample 转换成目标数据格式"""
        data = []
        for samples in samples_list:
            for sample in samples:
                deformer = self.deformers_map[sample.name](sample)
                data.append(
                    {
                        # 指标，必需项
                        "metrics": {sample.name: sample.value},
                        # 来源标识
                        "target": self.TARGET_LABEL,
                        "timestamp": timestamp,
                        "dimension": deformer.get_dimensions(),
                    }
                )

        return data

    def fetch(self):
        """从 transfer 节点获取运营指标"""
        target_keys = self.ingest_keys(self.KEY_PREFIX, self.get_coarse_keys())
        logger.debug("Got %s target keys", len(target_keys))

        selector = selectors.SelectSelector()
        loop = asyncio.SelectorEventLoop(selector)

        try:
            loop.run_until_complete(self._fetch(loop, target_keys))
        finally:
            loop.close()

        logger.debug("Got metrics: %s", len(self.metrics))

    def report(self):
        """将已加工过的数据上报到链路"""
        try:
            bk_data_id = int(GlobalConfig.objects.get(key="STATISTICS_REPORT_DATA_ID").value)
        except GlobalConfig.DoesNotExist:
            bk_data_id = settings.STATISTICS_REPORT_DATA_ID

        report_tool = custom_report_tool(bk_data_id)
        report_tool.send_data_by_http(self.metrics, access_token=DataSource.objects.get(bk_data_id=bk_data_id).token)
        logger.info("已经发送了 %s 条 Transfer 运营数据到 data_id: %s 中", len(self.metrics), bk_data_id)


import os
from typing import Any, Dict, List

import boto3
import requests
from aws_requests_auth.aws_auth import AWSRequestsAuth
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
from chaoslib.discovery.discover import (
    discover_actions,
    discover_activities,
    discover_probes,
    initialize_discovery_result,
)
from chaoslib.exceptions import InterruptExecution
from chaoslib.types import Configuration, DiscoveredActivities, Discovery, Secrets
from logzero import logger

__version__ = "0.25.0"
__all__ = ["__version__", "discover", "aws_client", "signed_api_call"]

def get_credentials(secrets: Secrets = None) -> Dict[str, str]:
    """
    Credentials may be provided via the secrets object. When they aren't,
    they will be loaded from the process environment (for instance, read from
    `~/.aws/credentials`).

    See: https://boto3.readthedocs.io/en/latest/guide/configuration.html#guide-configuration
    """  # noqa: E501
    creds = dict(
        aws_access_key_id=None, aws_secret_access_key=None, aws_session_token=None
    )

    if secrets:
        creds["aws_access_key_id"] = secrets.get("aws_access_key_id")
        creds["aws_secret_access_key"] = secrets.get("aws_secret_access_key")
        creds["aws_session_token"] = secrets.get("aws_session_token")

    return creds

def aws_client(
    resource_name: str, configuration: Configuration = None, secrets: Secrets = None
):
    """
    Create a boto3 client for the given resource.

    You may pass the `aws_region` key in the `configuration` object to
    be explicit about which region you want to use.

    You may pass `aws_profile_name` value to the `configuration` object so that
    we load the appropriate profile to converse with the AWS services. In that
    case, make sure your local `~/aws/credentials` config is properly setup, as
    per https://boto3.readthedocs.io/en/latest/guide/configuration.html#aws-config-file

    Also, if you want to assume a role, you should setup that file as per
    https://boto3.readthedocs.io/en/latest/guide/configuration.html#assume-role-provider
    as we do not read those settings from the `secrets` object.
    """  # noqa: E501
    configuration = configuration or {}
    aws_profile_name = configuration.get("aws_profile_name")
    aws_assume_role_arn = configuration.get("aws_assume_role_arn")
    params = get_credentials(secrets)

    region = configuration.get("aws_region")
    if not region:
        logger.debug(
            "The configuration key `aws_region` is not set, looking in the "
            "environment instead for `AWS_REGION` or `AWS_DEFAULT_REGION`"
        )
        region = os.getenv("AWS_REGION", os.getenv("AWS_DEFAULT_REGION"))
        if not region:
            raise InterruptExecution("AWS requires a region to be set!")

    if region:
        logger.debug(f"Using AWS region '{region}'")
        params["region_name"] = region

    if boto3.DEFAULT_SESSION is None:
        # we must create our own session so that we can populate the profile
        # name when it is provided. Only create the default session once.
        boto3.setup_default_session(profile_name=aws_profile_name, **params)

    if not aws_assume_role_arn:
        logger.debug(
            "Client will be using profile '{}' from boto3 session".format(
                aws_profile_name or "default"
            )
        )
        return boto3.client(resource_name, **params)
    else:
        logger.debug(
            "Fetching credentials dynamically assuming role '{}'".format(
                aws_assume_role_arn
            )
        )

        aws_assume_role_session_name = configuration.get("aws_assume_role_session_name")
        if not aws_assume_role_session_name:
            aws_assume_role_session_name = "ChaosToolkit"
            logger.debug(
                "You are missing the `aws_assume_role_session_name` "
                "configuration key. A unique one was generated: '{}'".format(
                    aws_assume_role_session_name
                )
            )

        client = boto3.client("sts", **params)
        params = {
            "RoleArn": aws_assume_role_arn,
            "RoleSessionName": aws_assume_role_session_name,
        }
        response = client.assume_role(**params)
        creds = response["Credentials"]
        logger.debug(
            "Temporary credentials will expire on {}".format(
                creds["Expiration"].isoformat()
            )
        )

        params = {
            "aws_access_key_id": creds["AccessKeyId"],
            "aws_secret_access_key": creds["SecretAccessKey"],
            "aws_session_token": creds["SessionToken"],
        }
        if region:
            params["region_name"] = region

        return boto3.client(resource_name, **params)

def signed_api_call(
    service: str,
    path: str = "/",
    method: str = "GET",
    configuration: Configuration = None,
    secrets: Secrets = None,
    params: Dict[str, Any] = None,
) -> requests.Response:
    """
    Perform an API call against an AWS service.

    This should only be used when boto does not already implement the service
    itself. See https://boto3.readthedocs.io/en/latest/reference/services/index.html

    for a list of supported services by boto. This function does not claim
    being generic enough to support the whole range of AWS API.

    The `configuration` object should look like this:

    ```json
    {
        "aws_region": "us-east-1",
        "aws_host": "amazonaws.com"
    }
    ```

    While both are optional, and default to the values shown in this snippet,
    you should make sure to be explicit about them to avoid confusion.

    The endpoint being called is built from the given `service` name, the
    given region and host as well as the `path` of the action being called on
    the service. By default, the call is made over `HTTPS` but this can be
    changed by setting `aws_endpoint_scheme` in the configuration dictionary.

    Pass any parameters of the API itself as part of the remaining `params`
    paramater is a dictionary. It should match the signature of the service
    you are trying to call and will be sent as a query-string when `method` is
    `"GET"` or `"DELETE"`, or as a JSON payload otherwise. Refer to the AWS
    documentation for each service type.

    This function does not support profile names so you must provide the
    credentials in secrets.
    """  # noqa: E501
    configuration = configuration or {}
    region = configuration.get("aws_region", "us-east-1") or ""
    host = configuration.get("aws_host", "amazonaws.com")
    scheme = configuration.get("aws_endpoint_scheme", "https")
    host = f"{service}.{region}.{host}"
    endpoint = configuration.get("aws_endpoint", f"{scheme}://{host}").replace(
        "..", "."
    )
    endpoint = f"{endpoint}{path}"
    creds = get_credentials(secrets)

    # when creds weren't provided via secrets, we let boto search for them
    # from the process environment

    if creds["aws_access_key_id"] and creds["aws_secret_access_key"]:
        auth = AWSRequestsAuth(
            aws_access_key=creds["aws_access_key_id"],
            aws_secret_access_key=creds["aws_secret_access_key"],
            aws_host=host,
            aws_region=region,
            aws_service=service,
        )
    else:
        auth = BotoAWSRequestsAuth(
            aws_host=host, aws_region=region, aws_service=service
        )

    headers = {"Accept": "application/json"}

    if method in ("DELETE", "GET"):
        return requests.request(
            method, endpoint, headers=headers, auth=auth, params=params
        )

    return requests.request(method, endpoint, headers=headers, auth=auth, json=params)

def discover(discover_system: bool = True) -> Discovery:
    """
    Discover AWS capabilities from this extension as well, if a aws
    configuration is available, some information about the AWS environment.
    """
    logger.info("Discovering capabilities from chaostoolkit-aws")

    discovery = initialize_discovery_result("chaostoolkit-aws", __version__, "aws")
    discovery["activities"].extend(load_exported_activities())

    return discovery

###############################################################################
# Private functions
###############################################################################
def load_exported_activities() -> List[DiscoveredActivities]:
    """
    Extract metadata from actions and probes exposed by this extension.
    """
    activities = []
    activities.extend(discover_actions("chaosaws.ec2.actions"))
    activities.extend(discover_probes("chaosaws.ec2.probes"))
    activities.extend(discover_actions("chaosaws.ecs.actions"))
    activities.extend(discover_probes("chaosaws.ecs.probes"))
    activities.extend(discover_actions("chaosaws.iam.actions"))
    activities.extend(discover_probes("chaosaws.iam.probes"))
    activities.extend(discover_actions("chaosaws.eks.actions"))
    activities.extend(discover_probes("chaosaws.eks.probes"))
    activities.extend(discover_actions("chaosaws.elbv2.actions"))
    activities.extend(discover_probes("chaosaws.elbv2.probes"))
    activities.extend(discover_actions("chaosaws.asg.actions"))
    activities.extend(discover_probes("chaosaws.asg.probes"))
    activities.extend(discover_actions("chaosaws.awslambda.actions"))
    activities.extend(discover_probes("chaosaws.awslambda.probes"))
    activities.extend(discover_actions("chaosaws.cloudwatch.actions"))
    activities.extend(discover_probes("chaosaws.cloudwatch.probes"))
    activities.extend(discover_actions("chaosaws.rds.actions"))
    activities.extend(discover_probes("chaosaws.rds.probes"))
    activities.extend(discover_actions("chaosaws.elasticache.actions"))
    activities.extend(discover_probes("chaosaws.elasticache.probes"))
    activities.extend(discover_actions("chaosaws.emr.actions"))
    activities.extend(discover_probes("chaosaws.emr.probes"))
    activities.extend(discover_actions("chaosaws.route53.actions"))
    activities.extend(discover_probes("chaosaws.route53.probes"))
    activities.extend(discover_actions("chaosaws.ssm.actions"))
    activities.extend(discover_actions("chaosaws.fis.actions"))
    activities.extend(discover_probes("chaosaws.s3.probes"))
    activities.extend(discover_actions("chaosaws.s3.actions"))
    activities.extend(discover_activities("chaosaws.s3.controls.upload", "control"))
    activities.extend(discover_probes("chaosaws.xray.probes"))
    return activities


import time
import sys
from app.common import definitions, values
from app.common.utilities import error_exit, save_current_state, load_state
from app.tools import translator, emitter, reader, writer, logger

translated_script_list = dict()

def translate_scripts():
    global translated_script_list
    logger.trace(__name__ + ":" + sys._getframe().f_code.co_name, locals())
    if not values.diff_transformation_info:
        error_exit("nothing to translate")

    generated_script_list = values.diff_transformation_info
    translated_script_list = dict()
    for file_list, generated_data in generated_script_list.items():
        emitter.sub_sub_title(file_list[0])
        translated_script, original_script = translator.translate_script_list(file_list, generated_data)
        translated_script_list[file_list] = (translated_script, original_script)
        emitter.highlight("\tTranslated AST script")
        emitter.emit_ast_script(translated_script)

def safe_exec(function_def, title, *args):
    start_time = time.time()
    emitter.sub_title("Starting " + title + "...")
    description = title[0].lower() + title[1:]
    try:
        if not args:
            result = function_def()
        else:
            result = function_def(*args)
        duration = format((time.time() - start_time) / 60, '.3f')
        emitter.success("\n\tSuccessful " + description + ", after " + duration + " minutes.")
    except Exception as exception:
        duration = format((time.time() - start_time) / 60, '.3f')
        emitter.error("Crash during " + description + ", after " + duration + " minutes.")
        error_exit(exception, "Unexpected error during " + description + ".")
    return result

def load_values():
    load_state()
    if values.DEFAULT_OPERATION_MODE not in [1, 2]:
        if not values.ast_map:
            values.ast_map = reader.read_ast_map(definitions.FILE_AST_MAP_LOCAL)
        if not values.map_namespace_global:
            values.map_namespace_global = reader.read_namespace_map(definitions.FILE_NAMESPACE_MAP_GLOBAL)

    definitions.FILE_TRANSLATED_SCRIPT_INFO = definitions.DIRECTORY_OUTPUT + "/trans-script-info"

def save_values():
    writer.write_script_info(translated_script_list, definitions.FILE_TRANSLATED_SCRIPT_INFO)
    values.ast_transformation_info = translated_script_list
    save_current_state()

def start():
    global translated_script_list
    emitter.title("Translate AST Script")
    load_values()
    if values.PHASE_SETTING[definitions.PHASE_TRANSLATION]:
        safe_exec(translate_scripts, "translation of generated scripts")
        save_values()
    else:
        emitter.special("\n\t-skipping this phase-")


import scraper
import xlsxwriter

workbook = xlsxwriter.Workbook('data.xlsx')
main = workbook.add_worksheet()
schedule = workbook.add_worksheet()

data = scraper.data
headers1 = scraper.headers1
headers2 = ["Class (CRN)"] + scraper.headers2

r, c = 0,0
for header in headers1:
    main.write(r, c, header)
    c += 1
c = 0
for header in headers2:
    schedule.write(r, c, header)
    c+=1
r, rs = 1, 1
for row in data:
    main.write(r, 0, row["CRN"])
    main.write(r, 1, row["Subj"])
    main.write(r, 2, row["Crse"])
    main.write(r, 3, row["Sec"])
    main.write(r, 4, row["Units"])
    main.write(r, 5, row["Title"])
    main.write(r, 6, row["Campus"])
    r += 1
    for day in row["Schedule"]:
        schedule.write(rs, 0, row["CRN"])
        schedule.write(rs, 1, day["StartDate"])
        schedule.write(rs, 2, day["EndDate"])
        schedule.write(rs, 3, day["Days"])
        schedule.write(rs, 4, day["Times"])
        schedule.write(rs, 5, day["Bldg"])
        schedule.write(rs, 6, day["Room"])
        rs += 1
    schedule.write(rs, 0, "")
    rs += 1

workbook.close()
print("xls file created")


# -*- coding: utf-8 -*-
# @File    : check_mask.py
# @Time    : 02/02/2023
# @Author  : Fanyi Sun
# @Github  : https://github.com/sunfanyi
# @Software: PyCharm

import os
import numpy as np
import skimage.io
import matplotlib.pyplot as plt

dataset_dir = os.path.abspath("")

file_name = 'aeroplaneFGL1_BGL1\\n02690373_16'
annotation_path = os.path.join(dataset_dir, 'annotations', file_name) + '.npz'
image_path = os.path.join(dataset_dir, 'images', file_name) + '.jpeg'

annotation = np.load(annotation_path, allow_pickle=True)
image = skimage.io.imread(image_path)

plt.figure()
plt.imshow(image.astype(np.uint8))
plt.axis('off')
plt.show()

print(annotation.files)
print(annotation['source'])
print(image.shape)

mask = (annotation['mask'] > 200)
plt.figure()
plt.title('occluded original mask')
plt.axis('off')
plt.imshow(mask.astype(np.uint8))
plt.show()

color = [255, 100, 100]
masked_image = image.copy()
alpha = 0.5
for c in range(3):
    masked_image[:, :, c] = np.where(mask == 1,
                                     # image[:, :, c] *
                                     (1 - alpha) + alpha * color[c] * 255,
                                     image[:, :, c])

plt.figure()
plt.title('masked_image')
plt.axis('off')
plt.imshow(masked_image.astype(np.uint8))
plt.show()


# 导入类库
import numpy as np
from numpy import arange
from matplotlib import pyplot
from pandas import read_csv
from pandas import  set_option
from pandas.plotting import scatter_matrix
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
from sklearn.tree import DecisionTreeRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.svm import SVR
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.ensemble import ExtraTreesRegressor
from sklearn.ensemble import AdaBoostRegressor
from sklearn.metrics import mean_squared_error

# 导入数据
filename = 'housing.csv'
names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS',
         'RAD', 'TAX', 'PRTATIO', 'B', 'LSTAT', 'MEDV']
dataset = read_csv(filename, names=names, delim_whitespace=True)

# 数据维度
print(dataset.shape)

# 特征熟悉的字段类型
print(dataset.dtypes)

# 查看最开始的30条记录
set_option('display.line_width', 120)
print(dataset.head(30))

# 描述性统计信息
set_option('precision', 1)
print(dataset.describe())

# 关联关系
set_option('precision', 2)
print(dataset.corr(method='pearson'))

# 直方图
dataset.hist(sharex=False, sharey=False, xlabelsize=1, ylabelsize=1)
pyplot.show()

# 密度图
dataset.plot(kind='density', subplots=True, layout=(4,4), sharex=False, fontsize=1)
pyplot.show()

# 箱线图
dataset.plot(kind='box', subplots=True, layout=(4,4), sharex=False, sharey=False, fontsize=8)
pyplot.show()

# 散点矩阵图
scatter_matrix(dataset)
pyplot.show()

# 相关矩阵图
fig = pyplot.figure()
ax = fig.add_subplot(111)
cax = ax.matshow(dataset.corr(), vmin=-1, vmax=1, interpolation='none')
fig.colorbar(cax)
ticks = np.arange(0, 14, 1)
ax.set_xticks(ticks)
ax.set_yticks(ticks)
ax.set_xticklabels(names)
ax.set_yticklabels(names)
pyplot.show()

# 分离数据集
array = dataset.values
X = array[:, 0:13]
Y = array[:, 13]
validation_size = 0.2
seed = 7
X_train, X_validation, Y_train, Y_validation = train_test_split(X, Y,test_size=validation_size, random_state=seed)

# 评估算法 - 评估标准
num_folds = 10
seed = 7
scoring = 'neg_mean_squared_error'

# 评估算法 - baseline
models = {}
models['LR'] = LinearRegression()
models['LASSO'] = Lasso()
models['EN'] = ElasticNet()
models['KNN'] = KNeighborsRegressor()
models['CART'] = DecisionTreeRegressor()
models['SVM'] = SVR()
# 评估算法
results = []
for key in models:
    kfold = KFold(n_splits=num_folds, random_state=seed)
    cv_result = cross_val_score(models[key], X_train, Y_train, cv=kfold, scoring=scoring)
    results.append(cv_result)
    print('%s: %f (%f)' % (key, cv_result.mean(), cv_result.std()))
#评估算法 - 箱线图
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results)
ax.set_xticklabels(models.keys())
pyplot.show()

# 评估算法 - 正态化数据
pipelines = {}
pipelines['ScalerLR'] = Pipeline([('Scaler', StandardScaler()), ('LR', LinearRegression())])
pipelines['ScalerLASSO'] = Pipeline([('Scaler', StandardScaler()), ('LASSO', Lasso())])
pipelines['ScalerEN'] = Pipeline([('Scaler', StandardScaler()), ('EN', ElasticNet())])
pipelines['ScalerKNN'] = Pipeline([('Scaler', StandardScaler()), ('KNN', KNeighborsRegressor())])
pipelines['ScalerCART'] = Pipeline([('Scaler', StandardScaler()), ('CART', DecisionTreeRegressor())])
pipelines['ScalerSVM'] = Pipeline([('Scaler', StandardScaler()), ('SVM', SVR())])
results = []
for key in pipelines:
    kfold = KFold(n_splits=num_folds, random_state=seed)
    cv_result = cross_val_score(pipelines[key], X_train, Y_train, cv=kfold, scoring=scoring)
    results.append(cv_result)
    print('%s: %f (%f)' % (key, cv_result.mean(), cv_result.std()))
#评估算法 - 箱线图
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results)
ax.set_xticklabels(models.keys())
pyplot.show()

# 调参改进算法 - KNN
scaler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
param_grid = {'n_neighbors': [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]}
model = KNeighborsRegressor()
kfold = KFold(n_splits=num_folds, random_state=seed)
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring, cv=kfold)
grid_result = grid.fit(X=rescaledX, y=Y_train)

print('最优：%s 使用%s' % (grid_result.best_score_, grid_result.best_params_))
cv_results = zip(grid_result.cv_results_['mean_test_score'],
                 grid_result.cv_results_['std_test_score'],
                 grid_result.cv_results_['params'])
for mean, std, param in cv_results:
    print('%f (%f) with %r' % (mean, std, param))

# 集成算法
ensembles = {}
ensembles['ScaledAB'] = Pipeline([('Scaler', StandardScaler()), ('AB', AdaBoostRegressor())])
ensembles['ScaledAB-KNN'] = Pipeline([('Scaler', StandardScaler()),
                                       ('ABKNN', AdaBoostRegressor(base_estimator=KNeighborsRegressor(n_neighbors=3)))])
ensembles['ScaledAB-LR'] = Pipeline([('Scaler', StandardScaler()), ('ABLR', AdaBoostRegressor(LinearRegression()))])
ensembles['ScaledRFR'] = Pipeline([('Scaler', StandardScaler()), ('RFR', RandomForestRegressor())])
ensembles['ScaledETR'] = Pipeline([('Scaler', StandardScaler()), ('ETR', ExtraTreesRegressor())])
ensembles['ScaledGBR'] = Pipeline([('Scaler', StandardScaler()), ('RBR', GradientBoostingRegressor())])

results = []
for key in ensembles:
    kfold = KFold(n_splits=num_folds, random_state=seed)
    cv_result = cross_val_score(ensembles[key], X_train, Y_train, cv=kfold, scoring=scoring)
    results.append(cv_result)
    print('%s: %f (%f)' % (key, cv_result.mean(), cv_result.std()))

# 集成算法 - 箱线图
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results)
ax.set_xticklabels(ensembles.keys())
pyplot.show()

# 集成算法GBM - 调参
scaler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
param_grid = {'n_estimators': [10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900]}
model = GradientBoostingRegressor()
kfold = KFold(n_splits=num_folds, random_state=seed)
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring, cv=kfold)
grid_result = grid.fit(X=rescaledX, y=Y_train)
print('最优：%s 使用%s' % (grid_result.best_score_, grid_result.best_params_))

# 集成算法ET - 调参
scaler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
param_grid = {'n_estimators': [5, 10, 20, 30, 40, 50, 60, 70, 80]}
model = ExtraTreesRegressor()
kfold = KFold(n_splits=num_folds, random_state=seed)
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring, cv=kfold)
grid_result = grid.fit(X=rescaledX, y=Y_train)
print('最优：%s 使用%s' % (grid_result.best_score_, grid_result.best_params_))

#训练模型
scaler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
gbr = ExtraTreesRegressor(n_estimators=80)
gbr.fit(X=rescaledX, y=Y_train)
# 评估算法模型
rescaledX_validation = scaler.transform(X_validation)
predictions = gbr.predict(rescaledX_validation)
print(mean_squared_error(Y_validation, predictions))


from sklearn.metrics import average_precision_score
import pandas as pd
import numpy as np

def mAP_score(preds: pd.DataFrame, trues: pd.DataFrame):
    """ Funkcja obliczająca wynik modelu sieci neuronowej

        :param preds: Wartości przewidywane przez model
        :type preds: pd.DataFrame
        :param trues: Wartości prawdziwe
        :type trues: pd.DataFrame
        :return: Ogólny wynik modelu oraz wyniki dla każdej z cech w postaci listy
        :rtype: float, list
        """
    labels_score = []
    trues = trues.replace(-1,0)
    score = 0.0
    for p, t in zip(preds, trues):
        ap = 0.0
        if np.sum(trues[t]) != 0:
            ap = average_precision_score(trues[t], preds[p])
        labels_score.append(ap)
        score += ap

    score /= preds.shape[1]

    return score, labels_score