import numpy as np
import torch

def nms(boxes, scores, overlap=0.5, top_k=200):
    """Apply non-maximum suppression at test time to avoid detecting too many
    overlapping bounding boxes for a given object.
    Args:
        boxes: (tensor) The location preds for the img, Shape: [num_priors,4].
        scores: (tensor) The class predscores for the img, Shape:[num_priors].
        overlap: (float) The overlap thresh for suppressing unnecessary boxes.
        top_k: (int) The Maximum number of box preds to consider.
    Return:
        The indices of the kept boxes with respect to num_priors.
    """

    keep = scores.new(scores.size(0)).zero_().long()
    if boxes.numel() == 0:
        return keep
    x1 = boxes[:, 0]  #输入boxes的所有框的x1
    y1 = boxes[:, 1]  #输入boxes的所有框的y1
    x2 = boxes[:, 2]  #输入boxes的所有框的x2
    y2 = boxes[:, 3]  #输入boxes的所有框的y2
    area = torch.mul(x2 - x1, y2 - y1)
    v, idx = scores.sort(0)  # sort in ascending order  小->大
    # I = I[v >= 0.01]
    idx = idx[-top_k:]  # indices of the top-k largest vals 取前200个大的
    xx1 = boxes.new()
    yy1 = boxes.new()
    xx2 = boxes.new()
    yy2 = boxes.new()
    w = boxes.new()
    h = boxes.new()

    # keep = torch.Tensor()
    count = 0
    while idx.numel() > 0: #前top_k个框列表中若还有框
        i = idx[-1]  # index of current largest val 取最大的框序号为i
        # keep.append(i)
        keep[count] = i #用keep列表记住取出的框的顺序
        count += 1
        if idx.size(0) == 1:
            break
        idx = idx[:-1]  # remove kept element from view 框序号列表中去掉当前最大的框序号
        # load bboxes of next highest vals
        xx1 = torch.index_select(x1, 0, idx) #xx1是 idx框中的x1
        yy1 = torch.index_select(y1, 0, idx)#yy1是 idx框中的y1
        xx2 = torch.index_select(x2, 0, idx)#xx2是 idx框中的x2
        yy2 = torch.index_select(y2, 0, idx)#yy1是 idx框中的y2
        # store element-wise max with next highest score
        #print(x1[i])
        xx1 = torch.clamp(xx1, min=x1[i].item())
        yy1 = torch.clamp(yy1, min=y1[i].item())
        xx2 = torch.clamp(xx2, max=x2[i].item())
        yy2 = torch.clamp(yy2, max=y2[i].item())
        # w.reshape_as(xx2)
        # h.reshape_as(yy2)
        w = xx2 - xx1
        h = yy2 - yy1
        # check sizes of xx1 and xx2.. after each iteration
        w = torch.clamp(w, min=0.0)
        h = torch.clamp(h, min=0.0)
        inter = w*h
        # IoU = i / (area(a) + area(b) - i)
        rem_areas = torch.index_select(area, 0, idx)  # load remaining areas)
        union = (rem_areas - inter) + area[i]
        IoU = inter/union  # store result in iou  计算idx中所有框与当前分类置信度最大框的IOU
        # keep only elements with an IoU <= overlap
        idx = idx[IoU.le(overlap)] #idx中IoU大于overlap的框都去除
    return keep, count#keep是同一类中，每个个体的框的序号，count则是个数

def generateProirBox(num_prior_box=[4,6,6,6,4,4]):
    m = len(num_prior_box)

    scale_list = []
    min_scale = 0.2
    max_scale = 0.9  #论文没写voc的 网上应该使用原始代码看的

    offset = 0.5

    feature_size = [38,19,10,5,3,1]
    # step_list = [8, 16, 32, 64, 100, 300]

    scale_list = [0.1]
    #论文说是0.2到0.9 但是实际voc的是第一层是0.1 后面5层才是0.2-0.9,
    #然后最后一个最大的框为1.05论文也没说明
    for i in range(m):
        k = i+1
        sk = min_scale+(max_scale-min_scale)/(m-1)*(k-1)
        scale_list.append(sk)
    scale_list.append(1.05)
    #print(scale_list)
    #[0.1, 0.2, 0.34, 0.48, 0.62, 0.76, 0.9, 1.05]

    prior_boxes = [] # cx cy w h

    cw_list =[]
    for i in range(m):

        for x in range(feature_size[i]):
            for y in range(feature_size[i]):
                cx = (x+offset)/feature_size[i]
                cy = (y+offset)/feature_size[i]

                if num_prior_box[i]==4:
                    aspect_ratio = [1,2,1/2]

                elif num_prior_box[i]==6:
                    aspect_ratio = [1,2,3,1/2,1/3]

                else:
                    pass

                for a in aspect_ratio:
                    cw = scale_list[i]*a**0.5
                    ch = scale_list[i]/a**0.5
                    # print(a, cw, ch)
                    prior_boxes.append([cx, cy, cw, ch])

                ch = cw = (scale_list[i]*scale_list[i+1])**0.5
                # 这里其实也不对 论文是上面的公式，但是开源项目基本都是下面的算法
                # min_size = scale_list[i]
                # max_size = scale_list[i+1]
                # print(ch)
                prior_boxes.append([cx, cy, cw, ch])
                # print(np.array(prior_boxes)*300)
                # b

    # print(cw_list)
    # print(prior_boxes[-5:])
    # print(len(prior_boxes)) #8732

    # img = np.ones((2000,2000,3))*255
    # for box in prior_boxes:
    #     x1 = int(max(0, (box[0]-box[2]/2)*2000))
    #     y1 = int(max(0, (box[1]-box[3]/2)*2000))
    #     x2 = int(min(2000, (box[0]+box[2]/2)*2000))
    #     y2 = int(min(2000, (box[1]+box[3]/2)*2000))
    #     print((x1,y1), (x2,y2))
    #     cv2.rectangle(img, (x1,y1), (x2,y2), (255,0,0), 1)
    # cv2.imwrite("box.jpg", img)
    # b
    # print(np.array(prior_boxes).shape)
    # b
    return np.array(prior_boxes)

def matchPriorBox(prior_boxes, labels, iou_threshold=0.5):
    # prior_boxes: [1, 8732, 4] [cx, cy, w, h]
    # labels: [batchsize, n, 5] 5 means[xmin, ymin, xmax, ymax, class_id]
    # return [cx, cy, w, h, class_id]
    prior_boxes_matched = torch.zeros((labels.shape[0], prior_boxes.shape[1], 1))
    #[batchsize, 8732, 6]
    #print(labels.shape)
    for b in range(labels.shape[0]):
        for i,prior_box in enumerate(prior_boxes[0]):
            # TO DO: speed up(比如通过中心点定位)
            for label_box in labels[b]:
                box1 = label_box[:4]

                x0 = prior_box[0]-prior_box[2]//2
                y0 = prior_box[1]-prior_box[3]//2
                x1 = prior_box[0]+prior_box[2]//2
                y1 = prior_box[1]+prior_box[3]//2
                box2 = [x0, y0, x1, y1]
                iou = jaccardOverlap(box1, box2)

                prior_boxes_matched[b][i][0] = prior_box[0]
                prior_boxes_matched[b,i,1] = prior_box[1]
                prior_boxes_matched[b,i,2] = prior_box[2]
                prior_boxes_matched[b,i,3] = prior_box[3]
                if iou>iou_threshold:
                    prior_boxes_matched[b,i,4] = label_box[4]
                    # one_batch.append([prior_box[0], prior_box[1], prior_box[2], prior_box[3], label_box[4]])
                else:
                    prior_boxes_matched[b,i,4] = 0
                    # one_batch.append([prior_box[0], prior_box[1], prior_box[2], prior_box[3], 0])
    return prior_boxes_matched

def intersect(box_a, box_b):
    """ We resize both tensors to [A,B,2] without new malloc:
    [A,2] -> [A,1,2] -> [A,B,2]
    [B,2] -> [1,B,2] -> [A,B,2]
    Then we compute the area of intersect between box_a and box_b.
    Args:
      box_a: (tensor) bounding boxes, Shape: [A,4].
      box_b: (tensor) bounding boxes, Shape: [B,4].
    Return:
      (tensor) intersection area, Shape: [A,B].
    """
    A = box_a.size(0)
    B = box_b.size(0)

    max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2),
                       box_b[:, 2:].unsqueeze(0).expand(A, B, 2))
    min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2),
                       box_b[:, :2].unsqueeze(0).expand(A, B, 2))
    inter = torch.clamp((max_xy - min_xy), min=0)
    return inter[:, :, 0] * inter[:, :, 1]

def jaccard(box_a, box_b):
    """Compute the jaccard overlap of two sets of boxes.  The jaccard overlap
    is simply the intersection over union of two boxes.  Here we operate on
    ground truth boxes and default boxes.
    E.g.:
        A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B)
    Args:
        box_a: (tensor) Ground truth bounding boxes, Shape: [num_objects,4]
        box_b: (tensor) Prior boxes from priorbox layers, Shape: [num_priors,4]
    Return:
        jaccard overlap: (tensor) Shape: [box_a.size(0), box_b.size(0)]
    """
    inter = intersect(box_a, box_b)
    area_a = ((box_a[:, 2]-box_a[:, 0]) *
              (box_a[:, 3]-box_a[:, 1])).unsqueeze(1).expand_as(inter)  # [A,B]
    area_b = ((box_b[:, 2]-box_b[:, 0]) *
              (box_b[:, 3]-box_b[:, 1])).unsqueeze(0).expand_as(inter)  # [A,B]
    union = area_a + area_b - inter
    return inter / union  # [A,B]

def pointMidToCorner(boxes):
    """ Convert prior_boxes to (xmin, ymin, xmax, ymax)
    representation for comparison to point form ground truth data.
    Args:
        boxes: (tensor) center-size default boxes from priorbox layers.
    Return:
        boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
    """
    return torch.cat((boxes[:, :2] - boxes[:, 2:]/2,     # xmin, ymin
                     boxes[:, :2] + boxes[:, 2:]/2), 1)  # xmax, ymax

################

def center_size(boxes):
    """ Convert prior_boxes to (cx, cy, w, h)
    representation for comparison to center-size form ground truth data.
    Args:
        boxes: (tensor) point_form boxes
    Return:
        boxes: (tensor) Converted xmin, ymin, xmax, ymax form of boxes.
    """
    return torch.cat((boxes[:, 2:] + boxes[:, :2])/2,  # cx, cy
                     boxes[:, 2:] - boxes[:, :2], 1)  # w, h

def match(threshold, truths, priors, variances, labels, loc_t, conf_t, idx):
    """Match each prior box with the ground truth box of the highest jaccard
    overlap, encode the bounding boxes, then return the matched indices
    corresponding to both confidence and location preds.
    Args:
        threshold: (float) The overlap threshold used when mathing boxes.
        truths: (tensor) Ground truth boxes, Shape: [num_obj, 4].
        priors: (tensor) Prior boxes from priorbox layers, Shape: [n_priors,4].
        variances: (tensor) Variances corresponding to each prior coord,
            Shape: [1, 2].
        labels: (tensor) All the class labels for the image, Shape: [num_obj].
        loc_t: (tensor) Tensor to be filled w/ endcoded location targets.
        conf_t: (tensor) Tensor to be filled w/ matched indices for conf preds.
        idx: (int) current batch index
    Return:
        The matched indices corresponding to 1)location and 2)confidence preds.
    """
    # jaccard index
    overlaps = jaccard(
                        truths,
                        pointMidToCorner(priors)
                        )
    # (Bipartite Matching)
    # [1,num_objects] best prior for each ground truth
    best_prior_overlap, best_prior_idx = overlaps.max(1, keepdim=True)
    # [1,num_priors] best ground truth for each prior
    best_truth_overlap, best_truth_idx = overlaps.max(0, keepdim=True)

    best_truth_idx.squeeze_(0)
    best_truth_overlap.squeeze_(0)
    best_prior_idx.squeeze_(1)
    best_prior_overlap.squeeze_(1)
    best_truth_overlap.index_fill_(0, best_prior_idx, 2)  # ensure best prior
    # TODO refactor: index  best_prior_idx with long tensor
    # ensure every gt matches with its prior of max overlap
    for j in range(best_prior_idx.size(0)):
        best_truth_idx[best_prior_idx[j]] = j
    matches = truths[best_truth_idx]          # Shape: [num_priors,4]
    conf = labels[best_truth_idx] + 1         # Shape: [num_priors]
    conf[best_truth_overlap < threshold] = 0  # label as background
    loc = encode(matches, priors, variances)
    loc_t[idx] = loc    # [num_priors,4] encoded offsets to learn
    conf_t[idx] = conf  # [num_priors] top class label for each prior

