from plone.dexterity.interfaces import IDexterityContent
from plone.registry.interfaces import IRegistry
from plone.restapi.controlpanels import IControlpanel
from plone.restapi.interfaces import IFieldSerializer
from plone.restapi.interfaces import ISerializeToJson
from plone.restapi.interfaces import ISerializeToJsonSummary
from plone.restapi.serializer.converters import json_compatible
from plone.restapi.types import utils
from zope.component import adapter
from zope.component import getUtility
from zope.component import queryMultiAdapter
from zope.interface import alsoProvides
from zope.interface import implementer
from zope.interface import noLongerProvides

import zope.schema

SERVICE_ID = "@controlpanels"

@implementer(ISerializeToJsonSummary)
@adapter(IControlpanel)
class ControlpanelSummarySerializeToJson:
    def __init__(self, controlpanel):
        self.controlpanel = controlpanel

    def __call__(self):
        return {
            "@id": "{}/{}/{}".format(
                self.controlpanel.context.absolute_url(),
                SERVICE_ID,
                self.controlpanel.__name__,
            ),
            "title": self.controlpanel.title,
            "group": self.controlpanel.group,
        }

def get_jsonschema_for_controlpanel(controlpanel, context, request, form=None):
    """Build a complete JSON schema for the given controlpanel."""
    if not form:
        schema = controlpanel.schema
        fieldsets = utils.get_fieldsets(context, request, schema)
    else:
        fieldsets = utils.get_form_fieldsets(form)

    # Build JSON schema properties
    properties = utils.get_jsonschema_properties(context, request, fieldsets)

    # Determine required fields
    required = []
    for field in utils.iter_fields(fieldsets):
        if field.field.required:
            required.append(field.field.getName())

    # Include field modes
    for field in utils.iter_fields(fieldsets):
        if field.mode:
            properties[field.field.getName()]["mode"] = field.mode

    return {
        "type": "object",
        "properties": properties,
        "required": required,
        "fieldsets": utils.get_fieldset_infos(fieldsets),
    }

@implementer(ISerializeToJson)
@adapter(IControlpanel)
class ControlpanelSerializeToJson:
    def __init__(self, controlpanel):
        self.controlpanel = controlpanel
        self.schema = self.controlpanel.schema
        self.schema_prefix = self.controlpanel.schema_prefix

        self.registry = getUtility(IRegistry)

    def __call__(self):
        json_schema = get_jsonschema_for_controlpanel(
            self.controlpanel, self.controlpanel.context, self.controlpanel.request
        )

        proxy = self.registry.forInterface(self.schema, prefix=self.schema_prefix)

        # Temporarily provide IDexterityContent, so we can use DX field
        # serializers
        alsoProvides(proxy, IDexterityContent)

        json_data = {}
        for name, field in zope.schema.getFields(self.schema).items():
            serializer = queryMultiAdapter(
                (field, proxy, self.controlpanel.request), IFieldSerializer
            )
            if serializer:
                value = serializer()
            else:
                value = getattr(proxy, name, None)
            json_data[json_compatible(name)] = value

        noLongerProvides(proxy, IDexterityContent)

        # JSON schema
        return {
            "@id": "{}/{}/{}".format(
                self.controlpanel.context.absolute_url(),
                SERVICE_ID,
                self.controlpanel.__name__,
            ),
            "title": self.controlpanel.title,
            "group": self.controlpanel.group,
            "schema": json_schema,
            "data": json_data,
        }


"""Stormpath CustomData resource mappings."""

from dateutil.parser import parse

from .base import (
    DeleteMixin,
    Resource,
    SaveMixin,
)

class CustomData(Resource, DeleteMixin, SaveMixin):
    """CustomData Resource for custom user data.

    Resources have predefined fields that are useful to many applications,
    but you are likely to have your own custom data that you need to associate
    with a resource as well. It behaves like a Python dictionary.

    More info in documentation:
    http://docs.stormpath.com/rest/product-guide/#custom-data
    """
    data_field = '_data'
    readonly_attrs = (
        'created_at',
        'href',
        'ionmeta',
        'ion_meta',
        'meta',
        'modified_at',
        'spmeta',
        'sp_meta',
        'sp_http_status',
    )

    exposed_readonly_timestamp_attrs = (
        'created_at',
        'modified_at',
    )

    def __init__(self, *args, **kwargs):
        super(CustomData, self).__init__(*args, **kwargs)
        self._deletes = set([])

    def __getitem__(self, key):
        if key == self.data_field:
            return self.__dict__[self.data_field]

        if (key not in self.__dict__.get(self.data_field, {})) and \
                (self._get_key_href(key) not in self._deletes):
            self._ensure_data()

        return getattr(self, self.data_field)[key]

    def __setitem__(self, key, value):
        if key == self.data_field:
            self.__dict__[self.data_field] = value

        if key in self.readonly_attrs or \
                self.from_camel_case(key) in self.readonly_attrs:
            raise KeyError(
                "Custom data property '%s' is not writable" % (key))
        else:
            if key.startswith('-'):
                raise KeyError(
                    "Usage of '-' at the beginning of key is not allowed")

            key_href = self._get_key_href(key)
            if key_href in self._deletes:
                self._deletes.remove(key_href)

            getattr(self, self.data_field)[key] = value

    def __delitem__(self, key):
        if key in self.exposed_readonly_timestamp_attrs:
            raise KeyError(
                "Custom data property '%s' is not deletable" % (key))

        self._ensure_data()

        for href in self._deletes:
            try:
                del self.__dict__.get(self.data_field, {})[href.split('/')[-1]]
            except KeyError:
                pass

        del self.__dict__.get(self.data_field, {})[key]

        if not self.is_new():
            self._deletes.add(self._get_key_href(key))

    def __contains__(self, key):
        self._ensure_data()
        return key in self.__dict__.get(self.data_field, {})

    def __setattr__(self, name, value):
        ctype = self.get_resource_attributes().get(name)

        if ctype and not isinstance(value, ctype) \
                and name not in self.readonly_attrs:
            getattr(self, name)._set_properties(value)
        elif name.startswith('_') or name in self.writable_attrs:
            super(CustomData, self).__setattr__(name, value)
        else:
            self._set_properties({name: value})

    def __getattr__(self, name):
        if name == 'href':
            return self.__dict__.get('href')

        self._ensure_data()
        if name in self.__dict__:
            return self.__dict__[name]
        elif name in self.__dict__[self.data_field]:
            return self.__dict__[self.data_field][name]
        else:
            raise AttributeError(
                "%s has no attribute '%s'" %
                (self.__class__.__name__, name))

    def _get_key_href(self, key):
        return '%s/%s' % (self.href, key)

    def keys(self):
        self._ensure_data()
        return self.__dict__.get(self.data_field, {}).keys()

    def values(self):
        self._ensure_data()
        return self.__dict__.get(self.data_field, {}).values()

    def items(self):
        self._ensure_data()
        return self.__dict__.get(self.data_field, {}).items()

    def get(self, key, default=None):
        try:
            return self.__getitem__(key)
        except KeyError:
            return default

    def __iter__(self):
        self._ensure_data()
        return iter(self.__dict__.get(self.data_field, {}))

    def _get_properties(self):
        data = self.__dict__.get(self.data_field, {})
        writable_attrs = set(data) - set(
            self.exposed_readonly_timestamp_attrs)
        if data:
            return {k: self.__dict__[self.data_field][k] for k in writable_attrs}
        return data

    def _set_properties(self, properties, overwrite=False):
        data = self.__dict__.get(self.data_field, {})
        for k, v in properties.items():
            kcc = self.from_camel_case(k)
            if kcc in self.readonly_attrs:
                if kcc in self.exposed_readonly_timestamp_attrs:
                    v = parse(v)
                    data[kcc] = v
                self.__dict__[kcc] = v
            else:
                if k not in data:
                    data[k] = v
        if data:
            self.__dict__[self.data_field] = data

    def save(self):
        for href in self._deletes:
            self._store.delete_resource(href)

        self._deletes = set()

        if self.data_field in self.__dict__ and \
                len(self._get_properties()):
            super(CustomData, self).save()

    def delete(self):
        super(CustomData, self).delete()
        self.__dict__[self.data_field] = {}


from time import sleep
import os
from youtube_dl import YoutubeDL
import discord
from discord.ext import commands
import random
from dotenv import load_dotenv

MUSICA = []
ydl_opts = {
    'format' : 'bestaudio/best',
    'postprocessors': [{
        'key': 'FFmpegExtractAudio',
        'preferredcodec': 'mp3',
        'preferredquality': '192',
    }]
}

FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
dotenv_path = ('.env')
load_dotenv(dotenv_path)

client = commands.Bot(command_prefix='-')

@client.command()
async def stop(ctx):
    voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
    voice_client.stop()

@client.command()
async def c(ctx):
    try:
        canal_nome = str(ctx.message.author.voice.channel)
        await ctx.send('ESTOU CONECTADA NO CANAL' +" "+ str(canal_nome))
        connect = discord.utils.get(ctx.guild.voice_channels, name=canal_nome)
        await connect.connect()

        voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
        voice_client.play(discord.FFmpegPCMAudio(executable="vendor/ffmpeg/ffmpeg", source="toca/Bandeirantes.mp3"))
        # voice_client.play(discord.FFmpegPCMAudio(executable="ffmpeg.exe", source="toca/Bandeirantes.mp3"))
    except Exception as e:
        print("#"*100)
        print(e)
        print("#"*100)

@client.command()
async def play(ctx,*, url):
    voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
    if voice_client.is_playing():
        MUSICA.append(url)
        await ctx.send("Musica adicionada na lista")
    else:
        await ctx.channel.send("tocando musica")
        songs = os.path.isfile(f"/app/song.mp3")

        if songs:
            os.remove('/app/song.mp3')

        ale = random.randint(1, 4)
        voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
        # voice_client.play(discord.FFmpegPCMAudio(executable="vendor/ffmpeg/ffmpeg", source=f"toca/{ale}.mp3"))
        # voice_client.play(discord.FFmpegPCMAudio(executable="ffmpeg.exe", source=f"toca\\{ale}.mp3"))
        sleep(2)
        try:
            if url[:5] == "https":
                with YoutubeDL(ydl_opts) as ydl:
                    # url = "ytsearch:"+url
                    dados = ydl.extract_info(url, download=False)
                    link = dados['formats'][0]['url']
                    print(link)
            else:
                with YoutubeDL(ydl_opts) as ydl:
                    url = "ytsearch:"+url
                    dados = ydl.extract_info(url, download=False)
                    p = dados['entries']
                    for itens in p:
                        link = itens['url']

            voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
            if voice_client.is_playing():
                await stop(ctx)

            voice_client.play(discord.FFmpegPCMAudio(link,**FFMPEG_OPTIONS))
        except Exception as e:
            print("#"*100)
            print(e)
            print("#"*100)

@client.command()
async def skip(ctx):
    url = MUSICA.pop(0)
    voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
    if voice_client.is_playing():
        await stop(ctx)
    await ctx.send("Tocado Musica : "+url)
    try:
        if url[:5] == "https":
            with YoutubeDL(ydl_opts) as ydl:
                # url = "ytsearch:"+url
                dados = ydl.extract_info(url, download=False)
                link = dados['formats'][0]['url']
                print(link)
        else:
            with YoutubeDL(ydl_opts) as ydl:
                url = "ytsearch:"+url
                dados = ydl.extract_info(url, download=False)
                p = dados['entries']
                for itens in p:
                    link = itens['url']

        voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
        voice_client.play(discord.FFmpegPCMAudio(link,**FFMPEG_OPTIONS))
    except Exception as e:
        print("#"*100)
        print(e)
        print("#"*100)

@client.command()
async def lista(ctx):
    ctx.send("Musica da lista")
    ctx.send("#"*20)
    for i in MUSICA:
        await ctx.send(i)
    ctx.send("#"*20)

