# Lint as: python3
"""Flax implementation of ResNet V1.
"""

from flax import nn

from jax import lax
import jax.numpy as jnp

class SpaceToDepthConv(nn.base.Module):
  """Convolution on space-to-depth transformed input images."""

  def apply(self,
            inputs,
            filters,
            kernel_size,
            block_size,
            strides=None,
            padding='SAME',
            input_dilation=None,
            kernel_dilation=None,
            feature_group_count=1,
            bias=True,
            dtype=jnp.float32,
            precision=None,
            kernel_init=nn.linear.default_kernel_init,
            bias_init=nn.initializers.zeros):
    """Applies a convolution to the inputs.

    Args:
      inputs: input data with dimensions (batch, spatial_dims..., features).
      filters: number of convolution filters.
      kernel_size: shape of the convolutional kernel.
      block_size: shape of space-to-depth blocks.
      strides: a sequence of `n` integers, representing the inter-window
        strides.
      padding: either the string `'SAME'`, the string `'VALID'`, or a sequence
        of `n` `(low, high)` integer pairs that give the padding to apply before
        and after each spatial dimension.
      input_dilation: `None`, or a sequence of `n` integers, giving the
        dilation factor to apply in each spatial dimension of `inputs`.
        Convolution with input dilation `d` is equivalent to transposed
        convolution with stride `d`.
      kernel_dilation: `None`, or a sequence of `n` integers, giving the
        dilation factor to apply in each spatial dimension of the convolution
        kernel. Convolution with kernel dilation is also known as 'atrous
        convolution'.
      feature_group_count: integer, default 1. If specified divides the input
        features into groups.
      bias: whether to add a bias to the output (default: True).
      dtype: the dtype of the computation (default: float32).
      precision: numerical precision of the computation see `jax.lax.Precision`
        for details.
      kernel_init: initializer for the convolutional kernel.
      bias_init: initializer for the bias.
    Returns:
      The convolved data.
    """
    inputs = jnp.asarray(inputs, dtype)

    if strides is None:
      strides = block_size
    assert strides[0] % block_size[0] == 0
    assert strides[1] % block_size[1] == 0
    strides = tuple(s // b for s, b in zip(strides, block_size))

    # create kernel as if there were no space to depth
    batch_size, h, w, features = inputs.shape
    original_input_shape = (
        batch_size, h * block_size[0],
        w * block_size[1], features // block_size[0] // block_size[1])
    in_features = original_input_shape[-1]
    assert in_features % feature_group_count == 0
    kernel_shape = kernel_size + (in_features // feature_group_count, filters)
    kernel = self.param('kernel', kernel_shape, kernel_init)
    kernel = jnp.asarray(kernel, dtype)

    # zero-pad kernel to multiple of block size (e.g. 7x7 --> 8x8)
    h_blocks, h_ragged = divmod(kernel_size[0], block_size[0])
    h_blocks = h_blocks + 1
    if h_ragged != 0:
      kernel = jnp.pad(
          kernel,
          pad_width=[[block_size[0] - h_ragged, 0], [0, 0], [0, 0], [0, 0]],
          mode='constant',
          constant_values=0.)
    w_blocks, w_ragged = divmod(kernel_size[1], block_size[1])
    w_blocks = w_blocks + 1
    if w_ragged != 0:
      kernel = jnp.pad(
          kernel,
          pad_width=[[0, 0], [block_size[1] - w_ragged, 0], [0, 0], [0, 0]],
          mode='constant',
          constant_values=0.)

    # transform kernel following space-to-depth logic: http://shortn/_9YvHW96xPJ
    kernel = jnp.reshape(
        kernel,
        [h_blocks, block_size[0],
         w_blocks, block_size[1], in_features // feature_group_count, filters])
    kernel = jnp.transpose(kernel, [0, 2, 1, 3, 4, 5])
    kernel = jnp.reshape(kernel, [h_blocks, w_blocks, features, filters])
    kernel = kernel.astype(inputs.dtype)

    dimension_numbers = nn.linear._conv_dimension_numbers(inputs.shape)  # pylint: disable=protected-access

    y = lax.conv_general_dilated(
        lhs=inputs,
        rhs=kernel,
        window_strides=strides,
        padding=padding,
        lhs_dilation=input_dilation,
        rhs_dilation=kernel_dilation,
        dimension_numbers=dimension_numbers,
        feature_group_count=feature_group_count,
        precision=precision)
    if bias:
      bias = self.param('bias', (features,), bias_init)
      bias = jnp.asarray(bias, dtype)
      y = y + bias
    return y

class ResidualBlock(nn.Module):
  """Bottleneck ResNet block."""

  def apply(self, x, filters, strides=(1, 1), train=True, axis_name=None,
            axis_index_groups=None, dtype=jnp.float32):
    needs_projection = x.shape[-1] != filters * 4 or strides != (1, 1)
    batch_norm = nn.BatchNorm.partial(
        use_running_average=not train, momentum=0.9, epsilon=1e-5,
        axis_name=axis_name, axis_index_groups=axis_index_groups, dtype=dtype)
    conv = nn.Conv.partial(bias=False, dtype=dtype)

    residual = x
    if needs_projection:
      residual = conv(residual, filters * 4, (1, 1), strides, name='proj_conv')
      residual = batch_norm(residual, name='proj_bn')

    y = conv(x, filters, (1, 1), name='conv1')
    y = batch_norm(y, name='bn1')
    y = nn.relu(y)
    y = conv(y, filters, (3, 3), strides, name='conv2')
    y = batch_norm(y, name='bn2')
    y = nn.relu(y)
    y = conv(y, filters * 4, (1, 1), name='conv3')

    y = batch_norm(y, name='bn3', scale_init=nn.initializers.zeros)
    y = nn.relu(residual + y)
    return y

class ResNet(nn.Module):
  """ResNetV1."""

  def apply(self, x, num_classes, num_filters=64, num_layers=50,
            train=True, axis_name=None, axis_index_groups=None,
            dtype=jnp.float32, conv0_space_to_depth=False):
    if num_layers not in _block_size_options:
      raise ValueError('Please provide a valid number of layers')
    block_sizes = _block_size_options[num_layers]
    if conv0_space_to_depth:
      conv = SpaceToDepthConv.partial(block_size=(2, 2),
                                      padding=[(2, 1), (2, 1)])
    else:
      conv = nn.Conv.partial(padding=[(3, 3), (3, 3)])
    x = conv(x, num_filters, kernel_size=(7, 7), strides=(2, 2), bias=False,
             dtype=dtype, name='conv0')
    x = nn.BatchNorm(x,
                     use_running_average=not train,
                     momentum=0.9, epsilon=1e-5,
                     name='init_bn', axis_name=axis_name,
                     axis_index_groups=axis_index_groups, dtype=dtype)
    x = nn.relu(x)  # MLPerf-required
    x = nn.max_pool(x, (3, 3), strides=(2, 2), padding='SAME')
    for i, block_size in enumerate(block_sizes):
      for j in range(block_size):
        strides = (2, 2) if i > 0 and j == 0 else (1, 1)
        x = ResidualBlock(x, num_filters * 2 ** i,
                          strides=strides,
                          train=train, axis_name=axis_name,
                          axis_index_groups=axis_index_groups, dtype=dtype)
    x = jnp.mean(x, axis=(1, 2))
    x = nn.Dense(x, num_classes, kernel_init=nn.initializers.normal(),
                 dtype=dtype)
    x = nn.log_softmax(x)
    return x

# a dictionary mapping the number of layers in a resnet to the number of blocks
# in each stage of the model.
_block_size_options = {
    18: [2, 2, 2, 2],
    34: [3, 4, 6, 3],
    50: [3, 4, 6, 3],
    101: [3, 4, 23, 3],
    152: [3, 8, 36, 3],
    200: [3, 24, 36, 3]
}

class FakeResNet(nn.Module):
  """Minimal NN (for debugging) with the same signature as a ResNet."""

  def apply(self, x, num_classes, train=True, batch_stats=None, axis_name=None,
            axis_index_groups=None, dtype=jnp.float32):
    x = nn.BatchNorm(x,
                     batch_stats=batch_stats,
                     use_running_average=not train,
                     momentum=0.9, epsilon=1e-5,
                     name='init_bn', axis_name=axis_name,
                     axis_index_groups=axis_index_groups, dtype=dtype)
    x = jnp.mean(x, axis=(1, 2))
    x = nn.Dense(x, num_classes, kernel_init=nn.initializers.normal(),
                 dtype=dtype)
    x = nn.log_softmax(x)
    return x


import argparse
import os
import torch

import torch.optim as optim
from torch.optim.lr_scheduler import ReduceLROnPlateau

from trainer import train_model
from model import createDeepLabv3

from utils import create_nested_dir, get_criterion_by_name, get_segmentation_model, get_data_loaders, get_log_path
from kidney_dataset_utils.misc.split_kits19 import load_dataset_dist
from kidney_utils.metrics import mean_dice_coef, mean_dice_coef_remove_empty

import lua_enums as l_enum
from kidney_dataset_utils.misc.split_kits19 import load_dpa_dist
# from networks.res_unet import ResUNet
# from networks.lua_res_unet_att import LuaResUnetAtt

def run_nn():
    """
        Version requirements:
            PyTorch Version:  >1.2.0
            Torchvision Version:  >0.4.0a0+6b959ee
    """

    """
        Parameters to execute the method
    """
    # root_dir =  r'D:\DoutoradoLuana\datasets\gerados\Kits19_25D_with_kidney_masks\Kits19_npz_25D_512_todas_fatias_rim'
    root_dir =  r'D:\DoutoradoLuana\datasets\gerados\Kits19_25D_with_tumor_masks\KiTS19_master_npz'

    #reconstrucao
    # root_dir =  r'D:\DoutoradoLuana\datasets\gerados\Kits19_npz_25D_rebuild_tumor_512_sem_EH'

    epochs = 5
    batch_size = 8
    # Filename of the final model weigths
    weight_filename = "weights_final.pt"
    loss_name = "dice"
    # the distribution of the data set created in the spreadsheet
    dpa_dist = 'DPA_group_kf5.json'
    # cases = dm.load_dataset_dist(dataset_id="natal_v7")['test']
    cases =  load_dpa_dist(dpa_dist)
    # The folder that will contain weights and log file.\
    cnn = 'deeplabv3+'
    backbone = 'dpn131'

    data_aug = l_enum.DataAug.ONLINE

    in_channels = 3

    log_path = get_log_path(data_aug, cnn, loss_name,
                            backbone, dpa_dist, in_channels,sufix = '')
    print("###\n")
    print("| {} => {} | Data Aug: {} ".format(
        cnn.upper(), backbone.upper(), data_aug.value))
    print("| Loss: {}\n".format(loss_name))
    print("| Canais: {}\n".format(in_channels))
    print("###")

    """
        Main
    """

    create_nested_dir(log_path)

    # Create the dataloader

    dataloaders = get_data_loaders(
        data_aug, cases, root_dir, batch_size)

    #model = get_segmentation_model(backbone, cnn, in_channels=in_channels)
    model = torch.load(r'C:\Users\domin\Desktop\kf4\weights_final.pt', map_location={'cuda:1': 'cuda:0'})
    # model = LuaResUnet(in_ch=3, out_ch=1).cuda()
    # model = ResUNet(in_ch=3, out_ch=1).cuda()
    # model = LuaResUnetAtt(in_ch=3, out_ch=1).cuda()
    model.train()

    # Load the loss object by name
    criterion = get_criterion_by_name(loss_name)

    # Specify the optimizer with a lower learning rate
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)

    exp_lr_scheduler = torch.optim.lr_scheduler.StepLR(
        optimizer, step_size=7, gamma=0.9
    )

    # exp_lr_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
    #     optimizer, mode='max', factor=0.1, patience=5, verbose=True,
    #     threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08
    # )

    # Specify the evalutation metrics
    metrics = {'dice': mean_dice_coef,
               'dice_lesao': mean_dice_coef_remove_empty}

    train_model(model, criterion, dataloaders,
                optimizer, exp_lr_scheduler, bpath=log_path, metrics=metrics, num_epochs=epochs)

    # Save the trained model
    torch.save(model, os.path.join(log_path, weight_filename))
    print('\n\n ### ===> Training finished sucessfully!\n\n')

if __name__ == '__main__':
    run_nn()


#!/bin/env/python

import requests
from bs4 import BeautifulSoup
from csv import DictWriter
import re
import json
from shutil import which
from subprocess import call

def parse_last_update(page):
    soup = BeautifulSoup(page.text, features="html.parser")
    update_tag = soup.find(lambda tag:tag.name=="div" and tag.text.startswith("Last Updated Date"))
    return update_tag.text

def parse_edges(page):
    try:
        pattern = re.search(
                r"var edges = new vis\.DataSet\((.*?)\);",
                page.text,
                re.MULTILINE | re.DOTALL
            )
        return json.loads(pattern.group(1))
    except Exception as e:
        print(e)
        return None

def parse_nodes(page):
    soup = BeautifulSoup(page.text, features='html.parser')

    nodes = []
    headers = ["ID", ] + [ x.text for x in soup.select_one(".covid_table_header").find_all("div") ]
    for row in soup.select(".covid_table_row"):
        values = [row.get("data-id")] + [x.text for x in row.find_all("div") ]
        nodes.append(dict(zip(headers, values)))

    return nodes

def write_edges(edges):
    if edges:
        with open("edges_official.csv", "w") as f:
            writer = DictWriter(f, ['to', 'from', 'dashes'] )
            writer.writeheader()
            writer.writerows(edges)

def write_nodes(nodes):
    with open("nodes_official.csv", "w") as f:
        writer = DictWriter(f, nodes[0].keys())
        writer.writeheader()
        writer.writerows(nodes)

if __name__ == "__main__":
    doc = requests.get(
            "https://covid19.health.gov.mv/dashboard",
            headers = {
                'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'
                }
        )
    if doc.status_code == 200:                  # note: requests doesn't necessary mean HTTP200 here
        updated_on = parse_last_update(doc)
        print(f"Fetched Dashboard: {updated_on}")

        # process nodes
        nodes = parse_nodes(doc)
        if nodes:
            print(f"Writing {len(nodes)} Nodes to file")
            write_nodes(nodes)

        edges = parse_edges(doc)
        if edges:
            print(f"Writing {len(edges)} Edges to file")
            write_edges(edges)

        # print git diff
        if which("git"):
            call([
                "git",
                "diff",
                "--stat",
                "nodes_official.csv",
                "edges_official.csv"
            ])

    else:
        print("Error: Response returned unsuccessful")


import apriltag
import cv2
import numpy as np

#gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

	# slide a window across the image
def reader(img):
    tagList = []
    global img2
    for y in range(0, img.shape[0], 350):
        for x in range(0, img.shape[1], 350):

            result, img2 = detector.detect(img[y:y + 450, x:x + 450], return_image = True)
            if ((len(result) != 0) and result not in tagList):
                tagList.append(result)
                print(result)
                cv2.imwrite("output.jpg",img2)

if __name__ == '__main__':
    cap = cv2.VideoCapture(0)
    detector = apriltag.Detector()
    img = cv2.imread("data/Track 10-22/90_0.png", cv2.IMREAD_GRAYSCALE)
    reader(img)
    cap.release()
    cv2.destroyAllWindows()


from lib.icsp import ICSPBaseActions

class SetServerAttribute(ICSPBaseActions):
    def run(self, mid, attribute_key, function,
            attribute_value=None, connection_details=None):

        self.set_connection(connection_details)
        self.get_sessionid()
        endpoint = "/rest/os-deployment-servers/%s" % (mid)
        payload = {"category": "os-deployment-servers",
                   "customAttributes": [], "type": "OSDServer"}
        if function == "Add":
            payload["customAttributes"].append(
                {"key": attribute_key, "values": [
                    {"scope": "server", "value": attribute_value}]})

        # If function is set to append any undefined attributes from server
        # any attribute to replace must be defined in full in the new call

        currentdetails = self.icsp_get(endpoint)
        payload["name"] = currentdetails['name']
        for element in currentdetails['customAttributes']:
            if element['values'][0]['scope'] == 'server'\
                    and not element['key'].startswith("__"):
                if function == "Delete" and element['key'] == attribute_key:
                    continue
                else:
                    if element['key'] != attribute_key:
                        oldatt = {"key": element['key'], "values": [
                            {"scope": "server",
                             "value": element['values'][0]['value']}]}
                        payload['customAttributes'].append(oldatt)

        try:
            self.icsp_put(endpoint, payload)
        except Exception as e:
            raise Exception("Error: %s" % e)
        return


from flask import jsonify, make_response
from app import app
from app.database import db

@app.errorhandler(404)
def error_404(error):
    """这个handler可以catch住所有abort(404)以及找不到对应router的处理请求"""
    app.logger.exception(error)
    db.session.remove()
    response = dict(status=404, message="{}".format(error))
    return jsonify(response), 404

@app.errorhandler(Exception)
def error_500(error):
    """这个handler可以catch住所有的abort(500)和raise exeception."""
    app.logger.exception(error)
    db.session.remove()
    response = dict(status=500, message="{}".format(error))
    return jsonify(response), 500

class InvalidMessage(Exception):
    status_code = 400

    def __init__(self, message, status_code=400):
        Exception.__init__(self)
        self.message = message
        self.status_code = status_code

@app.errorhandler(InvalidMessage)
def invalid_usage(error):
    db.session.remove()
    response = make_response(error.message)
    response.status_code = error.status_code
    response.heards['Content-Type'] = 'application/json'
    return response


"""
This is a template algorithm on Quantopian for you to adapt and fill in.
"""
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import AverageDollarVolume, CustomFactor, Returns
from quantopian.pipeline.filters import StaticAssets
from quantopian.pipeline.filters.morningstar import Q1500US

def logging(msgs):
    dt = get_datetime('US/Eastern')
    youbi = dt.strftime("%w")
    youbidict = {0:"Sun", 1:"Mon", 2:"Tue", 3:"Wed", 4:"Thu", 5:"Fri", 6:"Sat"}
    msgs = '\t%s\t%s:\t%s' % (dt.strftime('%Y/%m/%d %H:%M'), youbidict[int(youbi)], msgs)
    log.info(msgs)

def initialize(context):
    """
    Called once at the start of the algorithm.
    """
    context.vxx = sid(38054)
    context.tvix = sid(40515)
    context.xiv = sid(40516)
    context.forward = sid(8554)
    context.inverse = sid(32382)

    # Rebalance every day, 1 hour after market open.
    schedule_function(my_rebalance_open, date_rules.every_day(), time_rules.market_open(minutes=60))

    schedule_function(my_rebalance_close, date_rules.every_day(), time_rules.market_close())

    set_commission(commission.PerShare(cost=0, min_trade_cost=0))
    set_slippage(slippage.FixedSlippage(spread=0))
    # Record tracking variables at the end of each day.
    #schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close())

    # Create our dynamic stock selector.
    attach_pipeline(make_pipeline(), 'my_pipeline')

class PrevClose(CustomFactor):
    inputs = [USEquityPricing.close]
    window_length = 2
    def compute(self, today, assets, out, close):
        out[:] = close[-2]

def make_pipeline():
    """
    A function to create our dynamic stock selector (pipeline). Documentation on
    pipeline can be found here: https://www.quantopian.com/help#pipeline-title
    """

    sids = StaticAssets(symbols('VXX', 'XIV', 'TVIX'))
    base_universe = sids

    # Factor of yesterday's close price.
    yesterday_close = PrevClose()
    close_to_close = Returns(window_length=2)

    pipe = Pipeline(
        screen = base_universe,
        columns = {
            'yesterday_close': yesterday_close,
            'close_to_close': close_to_close,

        }
    )
    return pipe

def before_trading_start(context, data):
    """
    Called every day before market open.
    """
    context.output = pipeline_output('my_pipeline')
    context.go = False
    if abs(context.output.ix[context.vxx]['close_to_close']) > 0.01:
        logging("VXX Return: %s" % context.output.ix[context.vxx]['close_to_close'] )
        context.go = True

    # These are the securities that we are interested in trading each day.
    #context.security_list = context.output.index

def my_assign_weights(context, data):
    """
    Assign weights to securities that we want to order.
    """
    pass

def my_rebalance_close(context,data):
    if context.portfolio.positions[context.vxx]:
        if data.can_trade(context.vxx):
            order_target(context.vxx, 0)
    if context.portfolio.positions[context.xiv]:
        if data.can_trade(context.xiv):
            order_target(context.xiv, 0)

    if context.portfolio.positions[context.tvix]:
        if data.can_trade(context.tvix):
            order_target(context.tvix, 0)

def my_rebalance_open(context,data):

    if context.go and data.can_trade(context.vxx) and data.can_trade(context.tvix):
    #if data.can_trade(context.xiv) and data.can_trade(context.tvix):
        order_percent(context.vxx, 0.6)
        order_percent(context.tvix,-0.3)

        #order_percent(context.xiv,-0.6)

def my_record_vars(context, data):
    """
    Plot variables at the end of each day.
    """
    pass

def handle_data(context,data):
    """
    Called every minute.
    """
    track_orders(context, data)

def track_orders(context, data):
    '''  Show orders when made and filled.
           Info: https://www.quantopian.com/posts/track-orders
    '''
    c = context
    if 'trac' not in c:
        c.t_options = {           # __________    O P T I O N S    __________
            'log_neg_cash': 1,    # Show cash only when negative.
            'log_cash'    : 0,    # Show cash values in logging window or not.
            'log_ids'     : 0,    # Include order id's in logging window or not.
            'log_unfilled': 1,    # When orders are unfilled. (stop & limit excluded).
        }    # Move these to initialize() for better efficiency.
        c.trac = {}
        c.t_dates  = {  # To not overwhelm the log window, start/stop dates can be entered.
            'active': 0,
            'start' : [],   # Start dates, option like ['2007-05-07', '2010-04-26']
            'stop'  : []    # Stop  dates, option like ['2008-02-13', '2010-11-15']
        }
    from pytz import timezone     # Python only does once, makes this portable.
                                  #   Move to top of algo for better efficiency.
    # If 'start' or 'stop' lists have something in them, triggers ...
    if c.t_dates['start'] or c.t_dates['stop']:
        date = str(get_datetime().date())
        if   date in c.t_dates['start']:    # See if there's a match to start
            c.t_dates['active'] = 1
        elif date in c.t_dates['stop']:     #   ... or to stop
            c.t_dates['active'] = 0
    else: c.t_dates['active'] = 1           # Set to active b/c no conditions.
    if c.t_dates['active'] == 0: return     # Skip if not active.
    def _minute():   # To preface each line with the minute of the day.
        bar_dt = get_datetime().astimezone(timezone('US/Eastern'))
        return str((bar_dt.hour * 60) + bar_dt.minute - 570).rjust(3) # (-570 = 9:31a)
    def _trac(to_log):      # So all logging comes from the same line number,
        log.info(to_log)    #   for vertical alignment in the logging window.

    for oid in c.trac.copy():               # Existing known orders
      o = get_order(oid)
      c.trac[o.id]['cb'] = c.portfolio.positions[o.sid].cost_basis if c.portfolio.positions[o.sid].cost_basis else c.trac[o.id]['cb']
      if o.dt == o.created: continue        # No chance of fill yet.
      cash = ''
      if (c.t_options['log_neg_cash'] and c.portfolio.cash < 0) or c.t_options['log_cash']:
        cash = 'cash {}'.format(int(c.portfolio.cash))
      if o.status == 2:                     # Canceled
        prc = '%.2f' % data.current(o.sid, 'price') if data.can_trade(o.sid) else 'unknwn'
        do  = 'Buy' if o.amount > 0 else 'Sell' ; style = ''
        if o.stop:
          style = ' stop {}'.format(o.stop)
          if o.limit: style = ' stop {} limit {}'.format(o.stop, o.limit)
        elif o.limit: style = ' limit {}'.format(o.limit)
        _trac(' {}     Canceled {} {} {}{} at {}   {}  {}'.format(_minute(), do, o.amount,
           o.sid.symbol, style, prc, cash, o.id[-4:] if c.t_options['log_ids'] else ''))
        del c.trac[o.id]
      elif o.filled:                        # Filled at least some.
        filled = '{}'.format(o.amount)
        filled_amt = 0
        if o.filled == o.amount:            # Complete
          if 0 < c.trac[o.id]['amnt'] < o.amount:
            filled   = 'all {}/{}'.format(o.filled - c.trac[o.id]['amnt'], o.amount)
          filled_amt = o.filled
        else:                               # ['amnt'] is previously filled total
          filled_amt = o.filled - c.trac[o.id]['amnt']   # filled this time, can be 0
          c.trac[o.id]['amnt'] = o.filled                # save for increments math
          filled = '{}/{}'.format(filled_amt, o.amount)
        if filled_amt:
          prc = c.portfolio.positions[o.sid].last_sale_price if o.sid in c.portfolio.positions else 'unknwn'
          prc = data.history(o.sid, 'price', 1, '1d')[-1] if prc is 'unknwn' else prc
          now = ' ({})'.format(c.portfolio.positions[o.sid].amount) if c.portfolio.positions[o.sid].amount else ' _'
          pnl = ''  # for the trade only
          amt = c.portfolio.positions[o.sid].amount ; style = ''
          if (amt - o.filled) * o.filled < 0:  # Profit-taking scenario including short-buyback
            if c.trac[o.id]['cb']:
              pnl  = -filled_amt * (prc - c.trac[o.id]['cb'])
              sign = '+' if pnl > 0 else '-'
              pnl  = '  ({}{})'.format(sign, '%.0f' % abs(pnl))
          if o.stop:
            style = ' stop {}'.format(o.stop)
            if o.limit: style = ' stop () limit {}'.format(o.stop, o.limit)
          elif o.limit: style = ' limit {}'.format(o.limit)
          if o.filled == o.amount: del c.trac[o.id]
          _trac(' {}      {} {} {}{} at {}{}{}'.format(_minute(),
            'Bot' if o.amount > 0 else 'Sold', filled, o.sid.symbol, now,
            '%.2f' % prc, pnl, style).ljust(52) + '  {}  {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else ''))
      elif c.t_options['log_unfilled'] and not (o.stop or o.limit):
        _trac(' {}         {} {}{} unfilled  {}'.format(_minute(), o.sid.symbol, o.amount,
         ' limit' if o.limit else '', o.id[-4:] if c.t_options['log_ids'] else ''))

    oo = get_open_orders().values()
    if not oo: return                       # Handle new orders
    cash = ''
    if (c.t_options['log_neg_cash'] and c.portfolio.cash < 0) or c.t_options['log_cash']:
      cash = 'cash {}'.format(int(c.portfolio.cash))
    for oo_list in oo:
      for o in oo_list:
        if o.id in c.trac: continue         # Only new orders beyond this point
        prc  = '%.2f' % data.current(o.sid, 'price') if data.can_trade(o.sid) else 'unknwn'
        c.trac[o.id] = {'amnt': 0, 'cb': 0} ; style = ''
        now  = ' ({})'.format(c.portfolio.positions[o.sid].amount) if c.portfolio.positions[o.sid].amount else ' _'
        if o.stop:
          style = ' stop {}'.format(o.stop)
          if o.limit: style = ' stop {} limit {}'.format(o.stop, o.limit)
        elif o.limit: style = ' limit {}'.format(o.limit)
        _trac(' {}   {} {} {}{} at {}{}'.format(_minute(), 'Buy' if o.amount > 0 else 'Sell',
          o.amount, o.sid.symbol, now, prc, style).ljust(52) + '  {}  {}'.format(cash, o.id[-4:] if c.t_options['log_ids'] else ''))

algorithms/vxx tvix daytime/backtests/Backtest 6-5916bfaf5ed5976620c924fb.py


# cpp, java, python 중 하나
# 백이나 프론트 중 하나를 선택해야함
# junior와 senior 중 하나를 선택
# chicken과 pizza중 하나 선택

# 지원 조건을 선택하면 해당 조건에 맞는 지원자가  몇 명인지 쉽게 알 수 잇는 도구를 만들고 싶음

# java, backend, junior, pizza 선택 중 50점 이상 받은 지원자는?

# 모든 선택을 필수로 할 필요는 없다.

# 4가지 정보, 코딩테스트 점수 하나의 문자열로 구성한 값의 배열 info
# 개발팀이 궁금해하는 문의 조건이 문자열 형태로 담긴 배열query가 매개변수
# 각 문의 조건에 해당하는 사람들의 숫자를 순서대로 배열에 담아 return

# 딕셔너리에 lan, pos, prof, food, score
# 셋으로 교집합으로 해서

# def solution(info, query):
#     answer = []
#     entire = defaultdict(dict)
#     entire['lan'] = defaultdict(set)
#     entire['pos'] = defaultdict(set)
#     entire['prof'] = defaultdict(set)
#     entire['food'] = defaultdict(set)
#     entire['score']= defaultdict(int)
#
#     #딕셔너리에 넣기
#     for i1 in range(len(info)):
#         tmp1 = list(info[i1].split(' '))
#         entire['lan'][tmp1[0]].add(i1)
#         entire['pos'][tmp1[1]].add(i1)
#         entire['prof'][tmp1[2]].add(i1)
#         entire['food'][tmp1[3]].add(i1)
#         entire['score'][i1] = tmp1[4]
#     entire['lan']['-'] = entire['lan']['cpp'] | entire['lan']['java'] | entire['lan']['python']
#     entire['pos']['-'] = entire['pos']['backend'] | entire['pos']['frontend']
#     entire['prof']['-'] = entire['prof']['junior'] | entire['prof']['senior']
#     entire['food']['-'] = entire['food']['chicken'] | entire['food']['pizza']
#
#     #쿼리 정보검색
#     for i2 in range(len(query)):
#         #조건 검색
#         tmp2 = list(query[i2].split(' and '))
#         tmp3 = list(tmp2[3].split(' ')) #첫번째는 음식 두번째는 점수
#
#         #언어 검색
#         if tmp2[0] == "-":
#             first = entire['lan']['-']
#         else:
#             first = entire['lan'][tmp2[0]]
#         if tmp2[1] == '-':
#             scnd = entire['pos']['-']
#         else:
#             scnd = entire['pos'][tmp2[1]]
#         if tmp2[2] == '-':
#             thrd = entire['prof']['-']
#         else:
#             thrd = entire['prof'][tmp2[2]]
#         #음식
#         if tmp3[0] == '-':
#             frth = entire['food']['-']
#         else:
#             frth = entire['food'][tmp3[0]]
#         #합산 하기
#         condition = first & scnd & thrd & frth
#         cal = 0
#         for i3 in (condition):
#             if int(entire['score'][i3]) >= int(tmp3[1]):
#                 cal += 1
#         answer.append(cal)
#
#     return answer

from collections import *
from itertools import combinations
def solution(info, query):
    answer = []
    info_dict = defaultdict(list)
    #정보 넣기
    for i1 in info:
        tmp = list(i1.split(' '))
        except_value = tmp[:-1]
        value = int(tmp[-1])
        for i2 in range(5):
            for i3 in combinations(except_value,i2):
                tmp_key = ''.join(i3)
                info_dict[tmp_key].append(value)
    for v in info_dict:
        info_dict[v].sort()

    for j1 in query:
        tmp2 = j1.split(' and ')
        while '-' in tmp2:
            tmp2.remove('-')
        query_tmp = tmp2[-1].split(' ')
        val_query = int(query_tmp[1])
        if query_tmp[0] != "-":
            tmp2 = ''.join(tmp2[:-1]) + query_tmp[0]
        else:
            tmp2 = ''.join(tmp2[:-1])

        if tmp2 in info_dict:
            score = info_dict[tmp2]
            if score:
                answer.append(binary_search(val_query,score))
        else:
            answer.append(0)
    return answer

def binary_search(t,lst):
    start = 0
    end = len(lst) - 1

    while start <= end:
        mid = (end +  start)//2
        if lst[mid] >= t:
            end = mid - 1
        else:
            start = mid + 1
    return len(lst) - end - 1

        # 맨 처음이거나
        # 맨 마지막이거나
        # 왼쪽은 작고 오른쪽은 크고

info = ["java backend junior pizza 150","python frontend senior chicken 210","python frontend senior chicken 150","cpp backend senior pizza 260","java backend junior chicken 80","python backend senior chicken 50"]
query = ["java and backend and junior and pizza 100","python and frontend and senior and chicken 200","cpp and - and senior and pizza 250","- and backend and senior and - 150","- and - and - and chicken 100","- and - and - and - 150"]

print(solution(info,query))

29/김민준/순위 검색.py


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

class DQN(nn.Module):
    def __init__(self, num_actions):
        super(DQN, self).__init__()
        self.num_actions = num_actions

        self.convLayer1 = nn.Conv2d(
            in_channels = 4,
            out_channels = 32,
            kernel_size = 8,
            stride = 4
        )
        self.batchNorm1 = nn.BatchNorm2d(32)

        self.convLayer2 = nn.Conv2d(
            in_channels = 32,
            out_channels = 64,
            kernel_size = 4,
            stride = 2
        )
        self.batchNorm2 = nn.BatchNorm2d(64)

        self.convLayer3 = nn.Conv2d(
            in_channels = 64,
            out_channels = 64,
            kernel_size = 3,
            stride = 1
        )
        self.batchNorm3 = nn.BatchNorm2d(64)

        self.feedForward1 = nn.Linear(7 * 7 * 64, 512)
        self.feedForward2 = nn.Linear(512, self.num_actions)

    def forward(self, x):
        val = F.relu(self.batchNorm1(self.convLayer1(x)))
        val = F.relu(self.batchNorm2(self.convLayer2(val)))
        val = F.relu(self.batchNorm3(self.convLayer3(val)))

        val = val.view(val.size(0), -1)

        val = F.relu(self.feedForward1(val))
        val = self.feedForward2(val)

        return val


from flask import Flask,render_template
import time
from multiprocessing import Process as pcs
from multiprocessing import Queue as queue

class WifiSender():
    def __init__(self,maxsize=5):
        self.T=T=time.time()
        self.Q=Q=queue.Queue(maxsize=maxsize)

        self.app=app=Flask(__name__)
        app.jinja_env.auto_reload = True
        app.config['TEMPLATES_AUTO_RELOAD'] = True
        app.config['SECRET_KEY'] = 'iamthekey'

        @app.route('/')
        def root():
            return render_template('log.html')

        @app.route('/data<string:t>')
        def data(t):
            if Q.qsize():
                t=f'{t[:-3]}.{t[-2:]}'

                last=float(t)-T
                return f'[{last:.0f}s]'+Q.get()
            else:
                return 'NoData'

        # Thread(target=self.run).start()

    def put(self,msg):
            self.Q.put(msg)

    def run(self,host='0.0.0.0',post='1881'):
         self.app.run(host,post)

    def get_Q(self):
         return self.Q

def pcd_tasker(Q):
    from flask import Flask,render_template
    from threading import Thread
    import time

    class WifiSender():
        def __init__(self,Q):
            self.T=T=time.time()
            self.Q=Q

            self.app=app=Flask(__name__)
            app.jinja_env.auto_reload = True
            app.config['TEMPLATES_AUTO_RELOAD'] = True
            app.config['SECRET_KEY'] = 'iamthekey'

            @app.route('/')
            def root():
                return render_template('log.html')

            @app.route('/data<string:t>')
            def data(t):
                if Q.qsize():
                    t=f'{t[:-3]}.{t[-2:]}'
                    last=float(t)-T
                    return f'[{last:.2f}s]{Q.get()}'
                else:
                    return 'NoData'

        def put(self,msg):
                self.Q.put(msg)

        def run(self,host='0.0.0.0',post='1881'):
            self.app.run(host,post)

    sender=WifiSender(Q)
    Thread(target=sender.run).start()
    while 1:
         sender.put(Q.get())

if __name__=='__main__':
    #  sender=WifiSender()
    #  Thread(target=sender.run).start()
    #  while 1:
    #     sender.put('555555555555555')
    #     time.sleep(1)

    Q=queue(maxsize=5)
    pcs(target=pcd_tasker,args=[Q]).start()
    while 1:
         Q.put(time.time())
         time.sleep(1)


import asyncio
import datetime
import typing
from typing import Optional
from unicodedata import category
import disnake
from disnake.ext.commands import Cog, has_permissions, Param, cooldown, BucketType, has_any_role
from disnake.ext.commands.slash_core import slash_command
from lib.db import db
from lib.utils.helpers import get_random_string
from disnake.ext import tasks

class Commands(Cog):
    def __init__(self, bot):
        self.bot = bot

    @Cog.listener()
    async def on_ready(self):
        if not self.bot.ready:
            self.bot.cogs_ready.ready_up('Commands')

    @slash_command(name="key_gen", default_member_permissions=disnake.Permissions(administrator=True))
    async def key_generator(self, inter, amount: int):
        """
        Generate redeemable keys

        Parameters
        ----------
        amount: The amount of keys you want to generate
        """
        if amount < 1:
            return await inter.send("You need to specify a number greater than 0")
        get_random_string(amount)

        await inter.send(f"Successfully generated {amount} keys", ephemeral=True)

    @slash_command(name="redeem")
    async def redeem_key(self, inter, key: str):
        """
        Redeem a key

        Parameters
        ----------
        key: The key you want to redeem
        """
        role = inter.guild.get_role(996256479990513734)
        if len(key) < 1:
            return await inter.send("You need to specify a key")
        keys = db.column("SELECT * FROM access_keys")
        if key in keys:
            db.execute("DELETE FROM access_keys WHERE access_key = ?", key)
            db.commit()
            await inter.author.add_roles(role)
            await inter.send("Successfully redeemed key", ephemeral=True)
            embed = disnake.Embed(title="Key Redeemed", description=f"{inter.author.mention} has redeemed a key", color=0x00ff00)

            embed.set_footer(text=inter.author, icon_url=inter.author.avatar.url)

        else:
            await inter.send("Invalid key.", ephemeral=True)

    @slash_command(name="key_list", default_member_permissions=disnake.Permissions(administrator=True))
    async def key_list(self, inter):
        """
        List all redeemable keys
        """
        keys = db.record("SELECT * FROM access_keys")
        if len(keys) < 1:
            return await inter.send("There are no keys")
        await inter.send("```\n" + "\n".join(keys) + "```", ephemeral=True)

    @slash_command(name="key", default_member_permissions=disnake.Permissions(administrator=True))
    async def key(self, inter, member: disnake.Member, duration: typing.Literal["1d", "3d", "7d", "30d", "Lifetime"]):
        """
        Give a user a key

        Parameters
        ----------
        member: The user you want to give a key to
        duration: The duration of the key
        """
        if duration == "1d":
            duration = datetime.datetime.now() + datetime.timedelta(days=1)
        elif duration == "3d":
            duration = datetime.datetime.now() + datetime.timedelta(days=3)
        elif duration == "7d":
            duration = datetime.datetime.now() + datetime.timedelta(days=7)
        elif duration == "30d":
            duration = datetime.datetime.now() + datetime.timedelta(days=30)
        elif duration == "Lifetime":
            duration = datetime.datetime.now() + datetime.timedelta(days=999999)
        else:
            return await inter.send("Invalid duration.")
        key = db.field("SELECT * FROM access_keys ORDER BY RANDOM() LIMIT 1")
        check = db.field("SELECT userID FROM members WHERE userID = ?", member.id)
        if check is None:
            db.execute("INSERT INTO members (userID, rTime) VALUES (?, ?)", member.id, duration)
            db.commit()
            await member.send(f"You have received a key. Expiration: {duration}.\n\n{key}")
            await inter.send(f"Successfully gave {member.mention} a key. Expiration: {duration}", ephemeral=True)
        else:
            db.execute("UPDATE members SET rTime = ? WHERE UserID = ?", duration, member.id)
            db.commit()
            await member.send(f"You have received a key. Expiration: {duration}.\n\n{key}")
            await inter.send(f"Successfully gave {member.mention} a key. Expiration: {duration}", ephemeral=True)

    @slash_command(name="upload", default_member_permissions=disnake.Permissions(administrator=True))
    async def upload(self, inter, attachment: disnake.Attachment, account_type: typing.Literal["aged cod", "bnet", "phub", "spotify", "disney", "val", "hbo max", "netflix"]):
        """
        Upload accounts to the database

        Parameters
        ----------
        file: The file you want to upload
        account_type: The type of accounts you are uploading
        """
        await inter.response.defer(with_message=True, ephemeral=True)

        await attachment.save(f"./{attachment.filename}")
        with open(attachment.filename, "r") as f:
            accounts = f.read().split("\n")
        for account in accounts:
            if len(account) < 1:
                continue
            db.execute("INSERT INTO accs (account, AccountType) VALUES (?, ?)", account, account_type)
        db.commit()
        await inter.edit_original_message(content="Successfully uploaded accounts")

    @slash_command(name="account")
    @cooldown(15, 86400, BucketType.member)
    async def account(self, inter: disnake.ApplicationCommandInteraction, account_type: typing.Literal["aged cod", "bnet", "phub", "spotify", "disney", "val", "hbo max", "netflix"]):
        """
        Get a random account of a certain type

        Parameters
        ----------
        account_type: The type of account you want to get
        """
        role = inter.guild.get_role(996256479990513734)

        if role not in inter.author.roles:
            return await inter.send("You do not have permission to use this command.")

        account = db.field("SELECT * FROM accs WHERE accounttype = ? ORDER BY RANDOM() LIMIT 1", account_type)
        db.execute("DELETE FROM accs WHERE account = ?", account)
        if account is None:
            return await inter.send("No accounts of this type")
        db.execute("UPDATE members SET redeems = redeems + ? WHERE userID = ?", 1, inter.author.id)
        db.commit()
        redeems = db.field("SELECT redeems FROM members WHERE userID = ?", inter.author.id)
        log_channel = inter.guild.get_channel(1008122637987369031)
        embed = disnake.Embed(title=f"{account_type} has been generated", color=0x00ff00)
        embed.set_author(name=inter.author, icon_url=inter.author.avatar.url)
        embed.add_field(name="Daily Redeems", value=redeems)
        await log_channel.send(embed=embed)
        await inter.send(f"{account}", ephemeral=True)

    @slash_command(name="stock")
    async def stock(self, inter, account_type: typing.Literal["aged cod", "bnet", "phub", "spotify", "disney", "val", "hbo max", "netflix"]):
        """
        Get a random account of a certain type

        Parameters
        ----------
        account_type: The type of account you want to get
        """
        account = db.field("SELECT COUNT(*) FROM accs WHERE accounttype = ?", account_type)
        if account is None:
            return await inter.send("No accounts of this type")
        await inter.send(f"{account} {account_type} accounts")

    @slash_command(name="clear_stock", default_member_permissions=disnake.Permissions(administrator=True))
    async def clear_stock(self, inter, account_type: typing.Literal["aged cod", "bnet", "phub", "spotify", "disney", "val", "hbo max", "netflix"]):
        """
        Clear all accounts of a certain type

        Parameters
        ----------
        account_type: The type of account you want to clear
        """
        db.execute("DELETE FROM accs WHERE accounttype = ?", account_type)
        db.commit()
        await inter.send(f"Cleared {account_type} accounts")

    @tasks.loop(hours=24)
    async def redeem_reset(self):
        for member in self.bot.guild.members:
            db.execute("UPDATE members SET redeems = ? WHERE UserID = ?", 0, member.id)

    @slash_command(name="sync", default_member_permissions=disnake.Permissions(administrator=True))
    async def sync(self, inter: disnake.ApplicationCommandInteraction):
        """
        Sync the database with the bot's database
        """
        await inter.response.defer(with_message=True, ephemeral=True)
        await inter.edit_original_message(content="Syncing...")
        for member in inter.guild.members:
            await db.execute("INSERT OR IGNORE INTO members (userID) VALUES (?)", member.id)
        await db.commit()
        await inter.edit_original_message(content="Successfully synced")

def setup(bot):
    bot.add_cog(Commands(bot))


from flask.ext.mongoengine import MongoEngine
from mongoengine import *
from mongoengine.base import BaseList, BaseDocument

engine_db = MongoEngine()

def is_empty(doc):
    if doc is None:
        return True
    if isinstance(doc, BaseList):
        return False if doc else True
    if isinstance(doc, BaseDocument):
        return all(not getattr(doc, field, None) for field in doc._fields.keys())
    else:
        return False if doc else True

# Resume models follow:
class BasicInfo(EmbeddedDocument):
    location = StringField()
    email = EmailField()
    phone_number = StringField()
    website = URLField()
    industry = StringField()

class Skill(EmbeddedDocument):
    name = StringField()
    url = URLField()
    skill_level = IntField(default=3)  # 1 - 10
    years = IntField(default=0)  # 0 or greater
    order_by = IntField(default=9)  # 1-10
    description = StringField()

class Language(EmbeddedDocument):
    name = StringField()
    proficiency_level = StringField()

class Experience(EmbeddedDocument):
    company_title = StringField(required=True)
    position_location = StringField()
    company_url = URLField()
    time_at_position = StringField(required=True)
    position_title_url = URLField()
    position_title = StringField(required=True)
    company_image_url = URLField()
    from_date = StringField()
    to_date = StringField()
    description = StringField()
    sensitive = BooleanField(default=False)

class Certification(EmbeddedDocument):
    title = StringField(required=True)
    license = StringField()
    issuer_url_or_certificate_url = URLField()
    issuer_url = URLField()
    date = StringField()
    issuer_image_url = StringField()
    cert_url = URLField()
    institution = StringField(required=True)

class SummaryInfo(EmbeddedDocument):
    current_position = StringField()
    previous_positions = ListField(StringField())
    previous_position = ListField(StringField())
    summary = StringField()

class School(EmbeddedDocument):
    name = StringField(required=True)
    image = URLField()
    to_date = StringField()
    from_date = StringField()
    degree = StringField(required=True)
    url = URLField()

class Other(EmbeddedDocument):
    opportunities = ListField(StringField())
    organizations = ListField(StringField())
    causes = ListField(StringField())

class Book(EmbeddedDocument):
    goodreads_id = IntField()
    isbn = StringField()
    isbn13 = StringField()
    title = StringField()
    image_url = URLField()
    small_image_url = URLField()
    link = URLField()
    num_pages = IntField()
    publisher = StringField()
    average_rating = StringField()
    description = StringField()
    authors = ListField(StringField())
    rating = StringField()
    started_at = DateTimeField()
    read_at = DateTimeField()
    date_added = DateTimeField()
    date_updated = DateTimeField()
    review_body = StringField()

class ReadingList(EmbeddedDocument):
    to_read = ListField(EmbeddedDocumentField(Book))
    currently_reading = ListField(EmbeddedDocumentField(Book))
    finished_reading_general = ListField(EmbeddedDocumentField(Book))
    finished_reading = ListField(EmbeddedDocumentField(Book))

# link to code eval github etc
class ServiceLink(EmbeddedDocument):
    name = StringField()
    user_id = StringField()
    key = StringField()
    secret = StringField()
    oauth_key = StringField()
    oauth_secret = StringField()

class SiteLink(EmbeddedDocument):
    site_name = StringField()
    css_name = StringField()
    url = URLField()

class Resume(Document):
    '''
    About me +
    Basic Info +
    Skills
    Testimonials
    Education
    Courses
    Languages -
    Latest Blog Posts -
    Latest Projects -
    Other Projects -
    Work Experience
    My Github
    CodeEval (maybe) -
    Favorite Coding Music -
    Conferences -
    Credits (look into requirements)
    -------
    certifications
    summary_info
    top_skills
    other_skills
    organizations
    locality?
    name
    industry
    connections
    experiences
    headline
    school
    causes
    '''

    is_primary = BooleanField(default=True)
    meta = {'strict': False}

    title = StringField()
    github_username = StringField()

    headline = StringField()
    name = StringField()
    industry = StringField()
    connections = StringField()
    site_links = ListField(EmbeddedDocumentField(SiteLink))
    basic_info = EmbeddedDocumentField(BasicInfo)
    summary_info = EmbeddedDocumentField(SummaryInfo)
    skills = ListField(EmbeddedDocumentField(Skill))
    work_experience_text = StringField()
    work_experiences = ListField(EmbeddedDocumentField(Experience))
    certifications = ListField(EmbeddedDocumentField(Certification))
    schools = ListField(EmbeddedDocumentField(School))
    other = EmbeddedDocumentField(Other)
    languages = ListField(EmbeddedDocumentField(Language))
    reading_list = EmbeddedDocumentField(ReadingList)
    service_links_list = ListField(EmbeddedDocumentField(ServiceLink))

    def __repr__(self):
        return '<Resume: {}>'.format(self.title)

    def __str__(self):
        return '<Resume: {}>'.format(self.title)

class ResumeSettings(Document):
    enable_limited_resume = BooleanField(default=False)
    mail_to = StringField()
    limited_resume_url_specifier = StringField()
    hidden_experiences = ListField(StringField())
    looking_for = StringField()
    hide_basic_info = BooleanField(default=False)
    resume_link = URLField()

    enable_goodreads_booklist_sync = BooleanField(default=False)
    resume_to_sync = ReferenceField(document_type=Resume)


from tkinter import *
from pytube import YouTube

base = Tk()
base.geometry("500x300")
base.resizable(0, 0)
base.title("YT Video Downloader")

Label(base, text = "Youtube Video Downloader", font = "arial 20 bold").pack()

link = StringVar()

Label(base, text = "Paste Link Here:", font = 'arial 15 bold').place(x= 160 , y = 60)
link_enter = Entry(base, width = 70, textvariable = link).place(x = 32, y = 90)

def Downloader():
    url = YouTube(str(link.get()))
    video = url.streams.first()
    video.download()
    Label(base, text = "DOWNLOADED", font = "arial 15").place(x = 180 , y = 210)

Button(base, text = "DOWNLOAD", font = "arial 15 bold", bg = "pale violet red", padx = 2, command = Downloader).place(x = 180, y = 150)

base.mainloop()


#coding=utf-8
import torch
from torch.autograd import Variable
from torch.backends import cudnn
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
import numpy as np
import pprint
import os
import argparse
import pandas as pd

import warnings
warnings.filterwarnings("ignore")

# from data_load_gray_multiscale import MouseKeypointsDataset
from data_load_RGB_multiscale import MouseKeypointsDataset
from utilis.checkpointsave import savecheckpoint, saveepochcheckpont, saveepochcheckpont_PCK
from utilis.netparameter160 import config

from utilis.metrics import PCK
# from model.mainStackedHourGlass_full_finalcas2_C1GM2 import *
from model.mainStackedHourGlass_full_finalcas2_C3GM2 import *

from tensorboardX import SummaryWriter

cudnn.benchmark = True

device = torch.device("cuda:0,1" if torch.cuda.is_available() else "cpu")

#DeepLabCut dataset
# netname = 'mousefullnet_finalcas2_C1GM2_4fulltrain'
# validresultname = 'results/mouse/compare/results/validresult_fullnet_finalcas2_C1GM2_4fulltrain.csv'
# trainresultname = 'results/mouse/compare/results/trainresult_fullnet_finalcas2_C1GM2_4fulltrain.csv'

#PDMB
netname = 'pdmousefullnet_finalcas2_C3GM2'
validresultname = 'results/pdmouse/compare/results/validresult_fullnet_finalcas2_C3GM2.csv'
trainresultname = 'results/pdmouse/compare/results/trainresult_fullnet_finalcas2_C3GM2.csv'

#zebra dataset
# netname = 'zebrafullnet_finalcas2_C3GM2'
# validresultname = 'results/zebra/compare/results/validresult_fullnet_finalcas2_C3GM2.csv'
# trainresultname = 'results/zebra/compare/results/trainresult_fullnet_finalcas2_C3GM2.csv'

parser = argparse.ArgumentParser(description='PyTorch Mousepose Training')
parser.add_argument('--resume', '-r', action='store_true', help='resume from checkpoint')
args = parser.parse_args()

def get_peak_points(heatmaps):
    """
    heatmap to keypoints
    :param heatmaps: numpy array (N,4,240,320)
    :return:numpy array (N,4,2)
    """
    N,C,H,W = heatmaps.shape
    all_peak_points = []
    for i in range(N):
        peak_points = []
        for j in range(C):
            yy,xx = np.where(heatmaps[i,j] == heatmaps[i,j].max())
            y = yy[0]
            x = xx[0]
            peak_points.append([x,y])
        all_peak_points.append(peak_points)
    all_peak_points = np.array(all_peak_points)
    return all_peak_points

def get_mse(pred_points,gts,indices_valid=None):
    """

    :param pred_points: numpy (N,4,2)
    :param gts: numpy (N,4,2)
    :return:
    """
    pred_points = pred_points[indices_valid[0],indices_valid[1],:]
    gts = gts[indices_valid[0],indices_valid[1],:]
    pred_points = torch.from_numpy(pred_points).float()
    gts = torch.from_numpy(gts).float()
    criterion = nn.MSELoss()
    corloss = criterion(pred_points,gts)
    rmse = np.sqrt(corloss)
    #print("loss-----: %f" % corloss)
    return rmse

def calculate_mask(heatmaps_targets):
    """
    :param heatmaps_target: Variable (N,15,96,96)
    :return: Variable (N,15,96,96)
    """
    N,C,_,_ = heatmaps_targets.size()
    N_idx = []
    C_idx = []
    NaN_N_idx = []
    NaN_C_idx = []
    for n in range(N):
        for c in range(C):
            max_v = heatmaps_targets[n,c,:,:].max()
            if max_v != 0.0:
                N_idx.append(n)
                C_idx.append(c)
            else:
                NaN_N_idx.append(n)
                NaN_C_idx.append(c)

    mask = torch.zeros(heatmaps_targets.size())
    mask[N_idx,C_idx,:,:] = 1.
    # mask = mask.float().to(device)
    return mask,[N_idx,C_idx],[NaN_N_idx,NaN_C_idx]

def makenotvalidpointsasnan(predicted, gts,indices_notvalid):
    for i,j in zip(indices_notvalid[0],indices_notvalid[1]):
        predicted[i,j,:] = [-1,-1]
        gts[i, j, :] = [-1, -1]
    return  predicted, gts

def resume_checkpoint(net):
    '''
    :return:
    '''
    if args.resume:
        # Load checkpoint.
        print('==> Resuming from checkpoint..')
        assert os.path.isdir('checkpoint'), 'Error: no checkpoint directory found!'
        checkpoint = torch.load(os.path.join('./checkpoint', netname, 'epoch_6checkpoint.ckpt'))
        net.load_state_dict(checkpoint['net'])
        start_epoch = checkpoint['epoch']
        config['start_epoch'] = start_epoch+1

def initnet():
    pprint.pprint(config)
    torch.manual_seed(0)
    net = Gmscenet( nChannels=128, nStack=config['nstack'], nModules=1, numReductions=3, nJoints=4)

    # using 2 Gpus
    print("Let's use", torch.cuda.device_count(), "GPUs")
    if torch.cuda.device_count() > 1:
        print("Let's use", torch.cuda.device_count(), "GPUs")
        net = torch.nn.DataParallel(net)
    net.to(device)
    print(device)

    trainDataset = MouseKeypointsDataset(csv_file=config['trainsample'], root_dir='')
    sample_num = len(trainDataset)
    config['train_num'] = sample_num

    validDataset = MouseKeypointsDataset(csv_file=config['validsample'], root_dir='')
    sample_num = len(validDataset)
    config['valid_num'] = sample_num
    print('train:',  config['train_num'], 'validation:',  config['valid_num'])

    # split train and valid
    # train_size = int(0.8 * sample_num)
    # valid_size = sample_num - train_size
    # config['train_num'], config['valid_num'] = train_size, valid_size
    # train_db, val_db = torch.utils.data.random_split(trainDataset, [train_size, valid_size])
    # print('train:', len(train_db), 'validation:', len(val_db))

    trainDataLoader = DataLoader(trainDataset, config['batch_size'], shuffle=True, num_workers=2)
    validDataLoader = DataLoader(validDataset, config['batch_size_valid'], shuffle=True, num_workers=2)

    # if (config['checkout'] != ''):
    #     net.load_state_dict(torch.load(config['checkout'],map_location='cpu'))
    resume_checkpoint(net)
    return net, trainDataLoader,validDataLoader

def train(net, trainDataLoader, epoch):
    train_loss=0
    train_rmse=0
    train_PCK= 0
    train_PCK2= [0, 0, 0, 0 ,0]
    pckcount = [0, 0, 0, 0, 0]
    net.train()
    criterion = nn.MSELoss()
    # optimizer = optim.SGD(net.parameters(), lr=config['lr'], momentum=config['momentum'] , weight_decay=config['weight_decay'])
    optimizer = optim.Adam(net.parameters(), lr=config['lr'])

    for i, data in enumerate(trainDataLoader):
        inputs = data['image']
        heatmaps_targets = data['heatmaps']
        heatmaps_targets_2s = data['heatmaps_2s']
        gts = data['keypoints']
        mask, indices_valid, indices_notvalid = calculate_mask(heatmaps_targets)

        heatmaps_targets = heatmaps_targets * mask

        #2s
        mask_2s, indices_valid_2s, indices_notvalid_2s = calculate_mask(heatmaps_targets_2s)
        heatmaps_targets_2s = heatmaps_targets_2s * mask_2s

        inputs = inputs.to(device)
        heatmaps_targets = heatmaps_targets.to(device)
        mask = mask.float().to(device)

        #2s
        heatmaps_targets_2s = heatmaps_targets_2s.to(device)
        mask_2s = mask_2s.float().to(device)

        optimizer.zero_grad()
        outputs, outputs_2s = net(inputs)
        if(i ==0):
            print("outputs:   ", len(outputs))
            print("outputs_2s:   ", len(outputs_2s))

        #intermideate supervision
        loss=0
        loss_gm=0
        loss_2s=0

        #
        for j in range(config['nstack']+2):
            stackoutput = outputs[j] * mask
            loss += criterion(stackoutput, heatmaps_targets)
            # 2s
            if (j < config['nstack']+1):
                stackoutput_2s = outputs_2s[j] * mask_2s
                loss_2s += criterion(stackoutput_2s, heatmaps_targets_2s)
        loss = loss + loss_2s

        # for j in range(config['nstack'] + 2):
        #     if(j!= config['nstack']-1):
        #         stackoutput = outputs[j] * mask
        #         loss += criterion(stackoutput, heatmaps_targets)
        #     else:
        #         stackoutput = outputs[j] * mask
        #         loss_gm = criterion(stackoutput, heatmaps_targets)
        #     # 2s
        #     if (j < config['nstack']+1):
        #         stackoutput_2s = outputs_2s[j] * mask_2s
        #         loss_2s += criterion(stackoutput_2s, heatmaps_targets_2s)
        # loss =  loss + 1.4 * loss_gm + loss_2s

        loss.backward()
        optimizer.step()
        train_loss += loss.item()

        #gt size
        gts = gts.numpy()
        gts = gts * [ 2 , 2]
        # gts = gts.numpy() * [1 / 2, 1 / 2]

        # evaluate
        all_peak_points = get_peak_points(outputs_2s[config['nstack']].cpu().detach().numpy())
        # all_peak_points = get_peak_points(outputs[config['nstack']].cpu().detach().numpy())
        all_peak_points = all_peak_points * [2, 2]
        rmse = get_mse(all_peak_points, gts, indices_valid_2s)
        train_rmse += rmse

        # PCK
        acc,aveacc,_ = pck.eval(all_peak_points, gts, 0.2)
        train_PCK += aveacc

        #  each part pck
        for k in range(0, 5):
            if acc[k] != -1:
                pckcount[k] += 1
                train_PCK2[k] += acc[k]
        print('[ train---Epoch {:005d} -> {:005d} / {} ] loss : {:15} rmse : {:15} allPCK : {:5} {:5} {:5} {:5} {:5}'.format(
            epoch, i * config['batch_size'], config['train_num'], loss, rmse, acc[0], acc[1], acc[2], acc[3], acc[4]))

    trainallPCK = np.true_divide(train_PCK2, pckcount)
    AvetrainPCK = (trainallPCK[1] + trainallPCK[2] + trainallPCK[3] + trainallPCK[4]) / 4
    train_loss_everyepoch = train_loss / (i + 1)
    train_rmse_everyepoch = train_rmse / (i + 1)
    train_PCK_everyepoch = train_PCK / (i + 1)

    # save result
    dict = {'epoch': 0, 'lr': 0, 'loss': 0, 'rmse': 0, 'avePCKepoch': 0 , 'avePCK' : 0, 'part1PCK' : 0,
            'part2PCK' :0,  'part3PCK' :0, 'part4PCK' :0}
    dict['epoch'] = epoch
    dict['lr'] = config['lr']
    dict['loss'] = train_loss_everyepoch
    dict['rmse'] = train_rmse_everyepoch.numpy()
    dict['avePCKepoch'] = train_PCK_everyepoch
    dict['avePCK'] = AvetrainPCK
    dict['part1PCK'] = trainallPCK[1]
    dict['part2PCK'] = trainallPCK[2]
    dict['part3PCK'] = trainallPCK[3]
    dict['part4PCK'] = trainallPCK[4]

    df = pd.DataFrame([dict])
    if epoch == 0:
        df.to_csv(trainresultname)
    else:
        df.to_csv(trainresultname, mode='a', header=False)
    print('[ train---Epoch {:005d} ] loss : {:15} rmse : {:15} allPCK : {:5} {:5} {:5} {:5} {:5} {:5} '.format(epoch, train_loss_everyepoch, train_rmse_everyepoch, train_PCK_everyepoch,
                                                                                AvetrainPCK, trainallPCK[1], trainallPCK[2],trainallPCK[3], trainallPCK[4]))

    return net, (train_loss_everyepoch,train_rmse_everyepoch, train_PCK_everyepoch)

def valid(net, validDataLoader,epoch):
    lowrmse = 100000
    valid_loss = 0
    valid_rmse = 0
    valid_PCK = 0
    valid_PCK2 = [0, 0, 0, 0, 0]
    pckcount = [0, 0, 0, 0, 0]
    net.eval()
    criterion = nn.MSELoss()
    with torch.no_grad():
        for i, data in enumerate(validDataLoader):
            inputs = data['image']
            heatmaps_targets = data['heatmaps']
            heatmaps_targets_2s = data['heatmaps_2s']
            gts = data['keypoints']
            mask, indices_valid, indices_notvalid = calculate_mask(heatmaps_targets)
            heatmaps_targets = heatmaps_targets * mask

            #2s
            mask_2s, indices_valid_2s, indices_notvalid_2s = calculate_mask(heatmaps_targets_2s)
            heatmaps_targets_2s = heatmaps_targets_2s * mask_2s

            inputs = inputs.to(device)
            heatmaps_targets = heatmaps_targets.to(device)
            mask = mask.float().to(device)

            #2s
            heatmaps_targets_2s = heatmaps_targets_2s.to(device)
            mask_2s = mask_2s.float().to(device)

            outputs, outputs_2s = net(inputs)

            # intermideate supervision
            loss = 0
            loss_2s = 0

            for j in range(config['nstack']+2):
                stackoutput = outputs[j] * mask  # outputs为8次stack每次输出预测值，8哥tensor的列表
                loss += criterion(stackoutput, heatmaps_targets)
                # 2s
                if (j < config['nstack']+1 ):
                    stackoutput_2s = outputs_2s[j] * mask_2s  # outputs为8次stack每次输出预测值，8哥tensor的列表
                    loss_2s += criterion(stackoutput_2s, heatmaps_targets_2s)
            loss = loss + loss_2s
            valid_loss += loss.item()

            # gt size
            gts = gts.numpy()
            gts = gts* [ 2 , 2]
            # gts = gts.numpy() * [1 / 2, 1 / 2]

            all_peak_points = get_peak_points(outputs_2s[config['nstack']].cpu().detach().numpy())
            # all_peak_points = get_peak_points(outputs[config['nstack']].cpu().detach().numpy())
            all_peak_points = all_peak_points * [2, 2]
            rmse = get_mse(all_peak_points, gts, indices_valid_2s)  # 关键点坐标的loss
            valid_rmse += rmse

            # PCK
            acc, aveacc, _ = pck.eval(all_peak_points, gts, 0.2)
            valid_PCK += aveacc

            # 计算每个部位的pck
            for k in range(0, 5):
                if acc[k] != -1:
                    pckcount[k] += 1
                    valid_PCK2[k] += acc[k]
            print('[ valid---Epoch {:005d} -> {:005d} / {} ] loss : {:15} rmse : {:15} allPCK : {:5} {:5} {:5} {:5} {:5} {:5}'.format(
                epoch, i, config['valid_num'], loss, rmse, aveacc, acc[0], acc[1], acc[2], acc[3], acc[4]))

        validallPCK = np.true_divide(valid_PCK2, pckcount)
        AvevalidPCK = (validallPCK[1] + validallPCK[2] + validallPCK[3] + validallPCK[4]) / 4

        valid_loss_everyepoch = valid_loss / (i + 1)
        valid_rmse_everyepoch = valid_rmse / (i + 1)
        valid_PCK_everyepoch = valid_PCK / (i + 1)

        # save result
        validdict = {'epoch': 0, 'lr': 0,'loss': 0, 'rmse': 0, 'avePCKepoch': 0, 'avePCK': 0, 'part1PCK': 0,
                'part2PCK': 0, 'part3PCK': 0, 'part4PCK': 0, }
        validdict['epoch'] = epoch
        validdict['r'] = config['lr']
        validdict['loss'] = valid_loss_everyepoch
        validdict['rmse'] = valid_rmse_everyepoch.numpy()
        validdict['avePCKepoch'] = valid_PCK_everyepoch
        validdict['avePCK'] = AvevalidPCK
        validdict['part1PCK'] = validallPCK[1]
        validdict['part2PCK'] = validallPCK[2]
        validdict['part3PCK'] = validallPCK[3]
        validdict['part4PCK'] = validallPCK[4]

        df = pd.DataFrame([validdict])
        if epoch == 0:
            df.to_csv(validresultname)
        else:
            df.to_csv(validresultname, mode='a', header=False)

        print('[ valid---Epoch {:005d} ] loss : {:15} rmse : {:15} allPCK : {:5}, {:5} {:5} {:5} {:5} {:5}'.format( epoch, valid_loss_everyepoch, valid_rmse_everyepoch, valid_PCK_everyepoch,
                                                                                AvevalidPCK, validallPCK[1],
                                                                                validallPCK[2], validallPCK[3],
                                                                                validallPCK[4]
                                                                                ))

    # Save checkpoint.
    saveepochcheckpont_PCK(valid_PCK_everyepoch, config['highPCK'], epoch, net, netname)
    return (valid_loss_everyepoch,valid_rmse_everyepoch, valid_PCK_everyepoch)

if __name__ == '__main__':
    pck = PCK(njoints=4)
    writer = SummaryWriter(comment='mousepose_train')
    writer_total = SummaryWriter(comment='mousepose_valid')
    net,trainDataLoader, validDataLoader = initnet()
    updatelr = []
    for epoch in range(config['start_epoch'],config['epoch_num']+config['start_epoch']):
        running_loss = 0.0
        nettrain, (train_loss_everyepoch,train_rmse_everyepoch, train_PCK_everyepoch) = train(net, trainDataLoader, epoch)
        (valid_loss_everyepoch,valid_rmse_everyepoch, valid_PCK_everyepoch) = valid(nettrain, validDataLoader, epoch)
        updatelr.append(valid_rmse_everyepoch)
        writer.add_scalar('loss', train_loss_everyepoch, global_step=epoch)
        writer.add_scalar('RMSE', train_rmse_everyepoch, global_step=epoch)
        writer.add_scalar('PCK', train_PCK_everyepoch, global_step=epoch)

        writer_total.add_scalar('loss', valid_loss_everyepoch, global_step=epoch)
        writer_total.add_scalar('RMSE', valid_rmse_everyepoch, global_step=epoch)
        writer_total.add_scalar('PCK', valid_PCK_everyepoch, global_step=epoch)


import pandas as pd
import numpy as np
from tqdm import tqdm

"""
生成positive 和negative采样
"""

saving_file = "../../tmp/finData/finSamples4Level.npy"

# 实体表csv文件路径
ENTITY_DATA_PATH = "../../tmp/finData/finEntity.csv"
# 关系表csv文件路径
RELATION_DATA_PATH = "../../tmp/finData/finRelation.csv"
# [CLS]符号
CLS_CHAR = "$"
# [SEP]符号
SEP_CHAR = "#"
# '[PATH]'符号
PATH_CHAR = "@"
# 是否使用双重路径
USE_DOUBLE_PATH = True
# 选择目标节点时是否以更高概率选择同标签的实体
USE_WEIGHTED_SAMPLE = True
# 选择目标节点时，选择同标签的实体的概率/选择不同标签的实体的概率
SAME_LABEL_WEIGHT = 10
# 序列长度限制
SEQUENCE_LENGTH = 128
# 随机种子
RANDOM_SEED = 666
# 最大的邻域半径
MAX_LEVEL = 4
# 每个实体每个邻域半径生成的数据量
DATA_NUM = 2
# 反向关系映射表
REVERSE_RELATION = {
    "位于": "有公司",
    "属于行业": "行业包含",
    "法人代表": "法人代表",
    "产业链包含产品": "产品属于产业链",
    "公司生产产品": "由公司生产",
    "上下游产品": "上下游产品",
    "行业包含": "属于行业",
    "产品属于行业": "行业包含产品",
}

np.random.seed(RANDOM_SEED)

def get_entity_label(entity_data, relation_data):
    entity_label = {}
    for label, name_list in zip(entity_data["label"], entity_data["name_list"]):
        name_list = [i for i in name_list.split("|") if len(i) > 0]
        for name in name_list:
            entity_label[name] = label
    return entity_label

def get_relation_list(entity_data, relation_data):
    entity_id_to_name_list = {}
    for index, name_list in zip(entity_data["index"], entity_data["name_list"]):
        name_list = [i for i in name_list.split("|") if len(i) > 0]
        entity_id_to_name_list[index] = name_list
    relation_list = []
    for head_id, tail_id, label in zip(
            relation_data["head"], relation_data["tail"], relation_data["label"]):
        for head in entity_id_to_name_list[head_id]:
            for tail in entity_id_to_name_list[tail_id]:
                relation_list.append((head, tail, label))
    relation_list = sorted(list(set(relation_list)))
    return relation_list

def create_full_name_map(entity_df):
    """
    构造name-->id映射，包含全称、简称
    :param entity_df:
    :return:
    """
    full_name_to_id = {}
    for i in range(len(entity_df)):
        full_name = entity_df.iloc[i]['main_name']
        name_list = entity_df.iloc[i]['name_list'].split('|')
        if pd.isna(full_name):
            full_name = entity_df.iloc[i]["name_list"].split('|')[0]
            name_list = entity_df.iloc[i]['name_list'].split('|')
        id = int(entity_df.iloc[i]['index'])
        for name in name_list:
            full_name_to_id[name] = id
    return full_name_to_id

class KnowledgeGraphManager:
    def __init__(self, relation_list, entity_label):
        self.node = []
        self.neighbor = []
        self.relation = {}
        self.entity_name_to_id = {}
        self.entity_label = entity_label
        self.valid_node = []
        self.build_graph(relation_list)
        self.mark = [-1]*len(self.node)
        self.previous_node = [-1]*len(self.node)
        self.node_cache = []

    def add_node(self, name):
        if name not in self.entity_name_to_id:
            self.node.append(name)
            self.neighbor.append([])
            self.entity_name_to_id[name] = len(self.entity_name_to_id)

    def build_graph(self, relation_list):
        for head, tail, relation in relation_list:
            self.add_node(head)
            self.add_node(tail)
            if head != tail:
                head = self.entity_name_to_id[head]
                tail = self.entity_name_to_id[tail]
                self.neighbor[head].append(tail)
                self.neighbor[tail].append(head)
                self.relation[(head, tail)] = relation
                self.relation[(tail, head)] = REVERSE_RELATION.get(
                    relation, relation)
        for i in range(len(self.node)):
            if len(self.neighbor[i]) > 0:
                self.valid_node.append(self.node[i])
        np.random.shuffle(self.valid_node)

    def __iter__(self):
        return self.valid_node.__iter__()

    def __next__(self):
        return self.valid_node.__next__()

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

    def clear_cache(self):
        for u in self.node_cache:
            self.mark[u] = -1
            self.previous_node[u] = -1
        self.node_cache.clear()

    def bfs(self, start_node, max_depth):
        queue = [start_node]
        self.mark[start_node] = 0
        self.node_cache.append(start_node)
        while len(queue) > 0:
            u = queue.pop(0)
            for v in self.neighbor[u]:
                if self.mark[v] == -1:
                    self.mark[v] = self.mark[u]+1
                    self.previous_node[v] = u
                    self.node_cache.append(v)
                    if self.mark[v] < max_depth:
                        queue.append(v)

    def generate_shortest_path(self, start_node, end_node):
        shortest_path = [end_node]
        while shortest_path[0] != start_node:
            u = shortest_path[0]
            shortest_path.insert(0, self.previous_node[u])
        return shortest_path

    def generate_another_path(self, start_node, end_node, shortest_path):
        unvisible_node = set([i for i in shortest_path if i != end_node])
        visited_node = set()
        previous_node = {}
        queue = [start_node]
        visited_node.add(start_node)
        while len(queue) > 0:
            u = queue.pop(0)
            for v in self.neighbor[u]:
                if self.mark[v] != -1 and (v not in unvisible_node)\
                        and (v not in visited_node):
                    visited_node.add(v)
                    previous_node[v] = u
                    queue.append(v)
                    if v == end_node:
                        path = [v]
                        while path[0] != start_node:
                            path.insert(0, previous_node[path[0]])
                        return path
        return None

    def select_end_node(self, start_node, end_node_list):
        if USE_WEIGHTED_SAMPLE:
            p = [SAME_LABEL_WEIGHT if self.entity_label[start_node] == self.entity_label[end_node] else 1
                 for end_node in end_node_list]
            sum_p = sum(p)
            p = [i/sum_p for i in p]
            return np.random.choice(end_node_list, p=p)
        else:
            return np.random.choice(end_node_list)

    def path_to_str(self, path):
        result = self.node[path[0]] + SEP_CHAR
        for u, v in zip(path[:-1], path[1:]):
            result += self.relation[(u, v)] + SEP_CHAR
            result += self.node[v] + SEP_CHAR
        return result

    def __call__(self, start_node, max_depth):
        start_node = self.entity_name_to_id[start_node]
        self.bfs(start_node, max_depth)
        end_node_list = [self.node[i]
                         for i in self.node_cache if self.mark[i] == max_depth]
        if len(end_node_list) == 0:
            self.clear_cache()
            return None, None
        data = CLS_CHAR
        position = [0]
        while True:
            end_node = self.select_end_node(
                self.node[start_node], end_node_list)
            end_node = self.entity_name_to_id[end_node]
            shortest_path = self.generate_shortest_path(start_node, end_node)
            path = self.path_to_str(shortest_path)
            if USE_DOUBLE_PATH:
                another_path = self.generate_another_path(
                    start_node, end_node, shortest_path)
                if another_path is not None:
                    path += self.path_to_str(another_path)
            if len(data)+len(path) <= SEQUENCE_LENGTH:
                data += path
                position += [position[-1] + 1] * len(path)
                # print(len(data), len(position))
            else:
                self.clear_cache()
                return data, position

# 读取csv文件
entity_data = pd.read_csv(ENTITY_DATA_PATH)
relation_data = pd.read_csv(RELATION_DATA_PATH)
# 获取实体名到实体标签的映射
entity_label = get_entity_label(entity_data, relation_data)
# 获取关系列表（已将实体按照名称克隆）
relation_list = get_relation_list(entity_data, relation_data)
# 输出KG信息
print("%d entities, %d relations" % (len(entity_label), len(relation_list)))
# 构造name2id字典
name2id = create_full_name_map(entity_data)

# 初始化KG管理器
manager = KnowledgeGraphManager(relation_list, entity_label)

# 搞起来！
data_dict = {}
for start_entity in tqdm(manager):
    start_entity_id = name2id[start_entity]
    data_dict[start_entity_id] = {}
    for level in range(1, MAX_LEVEL+1):
        data_dict[start_entity_id]["level_%d" % level] = []
        for i in range(DATA_NUM):
            sequence, position = manager(start_entity, level)
            # 需要注意，如果半径为level的邻域边界上没有节点，则返回None，这仅在邻域半径过大时发生
            if sequence is not None:

                # 转换为token_id，并且控制sequence_len
                # tokens = ["[CLS]" if x == "$" else ("[SEP]" if x == "#" else ("[PATH]" if x=="@" else x)) for x in sequence]
                tokens = ["[CLS]" if x == "$" else ("[SEP]" if x == "#" else x) for x in sequence]
                data_dict[start_entity_id]["level_%d" % level].append(
                    {'name': start_entity, 'sequence': sequence, 'tokens': tokens, 'position_id': position}
                )

# print(data_dict["浦发银行"])
np.save(saving_file, data_dict)
print("successful save ", saving_file)


# -*- coding: utf-8 -*-
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.addons.http_routing.models.ir_http import slug, slugify
import json

class EventTheater(models.Model):
    _name = 'event.theater'
    _description = 'Theater'

    name = fields.Char(string='Name', required=True)
    disposition = fields.Text(string='Disposition', required=True)
    seats_names = fields.Text(string='Seats names', required=True, help="Category, relative to seat map. One category per line. Ex: A: Section A")
    colors = fields.Text(string='Colors', help="Colors, relative to seat map. One color (HTML code) per line. Ex: A: #00ff00")
    rows = fields.Selection([('letter', 'Letters'), ('number', 'Numbers')], string='Label on rows', default='letter', required=True)
    display_selected = fields.Selection([('single', 'Single'), ('group', 'Group'), ('both', 'Both')], string='Display selected seats', default='both', required=True)
    seat_ids = fields.One2many('event.theater.seat', 'theater_id', string='Seats')
    active = fields.Boolean(string='Active', default=True)

    @api.multi
    def open_website_url(self):
        self.ensure_one()
        return {
            'type': 'ir.actions.act_url',
            'url': '/event_seating/preview/%s' % slug(self),
            'target': 'self',
        }

    @api.multi
    def get_json_disposition(self):
        self.ensure_one()
        res = []
        for row in self.disposition.strip().split('\n'):
            res.append(row.strip())
        return json.dumps(res)

    @api.multi
    def _get_seats_name_mapping(self):
        self.ensure_one()
        res = {}
        for line in self.seats_names.split('\n'):
            line = line.strip()
            if line:
                seat, name = list(map(str.strip, line.split(':', 1)))
                res[seat] = {
                    'classes': slugify(name),
                    'category': name,
                }
        return res

    @api.multi
    def _get_seat_colors_mapping(self):
        self.ensure_one()
        res = {}
        if self.colors:
            for line in self.colors.split('\n'):
                line = line.strip()
                if line:
                    seat, color = list(map(str.strip, line.split(':', 1)))
                    res[seat] = color
        return res

    @api.multi
    def get_json_seats(self):
        self.ensure_one()
        return json.dumps(self._get_seats_name_mapping())

    @api.multi
    def get_css_seats_colors(self):
        self.ensure_one()
        classes = self._get_seats_name_mapping()
        colors = self._get_seat_colors_mapping()
        res = ''
        for sear, color in colors.items():
            cl = classes.get(sear, {}).get('classes')
            if cl:
                res += '.seatCharts-seat.available.%s { background-color: %s !important; }\n' % (cl, color)
        return '<style>%s</style>' % res if res else ''

    @api.multi
    def get_json_legend_items(self):
        self.ensure_one()
        res = []
        infos = self._get_seats_name_mapping()
        for seat, info in infos.items():
            res.append([seat, 'available', info['category']])
        res.append(['', 'unavailable', _('Booked')])
        return json.dumps(res)

    @api.multi
    def _get_rows_label(self):
        self.ensure_one()
        rows = self.disposition.strip().split('\n')
        res = range(1, len(rows) + 1, 1)
        if self.rows == 'letter':
            res = [chr(i + 64) for i in res]
        return res

    @api.multi
    def get_rows(self):
        self.ensure_one()
        return json.dumps(self._get_rows_label())

    @api.one
    def create_seats_from_theater(self):
        self.env['event.theater.seat'].search([('theater_id', '=', self.id)]).unlink()
        seat_names = self._get_seats_name_mapping()
        row_labels = self._get_rows_label()
        row = 1
        n = 1
        for line in self.disposition.strip().split('\n'):
            col = 1
            line = line.strip()
            for c in line:
                if c != '_':
                    label = '%s-%s' % (row_labels[row-1], n)
                    self.env['event.theater.seat'].create({
                        'theater_id': self.id,
                        'column': col,
                        'row': row,
                        'character': c,
                        'label': label,
                        'category': seat_names.get(c, {}).get('category', False),
                        'reduced_mobility': col == 1 or col == len(line) or line[col - 2] == '_' or line[col] == '_',
                    })
                    n += 1
                col += 1
            row += 1

    @api.one
    @api.constrains('disposition', 'seats_names')
    def check_disposition_and_names(self):
        row_length = False
        characters = set()
        for line in self.disposition.strip().split('\n'):
            if not row_length:
                row_length = len(line.strip())
            elif len(line.strip()) != row_length:
                raise ValidationError(_('All lines in disposition must have the same length. Use "_" to fill the line.'))
            else:
                for c in line.strip():
                    if c != '_':
                        characters.add(c)
        names = set(self._get_seats_name_mapping().keys())
        for c in characters:
            if c not in names:
                raise ValidationError(_('All used characters in disposition (except "_") must have a seat name.'))

    @api.model
    def create(self, vals):
        record = super(EventTheater, self).create(vals)
        record.create_seats_from_theater()
        return record

    @api.multi
    def write(self, vals):
        res = super(EventTheater, self).write(vals)
        self.create_seats_from_theater()
        return res

class EventTheaterSeat(models.Model):
    _name = 'event.theater.seat'
    _description = 'Theater seat'
    _rec_name = 'label'

    theater_id = fields.Many2one('event.theater', string='Theaters', required=True, ondelete='cascade')
    column = fields.Integer(string='Column')
    row = fields.Integer(string='Row')
    character = fields.Char(string='Character', size=1)
    label = fields.Char(string='Label', required=True)
    category = fields.Char(string='Category')
    reduced_mobility = fields.Boolean(string='Reduced Mobility')

    def __repr__(self):
        return self.label

    def __str__(self):
        return self.label


#!/usr/bin/env python

"""Time humanizing functions.  These are largely borrowed from Django's
``contrib.humanize``."""

import datetime as dt
from enum import Enum

from .i18n import gettext as _
from .i18n import ngettext

__all__ = ["naturaldelta", "naturaltime", "naturalday", "naturaldate"]

class Unit(Enum):
    MILLISECONDS = 0
    MICROSECONDS = 1
    SECONDS = 2

def _now():
    return dt.datetime.now()

def abs_timedelta(delta):
    """Returns an "absolute" value for a timedelta, always representing a
    time distance."""
    if delta.days < 0:
        now = _now()
        return now - (now + delta)
    return delta

def date_and_delta(value, *, now=None):
    """Turn a value into a date and a timedelta which represents how long ago
    it was.  If that's not possible, return (None, value)."""
    if not now:
        now = _now()
    if isinstance(value, dt.datetime):
        date = value
        delta = now - value
    elif isinstance(value, dt.timedelta):
        date = now - value
        delta = value
    else:
        try:
            value = int(value)
            delta = dt.timedelta(seconds=value)
            date = now - delta
        except (ValueError, TypeError):
            return None, value
    return date, abs_timedelta(delta)

def naturaldelta(value, months=True, minimum_unit="seconds"):
    """Return a natural representation of a timedelta or number of seconds.

    This is similar to naturaltime, but does not add tense to the result.

    Args:
        value: A timedelta or a number of seconds.
        months: If True, then a number of months (based on 30.5 days) will be used for
            fuzziness between years.
        minimum_unit: If microseconds or milliseconds, use those units for subsecond
            deltas.

    Returns:
        str: A natural representation of the amount of time elapsed.
    """
    minimum_unit = Unit[minimum_unit.upper()]
    date, delta = date_and_delta(value)
    if date is None:
        return value

    use_months = months

    seconds = abs(delta.seconds)
    days = abs(delta.days)
    years = days // 365
    days = days % 365
    months = int(days // 30.5)

    if not years and days < 1:
        if seconds == 0:
            if minimum_unit == Unit.MICROSECONDS:
                return (
                    ngettext("%d microsecond", "%d microseconds", delta.microseconds)
                    % delta.microseconds
                )
            elif minimum_unit == Unit.MILLISECONDS:
                milliseconds = delta.microseconds / 1000
                return (
                    ngettext("%d millisecond", "%d milliseconds", milliseconds)
                    % milliseconds
                )
            return _("a moment")
        elif seconds == 1:
            return _("a second")
        elif seconds < 60:
            return ngettext("%d second", "%d seconds", seconds) % seconds
        elif 60 <= seconds < 120:
            return _("a minute")
        elif 120 <= seconds < 3600:
            minutes = seconds // 60
            return ngettext("%d minute", "%d minutes", minutes) % minutes
        elif 3600 <= seconds < 3600 * 2:
            return _("an hour")
        elif 3600 < seconds:
            hours = seconds // 3600
            return ngettext("%d hour", "%d hours", hours) % hours
    elif years == 0:
        if days == 1:
            return _("a day")
        if not use_months:
            return ngettext("%d day", "%d days", days) % days
        else:
            if not months:
                return ngettext("%d day", "%d days", days) % days
            elif months == 1:
                return _("a month")
            else:
                return ngettext("%d month", "%d months", months) % months
    elif years == 1:
        if not months and not days:
            return _("a year")
        elif not months:
            return ngettext("1 year, %d day", "1 year, %d days", days) % days
        elif use_months:
            if months == 1:
                return _("1 year, 1 month")
            else:
                return (
                    ngettext("1 year, %d month", "1 year, %d months", months) % months
                )
        else:
            return ngettext("1 year, %d day", "1 year, %d days", days) % days
    else:
        return ngettext("%d year", "%d years", years) % years

def naturaltime(value, future=False, months=True, minimum_unit="seconds"):
    """Return a natural representation of a time in a resolution that makes sense.

    This is more or less compatible with Django's naturaltime filter.

    Args:
        value: A timedate or a number of seconds.
        future: Ignored for datetimes, where the tense is always figured out based on
            the current time. For integers, the return value will be past tense by
            default, unless future is True.
        months: If True, then a number of months (based on 30.5 days) will be used for
            fuzziness between years.
        minimum_unit: If microseconds or milliseconds, use those units for subsecond
            times.

    Returns:
        str: A natural representation of the input in a resolution that makes sense.
    """
    now = _now()
    date, delta = date_and_delta(value, now=now)
    if date is None:
        return value
    # determine tense by value only if datetime/timedelta were passed
    if isinstance(value, (dt.datetime, dt.timedelta)):
        future = date > now

    ago = _("%s from now") if future else _("%s ago")
    delta = naturaldelta(delta, months, minimum_unit)

    if delta == _("a moment"):
        return _("now")

    return ago % delta

def naturalday(value, format="%b %d"):
    """For date values that are tomorrow, today or yesterday compared to
    present day returns representing string. Otherwise, returns a string
    formatted according to ``format``."""
    try:
        value = dt.date(value.year, value.month, value.day)
    except AttributeError:
        # Passed value wasn't date-ish
        return value
    except (OverflowError, ValueError):
        # Date arguments out of range
        return value
    delta = value - dt.date.today()
    if delta.days == 0:
        return _("today")
    elif delta.days == 1:
        return _("tomorrow")
    elif delta.days == -1:
        return _("yesterday")
    return value.strftime(format)

def naturaldate(value):
    """Like naturalday, but append a year for dates more than about five months away.
    """
    try:
        value = dt.date(value.year, value.month, value.day)
    except AttributeError:
        # Passed value wasn't date-ish
        return value
    except (OverflowError, ValueError):
        # Date arguments out of range
        return value
    delta = abs_timedelta(value - dt.date.today())
    if delta.days >= 5 * 365 / 12:
        return naturalday(value, "%b %d %Y")
    return naturalday(value)


from typing import List

from flask import current_app

from raspcuterie.devices import InputDevice
from raspcuterie.devices import OutputDevice

class ControlRule:
    registry: List["ControlRule"] = []

    def __init__(self, device: OutputDevice, expression: str, action: str, name: str = None):
        ControlRule.registry.append(self)
        self.name = name
        self.device: OutputDevice = device
        self.expression: str = expression
        self.action: str = action

    @staticmethod
    def context():
        context = {}

        for device in InputDevice.registry.values():
            context.update(device.get_context())
        return context

    def matches(self):
        return eval(self.expression, self.context())

    def execute(self):
        try:
            action = getattr(self.device, self.action)
            return action()
        except Exception as e:
            current_app.logger.exeception(e)

    def execute_if_matches(self):
        if self.matches():
            current_app.logger.info(f"Matches expression {self.expression}, executing {self.name}.{self.action}")
            return self.execute()
        else:
            current_app.logger.info(f"Does not match expression: {self.expression}")


import pytest
import server
from server import app

@pytest.fixture
def client():
    """ Fixture du client pour tests """
    app.config['TESTING'] = True
    with app.test_client() as client:
        yield client

@pytest.fixture
def load_clubs(mocker):
    """ Fixture données clubs pour tests """
    return mocker.patch.object(
            server,
            'clubs',
            [{
                "name": "Club Test",
                "email": "secretary@clubtest.com",
                "points": "8"
                }]
            )

@pytest.fixture
def load_competitions(mocker):
    """ Fixture données compétititons pour tests """
    return mocker.patch.object(
            server,
            'competitions',
            [
                {
                    "name": "Competition Test",
                    "date": "2022-03-27 10:00:00",
                    "numberOfPlaces": "12"
                },
                {
                    "name": "Passed Test",
                    "date": "2020-03-27 10:00:00",
                    "numberOfPlaces": "12"
                }
                ]
            )