#-*- coding-f:utf-8 -*-

import math
import matplotlib.pyplot as plt
import numpy as np

def resize(number):
    if (number < -0.5):
        number+=1
    elif (number > 0.5):
        number -=1

    return number

def read_wldata_oneday(filename):
    mapsat_wl = {}
    with open(filename) as wlfile:
        for i in wlfile:
            if i[0] != " ":
                continue
            temp = i.split()
            sat = temp[0]
            value = float(temp[1])
            mapsat_wl[sat] = resize(value)

    return mapsat_wl

def read_wldata_ndays(filelist, doylist,satsys="G",satlist = None):
    """
    read the wide-lane data from n days
    """

    # default satlist is all sat list
    # TODO:define the satlist in gnss_sat.py
    if not satlist:
        satlist = []
        for i in range(1, 33):
            if i != 4:
                satlist.append(f"G{i:02}")

    data = {sat:{doy:0.0 for doy in doylist} for sat in satlist if sat[0] == satsys}

    # read all file
    for f,doy in zip(filelist,doylist):
        wldata = read_wldata_oneday(f)

        for sat in wldata.keys():
            if sat in data:
                data[sat][doy] = wldata[sat]

    # nomallize
    for sat in satlist:
        ref_value = None
        for doy in doylist:
            if data[sat][doy] == 0.0:
                continue
            if not ref_value:
                ref_value = data[sat][doy]

            data[sat][doy] = ref_value + resize(data[sat][doy]-ref_value)

    return data

def read_nldata(filename):
    with open(filename) as nlfile:
        hour = 0.0
        mapnl = {}
        for i in nlfile:
            temp = i.split()
            if temp[0] == "EPOCH-TIME":
                hour = float(temp[2])/3600.0
                continue
            if (i[0] != " "):
                continue
            sat = temp[0]
            sat_data = mapnl.setdefault(sat,{})
            sat_data[hour]=resize(float(temp[1]))

    return mapnl

def draw_8sat(sat_list,allsat_value):
    color = ["b","g","r","c","m","y","k","#FFA500"]
    style = ["o","v","^","<",">","s","*","d"]

    doy_list = list(allsat_value[sat_list[0]].keys())
    for i in range(len(sat_list)):
        value = allsat_value[sat_list[i]].values()
        x = allsat_value[sat_list[i]].keys()
        plt.plot(x, value, color=color[i],lw=2.5 ,marker=style[i], label=sat_list[i])
        #plt.plot(x,value,color=color[i], marker ='-.')

    plt.xlabel("Day of Year", fontsize=13)
    plt.ylabel("WL UPD(Cycle)", fontsize=13)
    plt.ylim(-0.6,0.6)
    plt.xlim(doy_list[0]-1,doy_list[-1]+5)
    #plt.xticks(x,[str(i) for i in x],fontsize=13)
    plt.yticks(np.arange(-0.6,0.6,0.2),fontsize=13)
    plt.legend(loc="upper right")

def draw_wl_ndays(wldata,doylist,save_dir="."):

    sat_list = list(wldata.keys())
    ## draw row * col pictures in one png
    count = 8
    col = 2
    row =  math.ceil(len(sat_list) / float(col) / float(count))
    sat_sys = sat_list[0][0]

    plt.figure(figsize=(16,8),dpi=100)
    for i in range(row * col):
        plt.subplot(row, col, i + 1)
        sats = [sat_list[i] for i in range(i*count,(i+1)*count) if i < len(sat_list)]
        draw_8sat(sats,wldata)

    plt.savefig(f"wl_UPD_{len(doylist)}_day_"+sat_sys,dpi=120)
    plt.show()

def compute_wl():
    mapwl_allday= {}
    for i in range(14, 20):
        filename = "upd_wl_20190" + str(i) + "_GEC"
        mapwl_1day =read_wldata_oneday(filename)
        for sat in mapwl_1day:
            sat_wldata = mapwl_allday.setdefault(sat, [])
            sat_wldata.append(mapwl_1day[sat])

    sat_sys = "E"
    Max_std = ["",0.0]
    Max_diff = ["",0.0]
    with open("wl_data_"+sat_sys+".txt", "w") as myfile:
        myfile.write("Sat name  Max-Min STD \n")

        sat_list = list(mapwl_allday.keys())

        for sat in sat_list:
            if sat[0] != sat_sys:
                continue
            diff = max(mapwl_allday[sat]) - min(mapwl_allday[sat])
            std = np.std(mapwl_allday[sat],ddof=1)
            if (diff > Max_diff[1]):
                Max_diff[0] = sat
                Max_diff[1] = diff
            if (std > Max_std[1]):
                Max_std[0] = sat
                Max_std[1] = std
            myfile.write(sat + " " + "{0:.4f}".format(diff) +" "+"{0:.4f}".format(std)+"\n")

        myfile.write("Max diff:"+ Max_diff[0]+"\n")
        myfile.write("Max std:" + Max_std[0]+"\n")

def compute_nl():
    #get data
    mapnl = read_nldata("upd_nl_2019014_GEC")

    sat_list = mapnl.keys()
    sat_sys = "G"
    sat_list = [sat for sat in sat_list if sat[0] == sat_sys]
    sat_list = sorted(sat_list)

    Max_diff= ["",0.0]
    Max_std = ["",0.0]
    list_std = [ ]
    with open("nl_data_"+".txt","w") as nlfile:
        nlfile.write("Sat_name Max-Min std\n")
        for sat in sat_list:
            if (sat in ("G26")):
                continue
            value = list(mapnl[sat].values())
            diff = max(value) - min(value)
            std = np.std(value,ddof=1)
            list_std.append(std)

            if (diff > Max_diff[1]):
                Max_diff[0] = sat
                Max_diff[1] = diff
            if (std > Max_std[1]):
                Max_std[0] = sat
                Max_std[1] = std

            nlfile.write(sat+" "+"{0:.4f}".format(diff)+" "+"{0:.4f}".format(std)+"\n")
        nlfile.write("Max diff:"+Max_diff[0]+"\n")
        nlfile.write("Max std:"+Max_std[0]+"\n")
        nlfile.write("mean std:"+"{0:.4f}".format(np.std(list_std,ddof=1)))

def draw_1sat_nl(sat_list,allnl):
    color = ["r","g","b","c","m","y","k"]
    for i in range(len(sat_list)):
        sat_data = allnl[sat_list[i]]
        x = list(sat_data.keys())
        y = [sat_data[i] for i in x]
        plt.plot(x,y,color=color[i],lw=3,label=sat_list[i])

def draw_nl(nldata):

    #sat_list_G = ["G13","G15","G20","G21","G24","G29"]
    sat_list_G = ["G06"]
    sat_list_E = ["E03","E05","E09","E18","E25"]
    sat_list_C = ["C06","C07","C08","C09"]

    plt.figure(figsize=(12,6),dpi=120)
    plt.subplot(111)

    draw_1sat_nl(sat_list_G,nldata)
    plt.ylim(-1,0.4)
    plt.yticks(np.arange(-1,0.4,0.2),fontsize=13)

    plt.xlabel("Time(Hours)",fontsize=13)
    plt.ylabel("NL UPD(Cycles)",fontsize=13)

    plt.legend()
    plt.grid()
    plt.savefig("NL_DATA_C.png",dpi=120)
    plt.show()

if __name__ == "__main__":
    #draw_wl_7days()
    #compute_wl()
    #draw_nl()
    compute_nl()


from flask import Flask, request
from gpiozero import Robot

print(
    "                  ____            _           _   \n" +
    "                  |  _\\          | |         | |  \n" +
    "                  | |_) |_ __ ___ | |__   ___ | |_ \n" +
    "                  |  _ <| '__/ _ \\| '_ \\ / _ \\| __|\n" +
    "                  | |_) | | | (_) | |_) | (_) | |_ \n" +
    "                  |____/|_|  \\___/|_.__/ \\___/ \\__|\n" +
    "")

api = Flask(__name__)

robby = Robot(left=(9, 10), right=(7, 8))
robby.stop()

@api.route('/move', methods=['GET'])
def move():
    dir = request.args.get('dir')
    print('Received command: ' + dir)
    if dir == 'forward':
        robby.forward()
    elif dir == 'backward':
        robby.backward()
    elif dir == 'right':
        robby.right()
    elif dir == 'left':
        robby.left()
    else:
        robby.stop()
    return 'OK'

if __name__ == '__main__':
    api.run(host="0.0.0.0", port=8000)


from pathlib import Path
from typing import List, Tuple

DATA_PATH = Path(__file__).resolve().parents[1] / "data"

def read_input(path: Path) -> List[List[int]]:
    lines = []
    for line in path.read_text().strip("\n").split("\n"):
        lines.append([int(elem) for elem in line])
    return lines

def get_neighbors(
    grid: List[List[int]], coords: Tuple[int, int]
) -> List[Tuple[int, int]]:
    """Return the list of the neighbors (coordinates) of a point"""
    ii, jj = coords
    neighbors = []
    for i in range(-1, 2):
        for j in range(-1, 2):
            if i == j == 0:
                continue
            if ii + i < 0 or jj + j < 0:
                continue
            if ii + i >= len(grid) or jj + j >= len(grid[0]):
                continue
            neighbors.append((ii + i, jj + j))

    return neighbors

def do_step(grid: List[List[int]]) -> int:
    """Perform a step and retun the number of flashing octopuses at this step"""
    # First increment
    flashing = []
    for i in range(len(grid)):
        for j in range(len(grid[0])):
            grid[i][j] = grid[i][j] + 1
            if grid[i][j] == 10:
                flashing.append((i, j))
                grid[i][j] = 0

    # Increment neighbors
    to_flash = list(flashing)
    while to_flash:
        coords = to_flash.pop(0)
        neighbors = get_neighbors(grid, coords)
        for i, j in neighbors:
            # Flashin octopuse always restart at 0
            if (i, j) in flashing:
                continue
            grid[i][j] = grid[i][j] + 1
            if grid[i][j] == 10:
                to_flash.append((i, j))
                flashing.append((i, j))
                grid[i][j] = 0

    return len(flashing)

def main(problem_number: int):

    # Part 1
    data = read_input(DATA_PATH / f"input_{problem_number}.txt")
    print(sum(do_step(data) for _ in range(100)))

    # Part 2
    data = read_input(DATA_PATH / f"input_{problem_number}.txt")
    step = 0
    while True:
        step += 1
        n_flash = do_step(data)
        if n_flash == len(data) * len(data[0]):
            break

    print(step)


"""Demo module."""
import pygame
import logging

from .assets import AssetManager
from .display import ScrollingMapEntityDisplayLayer, DisplayModule, DisplayLayer
from .events import EventManager
from .entities import EntityManager, EntityInput
from .session import SessionManager
from .modules import Game
from .states import GameState, SplashScreen, StateManager
from .input import InputModule
from .audio import AudioModule
from .locals import *  # noqa

logger = logging.getLogger(__name__)

class DemoGame(Game):

    """Demo game."""

    def __init__(self):
        """Constructor."""
        self.states = self.container.get(StateManager)

        self.game_realm = DemoGameState()
        self.splash_screen = SplashScreen(image='graphics/logos/multatronic.png', next=self.game_realm)
        self.states.add(self.splash_screen)
        self.states.add(self.game_realm)

    def play(self):
        """Play the game."""
        self.states.set_active(self.splash_screen)

