import sys
import os
import pathlib
sys.path.append(os.path.join(pathlib.Path(__file__).parent.absolute(), '..'))
import glob
import copy
import torch
import numpy as np
import time
from options import TrainOptions
from data import create_data_loader, create_dataset
from models import create_model
from models.mvs.mvs_points_model import MvsPointsModel
from models.mvs import mvs_utils, filter_utils
from pprint import pprint
from utils.visualizer import Visualizer
from utils import format as fmt
from run.evaluate import report_metrics
torch.manual_seed(0)
np.random.seed(0)
import random
import cv2
from PIL import Image
from tqdm import tqdm
import gc

def mse2psnr(x): return -10.* torch.log(x)/np.log(10.)

def save_image(img_array, filepath):
    assert len(img_array.shape) == 2 or (len(img_array.shape) == 3
                                         and img_array.shape[2] in [3, 4])

    if img_array.dtype != np.uint8:
        img_array = (np.clip(img_array, 0, 1) * 255).astype(np.uint8)
    os.makedirs(os.path.dirname(filepath), exist_ok=True)
    Image.fromarray(img_array).save(filepath)

def nearest_view(campos, raydir, xyz, id_list):
    cam_ind = torch.zeros([0,1], device=campos.device, dtype=torch.long)
    step=10000
    for i in range(0, len(xyz), step):
        dists = xyz[i:min(len(xyz),i+step), None, :] - campos[None, ...] # N, M, 3
        dists_norm = torch.norm(dists, dim=-1) # N, M
        dists_dir = dists / (dists_norm[...,None]+1e-6) # N, M, 3
        dists = dists_norm / 200 + (1.1 - torch.sum(dists_dir * raydir[None, :],dim=-1)) # N, M
        cam_ind = torch.cat([cam_ind, torch.argmin(dists, dim=1).view(-1,1)], dim=0) # N, 1
    return cam_ind

def masking(mask, firstdim_lst, seconddim_lst):
    first_lst = [item[mask, ...] if item is not None else None for item in firstdim_lst]
    second_lst = [item[:, mask, ...] if item is not None else None for item in seconddim_lst]
    return first_lst, second_lst