def encode(matched, priors, variances):
    """Encode the variances from the priorbox layers into the ground truth boxes
    we have matched (based on jaccard overlap) with the prior boxes.
    Args:
        matched: (tensor) Coords of ground truth for each prior in point-form
            Shape: [num_priors, 4].
        priors: (tensor) Prior boxes in center-offset form
            Shape: [num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        encoded boxes (tensor), Shape: [num_priors, 4]
    """

    # dist b/t match center and prior's center
    g_cxcy = (matched[:, :2] + matched[:, 2:])/2 - priors[:, :2]
    # encode variance
    g_cxcy /= (variances[0] * priors[:, 2:])
    # match wh / prior wh
    g_wh = (matched[:, 2:] - matched[:, :2]) / priors[:, 2:]
    g_wh = torch.log(g_wh) / variances[1]
    # return target for smooth_l1_loss
    return torch.cat([g_cxcy, g_wh], 1)  # [num_priors,4]

# Adapted from https://github.com/Hakuyume/chainer-ssd
def decode(loc, priors, variances):
    """Decode locations from predictions using priors to undo
    the encoding we did for offset regression at train time.
    Args:
        loc (tensor): location predictions for loc layers,
            Shape: [num_priors,4]
        priors (tensor): Prior boxes in center-offset form.
            Shape: [num_priors,4].
        variances: (list[float]) Variances of priorboxes
    Return:
        decoded bounding box predictions
    """

    boxes = torch.cat((
        priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:],
        priors[:, 2:] * torch.exp(loc[:, 2:] * variances[1])), 1)
    boxes[:, :2] -= boxes[:, 2:] / 2
    boxes[:, 2:] += boxes[:, :2]
    return boxes

def log_sum_exp(x):
    """Utility function for computing log_sum_exp while determining
    This will be used to determine unaveraged confidence loss across
    all examples in a batch.
    Args:
        x (Variable(tensor)): conf_preds from conf layers
    """
    x_max = x.data.max()
    return torch.log(torch.sum(torch.exp(x-x_max), 1, keepdim=True)) + x_max

# Original author: Francisco Massa:
# https://github.com/fmassa/object-detection.torch
# Ported to PyTorch by Max deGroot (02/01/2017)
def nms(boxes, scores, overlap=0.5, top_k=200):
    """Apply non-maximum suppression at test time to avoid detecting too many
    overlapping bounding boxes for a given object.
    Args:
        boxes: (tensor) The location preds for the img, Shape: [num_priors,4].
        scores: (tensor) The class predscores for the img, Shape:[num_priors].
        overlap: (float) The overlap thresh for suppressing unnecessary boxes.
        top_k: (int) The Maximum number of box preds to consider.
    Return:
        The indices of the kept boxes with respect to num_priors.
    """

    keep = scores.new(scores.size(0)).zero_().long()
    if boxes.numel() == 0:
        return keep
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]
    area = torch.mul(x2 - x1, y2 - y1)
    v, idx = scores.sort(0)  # sort in ascending order
    # I = I[v >= 0.01]
    idx = idx[-top_k:]  # indices of the top-k largest vals
    xx1 = boxes.new()
    yy1 = boxes.new()
    xx2 = boxes.new()
    yy2 = boxes.new()
    w = boxes.new()
    h = boxes.new()

    # keep = torch.Tensor()
    count = 0
    while idx.numel() > 0:
        i = idx[-1]  # index of current largest val
        # keep.append(i)
        keep[count] = i
        count += 1
        if idx.size(0) == 1:
            break
        idx = idx[:-1]  # remove kept element from view
        # load bboxes of next highest vals
        torch.index_select(x1, 0, idx, out=xx1)
        torch.index_select(y1, 0, idx, out=yy1)
        torch.index_select(x2, 0, idx, out=xx2)
        torch.index_select(y2, 0, idx, out=yy2)
        # store element-wise max with next highest score
        xx1 = torch.clamp(xx1, min=x1[i])
        yy1 = torch.clamp(yy1, min=y1[i])
        xx2 = torch.clamp(xx2, max=x2[i])
        yy2 = torch.clamp(yy2, max=y2[i])
        w.resize_as_(xx2)
        h.resize_as_(yy2)
        w = xx2 - xx1
        h = yy2 - yy1
        # check sizes of xx1 and xx2.. after each iteration
        w = torch.clamp(w, min=0.0)
        h = torch.clamp(h, min=0.0)
        inter = w*h
        # IoU = i / (area(a) + area(b) - i)
        rem_areas = torch.index_select(area, 0, idx)  # load remaining areas)
        union = (rem_areas - inter) + area[i]
        IoU = inter/union  # store result in iou
        # keep only elements with an IoU <= overlap
        idx = idx[IoU.le(overlap)]
    return keep, count

def showAnchorBox(anchors):
    #可视化anchor box
    colors = [(255,0,0),
              (0,255,0),
              (0,0,255),
              (255,255,0),
              (255,0,255),
              (0,255,255)]
    size = 3000
    #为了看的清楚 用比较大的尺寸可视化画框

    #print(anchors)
    # print(anchors[2000:2004])
    # print(anchors[5776+600:5776+606])
    print(anchors.shape)
    #38*38*4+19*19*6+10*10*6+5*5*6+3*3*4+1*1*4=8732

    #第一个特征层 38
    img = np.ones((size,size,3))
    for i,anchor in enumerate(anchors[2000:2000+4]):
        cx = anchor[0]*size
        cy = anchor[1]*size
        w = anchor[2]*size
        h = anchor[3]*size
        x0 = int(cx - w/2)
        y0 = int(cy - h/2)
        x1 = int(x0+w)
        y1 = int(y0+h)
        cv2.rectangle(img,(x0,y0),(x1,y1),colors[i],18-i*3)
    cv2.imwrite('img1.jpg', img)

    #第二个特征层 19
    img = np.ones((size,size,3))
    for i,anchor in enumerate(anchors[5776+600:5776+606]):
        cx = anchor[0]*size
        cy = anchor[1]*size
        w = anchor[2]*size
        h = anchor[3]*size
        x0 = int(cx - w/2)
        y0 = int(cy - h/2)
        x1 = int(x0+w)
        y1 = int(y0+h)
        cv2.rectangle(img,(x0,y0),(x1,y1),colors[i],18-i*3)
    cv2.imwrite('img2.jpg', img)

    #第三个特征层 10
    img = np.ones((size,size,3))
    for i,anchor in enumerate(anchors[7942+330:7942+336]):
        cx = anchor[0]*size
        cy = anchor[1]*size
        w = anchor[2]*size
        h = anchor[3]*size
        x0 = int(cx - w/2)
        y0 = int(cy - h/2)
        x1 = int(x0+w)
        y1 = int(y0+h)
        cv2.rectangle(img,(x0,y0),(x1,y1),colors[i],18-i*3)
    cv2.imwrite('img3.jpg', img)

    #第四个特征层 5
    img = np.ones((size,size,3))
    for i,anchor in enumerate(anchors[8542+72:8542+78]):
        cx = anchor[0]*size
        cy = anchor[1]*size
        w = anchor[2]*size
        h = anchor[3]*size
        x0 = int(cx - w/2)
        y0 = int(cy - h/2)
        x1 = int(x0+w)
        y1 = int(y0+h)
        cv2.rectangle(img,(x0,y0),(x1,y1),colors[i],18-i*3)
    cv2.imwrite('img4.jpg', img)

    #第五个特征层 3
    img = np.ones((size,size,3))
    for i,anchor in enumerate(anchors[8692+16:8692+20]):
        cx = anchor[0]*size
        cy = anchor[1]*size
        w = anchor[2]*size
        h = anchor[3]*size
        x0 = int(cx - w/2)
        y0 = int(cy - h/2)
        x1 = int(x0+w)
        y1 = int(y0+h)
        cv2.rectangle(img,(x0,y0),(x1,y1),colors[i],18-i*3)
    cv2.imwrite('img5.jpg', img)

    #第六个特征层 1
    img = np.ones((size,size,3))
    for i,anchor in enumerate(anchors[8728+0:8728+4]):
        cx = anchor[0]*size
        cy = anchor[1]*size
        w = anchor[2]*size
        h = anchor[3]*size
        x0 = int(cx - w/2)
        y0 = int(cy - h/2)
        x1 = int(x0+w)
        y1 = int(y0+h)
        cv2.rectangle(img,(x0,y0),(x1,y1),colors[i],18-i*3)
    cv2.imwrite('img6.jpg', img)

if __name__ == "__main__":

    import cv2

    anchors = generateProirBox()
    showAnchorBox(anchors)


"""
Created on Wed Jul 22 15:39:20 2020
Parse drugs info for disease name and MeSH ID

@author: Tianqi
"""

xml_file = '../data/full database.xml'
import collections
import xml.etree.ElementTree as etree
import pandas as pd
import os

import json
import csv
# import spacy
# from scispacy.abbreviation import AbbreviationDetector
# # nlp = spacy.load("en_core_sci_sm")
# nlp = spacy.load("en_ner_bc5cdr_md")
import requests

def query_raw(text, url="https://bern.korea.ac.kr/plain"):
    return requests.post(url, data={'sample_text': text}).json()
#%%
cnt = 0
rows = list()
ns = '{http://www.drugbank.ca}'
for event, elem in etree.iterparse(xml_file, events=('start','end')): ### iterate all elements
    ##### find </drug type='biotech'> element, event='end' is corresponding to event ='start', but elemnt size is
    #### mostly dependent on 'end'
    if event == 'end' and '{http://www.drugbank.ca}drug' == elem.tag and 'type' in elem.attrib:

        cnt += 1
        assert elem.tag == ns + 'drug'
        drugbank_id = elem.findtext(ns + "drugbank-id[@primary='true']")
        discription_text = elem.findtext(ns + 'indication')

        result = (query_raw(discription_text))
        if 'logits' in result:

            disease = result['logits']['disease']
            text = result['text']

            for idx in range(len(disease)):
                di_dict = disease[idx][0]
                if 'id' in di_dict:
                    meshId = di_dict['id'] # disease_id including MeSH ID and BERN-ID
                else:
                    meshId = None

                disease_name = text[di_dict['start']:di_dict['end']] # disease_name
                disease_name = disease_name.casefold()

                row = collections.OrderedDict()
                row['disease'] = disease_name
                row['drugbank_id'] = drugbank_id
                row['MeSHID'] = meshId
                row['cas_num'] = elem.findtext(ns + "cas-number")
                row['type'] = elem.get('type')
                row['name'] = elem.findtext(ns + "name")
                rows.append(row)

        else:
            continue

        elem.clear()

#%%
columns = ['drugbank_id', 'name', 'cas_num', 'type', 'disease', 'MeSHID']
disease_df = pd.DataFrame.from_dict(rows)[columns]
#protein_df.to_csv(path, sep='\t', index=False)
disease_df.to_csv('drugbank_compound_disease_BERN.tsv', sep='\t', index=False, columns=columns)