@client.command()
async def d(ctx):
    try:
        voice_client = discord.utils.get(client.voice_clients, guild=ctx.guild)
        if voice_client.is_playing():
            await stop(ctx)
            voice_client.play(discord.FFmpegPCMAudio(executable="vendor/ffmpeg/ffmpeg", source="toca/palmeiras.mp3"))
            sleep(3)
        if voice_client.is_connected():
            await voice_client.disconnect()
        else:
            await ctx.send("bot não conectando")
    except Exception as e:
        print("#"*100)
        print(e)
        print("#"*100)

@client.command()
async def revolucao(ctx):
        # 8589934591
        role = discord.utils.get(ctx.guild.roles, name='Um bosta qualquer')
        print(role)
        await discord.Member.add_roles(ctx.author, role)

@client.command()
async def enviar(ctx):
    await ctx.channel.purge(limit=6)

token = os.environ.get("token")
client.run(token)


import boto3
import botocore
import datetime
import logging
import os

logger = logging.getLogger()
logger.setLevel(logging.INFO)

s3 = boto3.client(
    "s3",
    region_name="us-east-1",
    config=botocore.config.Config(s3={"addressing_style":"path"})
)

s3_bucket = os.environ["S3_BUCKET_NAME"]

def compute_num_completed_tasks(job_id):
    """
    Compute number of files in the job's worker output S3 directory.

    Note: need to use paginator to get around 1000 item limit
    https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
    """
    paginator = s3.get_paginator("list_objects_v2")
    pages = paginator.paginate(Bucket=s3_bucket, Prefix=f"intermediate/{job_id}/")
    num_completed = 0
    for page in pages:
        num_completed += page["KeyCount"]
    return num_completed

def compute_num_remaining_tasks(event):
    """
    Compute number of dispatched tasks that have not written output to S3.
    """
    job_id = event["job_id"]
    num_dispatched = event["num_tasks_dispatched"]
    num_completed = compute_num_completed_tasks(job_id)
    num_remaining = num_dispatched - num_completed
    return num_remaining

def compute_elapsed_secs(start_ftime):
    """
    Compute number of seconds since state machine execution started.
    """
    start_time = datetime.datetime.strptime(start_ftime, '%Y-%m-%dT%H-%M-%S')
    elapsed_secs = datetime.datetime.now() - start_time
    elapsed_secs = elapsed_secs.total_seconds()
    return elapsed_secs

def lambda_handler(event, context):
    logger.info(f"Input event: {event}")
    num_remaining = compute_num_remaining_tasks(event)
    elapsed_secs = compute_elapsed_secs(event["start_time"])
    output = {
        **event,
        "num_tasks_remaining": num_remaining,
        "elapsed_secs": elapsed_secs
    }

    # Job finished (all tasks completed)
    if num_remaining == 0:
        return {
            **output,
            "completed": True
        }

    # Job timed out
    class JobTimedOutException(Exception): pass
    if elapsed_secs > event["job_timeout_secs"]:
        raise JobTimedOutException("Job timed out")

    # Job still running
    return {
        **output,
        "completed": False
    }


import copy
from mmdet.models import DETECTORS
from mmdet3d.core import bbox3d2result
from mmdet3d.models.detectors.mvx_two_stage import MVXTwoStageDetector
from projects.mmdet3d_plugin.models.utils.grid_mask import GridMask
from mmcv.runner import force_fp32, auto_fp16
import torch

# shiyu add: build mask seg head
from ..builder import build_head
import cv2
import numpy as np
import os.path as osp
import matplotlib.pyplot as plt

CANDIDATE=['n008-2018-08-01-15-16-36-0400_1533151184047036',
           'n008-2018-08-01-15-16-36-0400_1533151200646853',
           'n008-2018-08-01-15-16-36-0400_1533151274047332',
           'n008-2018-08-01-15-16-36-0400_1533151369947807',
           'n008-2018-08-01-15-16-36-0400_1533151581047647',
           'n008-2018-08-01-15-16-36-0400_1533151585447531',
           'n008-2018-08-01-15-16-36-0400_1533151741547700',
           'n008-2018-08-01-15-16-36-0400_1533151854947676',
           'n008-2018-08-22-15-53-49-0400_1534968048946931',
           'n008-2018-08-22-15-53-49-0400_1534968255947662',
           'n008-2018-08-01-15-16-36-0400_1533151616447606',
           'n015-2018-07-18-11-41-49+0800_1531885617949602',
           'n008-2018-08-28-16-43-51-0400_1535489136547616',
           'n008-2018-08-28-16-43-51-0400_1535489145446939',
           'n008-2018-08-28-16-43-51-0400_1535489152948944',
           'n008-2018-08-28-16-43-51-0400_1535489299547057',
           'n008-2018-08-28-16-43-51-0400_1535489317946828',
           'n008-2018-09-18-15-12-01-0400_1537298038950431',
           'n008-2018-09-18-15-12-01-0400_1537298047650680',
           'n008-2018-09-18-15-12-01-0400_1537298056450495',
           'n008-2018-09-18-15-12-01-0400_1537298074700410',
           'n008-2018-09-18-15-12-01-0400_1537298088148941',
           'n008-2018-09-18-15-12-01-0400_1537298101700395',
           'n015-2018-11-21-19-21-35+0800_1542799330198603',
           'n015-2018-11-21-19-21-35+0800_1542799345696426',
           'n015-2018-11-21-19-21-35+0800_1542799353697765',
           'n015-2018-11-21-19-21-35+0800_1542799525447813',
           'n015-2018-11-21-19-21-35+0800_1542799676697935',
           'n015-2018-11-21-19-21-35+0800_1542799758948001',
           ]

DEBUG_CANDIDATE=[
    'n008-2018-08-01-15-16-36-0400_1533151212898782',
    'n008-2018-08-01-15-16-36-0400_1533151274047332'
]

# shiyu add
def img_pro_shiyu(img_pro):
    # import pdb; pdb.set_trace()
    img_min = np.min(img_pro)
    img_max = np.max(img_pro)
    interval = img_max - img_min
    new_img = (img_pro - img_min)/interval
    new_img = new_img * 255.0
    return new_img

def gen_random_color():
    random_RGB = np.random.randint(50,255,size=3)
    # random_r = random.randint(0,255)
    # random_g = random.randint(0,255)
    # random_b = random.randint(0,255)
    # random_RGB = [random_r,random_g,random_b]
    return random_RGB

def cal_iou(gt_mask, pre_mask):
    # import pdb; pdb.set_trace()
    intersect = (gt_mask & pre_mask).astype(np.int)
    # union = int(gt_mask | pre_mask)
    union = (gt_mask).astype(np.int)
    intersection_count = np.sum(intersect)
    union_count = np.sum(union)
    if union_count==0: return 0
    return round((intersection_count/union_count), 2)

# 计算一个类别里面所有的ious
def cal_ious_list(gt_mask_list, pre_mask_list):
    len_gt = len(gt_mask_list)
    len_dt = len(pre_mask_list)
    ious = np.empty([len_dt,len_gt], dtype = float)
    for i in range(len_dt):
        for j in range(len_gt):
            iou = cal_iou(gt_mask_list[j].astype(bool),pre_mask_list[i])
            ious[i][j] = iou
    return ious

# 顺序： front, front_right, front_left, cam_back, cam_back_left, cam_back_right
def draw_pv_img(img_list):
    new_size = [1067,600] # width, height
    front_img = cv2.imread(img_list[0],1)   # flag=1,bgr 3 channels
    front_right = cv2.imread(img_list[1],1)
    front_left = cv2.imread(img_list[2],1)
    cam_back = cv2.imread(img_list[3],1)
    cam_back_left = cv2.imread(img_list[4],1)
    cam_back_right = cv2.imread(img_list[5],1)

    new_front = cv2.resize(front_img, new_size, interpolation=cv2.INTER_LINEAR)
    new_front_right = cv2.resize(front_right, new_size, interpolation=cv2.INTER_LINEAR)
    new_front_left = cv2.resize(front_left, new_size, interpolation=cv2.INTER_LINEAR)
    new_cam_back = cv2.resize(cam_back, new_size, interpolation=cv2.INTER_LINEAR)
    new_cam_back_left = cv2.resize(cam_back_left, new_size, interpolation=cv2.INTER_LINEAR)
    new_cam_back_right = cv2.resize(cam_back_right, new_size, interpolation=cv2.INTER_LINEAR)

    row_1 = np.hstack([new_front_left,new_front,new_front_right])
    row_2 = np.hstack([new_cam_back_left, new_cam_back, new_cam_back_right])
    # import pdb; pdb.set_trace()
    # [1200,3200]
    result = np.vstack([row_1,row_2])

    return result

def draw_pv_img_low_res(img_list):
    # new_size = [1067,600] # width, height
    new_size = [178,100] # width, height
    front_img = cv2.imread(img_list[0],1)   # flag=1,bgr 3 channels
    front_right = cv2.imread(img_list[1],1)
    front_left = cv2.imread(img_list[2],1)
    cam_back = cv2.imread(img_list[3],1)
    cam_back_left = cv2.imread(img_list[4],1)
    cam_back_right = cv2.imread(img_list[5],1)

    new_front = cv2.resize(front_img, new_size, interpolation=cv2.INTER_LINEAR)
    new_front_right = cv2.resize(front_right, new_size, interpolation=cv2.INTER_LINEAR)
    new_front_left = cv2.resize(front_left, new_size, interpolation=cv2.INTER_LINEAR)
    new_cam_back = cv2.resize(cam_back, new_size, interpolation=cv2.INTER_LINEAR)
    new_cam_back_left = cv2.resize(cam_back_left, new_size, interpolation=cv2.INTER_LINEAR)
    new_cam_back_right = cv2.resize(cam_back_right, new_size, interpolation=cv2.INTER_LINEAR)

    row_1 = np.hstack([new_front_left,new_front,new_front_right])
    row_2 = np.hstack([new_cam_back_left, new_cam_back, new_cam_back_right])
    # import pdb; pdb.set_trace()
    # [1200,3200]
    result = np.vstack([row_1,row_2])

    return result

# 画出 ins 匹配之后的实例
def draw_ins_w_match(gts, dts, gt_match, dt_match, gt_label, bev_feat_list):

    bev_feat = bev_feat_list[0][0,:,:,:]    # c,h,w
    bev_feat = torch.mean(bev_feat,0,keepdim=True)  #1,h,w
    bev_feat = bev_feat.permute(1,2,0)
    bev_feat_vis = bev_feat.clone().detach().cpu().numpy()
    dt_img = cv2.cvtColor(bev_feat_vis, cv2.COLOR_GRAY2BGR) #h,w,3

    dt_img = np.ones([200,100,3])*255

    # new_mask_size = [600,1200]

    # import pdb; pdb.set_trace()
    gt_label = gt_label.clone().detach().cpu().numpy()
    for i in range(len(gt_match)):
        single_dt_idx = gt_match[i]         # 和dt match的参数
        if single_dt_idx==(-1): continue
        color = LABEL2COLOR[gt_label[i]]
        single_dt = dts[single_dt_idx]
        dt_img[single_dt] = color
    return dt_img

# pre_masks 已经排序好了
def match_masks(gt_masks, pre_masks, thr=0.0):
    height = len(pre_masks)
    width = len(gt_masks)
    # gt_masks = gt_masks.astype(bool)
    pre_masks = pre_masks.astype(bool)
    ious = cal_ious_list(gt_masks, pre_masks)
    gt_match = np.empty([width], dtype = int)
    dt_match = np.empty([height], dtype = int)
    gt_match.fill(-1)
    dt_match.fill(-1)
    for i in range(height):  # dt
        single_ious = ious[i]
        if len(single_ious)==0: continue
        max_idx = np.argmax(single_ious)
        # max_idx = single_ious.index(max(single_ious))
        max_iou = ious[i][max_idx]
        if gt_match[max_idx] > 0: dt_match[i] = -2; continue  # 如果已经匹配了，就继续运行
        if max_iou<thr: continue
        dt_match[i] = max_idx
        gt_match[max_idx] = i
    return dt_match, gt_match,ious