class DemoGameState(GameState):

    """Temporary demo middleware."""

    def __init__(self):
        """Constructor."""
        super().__init__()

        self.events = self.container.get(EventManager)
        self.display = self.container.get(DisplayModule)
        self.audio = self.container.get(AudioModule)
        self.assets = self.container.get(AssetManager)
        self.entities = self.container.get(EntityManager)
        self.session = self.container.get(SessionManager)
        self.input = self.container.get(InputModule)
        self.shutdown = self.container.get(ShutdownFlag)

    def on_quit(self, event):
        """Handle quitting."""
        self.shutdown.set()

    def enable(self):
        """Initialize the gamestate."""
        self.input.add_action_listener('game_quit', self.on_quit)

        # self.tmx_data = self.assets.get_tmx_data('pyscroll_demo/grasslands.tmx')
        self.tmx_data = self.assets.get_tmx_data('maps/urdarbrunn/map.tmx')
        self.layer = ScrollingMapEntityDisplayLayer(self.tmx_data, default_layer=2)

        self.ui_layer = DisplayLayer(flags=pygame.SRCALPHA, z_index=101)

        self.display.add_layer(self.ui_layer)
        self.display.add_layer(self.layer)

        player = self.session.get('player')

        if not player:
            player = self.entities.find_entities_by_components(['player'])[0]
            self.session.set('player', player)

            # Set selected skill to fireball
            # @TODO Remove this
            player.components['input'].input[EntityInput.SELECTED_SKILL] = 'skill_fireball'

        self.layer.center = player

        # Load audio files
        # music
        self.audio.add_music("audio/music/magical_theme.ogg", "world01")

        # sound effects
        self.audio.add_sound("audio/sfx/sfx_step_grass.ogg", "terrain_grass")
        self.audio.add_sound("audio/sfx/sfx_step_rock.ogg", "terrain_stone")

        # create channels
        self.audio.add_channel('terrain')

        # start playing the background music
        self.audio.play_music("world01")

    def disable(self):
        """Stop the gamestate."""
        self.input.remove_action_listener(self.on_quit)


"""
This file may contain a convenient interface/function for

1: computing a trajectory using an ODE solver from solver.py
2: save data to file
3: plot data
and possible another function that

2: load data from file
3: plot data

"""
import numpy as np
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
import lorenz.plot as pl
import lorenz.solver as sol
import lorenz.filehandling as fh
import lorenz.util as ut
import matplotlib.pyplot as plt

def run_lorenz(parameters, ini_state = [0.1, 0.1, 0.1], t_d = 1e-3,
               N = 50000, plot = False, save = False, fname = 'Test',
               directory = None):
    """
    Return the states, save the variables, plots and save the plots
    using the auxiliary functions provided.

    INPUT::

     parameters:    the parameters of the lorenz attractor
     ini_state:    initial state of the lorenz attractor
     t_d:    the time differential
     N:    number of samples
     plot:    bool to plot
     save:    bool for saving
     fname:    name of file
     directory:    directory to save

    OUTPUT::

     states:    the states of the lorenz attractor in the span of
                the differential time and number of samples

    Example:

    >>> param = [10, 2, 6]
    >>> run_lorenz(param)

    """
    sigma, rho, beta = parameters
    x, y, z = ini_state
    #t_d = t/N
    #time = [i*t_d for i in range(N)] #get each discrete time
    states = np.array([[x,y,z]]) #create the array
    t = t_d * N
    ti = np.arange(0.0, t, t_d)
    cntr = 1
    for i in ti[:-1]:
        states = np.concatenate((states,
             [sol.lorenz_solver(states[cntr-1,:], parameters, t_d)]))
        cntr = cntr + 1
        #states = np.concatenate((states,
        #    [sol.lorenz_solver(states[i-1,:], parameters, t_d)]))
    if plot:
        pl.plot_3d_states(states, save, fname, directory) #plot x,y,z
        pl.plot_2d("xy", states, save, fname, directory) #plot xy
        pl.plot_2d("xz", states, save, fname, directory) #plot xz
        pl.plot_2d("yz", states, save, fname, directory) #plot yz
    if save:
        fh.save_all(fname, sigma, rho, beta, x, y, z, t_d, N, states,
                    directory)
    return states

def load_lorenz(fname = 'Test', plot = True):
    """
    This function will load the lorenz and plot it

    INPUT::

     fname:    the name of the file to open
     plot:    bool to plot or not

    OUTPUT::

     Nothing, just plots

    Example:

    >>> load_lorenz('Test', True)
    """
    [s2,r3,b2,x2,y2,z2,t_d2,N2,st2] = fh.load_all(fname)
    if plot:
        pl.plot_3d_states(st2)
    return

if __name__ == '__main__':
    """
    This is just debugging code
    """
#print("This is a convenient interface for running the simulation \
#     of a lorenz attractor")
    #sigma = ut.my_input_float("sigma") #input all parameters
    #rho = ut.my_input_float("rho")
    #beta = ut.my_input_float("beta")
    #x = ut.my_input_float("x") #input initial conditions
    #y = ut.my_input_float("y")
    #z = ut.my_input_float("z")
    #ini_state = x, y, z
    sigma = 10
    rho = 6
    beta = 8/3
    ini_state = [1.0, 1.0, 1.0]
    t_d = 0.01
    #t = ut.my_input_int("time in seconds")
    parameters = (sigma, rho, beta)
    N = 80000 #assign 50000 steps as suggested
    t = t_d * N #timestep calculated from simulation time
    #states = np.array([[x,y,z]]) #create the array
    states = np.array([ini_state])
    for i in range(0,N-1):
        states = np.concatenate((states,
            [sol.lorenz_solver(states[i-1,:], parameters, t_d)]))

    pl.plot_3d_states(states) #plot x,y,z
    #pl.plot_2d("xy", states) #plot xy
    #pl.plot_2d("xz", states) #plot xz
    #pl.plot_2d("yz", states) #plot yz

    #fh.save_all('testo',sigma,rho,beta,x,y,z,t,t_d,states)
    #[s2,r3,b2,x2,y2,z2,t2,t_d2,st2] = fh.load_all('testo')

    #pl.plot_3d_states(st2)

    """
    This is for testing. For testing the function.
    """
    w_states = ut.wikipedia_lorenz([sigma, rho, beta], ini_state, t_d, N, plot = True)

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot(w_states[0000:70000,0], w_states[0000:70000,1], w_states[0000:70000,2])
    plt.legend(['wiki'])
    plt.title('Wikipedia')
    plt.show()

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot(states[0000:70000,0], states[0000:70000,1], states[0000:70000,2])
    plt.legend(['my'])
    plt.title(' mine')
    plt.show()

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot(states[:,0], states[:,1], states[:,2])
    ax.plot(w_states[:,0], w_states[:,1], w_states[:,2])
    plt.legend(['my','wiki'])
    plt.title('Wikipedia vs mine')
    plt.show()

    ss = states - w_states
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot(ss[:,0], ss[:,1], ss[:,2])
    plt.legend(['my'])
    plt.title('diff Wikipedia vs mine')
    plt.show()
#

#
#    import numpy as np
#    import matplotlib.pyplot as plt
#    from scipy.integrate import odeint
#    from mpl_toolkits.mplot3d import Axes3D
#
#    rho = 28.0
#    sigma = 10.0
#    beta = 8.0 / 3.0
#
#    def f(state, t):
#        x, y, z = state  # unpack the state vector
#        return sigma * (y - x), x * (rho - z) - y, x * y - beta * z  # derivatives
#
#    state0 = [1.0, 1.0, 1.0]
#    t = np.arange(0.0, 40.0, 0.01)
#
#    states = odeint(f, state0, t)
#
#    fig = plt.figure()
#    ax = fig.gca(projection='3d')
#    ax.plot(states[:,0], states[:,1], states[:,2])
#    plt.show()


try:
    from onitama.connect.card import LI
except:
    from card import LI
from matplotlib import pyplot as plt
import matplotlib.image as img
import numpy
import os

try:
    os.mkdir(r'C:\Users\吕\Desktop\supergame\static\onitama\card')
except:
    pass

plt.rcParams['font.sans-serif'] = ['KaiTi']

for card in LI:
    print(card.name)
    fig = plt.figure(figsize=(5, 5))
    # plt.title(card.name)

    plt.gca().xaxis.set_major_locator(plt.NullLocator())
    plt.gca().yaxis.set_major_locator(plt.NullLocator())
    plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=1, wspace=1)
    # # plt.margins(0, 0)

    plt.axis([0.3, 5.7, 0.3, 5.7])
    plt.axis('off')

    bgimg = img.imread(r'C:\Users\吕\Desktop\supergame\static\onitama\other\yangpi.jpg')
    plt.figimage(bgimg)

    tick = numpy.asarray((0, 1, 2, 3, 4, 5)) + 0.5
    plt.xticks(tick, [])
    plt.yticks(tick, [])
    for _ in tick:
        plt.plot(tick, numpy.ones_like(tick)*_, c='black')
        plt.plot(numpy.ones_like(tick)*_, tick, c='black')

    old = numpy.asarray((3, 3))
    new = numpy.asarray(card.method) + old
    plt.scatter(new[:, 0], new[:, 1], c='black', s=2400, marker='*')
    plt.scatter(old[0], old[1], c=card.seq, s=1800, marker='o')

    plt.text(3, 3, s=card.name, c=card.seq, size=150, alpha=0.3,
             va="center", ha="center")

    # plt.savefig(r'C:\Users\吕\Desktop\supergame\static\onitama\card\%s.jpg' % card.name)
    plt.show()
    break


import os
import os.path
from PIL import Image, ImageDraw

from . settings import Config
from . baseassets import Assets

class Door(Assets):
    def __init__(self, pos, type, coords=None):
        super().__init__()
        self.doors = {
            "front": {
                "closed": os.path.join(self.basedir, "doors/door_front_closed.png"),
                "open": os.path.join(self.basedir, "doors/door_front_open.png"),
                "fullopen": os.path.join(self.basedir, "doors/door_front_fullopen.png"),
                "hotspot": os.path.join(self.basedir, "doors/door_front_hotspot.png"),
                # front is placed by coords
                #"xpos": 130,
                #"ypos": 12,
            },
            "left": {
                "closed": os.path.join(self.basedir, "doors/door_left_closed.png"),
                "open": os.path.join(self.basedir, "doors/door_left_open.png"),
                "fullopen": os.path.join(self.basedir, "doors/door_left_fullopen.png"),
                "hotspot": os.path.join(self.basedir, "doors/door_left_hotspot.png"),
                "xpos": 7,
                "ypos": 20,
            },
            "right": {
                "closed": os.path.join(self.basedir, "doors/door_right_closed.png"),
                "open": os.path.join(self.basedir, "doors/door_right_open.png"),
                "fullopen": os.path.join(self.basedir, "doors/door_right_fullopen.png"),
                "hotspot": os.path.join(self.basedir, "doors/door_right_hotspot.png"),
                "xpos": -44, # note the negative value
                "ypos": 20,
            },
            "bottom": {
                "closed": os.path.join(self.basedir, "doors/door_bottom_closed.png"),
                "open": os.path.join(self.basedir, "doors/door_bottom_open.png"),
                "fullopen": os.path.join(self.basedir, "doors/door_bottom_fullopen.png"),
                "hotspot": os.path.join(self.basedir, "doors/door_bottom_hotspot.png"),
                "behind": os.path.join(self.basedir, "doors/door_bottom_behind.png"),
                #"xpos": 150,
                #"ypos": 146,
            },
        }
        self.pos = pos.lower()
        self.type = type.lower()
        if coords:
            self.coords = coords
        self.res = self.doors[self.pos]

    def LoadAssets(self, layers, layer_size=None):
        super().LoadAssets(layers)

        img_file = self.res[self.type]
        xpos,ypos = self.GetCoords()
        # manage relative values from the right, and bottom
        if xpos < 0: xpos = layer_size[0]+xpos
        if ypos < 0: ypos = layer_size[1]+ypos

        name = "door_%s_%s" % (self.pos, self.type)

        door = Image.open(img_file)
        door.load()
        # create the layer
        img = Image.new("RGBA", layer_size, color=Config.bg_trans)
        img.paste(door, (xpos, ypos))
        layers.append((name.lower(), img))

    def LoadHotSpots(self, mask):

        src = Image.new("RGBA", mask.size, color=Config.bg_trans)
        img_file = self.doors[self.pos]["hotspot"]
        img = Image.open(img_file)
        xpos,ypos = self.GetCoords()
        if xpos < 0: xpos = mask.size[0]+xpos
        if ypos < 0: ypos = mask.size[1]+ypos

        src.paste(img, (xpos, ypos))
        mask = Image.alpha_composite(mask, src)
        return mask

    def LoadBehinds(self, mask):
        "doors only have bottom behinds"
        if "bottom" == self.pos:
            src = Image.new("RGBA", mask.size, color=Config.bg_trans)
            img_file = self.doors[self.pos]["behind"]
            img = Image.open(img_file)
            xpos,ypos = self.GetCoords()
            if xpos < 0: xpos = mask.size[0]+xpos
            if ypos < 0: ypos = mask.size[1]+ypos

            src.paste(img, (xpos, ypos))
            mask = Image.alpha_composite(mask, src)

        return mask

    def GetCoords(self):
        if "xpos" in self.res.keys():
            xpos = self.res["xpos"]
            ypos = self.res["ypos"]
            return (xpos,ypos)
        else:
            return self.coords