#%%
meshid_df = pd.read_csv('./disease_mesh_ALL_updated.tsv',  sep="\t")
#
drugbank_disease_mesh_df = disease_df.merge(meshid_df, how = 'left', on = 'disease').drop_duplicates()
drugbank_disease_mesh_df.to_csv('./drugbank_CtD_vocabulary.tsv', sep = '\t', index = False)
drugbank_disease_mesh_df1 = drugbank_disease_mesh_df[['drugbank_id','name','disease' ,'mesh_id']].dropna()
drugbank_disease_mesh_df1 = drugbank_disease_mesh_df1.drop_duplicates()
# drugbank_disease_mesh_df1.to_csv('drugbank_CtD_vocabulary_slim.tsv', sep = '\t', index = False)
drugbank_disease_mesh_df2 = drugbank_disease_mesh_df1[['drugbank_id','mesh_id']]
dups = drugbank_disease_mesh_df2[drugbank_disease_mesh_df2.duplicated(keep=False)]
drugbank_disease_mesh_df2 = drugbank_disease_mesh_df2.drop_duplicates()
drugbank_disease_mesh_df2.to_csv('./drugbank_CtD.tsv', sep = '\t', index = False)

#%%
df = pd.read_csv('./drugbank_CtD.tsv', sep = '\t')
df =df.drop_duplicates()
# a1 = df[df.duplicated()]

ddi_df_new = df.assign(mesh_id=df['mesh_id'].str.split(',')).explode('mesh_id')
ddi_df_new = ddi_df_new.reset_index(drop=True)
ddi_df_new = ddi_df_new.drop_duplicates()

ddi_df_new['source'] = 'Compound::' + ddi_df_new[['drugbank_id']]
ddi_df_new['target'] = 'Disease::MESH:' + ddi_df_new[['mesh_id']]
ddi_df_new['edges'] = 'DRUGBANK::treats::Compound:Disease'
ddi_df_new.to_csv('../data/drugbank_triplets_CtreatD_mesh.tsv', sep = '\t', index = False)
# ddi_df_new = pd.concat([pd.Series(row['drugbank_id'], row['mesh_id'].split(','))
#                         for _, row in ddi_df.iterrows()]).reset_index()


import numpy as np
import multiflap as mf
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.integrate import odeint
x = [.1, 5., 3.6]

time_array = np.linspace(0, 180, 90000)
mymodel = mf.Rossler(a=0.2, b=0.2, c=5.7)

ms_obj =  mf.MultipleShootingPeriod(x, M=30, period_guess= 5.,
                                    t_steps=5000, model=mymodel, integrator='odeint')

mysol = mf.SolverPeriod(ms_obj = ms_obj).lma()

jac = mysol[4]

eigenvalues, eigenvectors = np.linalg.eig(jac)

# plot the trajectory related to the initial condition
[_, initial_traj] = ms_obj.get_mappedpoint(x, 0, 100)
initial_points = ms_obj.get_initial_guess()

sol_array = mysol[3].space
sol_time = mysol[3].time
period = sol_time[-1]

initial_traj = initial_traj.x

fig1 = plt.figure(1)
ax = fig1.gca(projection='3d')
ax.set_xlabel('$x$')
ax.set_ylabel('$y$')
ax.set_zlabel('$z$')
ax.plot(sol_array[:, 0],
        sol_array[:, 1],
        sol_array[:, 2],color = 'b')
ax.scatter(initial_points[:, 0],
        initial_points[:, 1],
        initial_points[:, 2],color = 'red', alpha=0.5)
plt.legend()
plt.show()
fig2 = plt.figure(2)
ax = fig2.gca(projection='3d')
ax.set_xlabel('$x$')
ax.set_ylabel('$y$')
ax.set_zlabel('$z$')
ax.plot(sol_array[:, 0],
        sol_array[:, 1],
        sol_array[:, 2],color = 'b', label='limit cycle')
ax.plot(initial_traj[:, 0],
        initial_traj[:, 1],
        initial_traj[:, 2],color = 'red', alpha=0.5, label='initial point trajectory')
plt.legend()
plt.show()


textoEntrada = """(
    <
    [precio] = 45.09,
    [descripcion] = "adios mundo",
    [disponible] = false
    >,
    <
    [precio] = 4.3,
    [descripcion] = "adios mundo",
    [disponible] = false
    >,
    <
    [precio] = -56.4,
    [descripcion] =  "este es el otro ejemplo las cadenas pueden ser muy largas",
    [disponible] = false
    >,
    <
    [precio] = 100,
    [descripcion] =  "valio madres",
    [disponible] = true
    >
)"""
textoEntrada2 = """(
    <
        [atributo_numerico] = 45.09,
        [atributo_cadena] = "hola mundo",
        [atributo_booleano] = true
    >,
    <
        [atributo_numerico] = 4,
        [atributo_cadena] = "adios mundo",
        [atributo_booleano] = false
    >,
    <
        [atributo_numerico] = -56.4,
        [atributo_cadena] = "este es otro ejemplo las cadenas pueden ser muy largas",
        [atributo_booleano] = false
    >
)"""
f = open('D:\Descargas\Archivo1.aon', 'r')
ArchivoTexto = f.read()

texto2 = textoEntrada.replace("", "")
text3 = texto2.replace("\n", "")
text4 = text3.replace(" ", "")
print(text4)

def AFD(cadena):
    palabra = ""
    palabra2 = ""
    numero = ''
    estado = 0
    j = 0;
    diccionario = {}
    total = []
    for i in range(len(textoEntrada)):
        if estado == 0:
            if cadena[i] == "(":
                print(cadena[i] + " =Token_parentesis")
                estado = 1
        if estado == 1:
            if cadena[i] == "<":
                print(cadena[i] + " =token_menorque")
                estado = 2
        if estado == 2:
            if cadena[i] == "[":
                print(cadena[i] + " =token_corchete")
                estado = 3
        if estado == 3:
            if cadena[i].isalpha() or cadena[i] == "_":
                palabra = palabra + cadena[i]
            elif cadena[i] == "]":
                print(palabra + " =token_palabra")
                print(cadena[i] + " =token_corchete")
                estado = 4
        if estado == 4:
            if cadena[i] == "=":
                print(cadena[i] + " =token_igual")
                estado = 5
        if estado == 5:
            if cadena[i].isdigit() or cadena[i] == "." or cadena[i] == "-":
                numero = numero + cadena[i]
            elif cadena[i].isalpha() :
                palabra2 = palabra2 + cadena[i]
            elif cadena[i] == ",":
                if numero != "":
                    print(numero + " =token_numero")
                    print(cadena[i] + " =token_coma")
                    diccionario[palabra] = numero
                    numero = ''
                    palabra = ""
                    estado = 2
                elif palabra2 != "":
                    print(palabra2 + " =token_palabra")
                    diccionario[palabra] = palabra2
                    print(cadena[i] + " =token_coma")
                    palabra2 = ''
                    palabra = ""
                    estado = 2
            elif cadena[i] == ">":
                print(palabra2 + ' =token_palabra')
                diccionario[palabra] = palabra2
                palabra2 = ''
                palabra = ""
                print(cadena[i] + " =token_mayorque")
                estado = 6
                total.append(diccionario)
                diccionario = {}
        if estado == 6:
            if cadena[i] == ",":
                print(cadena[i] + " =token_coma")
                estado = 1
            elif cadena[i] == ")":
                print(cadena[i] + " =token_parentesis")

                print(total)
                f.close()

try:
    AFD(text4)

except:
    print("")


import copy
import torch
import torch.nn as nn
import torch.optim as optim
from config import config

class Alg():
    def __init__(self, model):
        self.model = model
        self.target_model = copy.deepcopy(self.model)
        self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        self.model.to(self.device)
        self.target_model.to(self.device)
        self.gamma = config['gamma']
        self.lr = config['learning_rate']

        self.mse_loss = torch.nn.MSELoss()
        self.optimizer = optim.Adam(self.model.parameters(), lr=self.lr)

    def predict(self, state):
        with torch.no_grad():
            pred_q = self.model(state).cpu()
        action = pred_q.argmax(dim=-1).numpy()
        return action

    def learn(self, states, actions, rewards, next_states, done):
        pred_value = self.model(states).gather(1, actions)
        greedy_action = self.model(next_states).max(dim=-1, keepdim=True)[1]
        with torch.no_grad():
            max_v = self.target_model(next_states).gather(1, greedy_action)
            target = rewards + (1 - done) * self.gamma * max_v
        self.optimizer.zero_grad()
        loss = self.mse_loss(pred_value, target)
        loss.backward()
        self.optimizer.step()
        return loss.item()

    def update(self):
        self.target_model.load_state_dict(self.model.state_dict())

    def drop_reset(self, p=0.01):  # 将p部分的网络重置
        for name, h in self.model.named_children():
            if type(h) == nn.Linear:
                m = copy.deepcopy(h)
                m.requires_grad_(False)
                reset_matrix = copy.deepcopy(m)
                mask = (torch.rand(h.weight.shape) > p).float()
                anti_mask = 1 - mask
                mask = mask.clone().detach().to(self.device)
                anti_mask = anti_mask.clone().detach().to(self.device)
                torch.nn.init.normal_(reset_matrix.weight, std=0.01)
                m.weight = torch.nn.Parameter(m.weight * mask, requires_grad=False)
                reset_matrix.weight = torch.nn.Parameter(reset_matrix.weight * anti_mask, requires_grad=False)
                m.weight += reset_matrix.weight
                eval('self.model.' + name + '.load_state_dict(m.state_dict())')


def bellNumber(n):

    bell = [[0 for i in range(n+1)] for j in range(n+1)]
    bell[0][0] = 1
    for i in range(1, n+1):

        # Explicitly fill for j = 0
        bell[i][0] = bell[i-1][i-1]
        print(bell)

        # Fill for remaining values of j
        for j in range(1, i+1):
            bell[i][j] = bell[i-1][j-1] + bell[i][j-1]

    return bell[n][0]

for n in range(6):
    print('Bell Number', n, 'is', bellNumber(n))

"""Explanation: Let the set be {1, 2, 3}
             { {1}, {2}, {3} }
             { {1}, {2, 3} }
             { {2}, {1, 3} }
             { {3}, {1, 2} }
             { {1, 2, 3} }. """
"""
1
1  2
2  3  5
5  7  10 15
15 20 27 37 52
"""

Dynamic programming/bell number - separate n number to sequences.py


"""
Solicitar números al usuario hasta que ingrese el cero. Por cada uno, mostrar la suma de sus dígitos
(utilizando una función que realice dicha suma).
"""

def suma_digitos(x):
    contador=0
    while x!=0:
        y=x%10 #y=5
        contador+=y #contador=11
        x=x//10 #x=0
    return contador
suma=0
y=int(input("Escribe un número: ")) #y=40
while y!=0:
    print(suma_digitos(y)) #4
    suma+=y
    y=int(input("Escribe un número: ")) #y=13
print("La suma de los dígitos es", suma)


# -*- coding: utf-8 -*-
"""
Created on Tue Nov  5 09:12:30 2019

@author: George Barker and Andre Zeromski
@author: watso
"""

import csv
import numpy as np

from nltk.tokenize import word_tokenize
from gensim.models import Word2Vec
from collections import Counter
from nltk.corpus import stopwords

class RNN:

    def __init__(self, word_dim, hidden_dim, bptt_truncate=4):
        # Assign instance variables
        self.word_dim = word_dim
        self.hidden_dim = hidden_dim
        self.bptt_truncate = bptt_truncate
        # Randomly initialize the network parameters
        self.U = np.random.uniform(-np.sqrt(1./word_dim), np.sqrt(1./word_dim), (hidden_dim, word_dim))
        self.V = np.random.uniform(-np.sqrt(1./hidden_dim), np.sqrt(1./hidden_dim), (word_dim, hidden_dim))
        self.W = np.random.uniform(-np.sqrt(1./hidden_dim), np.sqrt(1./hidden_dim), (hidden_dim, hidden_dim))

def wordToVec(sentences):
    """ Given an array of tokenized words returns a Word2Vec model """
    model = Word2Vec(sentences, size = 10, min_count=1, iter = 5)
    return model