LABEL2COLOR={
    0: [255,0,0],
    1: [0,255,0],
    2: [0,0,255]
}
# feat_save_root = '/mnt/vepfs/ML/ml-users/shiyu/MapTR_local/mapseg_vis_highres/'
def draw_gt_bev_on_feature(gt_bboxes_3d, gt_label_list, img_metas, bev_feat_list,feat_save_root):
    # import pdb; pdb.set_trace()
    img_name = img_metas[0]['scene_token'] + '.png'
    bev_feat = bev_feat_list[0][0,:,:,:]    # c,h,w
    bev_feat = torch.mean(bev_feat,0,keepdim=True)  #1,h,w
    bev_feat = bev_feat.permute(1,2,0)
    bev_feat_vis = bev_feat.clone().detach().cpu().numpy()
    bev_feat_vis_color = cv2.cvtColor(bev_feat_vis, cv2.COLOR_GRAY2BGR) #h,w,3

    raw_img = bev_feat.clone().detach().cpu().numpy()
    raw_img = img_pro_shiyu(raw_img)
    raw_img = cv2.cvtColor(raw_img, cv2.COLOR_GRAY2BGR) #h,w,3
    bev_mask = gt_bboxes_3d[0].masks_list   # num_mask, h, w
    gt_label = gt_label_list[0]
    gt_label_cpu = gt_label.clone().detach().cpu().numpy()
    for i in range(len(bev_mask)):
        single_instance_mask = (bev_mask[i]).astype(bool)    #h,w
        # single_instance_mask = np.expand_dims(single_instance_mask,2).repeat(3,axis=2)
        label = gt_label_cpu[i]
        COLOR = LABEL2COLOR[label]
        bev_feat_vis_color[single_instance_mask] = COLOR
    result = np.hstack([raw_img,bev_feat_vis_color])
    feat_save_path = feat_save_root + img_name
    raw_save_path = feat_save_root + 'raw_img' + img_name
    cv2.imwrite(feat_save_path, result)
    # cv2.imwrite(raw_save_path, raw_img)

def draw_gt_img(mask_list, gt_label_list):
    # bg 是白色
    gt_img = np.ones([200,100,3]) * 255
    gt_labels = gt_label_list.clone().detach().cpu().numpy()
    # import pdb; pdb.set_trace()
    for i in range(len(mask_list)):
        label = gt_labels[i]
        COLOR = LABEL2COLOR[label]
        single_instance_mask = mask_list[i].clone().detach().cpu().numpy().astype(bool)
        gt_img[single_instance_mask] = COLOR
    return gt_img

def draw_gt_bev_on_feature_w_pred_low_res(gt_bboxes_3d, gt_label_list, pts_filename, bev_feat_list, pred_img, feat_save_root, pv_img=None):
    gt_new_size = [600,1200]
    Car_COLOR = [255,255,0]
    Car_position = [100,50]
    # Car_position = [600,300]
    car = cv2.imread('figs/car.png',1)
    car_resize = cv2.resize(car, [8,10], interpolation=cv2.INTER_LINEAR)
    car_img = np.zeros([1200,600,3])
    # x,y = 300,600
    x,y = 50,100
    # import pdb; pdb.set_trace()
    car_resize = cv2.flip(cv2.transpose(car_resize), 1)
    car_img[y:y + 8, x:x + 10,:] = car_resize

    img_name = pts_filename + '.png'
    bev_feat = bev_feat_list[0][0,:,:,:]    # c,h,w
    bev_feat = torch.mean(bev_feat,0,keepdim=True)  #1,h,w
    bev_feat = bev_feat.permute(1,2,0)
    bev_feat_vis = bev_feat.clone().detach().cpu().numpy()
    bev_feat_vis_color = cv2.cvtColor(bev_feat_vis, cv2.COLOR_GRAY2BGR) #h,w,3

    gt_img = np.ones([200,100,3])*255

    raw_img = bev_feat.clone().detach().cpu().numpy()
    raw_img = img_pro_shiyu(raw_img)
    raw_img = cv2.cvtColor(raw_img, cv2.COLOR_GRAY2BGR) #h,w,3
    bev_mask = gt_bboxes_3d[0].masks_list   # num_mask, h, w
    gt_label = gt_label_list[0]
    gt_label_cpu = gt_label.clone().detach().cpu().numpy()
    for i in range(len(bev_mask)):
        single_instance_mask = (bev_mask[i]).astype(bool)    #h,w
        # single_instance_mask = np.expand_dims(single_instance_mask,2).repeat(3,axis=2)
        label = gt_label_cpu[i]
        COLOR = LABEL2COLOR[label]
        gt_img[single_instance_mask] = COLOR

    # resize to higher resolution
    # gt_img = cv2.resize(gt_img, gt_new_size, interpolation=cv2.INTER_LINEAR)
    # pred_img = cv2.resize(pred_img, gt_new_size, interpolation=cv2.INTER_LINEAR)

    gt_img[y:y + 8, x:x + 10,:] = car_resize
    pred_img[y:y + 8, x:x + 10,:] = car_resize

    seg = np.zeros([200,3,3])
    # seg = np.zeros([1200,3,3])
    # seg = seg*255
    # import pdb; pdb.set_trace()
    result = np.hstack([gt_img,seg,pred_img])
    # result = np.hstack([raw_img,gt_img,seg,pred_img])
    feat_save_path = feat_save_root + 'low_res' + img_name
    raw_save_path = feat_save_root + 'raw_img' + img_name

    # import pdb; pdb.set_trace()
    result = np.hstack([pv_img, result])
    cv2.imwrite(feat_save_path, result)

def draw_gt_bev_on_feature_w_pred(gt_bboxes_3d, gt_label_list, pts_filename, bev_feat_list, pred_img, feat_save_root, pv_img=None):
    # import pdb; pdb.set_trace()
    # pv_img # [1200,3200]
    gt_new_size = [600,1200]
    Car_COLOR = [255,255,0]
    # Car_position = [100,50]
    Car_position = [600,300]
    car = cv2.imread('figs/car.png',1)
    car_resize = cv2.resize(car, [16,20], interpolation=cv2.INTER_LINEAR)
    car_img = np.zeros([1200,600,3])
    x,y = 300,600
    # import pdb; pdb.set_trace()
    car_resize = cv2.flip(cv2.transpose(car_resize), 1)
    car_img[y:y + 16, x:x + 20,:] = car_resize

    img_name = pts_filename + '.png'
    bev_feat = bev_feat_list[0][0,:,:,:]    # c,h,w
    bev_feat = torch.mean(bev_feat,0,keepdim=True)  #1,h,w
    bev_feat = bev_feat.permute(1,2,0)
    bev_feat_vis = bev_feat.clone().detach().cpu().numpy()
    bev_feat_vis_color = cv2.cvtColor(bev_feat_vis, cv2.COLOR_GRAY2BGR) #h,w,3

    gt_img = np.ones([200,100,3])*255

    raw_img = bev_feat.clone().detach().cpu().numpy()
    raw_img = img_pro_shiyu(raw_img)
    raw_img = cv2.cvtColor(raw_img, cv2.COLOR_GRAY2BGR) #h,w,3
    bev_mask = gt_bboxes_3d[0].masks_list   # num_mask, h, w
    gt_label = gt_label_list[0]
    gt_label_cpu = gt_label.clone().detach().cpu().numpy()
    for i in range(len(bev_mask)):
        single_instance_mask = (bev_mask[i]).astype(bool)    #h,w
        # single_instance_mask = np.expand_dims(single_instance_mask,2).repeat(3,axis=2)
        label = gt_label_cpu[i]
        COLOR = LABEL2COLOR[label]
        gt_img[single_instance_mask] = COLOR

    # resize to higher resolution
    gt_img = cv2.resize(gt_img, gt_new_size, interpolation=cv2.INTER_LINEAR)
    pred_img = cv2.resize(pred_img, gt_new_size, interpolation=cv2.INTER_LINEAR)

    # draw car
    # cv2.rectangle(bev_feat_vis_color, (99, 49), (101, 51), (0,0,255), 2)
    # cv2.rectangle(pred_img, (99, 49), (101, 51), (0,0,255), 2)
    # gt_img = gt_img + car_img
    # pred_img = pred_img + car_img
    # import pdb; pdb.set_trace()
    gt_img[y:y + 16, x:x + 20,:] = car_resize
    pred_img[y:y + 16, x:x + 20,:] = car_resize

    seg = np.zeros([1200,3,3])
    # seg = seg*255
    # import pdb; pdb.set_trace()
    result = np.hstack([gt_img,seg,pred_img])
    # result = np.hstack([raw_img,gt_img,seg,pred_img])
    feat_save_path = feat_save_root + img_name
    raw_save_path = feat_save_root + 'raw_img' + img_name

    # import pdb; pdb.set_trace()
    result = np.hstack([pv_img, result])
    cv2.imwrite(feat_save_path, result)
    # cv2.imwrite(raw_save_path, raw_img)

def draw_pred_bev_on_feature(pred_masks_list, gt_label_list, img_metas, bev_feat_list, feat_save_root):
    # import pdb; pdb.set_trace()
    img_name = img_metas[0]['scene_token'] + '.png'
    bev_feat = bev_feat_list[0][0,:,:,:]    # c,h,w
    bev_feat = torch.mean(bev_feat,0,keepdim=True)  #1,h,w
    bev_feat = bev_feat.permute(1,2,0)
    bev_feat_vis = bev_feat.clone().detach().cpu().numpy()
    bev_feat_vis_color = cv2.cvtColor(bev_feat_vis, cv2.COLOR_GRAY2BGR) #h,w,3

    raw_img = bev_feat.clone().detach().cpu().numpy()
    raw_img = img_pro_shiyu(raw_img)
    raw_img = cv2.cvtColor(raw_img, cv2.COLOR_GRAY2BGR) #h,w,3
    # 取最后一层
    bev_mask = pred_masks_list[-1][0]  # num_query, h, w
    gt_label = gt_label_list[0]
    gt_label_cpu = gt_label.clone().detach().cpu().numpy()
    for i in range(len(bev_mask)):
        single_instance_mask = (bev_mask[i]).astype(bool)    #h,w
        # single_instance_mask = np.expand_dims(single_instance_mask,2).repeat(3,axis=2)
        label = gt_label_cpu[i]
        COLOR = LABEL2COLOR[label]
        bev_feat_vis_color[single_instance_mask] = COLOR
    result = np.hstack([raw_img,bev_feat_vis_color])
    feat_save_path = feat_save_root + 'pred_mask' + img_name
    raw_save_path = feat_save_root + 'raw_img' + img_name
    cv2.imwrite(feat_save_path, result)
    # cv2.imwrite(raw_save_path, raw_img)

# curb=0,0,255
def draw_single_mask(single_mask, COLOR=[0,0,255]):
    # img_save_path = root + img_name
    vis_img = np.ones([200,100,3]) *255
    single_mask_bool = single_mask.clone().detach().cpu().numpy().astype(bool)

    vis_img[single_mask_bool] = COLOR

    return vis_img, single_mask_bool

def get_nerighbor_label(label, rigion_mask, rigion_label):
    '''
        label: label map
        rigion_mask: bool mask for single connected rigion
    '''
    kernel = np.ones((3, 3), np.uint8)
    dila_rigion = cv2.dilate(rigion_mask,kernel)
    neighbor_rigion = label[dila_rigion.astype(bool)]
    # import pdb; pdb.set_trace()
    neighbor_label = np.unique(neighbor_rigion)
    neighbor_label.tolist().remove(rigion_label)
    return neighbor_label