# -*- coding: utf-8 -*-
#https://www.kaggle.com/dasolmar/xgb-with-whq-jaccard/code/code

#==============================================================================
# Ensemble learning creation:
# base_algorithms = [logistic_regression, decision_tree_classification, ...] #for classification
#
# stacking_train_dataset = matrix(row_length=len(target), column_length=len(algorithms))
# stacking_test_dataset = matrix(row_length=len(test), column_length=len(algorithms))
#
# for i,base_algorithm in enumerate(base_algorithms):
#     for trainix, testix in split(train, k=10): #you may use sklearn.cross_validation.KFold of sklearn library
#         stacking_train_dataset[testix,i] = base_algorithm.fit(train[trainix], target[trainix]).predict(train[testix])
#     stacking_test_dataset[,i] = base_algorithm.fit(train).predict(test)
#
#
# final_predictions = combiner_algorithm.fit(stacking_train_dataset, target).predict(stacking_test_dataset)
#==============================================================================

import numpy as np
import pandas as pd
import xgboost as xgb
import operator
from sklearn.model_selection import train_test_split
from collections import Counter
from nltk.corpus import stopwords
import matplotlib.pyplot as plt
from pylab import plot, show, subplot, specgram, imshow, savefig

print("Started")
RS = 12357
np.random.seed(RS)

input_folder = 'F:/DS-main/Kaggle-main/Quora Question Pairs - inputs/data/'
df_train = pd.read_csv(input_folder + 'train.csv')
df_test  = pd.read_csv(input_folder + 'test.csv')

#==============================================================================
# #rnn 1 lstm
# train_rnn1Lstm = pd.read_csv('F:/DS-main/Kaggle-main/Quora Question Pairs - inputs/data/nn 1 lstm best results/0.2647_lstm_300_200_0.30_0.30Train.csv', header=0)
# test_rnn1Lstm = pd.read_csv('F:/DS-main/Kaggle-main/Quora Question Pairs - inputs/data/nn 1 lstm best results/0.2647_lstm_300_200_0.30_0.30.csv', header=0)
# df_rnn1Lstm = pd.concat([train_rnn1Lstm, test_rnn1Lstm])
#
# #rnn 1 GRU
# train_rnn1GRU = pd.read_csv('F:/DS-main/Kaggle-main/Quora Question Pairs - inputs/data/nn 1 gru/0.3143_lstm_300_200_0.50_0.50_gru_Train.csv', header=0)
# test_rnn1GRU = pd.read_csv('F:/DS-main/Kaggle-main/Quora Question Pairs - inputs/data/nn 1 gru/0.3143_lstm_300_200_0.50_0.50_gru.csv', header=0)
# df_rnn1GRU = pd.concat([train_rnn1GRU, test_rnn1GRU])
#==============================================================================

#adding final x features
x = pd.read_csv('F:/DS-main/Kaggle-main/Quora Question Pairs - inputs/data/x_final_features.csv', header=0)

#==============================================================================
# ##rnn 1 lstm
# print("rnn features")
# x['rnn1Lstm'] = df_rnn1Lstm['is_duplicate']
# ##rnn 1 gru
# print("rnn gru features")
# x['rnn1GRU'] = df_rnn1GRU['is_duplicate']
#==============================================================================

print(x.columns)
print(x.describe())

feature_names = list(x.columns.values)
print("Features: {}".format(feature_names))

x_train = x[:df_train.shape[0]]
x_test  = x[df_train.shape[0]:]
y_train = df_train['is_duplicate'].values
x_train_for_ensemble =  x_train
y_train_for_ensemble =  y_train
del x, df_train
#params['scale_pos_weight'] = 0.360

if 1: # Now we oversample the negative class - on your own risk of overfitting!
	pos_train = x_train[y_train == 1]
	neg_train = x_train[y_train == 0]

	print("Oversampling started for proportion: {}".format(len(pos_train) / (len(pos_train) + len(neg_train))))
	p = 0.165
	scale = ((len(pos_train) / (len(pos_train) + len(neg_train))) / p) - 1
	while scale > 1:
		neg_train = pd.concat([neg_train, neg_train])
		scale -=1
	neg_train = pd.concat([neg_train, neg_train[:int(scale * len(neg_train))]])
	print("Oversampling done, new proportion: {}".format(len(pos_train) / (len(pos_train) + len(neg_train))))

	x_train = pd.concat([pos_train, neg_train])
	y_train = (np.zeros(len(pos_train)) + 1).tolist() + np.zeros(len(neg_train)).tolist()
	del pos_train, neg_train

####################################################################
# XGBoost
####################################################################
ratio = float(np.sum(y_train == 0)) / np.sum(y_train==1)

print("Training data: X_train: {}, Y_train: {}, X_test: {}".format(x_train.shape, len(y_train), x_test.shape))
ROUNDS = 1000
#training
def create_feature_map(features):
	outfile = open('xgb.fmap', 'w')
	i = 0
	for feat in features:
		outfile.write('{0}\t{1}\tq\n'.format(i, feat))
		i = i + 1
	outfile.close()
create_feature_map(feature_names)

print("Will train XGB for {} rounds, RandomSeed: {}".format(ROUNDS, RS))
params = {}
#?params['scale_pos_weight'] = ratio
params['objective'] = 'binary:logistic'
params['eval_metric'] = 'logloss'
params['eta'] = 0.11
params['max_depth'] = 5
params['silent'] = 1
params['seed'] = RS
X_training, X_val, y_training, y_val = train_test_split(x_train, y_train, test_size=0.2, random_state=RS)
xg_train = xgb.DMatrix(X_training, label=y_training)
xg_val = xgb.DMatrix(X_val, label=y_val)
watchlist  = [(xg_train,'train'), (xg_val,'eval')]

clr = xgb.train(params, xg_train, ROUNDS, watchlist, early_stopping_rounds=50)

preds = clr.predict(xgb.DMatrix(x_test))

print("Writing output...")
sub = pd.DataFrame()
sub['test_id'] = df_test['test_id']
sub['is_duplicate'] = preds *.75
sub.to_csv("xgb1_seed{}_n{}.csv".format(RS, ROUNDS), index=False)

print("Features importances...")
importance = clr.get_fscore(fmap='xgb.fmap')
importance = sorted(importance.items(), key=operator.itemgetter(1))
ft = pd.DataFrame(importance, columns=['feature', 'fscore'])
ft.plot(kind='barh', x='feature', y='fscore', legend=False, figsize=(10, 25))
plt.gcf().savefig('features_importance.png')

print("Done.")

#--- pred training for ensemble

print("pred training for ensemble")
preds = clr.predict(xgb.DMatrix(x_train_for_ensemble))

print("Writing output...")
sub = pd.DataFrame()
sub['is_duplicate'] = preds *.75
sub.to_csv("xgb_seed{}_n{}training.csv".format(RS, ROUNDS), index=False)

####################################################################
# ANN
####################################################################
# Importing the Keras libraries and packages
#==============================================================================
# import keras
# from keras.models import Sequential
# from keras.layers import Dense, PReLU
# from keras.layers import Dropout
# from keras.layers.normalization import BatchNormalization
# from keras.callbacks import EarlyStopping, ModelCheckpoint
#
#
# # Initialising the ANN
# classifier = Sequential()
# # Adding the input layer and the first hidden layer
# classifier.add(Dense(units = 200, kernel_initializer = 'truncated_normal', activation='relu', input_dim = 71))
# classifier.add(Dropout(rate = 0.1))
#
# classifier.add(Dense(200, kernel_initializer = 'truncated_normal', activation='relu'))
# classifier.add(Dropout(rate = 0.1))
#
# classifier.add(Dense(200, kernel_initializer = 'truncated_normal', activation='relu'))
# classifier.add(Dropout(rate = 0.1))
#
# classifier.add(Dense(units = 1, kernel_initializer = 'truncated_normal', activation = 'sigmoid'))
#
# early_stopping =EarlyStopping(monitor='val_loss', patience = 10)
# model_checkpoint = ModelCheckpoint('weightsANN_X_final_Features.h5', save_best_only=True, save_weights_only=True, verbose=1)
#
# classifier.compile(optimizer = 'nadam', loss = 'binary_crossentropy', metrics = ['accuracy'])
# classifier.fit(x_train_for_ensemble.values, np.array(y_train_for_ensemble), batch_size=2048, epochs=300, verbose=1, validation_split=0.1, shuffle=True, callbacks=[early_stopping, model_checkpoint])
#
# classifier.load_weights('weightsANN_X_final_Features.h5')
#
# y_pred = classifier.predict(x_test.values, batch_size=2048, verbose=1)
# submissionTest = pd.DataFrame({'is_duplicate':y_pred.ravel()})
# submissionTest.to_csv('denseANN_Test.csv', index=False)
#
# y_pred_training = classifier.predict(x_train_for_ensemble.values, batch_size=2048, verbose=1)
# submissionTraining = pd.DataFrame({'is_duplicate':y_pred_training.ravel()})
# submissionTraining.to_csv('denseANN_Training.csv', index=False)
#==============================================================================

####################################################################
# K-nn
####################################################################


import numpy as np
import pandas as pd

import torch
import torchvision.transforms.functional as TF

def gen_denseTensorChunk(X, tchunksize):
    # X_coal = X.to('cpu').coalesce()
    X_coal = X
    (t_idx, c_idx, y_idx, x_idx), vals = X_coal.indices(), X_coal.values()

    tstart, tstop = 0, tchunksize
    last_chunk = False
    while not last_chunk:
        if tstop >= X.shape[0]:
            tstop = X.shape[0]
            last_chunk = True

        t_mask = (t_idx >=tstart) & (t_idx <tstop)
        indices = torch.stack((t_idx[t_mask]-tstart, c_idx[t_mask], y_idx[t_mask], x_idx[t_mask]))
        outshape = (tstop-tstart, *X.shape[1:])

        yield torch.sparse_coo_tensor(indices, vals[t_mask], size=outshape).to_dense()
        tstart, tstop = tstop, tstop+tchunksize

def transform_X(X, tchunksize, angle, flip_dims, dy, dx, sizey, sizex, device):
    # translating
    if dx or dy:
        X_coal = X.coalesce()
        indices, vals = X_coal.indices(), X_coal.values()
        oof = torch.ones(vals.shape, dtype=bool) # ~out of frame

        if dy:
            indices[2] = (indices[2] + dy).to(torch.long)
            oof[(indices[2]>=sizey) | (indices[2]<0)] = False
        if dx:
            indices[3] = (indices[3] + dx).to(torch.long)
            oof[(indices[3]>=sizex) | (indices[3]<0)] = False

        # torch doens't broadcast like numpy?
        oof_brdcst = torch.stack([oof]*4)
        indices = indices[oof_brdcst].reshape((4, oof.sum()))
        X = torch.sparse_coo_tensor(indices, vals[oof], X.shape)

    if not flip_dims and not angle:
        return X.to_dense()
    else:
        X_coal = X.coalesce()

        X_dense = []
        for X_chunk in gen_denseTensorChunk(X_coal, tchunksize):
            # X_chunk = X_chunk.to(device)

            # flipping
            if flip_dims:
                X_chunk = torch.flip(X_chunk, flip_dims)
            # rotating
            if angle:
                X_chunk = TF.rotate(X_chunk, angle)
            X_dense.append(X_chunk.to('cpu'))

        return torch.cat(X_dense)