def tokenizeLines(arrayOfLines):
    """ Takes in a array of lines of text and returns tokenized lines """
    i = 0
    for line in arrayOfLines:
        arrayOfLines[i] = tokenizeText(line[0])
        i += 1
    flattened  = [val for sublist in arrayOfLines for val in sublist]
    vocabulary = findVocab(flattened)
    l = 0
    for line in arrayOfLines:
        w = 0
        for word in line:
            if word not in vocabulary:
                arrayOfLines[l][w] = "UNK"
            w += 1
        arrayOfLines[l].insert(0,"START")
        arrayOfLines[l].append("END")
        l += 1
    return arrayOfLines

def tokenizeText(text):
    """ Takes in a string of text and returns an array of tokenized words """
    # tokenize words based on seperating whitespace
    tokens = word_tokenize(text)
    # lowercase all words
    tokens = [token.lower() for token in tokens]
    # remove stop words
    stopWords = set(stopwords.words('english'))
    tokens = [word for word in tokens if not word in stopWords]
    return tokens

def findVocab(listOfWords):
    """ Take in a tokenized array of words and returns a list of top 8000 words """
    counterWords = Counter(listOfWords)
    most_occur = counterWords.most_common(8000)
    vocab = []
    for position in most_occur:
        vocab.append(position[0])
    return vocab

def importData(filename):
    """ Return the text from the file where each line is an element in an array """
    f = open(filename)
    csv_f = csv.reader(f)
    text = []
    for row in csv_f:
        text.append(row)
    return text

def main():
#    vocabulary_size = 8000
#    unknown_token = "UNK"
#    sentence_start_token = "START"
#    sentence_end_token = "END"
    text = importData("rnnDataset.csv")
    tokenizedTextLines = tokenizeLines(text)
    model = wordToVec(tokenizedTextLines)
    # Print first 10 tokenized words and vectorized 10 tokenized words
    for line in tokenizedTextLines[:10]:
        print()
        print(line)
        for word in line:
            print(word)
            print(model.wv.__getitem__(word))
    print()
    print(model)

if __name__ == "__main__":
    main()


#ok so im bored and i keep thinking about these tables so imma make the tables

#init table with a list of column classes
#then the tabe class will have a "addrow" method which adds a row of pre formatted data to the column
#then the table class will have a __str__ that converts all of the data to a neatly formatted table useing the funky charaters
# ╔ ═ ╤ ║ │ ╪ ╗ ╣ ╝ ╚ ─ ┼

from math import floor , ceil , log10

def numToCharLen(num : int | float , floatRounding = 1):
    #takes a number and returns the number of characters the string form of that int will take up
    if isinstance(num , int):
        num = abs(num)
        if num == 0:
            num += 1
        return floor(log10(num)) + 1
    else:
        num = round(num , floatRounding)
        extra = 1 + floatRounding # 1 for the decimal place
        return floor(log10(num)) + extra

def typesafeCharNum(element):
    if isinstance(element , (int , float)):
        return numToCharLen(element)
    else:
        return len(element)

class BaseColumn:
    def __init__(self , name : str , padding = 1 , floatRounding = 1): #can add things like a "percentage of" kind of thing which will format each column into [#####     ] 50% kind of thing
        self.name = name
        self.rows = [name]
        self.__padding = padding * 2
        self.pad = padding # yeha i know this is dumb shuuuush
        self.__floatRounding = floatRounding
        self.maxCharLen = len(name) + self.__padding # pad each end

    def addElement(self , row):
        #do it this way so that the maximum charLen can be updated
        isFloat = isinstance(row , float)
        if isFloat:
            row = round(row , self.__floatRounding)

        self.rows.append(row)

        if isinstance(row , int) or isFloat:
            length = numToCharLen(row , floatRounding = self.__floatRounding)
        else:
            length = len(row)

        length += self.__padding

        if length > self.maxCharLen:
            self.maxCharLen = length

    def getThickLineSeg(self) -> str:
        #gets the header / footer string without joiners or like the edge bits
        return "═"*self.maxCharLen

    def getThinLineSeg(self) -> str:
        return "─"*self.maxCharLen

    def getRowStr(self , index) -> str:
        #gets the str of the row at index, add padding etc
        data = self.rows[index]
        dataStr = str(data)
        padStr = " " * self.pad
        #ahhh fuck i forgot about whitespace
        charLen = typesafeCharNum(data)
        whiteSpace = self.maxCharLen - charLen - self.__padding

        return f"{padStr}{dataStr}{' ' * whiteSpace}{padStr}"

class PercentOfColumn(BaseColumn):
    def __init__(self, name: str, maxValue, granularity=10, padding=1, floatRounding=1):
        super().__init__(name, padding, floatRounding)
        self.maxValue = maxValue
        self.__granularity = granularity

    def addElement(self, row):
        #special case, creates a [#####    ] 50% out of rows[index] and self.maxValue then adds padding
        percFloat = row / self.maxValue
        percInt = floor(percFloat * self.__granularity)
        percNum = ceil(percFloat * 100)
        percStr = f"[{'#' * percInt}{' ' * (self.__granularity - percInt)}] {percNum}%{' ' * (3 - numToCharLen(percNum))}"
        return super().addElement(percStr)

class IndexColumn(BaseColumn):
    def __init__(self, padding = 1, startsAt = 0):
        super().__init__("#" , padding, 1)
        self.__index = startsAt

    def addElement(self , row = None):
        #had to make row = None becuase python be weird sometimes, it doesnt actually do anything tho
        super().addElement(self.__index)
        self.__index += 1

class Table:
    def __init__(self , columns : list[BaseColumn] , maxWidth = 100 , maxCharCount = 2000):
        #if either of the max attributes are exceeded when generateing the string, an error should be thrown
        #for now anyway
        self.columns  = columns
        self.maxWidth = maxWidth
        self.maxCharCount = maxCharCount

    def addRowList(self , data : list):
        if len(data) != len(self.columns):
            raise ValueError("the number of columns provided in this row is not the same as the number of columns this table posesses")
        for i , dat in enumerate(data):
            col : BaseColumn = self.columns[i]
            col.addElement(dat)

    def addRow(self , *data):
        #provides 2 methods, but they do the same thing
        self.addRowList(list(data))

    def __str__(self):
        #ok this is where most of the actuall shit happens
        header = f"╔{'╤'.join([col.getThickLineSeg() for col in self.columns])}╗\n"
        footer = f"╚{'╧'.join([col.getThickLineSeg() for col in self.columns])}╝"

        seperator = f"\n╟{'┼'.join([col.getThinLineSeg() for col in self.columns])}╢\n"

        rows = []
        for i in range(len(self.columns[0].rows)):
            row = "│".join([col.getRowStr(i) for col in self.columns])
            rows.append(f"║{row}║")

        main = seperator.join(rows)+"\n"
        return f"{header}{main}{footer}"

if __name__ == "__main__":
    #this is a test

    import random

    index = IndexColumn()
    nameCol = BaseColumn("name")
    balance = BaseColumn("titcoin")
    health = PercentOfColumn("health" , 1000)

    table = Table([index , nameCol , balance , health])
    for i in range(100):
        table.addRow(i , "a"*random.randint(1,6) , random.randint(60 , 10000) , random.randint(0 , 1000))

    print(table)


from __future__ import annotations

import math
import warnings
from collections.abc import Iterator
from typing import Optional, Tuple, List, Union, Dict

from PIL import Image
from range_typed_integers import i32

from skytemple_files.common.i18n_util import _, f
from skytemple_files.common.util import (
    iter_bytes_4bit_le,
    read_i32,
    read_bytes,
    write_i32,
    simple_quant,
    read_u32,
)
from skytemple_files.compression_container.common_at.handler import (
    COMMON_AT_MUST_COMPRESS_3,
    CommonAtType,
)
from skytemple_files.graphics.kao import (
    KAO_IMG_IMG_DIM,
    KAO_IMG_METAPIXELS_DIM,
    KAO_IMG_PAL_B_SIZE,
    SUBENTRIES,
    SUBENTRY_LEN,
)
from skytemple_files.graphics.kao.protocol import KaoImageProtocol, KaoProtocol

class KaoImage(KaoImageProtocol):
    def __init__(self, whole_kao_data: bytes, start_pnt: int):
        if not isinstance(whole_kao_data, memoryview):
            whole_kao_data = memoryview(whole_kao_data)

        """Construct a KaoImage using a raw image buffer (16 color palette, followed by AT)"""
        from skytemple_files.common.types.file_types import FileType

        cont_len = FileType.COMMON_AT.cont_size(
            whole_kao_data, start_pnt + KAO_IMG_PAL_B_SIZE
        )
        # palette size + at container size
        self.original_size = KAO_IMG_PAL_B_SIZE + cont_len
        self.pal_data = read_bytes(whole_kao_data, start_pnt, KAO_IMG_PAL_B_SIZE)
        self.compressed_img_data = read_bytes(
            whole_kao_data, start_pnt + KAO_IMG_PAL_B_SIZE, cont_len
        )
        self.as_pil: Optional[Image.Image] = None  # lazy loading
        self.modified = False
        self.empty = False

    @classmethod
    def create_from_raw(cls, cimg: bytes, pal: bytes) -> "KaoImage":
        """Create from raw compressed image and palette data"""
        return cls(bytes(pal) + bytes(cimg), 0)

    def get(self) -> Image.Image:
        """Returns the portrait as a PIL image with a 16-bit color palette"""
        if not self.as_pil:
            self.as_pil = kao_to_pil(self)
        return self.as_pil

    def clone(self) -> "KaoImage":
        return KaoImage(self.get_internal(), 0)

    def size(self) -> int:
        return KAO_IMG_PAL_B_SIZE + len(self.compressed_img_data)

    def get_internal(self) -> bytes:
        """Returns the portrait as 16 color palette followed by AT compressed image data"""
        return bytes(self.pal_data) + bytes(self.compressed_img_data)

    def set(self, pil: Image.Image) -> "KaoImage":
        """Sets the portrait using a PIL image with 16-bit color palette as input"""
        new_pal, new_img = pil_to_kao(pil)
        self.pal_data = new_pal
        self.compressed_img_data = new_img
        self.modified = True
        self.as_pil = None
        self.empty = False
        return self

    @classmethod
    def new(cls, pil: Image.Image) -> "KaoImage":
        """Creates a new KaoImage from a PIL image with 16-bit color palette as input"""
        new_pal, new_img = pil_to_kao(pil)
        new = cls(new_pal + new_img, 0)
        new.modified = True
        return new

    def raw(self) -> Tuple[bytes, bytes]:
        """Returns raw image data and palettes"""
        return bytes(self.compressed_img_data), bytes(self.pal_data)