@DETECTORS.register_module()
class MapTRSeg(MVXTwoStageDetector):
    """MapTR.
    Args:
        video_test_mode (bool): Decide whether to use temporal information during inference.
    """

    def __init__(self,
                 use_grid_mask=False,
                 pts_voxel_layer=None,
                 pts_voxel_encoder=None,
                 pts_middle_encoder=None,
                 pts_fusion_layer=None,
                 img_backbone=None,
                 pts_backbone=None,
                 img_neck=None,
                 pts_neck=None,
                 pts_bbox_head=None,
                 img_roi_head=None,
                 img_rpn_head=None,
                 # shiyu add
                 mask_seg_head=None,
                 seg_train_cfg=None,
                 seg_test_cfg=None,
                 train_cfg=None,
                 test_cfg=None,
                 pretrained=None,
                 video_test_mode=False
                 ):

        super(MapTRSeg,
              self).__init__(pts_voxel_layer, pts_voxel_encoder,
                             pts_middle_encoder, pts_fusion_layer,
                             img_backbone, pts_backbone, img_neck, pts_neck,
                             pts_bbox_head, img_roi_head, img_rpn_head,
                             train_cfg, test_cfg, pretrained)
        self.grid_mask = GridMask(
            True, True, rotate=1, offset=False, ratio=0.5, mode=1, prob=0.7)
        self.use_grid_mask = use_grid_mask
        self.fp16_enabled = False

        # temporal
        self.video_test_mode = video_test_mode
        self.prev_frame_info = {
            'prev_bev': None,
            'scene_token': None,
            'prev_pos': 0,
            'prev_angle': 0,
        }

        # shiyu add mask_seg_head initialize
        panoptic_head_ = copy.deepcopy(mask_seg_head)
        panoptic_head_.update(train_cfg=seg_train_cfg)
        panoptic_head_.update(test_cfg=seg_test_cfg)
        # import pdb; pdb.set_trace()
        self.panoptic_head = build_head(panoptic_head_)

        self.num_things_classes = self.panoptic_head.num_things_classes
        self.num_stuff_classes = self.panoptic_head.num_stuff_classes
        self.num_classes = self.panoptic_head.num_classes

    def extract_img_feat(self, img, img_metas, len_queue=None):
        """Extract features of images."""
        B = img.size(0)
        if img is not None:

            # input_shape = img.shape[-2:]
            # # update real input shape of each single img
            # for img_meta in img_metas:
            #     img_meta.update(input_shape=input_shape)

            if img.dim() == 5 and img.size(0) == 1:
                img.squeeze_()
            elif img.dim() == 5 and img.size(0) > 1:
                B, N, C, H, W = img.size()
                img = img.reshape(B * N, C, H, W)
            if self.use_grid_mask:
                img = self.grid_mask(img)

            img_feats = self.img_backbone(img)
            if isinstance(img_feats, dict):
                img_feats = list(img_feats.values())
        else:
            return None
        if self.with_img_neck:
            img_feats = self.img_neck(img_feats)

        img_feats_reshaped = []
        for img_feat in img_feats:
            BN, C, H, W = img_feat.size()
            if len_queue is not None:
                img_feats_reshaped.append(img_feat.view(int(B/len_queue), len_queue, int(BN / B), C, H, W))
            else:
                img_feats_reshaped.append(img_feat.view(B, int(BN / B), C, H, W))
        return img_feats_reshaped

    @auto_fp16(apply_to=('img'), out_fp32=True)
    def extract_feat(self, img, img_metas=None, len_queue=None):
        """Extract features from images and points."""

        img_feats = self.extract_img_feat(img, img_metas, len_queue=len_queue)

        return img_feats

    def forward_pts_train(self,
                          pts_feats,
                          gt_bboxes_3d,
                          gt_labels_3d,
                          img_metas,
                          gt_bboxes_ignore=None,
                          prev_bev=None):
        """Forward function'
        Args:
            pts_feats (list[torch.Tensor]): Features of point cloud branch
            gt_bboxes_3d (list[:obj:`BaseInstance3DBoxes`]): Ground truth
                boxes for each sample.
            gt_labels_3d (list[torch.Tensor]): Ground truth labels for
                boxes of each sampole
            img_metas (list[dict]): Meta information of samples.
            gt_bboxes_ignore (list[torch.Tensor], optional): Ground truth
                boxes to be ignored. Defaults to None.
            prev_bev (torch.Tensor, optional): BEV features of previous frame.
        Returns:
            dict: Losses of each branch.
        """
        # shiyu add: return bev feat list only
        bev_feat_list = self.pts_bbox_head(
            pts_feats, img_metas, prev_bev, only_bev=True)

        # vis feat
        # draw_gt_bev_on_feature(gt_bboxes_3d, gt_labels_3d, img_metas, bev_feat_list)

        # import pdb; pdb.set_trace()
        # shiyu add panoptic_head forward
        # list of [b, num_query, class], [b, num_query, h, w]
        all_cls_scores, all_mask_preds = self.panoptic_head(bev_feat_list, img_metas)

        # check candidate, if in candidate visualize
        pts_filename = img_metas[0]['pts_filename']
        pts_filename = osp.basename(pts_filename)
        pts_filename = pts_filename.replace('__LIDAR_TOP__', '_').split('.')[0]
        # if pts_filename in CANDIDATE:
            # shiyu add: match && visualize
        mask_pred = all_mask_preds[-1][0]
        mask_pred = mask_pred.sigmoid()
        mask_bool = mask_pred > 0.5     # mask bool

        mask_pred_cpu_bool = mask_bool.clone().detach().cpu().numpy().astype(bool)   # num_query, h, w
        # mask_pred_cpu = all_mask_preds[-1][0].clone().detach().cpu().numpy()   # num_query, h, w
        dt_match, gt_match, ious = match_masks(gt_bboxes_3d[0].masks_list, mask_pred_cpu_bool)

        # import pdb; pdb.set_trace()
        pred_mask = draw_ins_w_match(gt_bboxes_3d[0].masks_list, mask_pred_cpu_bool, gt_match, dt_match, gt_labels_3d[0], bev_feat_list)
        pv_img = draw_pv_img(img_metas[0]['filename'])
        pv_img_low_res = draw_pv_img_low_res(img_metas[0]['filename'])
        if pts_filename in CANDIDATE:
            feat_save_root = "/mnt/vepfs/ML/ml-users/shiyu/MapTR_local/mapseg_select_vis_epoch110/"
        else:
            feat_save_root = "/mnt/vepfs/ML/ml-users/shiyu/MapTR_local/mapseg_vis_highres/"

        # 画图
        # draw_gt_bev_on_feature_w_pred(gt_bboxes_3d, gt_labels_3d, pts_filename, bev_feat_list, pred_mask, feat_save_root, pv_img=pv_img)
        # draw_gt_bev_on_feature_w_pred_low_res(gt_bboxes_3d, gt_labels_3d, pts_filename, bev_feat_list, pred_mask, pv_img=pv_img_low_res)

        # import pdb; pdb.set_trace()
        # import pdb; pdb.set_trace()
        # preprocess ground truth
        # gt_labels, gt_masks = self.panoptic_head.preprocess_gt(gt_labels, gt_masks,
        #                                          gt_semantic_seg, img_metas)
        # import pdb; pdb.set_trace()
        # draw_pred_bev_on_feature(all_mask_preds, gt_labels_3d, img_metas, bev_feat_list)

        # shiyu add vis single mask

        # 将mask list从gt中分离出来
        gt_mask_lists = []
        for gt_bbox in gt_bboxes_3d:
            gt_masks = gt_bbox.masks_list
            single_frame_mask_list = []
            for i in range(len(gt_masks)):
                single_mask = gt_masks[i]
                single_mask_tensor = torch.from_numpy(single_mask).to(gt_labels_3d[0].device)
                single_frame_mask_list.append(single_mask_tensor)
            single_frame_mask = torch.stack(single_frame_mask_list,0)
            gt_mask_lists.append(single_frame_mask)

        # shiyu add
        single_mask_test_root = "/mnt/vepfs/ML/ml-users/shiyu/MapTR_local/single_mask_test_root5/"
        gt_mask_vis_single = draw_gt_img(gt_mask_lists[0],gt_labels_3d[0]) # 200,100,3
        outer_mask_img = np.ones([200,100,3]) * 255
        mask_curbs = np.ones([200,100])
        img_curb = np.ones([200,100,3]) * 255
        # mask_lanes_n_cross = np.ones([200,100,3])
        # curb_lines_list = []
        mask_root = single_mask_test_root + pts_filename + '_mask_curb' + ".png"
        for i in range(len(gt_labels_3d[0])):
            # 如果这个ins是curb的话
            if gt_labels_3d[0][i]==2:
                mask_img, mask_bool = draw_single_mask(gt_mask_lists[0][i])
                mask_path = single_mask_test_root + pts_filename + '_mask_curb_{}_'.format(i) + ".png"
                seg = np.zeros([200,3,3])
                mask_curbs[mask_bool] = 0

                # mask_curbs[mask_bool] = 1
        # # 连通域求错了
        # img_curb = np.sum(img_curb,2)   # single channel
        # mask_gray = img_curb > 255      # 有label的地方是0
        # mask_gray = ~mask_curbs     # 有label的地方是0
        mask_curb_root = single_mask_test_root + 'curb_mask.png'
        # cv2.imwrite(mask_curb_root, mask_curbs.astype(np.uint8)*255)
        # 连通域需要轮廓是黑色，值为0，
        # 但是膨胀腐蚀需要轮廓是白色，值为1
        num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(mask_curbs.astype(np.uint8)*255, connectivity=4)
        labels_root = single_mask_test_root + 'labels.png'
        # cv2.imwrite(labels_root, labels.astype(np.uint8)*30)
        # import pdb; pdb.set_trace()
        # 找到curb线所在的label编号
        line_list = []
        for i in range(num_labels):
            single_area = (labels==i)
            union = ~(mask_curbs.astype(bool)) & single_area
            if union.any(): line_list.append(i)

        drivable_area_label = []
        curb_area_label = []

        center_label = labels[100,50]
        center_rigion = (labels==center_label)
        drivable_area_label.append(center_label)

        tmp_list = []
        tmp_list.append(center_label)
        visited_list = []

        while tmp_list:
            current_label = tmp_list.pop()
            if current_label in visited_list: continue
            visited_list.append(current_label)
            if current_label in line_list: continue
            current_area = (labels==current_label)
            tmp_root = single_mask_test_root + 'tmp.png'
            # import pdb; pdb.set_trace()
            # img_curb[current_area] = [0,0,255]
            # cv2.imwrite(tmp_root, img_curb)
            # 邻域的所有标签
            neighbor_label = get_nerighbor_label(labels, current_area.astype(np.uint8), current_label)
            # 相邻连通域是否可行驶是相反的
            if current_label in drivable_area_label:
                neighbor_label_filter = set(neighbor_label).difference(set(drivable_area_label))
                curb_area_label=list(set(curb_area_label).union(neighbor_label_filter))
            elif current_label in curb_area_label:
                neighbor_label_filter = set(neighbor_label).difference(set(curb_area_label))
                drivable_area_label=list(set(drivable_area_label).union(neighbor_label_filter))
            else: print("current label not in any area!")

            tmp_list = list(set(tmp_list).union(set(neighbor_label)))
            # import pdb; pdb.set_trace()
            # print(tmp_list)
            # print("---------------visited list--------------")
            # print(visited_list)

        for i in range(len(curb_area_label)):
            single_curb_label = curb_area_label[i]
            single_curb_mask = (labels==single_curb_label)
            outer_mask_img[single_curb_mask] = [0,0,255]

        for i in range(len(line_list)):
            single_curb_label = line_list[i]
            single_curb_mask = (labels==single_curb_label)
            outer_mask_img[single_curb_mask] = [0,0,255]

        connect_label = cv2.cvtColor(labels.astype(np.float32),cv2.COLOR_GRAY2BGR)*30
        result = np.hstack([gt_mask_vis_single,connect_label,outer_mask_img])

        # 画ped crossing

        cv2.imwrite(mask_root, result)
        import pdb; pdb.set_trace()

        # # if pts_filename in DEBUG_CANDIDATE: import pdb; pdb.set_trace()
        # # shiyu add vis
        # gt_mask_vis_single = draw_gt_img(gt_mask_lists[0],gt_labels_3d[0]) # 200,100,3
        # single_mask_test_root = "/mnt/vepfs/ML/ml-users/shiyu/MapTR_local/single_mask_test_root3/"
        # mask_root = single_mask_test_root + pts_filename + '_mask_curb' + ".png"
        # outer_mask_img = np.ones([200,100,3]) * 255
        # seg = np.zeros([200,3,3])
        # # mask_curbs = np.ones([200,100,3]) * 255
        # for i in range(len(gt_labels_3d[0])):
        #     # 对于一个single instance
        #     if gt_labels_3d[0][i]==2:
        #         mask_img, single_mask_bool = draw_single_mask(gt_mask_lists[0][i])
        #         mask_path = single_mask_test_root + pts_filename + '_mask_curb_{}_'.format(i) + ".png"
        #         seg = np.zeros([200,3,3])

        #         # result_mask = np.hstack([gt_mask_vis_single,seg])
        #         result_mask = np.hstack([gt_mask_vis_single,seg,mask_img])

        #         # 画连通域
        #         # import pdb; pdb.set_trace()
        #         mask_img = np.sum(mask_img,2)   # single channel
        #         mask_gray = mask_img > 255      # 有label的地方是0
        #         # mask_gray = cv2.cvtColor(mask_img.astype(np.float32)/255,cv2.COLOR_BGR2GRAY)
        #         num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(mask_gray.astype(np.uint8), connectivity=4)
        #         # import pdb; pdb.set_trace()
        #         # bev_center = [100,50]
        #         center_label = labels[100,50]
        #         unique_label = np.unique(labels)
        #         num_labels = len(unique_label)
        #         areas = stats[:,4]
        #         line_ind = np.argmin(areas)      # min area is line

        #         outer_label=0
        #         max_area = 0
        #         for i in range(num_labels):
        #             # if i == line_ind: continue
        #             single_label = unique_label[i]
        #             if single_label == center_label: continue
        #             single_area = areas[i]
        #             if single_area>max_area:
        #                 max_area = single_area
        #                 outer_label = unique_label[i]

        #         outer_mask = labels==outer_label    #取这个mask
        #         # outer_mask_img = np.ones([200,100,3]) * 255
        #         outer_mask_img[outer_mask] = [0,0,255]

        #         # import pdb; pdb.set_trace()
        #         connect_label = cv2.cvtColor(labels.astype(np.float32),cv2.COLOR_GRAY2BGR)*100

        #         result_mask = np.hstack([result_mask, connect_label, outer_mask_img])

        #         # cv2.imwrite(mask_root, np.hstack([gt_mask_vis_single, seg, outer_mask_img]))
        #         if pts_filename in DEBUG_CANDIDATE:
        #             cv2.imwrite(mask_path, result_mask)
        #             import pdb; pdb.set_trace()
        #     # import pdb; pdb.set_trace()

        # import pdb;pdb.set_trace()

        # # loss
        losses = self.panoptic_head.loss(all_cls_scores, all_mask_preds, gt_labels_3d, gt_mask_lists,
                           img_metas)

        # 梯度清零，防止模型更新
        # import pdb; pdb.set_trace()
        new_losses = dict()
        for key,value in losses.items():
            new_losses[key] = value * 0.0

        # import pdb; pdb.set_trace
        return new_losses
        # return losses

        # loss_inputs = [gt_bboxes_3d, gt_labels_3d, outs]
        # losses = self.pts_bbox_head.loss(*loss_inputs, img_metas=img_metas)
        # return losses

    def forward_dummy(self, img):
        dummy_metas = None
        return self.forward_test(img=img, img_metas=[[dummy_metas]])

    def forward(self, return_loss=True, **kwargs):
        """Calls either forward_train or forward_test depending on whether
        return_loss=True.
        Note this setting will change the expected inputs. When
        `return_loss=True`, img and img_metas are single-nested (i.e.
        torch.Tensor and list[dict]), and when `resturn_loss=False`, img and
        img_metas should be double nested (i.e.  list[torch.Tensor],
        list[list[dict]]), with the outer list indicating test time
        augmentations.
        """
        if return_loss:
            return self.forward_train(**kwargs)
        else:
            return self.forward_test(**kwargs)

    def obtain_history_bev(self, imgs_queue, img_metas_list):
        """Obtain history BEV features iteratively. To save GPU memory, gradients are not calculated.
        """
        self.eval()

        with torch.no_grad():
            prev_bev = None
            bs, len_queue, num_cams, C, H, W = imgs_queue.shape
            imgs_queue = imgs_queue.reshape(bs*len_queue, num_cams, C, H, W)
            img_feats_list = self.extract_feat(img=imgs_queue, len_queue=len_queue)
            for i in range(len_queue):
                img_metas = [each[i] for each in img_metas_list]
                # img_feats = self.extract_feat(img=img, img_metas=img_metas)
                img_feats = [each_scale[:, i] for each_scale in img_feats_list]
                prev_bev = self.pts_bbox_head(
                    img_feats, img_metas, prev_bev, only_bev=True)
            self.train()
            return prev_bev

    # @auto_fp16(apply_to=('img', 'points'))
    @force_fp32(apply_to=('img','points','prev_bev'))
    def forward_train(self,
                      points=None,
                      img_metas=None,
                      gt_bboxes_3d=None,
                      gt_labels_3d=None,
                      gt_labels=None,
                      gt_bboxes=None,
                      img=None,
                      proposals=None,
                      gt_bboxes_ignore=None,
                      img_depth=None,
                      img_mask=None,
                      ):
        """Forward training function.
        Args:
            points (list[torch.Tensor], optional): Points of each sample.
                Defaults to None.
            img_metas (list[dict], optional): Meta information of each sample.
                Defaults to None.
            gt_bboxes_3d (list[:obj:`BaseInstance3DBoxes`], optional):
                Ground truth 3D boxes. Defaults to None.
            gt_labels_3d (list[torch.Tensor], optional): Ground truth labels
                of 3D boxes. Defaults to None.
            gt_labels (list[torch.Tensor], optional): Ground truth labels
                of 2D boxes in images. Defaults to None.
            gt_bboxes (list[torch.Tensor], optional): Ground truth 2D boxes in
                images. Defaults to None.
            img (torch.Tensor optional): Images of each sample with shape
                (N, C, H, W). Defaults to None.
            proposals ([list[torch.Tensor], optional): Predicted proposals
                used for training Fast RCNN. Defaults to None.
            gt_bboxes_ignore (list[torch.Tensor], optional): Ground truth
                2D boxes in images to be ignored. Defaults to None.
        Returns:
            dict: Losses of different branches.
        """

        len_queue = img.size(1)
        prev_img = img[:, :-1, ...]
        img = img[:, -1, ...]

        prev_img_metas = copy.deepcopy(img_metas)
        # prev_bev = self.obtain_history_bev(prev_img, prev_img_metas)
        # import pdb;pdb.set_trace()
        prev_bev = self.obtain_history_bev(prev_img, prev_img_metas) if len_queue>1 else None

        img_metas = [each[len_queue-1] for each in img_metas]
        img_feats = self.extract_feat(img=img, img_metas=img_metas)
        losses = dict()
        losses_pts = self.forward_pts_train(img_feats, gt_bboxes_3d,
                                            gt_labels_3d, img_metas,
                                            gt_bboxes_ignore, prev_bev)

        losses.update(losses_pts)
        return losses

    def forward_test(self, img_metas, img=None, **kwargs):
        for var, name in [(img_metas, 'img_metas')]:
            if not isinstance(var, list):
                raise TypeError('{} must be a list, but got {}'.format(
                    name, type(var)))
        img = [img] if img is None else img

        if img_metas[0][0]['scene_token'] != self.prev_frame_info['scene_token']:
            # the first sample of each scene is truncated
            self.prev_frame_info['prev_bev'] = None
        # update idx
        self.prev_frame_info['scene_token'] = img_metas[0][0]['scene_token']

        # do not use temporal information
        if not self.video_test_mode:
            self.prev_frame_info['prev_bev'] = None

        # Get the delta of ego position and angle between two timestamps.
        tmp_pos = copy.deepcopy(img_metas[0][0]['can_bus'][:3])
        tmp_angle = copy.deepcopy(img_metas[0][0]['can_bus'][-1])
        if self.prev_frame_info['prev_bev'] is not None:
            img_metas[0][0]['can_bus'][:3] -= self.prev_frame_info['prev_pos']
            img_metas[0][0]['can_bus'][-1] -= self.prev_frame_info['prev_angle']
        else:
            img_metas[0][0]['can_bus'][-1] = 0
            img_metas[0][0]['can_bus'][:3] = 0

        new_prev_bev, bbox_results = self.simple_test(
            img_metas[0], img[0], prev_bev=self.prev_frame_info['prev_bev'], **kwargs)
        # During inference, we save the BEV features and ego motion of each timestamp.
        self.prev_frame_info['prev_pos'] = tmp_pos
        self.prev_frame_info['prev_angle'] = tmp_angle
        self.prev_frame_info['prev_bev'] = new_prev_bev
        return bbox_results

    def pred2result(self, bboxes, scores, labels, pts, attrs=None):
        """Convert detection results to a list of numpy arrays.

        Args:
            bboxes (torch.Tensor): Bounding boxes with shape of (n, 5).
            labels (torch.Tensor): Labels with shape of (n, ).
            scores (torch.Tensor): Scores with shape of (n, ).
            attrs (torch.Tensor, optional): Attributes with shape of (n, ). \
                Defaults to None.

        Returns:
            dict[str, torch.Tensor]: Bounding box results in cpu mode.

                - boxes_3d (torch.Tensor): 3D boxes.
                - scores (torch.Tensor): Prediction scores.
                - labels_3d (torch.Tensor): Box labels.
                - attrs_3d (torch.Tensor, optional): Box attributes.
        """
        result_dict = dict(
            boxes_3d=bboxes.to('cpu'),
            scores_3d=scores.cpu(),
            labels_3d=labels.cpu(),
            pts_3d=pts.to('cpu'))

        if attrs is not None:
            result_dict['attrs_3d'] = attrs.cpu()

        return result_dict

    # def simple_test_pts(self, x, img_metas, prev_bev=None, rescale=False):
    #     """Test function"""
    #     outs = self.pts_bbox_head(x, img_metas, prev_bev=prev_bev)

    #     bbox_list = self.pts_bbox_head.get_bboxes(
    #         outs, img_metas, rescale=rescale)

    #     bbox_results = [
    #         self.pred2result(bboxes, scores, labels, pts)
    #         for bboxes, scores, labels, pts in bbox_list
    #     ]
    #     # import pdb;pdb.set_trace()
    #     return outs['bev_embed'], bbox_results
    # def simple_test(self, img_metas, img=None, prev_bev=None, rescale=False, **kwargs):
    #     """Test function without augmentaiton."""
    #     img_feats = self.extract_feat(img=img, img_metas=img_metas)

    #     bbox_list = [dict() for i in range(len(img_metas))]
    #     new_prev_bev, bbox_pts = self.simple_test_pts(
    #         img_feats, img_metas, prev_bev, rescale=rescale)
    #     for result_dict, pts_bbox in zip(bbox_list, bbox_pts):
    #         result_dict['pts_bbox'] = pts_bbox
    #     return new_prev_bev, bbox_list

    # shiyu modified
    def simple_test(self, imgs, img_metas, prev_bev=None, **kwargs):
        feats = self.extract_feat(imgs)

        bev_feat_list = self.pts_bbox_head(
            feats, img_metas, prev_bev, only_bev=True)

        mask_cls_results, mask_pred_results = self.panoptic_head.simple_test(
            bev_feat_list, img_metas, **kwargs)

        results = {}
        results['mask_pred'] = mask_pred_results
        results['cls_pred'] = mask_cls_results

        return None, results