def transform_Y(target, angle, flip_dims,  dy, dx, sizey, sizex):
    def rotate_indices(bboxes, imshape, angle):
        angle = torch.tensor([angle * np.pi / 180.])
        y_mid = (imshape[0] + 1) / 2.
        x_mid = (imshape[1] + 1) / 2.

        rotated_bboxes = bboxes.copy()
        rotated_bboxes.loc[:] = np.nan

        for tpoint in bboxes.index:
            pixelwise_indices_df = bboxes.loc[tpoint].unstack().dropna()
            pixelwise_indices = pixelwise_indices_df.values

            for row in range(pixelwise_indices.shape[0]):
                x, y = pixelwise_indices[row]
                x_rot = (x- x_mid) * torch.cos(angle) + (y - y_mid) * torch.sin(angle)
                y_rot = -1.0 * (x - x_mid) * torch.sin(angle) + (y - y_mid) * torch.cos(angle)
                x_rot = torch.round(x_rot + x_mid)
                y_rot = torch.round(y_rot + y_mid)

                x_rot = x_rot if (x_rot > 0  and x_rot < imshape[1]) else 0
                y_rot = y_rot if (y_rot > 0  and y_rot < imshape[0]) else 0
                pixelwise_indices[row] = (x_rot, y_rot) if x_rot and y_rot else (np.nan, np.nan)

            rotated_bboxes.loc[tpoint,pixelwise_indices_df.index] = pixelwise_indices.flatten()
        return rotated_bboxes

    def flip_indices(bboxes, imshape, which):
        y_mid = (imshape[0] + 1) / 2.
        x_mid = (imshape[1] + 1) / 2.

        if 2 in which:
            bboxes.loc[:, (slice(None),'anchor_y')] = y_mid + (y_mid - bboxes.loc[:, (slice(None),'anchor_y')])
        if 3 in which:
            bboxes.loc[:, (slice(None),'anchor_x')] = x_mid + (x_mid - bboxes.loc[:, (slice(None),'anchor_x')])
        return bboxes

    # make a new dataframe with reset index (y-axis from 0 - last timepoint)
    target_transf = target.copy()
    # get the anchor points of all the bboxes (center point)
    anchors = target.loc[:,(slice(None),['anchor_y', 'anchor_x'])].sort_index(axis=1).copy()

    # translating
    if dy or dx:
        y_anchor = anchors.loc[:, (slice(None), 'anchor_y')]
        x_anchor = anchors.loc[:, (slice(None), 'anchor_x')]
        if dy:
            y_anchor += dy
            oof = ((1 >= y_anchor) | (y_anchor >= sizey-1)).values
            y_anchor = y_anchor.where(~oof)
        if dx:
            x_anchor += dx
            oof = ((1 >= x_anchor) | (x_anchor >= sizex-1)).values
            x_anchor = x_anchor.where(~oof)
        # ----- check which bbox is lost after translation? -----
        anchors.loc[:, (slice(None), 'anchor_y')] = y_anchor
        anchors.loc[:, (slice(None), 'anchor_x')] = x_anchor

    # flipping
    if flip_dims:
        anchors = flip_indices(anchors, (sizey, sizex), flip_dims)

    # rotating
    # if transform_configs.get('rot',0) > .5:
    if angle:
        # ----- check which bbox is lost after rotation? -----
        anchors = rotate_indices(anchors, (sizey, sizex), angle)

    # get the new x,y anchors and mask extend in case bboxes got lost in rotation
    y_anchor = anchors.loc[:, (slice(None), 'anchor_y')].round()
    x_anchor = anchors.loc[:, (slice(None), 'anchor_x')].round()
    target_transf.loc[:, (slice(None),'anchor_y')] = y_anchor
    target_transf.loc[:, (slice(None),'anchor_x')] = x_anchor
    return target_transf

def apply_transformations(transform_configs, X, target, sizey, sizex, device):
    # make a transformation config: rotate, hflip, vflip translate - or not
    transform_configs = {key: round(torch.rand(1).item(), 3) for key in transform_configs}
    # transform_configs = {key: .7 for key in transform_configs}
    print(f'New transform config set: {transform_configs}\n'
            'Transforming data...', end='', flush=True)

    # translating parameter
    dy, dx = 0, 0
    # dy and dx are in [-.25, +.25]s
    if transform_configs.get('translateY', 0) >.6:
        dy = round(512 *(transform_configs.get('translateY', 0)-.75))
    if transform_configs.get('translateX', 0) >.6:
        dx = round(512 *(transform_configs.get('translateX', 0)-.75))

    # flipping parameter
    flip_dims = []
    if transform_configs.get('hflip',0) > .6:
        flip_dims.append(2)
    if transform_configs.get('vflip',0) > .6:
        flip_dims.append(3)

    # rotating parameter
    angle = None
    if transform_configs.get('rot',0) > .6:
        angle = ((transform_configs['rot'] * 40) -20)
        # angle = ((transform_configs['rot'] * 90) -45)

    # apply the transformation using paramters above, do on GPU, return on CPU
    tchunksize = 60
    X = transform_X(X, tchunksize, angle, flip_dims, dy, dx, sizey, sizex, device)
    # now transform the bboxes with the same paramters
    target_transf = transform_Y(target, angle, flip_dims, dy, dx, sizey, sizex)
    print('Done.', flush=True)
    torch.cuda.empty_cache()
    return X, target_transf

def sprse_scipy2torch(scipy_coo):
    indices = np.vstack((scipy_coo.row, scipy_coo.col))
    return torch.sparse_coo_tensor(indices, scipy_coo.data, scipy_coo.shape, dtype=torch.float32)

# def get_target_in_libmot_format(self, axon_boxs):
#     libmot_targets = []
#     for t in range(self.sizet):
#         target = self.target.iloc[self.timepoints_indices[t]].unstack().dropna()
#         x, y = target.values.T
#         x_topleft = target.anchor_x-axon_boxs//2
#         y_topleft = target.anchor_y-axon_boxs//2
#         frame_id = np.full(target.shape[0], t)
#         axon_id = np.array([int(idx[-3:]) for idx in target.index])
#         boxs = np.full(target.shape[0], axon_boxs)

#         libmot_target = np.stack([frame_id, axon_id, x_topleft, y_topleft,
#                                 boxs, boxs]).T.astype(int)
#         libmot_target = pd.DataFrame(libmot_target, columns=['FrameId', 'Id', 'X', 'Y', 'Width', 'Height'])
#         libmot_targets.append(libmot_target.set_index(['FrameId', 'Id']))
#     return pd.concat(libmot_targets)


from django.contrib import admin
from apps.suggestions.models import ProblemType, Problem, Location, ProblemImages

@admin.register(ProblemType)
class ProblemTypeAdmin(admin.ModelAdmin):
    list_display = ("name",)
    search_fields = ("name",)

@admin.register(ProblemImages)
class ProblemImagesAdmin(admin.ModelAdmin):
    list_display = ("id", "problem", "image")
    search_fields = ("id", "problem", "image")
    list_filter = ("problem",)
    readonly_fields = ("id", "problem", "image")

class ProblemImagesInline(admin.TabularInline):
    model = ProblemImages
    extra = 1

@admin.register(Problem)
class ProblemAdmin(admin.ModelAdmin):
    list_display = ("id", "user", "city", "district", "date", "status")
    search_fields = ("id", "user", "city", "district", "date", "status")
    list_filter = ("status",)
    readonly_fields = ("id", "city", "district", "date")
    inlines = [ProblemImagesInline]

@admin.register(Location)
class LocationAdmin(admin.ModelAdmin):
    list_display = ['id', 'lon', 'lat']


from config.db import db, ma, app

class Formulario(db.Model):
    __tablename__ = 'formulario'
    id = db.Column(db.Integer, primary_key=True)
    id_producto= db.Column(db.Integer, db.ForeignKey('Producto.id'))
    id_user = db.Column(db.Integer, db.ForeignKey('User.id'))
    id_vehiculo = db.Column(db.Integer, db.ForeignKey('Vehiculo.id'))

    def __init__(self, id_producto, id_user, id_vehiculo):
        self.id = id
        self.id_producto = id_producto
        self.id_user = id_user
        self.vehiculo = id_vehiculo

with app.app_context():
    db.create_all()

class FormulariosSchema(ma.Schema):
    class Meta:
        fields = ('id', 'id_producto', 'id_User','id_vehiculo')


from trainer import GPTTrainer, GPTDataset, activation_functions_dict
from preprocessing.tokenizer import Tokenizer
import warnings
import os

warnings.filterwarnings('ignore')

def train_model(
        manifest_path: str,
        tokenizer_path: str,
        n: int,
        d_model: int,
        heads: int,
        activation: str,
        dropout_rate: float,
        eps: float,
        device: str,
        learning_rate: float,
        epochs: int,
        batch_size: int,
        checkpoint: str,
        tracking_config_path: str,
        val_path: str,
        validation_config_path: str
):
    assert os.path.exists(tokenizer_path) and os.path.exists(manifest_path)

    tokenizer = Tokenizer(tokenizer_path)

    train_dataset = GPTDataset(manifest_path, tokenizer=tokenizer)

    val_dataset = None
    if val_path is not None:
        if os.path.exists(val_path) == True:
            val_dataset = GPTDataset(val_path, tokenizer=tokenizer)

    trainer = GPTTrainer(
        token_size=len(tokenizer.dictionary),
        n=n,
        d_model=d_model,
        heads=heads,
        activation=activation_functions_dict[activation],
        dropout_rate=dropout_rate,
        eps=eps,
        device=device,
        init_learning_rate=learning_rate,
        checkpoint=checkpoint
    )

    trainer.fit(
        train_dataset=train_dataset,
        val_dataset=val_dataset,
        epochs=epochs,
        batch_size=batch_size,
        tracking_config_path=tracking_config_path,
        validation_config_path=validation_config_path
    )

if __name__ == '__main__':
    from argparse import ArgumentParser

    parser = ArgumentParser()

    # Pre-config
    parser.add_argument("--manifest_path", type=str)
    parser.add_argument("--tokenizer_path", type=str)
    parser.add_argument("--val_path", type=str, default=None)

    # Model Hyper-parameters
    parser.add_argument("--n", type=int, default=12)
    parser.add_argument("--d_model", type=int, default=768)
    parser.add_argument("--heads", type=int, default=12)
    parser.add_argument("--dropout_rate", type=float, default=0.1)
    parser.add_argument("--eps", type=float, default=0.02)
    parser.add_argument("--activation", type=str, default='gelu')

    # Training
    parser.add_argument("--device", type=str, default="cpu")
    parser.add_argument("--learning_rate", type=float, default=3e-5)
    parser.add_argument("--epochs", type=int, default=1)
    parser.add_argument("--batch_size", type=int, default=1)
    parser.add_argument("--checkpoint", type=str, default="./gpt.pt")

    # Config
    parser.add_argument("--tracking_config_path", type=str, default=None)
    parser.add_argument("--validation_config_path", type=str, default=None)

    # Main Handle
    args = parser.parse_args()

    train_model(
        manifest_path=args.manifest_path,
        tokenizer_path=args.tokenizer_path,
        n=args.n,
        d_model=args.d_model,
        heads=args.heads,
        activation=args.activation,
        dropout_rate=args.dropout_rate,
        eps=args.eps,
        device=args.device,
        learning_rate=args.learning_rate,
        epochs=args.epochs,
        batch_size=args.batch_size,
        checkpoint=args.checkpoint,
        tracking_config_path=args.tracking_config_path,
        validation_config_path=args.validation_config_path,
        val_path=args.val_path
    )


from detection import detect_people
from scipy.spatial import distance as dist
import numpy as np
import streamlit as st
import cv2