class Kao(KaoProtocol[KaoImage]):
    # noinspection PyMissingConstructor
    def __init__(self, data: bytes):
        if not isinstance(data, memoryview):
            data = memoryview(data)

        # First 160 bytes are padding
        first_toc = SUBENTRIES * SUBENTRY_LEN
        # The following line won't work; what if the first byte of the first pointer is 0?
        # first_toc = next(x for x, val in enumerate(data) if val != 0)
        assert (
            first_toc % SUBENTRIES * SUBENTRY_LEN == 0
        )  # Padding should be a whole TOC entry
        # first pointer = end of TOC
        first_pointer = read_u32(data, first_toc)
        toc_len = int((first_pointer - first_toc) / (SUBENTRIES * SUBENTRY_LEN))

        self.original_data: bytearray = data  # type: ignore
        self.first_toc = first_toc
        self.toc_len: int = toc_len
        self.reset(toc_len)

    @classmethod
    def create_new(cls, number_entries: int):
        """Creates a new empty KAO with the specified number of entries."""
        self = cls.__new__(cls)
        self.first_toc = SUBENTRIES * SUBENTRY_LEN
        self.original_data = bytearray(
            [255] * (self.first_toc + (SUBENTRIES * SUBENTRY_LEN) * number_entries)
        )
        self.toc_len = number_entries
        self.reset(self.toc_len)
        return self

    def n_entries(self) -> int:
        return self.toc_len

    def expand(self, new_size: int) -> None:
        if new_size < self.toc_len:
            raise ValueError(f"Can't reduce size from {self.toc_len} to {new_size}")
        from skytemple_files.graphics.kao._writer import KaoWriter

        # Write all changes
        self.original_data = bytearray(KaoWriter().write(self))

        # Prepare for expanding
        expand_len = new_size - self.toc_len
        expand_size = expand_len * (SUBENTRIES * SUBENTRY_LEN)
        limit = self.first_toc + (self.toc_len * SUBENTRIES * SUBENTRY_LEN)
        # Rewrite all pointers
        last_pnt = i32(0)
        for x in range(self.toc_len * SUBENTRIES):
            start = self.first_toc + x * SUBENTRY_LEN
            pnt = read_i32(self.original_data, start)
            if pnt < 0:
                pnt -= expand_size  # type: ignore
                last_pnt = pnt
            elif pnt > 0:
                last_pnt = -KaoImage(self.original_data, pnt).size() - expand_size  # type: ignore
                pnt += expand_size  # type: ignore
            write_i32(self.original_data, pnt, start)

        # Expand
        expand_pnt = bytearray(4)
        write_i32(expand_pnt, last_pnt, 0)
        self.original_data = (
            self.original_data[:limit]
            + (expand_pnt * (expand_len * SUBENTRIES))
            + self.original_data[limit:]
        )
        self.toc_len = new_size
        self.reset(new_size)

    def reset(self, toc_len: int) -> None:
        self.loaded_kaos: List[List[Optional[KaoImage]]] = [
            [None for __ in range(0, SUBENTRIES)] for _ in range(0, toc_len)
        ]
        self.loaded_kaos_flat: List[
            Tuple[int, int, KaoImage]
        ] = []  # cache for performance

    def get(self, index: int, subindex: int) -> Union[KaoImage, None]:
        """Get the KaoImage at the specified location or None if no image is specified"""
        if index >= self.toc_len or index < 0:
            raise ValueError(
                f"The index requested must be between 0 and {self.toc_len}"
            )
        if subindex >= SUBENTRIES or subindex < 0:
            raise ValueError(
                f"The subindex requested must be between 0 and {SUBENTRIES}"
            )
        if self.loaded_kaos[index][subindex] is None:
            start_toc_entry = (
                self.first_toc
                + (index * SUBENTRIES * SUBENTRY_LEN)
                + subindex * SUBENTRY_LEN
            )
            pnt = read_i32(self.original_data, start_toc_entry)
            if pnt < 0:
                # NULL pointer
                return None
            self.loaded_kaos[index][subindex] = KaoImage(self.original_data, pnt)
            self.loaded_kaos_flat.append((index, subindex, self.loaded_kaos[index][subindex]))  # type: ignore
        elif self.loaded_kaos[index][subindex].empty:  # type: ignore
            return None
        return self.loaded_kaos[index][subindex]

    def set(self, index: int, subindex: int, img: KaoImageProtocol) -> None:
        return self._set_impl(index, subindex, img)

    def set_from_img(self, index: int, subindex: int, img: Image.Image) -> None:
        return self._set_impl(index, subindex, img)

    def _set_impl(
        self, index: int, subindex: int, img: Union[KaoImageProtocol, Image.Image]
    ) -> None:
        """
        Set the KaoImage at the specified location. This fails,
        if there is already an image there. Use get instead.
        """
        if index > self.toc_len or index < 0:
            raise ValueError(
                f"The index requested must be between 0 and {self.toc_len}"
            )
        if subindex > SUBENTRIES or subindex < 0:
            raise ValueError(
                f"The subindex requested must be between 0 and {SUBENTRIES}"
            )
        k = self.get(index, subindex)
        if isinstance(img, KaoImage):
            if k is not None:
                self.loaded_kaos_flat = [
                    (i, s, x)
                    for i, s, x in self.loaded_kaos_flat
                    if i != index or s != subindex
                ]
            img.modified = True
            self.loaded_kaos[index][subindex] = img
            self.loaded_kaos_flat.append((index, subindex, img))
            return
        else:
            if k is not None:
                k.set(img)  # type: ignore
                return

            self.loaded_kaos[index][subindex] = KaoImage.new(img)  # type: ignore
            self.loaded_kaos_flat.append((index, subindex, self.loaded_kaos[index][subindex]))  # type: ignore

    def delete(self, index: int, subindex: int) -> None:
        try:
            kao = self.get(index, subindex)
        except ValueError:
            return
        if kao:
            kao.empty = True
            kao.modified = True

    def has_loaded(self, index: int, subindex: int) -> bool:
        """Returns whether or not a kao image at the specified index was loaded"""
        return self.loaded_kaos[index][subindex] is not None

    def __iter__(self) -> "KaoIterator":
        """
        Iterates over all KaoImages.
        """
        return KaoIterator(self, self.toc_len, SUBENTRIES)

class KaoIterator(Iterator):  # type: ignore
    def __init__(self, kao: Kao, indices: int, subindices: int):
        self.kao = kao
        self.current_index = 0
        self.current_subindex = 0
        self.max_index = indices
        self.max_subindex = subindices

    def __next__(self) -> Tuple[int, int, Union[KaoImage, None]]:
        """Tuple: index, subindex, KaoImage or None"""
        if self.current_index < self.max_index:
            old_index = self.current_index
            old_subindex = self.current_subindex
            ret = None
            try:
                ret = self.kao.get(self.current_index, self.current_subindex)
            except ValueError as ex:
                warnings.warn(
                    f(_("Could not load KAO at {old_index},{old_subindex}: {ex}"))
                )
            self.current_subindex += 1
            if self.current_subindex >= self.max_subindex:
                self.current_index += 1
                self.current_subindex = 0
            return old_index, old_subindex, ret
        else:
            raise StopIteration

def kao_to_pil(kao: KaoImage) -> Image.Image:
    """Converts the data in Kao image to a PIL image"""
    from skytemple_files.common.types.file_types import FileType

    # Generates an array where every three entries a new color begins (r, g, b, r, g, b...)
    uncompressed_image_data = FileType.COMMON_AT.deserialize(
        kao.compressed_img_data
    ).decompress()

    return uncompressed_kao_to_pil(kao.pal_data, uncompressed_image_data)

def uncompressed_kao_to_pil(
    pal_data: bytes, uncompressed_image_data: bytes
) -> Image.Image:
    # The images are made up of 25 8x8 tiles stored linearly in the data, but to be arranged
    # as 5x5 "meta-pixels".
    img_dim = KAO_IMG_METAPIXELS_DIM * KAO_IMG_IMG_DIM
    pil_img_data = bytearray(img_dim * img_dim)

    for idx, pix in enumerate(iter_bytes_4bit_le(uncompressed_image_data)):
        # yikes... the mappings below can probably be simplified a lot
        tile_id = math.floor(idx / (KAO_IMG_METAPIXELS_DIM * KAO_IMG_METAPIXELS_DIM))
        tile_x = tile_id % KAO_IMG_IMG_DIM
        tile_y = math.floor(tile_id / KAO_IMG_IMG_DIM)

        idx_in_tile = idx - (KAO_IMG_METAPIXELS_DIM * KAO_IMG_METAPIXELS_DIM) * tile_id
        in_tile_x = idx_in_tile % KAO_IMG_METAPIXELS_DIM
        in_tile_y = math.floor(idx_in_tile / KAO_IMG_METAPIXELS_DIM)

        result_x = tile_x * KAO_IMG_METAPIXELS_DIM + in_tile_x
        result_y = tile_y * KAO_IMG_METAPIXELS_DIM + in_tile_y
        nidx = result_y * img_dim + result_x
        # print(f"{tile_id} : {tile_x}x{tile_y} -- {idx_in_tile} : {in_tile_x}x{in_tile_y} -> {result_x}x{result_y}={nidx}")
        pil_img_data[nidx] = pix

    assert len(pil_img_data) == img_dim * img_dim
    im = Image.frombuffer("P", (img_dim, img_dim), pil_img_data, "raw", "P", 0, 1)

    im.putpalette(pal_data)

    return im