@DETECTORS.register_module()
class MapTRSeg_fp16(MapTRSeg):
    """
    The default version BEVFormer currently can not support FP16.
    We provide this version to resolve this issue.
    """
    # @auto_fp16(apply_to=('img', 'prev_bev', 'points'))
    @force_fp32(apply_to=('img','points','prev_bev'))
    def forward_train(self,
                      points=None,
                      img_metas=None,
                      gt_bboxes_3d=None,
                      gt_labels_3d=None,
                      gt_labels=None,
                      gt_bboxes=None,
                      img=None,
                      proposals=None,
                      gt_bboxes_ignore=None,
                      img_depth=None,
                      img_mask=None,
                      prev_bev=None,
                      ):
        """Forward training function.
        Args:
            points (list[torch.Tensor], optional): Points of each sample.
                Defaults to None.
            img_metas (list[dict], optional): Meta information of each sample.
                Defaults to None.
            gt_bboxes_3d (list[:obj:`BaseInstance3DBoxes`], optional):
                Ground truth 3D boxes. Defaults to None.
            gt_labels_3d (list[torch.Tensor], optional): Ground truth labels
                of 3D boxes. Defaults to None.
            gt_labels (list[torch.Tensor], optional): Ground truth labels
                of 2D boxes in images. Defaults to None.
            gt_bboxes (list[torch.Tensor], optional): Ground truth 2D boxes in
                images. Defaults to None.
            img (torch.Tensor optional): Images of each sample with shape
                (N, C, H, W). Defaults to None.
            proposals ([list[torch.Tensor], optional): Predicted proposals
                used for training Fast RCNN. Defaults to None.
            gt_bboxes_ignore (list[torch.Tensor], optional): Ground truth
                2D boxes in images to be ignored. Defaults to None.
        Returns:
            dict: Losses of different branches.
        """

        img_feats = self.extract_feat(img=img, img_metas=img_metas)
        # import pdb;pdb.set_trace()
        losses = dict()
        losses_pts = self.forward_pts_train(img_feats, gt_bboxes_3d,
                                            gt_labels_3d, img_metas,
                                            gt_bboxes_ignore, prev_bev=prev_bev)
        losses.update(losses_pts)
        return losses

    def val_step(self, data, optimizer):
        """
        In BEVFormer_fp16, we use this `val_step` function to inference the `prev_pev`.
        This is not the standard function of `val_step`.
        """

        img = data['img']
        img_metas = data['img_metas']
        img_feats = self.extract_feat(img=img,  img_metas=img_metas)
        prev_bev = data.get('prev_bev', None)
        prev_bev = self.pts_bbox_head(img_feats, img_metas, prev_bev=prev_bev, only_bev=True)
        return prev_bev