def video_detect(video_name, MIN_CONF):

    cuda = 'False'

    labelsPath = "yolo-coco/coco.names"
    LABELS = open(labelsPath).read().strip().split("\n")

    USE_GPU = bool(cuda)
    MIN_DISTANCE = 50
    file_url = 'https://pjreddie.com/media/files/yolov3.weights'
    file_name = wget.download(file_url)
    #weightsPath = "yolov3.weights"
    weightsPath = file_name
    configPath = "yolo-coco/yolov3.cfg"

    net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)

    if USE_GPU:
        net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
        net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

    ln = net.getLayerNames()
    ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]

    vs = cv2.VideoCapture(video_name)
    writer = None
    image_placeholder = st.empty()
    while True:

        (grabbed, frame) = vs.read()

        if not grabbed:
            break

        frame = cv2.resize(frame, (700,700))
        results = detect_people(frame, net, ln,
                                personIdx=LABELS.index("person"))

        violate = set()

        if len(results) >= 2:

            centroids = np.array([r[2] for r in results])
            D = dist.cdist(centroids, centroids, metric="euclidean")

            for i in range(0, D.shape[0]):
                for j in range(i + 1, D.shape[1]):

                    if D[i, j] < MIN_DISTANCE:

                        violate.add(i)
                        violate.add(j)

        for (i, (prob, bbox, centroid)) in enumerate(results):

            (startX, startY, endX, endY) = bbox
            (cX, cY) = centroid
            color = (0, 255, 0)

            if i in violate:
                color = (0, 0, 255)

            cv2.rectangle(frame, (startX, startY), (endX, endY), color, 2)
            #cv2.circle(frame, (cX, cY), 5, color, 1)

        font = cv2.FONT_HERSHEY_SIMPLEX
        #datet = str(datetime.datetime.now())
        #frame = cv2.putText(frame, datet, (0, 35), font, 1,
         #                   (0, 255, 255), 2, cv2.LINE_AA)
        text = "Social Distancing Violations: {}".format(len(violate))
        cv2.putText(frame, text, (10, frame.shape[0] - 25),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.85, (0, 0, 255), 3)

        display = 1
        if display > 0:

            image_placeholder.image(
                frame, caption='Live Social Distancing Monitor Running..!', channels="BGR")

        if writer is not None:
            writer.write(frame)


from typing import Tuple
import numpy as np
import paddle
from paddle import Tensor
from paddle import nn
from paddle.nn import functional as F

def frame(x: Tensor,
          num_samples: Tensor,
          win_length: int,
          hop_length: int,
          clip: bool = True) -> Tuple[Tensor, Tensor]:
    """Extract frames from audio.

    Parameters
    ----------
    x : Tensor
        Shape (N, T), batched waveform.
    num_samples : Tensor
        Shape (N, ), number of samples of each waveform.
    win_length : int
        Window length.
    hop_length : int
        Number of samples shifted between ajancent frames.
    clip : bool, optional
        Whether to clip audio that does not fit into the last frame, by
        default True

    Returns
    -------
    frames : Tensor
        Shape (N, T', win_length).
    num_frames : Tensor
        Shape (N, ) number of valid frames
    """
    assert hop_length <= win_length
    num_frames = (num_samples - win_length) // hop_length
    padding = (0, 0)
    if not clip:
        num_frames += 1
        # NOTE: pad hop_length - 1 to the right to ensure that there is at most
        # one frame dangling to the righe edge
        padding = (0, hop_length - 1)

    weight = paddle.eye(win_length).unsqueeze(1)

    frames = F.conv1d(x.unsqueeze(1),
                      weight,
                      padding=padding,
                      stride=(hop_length, ))
    return frames, num_frames

class STFT(nn.Layer):
    """A module for computing stft transformation in a differentiable way.

    Parameters
    ------------
    n_fft : int
        Number of samples in a frame.

    hop_length : int
        Number of samples shifted between adjacent frames.

    win_length : int
        Length of the window.

    clip: bool
        Whether to clip audio is necesaary.
    """
    def __init__(self,
                 n_fft: int,
                 hop_length: int,
                 win_length: int,
                 window_type: str = None,
                 clip: bool = True):
        super().__init__()

        self.hop_length = hop_length
        self.n_bin = 1 + n_fft // 2
        self.n_fft = n_fft
        self.clip = clip

        # calculate window
        if window_type is None:
            window = np.ones(win_length)
        elif window_type == "hann":
            window = np.hanning(win_length)
        elif window_type == "hamming":
            window = np.hamming(win_length)
        else:
            raise ValueError("Not supported yet!")

        if win_length < n_fft:
            window = F.pad(window, (0, n_fft - win_length))
        elif win_length > n_fft:
            window = window[:n_fft]

        # (n_bins, n_fft) complex
        kernel_size = min(n_fft, win_length)
        weight = np.fft.fft(np.eye(n_fft))[:self.n_bin, :kernel_size]
        w_real = weight.real
        w_imag = weight.imag

        # (2 * n_bins, kernel_size)
        w = np.concatenate([w_real, w_imag], axis=0)
        w = w * window

        # (2 * n_bins, 1, kernel_size) # (C_out, C_in, kernel_size)
        w = np.expand_dims(w, 1)
        weight = paddle.cast(paddle.to_tensor(w), paddle.get_default_dtype())
        self.register_buffer("weight", weight)

    def forward(self, x: Tensor, num_samples: Tensor) -> Tuple[Tensor, Tensor]:
        """Compute the stft transform.
        Parameters
        ------------
        x : Tensor [shape=(B, T)]
            The input waveform.
        num_samples : Tensor
            Number of samples of each waveform.
        Returns
        ------------
        D : Tensor
            Shape(N, T', n_bins, 2) Spectrogram.

        num_frames: Tensor
            Shape (N,) number of samples of each spectrogram
        """
        num_frames = (num_samples - self.win_length) // self.hop_length
        padding = (0, 0)
        if not self.clip:
            num_frames += 1
            padding = (0, self.hop_length - 1)

        batch_size, _, _ = paddle.shape(x)
        x = x.unsqueeze(-1)
        D = F.conv1d(self.weight,
                     x,
                     stride=(self.hop_length, ),
                     padding=padding,
                     data_format="NLC")
        D = paddle.reshape(D, [batch_size, -1, self.n_bin, 2])
        return D, num_frames


from tkinter import *
import speech_recognition as sr
import pyttsx3
from datetime import datetime

import webbrowser
import subprocess

root = Tk()
root.geometry("500x500")
root.title("Speech Recognition")
root.configure(bg="cornflower blue")

label1 = Label(root,text="Welcome to your persnol desktop assistant",bg="cornflower blue",font=("Arial",15,"bold"))
label1.place(relx=0.5,rely=0.2,anchor=CENTER)

text_to_speech = pyttsx3.init()

def speak(audio):
    text_to_speech.say(audio)
    text_to_speech.runAndWait()

def r_audio():
    speak("How can i help you")
    speech_recognizer = sr.Recognizer()
    with sr.Microphone() as source:
        audio = speech_recognizer.listen(source)
        voice_data = ""
        try:
            voice_data = speech_recognizer.recognize_google(audio,language="en-in")
        except sr.UnknownValueError:
            print("Please repeat i did not get that")
            speak("Please repeat i did not get that")
            r_audio()
    print(voice_data)

    respond(voice_data)

def respond(voice_data):
    lower = voice_data.lower()

    if "name" in lower:
        print("My name is Ethihas")
        speak("My name is Ethihas")
    if "time" in lower:
        now = datetime.now()
        current_time = now.strftime("%H:%M:%S")
        print(current_time)
        speak(current_time)
    if "search" in lower:
        print("Opening Google")
        speak("Opening Google")
        webbrowser.get().open("https://www.google.com/")
    if "videos" in lower:
        print("Opening youtube")
        speak("Opening youtube")
        webbrowser.get().open("https://www.youtube.com/")
    if "editor" in lower:
        print("Opening notepad")
        speak("Opening notepad")
        subprocess.Popen(["notepad.exe"])

btn = Button(root,text="Start",bg="orange",fg="cyan",command=r_audio(),padx=10,pady=1,font=("Arial",11,"bold"),relif=FLAT)
btn.place(relx=0.5,rely=0.7,anchor=CENTER)
root.mainloop()


from PyQt5 import QtCore
from PyQt5 import uic
from PyQt5 import QtWidgets, QtGui
import pyqtgraph as pg
import os
import sys
from PyQt5.QtCore import QCoreApplication

from . import define as define
import logging as log
log.basicConfig(level=log.INFO)
logging = log.getLogger(__name__)

if True:
    translate = QCoreApplication.translate

    def _(text):
        return translate('signal', text)
else:
    import gettext
    _ = gettext.gettext