def pil_to_kao(
    pil: Image.Image, allowed_compressions: Optional[List[CommonAtType]] = None
) -> Tuple[bytes, bytes]:
    """Converts a PIL image (with a 16 bit palette) to a kao palette and at compressed image data"""
    from skytemple_files.common.types.file_types import FileType

    if allowed_compressions is None:
        allowed_compressions = COMMON_AT_MUST_COMPRESS_3

    img_dim = KAO_IMG_METAPIXELS_DIM * KAO_IMG_IMG_DIM
    if pil.width != img_dim or pil.height != img_dim:
        raise ValueError(
            f(
                _(
                    "Can not convert PIL image to Kao: Image dimensions must be {img_dim}x{img_dim}px."
                )
            )
        )
    if (
        pil.mode != "P"
        or pil.palette.mode != "RGB"
        or len(pil.palette.palette) != 16 * 3
    ):
        pil = simple_quant(pil, False)
    new_palette = bytearray(pil.palette.palette)

    # We have to cut the image back into this annoying tiling format :(
    new_img_size = int(img_dim * img_dim / 2)
    new_img = bytearray(new_img_size)
    raw_pil_image = pil.tobytes("raw", "P")
    the_two_px_to_write = [0, 0]
    for idx, pix in enumerate(raw_pil_image):
        # We store 2 bytes as one... in LE
        the_two_px_to_write[idx % 2] = pix
        if idx % 2 == 1:
            # -1 because we are always processing 2 px at the same time
            x = (idx - 1) % img_dim
            y = int((idx - 1) / img_dim)

            tile_x = math.floor(x / KAO_IMG_METAPIXELS_DIM) % KAO_IMG_METAPIXELS_DIM
            tile_y = math.floor(y / KAO_IMG_METAPIXELS_DIM) % KAO_IMG_METAPIXELS_DIM
            tile_id = tile_y * KAO_IMG_IMG_DIM + tile_x

            in_tile_x = x - KAO_IMG_METAPIXELS_DIM * tile_x
            in_tile_y = y - KAO_IMG_METAPIXELS_DIM * tile_y
            idx_in_tile = in_tile_y * KAO_IMG_METAPIXELS_DIM + in_tile_x

            nidx = int(
                (
                    tile_id * KAO_IMG_METAPIXELS_DIM * KAO_IMG_METAPIXELS_DIM
                    + idx_in_tile
                )
                / 2
            )
            # print(f"{idx}@{x}x{y}: {tile_id} : {tile_x}x{tile_y} -- {idx_in_tile} : {in_tile_x}x{in_tile_y} = {nidx}")
            # Little endian:
            new_img[nidx] = the_two_px_to_write[0] + (the_two_px_to_write[1] << 4)
    # Palette reordering algorithm
    # Tries to reorder the palette to have a more favorable data
    # configuration for the PX algorithm
    pairs: Dict[Tuple[int, int], int] = {}
    for x in range(len(new_img) - 1):
        l = [
            new_img[x] % 16,
            new_img[x] // 16,
            new_img[x + 1] % 16,
            new_img[x + 1] // 16,
        ]
        if l.count(l[0]) == 3 or (l.count(l[0]) == 1 and l.count(l[1]) == 3):
            a = l[0]
            for b in l:
                if b != a:
                    break
            if a >= b:
                c = b
                b = a
                a = c
            if (a, b) in pairs:
                pairs[(a, b)] += 1
            else:
                pairs[(a, b)] = 1
    new_order = [0]
    for k, v in sorted(pairs.items(), key=lambda x: -x[1]):
        k0_in_no = k[0] in new_order
        k1_in_no = k[1] in new_order
        if k0_in_no and k1_in_no:
            continue
        elif k0_in_no or k1_in_no:
            if k0_in_no:
                to_check = k[0]
                to_add = k[1]
            elif k1_in_no:
                to_check = k[1]
                to_add = k[0]
            i = new_order.index(to_check)
            if i > 0:
                if new_order[i - 1] == -1:
                    new_order.insert(i, to_add)
                if len(new_order) == i + 1 or new_order[i + 1] == -1:
                    new_order.insert(i + 1, to_add)
        else:
            new_order.append(-1)
            new_order.append(k[0])
            new_order.append(k[1])
    while -1 in new_order:
        new_order.remove(-1)
    for x in range(16):
        if not x in new_order:
            new_order.append(x)
    new_img_new = bytearray(800)
    for i, v in enumerate(new_img):
        new_v = (new_order.index(v % 16)) + (new_order.index(v // 16)) * 16
        new_img_new[i] = new_v
    new_palette_new = bytearray(KAO_IMG_PAL_B_SIZE)
    for i, v in enumerate(new_order):
        new_palette_new[i * 3] = new_palette[v * 3]
        new_palette_new[i * 3 + 1] = new_palette[v * 3 + 1]
        new_palette_new[i * 3 + 2] = new_palette[v * 3 + 2]
    new_img = new_img_new
    new_palette = new_palette_new
    # End of palette reordering

    # You can check if this works correctly, by checking if the reverse action returns the
    # correct image again:
    # >>> uncompressed_kao_to_pil(new_palette, new_img).show()

    new_img_compressed = FileType.COMMON_AT.serialize(
        FileType.COMMON_AT.compress(new_img, allowed_compressions)
    )
    if len(new_img_compressed) > 800:
        raise AttributeError(
            f(
                _(
                    "This portrait does not compress well, the result size is greater than 800 bytes ({len(new_img_compressed)} bytes total).\n"
                    "If you haven't done already, try applying the 'ProvideATUPXSupport' to install an optimized compression algorithm, "
                    "which might be able to better compress this image."
                )
            )
        )
    # You can check if compression works, by uncompressing and checking the image again:
    # >>> unc = FileType.COMMON_AT.unserialize(new_img_compressed).decompress()
    # >>> uncompressed_kao_to_pil(new_palette, unc).show()

    return new_palette[:KAO_IMG_PAL_B_SIZE], new_img_compressed


from empty import Empty
from priorityQueueBase import PriorityQueueBase

import unittest

class HeapPriorityQueue(PriorityQueueBase):

    def _parent(self, j):
        return (j - 1) // 2

    def _left(self, j):
        return 2 * j + 1

    def _right(self, j):
        return 2 * j + 2

    def _has_left(self, j):
        return self._left(j) < len(self._data)

    def _has_right(self, j):
        return self._right(j) < len(self._data)

    def _swap(self, i, j):
        self._data[i], self._data[j] = self._data[j], self._data[i]

    def _upheap(self, j):
        parent = self._parent(j)
        if j > 0 and self._data[j] < self._data[parent]:
            self._swap(j, parent)
            self._upheap(parent)

    def _downheap(self, j):
        if self._has_left(j):
            left = self._left(j)
            small_child = left
            if self._has_right(j):
                right = self._right(j)
                if self._data[right] < self._data[left]:
                    small_child = right
            if self._data[small_child] < self._data[j]:
                self._swap(j, small_child)
                self._downheap(small_child)

    def __init__(self):
        self._data = []

    def __len__(self):
        return len(self._data)

    def add(self, key, value):
        """Add a key-value pair to the priority queue."""

        self._data.append(self._Item(key, value))
        self._upheap(len(self._data) - 1)

    def min(self):
        if self.is_empty():
            raise Empty('Priority queue is empty')
        item = self._data[0]
        return (item._key, item._value)

    def remove_min(self):
        if self.is_empty():
            raise Empty('Priority queue is empty')
        self._swap(0, len(self._data) - 1)
        item = self._data.pop()
        self._downheap(0)
        return (item._key, item._value)

def pq_sort(C):
    n = len(C)
    P = PriorityQueue()
    for j in range(n):
        element = C.delete(C.first())
        P.add(element, element)
    for j in range(n):
        (k,v) = P.remove_min()
        C.add_last(v)

class Tests(unittest.TestCase):

    def test_add(self):
        q = HeapPriorityQueue()
        q.add(5, 50)
        q.add(2, 20)
        q.add(1, 10)
        q.add(10, 100)
        q.add(9, 90)

        self.assertEqual(len(q), 5)
        self.assertEqual(q.min(), (1, 10))

    def test_remove_min(self):
        q = HeapPriorityQueue()
        q.add(3, 30)
        q.add(2, 20)
        q.add(4, 40)
        q.add(1, 10)
        q.add(5, 50)

        result = q.remove_min()
        self.assertEqual(len(q), 4)
        self.assertEqual(result, (1, 10))
        self.assertEqual(q.min(), (2, 20))

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


"""
Example 7: NFA
--------------

An example of a nondeterministic finite automaton.
The NFA is converted into a DFA using the powerset construction.

Graphs:
- graph7_nfa.dot
- graph7_dfa.dot

Source:
https://en.wikipedia.org/wiki/Powerset_construction#/media/File:NFA_and_blown-up_equivalent_DFA_01.svg
"""
from fsmdot.nfa import Nfa

Q = {'X', '0', '1', '2', '3'}
S = {'0', '1'}
d = {
    'X': {
        '0': {'X'},
        '1': {'X', '0'}
    },
    '0': {
        '0': {'1'},
        '1': {'1'}
    },
    '1': {
        '0': {'2'},
        '1': {'2'}
    },
    '2': {
        '0': {'3'},
        '1': {'3'}
    }
}
q0 = 'X'
F = {'3'}

a = Nfa(Q, S, d, q0, F)
a.print_table()

G = a.dot_graph()
G.write('graph7_nfa.dot')

# Conversion to DFA
dfa = a.to_dfa()
dfa.print_table()
G2 = dfa.dot_graph()
G2.write('graph7_dfa.dot')


import os

# file = open('traffic_train.txt','r')
# file2 = open('t_test.txt','w')
#
# count = 0
# for f in os.listdir('/home/hjm/darknet/traffic_sign/l_test'):
#     f1 = f[:-4]
#     for line in file.readlines():
#         if line.find(f1)>0:
#             file2.write(line)
#             print('success')
#         count += 1
# print(count)

filedir = "/home/hjm/darknet/traffic/"
count = 0
# 定义file_data为列表
file_data = []
file_data1 = []
count_1 = 0
# 将路径定义为一个变量
jpg_path="/home/anngic/dataset/data_anngic/traffic_sign/JPEGImages/"

for file in os.listdir(filedir+"labels"):
    #print(file)
    #print(os.path.getsize(filedir+"labels/"+file))
    # 如果文档大小为空
    # if os.path.getsize(filedir+"labels/"+file) == 0:
    #     print(file)
    #     os.remove(filedir+"labels/"+file)
    #     os.remove(filedir + "JPEGImages/"+file[:-4]+".jpg")
    #     print("success")
    #     count+=1
    file_data.append(jpg_path+file[:-4]+".jpg\n")
    # file_data.append(jpg_path+file.strip('.txt'+'.jpg\n'))
    file_data1.append(file[:-4]+'\n')

    # with open(file, 'r') as r:
    #     for line in file:
    #
    # with open(file,'w') as w:
    #     for l in lines:
    #         if l[0] == '3':
    #             w.write(l)
file_data.sort()
file_data1.sort()
with open("/home/hjm/darknet/traffic/test-train.txt","w") as w:
    for i in range(0,len(file_data)):
        w.write(file_data[i])
with open("/home/hjm/darknet/traffic/test.txt","w") as w:
    for i in range(0,len(file_data1)):
        w.write(file_data1[i])
print(count)


import multiprocessing
import time
import sys

# To wait until a process has completed its work and exited, use the join() method.

def daemon():
	name = multiprocessing.current_process().name
	print('Starting:', name)
	time.sleep(2)
	print('Exiting :', name)

def non_daemon():
	name = multiprocessing.current_process().name
	print('Starting:', name)
	print('Exiting :', name)

if __name__ == '__main__':
	d = multiprocessing.Process(
	name='daemon',
	target=daemon,
	)
	d.daemon = True

	n = multiprocessing.Process(
	name='non-daemon',
	target=non_daemon,
	)
	n.daemon = False

	d.start()
	time.sleep(1)
	n.start()
	d.join()
	n.join()


import json
from .exec import exec_and_capture_output
from .view import View
from .json_utils import JsonDeltaCalculator
from .openai_utils import openai_streaming_response

functions = [{
    "name": "run_code",
    "description": "Executes given code in an IPython shell, capturing prints, return values, terminal outputs, and tracebacks.",
    "parameters": {
        "type": "object",
        "properties": {
            "code": {
                "type": "string",
                "description": "The code to execute as a JSON decodable string. Can include standard Python and IPython commands."
            }
        },
        "required": ["code"],
    },
    "function": exec_and_capture_output
}]

system_message = """
Only use the function you have been provided with, which has one keyword argument: code.
Remember to write your messages to the user in Markdown.
You can access the internet. Run whatever code you'd like to achieve the goal, and if at first you don't succeed, try again and again.
If you run_code and it fails, write a normal message explaining what happened, theorizing why, and planning a new way forward.
You can install new packages with !pip.
While you can generate and display static plots (like those from Matplotlib), interactive and dynamic visualizations (like those from Plotly) won't be displayed correctly, so if you need to do something like that, save it as an image and display it.
""".strip()

class Interpreter:
    def __init__(self):
        self.messages = []
        self._logs = []
        self.system_message = system_message
        self.openai_api_key = None

    def reset(self):
        self.messages = []
        self._logs = []

    def load(self, messages):
        self.messages = messages

    def chat(self, message=None, return_chat=False):
        if message:
            self.messages.append({"role": "user", "content": message})
            self.respond()

        else:
            print("Type 'exit' to leave the chat.\n")

            while True:
                user_input = input("> ")

                if user_input == 'exit':
                    break

                self.messages.append({"role": "user", "content": user_input})
                self.respond()

        if return_chat:
            return self.messages

    def display(self, delta):

        old_delta = delta

        if delta == None:
          return

        if "content" in delta and delta["content"] != None:
          delta = {"type": "message", "content": delta["content"]}
        elif "function_call" in delta:
          delta = {"type": "function", "content": delta["function_call"]}

        self._logs.append(["old delta:", old_delta, "new delta:", delta])
        self.view.process_delta(delta)

    def respond(self):

        # You always need a new view.
        self.view = View()

        try:

            # make openai call
            gpt_functions = [{k: v for k, v in d.items() if k != 'function'} for d in functions]
            response = openai_streaming_response(
                self.messages,
                gpt_functions,
                self.system_message,
                "gpt-4-0613",
                self.openai_api_key
            )

            base_event = {
                "role": "assistant",
                "content": ""
            }
            event = base_event

            func_call = {
                "name": None,
                "arguments": "",
            }

            for chunk in response:

                delta = chunk.choices[0].delta

                if "function_call" in delta:
                    if "name" in delta.function_call:

                        # New event!
                        if event != base_event:
                          self.messages.append(event)
                        event = {
                            "role": "assistant",
                            "content": None
                        }

                        func_call["name"] = delta.function_call["name"]
                        self.display(delta)

                        delta_calculator = JsonDeltaCalculator()

                    if "arguments" in delta.function_call:
                        func_call["arguments"] += delta.function_call["arguments"]

                        argument_delta = delta_calculator.receive_chunk(delta.function_call["arguments"])

                        # Reassemble it as though OpenAI did this properly

                        if argument_delta != None:
                          self.display({"content": None, "function_call": argument_delta})

                if chunk.choices[0].finish_reason == "function_call":

                    event["function_call"] = func_call
                    self.messages.append(event)

                    # For interpreter
                    if func_call["name"] != "run_code":
                      func_call["name"] = "run_code"

                    function = [f for f in functions if f["name"] == func_call["name"]][0]["function"]
                    self._logs.append(func_call["arguments"])

                    # For interpreter. Sometimes it just sends the code??
                    try:
                      function_args = json.loads(func_call["arguments"])
                    except:
                      function_args = {"code": func_call["arguments"]}

                    # The output might use a rich Live display so we need to finalize ours.
                    self.view.finalize()

                    output = function(**function_args)

                    event = {
                        "role": "function",
                        "name": func_call["name"],
                        "content": output
                    }
                    self.messages.append(event)

                    # Go around again
                    self.respond()

                if "content" in delta and delta.content != None:
                    event["content"] += delta.content
                    self.display(delta)

                if chunk.choices[0].finish_reason and chunk.choices[0].finish_reason != "function_call":
                    self.messages.append(event)

        finally:
            self.view.finalize()


'''
2023-07-30
backup simple codes from previous works.
This code used on the paper Yi et al., J. Phys. D. 49, 195103 (2016)
'''

import numpy as np
from pylab import plot,show

PI=3.141592

name=""
output=open(name+'_fin.txt','w')

#sample, middle, magnitude
a=np.loadtxt(name+"smp.txt",skiprows=2)
smm=a[:,1]
freq=a[:,0]

#sample, middle, arg
b=np.loadtxt(name+"sma.txt",skiprows=2)
sma=b[:,1]

#sample, short, mag
c=np.loadtxt(name+"ssp.txt",skiprows=2)
ssm=c[:,1]

#sample, short, arg
d=np.loadtxt(name+"ssa.txt",skiprows=2)
ssa=d[:,1]

#mirror, middle, mag
e=np.loadtxt(name+"mmp.txt",skiprows=2)
mmm=e[:,1]

#mirror, middle, arg
f=np.loadtxt(name+"mma.txt",skiprows=2)
mma=f[:,1]

#mirror, short, mag
g=np.loadtxt(name+"msp.txt",skiprows=2)
msm=g[:,1]

#mirror, short, arg
h=np.loadtxt(name+"msa.txt",skiprows=2)
msa=h[:,1]

smx=smm*np.cos(np.radians(sma)) #sample mirror x-value
smy=smm*np.sin(np.radians(sma))
ssx=ssm*np.cos(np.radians(ssa))
ssy=ssm*np.sin(np.radians(ssa))

sx=smx-ssx #sample x-value
sy=smy-ssy

sm=np.sqrt(sx*sx+sy*sy) #sample magnitude

mmx=mmm*np.cos(np.radians(mma))
mmy=mmm*np.sin(np.radians(mma))
msx=msm*np.cos(np.radians(msa))
msy=msm*np.sin(np.radians(msa))

mx=mmx-msx
my=mmy-msy

mm=np.sqrt(mx*mx+my*my)

length=len(mm)

for i in range(length):
    output.write(str(freq[i]))
    output.write('\t')
    output.write(str(sm[i]/mm[i]))
    output.write('\n')

plot(freq,sm/mm)
show()
output.close()


import turtle as t
import numpy as np
import random as r
t.shape('circle')
x=0
y=0
t.speed(0)
t.penup()
t.goto(-300,0)
t.pendown()
def foo(Vx, Vy,a):
    s=Vy
    while (0==0):
        t.goto (Vx*0.1+t.pos()[0], Vy*0.1+t.pos()[1])
        if t.pos()[1]<0:
            t.goto (t.pos()[0],0)
            break
        Vy = Vy+a*0.1
Vx=[0]*10
Vy=[0]*10
a=-0.5
for i in range(10):
    Vx[i]=3-0.3*i
    Vy[i]=10-1*i
for i in range(10):
    foo(Vx[i], Vy[i], a)


def daily(start, end):
	return range(start, end+1)

def weekly(start, end):
	return map(lambda x: x * 5, range(start, end+1))

def tech_key(data_key, period, tech_ind):
	return str(data_key) + "-" + str(period) + "_" + str(tech_ind)

def calculate_quarter_count(start_date, end_date):
	assert(start_date <= end_date)
	quarter_num = 0
	if start_date.month < 4:
		quarter_num += 4
	elif start_date.month < 5:
		quarter_num += 3
	elif start_date.month < 8:
		quarter_num += 2
	elif start_date.month < 11:
		quarter_num += 1
	else:
		quarter_num += 0

	if end_date.month < 4:
		quarter_num -= 4
	elif end_date.month < 5:
		quarter_num -= 3
	elif end_date.month < 8:
		quarter_num -= 2
	elif end_date.month < 11:
		quarter_num -= 1
	else:
		quarter_num -= 0

	year_delta = end_date.year - start_date.year
	quarter_num += year_delta * 4
	return quarter_num

from datetime import datetime
def quarterify(year, quarter_num):
	""" quarter_num = 1, 2, 3, 4
	"""
	year = int(year)
	assert(quarter_num in [1, 2, 3, 4])
	if quarter_num == 1:
		return datetime(year, 5, 1)
	elif quarter_num == 2:
		return datetime(year, 8, 1)
	elif quarter_num == 3:
		return datetime(year, 11, 1)
	else:
		return datetime(year+1, 4, 1)

def get_closest_quarter(cur_date, past=True):
	if cur_date.month < 4:
		if past:
			return (cur_date.year-1), 3
			#return cur_date.replace(year=(cur_date.year-1), month=11, day=1)
		else:
			return (cur_date.year-1), 4
			#return cur_date.replace(year=(cur_date.year), month=4, day=1)
	elif cur_date.month < 5:
		if past:
			return (cur_date.year-1), 4
			#return cur_date.replace(year=(cur_date.year), month=4, day=1)
		else:
			return (cur_date.year), 1
			#return cur_date.replace(year=(cur_date.year), month=5, day=1)
	elif cur_date.month < 8:
		if past:
			return (cur_date.year), 1
			#return cur_date.replace(year=(cur_date.year), month=5, day=1)
		else:
			return (cur_date.year), 2
			#return cur_date.replace(year=(cur_date.year), month=8, day=1)
	elif cur_date.month < 11:
		if past:
			return (cur_date.year), 2
			#return cur_date.replace(year=(cur_date.year), month=8, day=1)
		else:
			return (cur_date.year), 3
			#return cur_date.replace(year=(cur_date.year), month=11, day=1)
	else:
		if past:
			return (cur_date.year), 3
			#return cur_date.replace(year=(cur_date.year), month=11, day=1)
		else:
			return (cur_date.year), 4
			#return cur_date.replace(year=(cur_date.year+1), month=4, day=1)


"""
https://leetcode.com/problems/group-anagrams/
"""
# my solution after a while
import collections
class Solution:
    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        if not strs or strs is None:
            return []

        sorted_list = []
        result = []

        for index, items in enumerate(strs):
            sorted_list.append(("".join(sorted(items)), strs[index]))

        word_table = collections.defaultdict(list)

        for item, index in sorted_list:
            word_table[item].append(index)

        for i in word_table.values():
            result.append(i)
        return result


from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options

def driverConfig():
    PATH = "chromedriver.exe"
    invisibilidade = Options()
    invisibilidade.headless = True
    driver = webdriver.Chrome(PATH, options=invisibilidade)
    return driver

def abrindoGoogle():
    driver = driverConfig()
    driver.get("https://www.google.com/")
    return driver

def fazendoBusca(driver):
    loop = True

    pesquisa = driver.find_element_by_class_name("gLFyf.gsfi")
    pesquisa.clear()
    acao = input("Ação: ").strip()

    if acao == "":
        loop = False

    else:
        pesquisa.send_keys('cotação ' + acao)
        pesquisa.send_keys(Keys.RETURN)

        try:
            valorAcao = driver.find_element_by_class_name("IsqQVc.NprOob.XcVN5d")
            valorAcaoTexto = valorAcao.text

            print('O Ultimo valor de ', acao, 'encontado é de RS:' + valorAcaoTexto)

        except:
            print(f"Erro, Papel: {acao} não encontrado")

        return loop

loop = True

driver = abrindoGoogle()

while loop == True:
    loop = fazendoBusca(driver)

print('fim')


# -*- coding: utf-8 -*-
"""
Created on Mon Dec  6 16:52:21 2021

@author: Katarina
"""

"""
Opening a .h5 and loading from it
"""

import os
import keras
import gzip
import numpy as np

"""
## Extract 'sz' targets from in/out data
"""
def get_targets(x_in, y_in, x_out, y_out, sz=500):

    x_temp = np.vstack((x_in, x_out))
    y_temp = np.vstack((y_in, y_out))

    inv = np.ones((x_in.shape[0],1))
    outv = np.zeros((x_out.shape[0],1))
    in_out_temp = np.vstack((inv, outv))

    assert x_temp.shape[0] == y_temp.shape[0]

    if sz > x_temp.shape[0]:
        sz = x_temp.shape[0]

    perm = np.random.permutation(x_temp.shape[0])
    perm = perm[0:sz]
    x_targets = x_temp[perm,:]
    y_targets = y_temp[perm,:]

    in_out_targets = in_out_temp[perm,:]

    return x_targets, y_targets, in_out_targets

"""
Get all the files
"""
files = [
      'first_1000_train_labels.gz', 'first_1000_train_images.gz',
      'second_1000_train_labels.gz', 'second_1000_train_images.gz',
      'third_1000_train_labels.gz', 'third_1000_train_images.gz',
      'fourth_1000_train_labels.gz', 'fourth_1000_train_images.gz',
      't10k-labels-idx1-ubyte.gz', 't10k-images-idx3-ubyte.gz'
      ]

with gzip.open(files[0], 'rb') as lbpath:
    first_1000_train_labels = np.frombuffer(lbpath.read(), np.uint8)
    #print(first_1000_train_labels.shape)
    #print(first_1000_train_labels)

with gzip.open(files[1], 'rb') as imgpath:
    first_1000_train_images = np.frombuffer(
    imgpath.read(), np.uint8).reshape(len(first_1000_train_labels), 28, 28)
    #print(first_1000_train_images.shape)
    #print(first_1000_train_images)

with gzip.open(files[2], 'rb') as lbpath:
    second_1000_train_labels = np.frombuffer(lbpath.read(), np.uint8)

with gzip.open(files[3], 'rb') as imgpath:
    second_1000_train_images = np.frombuffer(
    imgpath.read(), np.uint8).reshape(len(second_1000_train_labels), 28, 28)

with gzip.open(files[4], 'rb') as lbpath:
    third_1000_train_labels = np.frombuffer(lbpath.read(), np.uint8)

with gzip.open(files[5], 'rb') as imgpath:
    third_1000_train_images = np.frombuffer(
    imgpath.read(), np.uint8).reshape(len(third_1000_train_labels), 28, 28)

with gzip.open(files[6], 'rb') as lbpath:
    fourth_1000_train_labels = np.frombuffer(lbpath.read(), np.uint8)

with gzip.open(files[7], 'rb') as imgpath:
    fourth_1000_train_images = np.frombuffer(
    imgpath.read(), np.uint8).reshape(len(fourth_1000_train_labels), 28, 28)

with gzip.open(files[8], 'rb') as lbpath:
    t10k_labels_idx1_ubyte = np.frombuffer(lbpath.read(), np.uint8, offset=8)
    #print(t10k_labels_idx1_ubyte.shape)

with gzip.open(files[9], 'rb') as imgpath:
    t10k_images_idx3_ubyte = np.frombuffer(
    imgpath.read(), np.uint8, offset=16).reshape(len(t10k_labels_idx1_ubyte), 28, 28)

x_train = first_1000_train_images #[:1000] # first 1000 images from .gz images file
y_train = first_1000_train_labels # first 1000 labels from .gz file

x_test = t10k_images_idx3_ubyte # all 10,000 images from test.gz?
y_test = t10k_labels_idx1_ubyte # all 10,000 labels from test.gz?

x_attack_train = third_1000_train_images # some images from mnist training data
y_attack_train = third_1000_train_labels

x_out = fourth_1000_train_images
y_out = fourth_1000_train_labels

target_train_size = x_train.shape[0]

# .gz has overall shape (2000, 28, 28) -- 2k images, each is 28x28 pixels
print('Loaded .gz data; shape: {} [y: {}], test shape: {} [y: {}]'.format(x_train.shape, y_train.shape, x_test.shape, y_test.shape))
# Let's flatten the images for easier processing (labels don't change)
flat_vector_size = 28 * 28
x_train = x_train.reshape(x_train.shape[0], flat_vector_size)
x_test = x_test.reshape(x_test.shape[0], flat_vector_size)
x_attack_train = x_attack_train.reshape(x_attack_train.shape[0], flat_vector_size)
x_out = x_out.reshape(x_out.shape[0], flat_vector_size)

# Put the labels in "one-hot" encoding using keras' to_categorical()
num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
y_attack_train = keras.utils.to_categorical(y_attack_train, num_classes)
y_out = keras.utils.to_categorical(y_out, num_classes)

# extract targets (some in, some out)
x_targets, y_targets, in_or_out_targets = get_targets(x_train, y_train, x_out, y_out)

"""
## Load model from file
"""
def load_model(base_fp):
    # Model reconstruction from JSON file
    arch_json_fp = '{}-architecture.json'.format(base_fp)
    if not os.path.isfile(arch_json_fp):
        return None

    with open(arch_json_fp, 'r') as f:
        model = keras.models.model_from_json(f.read())

    # Load weights into the new model
    model.load_weights('{}-weights.h5'.format(base_fp))

    print('Loaded model from file ({}).'.format(base_fp))
    return model

model = load_model('30e_025rc_300h')
if model is None:
    print('Model files do not exist. Train the model first!')

# evaluate loaded model on test data
model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])