#! /usr/bin/env python3

from typing import Any, Optional, Type
import discord
import os
import logging
import csv
import tabulate
from discord import app_commands
from discord.ext.commands.help import HelpCommand

from dotenv import load_dotenv
from discord.ext import commands
from tabulate import tabulate

#import FileBackingStore as store
import SheetsBackingStore as store
import ParamMapper

# initial version based on local on-disk csv file that is read for every operation. no cache here!
CSV_FILE = "test.csv" # DELETE

# setup logging
discord.utils.setup_logging(level=logging.DEBUG)
log = logging.getLogger(os.path.basename(__file__))

def main():
    bot = CSVBot("Taskbot Test Sheet")

    @bot.command()
    async def rows(ctx):
        all_rows = bot.store.values()
        table = tabulate(all_rows, headers=bot.store.fieldnames)
        await ctx.send("```\n" + table + "\n```")

    @bot.command()
    async def cols(ctx):
        #df = []
        #for field in bot.store.fieldnames(): # this is to for a list of single-element lists.
        #    df.append([field])
        table = tabulate(bot.store.fieldnames)
        await ctx.send("```\n" + table + "\n```")

    # https://discordpy.readthedocs.io/en/stable/ext/commands/commands.html#advanced-converters
    @bot.command()
    async def add(ctx, *, params: ParamMapper(CSV_FILE)):
        bot.store.add(params)
        await ctx.send(f'Added row with {params}')

    # uses the same multi-field style as `add`
    # this time to match records in the
    @bot.command()
    async def find(ctx, *, params: ParamMapper(CSV_FILE)):
        result = bot.store.find(params)
        table = tabulate(result, headers=bot.store.fieldnames)
        await ctx.send("```\n" + table + "\n```")

    # RUN the bot
    bot.run()

class CSVBot(commands.Bot):
    def __init__(self, filename: str):
        log.debug("__init__")
        self.store = store.SheetsBackingStore(filename)

        # load the secrets
        load_dotenv()

        # setup the bot
        intents = discord.Intents.default()
        intents.message_content = True
        super().__init__(command_prefix='$', intents=intents)

    def run(self):
        log.debug("run")
        super().run(os.getenv("DISCORD_TOKEN"))

# Handles the "operations" against the CSV file
def get_cols(filename: str):
        with open(filename) as csvfile:
            return csv.DictReader(csvfile).fieldnames

def validate_params(params, expected_fields):
    for key, value in params.items():
        if key in expected_fields:
            print(f"{key}, {value}")
        else:
            print(f"missing key: {key}")

if __name__ == '__main__':
    main()


import socket

s = socket.socket()
print("Socket successfully created")

port = 12345

s.bind(('', port))
print ('port:' + str(port))

s.listen()
print ('socket is listening')

while True:

   c, addr = s.accept()
   print ('Got connection from' + str(addr))

   ip = c.recv(1024)
   ip = ip.decode('utf-8')
   ip = ip.split('+')
   ans = 0
   for i in ip:
    ans += int(i)

   string = 'The sum of ' + str(ip[0]) + ' and ' + str(ip[1]) + 'is ' + str(ans)
   c.send(string.encode('utf-8'))

   c.close()


from rdflib import Graph, RDF, RDFS, OWL, Namespace
import owlrl

EX = Namespace('http://example.org#')

g = Graph()
g.bind('', EX)
NS = {
    '': EX,
    'rdf': RDF,
    'rdfs': RDFS,
}
g.update("""
INSERT DATA {
    :Socrates rdf:type :Human .
    :Human rdfs:subClassOf :Mortal .

    :Socrates :husbandOf :Xantippe .
    :husbandOf rdfs:domain :Man .
    :husbandOf rdfs:range :Woman .
}
""", initNs=NS)

rdfs_engine = owlrl.RDFSClosure.RDFS_Semantics(g, False, False, False)
rdfs_engine.closure()
rdfs_engine.flush_stored_triples()

res = g.query("""
ASK { :Socrates rdf:type :Mortal . }
""", initNs=NS)
print(res.askAnswer)


from pony.orm import Database, PrimaryKey, Required, Set, db_session
from uuid import uuid4 as gid

db = Database()

db.bind(provider='sqlite', filename='db.sqlite', create_db=True)

class Korisnik(db.Entity):
    id= PrimaryKey(str)
    Ime = Required(str)
    Prezime = Required(str)
    Username = Required(str)
    Lozinka = Required(str)
    kolaci = Set("Kolac")

class Kategorija(db.Entity):
    id = PrimaryKey(str)
    Naziv = Required(str)
    kolaci = Set("Kolac")
class Kolac(db.Entity):
    id= PrimaryKey(str)
    Naziv_kolaca = Required(str)
    sastojci=Required(str)
    priprema=Required(str)
    fotografija=Required(str)
    korisnici = Required(Korisnik)
    kategorije = Required(Kategorija)

db.generate_mapping(check_tables=True, create_tables=True)


from typing import List
from core.context import Context
import core.error as error
import core.config as config
import core.parse.base as parser_base
import re

TOKENIZE_PATTERN = re.compile(r"(\W|\s)")
USELSESS = ' '

def tokienize_str(string) -> List[str]:
    return re.split(TOKENIZE_PATTERN, string)

def tokienize_line(line):
    line.tokenized = tokienize_str(line.line)
    return line

def remove_meaningless_tokens_list(tokens_list):
    return [str(token) for token in tokens_list if token not in USELSESS]

def remove_meaningless_tokens(line):
    line.tokenized = remove_meaningless_tokens_list(line.tokenized)
    return line

def join_sign_expressions(line):
    tokens = line.tokenized
    output = list()
    i = 0
    while i < len(tokens):
        if tokens[i] == '-':
            try:
                parser_base.get_value(tokens[i+1])
                output.append(f"-{tokens[i+1]}")
                i += 2
                continue
            except:
                pass
        output.append(tokens[i])
        i += 1
    line.tokenized = output
    return line

def join_string(line):
    """
    Joins tokens between euotes:
    `['a', 'b', '"', ' ', "c". '"'] => ['a', 'b', '" c"']
    """
    tokens = line.tokenized
    state = False
    output = list()
    joined = ""
    for i in range(len(tokens)):
        if tokens[i] == '"':
            if state:
                output.append(f'"{joined}"')
                joined = ""
            state = not state
            continue
        if state:
            joined += tokens[i]
        else:
            output.append(tokens[i])
    if state:
        raise error.ParserError(line.line_index_in_file, 'Expected \'"\'')
    line.tokenized = output
    return line

def tokenize(program, context: Context):
    for line_obj in program:
        line_obj = remove_meaningless_tokens(join_sign_expressions(join_string(tokienize_line(line_obj))))
    return program, context


"""
The main file of the Stock Prediction application. MainWindow class defined here.

"""
import json
import sys

import matplotlib
matplotlib.use("Qt5Agg")  # use the Qt5 Aggregator for plotting matplotlib graphs to the Qt GUI

from PyQt5.QtWidgets import *

from plot import GraphPane
from widgets import StockSelector, TimePeriodsChooser, PlotStockButton

class ConfigurationModel:
    """
    Abstraction for the last used configuration (stock names and time periods)
    """
    def __init__(self):
        self.stock_1_code = ""
        self.stock_1_index = ""
        self.stock_2_code = ""
        self.stock_2_index = ""
        self.time_periods = []

    def load(self):
        """
        Loads the configuration from the file located in the same directory called 'config.json'

        :return: None
        """
        try:
            with open('config.json', 'r') as file:
                json_dict = json.load(file)

            self.stock_1_code = json_dict['stock_1']['code']
            self.stock_1_index = json_dict['stock_1']['index']
            self.stock_2_code = json_dict['stock_2']['code']
            self.stock_2_index = json_dict['stock_2']['index']
            self.time_periods = json_dict['time_periods']
        except FileNotFoundError:
            print('no config file found')

    def save(self):
        """
        Saves the configuration to the file located in the same directory called 'config.json'

        :return: None
        """
        json_dict = {
            'stock_1': {
                'code': self.stock_1_code,
                'index': self.stock_1_index
            },
            'stock_2': {
                'code': self.stock_2_code,
                'index': self.stock_2_index
            },
            'time_periods': self.time_periods
        }
        with open('config.json', 'w+') as file:
            json.dump(json_dict, file)  # serialize as json and save

class GraphPaneCollection(QHBoxLayout):
    """
    Layout to hold multiple graph panes to show graphs with different time periods and information about those stocks.
    """
    def __init__(self, n_graphs, model):
        """
        Constructor for GraphPaneCollection.

        Initializes a GraphPaneCollection with n_graphs objects of type GraphPane.

        :param n_graphs: The number of 'GraphPane'(s) to create.
        :param model: The ConfigurationModel to use when updating GraphPanes.
        """
        super().__init__()

        self.graphs = []
        self.model = model

        for _ in range(n_graphs):
            gp = GraphPane(model)
            self.graphs.append(gp)
            self.addLayout(gp)  # add the graph pane to the current layout