def render_vid(model, dataset, visualizer, opt, bg_info, steps=0, gen_vid=True):
    print('-----------------------------------Rendering-----------------------------------')
    model.eval()
    total_num = dataset.total
    print("test set size {}, interval {}".format(total_num, opt.test_num_step))
    patch_size = opt.random_sample_size
    chunk_size = patch_size * patch_size

    height = dataset.height
    width = dataset.width
    visualizer.reset()
    for i in range(0, total_num):
        data = dataset.get_dummyrot_item(i)
        raydir = data['raydir'].clone()
        pixel_idx = data['pixel_idx'].view(data['pixel_idx'].shape[0], -1, data['pixel_idx'].shape[3]).clone()
        # cam_posts.append(data['campos'])
        # cam_dirs.append(data['raydir'] + data['campos'][None,...])
        # continue
        visuals = None
        stime = time.time()

        for k in range(0, height * width, chunk_size):
            start = k
            end = min([k + chunk_size, height * width])
            data['raydir'] = raydir[:, start:end, :]
            data["pixel_idx"] = pixel_idx[:, start:end, :]
            # print("tmpgts", tmpgts["gt_image"].shape)
            # print(data["pixel_idx"])
            model.set_input(data)
            if opt.bgmodel.endswith("plane"):
                img_lst, c2ws_lst, w2cs_lst, intrinsics_all, HDWD_lst, fg_masks, bg_ray_lst = bg_info
                if len(bg_ray_lst) > 0:
                    bg_ray_all = bg_ray_lst[data["id"]]
                    bg_idx = data["pixel_idx"].view(-1,2)
                    bg_ray = bg_ray_all[:, bg_idx[:,1].long(), bg_idx[:,0].long(), :]
                else:
                    xyz_world_sect_plane = mvs_utils.gen_bg_points(data)
                    bg_ray, _ = model.set_bg(xyz_world_sect_plane, img_lst, c2ws_lst, w2cs_lst, intrinsics_all, HDWD_lst, data["plane_color"], fg_masks=fg_masks, vis=visualizer)
                data["bg_ray"] = bg_ray

            model.test()
            curr_visuals = model.get_current_visuals(data=data)
            if visuals is None:
                visuals = {}
                for key, value in curr_visuals.items():
                    if key == "gt_image": continue
                    chunk = value.cpu().numpy()
                    visuals[key] = np.zeros((height * width, 3)).astype(chunk.dtype)
                    visuals[key][start:end, :] = chunk
            else:
                for key, value in curr_visuals.items():
                    if key == "gt_image": continue
                    visuals[key][start:end, :] = value.cpu().numpy()

        for key, value in visuals.items():
            visualizer.print_details("{}:{}".format(key, visuals[key].shape))
            visuals[key] = visuals[key].reshape(height, width, 3)
        print("num.{} in {} cases: time used: {} s".format(i, total_num // opt.test_num_step, time.time() - stime), " at ", visualizer.image_dir)
        visualizer.display_current_results(visuals, i)

    # visualizer.save_neural_points(200, np.concatenate(cam_posts, axis=0),None, None, save_ref=False)
    # visualizer.save_neural_points(200, np.concatenate(cam_dirs, axis=0),None, None, save_ref=False)
    # print("vis")
    # exit()

    print('--------------------------------Finish Evaluation--------------------------------')
    if gen_vid:
        del dataset
        visualizer.gen_video("coarse_raycolor", range(0, total_num), 0)
        print('--------------------------------Finish generating vid--------------------------------')

    return

def test(model, dataset, visualizer, opt, bg_info, test_steps=0, gen_vid=True, lpips=True):
    print('-----------------------------------Testing-----------------------------------')
    model.eval()
    total_num = dataset.total
    print("test set size {}, interval {}".format(total_num, opt.test_num_step)) # 1 if test_steps == 10000 else opt.test_num_step
    patch_size = opt.random_sample_size
    chunk_size = patch_size * patch_size

    height = dataset.height
    width = dataset.width
    visualizer.reset()
    count = 0;
    for i in range(0, total_num, opt.test_num_step): # 1 if test_steps == 10000 else opt.test_num_step
        data = dataset.get_item(i)
        raydir = data['raydir'].clone()
        pixel_idx = data['pixel_idx'].view(data['pixel_idx'].shape[0], -1, data['pixel_idx'].shape[3]).clone()
        edge_mask = torch.zeros([height, width], dtype=torch.bool)
        edge_mask[pixel_idx[0,...,1].to(torch.long), pixel_idx[0,...,0].to(torch.long)] = 1
        edge_mask=edge_mask.reshape(-1) > 0
        np_edge_mask=edge_mask.numpy().astype(bool)
        totalpixel = pixel_idx.shape[1]
        tmpgts = {}
        tmpgts["gt_image"] = data['gt_image'].clone()
        tmpgts["gt_mask"] = data['gt_mask'].clone() if "gt_mask" in data else None
        print("data['gt_image']")
        # data.pop('gt_image', None)
        data.pop('gt_mask', None)

        visuals = None
        stime = time.time()
        ray_masks = []
        for k in range(0, totalpixel, chunk_size):
            start = k
            end = min([k + chunk_size, totalpixel])
            data['raydir'] = raydir[:, start:end, :]
            data["pixel_idx"] = pixel_idx[:, start:end, :]
            model.set_input(data)

            if opt.bgmodel.endswith("plane"):
                img_lst, c2ws_lst, w2cs_lst, intrinsics_all, HDWD_lst, fg_masks, bg_ray_lst = bg_info
                if len(bg_ray_lst) > 0:
                    bg_ray_all = bg_ray_lst[data["id"]]
                    bg_idx = data["pixel_idx"].view(-1,2)
                    bg_ray = bg_ray_all[:, bg_idx[:,1].long(), bg_idx[:,0].long(), :]
                else:
                    xyz_world_sect_plane = mvs_utils.gen_bg_points(data)
                    bg_ray, _ = model.set_bg(xyz_world_sect_plane, img_lst, c2ws_lst, w2cs_lst, intrinsics_all, HDWD_lst, data["plane_color"], fg_masks=fg_masks, vis=visualizer)
                data["bg_ray"] = bg_ray

            model.test()
            curr_visuals = model.get_current_visuals(data=data)
            chunk_pixel_id = data["pixel_idx"].cpu().numpy().astype(np.int32)
            if visuals is None:
                visuals = {}
                for key, value in curr_visuals.items():
                    if value is None or key=="gt_image":
                        continue
                    chunk = value.cpu().numpy()
                    visuals[key] = np.zeros((height, width, 3)).astype(chunk.dtype)
                    visuals[key][chunk_pixel_id[0,...,1], chunk_pixel_id[0,...,0], :] = chunk
            else:
                for key, value in curr_visuals.items():
                    if value is None or key=="gt_image":
                        continue
                    visuals[key][chunk_pixel_id[0,...,1], chunk_pixel_id[0,...,0], :] = value.cpu().numpy()
            if "ray_mask" in model.output and "ray_masked_coarse_raycolor" in opt.test_color_loss_items:
                ray_masks.append(model.output["ray_mask"] > 0)
        if len(ray_masks) > 0:
            ray_masks = torch.cat(ray_masks, dim=1)
        gt_image = torch.zeros((height*width, 3), dtype=torch.float32)
        gt_image[edge_mask, :] = tmpgts['gt_image'].clone()
        if 'gt_image' in model.visual_names:
            visuals['gt_image'] = gt_image
        if 'gt_mask' in curr_visuals:
            visuals['gt_mask'] = np.zeros((height, width, 3)).astype(chunk.dtype)
            visuals['gt_mask'][np_edge_mask,:] = tmpgts['gt_mask']
        if 'ray_masked_coarse_raycolor' in model.visual_names:
            visuals['ray_masked_coarse_raycolor'] = np.copy(visuals["coarse_raycolor"]).reshape(height, width, 3)
            print(visuals['ray_masked_coarse_raycolor'].shape, ray_masks.cpu().numpy().shape)
            visuals['ray_masked_coarse_raycolor'][ray_masks.view(height, width).cpu().numpy() <= 0,:] = 0.0
        if 'ray_depth_masked_coarse_raycolor' in model.visual_names:
            visuals['ray_depth_masked_coarse_raycolor'] = np.copy(visuals["coarse_raycolor"]).reshape(height, width, 3)
            visuals['ray_depth_masked_coarse_raycolor'][model.output["ray_depth_mask"][0].cpu().numpy() <= 0] = 0.0
        if 'ray_depth_masked_gt_image' in model.visual_names:
            visuals['ray_depth_masked_gt_image'] = np.copy(tmpgts['gt_image']).reshape(height, width, 3)
            visuals['ray_depth_masked_gt_image'][model.output["ray_depth_mask"][0].cpu().numpy() <= 0] = 0.0
        if 'gt_image_ray_masked' in model.visual_names:
            visuals['gt_image_ray_masked'] = np.copy(tmpgts['gt_image']).reshape(height, width, 3)
            visuals['gt_image_ray_masked'][ray_masks.view(height, width).cpu().numpy() <= 0,:] = 0.0
        for key, value in visuals.items():
            if key in opt.visual_items:
                visualizer.print_details("{}:{}".format(key, visuals[key].shape))
                visuals[key] = visuals[key].reshape(height, width, 3)

        print("num.{} in {} cases: time used: {} s".format(i, total_num // opt.test_num_step, time.time() - stime), " at ", visualizer.image_dir)
        visualizer.display_current_results(visuals, i, opt=opt)

        acc_dict = {}
        if "coarse_raycolor" in opt.test_color_loss_items:
            loss = torch.nn.MSELoss().to("cuda")(torch.as_tensor(visuals["coarse_raycolor"], device="cuda").view(1, -1, 3), gt_image.view(1, -1, 3).cuda())
            acc_dict.update({"coarse_raycolor": loss})
            print("coarse_raycolor", loss, mse2psnr(loss))

        if "ray_mask" in model.output and "ray_masked_coarse_raycolor" in opt.test_color_loss_items:
            masked_gt = tmpgts["gt_image"].view(1, -1, 3).cuda()[ray_masks,:].reshape(1, -1, 3)
            ray_masked_coarse_raycolor = torch.as_tensor(visuals["coarse_raycolor"], device="cuda").view(1, -1, 3)[:,edge_mask,:][ray_masks,:].reshape(1, -1, 3)
            loss = torch.nn.MSELoss().to("cuda")(ray_masked_coarse_raycolor, masked_gt)
            acc_dict.update({"ray_masked_coarse_raycolor": loss})
            visualizer.print_details("{} loss:{}, PSNR:{}".format("ray_masked_coarse_raycolor", loss, mse2psnr(loss)))

        if "ray_depth_mask" in model.output and "ray_depth_masked_coarse_raycolor" in opt.test_color_loss_items:
            ray_depth_masks = model.output["ray_depth_mask"].reshape(model.output["ray_depth_mask"].shape[0], -1)
            masked_gt = torch.masked_select(tmpgts["gt_image"].view(1, -1, 3).cuda(), (ray_depth_masks[..., None].expand(-1, -1, 3)).reshape(1, -1, 3))
            ray_depth_masked_coarse_raycolor = torch.masked_select(torch.as_tensor(visuals["coarse_raycolor"], device="cuda").view(1, -1, 3), ray_depth_masks[..., None].expand(-1, -1, 3).reshape(1, -1, 3))

            loss = torch.nn.MSELoss().to("cuda")(ray_depth_masked_coarse_raycolor, masked_gt)
            acc_dict.update({"ray_depth_masked_coarse_raycolor": loss})
            visualizer.print_details("{} loss:{}, PSNR:{}".format("ray_depth_masked_coarse_raycolor", loss, mse2psnr(loss)))
        print(acc_dict.items())
        visualizer.accumulate_losses(acc_dict)
        count+=1

    visualizer.print_losses(count)
    psnr = visualizer.get_psnr(opt.test_color_loss_items[0])
    print('--------------------------------Finish Test Rendering--------------------------------')
    report_metrics(visualizer.image_dir, visualizer.image_dir, visualizer.image_dir, ["psnr", "ssim", "lpips", "vgglpips", "rmse"] if lpips else ["psnr", "ssim", "rmse"], [i for i in range(0, total_num, opt.test_num_step)], imgStr="step-%04d-{}.png".format(opt.visual_items[0]),gtStr="step-%04d-{}.png".format(opt.visual_items[1]))
    print('--------------------------------Finish Evaluation--------------------------------')
    if gen_vid:
        del dataset
        visualizer.gen_video("coarse_raycolor", range(0, total_num, opt.test_num_step), test_steps)
        print('--------------------------------Finish generating vid--------------------------------')
    return psnr

def get_latest_epoch(resume_dir):
    os.makedirs(resume_dir, exist_ok=True)
    str_epoch = [file.split("_")[0] for file in os.listdir(resume_dir) if file.endswith("_states.pth")]
    int_epoch = [int(i) for i in str_epoch]
    return None if len(int_epoch) == 0 else str_epoch[int_epoch.index(max(int_epoch))]

def main():
    torch.backends.cudnn.benchmark = True

    opt = TrainOptions().parse()
    cur_device = torch.device('cuda:{}'.format(opt.gpu_ids[0]) if opt.
                              gpu_ids else torch.device('cpu'))
    print("opt.color_loss_items ", opt.color_loss_items)

    if opt.debug:
        torch.autograd.set_detect_anomaly(True)
        print(fmt.RED +
              '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
        print('Debug Mode')
        print(
            '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++' +
            fmt.END)
    visualizer = Visualizer(opt)
    train_dataset = create_dataset(opt)
    img_lst=None
    with torch.no_grad():
        print(opt.checkpoints_dir + opt.name + "/*_net_ray_marching.pth")
        if opt.bgmodel.endswith("plane"):
            _, _, _, _, _, img_lst, c2ws_lst, w2cs_lst, intrinsics_all, HDWD_lst = gen_points_filter_embeddings(train_dataset, visualizer, opt)

        resume_dir = os.path.join(opt.checkpoints_dir, opt.name)
        if opt.resume_iter == "best":
            opt.resume_iter = "latest"
        resume_iter = opt.resume_iter if opt.resume_iter != "latest" else get_latest_epoch(resume_dir)
        if resume_iter is None:
            visualizer.print_details("No previous checkpoints at iter {} !!", resume_iter)
            exit()
        else:
            opt.resume_iter = resume_iter
            visualizer.print_details('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
            visualizer.print_details('test at {} iters'.format(opt.resume_iter))
            visualizer.print_details(f"Iter: {resume_iter}")
            visualizer.print_details('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
        opt.mode = 2
        opt.load_points=1
        opt.resume_dir=resume_dir
        opt.resume_iter = resume_iter
        opt.is_train=True

    model = create_model(opt)
    model.setup(opt, train_len=len(train_dataset))
    # create test loader
    test_opt = copy.deepcopy(opt)
    test_opt.is_train = False
    test_opt.random_sample = 'no_crop'
    test_opt.random_sample_size = min(48, opt.random_sample_size)
    test_opt.batch_size = 1
    test_opt.n_threads = 0
    test_opt.prob = 0
    test_opt.split = "test"
    visualizer.reset()

    fg_masks = None
    test_bg_info = None
    if opt.bgmodel.endswith("plane"):
        test_dataset = create_dataset(test_opt)
        bg_ray_test_lst = create_all_bg(test_dataset, model, img_lst, c2ws_lst, w2cs_lst, intrinsics_all, HDWD_lst)
        test_bg_info = [img_lst, c2ws_lst, w2cs_lst, intrinsics_all, HDWD_lst, fg_masks, bg_ray_test_lst]
        del test_dataset
        # if opt.vid > 0:
        #     render_dataset = create_render_dataset(test_opt, opt, resume_iter, test_num_step=opt.test_num_step)
    ############ initial test ###############
    with torch.no_grad():
        test_opt.nerf_splits = ["test"]
        test_opt.split = "test"
        test_opt.name = opt.name + "/test_{}".format(resume_iter)
        test_opt.test_num_step = opt.test_num_step
        test_dataset = create_dataset(test_opt)
        model.opt.is_train = 0
        model.opt.no_loss = 1
        test(model, test_dataset, Visualizer(test_opt), test_opt, test_bg_info, test_steps=resume_iter)

if __name__ == '__main__':
    main()


import TensorFlow as tf

a = tf.placeholder(tf.float32, [None, 128])

print(a.shape.as_list())

# return a tensor which represents the shape of given tensor
print(tf.shape(a))

# The static shape of a tensor can be set with Tensor.set_shape() method:
a.set_shape([1,128])

print(a.shape)
a.set_shape([None, 128])

# You can reshape a given tensor dynamically using tf.reshape function:
# reshape不能随便改变形状，元素总数不能改变，必须能被行或者列总除
a = tf.reshape(a, [2,64])
print(a.shape)

# 写一个get_shape函数， 获取张量的静态形状，如果没有静态形状则返回静态形状，没有则返回动态
def get_shape(tensor):
    static_shape = tensor.shape.as_list()
    dynamic_shape = tf.unstack(tf.shape(tensor))
    zip_a = zip(static_shape, dynamic_shape)
    for i in zip_a:
        print(i)
    dims = [s[1] if s[0] is None else s[0]
        for s in zip(static_shape, dynamic_shape)
    ]
    return dims

b = tf.placeholder(name="b", shape=[None, 10, 3], dtype=tf.float32)
shape = get_shape(b)
b = tf.reshape(b, shape=[shape[0], shape[1] * shape[2]])
print(b)

if __name__ == "__main__":
    print("-------------------------------------------------")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Aug 22 12:51:23 2021

@author: nat

"""

def oddOcurrence(nums):
   total = 0
   for element in nums:
       total = total ^ element

   return total

print(oddOcurrence([-9, -12, 4, 8, -12,4,2,-12, -9,2,12, 7,8, 7, 12]))


def sum(a, b):
    add = a * b
    return add

# sum(10,20)
result = sum(10, 20)
print(result)

def f1():
    print('none')

# default value for return in python is none
x = f1()
print(x)

def factorial(num):
    res = 1
    while num >= 1:
        res = res * num
        num = num - 1
    return res

print('The factorial of 4 is :: ', factorial(4))

for i in range(1, 12):
   # print('Factorial of the number', i, 'is', factorial(i))
    print('Factorial of the number {} is : {}'.format(i, factorial(i)))


import os

from models.params import COMMON_PARAMS as CP
from models.params import IM_DECODER_PARAMS as IDP
from models.basic_models.linear import DoublingLinearNetwork

import torch as T
import torch.nn as nn
import torch.optim as optim

class ImageDecoderNetwork(nn.Module):
    def __init__(self, input_dim, output_dim=IDP.OUTPUT_DIM, output_im_dims=IDP.OUTPUT_IM_DIMS,
                 alpha=IDP.LEARNING_RATE, in_activation=IDP.IN_ACTIVATION, out_activation=IDP.OUT_ACTIVATION,
                 chkpt_dir=CP.CHECKPOINT_DIR, chkpt_filename=IDP.CHKPT_FILE):
        super(ImageDecoderNetwork, self).__init__()
        self.out_activation = out_activation
        self.output_im_dims = output_im_dims
        self.d_linear = DoublingLinearNetwork(input_dim, output_dim=output_dim, activation=in_activation)

        self.checkpoint_file = os.path.join(chkpt_dir, chkpt_filename)
        self.optimizer = optim.Adam(self.parameters(), lr=alpha)
        self.device = T.device('cuda:0' if T.cuda.is_available() else 'cpu')
        self.to(self.device)

    def forward(self, x):
        x.to(self.device)
        features = self.d_linear(x)
        out = self.out_activation(features)
        return out.view(-1, self.output_im_dims[0], self.output_im_dims[1], self.output_im_dims[2])


#!/usr/bin/python3

from __future__ import annotations

from abc import ABCMeta
from typing import TYPE_CHECKING

from pollinatarr.logger.log import logger
from pollinatarr.torrents.torrent_container import TorrentContainer

if TYPE_CHECKING:
    from pollinatarr.config.config import Config
    from pollinatarr.config.torrent_clients_config import TorrentClientConfig

class FailedToConnect(Exception):
    pass

class AbstractTorrentClient(object, metaclass=ABCMeta):
    def __init__(self, config: TorrentClientConfig, name: str):
        self.name = name
        self.config = config
        self.logger = logger.get_sub("TORRENT CLIENT").get_sub(name)

    def get_torrents_using_config(self, config: Config) -> TorrentContainer:
        torrents = TorrentContainer()
        for _tracker_name, _tracker_config in config.trackers.items():
            categories = _tracker_config.categories or config.categories
            for category in categories:
                self.logger.info(f"Searching torrents that match {category} category and {_tracker_name} tracker")
                _torrents = self.get_torrents_from_tracker(_tracker_name, category)
                self.logger.info(f"Found {len(_torrents)} torrents")
                torrents.merge(_torrents)
        return torrents

    def get_torrents_from_tracker(self, tracker_name: str, category: str) -> TorrentContainer:
        raise NotImplementedError


import keyboard
import time
import serial
import inputs

ser = serial.Serial('COM9', 9800, timeout=1)
steps=0.2
global lastevent
global lastlastevent
lastevent= ["hey",24]
lastlastevent= ["hey",24]
global tooglelumos
tooglelumos=False
while True:
    events = inputs.get_gamepad()

    for event in events:

        if event.code!="ABS_X" and event.code!="SYN_REPORT" and event.code!="ABS_Y" and event.code!="ABS_Z"  and event.code!="ABS_RY" and event.code!="ABS_RX":

            print("log"+str(lastevent))
            #pew-zauber
            if lastevent==["ABS_RZ",255] and event.code=="ABS_RZ" and event.state!=255:

                time.sleep(0.08)
                ser.write(b'P')
                time.sleep(steps)
                print("süden")

            #revelio
            if event.code=="ABS_HAT0X" and event.state ==-1:
                print("revelio")
                ser.write(b'R')
                time.sleep(steps)

            #lumos
            if lastevent==["ABS_RZ",255]:
                if event.code=="BTN_NORTH" and event.state ==1:
                    print("lumos")
                    if tooglelumos==False:
                        print("lumosstart")
                        time.sleep(0.2)
                        ser.write(b'L')
                        tooglelumos=True
                    else:

                        ser.write(b'S')
                        print("lumosstop")
                        tooglelumos=False
                    time.sleep(steps)

            if event.code=="BTN_NORTH" and event.state ==1 and lastevent!=["ABS_RZ",255]:
                print("east")
                ser.write(b'T')
                time.sleep(steps)
            lastevent=[event.code,event.state]
            lastlastevent=lastevent


import logging
import os
import sys

import pandas

from immuno_probs.cdr3.olga_container import OlgaContainer
from immuno_probs.model.default_models import get_default_model_file_paths
from immuno_probs.model.igor_interface import IgorInterface
from immuno_probs.model.igor_loader import IgorLoader
from immuno_probs.util.cli import dynamic_cli_options
from immuno_probs.util.conversion import nucleotides_to_aminoacids
from immuno_probs.util.constant import get_config_data
from immuno_probs.util.io import read_separated_to_dataframe, write_dataframe_to_separated, preprocess_separated_file, copy_to_dir

class GenerateSequences(object):
    """Commandline tool for generating sequences from and IGoR model.

    Parameters
    ----------
    subparsers : argparse.ArgumentParser
        A subparser object for appending the tool's parser and options.

    Methods
    -------
    run(args)
        Uses the given Namespace commandline arguments for generating sequences.

    """
    def __init__(self, subparsers):
        super(GenerateSequences, self).__init__()
        self.logger = logging.getLogger(__name__)
        self.subparsers = subparsers
        self._add_options()

    def _add_options(self):
        """Function for adding the parser and options to the given ArgumentParser.

        Notes
        -----
            Uses the class constructor's subparser object for appending the
            tool's parser and options.

        """
        # Create the description and options for the parser.
        description = "Generate VDJ or VJ sequences given a custom IGoR model (or build-in) by executing IGoR's " \
            "commandline tool via python subprocess. Or generate CDR3 sequences from the model by using OLGA."
        parser_options = {
            '-model': {
                'type': 'str.lower',
                'choices': get_default_model_file_paths(),
                'required': '-custom-model' not in sys.argv,
                'help': "Specify a pre-installed model for generation. (required if -custom-model NOT specified) "
                        "(select one: %(choices)s)."
            },
            '-type': {
                'type': 'str.lower',
                'choices': ['alpha', 'beta', 'light', 'heavy'],
                'required': ('-custom-model' in sys.argv),
                'help': 'The type of the custom model to use. (select one: %(choices)s) (required for -custom-model).'
            },
            '-anchor': {
                'metavar': ('<gene>', '<separated>'),
                'type': 'str',
                'action': 'append',
                'nargs': 2,
                'required': ('-cdr3' in sys.argv and '-custom-model' in sys.argv),
                'help': 'A gene (V or J) followed by a CDR3 anchor separated data file. Note: need to contain gene in the '
                        'first column, anchor index in the second and gene function in the third (required for -cdr3 and '
                        '-custom-model).'
            },
            '-custom-model': {
                'metavar': ('<parameters>', '<marginals>'),
                'type': 'str',
                'nargs': 2,
                'help': 'A IGoR parameters file followed by an IGoR marginals file.'
            },
            '-n-gen': {
                'type': 'int',
                'nargs': '?',
                'help': 'The number of sequences to generate (default: {}).'
                        .format(get_config_data('GENERATE', 'NUM_GENERATE', 'int'))
            },
            '-cdr3': {
                'action': 'store_true',
                'help': 'If specified (True), CDR3 sequences are generated, otherwise V(D)J sequences (default: {}).'
                        .format(get_config_data('GENERATE', 'EVAL_CDR3', 'bool'))
            },
        }

        # Add the options to the parser and return the updated parser.
        parser_tool = self.subparsers.add_parser('generate', help=description, description=description)
        parser_tool = dynamic_cli_options(parser=parser_tool, options=parser_options)

    @staticmethod
    def _process_realizations(data, model, v_gene_choice_col,
                              d_gene_choice_col, j_gene_choice_col):
        """Function for processing an IGoR realization dataframe with indices.

        Parameters
        ----------
        data : pandas.DataFrame
            A pandas dataframe object with the IGoR realization data.
        model : immuno_probs.model.igor_loader.IgorLoader
            Object containing the IGoR model.
        v_gene_choice_col : str
            The name of the V gene choice column to use.
        d_gene_choice_col : str
            The name of the D gene choice column to use.
        j_gene_choice_col : str
            The name of the J gene choice column to use.

        Returns
        -------
        pandas.DataFrame
            A pandas dataframe object with sequence index, the V(D)J gene choice columns containing the names of the
            selected genes.

        """
        # If the suplied model is VDJ, locate important columns and update index values.
        if model.get_type() == "VDJ":
            real_df = pandas.concat([data.filter(regex=("GeneChoice_V_gene_.*")),
                                     data.filter(regex=("GeneChoice_J_gene_.*")),
                                     data.filter(regex=("GeneChoice_D_gene_.*"))],
                                    axis=1, sort=False)
            real_df.columns = [v_gene_choice_col, j_gene_choice_col, d_gene_choice_col]
            real_df[v_gene_choice_col], real_df[j_gene_choice_col], \
                real_df[d_gene_choice_col] = zip(
                    *real_df.apply(lambda row: (
                        model.get_genomic_data().genV[int(row[v_gene_choice_col].strip('()'))][0],
                        model.get_genomic_data().genJ[int(row[j_gene_choice_col].strip('()'))][0],
                        model.get_genomic_data().genD[int(row[d_gene_choice_col].strip('()'))][0]
                    ), axis=1))

        # Or do the same if the model is VJ.
        elif model.get_type() == "VJ":
            real_df = pandas.concat([data.filter(regex=("GeneChoice_V_gene_.*")),
                                     data.filter(regex=("GeneChoice_J_gene_.*"))],
                                    axis=1, sort=False)
            real_df.columns = [v_gene_choice_col, j_gene_choice_col]
            real_df[v_gene_choice_col], real_df[j_gene_choice_col] = zip(
                *real_df.apply(lambda row: (
                    model.get_genomic_data().genV[int(row[v_gene_choice_col].strip('()'))][0],
                    model.get_genomic_data().genJ[int(row[j_gene_choice_col].strip('()'))][0]
                ), axis=1))
        return real_df

    def run(self, args, output_dir):
        """Function to execute the commandline tool.

        Parameters
        ----------
        args : Namespace
            Object containing our parsed commandline arguments.
        output_dir : str
            A directory path for writing output files to.

        """
        eval_cdr3 = get_config_data('GENERATE', 'EVAL_CDR3', 'bool')
        if args.cdr3:
            eval_cdr3 = args.cdr3

        # If the given type of sequences generation is not CDR3, use IGoR.
        if not eval_cdr3:

            # Add general igor commands.
            self.logger.info('Setting up initial IGoR command (1/3)')
            command_list = []
            working_dir = get_config_data('COMMON', 'WORKING_DIR')
            command_list.append(['set_wd', working_dir])
            command_list.append(['threads', str(get_config_data('COMMON', 'NUM_THREADS', 'int'))])

            # Add the model (build-in or custom) command.
            self.logger.info('Processing IGoR model files (2/3)')
            try:
                if args.model:
                    files = get_default_model_file_paths(name=args.model)
                    command_list.append([
                        'set_custom_model',
                        files['parameters'],
                        files['marginals']
                    ])
                elif args.custom_model:
                    command_list.append([
                        'set_custom_model',
                        copy_to_dir(working_dir, str(args.custom_model[0]), 'txt'),
                        copy_to_dir(working_dir, str(args.custom_model[1]), 'txt')
                    ])
            except IOError as err:
                self.logger.error(str(err))
                return

            # Add generate command.
            self.logger.info('Adding additional variables to IGoR command (3/3)')
            if args.n_gen:
                command_list.append(['generate', str(args.n_gen), ['noerr']])
            else:
                command_list.append(['generate', str(get_config_data('GENERATE', 'NUM_GENERATE', 'int')), ['noerr']])

            # Execute IGoR through command line and catch error code.
            self.logger.info('Executing IGoR (this might take a while)')
            try:
                igor_cline = IgorInterface(command=command_list)
                exit_code, _, stderr, _ = igor_cline.call()
                if exit_code != 0:
                    self.logger.error(
                        "An error occurred during execution of IGoR command (exit code %s):\n%s",
                        exit_code, stderr
                    )
                    return
            except OSError as err:
                self.logger.error(str(err))
                return

            # Merge the generated output files together (translated).
            self.logger.info('Processing sequence realizations')
            try:
                seqs_df = read_separated_to_dataframe(
                    file=os.path.join(working_dir, 'generated', 'generated_seqs_noerr.csv'),
                    separator=';',
                    index_col='seq_index',
                    cols=['nt_sequence'])
                seqs_df.index.names = [get_config_data('COMMON', 'I_COL')]
                seqs_df.columns = [get_config_data('COMMON', 'NT_COL')]
                seqs_df[get_config_data('COMMON', 'AA_COL')] = \
                    seqs_df[get_config_data('COMMON', 'NT_COL')].apply(nucleotides_to_aminoacids)
                real_df = read_separated_to_dataframe(
                    file=os.path.join(working_dir, 'generated', 'generated_realizations_noerr.csv'),
                    separator=';',
                    index_col='seq_index')
                real_df.index.names = [get_config_data('COMMON', 'I_COL')]
                if args.model:
                    files = get_default_model_file_paths(name=args.model)
                    model_type = files['type']
                    model = IgorLoader(model_type=model_type,
                                       model_params=files['parameters'],
                                       model_marginals=files['marginals'])
                elif args.custom_model:
                    model_type = args.type
                    model = IgorLoader(model_type=model_type,
                                       model_params=args.custom_model[0],
                                       model_marginals=args.custom_model[1])
                real_df = self._process_realizations(
                    data=real_df,
                    model=model,
                    v_gene_choice_col=get_config_data('COMMON', 'V_GENE_CHOICE_COL'),
                    d_gene_choice_col=get_config_data('COMMON', 'D_GENE_CHOICE_COL'),
                    j_gene_choice_col=get_config_data('COMMON', 'J_GENE_CHOICE_COL'))
                full_seqs_df = seqs_df.merge(real_df, left_index=True, right_index=True)
            except (IOError, KeyError, ValueError) as err:
                self.logger.error(str(err))
                return

            # Write the pandas dataframe to a separated file.
            try:
                self.logger.info('Writing generated sequences to file system')
                output_filename = get_config_data('COMMON', 'OUT_NAME')
                if not output_filename:
                    output_filename = 'generated_seqs_{}'.format(model_type)
                _, filename = write_dataframe_to_separated(
                    dataframe=full_seqs_df,
                    filename=output_filename,
                    directory=output_dir,
                    separator=get_config_data('COMMON', 'SEPARATOR'),
                    index_name=get_config_data('COMMON', 'I_COL'))
                self.logger.info("Written '%s'", filename)
            except IOError as err:
                self.logger.error(str(err))
                return

        # If the given type of sequences generation is CDR3, use OLGA.
        elif eval_cdr3:

            # Get the working directory.
            working_dir = get_config_data('COMMON', 'WORKING_DIR')

            # Load the model, create the sequence generator and generate the sequences.
            self.logger.info('Loading the IGoR model files')
            try:
                if args.model:
                    files = get_default_model_file_paths(name=args.model)
                    model_type = files['type']
                    model = IgorLoader(model_type=model_type,
                                       model_params=files['parameters'],
                                       model_marginals=files['marginals'])
                    args.anchor = [['V', files['v_anchors']],
                                   ['J', files['j_anchors']]]
                    separator = '\t'
                elif args.custom_model:
                    model_type = args.type
                    model = IgorLoader(model_type=model_type,
                                       model_params=args.custom_model[0],
                                       model_marginals=args.custom_model[1])
                    separator = get_config_data('COMMON', 'SEPARATOR')
                for gene in args.anchor:
                    anchor_file = preprocess_separated_file(
                        os.path.join(working_dir, 'cdr3_anchors'),
                        str(gene[1]),
                        separator,
                        ','
                    )
                    model.set_anchor(gene=gene[0], file=anchor_file)
                model.initialize_model()
            except (TypeError, OSError, IOError, KeyError, ValueError) as err:
                self.logger.error(str(err))
                return

            # Setup the sequence generator and generate sequences.
            self.logger.info('Generating sequences')
            try:
                seq_generator = OlgaContainer(
                    igor_model=model,
                    nt_col=get_config_data('COMMON', 'NT_COL'),
                    nt_p_col=get_config_data('COMMON', 'NT_P_COL'),
                    aa_col=get_config_data('COMMON', 'AA_COL'),
                    aa_p_col=get_config_data('COMMON', 'AA_P_COL'),
                    v_gene_choice_col=get_config_data('COMMON', 'V_GENE_CHOICE_COL'),
                    j_gene_choice_col=get_config_data('COMMON', 'J_GENE_CHOICE_COL'))
                n_generate = get_config_data('GENERATE', 'NUM_GENERATE', 'int')
                if args.n_gen:
                    n_generate = args.n_gen
                if n_generate > 0:
                    cdr3_seqs_df = seq_generator.generate(num_seqs=n_generate)
                else:
                    self.logger.error(
                        'Number of sequences to generate should be higher 0')
                    return
            except (TypeError, IOError) as err:
                self.logger.error(str(err))
                return

            # Write the pandas dataframe to a separated file with.
            try:
                self.logger.info('Writing generated sequences to file system')
                output_filename = get_config_data('COMMON', 'OUT_NAME')
                if not output_filename:
                    output_filename = 'generated_seqs_{}_CDR3'.format(model_type)
                _, filename = write_dataframe_to_separated(
                    dataframe=cdr3_seqs_df,
                    filename=output_filename,
                    directory=output_dir,
                    separator=get_config_data('COMMON', 'SEPARATOR'),
                    index_name=get_config_data('COMMON', 'I_COL'))
                self.logger.info("Written '%s'", filename)
            except IOError as err:
                self.logger.error(str(err))
                return

def main():
    """Function to be called when file executed via terminal."""
    print(__doc__)

if __name__ == "__main__":
    main()


"""
# Definition for a Node.
class Node:
    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
        self.val = int(x)
        self.next = next
        self.random = random
"""
# Initial thoughts
    # Can just iterate through the linked list to make copies of the values
    # Can't do a single iteration to make the random variable because that node
        # may not exist yet
    # Can't iterate twice because the next/random pointers may be behind the current node
    # Therefore, probably want to use some type of hash to store nodes so that you
        # can instantly find the linked one when populating the copy
# Algorithm
    # Iterate through the linked list and create nodes containing the same value for each pointer
    # Iterate through the list again
        # Set the mapped node's next value to the map of the old.next value
        # Set the mapped node's random value to the map of the old.random value
    # Need to include {None: None} in the hash for nodes with null pointers
class Solution:
    def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
        old_nodes = {None: None}

        cur = head
        while cur:
            copy = Node(cur.val)
            old_nodes[cur] = copy
            cur = cur.next

        cur = head
        while cur:
            copy = old_nodes[cur]
            copy.next = old_nodes[cur.next]
            copy.random = old_nodes[cur.random]
            cur = cur.next

        return old_nodes[head]


from generic import Editable
from generic.collection import Collection2d
from util import BinaryIO

class MapMatrix(Editable):
    def define(self):
        self.uint8('width')
        self.uint8('height')
        self.uint8('has_map_definition_ids')
        self.uint8('has_mystery_zone')
        self.uint8('namelen')
        self.name = ''  # pascal string

    def reshape(self, width, height, copy=True):
        """Reshape the world to a new width/height

        Parameters
        ----------
        width : int
            New width
        height : int
            New height
        copy : Bool
            If true, copy the existing data in
        """
        self.width = width
        self.height = height
        if self.has_map_definition_ids:
            old_collection = self.map_definitions
            self.map_definitions = Collection2d(self.uint16, self.width,
                                                self.height)
            if copy:
                for x in range(self.width):
                    for y in range(self.height):
                        try:
                            self.map_definitions[x, y] = old_collection[x, y]
                        except:
                            break
        if self.has_mystery_zone:
            old_collection = self.mystery_details
            self.mystery_details = Collection2d(self.uint8, self.width,
                                                self.height)
            if copy:
                for x in range(self.width):
                    for y in range(self.height):
                        try:
                            self.mystery_details[x, y] = old_collection[x, y]
                        except:
                            break
        old_collection = self.land_data_maps
        self.land_data_maps = Collection2d(self.uint16, self.width,
                                           self.height)
        if copy:
            for x in range(self.width):
                for y in range(self.height):
                    try:
                        self.land_data_maps[x, y] = old_collection[x, y]
                    except:
                        break

    def load(self, reader):
        reader = BinaryIO.reader(reader)
        Editable.load(self, reader)
        self.name = reader.read(self.namelen)
        """land_data_block = Editable()
        land_data_block.array('entries', land_data_block.uint16,
                              length=self.width*self.height)
        land_data_block.freeze()
        self.land_data_maps = land_data_block.load(reader)
        print(len(reader.read()))"""
        with self.simulate():

            if self.has_map_definition_ids:
                self.map_definitions = Collection2d(self.uint16, self.width,
                                                    self.height)
                self.map_definitions.load(reader)
            else:
                self.map_definitions = None

            if self.has_mystery_zone:
                self.mystery_details = Collection2d(self.uint8, self.width,
                                                    self.height)
                self.mystery_details.load(reader)
            else:
                self.mystery_details = None
            self.land_data_maps = Collection2d(self.uint16,
                                               self.width, self.height)
            self.land_data_maps.load(reader)

    def save(self, writer=None):
        self.namelen = len(self.name)
        writer = Editable.save(self, writer)
        writer.write(self.name)
        if self.has_map_definition_ids:
            writer = self.map_definitions.save(writer)
        if self.has_mystery_zone:
            writer = self.mystery_details.save(writer)
        writer = self.land_data_maps.save(writer)
        return writer
World = MapMatrix


#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
# =============================================================================
#      FileName: trace.py
#        Author: Chu Yanshuo
#         Email: chu@yanshuo.name
#      HomePage: http://yanshuo.name
#       Version: 0.0.1
#    LastChange: 2017-04-07 09:57:40
#       History:
# =============================================================================
'''
import bz2
import csv
import os

class TraceDB(object):

    def __init__(self, out_dir, mutations):
        if os.path.exists(out_dir):
            raise Exception("{0} exists, cannot overwrite.".format(out_dir))

        if not os.path.exists(os.path.dirname(os.path.abspath(out_dir))):
            raise Exception(
                "Folder {0} does not exist to create pyclone file in.".format(
                    os.path.dirname(out_dir)))

        os.makedirs(out_dir)
        self._open_files(out_dir)
        self._frequencies_writer.writerow(mutations)
        self._labels_writer.writerow(mutations)

    def _open_files(self, out_dir):
        '''
        Load the shelve db object if it exists, otherwise initialise.
        '''
        mode = 'w'
        self._alpha_file = bz2.BZ2File(
            os.path.join(out_dir, 'alpha.tsv.bz2'), mode)
        self._frequencies_file = bz2.BZ2File(os.path.join(
            out_dir, 'cellular_frequencies.tsv.bz2'), mode)
        self._labels_file = bz2.BZ2File(
            os.path.join(out_dir, 'labels.tsv.bz2'), mode)
        self._phi_file = bz2.BZ2File(os.path.join(out_dir, 'phi.tsv.bz2'), mode)
        self._alpha_writer = csv.writer(self._alpha_file, delimiter='\t')
        self._frequencies_writer = csv.writer(
            self._frequencies_file, delimiter='\t')
        self._labels_writer = csv.writer(self._labels_file, delimiter='\t')
        self._phi_writer = csv.writer(self._phi_file, delimiter='\t')

    def update_trace(self, state):
        self._alpha_writer.writerow([state['alpha'], ])
        self._frequencies_writer.writerow(state['cellular_frequencies'])
        self._labels_writer.writerow(state['labels'])
        self._phi_writer.writerow(state['phi'])

    def close(self):
        self._alpha_file.close()
        self._frequencies_file.close()
        self._labels_file.close()
        self._phi_file.close()


from pathlib import Path

from antarest.study.storage.rawstudy.io.reader import MultipleSameKeysIniReader
from antarest.study.storage.rawstudy.io.writer.ini_writer import IniWriter
from antarest.study.storage.rawstudy.model.filesystem.root.settings.generaldata import DUPLICATE_KEYS

GENERAL_DATA_PATH = "settings/generaldata.ini"

def upgrade_800(study_path: Path) -> None:
    """
    Upgrade the study configuration to version 800.

    NOTE:
        The file `study.antares` is not upgraded here.

    Args:
        study_path: path to the study directory.
    """

    reader = MultipleSameKeysIniReader(DUPLICATE_KEYS)
    data = reader.read(study_path / GENERAL_DATA_PATH)
    data["other preferences"]["hydro-heuristic-policy"] = "accommodate rule curves"
    data["optimization"]["include-exportstructure"] = False
    data["optimization"]["include-unfeasible-problem-behavior"] = "error-verbose"
    data["general"]["custom-scenario"] = data["general"]["custom-ts-numbers"]
    del data["general"]["custom-ts-numbers"]
    writer = IniWriter(special_keys=DUPLICATE_KEYS)
    writer.write(data, study_path / GENERAL_DATA_PATH)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('store', '0001_initial'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='category',
            options={'verbose_name_plural': 'Categories'},
        ),
        migrations.RemoveField(
            model_name='review',
            name='title',
        ),
    ]


#!/usr/bin/env python

# This script keeps track of active keyboard layouts per window.
#
# This script requires i3ipc-python package (install it from a system package
# manager or pip).

import i3ipc

ipc = i3ipc.Connection()
prev_focused = -1
windows = {}

def on_window_focus(ipc, event):
    global windows, prev_focused

    # Save current layout
    layouts = {}
    for input in ipc.get_inputs():
        layouts[input.identifier] = input.xkb_active_layout_index
    windows[prev_focused] = layouts

    # Restore layout of the newly focused window
    if event.container.id in windows:
        for (input_id, layout_index) in windows[event.container.id].items():
            if layout_index != layouts[input_id]:
                ipc.command("input \"{}\" xkb_switch_layout {}".format(
                    input_id, layout_index))

    prev_focused = event.container.id

def on_window_close(ipc, event):
    global windows
    if event.container.id in windows:
        del(windows[event.container.id])

def on_window(ipc, event):
    if event.change == "focus":
        on_window_focus(ipc, event)
    elif event.change == "close":
        on_window_close(ipc, event)

ipc.on("window", on_window)
ipc.main()


#KMP
'''求解next数组，假设字符串为i个元素
比较字符串0到i-1的串的前缀数组和后缀数据的相同项
1、i=0时，next[i]=0
2、i=1时，next[i]=1
3、i>=2，且2到i-1的串的前缀数组和后缀数据存在相同项，next[i]=max(相同字符长度)
4、其他，next[i]=1
'''
def next_list(str2):
    next_list , ys= [],[]
    for i in range(0,len(str2)):
        #print('--->',str2[0:i])
        if i == 0:
            next_list.append(0)
        elif i == 1:
            next_list.append(1)
        else:
            for j in range(0,i-1):
                str_prefix = str2[0:i][:j+1]  #前缀，B+S
                str_suffix = str2[0:i][-j-1:] #后缀，S+B
                #print(str_prefix,str_suffix)
                if str_suffix == str_prefix:
                    ys.append(len(str_prefix)+1)
                else:
                    ys.append(1)
                #print(ys)
            next_list.append(max(ys))
            ys.clear()
    return next_list

'''借用前一个字符的判断结果，计算当前字符对应的 next 值
'''
def next_list_1(str2):
    next_list = []
    i = 1
    j = 0
    next_list.append(0)
    while i < len(str2):
        if j == 0 or (str2[i-1] == str2[j-1]):
            i = i + 1
            j = j + 1
            next_list.append(j)
        else:
            j = next_list[j-1]
    return next_list

def nextval(str2):
    nextval_list = []
    i = 1
    j = 0
    nextval_list.append(0)
    while i < len(str2):
        if j == 0 or (str2[i-1] == str2[j-1]):
            i = i + 1
            j = j + 1
            if str2[i-1] != str2[j-1]:
                nextval_list.append(j)   #不相等，则将j值赋予nextval,等同于nextval[j]=next[j]
            else:
                nextval_list.append(nextval_list[j-1])  #相等，则将前一个nextval值赋予当次的nextval。等同于nextval[j] = nextval[next[j]-1]
        else:
            j = nextval_list[j-1]
    return nextval_list

def KMP_matching(str1,str2,pos):
    n = len(str1)
    m = len(str2)
    i = pos
    j = 0  #从0位开始标记
    next = nextval(str2)
    while  i < n and j < m:
        if j == -1 or str1[i] == str2[j]:
            i = i + 1
            j = j + 1
        elif str1[i] != str2[j]:
            if j == 0:  #在字符匹配不相等的情况下，子串如果回到了首位，则表示重新开始匹配，需要主串移动一位
                j = 0
                i = i+1
            else:
                j = next[j-1]
    if j > m - 1 :
        return i - m
    else:
        return 'None'

str1=input('给出str1:')
str2=input('给出str2:')
pos=int(input('给出pos值:'))
print(KMP_matching(str1,str2,pos))


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pandas_datareader as data
import streamlit as st

st.title('Stock Trend Prediction')

start = '2010-01-01'
end = '2019-12-31'

user_input = st.text_input('Enter Stock Ticker', 'AAPL')
df = data.DataReader(user_input, 'yahoo', start, end)

st.subheader('Data from 2010-2019')
st.write(df.describe())

st.subheader('Closing Price vs Time chart')
fig = plt.figure(figsize = (12,6))
plt.plot(df.Close)
st.pyplot(fig)

st.subheader('Closing Price vs Time chart 100MA')
ma100 = df.Close.rolling(100).mean()
fig = plt.figure(figsize = (12,6))
plt.plot(df.Close)
plt.plot(ma100,'r')
st.pyplot(fig)

st.subheader('Closing Price vs Time chart with 100MA & 200MA')
ma200 = df.Close.rolling(200).mean()
fig = plt.figure(figsize = (12,6))
plt.plot(df.Close)
plt.plot(ma100,'r')
plt.plot(ma200,'g')
st.pyplot(fig)


from .base import *

SECRET_KEY = 'z9)h7_)&#t-17uql1*1kst%95%9jj5gj7$@15vljg4xq@u2o@@'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

DEBUG = os.environ.get("DEBUG", True)

STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'), )
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
SYSTEM_EMAIL = 'yourname@example.com'


# Resolve.py
"""
We consider a normal order ramified on snc but no secondary ramification. We
blow up repeatedly at nodes recording the log discrepancy and
b-discrepancy until we have all possible negative discrepancy curves.

The exceptional curves should probably be indexed by dyadic fractions, written
as binary numbers, but we will instead clear denominators and work with
integers.
"""

from fractions import Fraction

# Enter initial ramification data.
# The ramification cover of the curve i is gi copies of zi modulo n
initial_ram_data = input("Please enter the ramification data tuple n,z1,z2,g1,g2\n")
n_str, z1_str, z2_str, g1_str, g2_str = initial_ram_data.split(',')
n = int(n_str.strip())
z1 = int(z1_str.strip())
z2 = int(z2_str.strip())
g1 = int(g1_str.strip())
g2 = int(g2_str.strip())

#This function computes the order of an element in a cyclic group.
def order(num,modulus):
    ord = 1
    while ord*num %modulus !=0:
        ord +=1
    return ord

print("Corresponding maximal order has ram data", end=':')
print(z1 % n, z2 % n, ' modulo ', n, end='')
f1 = order(z1,n) # these are ramification indices of max order
f2 = order(z2,n)
print(' giving ramification indices ', f1, f2,'.')
# Check working by showing ramification of containing maximal order

"""
This is the function that computes log and b-discrepancies of
all exceptional curves in a good log resolution. Here the good log
resolution is one chosen so all negative discrepancy curves are
guaranteed to be found there. The data will be recorded in a dictionary.
"""
def resolve(n,z1,z2,g1,g2):

    no_blowups = max(g1,g2)*n -1
    # crude bound on number of blowups to ensure good log resolution
    print(f'We need to blowup set of nodes  at most {no_blowups} times.')
    no_curves = 2**no_blowups # number of exc curves actually 2**no_blowups -1
    curves = {0:[Fraction(1,f1*g1)-1,z1] , no_curves:[Fraction(1,f2*g2)-1,z2]}
    # Create dictionary of curve data. Keys are 0 up to no_curves.
    # Current values are lists of [log discrepancy, ram of max order]
    step = no_curves # Final indices for strict transforms of initial ram
                     # curves are `step' apart

    for i in range(1,no_blowups+1):

        print(f'This is the {i}-th blowup. New curves have  log and b- discrepancy and ramification:')
        step = int(step/2) # indices of i-th blowup curves have indices 'step' apart
        l = len(curves)-1 # the number of new exceptional curves
        is_good_res = True
        # We'll use this to test if the i-th blowup gives a good resolution

        for j in range(l):
            log_disc = 1 + curves[2*j*step][0] + curves[(2*j+2)*step][0]
            #  Give log discrepancy of j-th new exceptional in i-th blowup
            is_good_res =  is_good_res and (log_disc >=0)
            ram = (curves[2*j*step][1] + curves[(2*j+2)*step][1])%n
            # Gives ramification along j-th new exceptional in i-th blowup
            b_disc = log_disc + 1-Fraction(1,order(ram,n))
            # Compute the b-discrepancy
            curves[(2*j +1)*step] = [log_disc, ram, b_disc]
            # Update curves dictionary with entry for j-th curve in i-th blowup
            print(log_disc,b_disc, ram, end=';')

        if is_good_res:
            break
        else:
            print(' DONE', end='\n\n')

    print('\n\n Good log resolution has been achieved.')

resolve(n,z1,z2,g1,g2)


import discord

import klutzbot.command_defs.message

class Command(klutzbot.command_defs.message.Message):
    """
    Representation of one command and all its useful properties
    """

    start = "!"

    def __init__(self, message: discord.Message, client: discord.Client):
        super().__init__(message, client)
        # Strip out the start command indicator
        message_split = message.content[len(self.start):].split(" ")
        self.command = message_split[0].lower()
        if len(message_split) > 0:
            self.args = message_split[1:]
        else:
            self.args = []
        self.num_args = len(self.args)

async def say(cmd: Command):
    help_str=f"Need exactly two arguments: {Command.start}{cmd.command} <id of channel to send message to> <message>"
    if cmd.num_args >= 2:
        target_channel = cmd.client.get_channel(int(cmd.args[0]))
        host_message = ' '.join(cmd.args[1:])
        await target_channel.send(host_message)
    else:
        await cmd.channel.send(help_str)

async def reply(cmd: Command):
    help_str=f"Need exactly three arguments: {Command.start}{cmd.command} <id of channel to send message to> <id of message to reply to> <message>"
    if cmd.num_args >= 3:
        target_channel = cmd.client.get_channel(int(cmd.args[0]))
        target_message = await target_channel.fetch_message(int(cmd.args[1]))
        host_message = ' '.join(cmd.args[2:])
        await target_message.channel.send(host_message, reference=target_message)
    else:
        await cmd.channel.send(help_str)

async def react(cmd: Command):
    help_str=f"Need exactly three arguments: {Command.start}{cmd.command} <id of channel to send message to> <id of message to react to> <message>"
    if cmd.num_args == 3:
        target_channel = cmd.client.get_channel(int(cmd.args[0]))
        target_message = await target_channel.fetch_message(int(cmd.args[1]))
        host_react = cmd.args[2]
        await target_message.add_reaction(host_react)
    else:
        await cmd.channel.send(help_str)


from itertools import (
    chain,
    product,
    permutations,
    repeat,
)
from functools import (
    reduce,
)
from operator import add

import blinker

from .replication_manager import GameObject
from .tools import dict_merge
from .bind_widget import bind_widget

summon_event = blinker.signal("summon")
revoke = blinker.signal("revoke")

def sum_iterables(iter1, iter2):
    # # print(iter1, iter2)
    return [add(*x) for x in zip(iter1, iter2)]

class Cell:

    # hooks = ['take', 'place']
    hooks = []

    def __init__(self, pos, grid=None, terrain=None):
        # super().__init__(id_=id_)
        self.grid = grid
        self.pos = pos
        self.adjacent = []
        self.additional_content = []
        self.object = None
        self.terrain = terrain or None

    def place(self, obj):
        self.object = obj
        # self.terrain = None

    def take(self, _=None):
        self.object = None

    def __repr__(self):
        return "{} at {}".format(self.__class__.__name__, self.pos)

class Grid(GameObject):

    hooks = []
    cell = Cell
    load_priority = 1

    def __init__(self, size=None, id_=None):
        super().__init__(id_)
        self.size = size
        self._grid = None
        self._changed_terrains = []
        if size is not None:
            self.create_cells()
        summon_event.connect(self.summon)
        revoke.connect(self.revoke)

    def change_terrain(self):
        pass

    def summon(self, _, unit, cell):
        # unit = unit(owner)
        unit.place_in(cell)
        # print(unit)

    def revoke(self, _, unit=None, cell=None):
        cell.take()
        unit.cell = None

    def create_cells(self):
        pass

    def get_ring(self, pos_or_cell, r):
        pass

    def get_area(self, pos_or_cell, r):
        pass

    def find_path(self, from_pos_or_cell, to_pos_or_cell):
        pass

    def make_cell(self, *args, **kwargs):
        return self.cell(*args, grid=self, **kwargs)

    def __getitem__(self, item):
        pass

    def load(self, struct):
        if self._grid is None:
            self.size = struct['size']
            self.create_cells()

    def dump(self):
        # return {
        #     **super().dump(),
        #     'size': self.size,
        # }
        return dict_merge(
            super().dump(),
            {'size': self.size}
        )

    @classmethod
    def locate(cls):
        return super().locate()[-1]

class RectCell(Cell):
    pass

class RectGrid(Grid):

    cell = RectCell

    def __init__(self, size=None, id_=None):
        super().__init__(id_)
        self.size = size
        self._grid = None
        if size is not None:
            self.create_cells()

    def create_cells(self):
        w, h = self.size
        self._grid = [[self.make_cell((i, j)) for j in range(h)] for i in range(w)]
        for i, j in product(range(w), range(h)):
            cur_cell = self._grid[i][j]
            if i > 0:
                cur_cell.adjacent.append(self._grid[i-1][j])
            if i < w - 1:
                cur_cell.adjacent.append(self._grid[i+1][j])
            if j > 0:
                cur_cell.adjacent.append(self._grid[i][j-1])
            if j < h - 1:
                cur_cell.adjacent.append(self._grid[i][j+1])

    def __getitem__(self, item):
        return self._grid[item[0]][item[1]]

    def __iter__(self):
        return iter(chain(*self._grid))

@bind_widget('HexCellWidget')
class HexCell(Cell):
    pass

@bind_widget('Hexgrid')
class HexGrid(Grid):

    cell = HexCell

    def create_cells(self):
        w, h = self.size
        self._grid = [[self.make_cell((i, j)) for j in range(h)] for i in range(w)]
        for cell in self:
            coord = self.offsets_to_cube(cell.pos)
            for d in permutations([1, 0, -1]):
                adj_cell = self[sum_iterables(coord, d)]
                if adj_cell is not None:
                    cell.adjacent.append(adj_cell)

    @staticmethod
    def cube_to_offsets(pos):
        x, y, z = pos
        col = x
        row = z + (x + (x & 1)) // 2
        return col, row

    @staticmethod
    def offsets_to_cube(pos):
        col, row = pos
        x = col
        z = row - (col + (col & 1)) // 2
        y = -x - z
        return x, y, z

    def distance(self, cell_a, cell_b):
        pos_a = self.offsets_to_cube(cell_a.pos)
        pos_b = self.offsets_to_cube(cell_b.pos)
        return max((abs(a - b) for a, b in zip(pos_a, pos_b)))

    @staticmethod
    def inter(a, b, t):
        return a + (b - a)*t

    def cube_inter(self, pos_a, pos_b, t):
        # # print("CUBINTER")
        # # print(pos_a, pos_b)
        return tuple((self.inter(*args) for args in zip(pos_a, pos_b, repeat(t, 3))))

    @staticmethod
    def round_cube(pos):
        # x, y, z = pos
        rx, ry, rz = rpos = tuple(int(p) for p in pos)
        dx, dy, dz = (abs(p - rp) for p, rp in zip(pos, rpos))
        if dx > dy and dx > dz:
            rx = -ry - rz
        elif dy > dz:
            ry = -rx - rz
        else:
            rz = -rx - ry
        return int(rx), int(ry), int(rz)

    def get_line(self, source_cell, target_cell, length=None):
        # TODO правильно продлевать длину линий
        distance = self.distance(source_cell, target_cell)
        if distance == 0:
            return [source_cell]
        step = 1 / distance
        length = length or distance
        result = []
        s_cube_pos = self.offsets_to_cube(source_cell.pos)
        t_cube_pos = self.offsets_to_cube(target_cell.pos)
        for i in range(length+1):
            col, row = self.cube_to_offsets(self.round_cube(self.cube_inter(s_cube_pos, t_cube_pos, step*i)))
            width, height = self.size
            if col < width and col >= 0 and row < height and row >= 0:
                result.append(self[(col, row)])
            else:
                break
        return result

    def _get_generations(self, pos_or_cell, r):
        if not isinstance(pos_or_cell, Cell):
            cell = self[pos_or_cell]
        else:
            cell = pos_or_cell

        generations = [{cell}]
        for i in range(r):
            generations.append(
                reduce(lambda prev, x: prev | set(x.adjacent), generations[-1], set())
            )
        return generations

    def get_area(self, pos_or_cell, r):
        generations = self._get_generations(pos_or_cell, r)
        return reduce(lambda prev, x: prev | x, generations, set())

    def get_ring(self, pos_or_cell, r, inner_r=None):
        inner_r = inner_r or (r - 1)
        generations = self._get_generations(pos_or_cell, r)
        return generations[-1] - (reduce(lambda prev, x: prev | x, generations[:inner_r:], set()))

    def __getitem__(self, item):
        if len(item) == 3:
            return self[self.cube_to_offsets(item)]
        else:
            q, r = item
            w, h = self.size
            # # print(q, r)
            if 0 <= q < w and 0 <= r < h:
                return self._grid[q][r]
            else:
                return None

    def find_path(self, from_pos_or_cell, to_pos_or_cell):

        if isinstance(from_pos_or_cell, tuple):
            fcell = self[from_pos_or_cell]
        else:
            fcell = from_pos_or_cell

        if isinstance(to_pos_or_cell, tuple):
            tcell = self[to_pos_or_cell]
        else:
            tcell = to_pos_or_cell

        return self._find_path(fcell, tcell)

    def _find_path(self, fcell, tcell):
        paths = [[fcell]]
        already = set()
        while True:
            new_paths = []
            for path in paths:
                last_cell = path[-1]
                for cell in (cell for cell in last_cell.adjacent if cell not in already):
                    already.add(cell)
                    if cell is tcell:
                        return path + [cell]
                    else:
                        new_paths.append(path + [cell])
            if new_paths:
                paths = new_paths
            else:
                return []

    def __iter__(self):
        return iter(chain(*self._grid))

def cell_constructor(loader, node):
    coord = tuple(loader.construct_sequence(node))
    hexgrid = HexGrid.locate()
    return hexgrid[coord]

CELL_TAG = "!cell"

if __name__ == '__main__':
    grid = HexGrid((10, 10))
    # print(grid.get_area((4, 4), 2))


names = ['russel' , 'arish', 'momo', 'nazrul']
heroes = ['spiderman', 'superman', 'deadpool', 'batman']
universes = ['marvel', 'dc', 'marvel', 'dc']

zipped = list(zip(names, heroes))

print(zipped)

unzipped = list( zip(*zipped))

print(unzipped)

items = ['apple', 'banana', 'orange']
counts = [3, 12, 6]
prices = [.99, .25, .50]

sentences = []
for (item, count, price) in zip(items, counts, prices):
    item, count, price = str(item), str(count), str(price)
    sentence = 'I bought ' + count + ' ' + item + 's at $' + price + ' .'
    sentences.append(sentence)

print(sentences)


# Randomly fills a grid of size 10 x 10 with digits between 0
# and bound - 1, with bound provided by the user.
# Given a point P of coordinates (x, y) and an integer "target"
# also all provided by the user, finds a path starting from P,
# moving either horizontally or vertically, in either direction,
# so that the numbers in the visited cells add up to "target".
# The grid is explored in a depth-first manner, first trying to move north,
# always trying to keep the current direction,
# and if that does not work turning in a clockwise manner.
#
# Written by Eric Martin for COMP9021

import sys
from random import seed, randrange

from stack_adt import *

def display_grid():
    for i in range(len(grid)):
        print('   ', ' '.join(str(grid[i][j]) for j in range(len(grid[0]))))

def explore_depth_first(x, y, target):
    #path = None
    check_point = False
    if grid[x][y] > target:
        return
    else:
        path = Stack()
        path.push((x,y))
        sum_path = grid[x][y]
        #change_point = y
        #unchange_point = x
        while 1:
            if sum_path == target:
                return path._data
                break
            change_point = path._data[-1][0]
            unchange_point = path._data[-1][1]
            if change_point > 0:
                i = change_point
                while i > 0:
                    i -= 1
                    if (i,unchange_point) in path._data:
                        break
                    elif sum_path + grid[i][unchange_point] < target:
                        sum_path = sum_path + grid[i][unchange_point]
                        path.push((i,unchange_point))
                    elif sum_path + grid[i][unchange_point] > target:
                        break
                    elif sum_path + grid[i][unchange_point] == target:
                        path.push((i,unchange_point))
                        return path._data

            change_point = path._data[-1][1]
            unchange_point = path._data[-1][0]
            if change_point < 9:
                i = change_point
                while i < 9:
                    i += 1
                    if (unchange_point,i) in path._data:
                        break
                    elif sum_path + grid[unchange_point][i] < target:
                        sum_path = sum_path + grid[unchange_point][i]
                        path.push((unchange_point,i))
                    elif sum_path + grid[unchange_point][i] > target:
                        break
                    elif sum_path + grid[unchange_point][i] == target:
                        path.push((unchange_point,i))
                        return path._data

            change_point = path._data[-1][0]
            unchange_point = path._data[-1][1]
            if change_point < 9:
                i = change_point
                while i < 9:
                    i += 1
                    if (i,unchange_point) in path._data:
                        break
                    elif sum_path + grid[i][unchange_point] < target:
                        sum_path = sum_path + grid[i][unchange_point]
                        path.push((i,unchange_point))
                    elif sum_path + grid[i][unchange_point] > target:
                        break
                    elif sum_path + grid[i][unchange_point] == target:
                        path.push((i,unchange_point))
                        return path._data

            change_point = path._data[-1][1]
            unchange_point = path._data[-1][0]
            if change_point > 0:
                i = change_point
                while i > 0:
                    i -= 1
                    if (unchange_point,i) in path._data:
                        break
                    elif sum_path + grid[unchange_point][i] < target:
                        sum_path = sum_path + grid[unchange_point][i]
                        path.push((unchange_point,i))
                    elif sum_path + grid[unchange_point][i] > target:
                        break
                    elif sum_path + grid[unchange_point][i] == target:
                        path.push((unchange_point,i))
                        return path._data

    pass

try:
    for_seed, bound, x, y, target = [int(x) for x in input('Enter five integers: ').split()]
    if bound < 1 or x not in range(10) or y not in range(10) or target < 0:
        raise ValueError
except ValueError:
    print('Incorrect input, giving up.')
    sys.exit()
seed(for_seed)
grid = [[randrange(bound) for _ in range(10)] for _ in range(10)]
print('Here is the grid that has been generated:')
display_grid()
path = explore_depth_first(x, y, target)
if not path:
    print(f'There is no way to get a sum of {target} starting from ({x}, {y})')
else:
    print('With North as initial direction, and exploring the space clockwise,')
    print(f'the path yielding a sum of {target} starting from ({x}, {y}) is:')
    print(path)


#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@File    ：test_invite.py
@Author  ：Zeno
@Email   ：zhangyongjun@ones.ai
@Date    ：2021/12/2
@Desc    ：邀请注册
"""
from falcons.com.nick import feature, story, parametrize, fixture, mark
from falcons.helper.mysql import MysqlOps

from main.api.project import InvitationsAdd
from main.params.auth import invitation
from main.params.const import ACCOUNT

@fixture(autouse=True, scope='class')
def my_fixture(environment):
    yield
    print("Clean invitation record.")
    cnf = {'db': environment['db'], 'ssh_config': environment['ssh_config']}
    db = MysqlOps(cnf)

    _db = cnf['db'].db
    if _db:
        db_name = f'project_{_db}'
    else:
        db_name = f'project_{environment["sprint"]}' if environment["sprint"] else 'project'

    sql = f"delete from {db_name}.invitation where status=1 and team_uuid='{ACCOUNT.user.team_uuid}';"
    r = db.execute_sql(sql)
    print(f'invitation: {r} records deleted.')

    sql = f"delete from {db_name}.team_member where team_uuid='{ACCOUNT.user.team_uuid}';"
    r = db.execute_sql(sql)
    print(f'team_member: {r} records deleted.')

@fixture(scope='module')
def _storage():
    """存储用户UUID"""
    p = []
    return p

@feature('邀请注册接口')
class TestInvitation:
    @mark.smoke
    @story('邀请注册成功')
    @parametrize('param', invitation())
    def test_invite_success(self, param):
        """邀请注册"""

        invite = InvitationsAdd()

        # 调用接口
        invite.call(param.json, **param.extra)
        # 检查接口响应码
        invite.is_response_code(200)

    @story('邀请注册成功')
    @parametrize('param', invitation())
    def test_invite_success_empty_product(self, param):
        """邀请注册"""

        invite = InvitationsAdd()
        param.json['license_types'] = []  # 不授权产品
        # 调用接口
        invite.call(param.json, **param.extra)
        # 检查接口响应码
        invite.is_response_code([200, 400, 804])  # 接口返回不稳定啊

    @story('邀请注册失败-授权产品非法')
    @parametrize('param', invitation())
    def test_invite_fail_invalid_product(self, param):
        """邀请注册"""

        invite = InvitationsAdd()
        param.json['license_types'] = [999, 888]  # 授权产品代码非法
        # 调用接口
        invite.call(param.json, **param.extra)
        # 检查接口响应码
        invite.is_response_code([400, 804])
        # 检查测试响应数据
        # invite.check_response('errcode', 'InvalidParameter.LicenseGrant.Type.InvalidType')

    @story('邀请注册失败-邮箱为空')
    @parametrize('param', invitation())
    def test_invite_fail_empty_mail(self, param):
        """邀请注册"""

        invite = InvitationsAdd()
        json = param.json
        json['invite_settings'] = []  # 空邀请邮箱
        # 调用接口
        invite.call(param.json, **param.extra)
        # 检查接口响应码
        invite.is_response_code([400, 804])

        # 检查测试响应数据
        # invite.check_response('errcode', 'MissingParameter.Invitation.Email')


import json
import xmltodict
from StringIO import StringIO ##IF PYTHON3 from io import StringIO

from pyang.__init__ import Context, FileRepository
from pyang.translators.yin import YINPlugin

def create_yin(yang_model):
    yang_model = str(yang_model).replace('\n', '')

    yang_model_dict = _transform_yang_to_dict(yang_model)
    return json.dumps(yang_model_dict['module'], ensure_ascii=False)

def _transform_yang_to_dict(yang_model_string):
    class Opts(object):
        def __init__(self, yin_canonical=False, yin_pretty_strings=True):
            self.yin_canonical = yin_canonical
            self.yin_pretty_strings = yin_pretty_strings

    ctx = Context(FileRepository())
    yang_mod = ctx.add_module('yang', yang_model_string, format='yang')

    yin = YINPlugin()
    modules = []
    modules.append(yang_mod)
    ctx.opts = Opts()
    yin_string = StringIO()
    yin.emit(ctx=ctx, modules=modules, fd=yin_string)
    xml = yin_string.getvalue()
    return xmltodict.parse(xml)


import math
import seaborn as sns
from bioexplorer import BioExplorer, ParametricMembrane, Protein, Sugars, Virus, RNASequence, \
    Vector2, Vector3, Quaternion

# pylint: disable=no-member
# pylint: disable=missing-function-docstring

def test_virus():
    resource_folder = 'tests/test_files/'
    pdb_folder = resource_folder + 'pdb/'
    rna_folder = resource_folder + 'rna/'
    glycan_folder = pdb_folder + 'glycans/'

    bio_explorer = BioExplorer('localhost:5000')
    bio_explorer.reset()

    # Settings
    virus_radius = 45.0
    add_glycans = True
    protein_radius_multiplier = 1.0
    protein_representation = BioExplorer.REPRESENTATION_ATOMS
    protein_load_hydrogen = False

    # Virus configuration
    nb_protein_s = 62
    nb_protein_s_indices = [1, 27, 43]
    nb_protein_e = 42
    nb_protein_m = 50
    show_rna = True

    # Virus parameters
    show_functional_regions = False
    show_glycosylation_sites = False

    # Suspend image streaming
    bio_explorer.core_api().set_application_parameters(image_stream_fps=0)

    # Protein S
    open_conformation_indices = nb_protein_s_indices
    closed_conformation_indices = list()
    for i in range(nb_protein_s):
        if i not in open_conformation_indices:
            closed_conformation_indices.append(i)

    params = [11.5, 0, 0.0, 0, 0.0, 0.0]
    virus_protein_s = Protein(
        sources=[pdb_folder + '6vyb.pdb', pdb_folder + 'sars-cov-2-v1.pdb'],
        load_hydrogen=protein_load_hydrogen, occurences=nb_protein_s,
        assembly_params=params, rotation=Quaternion(0.087, 0.0, 0.996, 0.0),
        instance_indices=[open_conformation_indices, closed_conformation_indices])

    # Protein M (QHD43419)
    params = [2.5, 0, 0.0, 0, 0.0, 0.0]
    virus_protein_m = Protein(
        sources=[pdb_folder + 'QHD43419a.pdb'],
        load_hydrogen=protein_load_hydrogen, occurences=nb_protein_m,
        assembly_params=params, rotation=Quaternion(0.99, 0.0, 0.0, 0.135))

    # Protein E (QHD43418 P0DTC4)
    params = [2.5, 0, 0.0, 0, 0.0, 0.0]
    virus_protein_e = Protein(
        sources=[pdb_folder + 'QHD43418a.pdb'], load_hydrogen=protein_load_hydrogen,
        occurences=nb_protein_e, assembly_params=params,
        rotation=Quaternion(0.705, 0.705, -0.04, -0.04))

    # Virus membrane
    virus_membrane = ParametricMembrane(
        sources=[pdb_folder + 'membrane/popc.pdb'],
        occurences=15000)

    # RNA Sequence
    clip_planes = list()
    rna_sequence = None
    if show_rna:
        clip_planes.append([0.0, 0.0, -1.0, 15.0])
        rna_sequence = RNASequence(
            source=rna_folder + 'sars-cov-2.rna', assembly_params=[11.0, 0.5],
            t_range=Vector2(0, 30.5 * math.pi), shape=bio_explorer.RNA_SHAPE_TREFOIL_KNOT,
            shape_params=Vector3(1.51, 1.12, 1.93))

    # Coronavirus
    name = 'Coronavirus'
    coronavirus = Virus(
        name=name, protein_s=virus_protein_s, protein_e=virus_protein_e, protein_m=virus_protein_m,
        membrane=virus_membrane, rna_sequence=rna_sequence,
        assembly_params=[virus_radius, 1, 0.025, 2, 0.4, 0.0])

    bio_explorer.add_virus(
        virus=coronavirus, position=Vector3(-70.0, -100.0, 230.0),
        representation=protein_representation, atom_radius_multiplier=protein_radius_multiplier,
        clipping_planes=clip_planes)

    # Glycans
    if add_glycans:
        complex_paths = [glycan_folder + 'complex/5.pdb', glycan_folder + 'complex/15.pdb',
                         glycan_folder + 'complex/25.pdb', glycan_folder + 'complex/35.pdb']
        high_mannose_paths = [
            glycan_folder + 'high-mannose/1.pdb', glycan_folder + 'high-mannose/2.pdb',
            glycan_folder + 'high-mannose/3.pdb', glycan_folder + 'high-mannose/4.pdb']
        o_glycan_paths = [glycan_folder + 'o-glycan/12.pdb']

        # High-mannose
        indices_closed = [61, 122, 234, 603, 709, 717, 801, 1074]
        indices_open = [61, 122, 234, 709, 717, 801, 1074]
        bio_explorer.add_multiple_glycans(
            assembly_name=name, glycan_type=bio_explorer.NAME_GLYCAN_HIGH_MANNOSE,
            protein_name=bio_explorer.NAME_PROTEIN_S_CLOSED, paths=high_mannose_paths,
            indices=indices_closed, representation=protein_representation,
            atom_radius_multiplier=protein_radius_multiplier)
        bio_explorer.add_multiple_glycans(
            assembly_name=name, glycan_type=bio_explorer.NAME_GLYCAN_HIGH_MANNOSE,
            protein_name=bio_explorer.NAME_PROTEIN_S_OPEN, paths=high_mannose_paths,
            indices=indices_open, representation=protein_representation,
            atom_radius_multiplier=protein_radius_multiplier)

        # Complex
        indices1 = [17, 74, 149, 165, 282, 331, 343, 616, 657, 1098, 1134, 1158, 1173, 1194]
        indices2 = [17, 74, 149, 165, 282, 331, 343, 1098, 657, 1134, 1158, 1173, 1194]
        bio_explorer.add_multiple_glycans(
            assembly_name=name, glycan_type=bio_explorer.NAME_GLYCAN_COMPLEX,
            protein_name=bio_explorer.NAME_PROTEIN_S_CLOSED, paths=complex_paths, indices=indices1,
            representation=protein_representation, atom_radius_multiplier=protein_radius_multiplier)
        bio_explorer.add_multiple_glycans(
            assembly_name=name, glycan_type=bio_explorer.NAME_GLYCAN_COMPLEX,
            protein_name=bio_explorer.NAME_PROTEIN_S_OPEN, paths=complex_paths, indices=indices2,
            representation=protein_representation, atom_radius_multiplier=protein_radius_multiplier)

        # O-Glycans
        for index in [323, 325]:
            o_glycan_name = name + '_' + bio_explorer.NAME_GLYCAN_O_GLYCAN + '_' + str(index)
            o_glycan = Sugars(
                assembly_name=name, name=o_glycan_name, source=o_glycan_paths[0],
                protein_name=name + '_' + bio_explorer.NAME_PROTEIN_S_CLOSED,
                representation=protein_representation, site_indices=[index],
                atom_radius_multiplier=protein_radius_multiplier)
            bio_explorer.add_sugars(o_glycan)

        # High-mannose glycans on Protein M
        indices = [5]
        protein_name = name + '_' + bio_explorer.NAME_PROTEIN_M
        high_mannose_glycans = Sugars(
            rotation=Quaternion(0.707, 0.0, 0.0, 0.707),
            assembly_name=name, name=protein_name + '_' + bio_explorer.NAME_GLYCAN_HIGH_MANNOSE,
            protein_name=protein_name, source=high_mannose_paths[0],
            site_indices=indices,
            representation=protein_representation
        )
        bio_explorer.add_glycans(high_mannose_glycans)

        # Complex glycans on Protein E
        indices = [48, 66]
        protein_name = name + '_' + bio_explorer.NAME_PROTEIN_E
        complex_glycans = Sugars(
            rotation=Quaternion(0.707, 0.0, 0.0, 0.707),
            assembly_name=name, name=protein_name + '_' + bio_explorer.NAME_GLYCAN_COMPLEX,
            protein_name=protein_name, source=complex_paths[0],
            site_indices=indices,
            representation=protein_representation
        )
        bio_explorer.add_glycans(complex_glycans)

    # Apply default materials
    bio_explorer.apply_default_color_scheme(shading_mode=bio_explorer.SHADING_MODE_BASIC)

    # Functional regions on open spike
    if show_functional_regions:
        indices = [1, 16, 306, 330, 438, 507, 522, 816, 835, 908, 986, 1076, 1274, 2000]
        region_colors = [
            [1.0, 1.0, 1.0], [0.0, 0.0, 1.0], [1.0, 1.0, 1.0], [0.0, 1.0, 0.0], [0.4, 0.1, 0.1],
            [0.0, 1.0, 0.0], [1.0, 1.0, 1.0], [1.0, 0.0, 0.0], [1.0, 1.0, 1.0], [1.0, 1.0, 0.0],
            [1.0, 1.0, 1.0], [1.0, 0.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]
        palette = list()
        for index in range(len(indices) - 1):
            for i in range(0, indices[index + 1] - indices[index]):
                color = list()
                for j in range(3):
                    color.append(region_colors[index][j] * 1)
                palette.append(color)
        bio_explorer.set_protein_color_scheme(
            assembly_name=name, name=name + '_' + bio_explorer.NAME_PROTEIN_S_OPEN,
            color_scheme=bio_explorer.COLOR_SCHEME_REGION, palette=palette)

    # Display glycosylation sites
    if show_glycosylation_sites:
        palette = sns.color_palette('Set2', 2)
        bio_explorer.set_protein_color_scheme(
            assembly_name=name, name=name + '_' + bio_explorer.NAME_PROTEIN_S_OPEN,
            color_scheme=bio_explorer.COLOR_SCHEME_GLYCOSYLATION_SITE, palette=palette)
        bio_explorer.set_protein_color_scheme(
            assembly_name=name, name=name + '_' + bio_explorer.NAME_PROTEIN_S_CLOSED,
            color_scheme=bio_explorer.COLOR_SCHEME_GLYCOSYLATION_SITE, palette=palette)

    # Set rendering settings
    bio_explorer.core_api().set_renderer(
        background_color=[96 / 255, 125 / 255, 139 / 255], current='bio_explorer',
        samples_per_pixel=1, subsampling=4, max_accum_frames=64)
    params = bio_explorer.core_api().BioExplorerRendererParams()
    params.shadows = 0.75
    params.soft_shadows = 1.0
    bio_explorer.core_api().set_renderer_params(params)

    # Restore image streaming
    bio_explorer.core_api().set_application_parameters(image_stream_fps=20)

if __name__ == '__main__':
    import nose

    nose.run(defaultTest=__name__)


from camel.generator import (
    AISocietyTaskPromptGenerator,
    RoleNameGenerator,
    SystemMessageGenerator,
)
from camel.typing import RoleType, TaskType

def test_system_message_generator():
    sys_msg_generator = SystemMessageGenerator(task_type=TaskType.AI_SOCIETY)
    sys_msg_generator.from_dict({"<ASSISTANT_ROLE>": "doctor"},
                                role_tuple=("doctor", RoleType.ASSISTANT))
    sys_msg_generator.from_dict({"<USER_ROLE>": "doctor"},
                                role_tuple=("doctor", RoleType.USER))

    sys_msg_generator.from_dicts(
        [{
            "<ASSISTANT_ROLE>": "chatbot",
            "<USER_ROLE>": "doctor"
        }] * 2,
        role_tuples=[("chatbot", RoleType.ASSISTANT),
                     ("doctor", RoleType.USER)],
    )

    sys_msg_generator = SystemMessageGenerator(task_type=TaskType.AI_SOCIETY)
    sys_msg_generator.from_dicts(
        [{
            "<ASSISTANT_ROLE>": "chatbot",
            "<USER_ROLE>": "doctor",
            "<TASK>": "Analyze a patient's medical report"
        }] * 2,
        role_tuples=[("chatbot", RoleType.ASSISTANT),
                     ("doctor", RoleType.USER)],
    )

def test_role_name_generator():
    role_name_generator = RoleNameGenerator().from_role_files()
    role_tuple = next(role_name_generator)
    assert isinstance(role_tuple, tuple)

def test_task_prompt_generator():
    role_name_generator = RoleNameGenerator().from_role_files()
    task_tuple = next(AISocietyTaskPromptGenerator().from_role_generator(
        role_name_generator))
    assert isinstance(task_tuple, str)

    task_tuple = next(AISocietyTaskPromptGenerator().from_role_files())
    assert isinstance(task_tuple, str)


from datetime import date, datetime
import pandas as pd
import pytest
from pandas._testing import assert_frame_equal

from python_project.data import (
    ForecastResult,
    ForecastParams,
    ForecastData,
    ForecastProblem,
)
from python_project.models.base import ForecastSolver

@pytest.mark.parametrize(
    "df,expected",
    [
        (
            pd.DataFrame({"y": [1]}),
            ForecastResult(
                forecast=pd.DataFrame({"y": [1]}),
                metrics=pd.DataFrame({"y": [1]}),
            ),
        )
    ],
)
def test_ForecastSolver_forecaster(mocker, df, expected):
    class_forecast = mocker.MagicMock()
    forecast_problem = mocker.MagicMock()

    train = class_forecast.test_train
    train.return_value = ("train", "test")

    result_forecast = class_forecast.run_forecast
    result_forecast.return_value = df

    result_metrics = class_forecast.metrics
    result_metrics.return_value = df

    result = ForecastSolver.forecaster(class_forecast, forecast_problem)

    class_forecast.test_train.assert_called_once()
    class_forecast.run_forecast.assert_called_once()
    class_forecast.metrics.assert_called_once()

    assert_frame_equal(result.forecast, expected.forecast)
    assert_frame_equal(result.metrics, expected.metrics)

@pytest.mark.parametrize(
    "df,expected",
    [
        (
            pd.DataFrame(
                columns=["ds", "y"],
                data=[
                    ["2020-01-06", 10],
                    ["2020-01-13", 20],
                    ["2020-01-20", 30],
                ],
            )
            .assign(ds=lambda x: pd.to_datetime(x.ds))
            .set_index("ds"),
            pd.DataFrame(
                {
                    "yhat": range(1, 17 + 1),
                    "ds": pd.date_range(
                        datetime(2020, 1, 27, 0, 0, 0), periods=17, freq="7d"
                    ),
                }
            )
            .set_index("ds")
            .asfreq("7d"),
        )
    ],
)
def test_ForecastSolver_run_forecast(df, expected, mocker):
    class_forecast = mocker.MagicMock()
    forecast_problem = mocker.MagicMock()

    n_value = 12 + 4 + 1
    forecast_problem.params.forecast_periods = n_value

    yhat = class_forecast.do_forecast
    yhat.return_value = [x for x in range(1, n_value + 1)]

    class_forecast.name_model = "model"

    df_predict = ForecastSolver.run_forecast(
        class_forecast, forecast_problem, df
    )

    class_forecast.do_forecast.assert_called_once()

    assert_frame_equal(df_predict, expected)

@pytest.mark.parametrize(
    "df,ds,expected",
    [
        (
            pd.DataFrame(
                columns=["ds", "y"],
                data=[["2017-12-04", 10], ["2018-01-01", 14]],
            ).assign(ds=lambda x: pd.to_datetime(x.ds)),
            date(2018, 1, 2),
            (
                pd.DataFrame(
                    columns=["ds", "y"],
                    data=[[datetime(2017, 12, 4, 0, 0, 0), 10]],
                ).set_index("ds"),
                pd.DataFrame(
                    columns=["ds", "y"],
                    data=[[datetime(2018, 1, 1, 0, 0, 0), 14]],
                ).set_index("ds"),
            ),
        )
    ],
)
def test_forecast_test_train(df, ds, expected):
    params = ForecastParams(
        forecast_start=ds,
    )
    data = ForecastData(df=df)
    forecast_problem = ForecastProblem(params=params, data=data)
    train, test = ForecastSolver.test_train(forecast_problem)
    assert_frame_equal(train, expected[0])
    assert_frame_equal(test, expected[1])

@pytest.mark.parametrize(
    "test, forecast,error",
    [
        (
            (
                pd.DataFrame(
                    columns=["ds", "y"],
                    data=[
                        ["2019-01-01", 10],
                        ["2019-01-02", 20],
                        ["2019-01-03", 30],
                    ],
                )
                .assign(ds=lambda x: pd.to_datetime(x.ds))
                .set_index("ds")
            ),
            (
                pd.DataFrame(
                    columns=["ds", "yhat"],
                    data=[
                        ["2019-01-01", 11],
                        ["2019-01-02", 18],
                        ["2019-01-03", 33],
                    ],
                )
                .assign(ds=lambda x: pd.to_datetime(x.ds))
                .set_index("ds")
            ),
            pd.DataFrame(
                columns=[
                    "mae",
                    "mse",
                    "rmse",
                    "mape",
                    "maape",
                    "wmape",
                    "mmape",
                    "smape",
                    "model",
                ],
                data=[[2.00, 4.67, 2.16, 0.1, 0.1, 0.1, 0.09, 0.1, "model"]],
            ),
        )
    ],
)
def test_forecast_metrics(
    test,
    forecast,
    error,
):
    result = ForecastSolver.metrics(test, forecast, "model")
    assert_frame_equal(result, error)


import os

from binance.client import Client
from binance.enums import *
from binance.exceptions import BinanceAPIException
from binance.websockets import BinanceSocketManager

from futuremaker import utils

class BinanceAPI:

    def __init__(self):
        key = os.getenv('key')
        secret = os.getenv('secret')
        self.client = Client(key, secret)
        self.ws = BinanceSocketManager(self.client)
        self.conn_key = None

    def __get_interval(self, timeframe):
        if timeframe == '1m':
            interval = Client.KLINE_INTERVAL_1MINUTE
        elif timeframe == '5m':
            interval = Client.KLINE_INTERVAL_5MINUTE
        elif timeframe == '10m':
            interval = Client.KLINE_INTERVAL_10MINUTE
        elif timeframe == '15m':
            interval = Client.KLINE_INTERVAL_15MINUTE
        elif timeframe == '30m':
            interval = Client.KLINE_INTERVAL_30MINUTE
        elif timeframe == '1h':
            interval = Client.KLINE_INTERVAL_1HOUR
        elif timeframe == '2h':
            interval = Client.KLINE_INTERVAL_2HOUR
        elif timeframe == '4h':
            interval = Client.KLINE_INTERVAL_4HOUR
        elif timeframe == '1d':
            interval = Client.KLINE_INTERVAL_1DAY
        elif timeframe == '1w':
            interval = Client.KLINE_INTERVAL_1WEEK
        return interval

    def bulk_klines(self, symbol, timeframe, since=None):
        # since: "1 Jan, 2017"
        interval = self.__get_interval(timeframe)
        klines = self.client.get_historical_klines(symbol, interval, start_str=since)
        return klines

    def get_klines(self, symbol, timeframe, since, limit=10):
        interval = self.__get_interval(timeframe)
        klines = self.client.get_historical_klines(symbol, interval, start_str=since, limit=limit)
        return klines

    def margin_account_info(self):
        info = self.client.get_margin_account()
        return info

    def create_buy_order(self, symbol, quantity, price=None):
        if price is not None:
            order = self.client.create_margin_order(
                symbol=symbol,
                quantity=quantity,
                price=price,
                side=SIDE_BUY,
                type=ORDER_TYPE_LIMIT,
                timeInForce=TIME_IN_FORCE_GTC)
        else:
            order = self.client.create_margin_order(
                symbol=symbol,
                quantity=quantity,
                side=SIDE_BUY,
                type=ORDER_TYPE_MARKET)
        return order

    def create_sell_order(self, symbol, quantity, price=None):
        if price is not None:
            order = self.client.create_margin_order(
                symbol=symbol,
                quantity=quantity,
                price=price,
                side=SIDE_SELL,
                type=ORDER_TYPE_LIMIT,
                timeInForce=TIME_IN_FORCE_GTC)
        else:
            order = self.client.create_margin_order(
                symbol=symbol,
                quantity=quantity,
                side=SIDE_SELL,
                type=ORDER_TYPE_MARKET)
        return order

    def get_my_trades(self, symbol):
        return self.client.get_my_trades(symbol=symbol)

    def get_price(self, symbol, price_type='lastPrice'):
        """
        :param symbol:
        :param price_type: bidPrice, askPrice, lastPrice
        :return:
        """
        ticker = self.client.get_ticker(symbol=symbol)
        return float(ticker[price_type])

    def create_loan(self, asset, amount):
        transaction = self.client.create_margin_loan(asset=asset, amount=amount)
        return transaction['tranId']

    def get_loan(self, asset, txId):
        details = self.client.get_margin_loan_details(asset=asset, txId=txId)
        if len(details['rows']) == 0:
            return -1, details
        elif details['rows'][0]['status'] == 'CONFIRMED':
            # 성공
            return 0, details
        else:
            # 실패
            return 1, details

    def repay_loan(self, asset, amount):
        transaction = self.client.repay_margin_loan(asset=asset, amount=amount)
        return transaction

    def repay_all(self, asset):
        info = self.margin_account_info()
        obj = next(item for item in info['userAssets'] if item['asset'] == asset)
        total = float(obj['borrowed']) + float(obj['interest'])
        available = min(total, float(obj['free']))
        self.repay_loan(asset, available)
        return available

    def asset_detail(self):
        details = self.client.get_asset_details()
        return details

    def get_orderbook_tickers(self, symbol):
        """
        :return: {'symbol': 'BTCUSDT', 'bidPrice': '9379.95000000', 'bidQty': '0.26652500', 'askPrice': '9380.00000000',
                    'askQty': '0.22441700'}
        """
        tickers = self.client.get_orderbook_tickers()
        return next(item for item in tickers if item['symbol'] == symbol)

    def start_websocket(self, symbol, timeframe, callback):
        interval = self.__get_interval(timeframe)
        self.conn_key = self.ws.start_kline_socket(symbol, callback, interval=interval)
        self.ws.start()

    def stop_websocket(self):
        self.ws.stop_socket(self.conn_key)

    def get_balance(self, asset):
        info = self.margin_account_info()
        o = next(item['free'] for item in info['userAssets'] if item['asset'] == asset)
        return float(o)