score = model.evaluate(x_test, y_test, verbose=0)
print(score)
print(model.metrics_names)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Date ：2020/10/31 18:47
# Author：Lydia
from typing import List

import pytest

# @pytest.fixture()
# def login():
#     # setup 操作
#     print("登录操作")
#     # yield 相当于return 操作
#     yield ['tom', '123456']
#     # teardown 操作
#     print("登出操作")

# login param 用法
@pytest.fixture(scope="function", params=['tom', 'lydia'])
def login(request):
    # setup 操作
    print("登录操作")
    username = request.param
    # yield 相当于return 操作
    yield username
    # teardown 操作
    print("登出操作")

@pytest.fixture(scope='session', autouse=True)
def conn_db():
    print("完成 数据库连接")
    yield "database"
    print("关闭 数据库连接")

# 中文转换
# pytest test_calc.py -m div -vs 执行打div标签的用例
def pytest_collection_modifyitems(
        session: "Session", config: "Config", items: List["Item"]
) -> None:
    print(type(items))
    # 调整执行顺序
    items.reverse
    # 调整编码格式
    for item in items:
        item.name = item.name.encode('utf-8').decode('unicode-escape')
        item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')
        # 加入标签
        if 'add' in item._nodeid:
            item.add_marker(pytest.mark.add)
        elif 'div' in item._nodeid:
            item.add_marker(pytest.mark.div)