class plotStyler(QtWidgets.QDialog):
    def __init__(self, plot=None, title="", stylesheet=""):
        super(plotStyler, self).__init__()
        if getattr(sys, 'frozen', False):
            # frozen
            packagedir = os.path.dirname(sys.executable)+'/RTOC/RTOC_GUI'
        else:
            # unfrozen
            packagedir = os.path.dirname(os.path.realpath(__file__))
        uic.loadUi(packagedir+"/ui/stylePlotDialog2.ui", self)
        self.setWindowTitle(title)
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        self.setStyleSheet(stylesheet)
        self.setCallbacks()
        self.plot = plot
        self.lineColor = None
        self.fillLevel = None
        self.symbolColor = None
        self.symbolPenColor = None
        self.shadowColor = None
        self.fillColor = None
        self.brush = {}
        self.symbol = {}
        self.colorDialog = QtGui.QColorDialog()
        self.colorDialog.hide()
        self.colorLayout.addWidget(self.colorDialog)
        self.colorDialog.colorSelected.connect(self.setColor)
        if plot is not None:
            symbol, brush = getStyle(plot)
            self.setGUIStyle(symbol, brush)

    def setCallbacks(self):
        self.cancelButton.clicked.connect(self.close)
        self.styleButton.clicked.connect(self.setStyleAction)
        self.lineColorButton.clicked.connect(self.setLineColor)
        self.shadowColorButton.clicked.connect(self.setShadowColor)
        self.symbolColorButton.clicked.connect(self.setSymbolColor)
        self.fillColorButton.clicked.connect(self.setFillColor)
        self.symbolPenColorButton.clicked.connect(self.setSymbolPenColor)
        self.fillColorSpinBox.valueChanged.connect(self.setFillLevel)
        self.deleteFillButton.clicked.connect(self.deleteFill)

    def setLineColor(self):
        self.colorDialog.show()
        self.setMinimumSize(1100, 500)
        self.resize(1100, 500)
        self.lineColorButton.setStyleSheet("background-color:" + self.lineColor)

    def setShadowColor(self):
        self.colorDialog.show()
        self.setMinimumSize(1100, 500)
        self.resize(1100, 500)
        self.shadowColorButton.setStyleSheet("background-color:" + self.shadowColor)

    def setColor(self):
        color = self.colorDialog.currentColor().name()
        stylesheet = "background-color:" + color
        if self.lineColorButton.isChecked():
            self.lineColor = color
            self.lineColorButton.setStyleSheet(stylesheet)
            self.lineColorButton.setChecked(False)
        if self.shadowColorButton.isChecked():
            self.shadowColor = color
            self.shadowColorButton.setStyleSheet(stylesheet)
            self.shadowColorButton.setChecked(False)

        if self.symbolColorButton.isChecked():
            self.symbolColor = color
            self.symbolColorButton.setStyleSheet(stylesheet)
            self.symbolColorButton.setChecked(False)

        if self.symbolPenColorButton.isChecked():
            self.symbolPenColor = color
            self.symbolPenColorButton.setStyleSheet(stylesheet)
            self.symbolPenColorButton.setChecked(False)

        if self.fillColorButton.isChecked():
            self.fillColor = color
            self.fillColorButton.setStyleSheet(stylesheet)
            self.fillColorButton.setChecked(False)

        self.colorDialog.hide()
        self.setMinimumSize(466, 500)
        self.resize(466, 500)

    def setSymbolColor(self):
        self.colorDialog.show()
        self.setMinimumSize(1100, 500)
        self.resize(1100, 500)
        if self.symbolColor is not None:
            self.symbolColorButton.setStyleSheet("background-color:" + str(self.symbolColor))

    def setFillColor(self):
        self.colorDialog.show()
        self.setMinimumSize(1100, 500)
        self.resize(1100, 500)
        if self.fillColor is not None:
            self.fillColorButton.setStyleSheet("background-color:" + str(self.fillColor))
        self.fillLevel = self.fillColorSpinBox.value()

    def setSymbolPenColor(self):
        self.colorDialog.show()
        self.setMinimumSize(1100, 500)
        self.resize(1100, 500)
        if self.symbolPenColor is not None:
            self.symbolPenColorButton.setStyleSheet("background-color:" + str(self.symbolPenColor))

    def setFillLevel(self):
        self.fillLevel = self.fillColorSpinBox.value()

    def deleteFill(self):
        self.fillLevel = None
        self.fillColorSpinBox.setValue(0)
        self.fillColor = None
        self.fillColorButton.setStyleSheet("")

    def setStyleAction(self, plot=None):
        plot = self.plot
        symbol, brush = self.getGUIStyle()
        setStyle(plot, symbol, brush)
        self.symbol, self.brush = getStyle(plot)
        self.accept()

    def setGUIStyle(self, symbol, brush):
        if "style" in symbol.keys():
            style = symbol["style"]
            idx = 0
            if style == QtCore.Qt.SolidLine:
                idx = 0
            elif style == QtCore.Qt.DotLine:
                idx = 1
            elif style == QtCore.Qt.DashLine:
                idx = 2
            elif style == QtCore.Qt.DashDotLine:
                idx = 3
            elif style == QtCore.Qt.DashDotDotLine:
                idx = 4
            self.lineStyleComboBox.setCurrentIndex(idx)

        if "shadowStyle" in symbol.keys():
            style = symbol["shadowStyle"]
            idx = 0
            if style == QtCore.Qt.SolidLine:
                idx = 1
            elif style == QtCore.Qt.DotLine:
                idx = 2
            elif style == QtCore.Qt.DashLine:
                idx = 3
            elif style == QtCore.Qt.DashDotLine:
                idx = 4
            elif style == QtCore.Qt.DashDotDotLine:
                idx = 5
            self.shadowStyleComboBox.setCurrentIndex(idx)

        if "alpha" in symbol.keys():
            self.alphaSpinBox.setValue(int(symbol["alpha"]*100))
        if "width" in symbol.keys():
            self.lineWidthSpinBox.setValue(symbol["width"])

        if "shadowWidth" in symbol.keys():
            self.shadowWidthSpinBox.setValue(symbol["shadowWidth"])

        if "color" in symbol.keys():
            self.lineColor = symbol["color"]
            if type(self.lineColor) == str:
                self.lineColorButton.setStyleSheet("background-color:"+str(self.lineColor))
            elif type(self.lineColor) == tuple:
                self.lineColorButton.setStyleSheet("background-color:"+str(self.lineColor))
            elif self.shadowColor is not None:
                self.lineColorButton.setStyleSheet("background-color:"+str(self.lineColor.name()))

        if "shadowColor" in symbol.keys():
            self.shadowColor = symbol["shadowColor"]
            if type(self.shadowColor) == str:
                self.shadowColorButton.setStyleSheet("background-color:"+str(self.shadowColor))
            elif type(self.shadowColor) == tuple:
                self.shadowColorButton.setStyleSheet("background-color:"+str(self.shadowColor))
            elif self.shadowColor is not None:
                self.shadowColorButton.setStyleSheet(
                    "background-color:"+str(self.shadowColor.name()))

        if "style" in brush.keys():
            style = brush["style"]
            idx = 0
            if style == "d":
                idx = 0
            elif style == "o":
                idx = 1
            elif style == "x":
                idx = 2
            elif style == "s":
                idx = 3
            elif style == "t":
                idx = 4
            elif style == "+":
                idx = 5
            self.symbolComboBox.setCurrentIndex(idx)

        if "size" in brush.keys():
            self.symbolSizeSpinBox.setValue(brush["size"])

        if "color" in brush.keys():
            self.symbolColor = brush["color"]
            if type(self.symbolColor) == str:
                self.symbolColorButton.setStyleSheet("background-color:"+str(self.symbolColor))
            elif type(self.symbolColor) == tuple:
                self.symbolColorButton.setStyleSheet("background-color:"+str(self.symbolColor))
            elif self.shadowColor is not None:
                self.symbolColorButton.setStyleSheet(
                    "background-color:"+str(self.symbolColor.name()))

        if "fillBrush" in brush.keys():
            self.fillColor = brush["fillBrush"]
            if type(self.fillColor) == str:
                self.fillColorButton.setStyleSheet("background-color:"+str(self.fillColor))
            elif type(self.fillColor) == tuple:
                self.fillColorButton.setStyleSheet("background-color:"+str(self.fillColor))
            elif self.shadowColor is not None:
                self.fillColorButton.setStyleSheet("background-color:"+str(self.fillColor.name()))

        if "pen" in brush.keys():
            self.symbolPenColor = brush["pen"]
            if type(self.symbolPenColor) == str:
                self.symbolPenColorButton.setStyleSheet(
                    "background-color:"+str(self.symbolPenColor))
            elif type(self.symbolPenColor) == tuple:
                self.symbolPenColorButton.setStyleSheet(
                    "background-color:"+str(self.symbolPenColor))
            elif self.shadowColor is not None:
                self.symbolPenColorButton.setStyleSheet(
                    "background-color:"+str(self.symbolPenColor.name()))

        if "fillLevel" in brush.keys():
            if brush["fillLevel"] is not None:
                self.fillLevel = brush["fillLevel"]
                self.fillColorSpinBox.setValue(self.fillLevel)

    def getGUIStyle(self):
        symbol = {}
        brush = {}
        style = self.lineStyleComboBox.currentText()
        if style == translate('RTOC', 'Line'):
            symbol["style"] = QtCore.Qt.SolidLine
        elif style == translate('RTOC', 'Dots (D)'):
            symbol["style"] = QtCore.Qt.DotLine
        elif style == translate('RTOC', 'Strokes (S)'):
            symbol["style"] = QtCore.Qt.DashLine
        elif style == translate('RTOC', 'D S'):
            symbol["style"] = QtCore.Qt.DashDotLine
        elif style == translate('RTOC', 'D D S'):
            symbol["style"] = QtCore.Qt.DashDotDotLine
        else:
            logging.warning('no style applied')

        style = self.shadowStyleComboBox.currentText()
        if style == translate('RTOC', 'Line'):
            symbol["shadowStyle"] = QtCore.Qt.SolidLine
        elif style == translate('RTOC', 'Dots (D)'):
            symbol["shadowStyle"] = QtCore.Qt.DotLine
        elif style == translate('RTOC', 'Strokes (S)'):
            symbol["shadowStyle"] = QtCore.Qt.DashLine
        elif style == translate('RTOC', 'D S'):
            symbol["shadowStyle"] = QtCore.Qt.DashDotLine
        elif style == translate('RTOC', 'D D S'):
            symbol["shadowStyle"] = QtCore.Qt.DashDotDotLine
        else:
            symbol["shadowStyle"] = 0

        symbol["alpha"] = self.alphaSpinBox.value()/100
        symbol["width"] = self.lineWidthSpinBox.value()
        symbol["shadowWidth"] = self.shadowWidthSpinBox.value()
        if self.lineColor is not None:
            symbol["color"] = self.lineColor

        symbol["shadowColor"] = self.shadowColor

        style = self.symbolComboBox.currentText()
        if style in [translate('RTOC', 'Rectangle'), translate('RTOC', 'Diamond')]:
            brush["style"] = "d"
        elif style == translate('RTOC', 'Circle'):
            brush["style"] = "o"
        elif style == "X":
            brush["style"] = "x"
        elif style == translate('RTOC', 'Square'):
            brush["style"] = "s"
        elif style == translate('RTOC', 'Triangle'):
            brush["style"] = "t"
        elif style == "Plus":
            brush["style"] = "+"
        else:
            brush["style"] = ""

        brush["size"] = self.symbolSizeSpinBox.value()

        if self.symbolColor is not None:
            brush["color"] = self.symbolColor

        if self.symbolPenColor is not None:
            brush["pen"] = self.symbolPenColor

        brush["fillLevel"] = self.fillLevel
        brush["fillBrush"] = self.fillColor

        return symbol, brush

def getStyle(plot):
    symbol = {}
    brush = {}

    opts = plot.opts

    symbol["style"] = opts['pen'].style()
    symbol["width"] = opts['pen'].width()
    symbol["color"] = opts['pen'].color().name()
    symbol["alpha"] = opts["alphaHint"]
    if opts['shadowPen'] is not None:
        symbol["shadowColor"] = opts['shadowPen'].color().name()
        symbol["shadowWidth"] = opts['shadowPen'].width()
        symbol["shadowStyle"] = opts['shadowPen'].style()
    else:
        symbol["shadowColor"] = None
        symbol["shadowWidth"] = 0
        symbol["shadowStyle"] = 0
        # 'shadowPen': None,
    brush["fillLevel"] = opts['fillLevel']
    if opts['fillBrush'] is not None:
        if type(opts['symbolBrush']) == tuple:
            brush["fillBrush"] = opts['fillBrush']
        else:
            brush["fillBrush"] = opts['fillBrush'].color().name()
            # 'fillBrush': None,

    brush["style"] = opts['symbol']
    brush["size"] = opts['symbolSize']
    if type(opts['symbolBrush']) == tuple:
        brush["color"] = opts['symbolBrush']
    else:
        brush["color"] = opts['symbolBrush'].color().name()

    if type(opts['symbolPen']) == tuple:
        brush["pen"] = opts['symbolPen']
    else:
        brush["pen"] = opts['symbolPen'].color().name()
    return symbol, brush

def setStyle(plot, symbol={}, brush={}):
    if symbol != {}:
        if "width" not in symbol.keys():
            symbol["width"] = define.defaultLineWidth
        if "style" not in symbol.keys():
            symbol["style"] = 1
        if "shadowWidth" not in symbol.keys():
            symbol["shadowWidth"] = None
        if "shadowStyle" not in symbol.keys():
            symbol["shadowStyle"] = None
        pen = pg.mkPen(color=symbol["color"], width=int(
            symbol["width"]), style=int(symbol["style"]))
        plot.setPen(pen)
        # logging.debug(symbol["style"])
        if symbol["shadowWidth"] is not None and symbol["shadowStyle"] is not None:
            plot.setShadowPen(color=symbol["shadowColor"], width=int(
                symbol["shadowWidth"]), style=int(symbol["shadowStyle"]), cosmetic=True)
        else:
            plot.setShadowPen(None)
    if "alpha" in symbol.keys():
        plot.setAlpha(symbol["alpha"], False)

    for key in brush.keys():
        if key == "style":
            if brush["style"] != "":
                plot.setSymbol(brush["style"])
            else:
                plot.setSymbol(None)
        elif key == "color":
            c = brush["color"]
            plot.setSymbolBrush(c)
        elif key == "size":
            plot.setSymbolSize(brush["size"])
        elif key == "fillLevel":
            plot.setFillLevel(brush["fillLevel"])
        elif key == "fillBrush":
            plot.setFillBrush(brush["fillBrush"])
        elif key == "pen":
            plot.setSymbolPen(brush["pen"])


"""Functions for working with songs."""
import logging
from typing import List

from cache import use_cache
from google_music import get_all_songs as get_all_songs_from_server

def get_all_songs() -> List[dict]:
    """Return songs."""

    logging.debug("Getting songs")

    songs = use_cache("songs", lambda: list(get_all_songs_from_server()))

    return songs

def summarise_song(song: dict) -> str:
    """Return a string representation of a song."""

    track = song["trackNumber"]
    artist = song["artist"]
    title = song["title"]
    album = song["album"]
    duration_millis = int(song["durationMillis"])
    duration_seconds = duration_millis / 1000
    duration_minutes, seconds = divmod(duration_seconds, 60)
    hours, minutes = divmod(duration_minutes, 60)
    plays = song["playCount"]

    return (
        f"{track} - {artist} - {album} - {title} "
        f"[{hours:02.0f}:{minutes:02.0f}:{seconds:02.0f}] "
        f"({plays} plays)"
    )


import sys
import logging
from diro2c.data_generation.helper import *
import pandas as pd
import numpy as np
from diro2c.data_generation.neighborhood_generation import modified_gpdatagenerator
from diro2c.data_generation.distance_functions import simple_match_distance, normalized_euclidean_distance, mixed_distance
import _pickle as cPickle
from diro2c.enums.diff_classifier_method_type import diff_classifier_method_type
from diro2c.data_generation.neighborhood_generation.gpdatagenerator import calculate_feature_values
from sklearn.tree import DecisionTreeClassifier
from sklearn import metrics
from data.getdata import loaddata, prepare_df
from data.split3fold import split3fold
from scipy.cluster.hierarchy import linkage, fcluster
import pickle
from collections import defaultdict
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from datetime import date
from FromLocalToGlobal import getglobal, getexplainer, clusterbasedinstances, stratifiedrandominstances, randominstances