class ApplicationWindow(QMainWindow):
    """
    Class representing the main application window that all other windows and widgets have as a parent.
    """
    def __init__(self, *args, **kwargs):
        """
        Constructor for ApplicationWindow.

        Initializes the QMainWindow base class, loads the app's ConfigurationModel
        and then invokes init_ui to set up our application's widgets.

        :param args: positional arguments to pass to the QMainWindow constructor
        :param kwargs: keyword arguments to pass to the QMainWindow constructor
        """
        super().__init__(*args, **kwargs)

        # set the number of graphs the application will display
        self.n_graphs = 3

        # set up the configuration model and load from file (if possible)
        self.model = ConfigurationModel()
        self.model.load()

        # create the widgets for this application.
        self.init_ui()

    def init_ui(self):
        """
        Method called during object construction to set up our application's widgets.

        :return: None
        """

        # set window size and title
        self.setGeometry(300, 300, 800, 800)
        self.setWindowTitle('Stocks Visualising')

        # set up 'exit' action
        exit_Action = QAction('Exit', self)
        exit_Action.setShortcut('Ctrl + Q')
        exit_Action.setStatusTip('Exit from Application')
        exit_Action.triggered.connect(self.close)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exit_Action)

        # create a main widget to act as a parent for all other widgets
        mainWidget = QWidget()

        # create the main layout of the application to be a VBox layout
        layout = QVBoxLayout()

        # ==== APP LAYOUT SECTIONS HERE ====

        # Add stock choosers for stocks 1 and 2
        stock_1_chooser = StockSelector(1, self.model)
        stock_2_chooser = StockSelector(2, self.model)

        layout.addLayout(stock_1_chooser)
        layout.addLayout(stock_2_chooser)

        # add a time period chooser
        time_period_chooser = TimePeriodsChooser(self.n_graphs, self.model)
        layout.addLayout(time_period_chooser)

        # create the graph pane collection (but don't add, we want this below the plot stock button defined below)
        graph_pane_collection = GraphPaneCollection(self.n_graphs, self.model)

        # create and add the plot stock button (which references the graph_pane_collection)
        plot_stock_button = PlotStockButton(graph_pane_collection, time_period_chooser, stock_1_chooser, stock_2_chooser)
        layout.addWidget(plot_stock_button)

        # add the graph pane collection, created above, to the layout
        layout.addLayout(graph_pane_collection)

        # === END APP LAYOUT SECTIONS ====

        # set the layout of the parent widget to the application layout we have created
        mainWidget.setLayout(layout)

        # set the app's central widget to said parent widget
        self.setCentralWidget(mainWidget)

if __name__ == '__main__':
    # if we are executing this file...

    # create a QApplication
    app = QApplication(sys.argv)

    # create an Application Window
    a_Window = ApplicationWindow()

    # enable one of the following:
    a_Window.show()
    # window.showFullScreen()

    # run the app and return the exit status code of the QApplication
    sys.exit(app.exec_())


# this porgramme describes how to loop through dictonary

thisDict3={
    "Name":"test2",
    "Designation" :"Manager",
    "Age":34
}

# looping  thourgh dic and printing

for x in thisDict3:
    print(x)

print("*************")
 #Print all values in the dictionary, one by one:

for x in thisDict3:
     print(thisDict3[x])


""" standard """
from random import randint
import re

""" custom """
from examples.working_init import *

#
# CHANGE FOR YOUR TESTING ENVIRONMENT
# - These adversaries must be created before running this script
#
owners = ['Example Community']  # org or community
lu_id = 5  # adversary id for loop update
mu_id = 6  # adversary id for manual update
# dl_id = 999999  # threat id to delete
email_id = 17  # email resource id to associate with adversary
email_address = 'notsobad@gmail.com'  # email address to associate to adversary
rn = randint(1, 1000)  # random number generator for testing

def main():
    """ """
    # set threat connect log (tcl) level
    tc.set_tcl_file('log/tc.log', 'debug')
    tc.set_tcl_console_level('critical')

    # (Required) Instantiate a Resource Object
    resources = tc.adversaries()

    # (Optional) Filters can be added here if required to narrow the result set.
    filter1 = resources.add_filter()
    filter1.add_owner(owners)

    # (Optional) retrieve all results
    resources.retrieve()

    # (Optional) iterate through all results if retrieve was used above
    for res in resources:

        # (Optional) match a particular resource by ID, Name or any other supported attribute.
        if res.get_id() == lu_id:
            #
            # update resource if required
            #
            res.set_name('LU Adversary #{0}'.format(rn))

            #
            # working with indicator associations
            #

            # (Optional) get all indicator associations
            resources.get_indicator_associations(res)
            for association in res.association_objects_indicators:
                # add delete flag to all indicator association that have a confidence under 10
                if association.get_confidence() < 10:
                    res.disassociate(association.resource_type, association.get_indicator())

            # associate an indicator
            res.associate(ResourceType.EMAIL_ADDRESSES, email_address)

            #
            # working with group associations
            #

            # (Optional) get all group associations
            resources.get_group_associations(res)
            for association in res.association_objects_groups:
                # add delete flag to all group association that match DELETE
                if re.findall('Loop', association.get_name()):
                    res.disassociate(association.resource_type, association.get_id())

            # associate a group
            res.associate(ResourceType.EMAILS, email_id)

            #
            # working with victim associations
            #

            # (Optional) get all victim associations
            resources.get_victim_associations(res)
            for association in res.association_objects_victims:
                print(association)
                # add delete flag to all group association that match DELETE
                # if re.findall('Loop', association.get_name()):
                #     res.disassociate(association.resource_type, association.get_id())

            # res.associate(ResourceType.VICTIMS, 747266)

            #
            # working with attributes
            #

            # (Optional) get all attributes associated with this resource
            resources.get_attributes(res)
            for attribute in res.attribute_objects:
                # add delete flag to all attributes that have 'test' in the value.
                if re.findall('test', attribute.get_value()):
                    res.delete_attribute(attribute.get_id())
                # add update flag to all attributes that have 'update' in the value.
                if re.findall('update', attribute.get_value()):
                    res.update_attribute(attribute.get_id(), 'updated attribute #{0}'.format(rn))
            # (Optional) add attribute to resource with type and value
            res.add_attribute('Description', 'test attribute #{0}'.format(rn))

            #
            # working with tags
            #

            # (Optional) get all tags associated with this resource
            resources.get_tags(res)
            for tag in res.tag_objects:
                # add delete flag to all tags that have 'DELETE' in the name.
                if re.findall('DELETE', tag.get_name()):
                    res.delete_tag(tag.get_name())
            # (Optional) add tag to resource
            res.add_tag('DELETE #{0}'.format(rn))
        #
        # delete resource if required
        #

        # (Optional) add delete flag to any resource that has 'DELETE' in the name.
        if re.findall('DELETE', res.get_name()):
            res.delete()

    #
    # add resource if required (will be delete on next run)
    #
    resource = resources.add('DELETE #{0}'.format(rn))

    # (Optional) add attribute to newly created resource
    resource.add_attribute('Description', 'Delete Example #{0}'.format(rn))

    # (Optional) add tag to newly created resource
    resource.add_tag('TAG #{0}'.format(rn))

    #
    # update resource if required
    #

    # (Optional) a resource can be updated directly by using the resource id.
    resource = resources.update(mu_id)
    resource.set_name('MU Adversary #{0}'.format(rn))

    # (Optional) add attribute to newly created resource
    resource.add_attribute('Description', 'Manual Update Example #{0}'.format(rn))

    # (Optional) add tag to newly created resource
    resource.add_tag('TAG #{0}'.format(rn))

    #
    # delete resource
    #

    # (Optional) a resource can be deleted directly by using the resource id.
    # resources.delete(dl_id)

    # (Required) commit all changes above.  No changes are made until the commit phase.
    try:
        resources.commit(owners)
    except RuntimeError as e:
        print(e)

    # (Optional) iterate through the result sets after changes.
    for res in resources:
        print(res)

    # (Optional) display a commit report of all API actions performed
    print(tc.report.stats)

    # display any failed api calls
    for fail in tc.report.failures:
        print(fail)

if __name__ == "__main__":
    main()
    sys.exit()


import random

from rest_framework import status
from rest_framework.decorators import permission_classes, api_view
from rest_framework.permissions import AllowAny, IsAuthenticated, BasePermission, SAFE_METHODS
from rest_framework.response import Response
from rest_framework.views import APIView

from lookups.api.v1.serializers import IngredientsSerializer, CupUnitSerializer
from lookups.models import IngredientsUnit, Ingredients, Cup, CupUnit
from machines.models import Sensor, Timer, Unit
from reports.models import ReportRefill
from .serializers import ReadingSensorSerializer, UnitSerializer

class ReadOnly(BasePermission):
    def has_permission(self, request, view):
        return request.method in SAFE_METHODS

class SensorView(APIView):

    @permission_classes((AllowAny,))
    def post(self, request):
        sensor = Sensor.objects.get(serial_number=request.data.get("sensor"))
        reading_data = {"value": str(request.data.get("value")),
                        "sensor": sensor.pk}
        serializer = ReadingSensorSerializer(data=reading_data)
        if serializer.is_valid():
            serializer.save()
            return Response(data={"message": 1}, status=status.HTTP_200_OK)
        return Response(data={"message": 0}, status=status.HTTP_400_BAD_REQUEST)

class UnitView(APIView):

    @permission_classes((AllowAny,))
    def get(self, request):
        lang = request.headers["lang"]
        response_data = {
            "state": True,
            "message": "Ok",
            "data": {"catList": []}
        }
        units = Unit.objects.all()
        serializer = UnitSerializer(instance=units, many=True, lang=lang, context={"request": request})
        response_data["data"] = serializer.data
        return Response(data=response_data, status=status.HTTP_200_OK)

class TimerView(APIView):

    @permission_classes((AllowAny,))
    def post(self, request):
        try:
            timer = Timer.objects.get(serial_number=request.data.get("timer"))
            timer.value = request.data.get("value")
            timer.save()
            return Response(data={"message": 1}, status=status.HTTP_200_OK)
        except:
            return Response(data={"message": 0}, status=status.HTTP_400_BAD_REQUEST)

class CupUnitView(APIView):
    permission_classes = [IsAuthenticated | ReadOnly]

    def get(self, request, operation, unit_id):
        response_data = {
            "state": True,
            "message": "Ok",
            "data": []
        }
        if operation == "show":
            cups = CupUnit.objects.filter(unit=unit_id)
            for c in cups:
                cup_obj = Cup.objects.get(pk=c.pk)
                cup_data = CupUnitSerializer(instance=c)
                temp = cup_data.data
                temp['size'] = cup_obj.size
                del temp['unit']
                del temp['cup']
                response_data['data'].append(temp)
        return Response(data=response_data, status=status.HTTP_200_OK)

    def post(self, request, operation, unit_id):
        response_data = {
            "state": True,
            "message": "Ok",
        }
        if operation == 'refill':
            for c in request.data.get("cups"):
                cup_unit_obj = CupUnit.objects.get(cup=c["id"], unit=unit_id)
                unit = Unit.objects.get(pk=unit_id)
                cup = Cup.objects.get(pk=c["id"])
                plus_value = c["value"] - cup_unit_obj.current_tank_size
                print(cup.quantity_stock)
                cup.quantity_stock -= plus_value
                print(cup.quantity_stock)
                report = ReportRefill(user=request.user, unit=unit, cup=cup,
                                      before=cup_unit_obj.current_tank_size, after=c["value"])
                cup_unit_obj.current_tank_size = c["value"]
                cup.save()
                cup_unit_obj.save()
                report.save()
        return Response(data=response_data, status=status.HTTP_200_OK)