#!/usr/bin/python3

import pathlib
import pandas as pd

# define the location of the enron dataset
enron_postgres = pathlib.Path('/opt/enron_processed/enron_postgresql/')

# read users table
users_table = enron_postgres / 'users.csv'
users_df = pd.read_csv(users_table, encoding="utf-8")

# count number of unique emails vs number of all emails
print(users_df['user_email'].nunique() / len(users_df['user_email']))

# drop duplicates emails
users_df = users_df.drop_duplicates(subset=['user_email'])

# export to csv
output_path = enron_postgres / 'unique_users.csv'
users_df.to_csv(output_path, index=False)


import pandas as pd
import numpy as np
import itertools
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics

df = pd.read_csv('Classification/KNN/teleCust1000t.csv')
# print(df['custcat'].value_counts())
# df.hist(column='income', bins=50)
# plt.show()

X = df[[
    'region', 'tenure', 'age', 'marital', 'address', 'income', 'ed', 'employ',
    'retire', 'gender', 'reside'
]].values
Y = df['custcat'].values

X = preprocessing.StandardScaler().fit(X).transform(X.astype(float))

X_train, X_test, Y_train, Y_test = train_test_split(X,
                                                    Y,
                                                    test_size=0.1,
                                                    random_state=4)
# print('Train: ', X_train.shape, Y_train.shape)
# print('Test: ', X_test.shape, Y_test.shape)

# Startgin Classifier with k = 4
""" K = 4
knn = KNeighborsClassifier(n_neighbors=K)
knn.fit(X_train, Y_train)
predicted = knn.predict(X_test)
train_predicted = knn.predict(X_train)
 """

# Evaluating Accuracy
""" print('Train Accuracy:', metrics.accuracy_score(
    y_true=Y_train, y_pred=train_predicted))
print('Test Accuracy:', metrics.accuracy_score(
    y_true=Y_test, y_pred=predicted)) """

# Finding the best K
K_list = range(1, 601)
accuracies = []
for k in K_list:
    print(k, end=': ')
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_train, Y_train)
    predicted = knn.predict(X_test)
    train_predicted = knn.predict(X_train)
    accuracy = metrics.accuracy_score(y_true=Y_test, y_pred=predicted)
    print(accuracy)
    accuracies.append(accuracy)

print('Best K:', K_list[accuracies.index(max(accuracies))], 'with Accuracy:',
      max(accuracies))

# Plot the graph to visually find the value
plt.plot(K_list, accuracies, 'b-')
plt.show()


import os
import numpy as np
from scipy import stats
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import sys

path = str(sys.path[0]).replace('\\run','')

churn = pd.read_csv(path + '/data/telecom_churn.csv')
# print(churn.head())
# print(churn.info())
# 数据没有缺失情况

# 相关关系分析
# 列联表
cross_table = pd.crosstab(churn.posTrend, churn.churn, margins=True)
# print(cross_table)
def percConvert(ser):
    return ser/float(ser[-1])
cross_table.apply(percConvert, axis=1)
# 列联表的卡方独立性检验：若显著，则说明二者存在相关关系
chi2, p, dof, expected_freq = stats.chi2_contingency(cross_table.iloc[:2, :2])
print(f"chisq = {chi2:.4f}\np-value = {p:.4f}\ndof = {dof}\nexpected_frep = {expected_freq}")
# 随机抽样 建立训练集与测试集
train = churn.sample(frac=0.7, random_state=666)
test = churn[~ churn.index.isin(train.index)]

print(' 训练集样本量: %i \n 测试样本量: %i' %(len(train), len(test)))

# 建立一元逻辑回归模型
lg = smf.logit('churn ~ duration', train).fit()
# 使用summary函数查看模型的一些信息
print(lg.summary())

# 变量选择 向前回归法
def forward_select(data, response):
    remaining = set(data.columns)
    remaining.remove(response)
    selected = []
    current_score, best_new_score = float('inf'), float('inf')
    while remaining:
        aic_with_cadidates = []
        for candidate in remaining:
            formula = "{} ~ {}".format(response, ' + '.join(selected + [candidate]))
            aic = smf.logit(formula=formula, data=data).fit().aic
            aic_with_cadidates.append((aic, candidate))

        aic_with_cadidates.sort(reverse=True)
        best_new_score, best_candidate = aic_with_cadidates.pop()
        if current_score > best_new_score:
            remaining.remove(best_candidate)
            selected.append(best_candidate)
            current_score = best_new_score
            print('aic is {},continuing!'.format(current_score))
        else:
            print('forward selection over!')
            break

        formula = "{} ~ {} ".format(response,' + '.join(selected))
        print('final formula is {}'.format(formula))
        model = smf.logit(formula=formula, data=data).fit()
        return model
# 对连续型变量进行筛选
candidates = ['churn', 'duration', 'AGE', 'incomeCode', 'nrProm', 'peakMinAv', 'peakMinDiff', 'call_10086']
data_for_select = train[candidates]
lg_ml = forward_select(data=data_for_select, response='churn')
lg_ml.summary()
print(f'原来有 {len(candidates)-1} 个变量')
print(f'筛选剩下 {len(lg_ml.params.index.tolist())} 个（包含 intercept 截距项）。')

# 对分类型变量进行筛选 判断个分类变量的显著性
class_col = ['posTrend', 'prom', 'edu_class', 'feton', 'curPlan', 'avgplan', 'gender', 'negTrend', 'planChange', 'posPlanChange', 'negPlanChange']
for i in class_col:
    tab = pd.crosstab(churn[i], churn.churn)
    print(i,''' p-value = %6.4f''' %stats.chi2_contingency(tab)[1])

# 建立逻辑回归模型
formula = '''churn ~ duration + AGE + incomeCode + peakMinDiff + call_10086 + C(edu_class) + C(feton) + C(posTrend) +
C(negTrend) + C(curPlan) + C(avgplan) + C(gender)'''
lg_m = smf.logit(formula=formula, data=train).fit()
print(lg_m.summary())

# 方差膨胀因子检测
def vif(df, col_i):
    from statsmodels.formula.api import ols
    cols = list(df.columns)
    cols.remove(col_i)
    cols_noti = cols
    formula = col_i + '~' + '+'.join(cols_noti)
    r2 = ols(formula, df).fit().rsquared
    return 1. / (1. - r2)

exog = train[candidates].drop(['churn'], axis=1)
for i in exog.columns:
    print(i, '\t', vif(df=exog, col_i=i))

train['proba'] = lg_m.predict(train)
test['proba'] = lg_m.predict(test)
print(test.info())

# ROC曲线
# 模型的准确率
# acc_m = sum(test['prediction'] == test['churn']) / np.float(len(test))
# print('The accurancy is %.2f' %acc_m)

# 混淆矩阵
test['prediction'] = (test['proba'] > 0.5).astype('int')
print(pd.crosstab(test.churn, test.prediction, margins=True))

# ROC曲线
for i in np.arange(0.1, 0.9, 0.1):
    prediction = (test['proba'] > i).astype('int')
    confusion_matrix = pd.crosstab(prediction, test.churn, margins=True)
    precision = confusion_matrix.loc[0, 0] / confusion_matrix.loc['All', 0]
    recall = confusion_matrix.loc[0, 0] / confusion_matrix.loc[0, 'All']
    Specificity = confusion_matrix.loc[1, 1] / confusion_matrix.loc[1, 'All']
    f1_score = 2 * (precision * recall) / (precision + recall)
    print('threshold:%s, precision:%.2f, recall:%.2f, Specificity:%.2f, f1_score:%.2f' %(i, precision, recall, Specificity, f1_score))

import sklearn.metrics as metrics
fpr_test, tpr_test, th_test = metrics.roc_curve(test.churn, test.proba)
fpr_train, tpr_train, th_train = metrics.roc_curve(train.churn, train.proba)

print('AUC = %.4f' %metrics.auc(fpr_test, tpr_test))
# 计算最优阈值
print(th_test[(tpr_test - fpr_test).argmax()])

plt.figure(figsize=[3, 3])
plt.plot(fpr_test, tpr_test, 'b--')
plt.plot(fpr_train, tpr_train, 'r-')
plt.title('ROC curve')
plt.show()


# A simple setup script for creating a Windows service. See the comments in the
# Config.py and ServiceHandler.py files for more information on how to set this
# up.
#
# Installing the service is done with the option --install <Name> and
# uninstalling the service is done with the option --uninstall <Name>. The
# value for <Name> is intended to differentiate between different invocations
# of the same service code -- for example for accessing different databases or
# using different configuration files.

from cx_Freeze import setup, Executable

buildOptions = dict(includes=["service", "dlp"], include_msvcr=1)
executable = Executable("config.py", base = "Win32Service",
        targetName = "service.exe")

setup(
        name = "pulse_pull_client",
        version = "0.1",
        description = "Pulse service for Pull-mode deployment",
        executables = [executable],
        options = dict(build_exe = buildOptions))