if __name__ == '__main__':

    data = sys.argv[1]
    methodin = sys.argv[2]

    if methodin == 'randominstances':
        method = randominstances
        methodname = '"Approach 1: Random sampling"'
        npointsin = [8,16,32,64]
        ts = [1]
    elif methodin == 'classstratifiedinstances':
        method = stratifiedrandominstances
        methodname = '"Approach 2: Class-stratified sampling"'
        npointsin = [8,16,32,64]
        ts = [1]
    elif methodin == 'clusterbasedinstances':
        method = clusterbasedinstances
        methodname = '"Approach 3: Cluster-stratified sampling"'

    if data == 'compas':
        ts = [{'2|0': 2.5, '0|1': 7.5,'2|1': 5, '1|2': 2,'0|2': 4, '1|0': 5},
              {'2|0': 4, '0|1': 15,'2|1': 10, '1|2': 7,'0|2': 12, '1|0': 15},
              {'2|0': 4, '0|1': 15,'2|1': 10, '1|2': 4.5,'0|2': 6, '1|0': 10}]
        npointsin = [1]
    elif data == 'bankmarketing':
        ts = [{'0|1': 25, '1|0': 10},
              {'0|1': 30, '1|0': 15},
              {'0|1': 20, '1|0': 7.5}]
        npointsin = [1]

    logging.basicConfig(filename='FromLocalToGlobalfit'+str(date.today())+'_'+data+'_'+methodin+'.log',
                        level=logging.DEBUG, format = '%(asctime)s %(message)s')
    performancefile = 'FromLocalToGlobalperformance'+str(date.today())+'_'+data+'_'+methodin+'.txt'

    with open(performancefile, 'a') as myfile:
        myfile.write('model data iteration npoints maxdepthexplainer depthexplainer leavesexplainer accuracy precisionmacro recallmacro\n')

    dataA, dataB, cols, discrete, continuous, le = loaddata(data)
    blackboxtrainA, trainA, testA = split3fold(dataA, 0.4, 0.2, random_state=1)
    blackboxtrainB, trainB, testB = split3fold(dataB, 0.4, 0.2, random_state=1)
    modelA = pickle.load(open('blackboxes/'+data+'A.sav', 'rb'))
    modelB = pickle.load(open('blackboxes/'+data+'B.sav', 'rb'))

    train = pd.concat([trainA, trainB])
    train['predA'] = modelA.predict(train[cols].values)
    train['predB'] = modelB.predict(train[cols].values)
    train['difference'] = train.apply(lambda row: str(int(row['predA'])) + '|' + str(int(row['predB'])), axis = 1)
    train.drop(columns=['predA', 'predB', 'y'], inplace=True, errors='ignore')
    train = train.reset_index(drop=True)

    test = pd.concat([testA, testB])
    test['predA'] = modelA.predict(test[cols].values)
    test['predB'] = modelB.predict(test[cols].values)
    test['difference'] = test.apply(lambda row: str(int(row['predA'])) + '|' + str(int(row['predB'])), axis = 1)
    test.drop(columns=['predA', 'predB', 'y'], inplace=True)
    test = test.reset_index(drop=True)

    discrete.append('difference')
    populationsize = 1000

    if methodin == 'advancedstratifiedrandominstances':
        for i in range(5):
            logging.info('start processing round: ' + str(i))
            for t in ts:
                globaldata = getglobal(train, classname='difference', npoints=1, populationsize=populationsize,
                                       method=method, random_state=i, discrete = discrete, continuous=continuous, t = t)
                nchoseninstances = len(np.unique(globaldata.index.get_level_values(0)))
                filename = 'neighborhoods/' + methodin + '_round' + str(i) + '_' + str(nchoseninstances) + '_' + data + '.npy'
                with open(filename, 'wb') as f:
                    np.save(f, globaldata)
                for j in [3,5,7,None]:
                    globalexplainer = getexplainer(globaldata.values, modelA, modelB, max_depth = j)
                    pred = globalexplainer.predict(test[cols].values)
                    with open(performancefile, 'a') as f:
                        line = ' '.join([methodname,
                                         data,
                                         str(i),
                                         str(nchoseninstances),
                                         str(j),
                                         str(globalexplainer.get_depth()),
                                         str(globalexplainer.get_n_leaves()),
                                         str(metrics.accuracy_score(test.difference, pred)),
                                         str(metrics.precision_score(test.difference, pred, average='macro')),
                                         str(metrics.recall_score(test.difference, pred, average='macro'))
                                         ])
                        f.write(line + '\n')
                logging.info('    finished nchoseninstances: ' + str(nchoseninstances))
    else:
        for i in range(5):
            logging.info('start processing round: ' + str(i))
            for npoints in npointsin:
                globaldata = getglobal(train, classname='difference', npoints=npoints, populationsize=populationsize,
                                       method=method, random_state=i, discrete = discrete, continuous=continuous)
                filename = 'neighborhoods/' + methodin + '_round' + str(i) + '_' + str(npoints) + '_' + data +'.npy'
                with open(filename, 'wb') as f:
                    np.save(f, globaldata)
                for j in [3,5,7,None]:
                    globalexplainer = getexplainer(globaldata.values, modelA, modelB, max_depth = j)
                    pred = globalexplainer.predict(test[cols].values)
                    with open(performancefile, 'a') as f:
                        line = ' '.join([methodname,
                                         data,
                                         str(i),
                                         str(npoints),
                                         str(j),
                                         str(globalexplainer.get_depth()),
                                         str(globalexplainer.get_n_leaves()),
                                         str(metrics.accuracy_score(test.difference, pred)),
                                         str(metrics.precision_score(test.difference, pred, average='macro')),
                                         str(metrics.recall_score(test.difference, pred, average='macro'))
                                         ])
                        f.write(line + '\n')
                logging.info('    finished npoints: ' + str(npoints))


import sys
import unittest
try:
    from unittest.mock import MagicMock
except ImportError:
    from mock import MagicMock
import botocore

##############
# Parameters #
##############

# Define the default resource to report to Config Rules
DEFAULT_RESOURCE_TYPE = 'AWS::ElastiCache::CacheCluster'

#############
# Main Code #
#############

CONFIG_CLIENT_MOCK = MagicMock()
STS_CLIENT_MOCK = MagicMock()
EC_CLIENT_MOCK = MagicMock()

class Boto3Mock():
    sample = 123
    def client(self, client_name, *args, **kwargs):
        self.sample = 123
        if client_name == 'config':
            return CONFIG_CLIENT_MOCK
        if client_name == 'sts':
            return STS_CLIENT_MOCK
        if client_name == 'elasticache':
            return EC_CLIENT_MOCK
        raise Exception("Attempting to create an unknown client")

sys.modules['boto3'] = Boto3Mock()

RULE = __import__('ELASTICACHE_REDIS_CLUSTER_AUTO_BACKUP_CHECK')

def replication_groups_se(**kwargs):
    if 'Marker' not in kwargs:
        return {'ReplicationGroups': [{'ReplicationGroupId':'ABC', 'SnapshotRetentionLimit': 16}], 'Marker': 'ABC'}
    return {'ReplicationGroups': [{'ReplicationGroupId':'DEF', 'SnapshotRetentionLimit': 10}]}

class CompliantResourceTest(unittest.TestCase):

    def test_scenario_5_is_compliant(self):
        EC_CLIENT_MOCK.describe_cache_clusters = MagicMock(return_value={'CacheClusters': [{'CacheClusterId':'GHI', 'SnapshotRetentionLimit': 16, 'Engine': 'redis'}]})
        EC_CLIENT_MOCK.describe_replication_groups.side_effect = replication_groups_se
        lambda_result = RULE.lambda_handler(build_lambda_scheduled_event('{"SnapshotRetentionPeriod":"15"}'), {})
        print(lambda_result)
        assert_successful_evaluation(self, lambda_result, [build_expected_response('COMPLIANT', "GHI"),
                                                           build_expected_response('COMPLIANT', "ABC"),
                                                           build_expected_response('NON_COMPLIANT', "DEF", annotation="Automatic backup retention period for Amazon ElastiCache cluster DEF is less then 15 day(s).")
                                                          ], len(lambda_result))

class NonCompliantResourceTest(unittest.TestCase):

    def test_scenario_4_low_retention(self):
        EC_CLIENT_MOCK.describe_cache_clusters = MagicMock(return_value={'CacheClusters': [{'CacheClusterId':'ABC', 'SnapshotRetentionLimit': 16, 'Engine': 'redis'}]})
        EC_CLIENT_MOCK.describe_replication_groups = MagicMock(return_value={'ReplicationGroups': []})
        lambda_result = RULE.lambda_handler(build_lambda_scheduled_event('{"SnapshotRetentionPeriod":"15"}'), {})
        assert_successful_evaluation(self, lambda_result, [build_expected_response("COMPLIANT", "ABC")], len(lambda_result))

    def test_scenario_3_no_auto_backup(self):
        # compliance_type, compliance_resource_id, compliance_resource_type=DEFAULT_RESOURCE_TYPE, annotation=None
        EC_CLIENT_MOCK.describe_cache_clusters = MagicMock(return_value={'CacheClusters': [{'CacheClusterId':'ABCD', 'SnapshotRetentionLimit': 0, 'Engine': 'redis'}]})
        EC_CLIENT_MOCK.describe_replication_groups = MagicMock(return_value={'ReplicationGroups': []})
        lambda_result = RULE.lambda_handler(build_lambda_scheduled_event('{"SnapshotRetentionPeriod":"15"}'), {})
        assert_successful_evaluation(self, lambda_result, [build_expected_response("NON_COMPLIANT", "ABCD", annotation="Automatic backup not enabled for Amazon ElastiCache cluster: ABCD")], len(lambda_result))

class ErrorTest(unittest.TestCase):

    def test_scenario_2_parameter_error(self):
        lambda_result = RULE.lambda_handler(build_lambda_scheduled_event('{"SnapshotRetentionPeriod":"-1"}'), {})
        assert_customer_error_response(self, lambda_result, customer_error_message='SnapshotRetentionPeriod value should be an integer greater than 0', customer_error_code='InvalidParameterValueException')

class NotApplicableResourceTest(unittest.TestCase):

    def test_scenario_1_no_resources(self):
        EC_CLIENT_MOCK.describe_cache_clusters = MagicMock(return_value={'CacheClusters': []})
        EC_CLIENT_MOCK.describe_replication_groups = MagicMock(return_value={'ReplicationGroups': []})
        lambda_result = RULE.lambda_handler(build_lambda_scheduled_event('{"SnapshotRetentionPeriod":"15"}'), {})
        assert_successful_evaluation(self, lambda_result, [build_expected_response("NOT_APPLICABLE", "123456789012")], len(lambda_result))

####################
# Helper Functions #
####################

def build_lambda_configurationchange_event(invoking_event, rule_parameters=None):
    event_to_return = {
        'configRuleName':'myrule',
        'executionRoleArn':'roleArn',
        'eventLeftScope': False,
        'invokingEvent': invoking_event,
        'accountId': '123456789012',
        'configRuleArn': 'arn:aws:config:us-east-1:123456789012:config-rule/config-rule-8fngan',
        'resultToken':'token'
    }
    if rule_parameters:
        event_to_return['ruleParameters'] = rule_parameters
    return event_to_return

def build_lambda_scheduled_event(rule_parameters=None):
    invoking_event = '{"messageType":"ScheduledNotification","notificationCreationTime":"2017-12-23T22:11:18.158Z"}'
    event_to_return = {
        'configRuleName':'myrule',
        'executionRoleArn':'roleArn',
        'eventLeftScope': False,
        'invokingEvent': invoking_event,
        'accountId': '123456789012',
        'configRuleArn': 'arn:aws:config:us-east-1:123456789012:config-rule/config-rule-8fngan',
        'resultToken':'token'
    }
    if rule_parameters:
        event_to_return['ruleParameters'] = rule_parameters
    return event_to_return