class IngredientUnitView(APIView):
    permission_classes = [IsAuthenticated | ReadOnly]

    def get(self, request, operation, unit_id):
        response_data = {
            "state": True,
            "message": "Ok",
            "data": []
        }
        if operation == "show":
            lang = request.headers["lang"]
            ingredients = IngredientsUnit.objects.filter(unit=unit_id)
            for i in ingredients:
                ingredient_obj = Ingredients.objects.get(pk=i.ingredient.pk)
                ingredient_data = IngredientsSerializer(instance=ingredient_obj, lang=lang,
                                                        context={"request": request})
                temp = ingredient_data.data
                temp['maxTankSize'] = i.max_tank_size
                temp['minTankSize'] = i.min_tank_size
                temp['currentTankSize'] = i.current_tank_size
                del temp['unit']
                del temp['product']
                response_data['data'].append(temp)
        return Response(data=response_data, status=status.HTTP_200_OK)

    def post(self, request, operation, unit_id):
        response_data = {
            "state": True,
            "message": "Ok",
        }
        if operation == 'refill':
            for i in request.data.get("ingredients"):
                ingredient_unit_obj = IngredientsUnit.objects.get(ingredient=i["id"], unit=unit_id)
                unit = Unit.objects.get(pk=unit_id)
                ingredient = Ingredients.objects.get(pk=i["id"])
                plus_value = i["value"] - ingredient_unit_obj.current_tank_size
                ingredient.quantity_stock -= plus_value
                report = ReportRefill(user=request.user, unit=unit, ingredient=ingredient,
                                      before=ingredient_unit_obj.current_tank_size, after=i["value"])
                ingredient_unit_obj.current_tank_size = i["value"]
                ingredient.save()
                ingredient_unit_obj.save()
                report.save()

        return Response(data=response_data, status=status.HTTP_200_OK)

@api_view(['GET'])
@permission_classes((AllowAny,))
def home(request):
    response_data = {
        "state": True,
        "message": "Ok",
        "data": {}
    }
    lang = request.headers["lang"]
    units = Unit.objects.all()
    unit_data = UnitSerializer(instance=units, many=True, lang=lang, context={"request": request})
    for d in unit_data.data:
        d['totalCups'] = 100
        d['availableCups'] = random.randint(0, 75)
        d['totalGrad'] = 100
        d['availableGrad'] = random.randint(0, 75)
        d['orders'] = 12345
        d['transactions'] = 20145
    response_data['data'] = unit_data.data
    return Response(data=response_data, status=status.HTTP_200_OK)


from django.http import HttpResponse
from datetime import datetime
from django.utils.timezone import make_aware

def index(request):
    response = HttpResponse("index首页")
    expires = datetime(year=2019,month=10,day=1,minute=0,second=0)
    # response.set_cookie('user_id','abc123456',max_age=180)
    response.set_cookie('user_id','abc123456',max_age=180)
    return response

def del_cookie(request):
    response = HttpResponse('delete_cookie')
    response.delete_cookie('user_id')
    return response

def my_list(request):
    cookies = request.COOKIES
    username = cookies.get('user_id')
    return HttpResponse(username)

def cms_view(request):
    cookies = request.COOKIES
    username = cookies.get('user_id')
    return HttpResponse(username)


from collections import deque

N = int(input())
board = [ list(input()) for _ in range(N) ]
board2 = [ row[:] for row in board ]
vis = [[False]*N for _ in range(N)]
dir = [ [0,1], [0,-1], [1,0], [-1,0] ]
ans = [0, 0]

def BFS (i, j, arr) :
  q = deque()
  q.append([i , j, arr[i][j]])
  vis[i][j] = True
  while q :
    curR, curC, curColor = q.popleft()
    for r, c in dir :
      nxtR = curR + r
      nxtC = curC + c
      if nxtR < 0 or nxtC < 0 or nxtR >= N or nxtC >= N  or vis[nxtR][nxtC] : continue
      if curColor == arr[nxtR][nxtC] :
        vis[nxtR][nxtC] = True
        q.append([ nxtR, nxtC, arr[nxtR][nxtC] ])
  return 1

for i in range(N) :
  for j in range(N) :
    if board[i][j] == 'G' : board2[i][j] = 'R'
    if vis[i][j] : continue
    ans[0] += BFS(i,j, board)

vis = [[False]*N for _ in range(N)]
for a in range(N) :
  for b in range(N) :
    if vis[a][b] : continue
    ans[1] += BFS(a,b, board2)

print(*ans)


# Regular Polygon Fractals using iteration method
# FB - 201003206
from PIL import Image
import math
imgx = 512
imgy = 512
maxIt = 16 # max iterations allowed

for n in range(3, 9):
    image = Image.new("RGB", (imgx, imgy))
    m = n % 2
    p = float(n - m - 2.0) / 4.0 + 2.0
    q = p - 1.0
    af = 2.0 * math.pi / n

    for ky in range(imgy):
        for kx in range(imgx):
            x = kx * 2.0 / (imgx-1.0) - 1.0
            y = ky * 2.0 / (imgy-1.0) - 1.0
            for i in range(maxIt):
                a = math.atan2(y, x)
                if a < 0:
                    a = 2.0 * math.pi - math.fabs(a)
                k = int(a / af) % n
                x = x * p - math.cos(k * af + af / 2.0) * q
                y = y * p - math.sin(k * af + af / 2.0) * q
                if math.hypot(x, y) > 1.0:
                    break

            r = i % 4 * 64
            g = i % 8 * 32
            b = i % 16 * 16
            image.putpixel((kx, ky), b * 65536 + g * 256 + r)

    image.save("rpItfr_" + str(n) + ".png", "PNG")


'''Exercício Python 062: Melhore o DESAFIO 061, perguntando para o usuário se ele quer mostrar mais alguns
termos. O programa encerrará quando ele disser que quer mostrar 0 termos.'''

print('Gerador de PA')
print('-=' * 20)
firstTerm = int(input('Primeiro termo: '))
ratio = int(input('Razão da PA: '))
term = firstTerm
counter = 1
moreTerms = 10
totalTerms = 0
while moreTerms != 0:
    totalTerms = totalTerms + moreTerms
    while counter <= totalTerms:
            print('{}'.format(term), end=' > ')
            term = term + ratio
            counter = counter + 1
    print('Pausa')
    moreTerms = int(input('Quantos termos você quer mostrar a mais? '))
print('Progressão finalizada com {} termos exibidos.'.format(totalTerms))


import pytest

from src.chess_utils.game import ChessGame, compute_delta_time

class TestGame:
    @staticmethod
    def test_game_finds_basic_attributes():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/loss_game_example.pgn")
        assert game is not None
        assert len(game) == 1
        for (k, v) in game[0].players.items():
            assert k in {"white", "black"}
            assert v.name in {"carequinha", "HardyJ"}
            assert v.rating in {1976, 1745}
        assert game[0].eco == "A43"

    @staticmethod
    def test_import_game_with_non_standard_format():
        with pytest.warns(Warning) as w:
            ChessGame.load_pgn_file("tests/unit/pgn_files/bad_file.pgn")
        assert len(w) > 0
        for wa in w:
            assert "'PGNGame' object has no attribute" in wa.message.args[0]

    @staticmethod
    def test_delta_time_computation():
        time = "00:00:01"
        expected = 1
        actual = compute_delta_time(time)
        assert actual == expected

        time = "00:01:00"
        expected = 60
        actual = compute_delta_time(time)
        assert actual == expected

        time = "01:00:00"
        expected = 3600
        actual = compute_delta_time(time)
        assert actual == expected

    @staticmethod
    def test_check_result():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/loss_game_example.pgn")
        assert game[0].get_result("carequinha") == 'LOSS'

        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        assert game[0].get_result('carequinha') == 'WIN'

        game = ChessGame.load_pgn_file("tests/unit/pgn_files/draw_game_example.pgn")
        assert game[0].get_result('carequinha') == 'DRAW'

        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        with pytest.warns(Warning) as w:
            game[0].get_result('abc')
        assert len(w) == 1
        assert w[0].message.args[0] == "That player is not in this game"

    @staticmethod
    def test_rating_difference():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/draw_game_example.pgn")
        assert game[0].get_rating_diff('carequinha') == 1863 - 1950

        game = ChessGame.load_pgn_file("tests/unit/pgn_files/loss_game_example.pgn")
        assert game[0].get_rating_diff('carequinha') == 1976 - 1745

    @staticmethod
    def test_get_player_names():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        for n in game[0].get_player_names():
            assert n in ('lorenzm', 'carequinha')

    @staticmethod
    def test_get_player_colors():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        assert game[0].get_player_color('carequinha') == 'white'

        game = ChessGame.load_pgn_file("tests/unit/pgn_files/draw_game_example.pgn")
        assert game[0].get_player_color('carequinha') == 'black'

        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        with pytest.raises(UserWarning) as e:
            game[0].get_player_color('abc')
        assert e.typename == 'UserWarning'
        assert str(e.value.args[0]) == 'No such player in this game.'

    @staticmethod
    def test_get_opponent_colors():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        assert game[0].get_opponent_color('carequinha') == ['black']

    @staticmethod
    def test_get_player_rating():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        rating = game[0].get_player_rating('carequinha')
        assert isinstance(rating, int)
        assert rating == 1912

    @staticmethod
    def test_get_opponent_rating():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        rating = game[0].get_opponent_rating('carequinha')
        assert rating == [2020]

        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        with pytest.raises(UserWarning) as e:
            game[0].get_opponent_rating('abc')
        assert e.typename == 'UserWarning'
        assert str(e.value.args[0]) == 'No such player in this game.'

    @staticmethod
    def test_parse_month_years():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        time = game[0].parse_month_year()
        assert time == 2019.75
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/loss_game_example.pgn")
        time = game[0].parse_month_year()
        assert time == 2016

    @staticmethod
    def test_parse_hours():
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/win_game_example.pgn")
        time = game[0].parse_hours()
        assert time == 12
        game = ChessGame.load_pgn_file("tests/unit/pgn_files/loss_game_example.pgn")
        time = game[0].parse_hours()
        assert time == 15


import pyautogui

width, height = pyautogui.size()  # 屏幕的宽度和高度
print(width, height)

currentMouseX, currentMouseY = pyautogui.position()  # 鼠标当前位置
print(currentMouseX, currentMouseY)

# 控制鼠标移动,duration为持续时间
for i in range(3):
    pyautogui.moveTo(100, 100, duration=0.25)  # 移动到 (100,100)
    pyautogui.moveTo(300, 100, duration=0.25)
    pyautogui.moveTo(400, 400, duration=0.25)
    pyautogui.moveTo(100, 200, duration=0.25)

    # 按住鼠标左键，把鼠标拖拽到(100, 200)位置
pyautogui.dragTo(100, 200, button='left')
# 按住鼠标左键，用2秒钟把鼠标拖拽到(300, 400)位置
pyautogui.dragTo(300, 400, 2, button='left')
# 按住鼠标左键，用0.2秒钟把鼠标向上拖拽
pyautogui.dragRel(0, -60, duration=0.2)


import os

def gather_credits(maximum_points_needed, *args):
    points_current = 0
    courses_dict = {}

    for course, points in args:

        if points_current >= maximum_points_needed:
            break

        if course not in courses_dict.keys():
            points_current += points
            courses_dict[course] = [points]

        if points_current >= maximum_points_needed:
            break

    final_print = []

    if points_current >= maximum_points_needed:
        final_print.append(f"Enrollment finished! Maximum credits: {points_current}.")
        final_print.append(f"Courses: {', '.join([key for key in sorted(courses_dict.keys(),key=lambda k: k[0])])}")

    else:
        final_print.append(
            f"You need to enroll in more courses! You have to gather {maximum_points_needed - points_current} credits more.")

    return os.linesep.join(final_print)

print(gather_credits(
    80,
    ("",0),
))

print()
print(gather_credits(
    80,
    ("Advanced", 30),
    ("Basics", 27),
    ("Fundamentals", 27),
))

print()
print(gather_credits(
    60,
    ("Basics", 27),
    ("Fundamentals", 27),
    ("Advanced", 30),
    ("Web", 30)
))