def build_expected_response(compliance_type, compliance_resource_id, compliance_resource_type=DEFAULT_RESOURCE_TYPE, annotation=None):
    if not annotation:
        return {
            'ComplianceType': compliance_type,
            'ComplianceResourceId': compliance_resource_id,
            'ComplianceResourceType': compliance_resource_type
            }
    return {
        'ComplianceType': compliance_type,
        'ComplianceResourceId': compliance_resource_id,
        'ComplianceResourceType': compliance_resource_type,
        'Annotation': annotation
        }

def assert_successful_evaluation(test_class, response, resp_expected, evaluations_count=1):
    if isinstance(response, dict):
        test_class.assertEquals(resp_expected['ComplianceResourceType'], response['ComplianceResourceType'])
        test_class.assertEquals(resp_expected['ComplianceResourceId'], response['ComplianceResourceId'])
        test_class.assertEquals(resp_expected['ComplianceType'], response['ComplianceType'])
        test_class.assertTrue(response['OrderingTimestamp'])
        if 'Annotation' in resp_expected or 'Annotation' in response:
            test_class.assertEquals(resp_expected['Annotation'], response['Annotation'])
    elif isinstance(response, list):
        test_class.assertEquals(evaluations_count, len(response))
        for i, response_expected in enumerate(resp_expected):
            test_class.assertEquals(response_expected['ComplianceResourceType'], response[i]['ComplianceResourceType'])
            test_class.assertEquals(response_expected['ComplianceResourceId'], response[i]['ComplianceResourceId'])
            test_class.assertEquals(response_expected['ComplianceType'], response[i]['ComplianceType'])
            test_class.assertTrue(response[i]['OrderingTimestamp'])
            if 'Annotation' in response_expected or 'Annotation' in response[i]:
                test_class.assertEquals(response_expected['Annotation'], response[i]['Annotation'])

def assert_customer_error_response(test_class, response, customer_error_code=None, customer_error_message=None):
    if customer_error_code:
        test_class.assertEqual(customer_error_code, response['customerErrorCode'])
    if customer_error_message:
        test_class.assertEqual(customer_error_message, response['customerErrorMessage'])
    test_class.assertTrue(response['customerErrorCode'])
    test_class.assertTrue(response['customerErrorMessage'])
    if "internalErrorMessage" in response:
        test_class.assertTrue(response['internalErrorMessage'])
    if "internalErrorDetails" in response:
        test_class.assertTrue(response['internalErrorDetails'])

def sts_mock():
    assume_role_response = {
        "Credentials": {
            "AccessKeyId": "string",
            "SecretAccessKey": "string",
            "SessionToken": "string"}}
    STS_CLIENT_MOCK.reset_mock(return_value=True)
    STS_CLIENT_MOCK.assume_role = MagicMock(return_value=assume_role_response)

##################
# Common Testing #
##################

class TestStsErrors(unittest.TestCase):

    def test_sts_unknown_error(self):
        RULE.ASSUME_ROLE_MODE = True
        STS_CLIENT_MOCK.assume_role = MagicMock(side_effect=botocore.exceptions.ClientError(
            {'Error': {'Code': 'unknown-code', 'Message': 'unknown-message'}}, 'operation'))
        response = RULE.lambda_handler(build_lambda_configurationchange_event('{}'), {})
        assert_customer_error_response(
            self, response, 'InternalError', 'InternalError')

    def test_sts_access_denied(self):
        RULE.ASSUME_ROLE_MODE = True
        STS_CLIENT_MOCK.assume_role = MagicMock(side_effect=botocore.exceptions.ClientError(
            {'Error': {'Code': 'AccessDenied', 'Message': 'access-denied'}}, 'operation'))
        response = RULE.lambda_handler(build_lambda_configurationchange_event('{}'), {})
        assert_customer_error_response(
            self, response, 'AccessDenied', 'AWS Config does not have permission to assume the IAM role.')


import math
from geometry_msgs.msg import Point, Quaternion, Vector3
from scipy.interpolate import interp1d
import numpy as np
import tf.transformations

def distance(point1, point2):
    return math.sqrt( (point2.x-point1.x)**2 + (point2.y-point1.y)**2 + (point2.z-point1.z)**2 )

def vector_to_list(vec):
    return [vec.x, vec.y, vec.z]

def vector_from_to(p0, p1):
    v = Vector3()
    v.x = p1.x - p0.x
    v.y = p1.y - p0.y
    v.z = p1.z - p0.z
    return v

def unit_vector_from_to(point1, point2):
    return normalize(vector_from_to(point1, point2))

def magnitude_vector(vec):
    return math.sqrt(vec.x**2 + vec.y**2 + vec.z**2 )

def normalize(vec, magnitude=1.0):
    res = Vector3()
    m = magnitude_vector(vec)
    res.x = vec.x * magnitude / m
    res.y = vec.y * magnitude / m
    res.z = vec.z * magnitude / m
    return res

def dot(v1,v2):
    return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z

def scalar_multiply(a,v):
    res = Vector3()
    res.x = a * v.x
    res.y = a * v.y
    res.z = a * v.z
    return res

def point_plus_vector(point, vector):
    res = Vector3()
    res.x = point.x + vector.x
    res.y = point.y + vector.y
    res.z = point.z + vector.z
    return res

def point_to_vector(point):
    res = Vector3()
    res.x = point.x
    res.y = point.y
    res.z = point.z
    return res

# http://www.chrobotics.com/library/understanding-quaternions
# http://mathworld.wolfram.com/Quaternion.html
# http://kieranwynn.github.io/pyquaternion/
# http://docs.ros.org/lunar/api/geometry_msgs/html/msg/Quaternion.html
# http://wiki.ros.org/tf2/Tutorials/Quaternions
# http://www.chrobotics.com/library/understanding-euler-angles
# http://docs.ros.org/jade/api/tf/html/python/transformations.html

def rpy_to_vector(roll, pitch, yaw, magnitude=1.0):
    v = Point()
    v.y = math.sin(yaw)*math.cos(pitch)
    v.x = math.cos(yaw)*math.cos(pitch)
    v.z = - math.sin(pitch)
    return normalize(v, magnitude)

def quaternion_to_vector(quaternion, magnitude=1.0):
    tf_quat = [quaternion.x,quaternion.y,quaternion.z,quaternion.w]
    tf_euler = tf.transformations.euler_from_quaternion(tf_quat)
    return rpy_to_vector(tf_euler[0],tf_euler[1],tf_euler[2], magnitude)

def rotate_vector_wrt_quaternion(quaternion, vector):
    p = np.array([vector.x, vector.y, vector.z, 0])
    q = np.array([quaternion.x, quaternion.y, quaternion.z, quaternion.w])
    # p' = q * p * q'
    p_prime = tf.transformations.quaternion_multiply(
                tf.transformations.quaternion_multiply(q, p),
                tf.transformations.quaternion_inverse(q))
    return Vector3(*(p_prime[:3].tolist()))

#def rotate_vector_wrt_quaternion(q, v):
#    tf_quat = np.array([q.x, q.y, q.z, q.w])
#    tf_vec = np.array([v.x, v.y, v.z])
#    result = np.matmul(tf.transformations.quaternion_matrix(tf_quat)[:3, :3], tf_vec)
#    return Vector3(*(result.tolist()))

def rpy_to_quat(roll, pitch, yaw):
    quaternion_array = tf.transformations.quaternion_from_euler(roll, pitch, yaw, 'rxyz')
    result = Quaternion()
    result.x = quaternion_array[0]
    result.y = quaternion_array[1]
    result.z = quaternion_array[2]
    result.w = quaternion_array[3]
    return result

def vector_to_quat(vec):
    """To fully determine the orientation represented by the resulting quaternion, this method will assume the top of objects would always facing up
    """
    np_vec = np.array([vec.x, vec.y, vec.z])
    norm = np.linalg.norm(np_vec)
    if norm < 1e-5:
        return np.array([0.0, 0.0, 0.0, 1.0])
    obj_x = np.array([vec.x, vec.y, vec.z]) / norm
    obj_z_t = np.array([0.0, 0.0, 1.0])
    obj_y = np.cross(obj_z_t, obj_x)
    obj_y /= np.linalg.norm(obj_y)
    obj_z = np.cross(obj_x, obj_y)
    rot_mat = np.identity(4)
    rot_mat[:3,:3] = np.array([obj_x,
                               obj_y,
                               obj_z]).T
    q = tf.transformations.quaternion_from_matrix(rot_mat)
    return q / np.linalg.norm(q)

def points_to_spline(points):
    # returns "spline" data that can be used for mapping between path distance s and Point on the spline.
    # https://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html
    distance_so_far = 0.0
    last_point = points[0]
    distances = []
    for point in points:
        distances.append(distance_so_far + distance(last_point, point))
        distance_so_far = distances[-1]
    return {'x': interp1d(distances, [p.x for p in points], kind='cubic', bounds_error=False, fill_value="extrapolate"),
            'y': interp1d(distances, [p.y for p in points], kind='cubic', bounds_error=False, fill_value="extrapolate"),
            'z': interp1d(distances, [p.z for p in points], kind='cubic', bounds_error=False, fill_value="extrapolate"),
            'max_distance': distances[-1]}

def spline_distance_to_point(spline, distance):
    res = Point()
    res.x = spline['x'](distance)
    res.y = spline['y'](distance)
    res.z = spline['z'](distance)
    return res

def spline_distance_to_tangent(spline,distance):
    return unit_vector_from_to(spline_distance_to_point(spline, distance - 0.1), spline_distance_to_point(spline, distance + 0.1))

def spline_distance_to_curvature(spline, distance):
    # Centripetal acceleration = curvature * speed^2 where both acceleration and curvature have type Vector3.
    # Use example speed of 1 m/s2 to calculate acceleration, then convert to curvature.
    # https://opentextbc.ca/physicstestbook2/chapter/centripetal-acceleration/
    # https://en.wikipedia.org/wiki/Differential_geometry_of_curves#Normal_or_curvature_vector
    velocity_before = spline_distance_to_tangent(spline, distance - 0.1)
    velocity_after = spline_distance_to_tangent(spline, distance - 0.1)
    acceleration = scalar_multiply(1/0.2, vector_from_to(velocity_before, velocity_after))
    curvature = acceleration # because acceleration calculated using speed of 1.0 and acceleration=curvature*speed^2
    return curvature


import os
from jcamp import JCAMP_reader
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pickle

with open('./data/IR_ABSORBANCE.pickle', 'rb') as handle:
    dc = pickle.load(handle)

datals = []
ls = []
for i in dc.keys():
    df = pd.DataFrame(list(zip(dc[i]['x'], dc[i]['y'])), columns=['x', i])
    df = df.groupby('x').aggregate(np.mean)
    df.reset_index(inplace=True)
    datals.append(df)
    ls.append([np.min(np.diff(df.x)), np.min(df.x), np.max(df.x)])
arr = np.array(ls)
bins = np.arange(np.min(arr[:, 1])-0.1,
                 np.max(arr[:, 2])+0.1, np.mean(arr[:, 0]))

datals[0]['x'] = pd.cut(datals[0]['x'], bins)
df = datals[0].groupby('x').aggregate(np.mean)
df.reset_index(inplace=True)

for i, df_ in enumerate(datals[1:]):
    df_['x'] = pd.cut(df_['x'], bins)
    df_ = df_.groupby('x').aggregate(np.mean)
    df_.reset_index(inplace=True)
    df = df.merge(df_, on='x', how='outer')
df.iloc[:, 1:] = df.iloc[:, 1:].interpolate(limit_direction='both', axis=0)
# df.to_csv("interpolateIR_TRANS.csv", index=False)
cas_idx = '50293'
print(df[cas_idx])
plt.bar(list(map(str, df.index)), list(df[cas_idx]))
plt.tick_params(
    axis='x',          # changes apply to the x-axis
    which='both',      # both major and minor ticks are affected
    bottom=False,      # ticks along the bottom edge are off
    top=False,         # ticks along the top edge are off
    labelbottom=False)  # labels along the bottom edge are off
plt.title(cas_idx)
plt.show()


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

#import numpy as np
#import matplotlib.pyplot as pl
#from util.mysave import mysave
#from util.get_abel_file import get_abel_dir
#from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
import sys
import argparse

def main():
    parser = argparse.ArgumentParser(description='Script to start different simulation cases')
    parser.add_argument('run_case' )

if __name__ == "__main__":
    main()