# -*- coding: utf-8 -*-
import logging
from gunicorn import glogging
from werkzeug.datastructures import MultiDict
from werkzeug.wrappers import Request, Response
from jsonrpc import JSONRPCResponseManager, dispatcher

from .storage import Storage
from . import forms

def make_key(*segments):
    return '/'.join(map(str, segments))

def do_vote\
    ( user_id
    , resource_id
    , score
    , score_range
    , namespace
    ):

    data = MultiDict(locals().copy())
    form = forms.CommonForm(data)
    if not form.validate():
        return {'error': form.errors}

    # Отмена голосования
    # Если пользовать проголосовал как 0 то удаляем запись о голосе
    if score == 0:
        return do_vote_cancel\
            ( user_id
            , resource_id
            , score_range
            , namespace
            )

    key = make_key(namespace, score_range, resource_id)

    # Если пользователь не голосовал
    user_key = make_key(key, user_id, 'score')
    user_score = int(Storage().get(user_key) or 0)

    with Storage() as storage:
        storage.watch(user_key)

        if user_score != score:
            # Отменяем голосование
            do_vote_cancel\
                ( user_id
                , resource_id
                , score_range
                , namespace
                )
            user_data = None

            # Инкрементируем кол-во голосов
            storage.increment\
                ( make_key(key, 'count')
                , 1
                )
            # Увеличиваем общую сумму голосов
            storage.increment\
                ( make_key(key, 'sum')
                , score
                )
            # Сохраняем данные голосования пользователя
            storage.set(user_key, score)
            return True
        else:
            return False
dispatcher.add_method(do_vote, name='vote')

def do_vote_cancel\
    ( user_id
    , resource_id
    , score_range
    , namespace
    ):

    data = MultiDict(locals().copy())
    form = forms.CommonForm(data)
    if not form.validate():
        return {'error': form.errors}

    key = make_key(namespace, score_range, resource_id)
    user_key = make_key(key, user_id, 'score')

    # Получем кол-во голосов пользователя
    with Storage() as storage:
        storage.watch(user_key)

        user_score = Storage().get(user_key)

        if user_score is not None:
            # Декрементируем кол-во голосов
            storage.decrement\
                ( make_key(key, 'count')
                , 1
                )
            # Уменьшаем общую сумму голосов
            storage.decrement\
                ( make_key(key, 'sum')
                , user_score
                )
            # Удаляем информацию о голосе пользователя
            storage.delete(user_key)
    return True
dispatcher.add_method(do_vote_cancel, name='cancel_vote')

def get_rating\
    ( user_id
    , resource_id
    , score_range
    , namespace
    ):

    data = MultiDict(locals().copy())
    form = forms.GetRatingForm(data)
    if not form.validate():
        return {'error': form.errors}

    key = make_key\
        ( namespace
        , score_range
        , resource_id
        )
    score_count = int(Storage().get(make_key(key, 'count')) or 0)
    score_sum = int(Storage().get(make_key(key, 'sum')) or 0)

    user_result = 0
    if user_id:
        user_result = int(Storage().get(make_key(key, user_id, 'score')) or 0)

    return \
        { 'score':
          { 'count': score_count or 0
          , 'sum': score_sum or 0
          , 'avg': float(score_sum) / score_count if score_count else 0
          }
        , 'user': user_result
        }
dispatcher.add_method(get_rating, name='get_rating')

@Request.application
def application(request):
    response = JSONRPCResponseManager.handle\
        ( request.data
        , dispatcher
        )
    return Response\
        ( response.json
        , mimetype='application/json'
        , headers=
          { 'Access-Control-Allow-Origin': '*'
          , 'Access-Control-Allow-Headers': 'Content-Type'
        } )


import numpy as np
from copy import deepcopy
import logging

class UnfoldCore:
    """
    Set of methods to rotate the input reactor core geometry.

    Attributes
    ----------
    coremap: array[int]
        2D array representing the whole reactor core. The entries represent
        the assembly types
    inp: array[int]
        2D array representing the reactor core sector defined in input.
        The entries represent the assembly types

    """

    def __init__(self, inpge, rotangle, regionsdict):
        """
        Initialise the class.

        Parameters
        ----------
        inpge: str
            Path of the input file containing the geometry arrangement of the
            core
        rotangle: float
            rotation angle over which the arrangement is symmetrically rotated.
            The rotation angle should be passed in degree (only 0,60,45,90,180
            values are allowed). With rotangle=0 no rotation occurs.

        Raises
        ------
        OSError:
            File %s not found
            Negative values are not allowed in input!
            The lattice should be squared! Check input file

        Returns
        -------
        ``None``
        """
        try:
            coremap = np.loadtxt(inpge, unpack=False, dtype=str, comments='%')
        except OSError:
            raise OSError(f"File {inpge} not found")

        coremap0 = deepcopy(coremap)
        # replace regions name with numbers
        for (k, v) in regionsdict.items():
            coremap[coremap == k] = v
            coremap[coremap == str(v)] = v

        # replace '*' with '0' for conversion, if any
        coremap[coremap == '*'] = '0'

        # convert from string ndarray to ndarray of integers
        try:
            coremap = coremap.astype(np.int64)
        except ValueError:
            raise OSError('Check input .txt entries match with assemblynames')
        coremap0 = coremap+0  # input
        # check negative entries
        if np.sum(coremap == -1) > 0:
            raise OSError("Negative values are not allowed in input!")

        # check that hexagonal symmetry holds
        Nx, Ny = np.shape(coremap)
        if Nx != Ny:
            logging.error(f"The lattice has {Ny} rows and {Nx} columns!")
            raise OSError('The lattice should be squared! Check input file')

        # -- compute number of sectors
        try:
            nsect = np.ceil(360/rotangle)
        except ZeroDivisionError:  # no symmetry, so map assumed as complete
            rotangle = 360
            nsect = 1

        nsect = int(nsect)  # convert to integer

        # -- apply rotation, if needed
        if nsect == 1:
            logging.info("No symmetry rotation is considered")
            self.coremap = coremap

        elif nsect == 2:
            self.coremap = UnfoldCore.rot180(coremap, Nx)

        elif nsect == 4:
            self.coremap = UnfoldCore.rot90(coremap, Nx)

        elif nsect == 6:
            self.coremap = UnfoldCore.rot60(coremap)

        elif nsect == 8:
            self.coremap = UnfoldCore.rot45(coremap, Nx)

        else:  # no rotation available
            logging.warning(f"Rotation of {rotangle} degree not available. No rotation performed!")
            self.coremap = coremap
        # assign also input file for reproducibility
        self.inp = coremap0

    @staticmethod
    def rot45(coremap, N):  # square geometry
        """Perform a counterclockwise 45° rotation.

        Parameters
        ----------
        coremap: np.array[int]
            2D array representing a 45° portion of the reactor core
        N: int
            number of nonzero elements in the file

        Returns
        -------
        coremap: np.array[int]
            2D array representing the whole reactor core
        """
        # use numpy methods to perform rotation and generate 1/4 of the core
        coremap = np.fliplr(coremap)+np.rot90(coremap)
        # divide by 2 overlappings in the diagonal
        for idiag in range(0, N):
            coremap[idiag, idiag] = coremap[idiag, idiag]/2

        # apply 90° rotation
        coremap = UnfoldCore.rot90(coremap, N)

        return coremap

    @staticmethod
    def rot60(coremap):  # hexagonal geometry
        """
        Perform a counterclockwise 60° rotation.

        Parameters
        ----------
        coremap: array[int]
            2D array representing a 60° portion of the reactor core
        N: int
            number of nonzero elements in the file

        Returns
        -------
        coremap: array[int]
            2D array representing the whole reactor core
        """
        # unpack non-zero coordinates of the matrix
        y, x = np.where(coremap != 0)  # rows, columns
        # define core central assembly
        yc, xc = [np.max(y), np.min(x)]
        # compute number of assemblies
        Nx, Ny = [np.max(x)-xc, yc-np.min(y)+1]
        Nxc = sum(coremap[xc, yc+1:] != 0)
        if Nxc < Nx:
            # non-regular hexagon: add dummy elements to have same Nx and Ny
            coremap[xc, Nxc+xc+1:Nx+xc+1] = -1
            # find min non-zero index
            indNZy = np.argwhere(coremap[:, np.max(x)]).min()
            # add elements along y to have Nx=Ny
            coremap[yc-Nx+1:indNZy, np.max(x)] = -1
            # set Ny equal to Nx (by definition)
            Ny = Nx
            # unpack non-zero coordinates of the matrix (they changed)
            y, x = np.where(coremap != 0)  # rows, columns

        # -- loop over rows
        for nb in range(1, Nx):

            xsectI = np.arange(xc+Nx, xc+nb, -1)  # decreasing order indeces
            ysectI = yc-nb  # going up along the matrix means to decrease yc

            # sector II
            coremap[np.min(y)-1:yc-nb, xc+nb] = coremap[ysectI, xsectI]

            # sector III
            coremap[yc-nb, xc-Nx+nb:xc] = coremap[ysectI, xsectI]

            # sector IV
            coremap[yc+nb, xc-Nx:xc-nb] = coremap[ysectI, xsectI]
            # flip since sectors V and VI are in III and IV cartesian quadrants
            xsectI = np.flip(xsectI, -1)

            # sector V
            coremap[yc+1+nb:yc+Ny+1, xc-nb] = coremap[ysectI, xsectI]

            # sector VI
            coremap[yc+nb, xc+1:xc+Nx-nb+1] = coremap[ysectI, xsectI]

        # -- fill "diagonals" (only sectors II and V actually are diagonals)
        corediag = coremap[yc, xc+1:xc+Nx+1]

        # sector II
        # define coordinates of the diagonal on sector II
        dcoord = (np.arange(yc-1, yc-Ny-1, -1), np.arange(xc+1, xc+Nx+1))
        index = np.ravel_multi_index(dcoord, dims=np.shape(coremap), order='F')
        coremap.ravel()[index] = corediag

        # sector III
        coremap[np.arange(yc-1, yc-Ny-1, -1), xc] = corediag

        # sector IV
        coremap[yc, np.arange(xc-1, xc-Nx-1, -1)] = corediag

        # sector V xc-1:-1:xc-Nx
        # define coordinates of the diagonal on sector II
        dcoord = (np.arange(yc+1, yc+Ny+1), np.arange(xc-1, xc-Nx-1, -1))
        index = np.ravel_multi_index(dcoord, dims=np.shape(coremap), order='F')
        coremap.ravel()[index] = corediag

        # sector VI
        coremap[np.arange(yc+1, yc+Ny+1), xc] = corediag

        # replace dummy elements "-1" with 0
        coremap[coremap == -1] = 0

        return coremap

    @staticmethod
    def rot90(coremap, N):  # square geometry
        """
        Perform a counterclockwise 90° rotation.

        Parameters
        ----------
        coremap: array[int]
            2D array representing a 90° portion of the reactor core
        N: int
            number of nonzero elements in the file

        Returns
        -------
        coremap: array[int]
            2D array representing the whole reactor core
        """
        # -- rotate to have 180° symmetry
        coremap = np.fliplr(coremap)+coremap
        # divide by 2 overlappings along rows
        if np.mod(N, 2) != 0:
            for irow in range(0, N):
                icol = (np.rint((N-1)/2)).astype(int)
                coremap[irow, icol] = coremap[irow, icol]/2

        # apply 180° rotation
        coremap = UnfoldCore.rot180(coremap, N)

        return coremap

    @staticmethod
    def rot180(coremap, N):  # square geometry
        """
        Perform a counterclockwise 180° rotation.

        Parameters
        ----------
        coremap: array[int]
            2D array representing a 180° portion of the reactor core
        N: int
            number of nonzero elements in the file

        Returns
        -------
        coremap: array[int]
            2D array representing the whole reactor core
        """
        coremap = np.flipud(coremap)+coremap
        # divide by 2 overlappings along columns
        if np.mod(N, 2) != 0:
            for icol in range(0, N):
                irow = (np.rint((N-1)/2)).astype(int)
                coremap[irow, icol] = coremap[irow, icol]/2

        return coremap


import numpy as np
import torch
maxf = 20181028
minf = -20181028
# T = 100
def simplifyDNF(DNFs):
	i = 0
	while (i<len(DNFs)):
		j = i + 1
		while (j<len(DNFs)):
			f1 = (DNFs[i][:, 0] >= DNFs[j][:, 0])
			f2 = (DNFs[i][:, 1] <= DNFs[j][:, 1])
			f3 = (DNFs[i][:, 0] <= DNFs[j][:, 0])
			f4 = (DNFs[i][:, 1] >= DNFs[j][:, 1])
			if (f1.min()==1) and  (f2.min()==1):
				DNFs = DNFs[:i] + DNFs[i+1:]
				i = i - 1
				break
			elif (f3.min()==1) and  (f4.min()==1):
				DNFs = DNFs[:j] + DNFs[j+1:]
			else:
				j = j + 1
		i += 1
	# DNF_array = torch.FloatTensor(DNFs)
	return DNFs

def calculateDNF(req, t, flag, T=100):
	# Set Req = (operator, op1, [op2])
	# Int t
	# Boolean flag
	# Return req
	if not flag:
		if req[0] == "mu":
			s = np.full((T,2),maxf)
			s[:, 0] = -s[:, 0]
			s[t, 1] = req[1]
			return [s]
		elif req[0] == "neg":
			return calculateDNF(req[1], t, True, T)
		elif req[0] == "and":
			return calculateDNF(('or', req[1], req[2]), t, True, T)
		elif req[0] == "or":
			return calculateDNF(('and', req[1], req[2]), t, True, T)
		elif req[0] == "always":
			return calculateDNF(('eventually', req[1]), t, True, T)
		elif req[0] == "eventually":
			return calculateDNF(('always', req[1]), t, True, T)
	else:
		if req[0] == "mu":
			s = np.full((T,2),maxf)
			s[:, 0] = -s[:, 0]
			s[t, 0] = req[1]
			return [s]
		elif req[0] == "neg":
			return calculateDNF(req[1], t, False, T)
		elif req[0] == "and":
			set1 = calculateDNF(req[1], t, True, T)
			set2 = calculateDNF(req[2], t, True, T)
			s = []
			for f1 in set1:
				for f2 in set2:
					fres = f1.copy()
					fres[: , 0] = np.maximum(f1[: , 0], f2[:, 0])
					fres[: , 1] = np.minimum(f1[: , 1], f2[:, 1])
					s.append(fres)
			s = simplifyDNF(s)
			return s
		elif req[0] == "or":
			set1 = calculateDNF(req[1], t, True, T)
			set2 = calculateDNF(req[2], t, True, T)
			return set1 + set2
		elif req[0] == "always":
			# print(req)
			t1 = req[1][0]
			t2 = req[1][1]
			s = calculateDNF(req[2], t + t1, True, T)
			for tt in range(t + t1 + 1, t + t2 + 1):
				print(len(s))
				set_curr = calculateDNF(req[2], tt, True, T)
				sc = []
				for f1 in set_curr:
					for f2 in s:
						fres = f1.copy()
						fres[: , 0] = np.maximum(f1[: , 0], f2[:, 0])
						fres[: , 1] = np.minimum(f1[: , 1], f2[:, 1])
						sc.append(fres)
				sc = simplifyDNF(sc)
				s = sc
			# print(s)
			return s
		elif req[0] == "eventually":
			t1 = req[1][0]
			t2 = req[1][1]
			s = []
			for tt in range(t + t1, t + t2 + 1):
				set_curr = calculateDNF(req[2], tt, True, T)
				s = s + set_curr
			return s

def trace_gen(DNF_array, trace):
	dist1 = DNF_array[:, :, 0].unsqueeze(0) - trace.unsqueeze(1)
	# print(dist1)
	dist2 = trace.unsqueeze(1) - DNF_array[:, :, 1].unsqueeze(0)
	# print(dist2)
	dist1 = torch.max(dist1, torch.zeros(dist1.size()))
	dist2 = torch.max(dist2, torch.zeros(dist2.size()))
	# print(dist1)
	# print(dist2)
	dnf_select = torch.max(dist1, dist2).sum(dim=2).argmin(dim=1)
	selected_dnf = DNF_array[dnf_select]
	# print(selected_dnf)
	trace_stl = torch.max(trace, selected_dnf[:, :, 0])
	trace_stl = torch.min(trace_stl, selected_dnf[:, :, 1])
	return trace_stl

if __name__=='__main__':
	mu_req = ('mu', 5)
	always_req = ('always', (0, 5), ('mu', 5))
	eventually_req = ('eventually', (0, 5), ('mu', 5))
	always_even_req = ('always', (0, 5), ('eventually', (0, 5), ('mu', 5)))
	even_even_req = ('eventually', (0, 5), ('eventually', (0, 5), ('mu', 5)))
	print(calculateDNF(mu_req, 0, True, 5))
	print(calculateDNF(always_req, 0, True, 6))
	print(calculateDNF(eventually_req, 0, True, 6))
	# print(calculateDNF(always_even_req, 0, True, 11))
	even_dnf = calculateDNF(even_even_req, 0, True, 11)
	print(even_dnf)
	print(simplifyDNF(even_dnf))


# Defining a count vowel function
def count_vowels(strin):
    count = 0
    for i in strin:
        k = i.lower()
        if k in ["a", "e", "i", "o", "u"]:
            count += 1
    return count

# Taking inputs from the user
string = input("Enter the string to count vowels\n")
# Calling the fcunction and printing the result
print("No of vowels in the given string are ", count_vowels(string))


def waktu_ke_menit(minggu, hari, jam, menit):
    minggu_menit = minggu * 7 * 24 * 60
    hari_menit = hari * 24 * 60
    jam_menit = jam * 60
    total_menit = minggu_menit + hari_menit + jam_menit + menit
    return total_menit

def ambil_integer(data):
    return list(filter(str.isdigit, data.split()))

data = ["3 minggu 3 hari 7 jam 21 menit",
        "5 minggu 5 hari 8 jam 11 menit",
        "7 minggu 1 hari 5 jam 33 menit"]

output_data = [waktu_ke_menit(*map(int, ambil_integer(item))) for item in data]

print('OutputData = ', output_data)

output_Int = [ambil_integer(item) for item in data]

for item in output_Int:
    print(item)


#!/usr/bin/env python2

import numpy as np
import scipy.io as sio
import argparse
from camera import Camera
from plotting import *

# A very simple, but useful method to take the difference between the
# first and second element (usually for 2D vectors)
def diff(x):
    return x[1] - x[0]

def form_initial_voxels(xlim, ylim, zlim, num_voxels):
    '''
    FORM_INITIAL_VOXELS  create a basic grid of voxels ready for carving

    Arguments:
        xlim - The limits of the x dimension given as [xmin xmax]

        ylim - The limits of the y dimension given as [ymin ymax]

        zlim - The limits of the z dimension given as [zmin zmax]

        num_voxels - The approximate number of voxels we desire in our grid

    Returns:
        voxels - An ndarray of size (N, 3) where N is approximately equal the
            num_voxels of voxel locations.

        voxel_size - The distance between the locations of adjacent voxels
            (a voxel is a cube)

    Our initial voxels will create a rectangular prism defined by the x,y,z
    limits. Each voxel will be a cube, so you'll have to compute the
    approximate side-length (voxel_size) of these cubes, as well as how many
    cubes you need to place in each dimension to get around the desired
    number of voxel. This can be accomplished by first finding the total volume of
    the voxel grid and dividing by the number of desired voxels. This will give an
    approximate volume for each cubic voxel, which you can then use to find the
    side-length. The final "voxels" output should be a ndarray where every row is
    the location of a voxel in 3D space.
    '''
    # Get length of each side of space
    xsize, ysize, zsize = diff(xlim), diff(ylim), diff(zlim)
    # Compute total volume
    total_volume = xsize*ysize*zsize
    # Divid total volume by number of voxels to get volume per voxel
    voxel_volume = total_volume / num_voxels
    # SIde length of a voxel is cube root of volume
    voxel_size = np.cbrt(voxel_volume)
    # Compute position of each voxel
    voxels = np.mgrid[
        xlim[0]:xlim[1]:voxel_size,
        ylim[0]:ylim[1]:voxel_size,
        zlim[0]:zlim[1]:voxel_size].reshape(3, -1).T

    return voxels, voxel_size

def get_voxel_bounds(cameras, estimate_better_bounds = False, num_voxels = 4000):
    '''
    GET_VOXEL_BOUNDS: Gives a nice bounding box in which the object will be carved
    from. We feed these x/y/z limits into the construction of the inital voxel
    cuboid.

    Arguments:
        cameras - The given data, which stores all the information
            associated with each camera (P, image, silhouettes, etc.)

        estimate_better_bounds - a flag that simply tells us whether to set tighter
            bounds. We can carve based on the silhouette we use.

        num_voxels - If estimating a better bound, the number of voxels needed for
            a quick carving.

    Returns:
        xlim - The limits of the x dimension given as [xmin xmax]

        ylim - The limits of the y dimension given as [ymin ymax]

        zlim - The limits of the z dimension given as [zmin zmax]

    The current method is to simply use the camera locations as the bounds. In the
    section underneath the TODO, please implement a method to find tigther bounds:
    One such approach would be to do a quick carving of the object on a grid with
    very few voxels. From this coarse carving, we can determine tighter bounds. Of
    course, these bounds may be too strict, so we should have a buffer of one
    voxel_size around the carved object.
    '''
    camera_positions = np.vstack([c.T for c in cameras])
    xlim = [camera_positions[:,0].min(), camera_positions[:,0].max()]
    ylim = [camera_positions[:,1].min(), camera_positions[:,1].max()]
    zlim = [camera_positions[:,2].min(), camera_positions[:,2].max()]

    # For the zlim we need to see where each camera is looking.
    camera_range = 0.6 * np.sqrt(diff( xlim )**2 + diff( ylim )**2)
    for c in cameras:
        viewpoint = c.T - camera_range * c.get_camera_direction()
        zlim[0] = min( zlim[0], viewpoint[2] )
        zlim[1] = max( zlim[1], viewpoint[2] )

    # Move the limits in a bit since the object must be inside the circle
    xlim = xlim + diff(xlim) / 4 * np.array([1, -1])
    ylim = ylim + diff(ylim) / 4 * np.array([1, -1])

    # Get better bounds by carving a small chunk of voxels
    if estimate_better_bounds:
        # Get initial bounds with few voxels
        voxels, voxel_size = form_initial_voxels(xlim, ylim, zlim, num_voxels)
        # Carve the voxel block
        for c in cameras:
            voxels = carve(voxels, c)
        # Get the min and max positions in each dimension for the carved block
        xmin, ymin, zmin = voxels.min(axis=0)
        xmax, ymax, zmax = voxels.max(axis=0)
        xlim = np.array([xmin, xmax])
        ylim = np.array([ymin, ymax])
        zlim = np.array([zmin, zmax])
        # Make the minimum difference between min and max bounds
        # equal to a factor of the voxel size, 3 works well
        # for this example
        f = 3
        if diff(xlim) < f*voxel_size:
            xlim[0] -= f*voxel_size/2
            xlim[1] += f*voxel_size/2
        if diff(ylim) < f*voxel_size:
            ylim[0] -= f*voxel_size/2
            ylim[1] += f*voxel_size/2
        if diff(zlim) < f*voxel_size:
            zlim[0] -= f*voxel_size/2
            zlim[1] += f*voxel_size/2

    return xlim, ylim, zlim

def carve(voxels, camera):
    '''
    CARVE: carves away voxels that are not inside the silhouette contained in
        the view of the camera. The resulting voxel array is returned.

    Arguments:
        voxels - an Nx3 matrix where each row is the location of a cubic voxel

        camera - The camera we are using to carve the voxels with. Useful data
            stored in here are the "silhouette" matrix, "image", and the
            projection matrix "P".

    Returns:
        voxels - a subset of the argument passed that are inside the silhouette
    '''
    # Convert voxels to homogeneous coordinates
    hvoxels = np.concatenate([voxels, np.ones((voxels.shape[0], 1))], axis=1)
    # Project the voxels into pixels in the image
    hpixels = np.dot(camera.P, hvoxels.T)
    # Convert pixels from homogeneous to euclidean
    pixels = (hpixels[:2, :]/hpixels[2, :]).T
    # Get silhouette dimensions
    Y, X = camera.silhouette.shape
    # Round projected pixel positions to ints
    pixels = np.round(pixels).astype(int)
    # First, get indeces of pixels inside the bounds of the silhouette
    boundedx = np.logical_and(pixels[:, 0] > 0, pixels[:, 0] < X)
    boundedy = np.logical_and(pixels[:, 1] > 0, pixels[:, 1] < Y)
    bounded = np.logical_and(boundedx, boundedy)
    bounded_pixels = pixels[bounded]
    xidx = bounded_pixels[:, 0]
    yidx = bounded_pixels[:, 1]
    # Then, check indeces of these pixels which fall under the silhouette
    sil_idx = camera.silhouette[yidx, xidx].astype(bool)
    # Index voxels first by bounded indeces, then by silhouette indeces
    return voxels[bounded][sil_idx]

'''
ESTIMATE_SILHOUETTE: Uses a very naive and color-specific heuristic to generate
the silhouette of an object

Arguments:
    im - The image containing a known object. An ndarray of size (H, W, C).

Returns:
    silhouette - An ndarray of size (H, W), where each pixel location is 0 or 1.
        If the (i,j) value is 0, then that pixel location in the original image
        does not correspond to the object. If the (i,j) value is 1, then that
        that pixel location in the original image does correspond to the object.
'''
def estimate_silhouette(im):
    return np.logical_and(im[:,:,0] > im[:,:,2], im[:,:,0] > im[:,:,1] )

if __name__ == '__main__':
    estimate_better_bounds = True
    use_true_silhouette = False
    frames = sio.loadmat('frames.mat')['frames'][0]
    cameras = [Camera(x) for x in frames]

    #for c in cameras:
    #    plt.imshow(c.image)
    #    plt.show()

    # Generate the silhouettes based on a color heuristic
    if not use_true_silhouette:
        for i, c in enumerate(cameras):
            c.true_silhouette = c.silhouette
            c.silhouette = estimate_silhouette(c.image)
            if i == 0:
                plt.figure()
                plt.subplot(121)
                plt.imshow(c.true_silhouette, cmap = 'gray')
                plt.title('True Silhouette')
                plt.subplot(122)
                plt.imshow(c.silhouette, cmap = 'gray')
                plt.title('Estimated Silhouette')
                plt.savefig('./plots/p1e1.png')

    # Generate the voxel grid
    # You can reduce the number of voxels for faster debugging, but
    # make sure you use the full amount for your final solution
    num_voxels = 6e6
    xlim, ylim, zlim = get_voxel_bounds(cameras, estimate_better_bounds)

    # This part is simply to test forming the initial voxel grid
    voxels, voxel_size = form_initial_voxels(xlim, ylim, zlim, 4000)
    #plot_surface(voxels, title='Initial Voxel Grid',
    #    save=True, path='./plots/p1a.png')
    voxels, voxel_size = form_initial_voxels(xlim, ylim, zlim, num_voxels)

    # Test the initial carving
    #voxels = carve(voxels, cameras[0])
    #if use_true_silhouette:
    #    plot_surface(voxels, title='Voxels After One Iteration of Carving',
    #        save=True, path='./plots/p1b.png')

    # Result after all carvings
    for i, c in enumerate(cameras):
        if i < 5:
            voxels = carve(voxels, c)
    plot_surface(voxels, voxel_size, title='Fully Carved Plot from Estimated Silhouette, with only 5 Views',
        save=True, path='./plots/p1e3.png')


import numpy as np
import scipy.sparse as sparse

from smooth_utils import nicp
from smooth_utils import arap

def solve_Y21_nicp(mesh1, mesh2, p2p_21, params):
    if p2p_21.ndim == 1:
        Y21 = mesh1.vertlist[p2p_21]
    else:
        Y21 = p2p_21 @ mesh1.vertlist

    _, Y21 = nicp.solve_nicp(mesh2, mesh1, p2p_21,
                             gamma=1, alpha=params['smooth_weight']/params['couple_weight'],
                             landmarks=None, lmks_weight=10,
                             nit=1, n_jobs=-1,
                             use_cotan=True, verbose=False)
    return Y21

def solve_Y21_exact(mesh1, mesh2, p2p_21, params):
    # print(mesh1.path, mesh2.path, p2p_21)
    if p2p_21.ndim == 1:
        Y21 = mesh1.vertlist[p2p_21]
    else:
        Y21 = p2p_21 @ mesh1.vertlist  # (n2, 3)

    # print(params.keys(), f'solver{solver_ind2}', hasattr(params, f'solver{solver_ind2}'))
    if 'solver_ind' in params.keys():

        B_mat = (params['couple_weight'] / (params['smooth_weight'] * mesh2.area)) * mesh2.A @ Y21

        Y21_new = params[f'solver{params["solver_ind"]}'](B_mat)

        return Y21_new

    raise ValueError("Not in the official code yet")

def solve_Y21_exact_bij(mesh1, mesh2, p2p_21, p2p_12, params, pb_or_def='pull-back'):
    w_couple = params['couple_weight']
    w_bij = params['bij_weight']
    w_smooth = params['smooth_weight']

    if p2p_12.ndim == 1:
        P12 = sparse.csr_matrix((np.ones(p2p_12.size),(np.arange(p2p_12.size), p2p_12)), shape=(mesh1.n_vertices, mesh2.n_vertices))
    else:
        P12 = p2p_12

    if p2p_21.ndim == 1:
        P21 = sparse.csr_matrix((np.ones(p2p_21.size),(np.arange(p2p_21.size), p2p_21)), shape=(mesh2.n_vertices, mesh1.n_vertices))
    else:
        P21 = p2p_21

    A_mat = (w_smooth/w_couple) * mesh2.W + mesh2.A + (w_bij/w_couple) * P12.T @ mesh1.A @ P12
    B_mat = mesh2.A @ P21 @ mesh1.vertlist + (w_bij/w_couple) * P12.T @ mesh1.A @ mesh1.vertlist

    Y21 = sparse.linalg.spsolve(A_mat, B_mat)

    return Y21

def solve_Y21_arap_couple(mesh1, mesh2, p2p_21, params, pb_or_def='pull-back'):
    if pb_or_def == 'deformation':
        raise ValueError("Not implemented")

    smooth_weight = params['smooth_weight']
    couple_weight = params['couple_weight']

    vert_source = mesh2.vertlist
    new_vert1 = mesh1.vertlist[p2p_21]

    W_coo = arap.get_cotan_mat(mesh2.W)

    covariances = arap.get_covariances(W_coo, vert_source, new_vert1)
    rotations = arap.rotation_from_covariances(covariances)

    # Solve for positions
    rotated_edges = arap.get_rotated_lap(W_coo, rotations, vert_source)

    A_mat = smooth_weight / couple_weight * mesh2.W + sparse.eye(mesh2.n_vertices)
    B_mat = smooth_weight / couple_weight * rotated_edges + new_vert1

    Y21 = sparse.linalg.spsolve(A_mat, B_mat)

    return Y21


import cv2
import numpy as np
cap =cv2.VideoCapture(0)
if cap.isOpened():
    while True:
        ret,img=cap.read()
        if ret:
            g_img = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2GRAY)


import tweepy

auth = tweepy.OAuthHandler("kXU34Ed346zm0YtUTWGLOJ9zj", "C9bdfFcCXvbCWIBdvwOvYFdTY9gYRjfnf87IKc9Apsh6wMwEqt")

# Redirect user to Twitter to authorize
#redirect_user(auth.get_authorization_url())

# Get access token
auth.set_access_token('751073154303393792-LiItR3rIgJu4lC6b5HDx1TxnDELn1pF','DKdxX4BebK2Sitz15plyCoF0hMz7wEcrzg19G5nsSXEYx')

# Construct the API instance
api = tweepy.API(auth)

result = api.search(q="titli")
#print(result[0])
#print(len(result))
pics = set()
for tweets in result:
    media = tweets.entities.get('media',[])

    if(hasattr(tweets, 'extended_entities')):
        media_ext = tweets.extended_entities.get('media',[])

    if(len(media)>0):
        pics.add(media[0]['media_url_https'])
        pics.add(media[0]['media_url'])
    if(len(media_ext)>0):
        pics.add(media_ext[0]['media_url'])
        pics.add(media_ext[0]['media_url_https'])

print(pics)


import torch
from math import *

from two_thinning.strategies.strategy_base import StrategyBase
from two_thinning.full_knowledge.RL.DQN.rare_change.evaluate import load_best_model, get_best_model_path
from two_thinning.full_knowledge.RL.DQN.rare_change.train import train, greedy

class FullKnowledgeRareChangeDQNStrategy(StrategyBase):
    def __init__(self, n, m, use_pre_trained=True):
        super(FullKnowledgeRareChangeDQNStrategy, self).__init__(n, m)
        self.threshold_change_freq = int(sqrt(m))
        self.curr_action = None
        self.round = 0
        existing_model = load_best_model(n=n, m=m)
        if existing_model is None or not use_pre_trained:
            version = ""
            if existing_model is not None and not use_pre_trained:
                print(
                    "There already exist a model with these parameters, so a new temporary version will be saved now.")
                version = "_tmp"
            elif existing_model is None and use_pre_trained:
                print("There is no trained model yet with the given parameters, so a new one will be trained now.")
            self.model = train(n=n, m=m, optimise_freq=int(sqrt(m)), max_threshold=max(3, 2 * (m + n - 1) // n),
                               threshold_change_freq=self.threshold_change_freq)
            torch.save(self.model.state_dict(), get_best_model_path(n=n, m=m)[:-4] + version + '.pth')
        else:
            self.model = existing_model

    def decide(self, bin):
        if self.round % self.threshold_change_freq == 0:
            self.curr_action = greedy(self.model, self.loads)
        self.curr_thresholds.append(self.curr_action)
        return self.loads[bin] <= self.curr_action

    def note(self, bin):
        self.round += 1

    def reset(self):
        self.round = 0
        self.curr_action = None

    def create_analyses(self, save_path):
        self.create_plot(save_path)

    def create_summary(self, save_path):
        self.create_summary_plot(save_path)


import argparse
import MSA
import Model
import Trainer
from Config import config
import numpy as np

parser = argparse.ArgumentParser(description='Trains and tests a NeuroAlign model for the simple case of exact nucleotide matches.')
parser.add_argument("-n", type=int, default=5000, help="number of training examples")
parser.add_argument("-dir", type=str, default="./data_20", help="directory with data files")
args = parser.parse_args()

#load the training dataset
msa = []
alphabet = ['A', 'C', 'G', 'T'] if config["type"] == "nucleotide" else ['A', 'R',  'N',  'D',  'C',  'Q',  'E',  'G',  'H', 'I',  'L',  'K',  'M',  'F',  'P', 'S',  'T',  'W',  'Y',  'V',  'B',  'Z',  'X']
for i in range(1,args.n+1):
    filepath = args.dir + "/A"+"{0:0=4d}".format(i)+".fa"
    #print(filepath)
    #print("Reading ", filepath)
    inst = MSA.Instance(filepath, alphabet)
    if inst.valid:
        msa.append(inst)

#instantiate the predictor and the trainer
predictor = Model.NeuroAlignPredictor(config, msa[0])
predictor.load_latest()
trainer = Trainer.NeuroAlignTrainer(config, predictor)

train_losses = []
mem_losses = []
rp_losses = []
gaps_losses = []
rest_dist_losses = []

for i in range(config["num_training_iteration"]):
    batch = []
    while len(batch) < config["batch_size"]:
        batch.append(msa[np.random.randint(len(msa))])
    train_loss_sum = 0
    mem_loss_sum = 0
    rp_loss_sum = 0
    gaps_loss_sum = 0
    res_dist_loss_sum = 0
    for m in batch:
        mem, train_loss, l_mem, l_rp, l_g, l_res_dist = trainer.train(m)
        train_loss_sum += train_loss.numpy()
        mem_loss_sum += l_mem.numpy()
        rp_loss_sum += l_rp.numpy()
        gaps_loss_sum += l_g.numpy()
        res_dist_loss_sum += l_res_dist.numpy()

    train_losses.append(train_loss_sum/config["batch_size"])
    mem_losses.append(mem_loss_sum/config["batch_size"])
    rp_losses.append(rp_loss_sum/config["batch_size"])
    gaps_losses.append(gaps_loss_sum/config["batch_size"])
    rest_dist_losses.append(res_dist_loss_sum/config["batch_size"])

    if len(train_losses) >= 100:
        print(i,
                " l=", sum(train_losses[-100:])/100,
                " mem=", sum(mem_losses[-100:])/100,
                " rp=", sum(rp_losses[-100:])/100,
                " gap=", sum(gaps_losses[-100:])/100,
                " res dist=", sum(rest_dist_losses[-100:])/100, flush=True)
    else:
        print(i,
                " l=", train_losses[i],
                " mem=", mem_losses[i],
                " rp=", rp_losses[i],
                " gap=", gaps_losses[i],
                " res dist=", rest_dist_losses[i], flush=True)

    if i % config["savestate_milestones"] == 0 and i > 0:
        predictor.save()


from joblib import load, dump, Parallel, delayed
from sklearn.metrics import mean_squared_error
from scipy.stats import norm
from statsmodels.tsa.exponential_smoothing.ets import ETSModel
import numpy as np
import pandas as pd

def get_n_spilt_index(data, n_spilit=5):
    index_list_in = np.arange((len(data)))
    output_index_out = []
    index_len = len(index_list_in)
    step = round(index_len/n_spilit)
    for i in range(n_spilit):
        output_index_out.append(i*step)
    return output_index_out

class ETS:
    def __init__(self, y):
        self.y = y.astype(float)
        self.best_para = None
        self.n_jobs = -2
        self.para_search_records = None
        self.model = None
        self.alpha = 0.05
        self.ts_cv = 5

    def get_tscv_results(self, error, trend, seasonal, seasonal_periods):
        y = self.y
        y = y.interpolate().dropna()
        n_spilit = self.ts_cv
        idx = get_n_spilt_index(y, n_spilit)

        output = []
        try:
            for i in range(n_spilit):
                train, test = y[: idx[i]], y[idx[i]:]
                model = ETSModel(
                    endog=y,
                    error=error,
                    trend=trend,
                    seasonal=seasonal,
                    seasonal_periods=seasonal_periods).fit(full_output=False, disp=False)

                pred = model.forecast(len(test))
                rmse = mean_squared_error(y_true=test, y_pred=pred)**(0.5)
                output.append(rmse)
            output = np.array(output)
            mean_rmse = output.mean()
            sd_rmse = output.std()
            output_dict = {
                'mean_rmse': mean_rmse,
                'std_rmse': sd_rmse,
                'error': error,
                'trend': trend,
                'seasonal': seasonal,
                'seasonal_periods': seasonal_periods}
        except:
            output_dict = {
                'mean_rmse': None,
                'std_rmse': None,
                'error': error,
                'trend': trend,
                'seasonal': seasonal,
                'seasonal_periods': seasonal_periods}
        return output_dict

    def search_para(self, para, n_jobs = -2):
        self.n_jobs = n_jobs
        r = Parallel(n_jobs=n_jobs)(
            delayed(self.get_tscv_results)(
                error, trend, seasonal, seasonal_periods )
                for error in para['error'] \
                    for trend in para['trend'] \
                        for seasonal in para['seasonal'] \
                            for seasonal_periods in para['seasonal_periods']
                )
        r = pd.DataFrame(r).sort_values('mean_rmse', ascending=True).reset_index(drop=True)
        self.para_search_records = r
        self.best_para = r[:1]

    def fitcv(self, para, n_jobs=-2, n_spilit=5):
        self.ts_cv = n_spilit
        y = self.y
        self.search_para(para, n_jobs)
        para_ = self.para_search_records[:1]
        y = y.interpolate().dropna()
        model = ETSModel(
            endog=y,
            error=para_['error'][0],
            trend=para_['trend'][0],
            seasonal=para_['seasonal'][0],
            seasonal_periods=para_['seasonal_periods'][0]).fit(full_output=False, disp=False)
        self.model = model

    def fit(self, seasonal_periods=None, error='add', trend='add', seasonal=None):
        y = self.y
        model = ETSModel(
            endog=y,
            error=error,
            trend=trend,
            seasonal=seasonal,
            seasonal_periods=seasonal_periods).fit(full_output=False, disp=False)
        self.model = model

    def predict(self, horizon, sig = 0.05 , CI = False):
        if CI == False:
            pred = np.array(self.model.forecast(horizon))
            return pred
        if CI == True:
            self.alpha = sig
            z = norm.ppf(1-sig/2)
            SE = self.y.std() * np.sqrt(1 + 1/np.arange(1, horizon+1))
            forecast_mean = self.model.forecast(horizon)
            forecast_lo = forecast_mean - z * SE,
            forecast_hi = forecast_mean + z * SE
            pred = pd.DataFrame({
                'forecast_mean': np.array(forecast_mean),
                'forecast_lo': np.array(forecast_lo[0]),
                'forecast_hi': np.array(forecast_hi)
            })
            return pred


from django.shortcuts import render,redirect
from django.http import JsonResponse
from django.views.generic import View,TemplateView
from django.http import HttpResponse, HttpResponseRedirect
from login.models import Applicant
from django.template import *
from .import views
from datetime import *
from django.contrib import messages

# Create your views here.

class PostsView(View):
    def get(self,request):
        return render(request,'createpost.html')

    def post(self,request):

        yearsOfExperience = request.POST.get("yearsOfExperience")
        position = request.POST.get("position")
        industry = request.POST.get("industry")
        region = request.POST.get("region")
        province = request.POST.get("province")
        city = request.POST.get("city")
        age = request.POST.get("age")
        isAgeViewable = request.POST.get("isAgeViewable")
        email = request.session['email']

        if isAgeViewable == 'on':
            isAgeViewable = 1
        else:
            isAgeViewable = 0

        email = request.session.get('email')
        firstname = request.session.get('firstname')
        lastname = request.session.get('lastname')

        Applicant.createpost(email,firstname,lastname,region,province,city,age,industry,yearsOfExperience,position,isAgeViewable)
        messages.success(request,'Post Succesful!')
        return redirect('viewas:viewasa_view')


from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton

from tgbot.keyboards.callback_data import for_key_back

async def def_key_back(language: dict):
    key_back = InlineKeyboardMarkup(
        inline_keyboard=[
            [
                InlineKeyboardButton(
                    text=f'< {language["back"]}',
                    callback_data=for_key_back.new(command="back")
                )
            ]
        ]
    )
    return key_back


from __future__ import absolute_import, unicode_literals

from django.contrib.staticfiles.templatetags.staticfiles import static
from django.utils.html import format_html
from wagtail.wagtailcore import hooks

@hooks.register('insert_global_admin_js')
def insert_global_admin_js():
    scripts = {}
    for hook in hooks.get_hooks('enqueue_scripts'):
        scripts.update(hook())

    HTML = '\n'.join([
        '<script src="{}"></script>'.format(
            static(meta['source'])
        ) for handle, meta in scripts.items()
    ])

    return HTML

@hooks.register('insert_global_admin_css')
def insert_global_admin_css():
    styles = {}
    for hook in hooks.get_hooks('enqueue_styles'):
        styles.update(hook())

    HTML = '\n'.join([
        '<link rel="stylesheet" href="{}">'.format(
            static(meta['source'])
        ) for handle, meta in styles.items()
    ])

    return HTML


import discord, asyncio
from discord.ext import commands

from core import *

def getChannel(ctx, name):
	logs = Vars.collection.find_one({'_id' : ctx.guild.id})['logs']
	if name in logs and ctx.guild.get_channel(logs[name]) != None:
		return ctx.guild.get_channel(logs[name]).mention
	else:
		return '`Not setted`'

logsNames = {
	'🔨' : 'Ban',
	'👢' : 'Kick',
	'🔇' : 'Mute',
	'☢' : 'Warn'
}

class Setup(commands.Cog):
	def __init__(self, client):
		self.client = client

	@commands.command()
	@commands.guild_only()
	@commands.has_permissions(administrator = True)
	async def prefix(self, ctx, prefix : str = None):
		current_prefix = custom_prefix(self.client, ctx.guild)[1]
		if prefix == None:
			return await ctx.send('The current prefix for {} in this server is `{}`'.format(self.client.user.name, current_prefix))
		if len(prefix) > 3:
			return await ctx.send('{} Please specify a prefix with at most 3 characters'.format(Emoji.cross))
		Vars.collection.update_one({"_id" : ctx.guild.id}, {"$set" : {"prefix" : prefix}})
		await ctx.send('{} The prefix has been setted correctly, now you can use `{}` as a prefix in this server'.format(Emoji.tick, prefix))

	@prefix.error
	async def prefix_error(self, ctx, error):
		if isinstance(error, commands.MissingPermissions):
			await ctx.send("{} You don't have the required permissions (Administrator)".format(Emoji.cross))

	@commands.group(description = 'A command that lets you change every setting of the bot', aliases = ["settings", "impostazioni", "config", "configuration"], invoke_without_command = True, case_insensitive = True)
	@commands.has_permissions(administrator = True)
	@commands.guild_only()
	async def setup(self, ctx):
		prefix = custom_prefix(self.client, ctx.message)[1]
		await ctx.send(embed = discord.Embed(color = Vars.color, title = 'Setup :gear:')
			.add_field(name = '<:channels:772528907156586537> Logs', value='Use `{}settings logs`'.format(prefix))
			.add_field(name = '{} BanAppeal'.format(Emoji.ban), value='Use `{}settings banappeal`'.format(prefix))
			.add_field(name = '\u200C', value = '\u200C')
			.add_field(name = '{} MuteRole'.format(Emoji.mute), value='Use `{}settings muterole`'.format(prefix))
			.add_field(name = ':pencil: Prefix', value='Use `{}prefix`'.format(prefix))
			.add_field(name = '\u200C', value = '\u200C')
		)

	@setup.error
	async def setup_error(self, ctx, error):
		if isinstance(error, commands.MissingPermissions):
			await ctx.send("{} You don't have the required permissions (Administrator)".format(Emoji.cross))

	@setup.command(name = 'logs')
	@commands.has_permissions(administrator = True)
	async def logs(self, ctx):
		logs = Vars.collection.find_one({'_id' : ctx.guild.id})['logs']
		msg = await ctx.send(
			embed = discord.Embed(color = Vars.color, title = 'Logs <:channels:772528907156586537>', description = 'React with the respective emoji to edit the channel.')
			.add_field(name = 'Ban Channel {}'.format(Emoji.ban), value = getChannel(ctx, 'ban'))
			.add_field(name = 'Kick Channel {}'.format(Emoji.kick), value = getChannel(ctx, 'kick'))
			.add_field(name = '\u200C', value = '\u200C')
			.add_field(name = 'Mute Channel {}'.format(Emoji.mute), value = getChannel(ctx, 'mute'))
			.add_field(name = 'Warn Channel {}'.format(Emoji.warn), value = getChannel(ctx, 'warn'))
			.add_field(name = '\u200C', value = '\u200C')
		)
		for el in logsNames:
			await msg.add_reaction(el)
		try:
			def check(reaction, user):
				return user == ctx.author and str(reaction.emoji) in logsNames
			reaction, user = await self.client.wait_for('reaction_add', timeout = 60.0, check = check)
			await msg.edit(
				embed = discord.Embed(
					color = Vars.color,
					title = '{} Channel {}'.format(logsNames[str(reaction)], reaction),
					description = 'React with:\n:green_square: to specify a new channel\n:red_square: to remove the current channel'
				)
				.add_field(name = 'Current Channel', value = getChannel(ctx, logsNames[str(reaction)].lower()))
			)
			message = await ctx.channel.fetch_message(msg.id)
			await message.clear_reactions()
		except asyncio.TimeoutError:
			message = await ctx.channel.fetch_message(msg.id)
			return await message.clear_reactions()
		await msg.add_reaction('🟩')
		await msg.add_reaction('🟥')

		try:
			def check(reaction, user):
				return user == ctx.author and str(reaction.emoji) in ('🟥', '🟩')
			react, user = await self.client.wait_for('reaction_add', timeout = 60.0, check = check)
			if str(react) == '🟩':
				await ctx.send('Send a message with only the mention of the **channel**.')
				def check(m):
					return m.author == ctx.author
				command = await self.client.wait_for('message', timeout = 60.0, check=check)
				command = command.content
				try:
					if command.startswith('<#') and command.endswith('>'):
						command = int(command.strip()[-19:-1])
					else:
						command = int(command)
				except:
					pass
				if (type(command) == int and len(str(command)) == 18) and ctx.guild.get_channel(command) != None:
					if ctx.guild.get_channel(command).type != discord.ChannelType.text:
						return await ctx.send('{} please specify only text channels'.format(Emoji.cross))
					logs.update({logsNames[str(reaction)].lower() : command})
					Vars.collection.update_one({'_id': ctx.guild.id}, {'$set': {'logs' : logs}})
					await ctx.send('{} Channel has been setted'.format(Emoji.tick))
				else:
					await ctx.send('{} Please specify a valid channel'.format(Emoji.cross))
			elif str(react) == '🟥':
				if getChannel(ctx, logsNames[str(reaction)].lower()).startswith('`'):
					await ctx.send('{} No channel has been previusly setted.'.format(Emoji.cross))
				else:
					del logs[logsNames[str(reaction)].lower()]
					Vars.collection.update_one({'_id': ctx.guild.id}, {'$set': {'logs' : logs}})
					await ctx.send("{} Channel has been removed from the bot's settings".format(Emoji.tick))
			raise asyncio.TimeoutError
		except asyncio.TimeoutError:
			message = await ctx.channel.fetch_message(msg.id)
			await message.clear_reactions()

	@logs.error
	async def setup_error(self, ctx, error):
		if isinstance(error, commands.MissingPermissions):
			await ctx.send("{} You don't have the required permissions (Administrator)".format(Emoji.cross))

	@setup.command(name = 'banappeal')
	@commands.has_permissions(administrator = True)
	async def banappeal(self, ctx):
		settings = Vars.collection.find_one({'_id' : ctx.guild.id})['settings']
		if 'banappeal' in settings:
			link = settings['banappeal']
		else:
			link = '`Not setted`'
		msg = await ctx.send(
			embed = discord.Embed(
				color = Vars.color,
				title = 'BanAppeal {emoji}'.format(emoji = Emoji.ban),
				description = 'React with:\n:green_square: to specify a new link\n:red_square: to remove the current link'
			)
			.add_field(name = 'Setted link', value = link)
		)
		await msg.add_reaction('🟩')
		await msg.add_reaction('🟥')
		try:
			def check(reaction, user):
				return user == ctx.author and str(reaction.emoji) in ('🟥', '🟩')
			reaction, user = await self.client.wait_for('reaction_add', timeout = 60.0, check = check)
			if str(reaction) == '🟩':
				await ctx.send('Send a message with only the new **link** to be used to appeal bans.')
				def check(m):
					return m.author == ctx.author
				try:
					command = await self.client.wait_for('message', timeout = 60.0, check=check)
					command = command.content
					if command.startswith('https://docs.google.com/forms'):
						settings.update({'banappeal' : command.strip()})
						Vars.collection.update_one({'_id': ctx.guild.id}, {'$set': {'settings' : settings}})
						await ctx.send('{} Link has been setted'.format(Emoji.tick))
					else:
						await ctx.send('{} Please specify a valid link (only link starting with <https://docs.google.com/forms> are allowed)'.format(Emoji.cross))
				except:
					raise asyncio.TimeoutError
			elif str(reaction) == '🟥':
				if link.startswith('`'):
					await ctx.send('{} No link has been previusly setted.'.format(Emoji.cross))
				else:
					del settings['banappeal']
					Vars.collection.update_one({'_id': ctx.guild.id}, {'$set': {'settings' : settings}})
					await ctx.send("{} Link has been removed from the bot's settings".format(Emoji.tick))
			raise asyncio.TimeoutError
		except asyncio.TimeoutError:
			message = await ctx.channel.fetch_message(msg.id)
			await message.clear_reactions()

	@banappeal.error
	async def setup_error(self, ctx, error):
		if isinstance(error, commands.MissingPermissions):
			await ctx.send("{} You don't have the required permissions (Administrator)".format(Emoji.cross))

	@setup.command(name = 'muterole')
	@commands.has_permissions(administrator = True)
	@commands.guild_only()
	async def muterole(self, ctx):
		settings = Vars.collection.find_one({'_id' : ctx.guild.id})['settings']
		if 'muterole' in settings and ctx.guild.get_role(settings['muterole']) != None:
			role = ctx.guild.get_role(settings['muterole']).mention
		else:
			role = '`Not setted`'
		msg = await ctx.send(
			embed = discord.Embed(
				color = Vars.color,
				title = 'MuteRole {}'.format(Emoji.mute),
				description = 'React with:\n:green_square: to specify a custom role\n:red_square: to remove the current role\n{} to create a standard one'.format(Emoji.mute)
			)
			.add_field(name = 'Setted role', value = role)
		)
		await msg.add_reaction('🟩')
		await msg.add_reaction('🟥')
		await msg.add_reaction('🔇')
		try:
			def check(reaction, user):
				return user == ctx.author and str(reaction.emoji) in ('🟥', '🔇', '🟩')
			reaction, user = await self.client.wait_for('reaction_add', timeout = 60.0, check = check)
			if str(reaction) == '🟩':
				await ctx.send('Send a message with only the **mention** or the **id** of the role.')
				def check(m):
					return m.author == ctx.author
				try:
					command = await self.client.wait_for('message', timeout = 60.0, check=check)
					command = command.content
					try:
						if command.startswith('<@&') and command.endswith('>'):
							command = int(command.strip()[-19:-1])
						else:
							command = int(command)
					except:
						pass
					if (type(command) == int and len(str(command)) == 18) and ctx.guild.get_role(command) != None:
						settings.update({'muterole' : command})
						Vars.collection.update_one({'_id': ctx.guild.id}, {'$set': {'settings' : settings}})
						await ctx.send('{} Role has been setted'.format(Emoji.tick))
					else:
						await ctx.send('{} Please specify a valid role'.format(Emoji.cross))
				except:
					raise asyncio.TimeoutError
			elif str(reaction) == '🟥':
				if role.startswith('`'):
					await ctx.send('{} No role has been previusly setted.'.format(Emoji.cross))
				else:
					del settings['muterole']
					Vars.collection.update_one({'_id': ctx.guild.id}, {'$set': {'settings' : settings}})
					await ctx.send("{} Role has been removed from the bot's settings".format(Emoji.tick))
			elif str(reaction) == '🔇':
				nRole = await create_mute_role(ctx.guild)
				get_mute_role(ctx.guild, nRole)
				await ctx.send('{} New role has been created ({})'.format(Emoji.tick, nRole.mention))
			raise asyncio.TimeoutError
		except asyncio.TimeoutError:
			message = await ctx.channel.fetch_message(msg.id)
			await message.clear_reactions()

	@muterole.error
	async def setup_error(self, ctx, error):
		if isinstance(error, commands.MissingPermissions):
			await ctx.send("{} You don't have the required permissions (Administrator)".format(Emoji.cross))

def setup(client):
	client.add_cog(Setup(client))


import tkinter

haren = tkinter.Tk()

width, height = haren.winfo_screenwidth(), haren.winfo_screenheight()
bg = tkinter.PhotoImage(file="Coverphoto1.png")

panel1 = tkinter.Label(haren, image=bg)
panel1.pack(side='top', fill='both', expand='yes')

haren.wm_title("Hi Sana")
haren.grid()
yeah=tkinter.Label(haren, text="Developed by Full Mad Haren Sarma")
yeah.pack()
haren.attributes('-fullscreen',True)
#haren.wm_geometry("%dx%d+0+0" % (width, height))
haren.mainloop()


# Now, Dasher! Now, Dancer! Now, Prancer, and Vixen! On, Comet! On, Cupid! On,
# Donder and Blitzen! That's the order Santa wanted his reindeer...right?
# What do you mean he wants them in order by their last names!? Looks like we need your help!

# Write a function that accepts a sequence of Reindeer names,
# and returns a sequence with the Reindeer names sorted by their last names.

# Example
# for this input:
# [
  # "Dasher Tonoyan",
  # "Dancer Moore",
  # "Prancer Chua",
  # "Vixen Hall",
  # "Comet Karavani",
  # "Cupid Foroutan",
  # "Donder Jonker",
  # "Blitzen Claus"
# ]
# you should return this output:
# [
  # "Prancer Chua",
  # "Blitzen Claus",
  # "Cupid Foroutan",
  # "Vixen Hall",
  # "Donder Jonker",
  # "Comet Karavani",
  # "Dancer Moore",
  # "Dasher Tonoyan",
# ]

# Tests
# sort_reindeer(['Kenjiro Mori', 'Susumu Tokugawa', 'Juzo Okita', 'Akira Sanada']),
# ['Kenjiro Mori', 'Juzo Okita', 'Akira Sanada', 'Susumu Tokugawa'])

# sort_reindeer(['Yasuo Kodai', 'Kenjiro Sado', 'Daisuke Aihara', 'Susumu Shima', 'Akira Sanada',
# 'Yoshikazu Okita', 'Shiro Yabu', 'Sukeharu Nanbu', 'Sakezo Yamamoto', 'Hikozaemon Ohta',
# 'Juzo Mori', 'Saburo Tokugawa']),
# ['Daisuke Aihara', 'Yasuo Kodai', 'Juzo Mori', 'Sukeharu Nanbu',
# 'Hikozaemon Ohta', 'Yoshikazu Okita', 'Kenjiro Sado', 'Akira Sanada',
# 'Susumu Shima', 'Saburo Tokugawa', 'Shiro Yabu', 'Sakezo Yamamoto'])

def sort_reindeer(reindeer : list) -> list:
    return sorted(reindeer, key=lambda x : x.split()[-1])

print(sort_reindeer([
  "Dasher Tonoyan",
  "Dancer Moore",
  "Prancer Chua",
  "Vixen Hall",
  "Comet Karavani",
  "Cupid Foroutan",
  "Donder Jonker",
  "Blitzen Claus"
]))


import pandas as pd
import numpy as np
from numpy.linalg import inv
import matplotlib.pyplot as plt
from matplotlib.pylab import rcParams
rcParams['figure.figsize']=10, 10

data=pd.read_csv('data.csv', ';')
print(data)

# we drop the zero values at the beginning

data=data.drop(data.index[0:1693])
data.reset_index(drop=True, inplace=True)

latitude=data[data.columns[4]].values.astype(float)
longitude=data[data.columns[5]].values.astype(float)
latitude=np.deg2rad(latitude)
longitude=np.deg2rad(longitude)
print(latitude)
print(longitude)

# We calculate x, y z:

earthRadius = 6378100
x = earthRadius * np.cos(latitude)*np.cos(longitude)
y = earthRadius * np.cos(latitude)*np.sin(longitude)
z = earthRadius * np.sin(latitude)
x=x-x[0]
y=y-y[0]
z=z-z[0]
z=np.array([x, y, z])
z=z.T

# We extract the time intervals and the acceleration:

time= data[data.columns[0]].values.astype(float)
time=time-time[0]
print(time)

acc=data[[data.columns[1], data.columns[2], data.columns[3]]].values.astype(float)
print(acc)

# KALMAN FILTER ALGORITHM

def kalman(acc, z, time):
    R=np.array([[np.std(z[:, 0])**2, 0, 0], [0, np.std(z[:, 1])**2, 0], [0, 0, np.std(z[:, 2])**2]])
    Q=0.05*np.identity(6)
    #Q=0

    x=np.zeros([z.shape[0], 6])
    P=np.identity(6)

    for k in range(1, z.shape[0]):
        delta=time[k]-time[k-1]

        A= np.array([[1, 0, 0, delta, 0, 0], [0, 1, 0, 0, delta, 0], [0, 0, 1, 0, 0, delta], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1]])
        B= np.array([[0.5*delta**2, 0, 0], [0, 0.5*delta**2, 0], [0, 0, 0.5*delta**2], [delta, 0, 0], [0, delta, 0], [0, 0, delta]])
        H= np.array([[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0]])

        x[k, :]=np.dot(A, x[k-1, :]) + np.dot(B, acc[k, :])
        P=np.dot(A, np.dot(P, A.T)) +Q

        K= P.dot( H.T.dot(inv(H.dot(P.dot(H.T)) + R)))

        x[k, :]= x[k, :] + K.dot(z[k, :] - H.dot(x[k, :]))

        P=(np.identity(6)-K.dot(H)).dot(P)

    return x

X=kalman(acc, z, time)

plt.figure()
plt.plot(X[:,0], X[:,1], color='red', label='trajectory filtered using KALMAN Filter')
plt.plot(x, y, color='blue', label='initial trajectory')
plt.grid(color='r', linestyle='--', linewidth=1)
plt.xlabel("x_coordinates")
plt.ylabel("y_coordinates")
plt.legend()
plt.title('Estimated trajectory')
plt.show

################################ TASK 2 KINECT #####################################"

import cv2
import numpy as np

def center(pointA, pointB):
    return (pointA[0] + pointB[0]) * 0.5, (pointA[1] + pointB[1]) * 0.5

#importing the images
image = cv2.imread('RGB_image.bmp')
depth = cv2.imread('Depth_image.png')

#extracting the contour of the object
blurred = cv2.pyrMeanShiftFiltering(image, 21, 51)
gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

_, contours, _ = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
rectangle = None
for contour in contours:

    # get rectangle bounding contour

    [x, y, w, h] = cv2.boundingRect(contour)
    # discard areas that are too large
    if h > 150 and h < 190 and w > 120 and w < 130:
        rect = cv2.minAreaRect(contour)
        rectangle = cv2.boxPoints(rect)
        rectangle = np.int0(rectangle)
        cv2.drawContours(image, [rectangle], 0, (255, 0, 0), 6)
plt.imshow(image)

#calculating and plotting the center of the object
(bl_point, tl_point, tr_point, br_point) = rectangle
(top_point_x, top_point_y) = center(tl_point, tr_point)
(bottom_point_x, bottom_point_y) = center(bl_point, br_point)
(left_point_x, left_point_y) = center(tl_point, bl_point)
(right_point_x, right_point_y) = center(tr_point, br_point)

cv2.line(image, (int(top_point_x), int(top_point_y)), (int(bottom_point_x), int(bottom_point_y)), (255, 0, 255), 6)
cv2.line(image, (int(left_point_x), int(left_point_y)), (int(right_point_x), int(right_point_y)), (255, 0, 255), 6)

cv2.circle(image, (int(top_point_x), int(top_point_y)), 3, (0, 0, 255), -1)
cv2.circle(image, (int(bottom_point_x), int(bottom_point_y)), 3, (0, 0, 255), -1)
cv2.circle(image, (int(left_point_x), int(left_point_y)), 3, (0, 0, 255), -1)
cv2.circle(image, (int(right_point_x), int(right_point_y)), 3, (0, 0, 255), -1)

center_x = (top_point_x+bottom_point_x)/2
center_y = (left_point_y+right_point_y)/2

# we print and plot the center point in the RGB image
print("Center point in RGB image:", center_x, center_y)
cv2.circle(image, (int(center_x), int(center_y)), 10, (255, 0, 0), -1)
plt.imshow(image)

# we apply the formula point_Depth= point_RGB *resolution_Depth/resolution_RBG
center_x_depth = center_x*(512/1920)
center_y_depth = center_y*(424/1080)

# we print and plot the center point in the depth image
print("Center point in depth image:", center_x_depth, center_y_depth)
cv2.circle(depth, (int(center_x_depth), int(center_y_depth)), 5, (255, 0, 0), -1)
plt.imshow(depth)

# We extract value of level of gray of the center point

print (depth[int(center_x_depth), int(center_y_depth)])


import random

import numpy as np

from nemo import logging
from nemo.collections.nlp.utils.callback_utils import (
    get_classification_report,
    get_f1_scores,
    list2str,
    plot_confusion_matrix,
    tensor2list,
)

__all__ = ['eval_iter_callback', 'eval_epochs_done_callback']

def eval_iter_callback(tensors, global_vars):
    if "all_intent_preds" not in global_vars.keys():
        global_vars["all_intent_preds"] = []
    if "all_intent_labels" not in global_vars.keys():
        global_vars["all_intent_labels"] = []
    if "all_slot_preds" not in global_vars.keys():
        global_vars["all_slot_preds"] = []
    if "all_slot_labels" not in global_vars.keys():
        global_vars["all_slot_labels"] = []
    if "all_subtokens_mask" not in global_vars.keys():
        global_vars["all_subtokens_mask"] = []

    all_intent_logits, all_intent_labels = [], []
    all_slot_logits, all_slot_labels = [], []
    all_subtokens_mask = []
    for kv, v in tensors.items():
        if kv.startswith('intent_logits'):
            for v_tensor in v:
                for logit_tensor in v_tensor:
                    all_intent_logits.append(tensor2list(logit_tensor))

        if kv.startswith('intents'):
            for v_tensor in v:
                for label_tensor in v_tensor:
                    all_intent_labels.append(tensor2list(label_tensor))

        if kv.startswith('slot_logits'):
            for v_tensor in v:
                for logit_tensor in v_tensor:
                    all_slot_logits.append(tensor2list(logit_tensor))

        if kv.startswith('slots'):
            for v_tensor in v:
                for label_tensor in v_tensor:
                    all_slot_labels.extend(tensor2list(label_tensor))

        if kv.startswith('subtokens_mask'):
            for v_tensor in v:
                for subtokens_mask_tensor in v_tensor:
                    all_subtokens_mask.extend(tensor2list(subtokens_mask_tensor))

    all_intent_preds = list(np.argmax(np.asarray(all_intent_logits), 1))
    all_slot_preds = list(np.argmax(np.asarray(all_slot_logits), 2).flatten())
    global_vars["all_intent_preds"].extend(all_intent_preds)
    global_vars["all_intent_labels"].extend(all_intent_labels)
    global_vars["all_slot_preds"].extend(all_slot_preds)
    global_vars["all_slot_labels"].extend(all_slot_labels)
    global_vars["all_subtokens_mask"].extend(all_subtokens_mask)

def eval_epochs_done_callback(global_vars, intents_label_ids, slots_label_ids, graph_fold=None, normalize_cm=True):
    intent_labels = np.asarray(global_vars['all_intent_labels'])
    intent_preds = np.asarray(global_vars['all_intent_preds'])

    slot_labels = np.asarray(global_vars['all_slot_labels'])
    slot_preds = np.asarray(global_vars['all_slot_preds'])
    subtokens_mask = np.asarray(global_vars['all_subtokens_mask']) > 0.5

    slot_labels = slot_labels[subtokens_mask]
    slot_preds = slot_preds[subtokens_mask]

    # print predictions and labels for a small random subset of data
    sample_size = 20
    i = 0
    if intent_preds.shape[0] > sample_size + 1:
        i = random.randint(0, intent_preds.shape[0] - sample_size - 1)
    logging.info("Sampled i_preds: [%s]" % list2str(intent_preds[i : i + sample_size]))
    logging.info("Sampled intents: [%s]" % list2str(intent_labels[i : i + sample_size]))
    logging.info("Sampled s_preds: [%s]" % list2str(slot_preds[i : i + sample_size]))
    logging.info("Sampled slots: [%s]" % list2str(slot_labels[i : i + sample_size]))

    if graph_fold:
        # calculate, plot and save the confusion_matrix
        plot_confusion_matrix(
            intent_labels, intent_preds, graph_fold, intents_label_ids, normalize=normalize_cm, prefix='Intent'
        )
        plot_confusion_matrix(
            slot_labels, slot_preds, graph_fold, slots_label_ids, normalize=normalize_cm, prefix='Slot'
        )

    logging.info('Slot Prediction Results:')
    slot_accuracy = np.mean(slot_labels == slot_preds)
    logging.info(f'Slot Accuracy: {slot_accuracy}')
    f1_scores = get_f1_scores(slot_labels, slot_preds, average_modes=['weighted', 'macro', 'micro'])
    for k, v in f1_scores.items():
        logging.info(f'{k}: {v}')

    logging.info(f'\n {get_classification_report(slot_labels, slot_preds, label_ids=slots_label_ids)}')

    logging.info('Intent Prediction Results:')
    intent_accuracy = np.mean(intent_labels == intent_preds)
    logging.info(f'Intent Accuracy: {intent_accuracy}')
    f1_scores = get_f1_scores(intent_labels, intent_preds, average_modes=['weighted', 'macro', 'micro'])
    for k, v in f1_scores.items():
        logging.info(f'{k}: {v}')

    logging.info(f'\n {get_classification_report(intent_labels, intent_preds, label_ids=intents_label_ids)}')

    return dict({'intent_accuracy': intent_accuracy, 'slot_accuracy': slot_accuracy})


import pygame, sys, random, math
from map_generation import *
from game_functions import *
from player import *
from paint_shop import *
import tournament
from traffic import *
from mini_game import *
from space_shooter import *

def read_coins(username):
    with open(f"profiles//profile_{username}.txt") as file:           #This function will read the user's profile from profile folder
        profile_info = file.readlines()
        profile_dict = eval(profile_info[0])
        coins = profile_dict['coins']
    return coins

def game(username, state):
    # initializes the pygame window
    pygame.init()
    clock = pygame.time.Clock()
    # CAPTION
    pygame.display.set_caption('BlackWolf')
    # SCREEN DIMENSIONS
    screen_width = 800
    screen_height = 600

    # Creates a window of size screen_width and screen_height
    screen = pygame.display.set_mode((screen_width, screen_height), 0, 32)

    # Stores all the objects on screen and their images in the form of a dictionary
    obj_dict, obj_img_dict, shops = create_map(screen)

    # initializes the state of the game

    player_dict = initialize_player()
    angle = 0

    # list of dictionaries of all cars
    car_dict_list = car_dicts(obj_dict['car'], obj_img_dict['car'])
    coins = read_coins(username)

    ended = False

    while state != 'end':
        # FOR ENDING GAME

        for events in pygame.event.get():
            if events.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if events.type == pygame.KEYDOWN:
                # checks if 'f' key is pressed and player colliding with any car

                if events.key == pygame.K_f and not player_dict['is_driving'] and collided_obj(player_dict, car_dict_list,'rect'):
                    player_dict['is_driving'] = True

                elif events.key == pygame.K_f and player_dict['is_driving']:
                    player_dict['is_driving'] = False

        keys = pygame.key.get_pressed()

        up = keys[pygame.K_UP]
        down = keys[pygame.K_DOWN]
        left = keys[pygame.K_LEFT]
        right = keys[pygame.K_RIGHT]

        player_rect = player_dict['rect']

        for key,values in shops.items():
            if player_rect.colliderect(shops[key][0]):
                state = key
                if state == 'space_shooter':
                    ended = False
                diff = player_rect.x - (obj_dict[key][0].x) + shops[key][0].width
                player_rect.x = shops[key][0].x + 20
                print(player_rect.x, player_rect.y)
                for keys, values in obj_dict.items():
                    for rect in obj_dict[keys]:
                        rect.x += diff

        if state == 'main_game':
            # clears the screen (by filling it with colour)
            screen.fill((77, 77, 77))
            # updating the movement of the player
            player_dict['movement'] = [up, down, left, right]
            # displays all objects on screen
            collision_side(screen,player_dict,obj_dict)
            #traffic
            scroll_objects(screen,player_dict, obj_dict)
            display(screen, obj_dict, obj_img_dict)

            traffic_cars(screen, car_dict_list, player_dict, obj_dict)
            display_player(screen, player_dict)

        elif state == 'paint_shop':
            coins, player_dict['purchased'], player_dict['image_path'], player_dict['car'], state = main_menu(coins,
                                                                                player_dict['purchased'],
                                                                                screen,
                                                                                font1,
                                                                                font2,
                                                                                player_dict['image_path'],
                                                                                player_dict['car'],
                                                                                username,
                                                                                state)
            player_dict['static_car'] = player_dict['car']

        elif state == 'tournament':
            state, coins = tournament.game(screen, username, screen_width, coins)

        elif state == 'mini_game':
            state, coins = mini_game(state, coins, screen, username)

        elif state == 'space_shooter':
            state , coins, ended = space_shooter(screen,coins,state,username,ended)

        # Limits the framerate of the game
        clock.tick(60)

        pygame.display.update()


import os
from pytorch_lightning.utilities.seed import seed_everything

from torch.utils.data.dataloader import T
import numpy as np
# TODO fix mkl problem
# os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import pywick
from pywick.models.segmentation import deeplab_v3_plus
from torch.utils.data.sampler import SubsetRandomSampler
from utils.util import json_file_to_dict_args, json_file_to_pyobj,get_tags
from dataio.loader import get_dataset, get_dataset_path
from dataio.transformation import get_dataset_transformation
from torch.utils.data import DataLoader, dataset
from pywick.modules import ModuleTrainer
import pywick.metrics as pwm
from utils.error_logger import ErrorLogger
import torch
import numpy
from tqdm import tqdm
import json
from utils.visualiser import Visualiser
from utils.error_logger import ErrorLogger

from models import get_model

def train(args):
    # if args.seed:
    #     seed_everything(5)

    # Parse input arguments
    # json_filename ="configs\config_SwinT.json"
    # json_filename ="configs\config_SwinT_unet.json"
    # json_filename ="configs\config_SwinT_v2_decoderCup.json"
    # json_filename ="configs\config_TransUnet.json"
    # json_filename ="configs\config_TransUnet_AG.json"
    # json_filename ="configs\config_deeplab.json"
    # json_filename ="configs\config_unet_epi_multi_att_dsv.json"

    # Load options
    json_opts = json_file_to_pyobj(args.config,args)
    wanb_config= get_tags(json_file_to_dict_args(args.config,args),args)

    train_opts = json_opts.training

    # Architecture type
    arch_type =  train_opts.arch_type

    # Setup Dataset and Augmentation
    ds_class = get_dataset(arch_type)
    ds_path  = get_dataset_path(arch_type, json_opts.data_path)
    ds_transform = get_dataset_transformation(arch_type, opts=json_opts.augmentation)

    # Setup Data Loader

    seed_everything(5)
    from sklearn.model_selection import KFold
    train_dataset = ds_class(ds_path, split='all',      transform=ds_transform['train'], preload_data=train_opts.preloadData,balance=False)

    splits=KFold(n_splits=args.cross_val,shuffle=True,random_state=int(os.environ.get("PL_GLOBAL_SEED")))

    for fold, (train_idx,val_idx) in enumerate(splits.split(np.arange(len(train_dataset)))):
        #re-init model each fold
        model = get_model(json_opts.model)

        train_sampler = SubsetRandomSampler(train_idx)

        test_sampler = SubsetRandomSampler(val_idx)
        train_loader = DataLoader(dataset=train_dataset, num_workers=8, batch_size= train_opts.batchSize, shuffle=False,pin_memory=True,persistent_workers=False,sampler=train_sampler)
        valid_loader= DataLoader(dataset=train_dataset, num_workers=8, batch_size= train_opts.batchSize, shuffle=False,pin_memory=True,persistent_workers=False,sampler=test_sampler)
        wanb_config['tags'] = wanb_config['tags']+'_fold_{}'.format(fold)

        visualizer = Visualiser(json_opts.visualisation, save_dir=model.save_dir,resume= False if json_opts.model.continue_train else False,config=wanb_config)
        error_logger = ErrorLogger()
        start_epoch = False if json_opts.training.n_epochs < json_opts.model.which_epoch else json_opts.model.continue_train
        if train_opts.lr_policy == "one_cycle":
            model.set_scheduler(train_opts,len_train=len(train_loader),max_lr=json_opts.model.max_lr,division_factor=json_opts.model.division_factor,last_epoch=json_opts.model.which_epoch * len(train_loader) if start_epoch else -1)
        else:
            model.set_scheduler(train_opts)
        frozen=False
        # model.freeze()
        for epoch in range(model.which_epoch, train_opts.n_epochs):
            print('(epoch: %d, total # iters: %d)' % (epoch, len(train_loader)))
            #if epoch % 10 == 0:
                #if frozen:
                    #model.unfreeze()
                    #frozen = False
                #else:
                    #print("freezing model")
                    #model.freeze()
                    #frozen=True

            # Training Iterations

            for epoch_iter, (images, labels) in tqdm(enumerate(train_loader, 1), total=len(train_loader)):
                # Make a training update
                model.set_input(images, labels)
                # with torch.autograd.set_detect_anomaly(True):
                model.optimize_parameters()
                # model.optimize_parameters_accumulate_grd(epoch_iter)
                lr = model.update_learning_rate()

                lr = {"lr":lr}
                # Error visualisation
                errors = model.get_current_errors()
                stats = model.get_segmentation_stats()
                error_logger.update({**errors, **stats,**lr}, split='train')
                visualizer.plot_current_errors(epoch, error_logger.get_errors('train'), split_name='train')

            # Validation and Testing Iterations
            for loader, split in zip([valid_loader], ['validation']):
                for epoch_iter, (images, labels) in tqdm(enumerate(loader, 1), total=len(loader)):

                    # Make a forward pass with the model
                    model.set_input(images, labels)
                    model.validate()

                    # Error visualisation
                    errors = model.get_current_errors()
                    stats = model.get_segmentation_stats()
                    error_logger.update({**errors, **stats}, split=split)

                    # Visualise predictions
                    visuals = model.get_current_visuals()
                    visualizer.display_current_results(visuals, epoch=epoch, save_result=False)

            # Update the plots
            for split in ['validation']:
                visualizer.plot_current_errors(epoch, error_logger.get_errors(split), split_name=split)
                visualizer.print_current_errors(epoch, error_logger.get_errors(split), split_name=split)
            error_logger.reset()
            visualizer.upload_limit=45

            # Save the model parameters
            if epoch % train_opts.save_epoch_freq == 0:
                model.save(epoch)
                visualizer.save_model(epoch)

            # Update the model learning rate
            # model.update_learning_rate(errors['Seg_Loss'])
        visualizer.finish()
        del train_loader,valid_loader

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='CNN Seg Training Function')
    parser.add_argument('-c', '--config',  help='training config file', required=False,type=str)

    parser.add_argument('-d', '--debug',   help='returns number of parameters and bp/fp runtime', action='store_true')
    parser.add_argument('-a', '--arch_type',   help='wich architecture type')
    parser.add_argument('-wandb', '--use_wandb',   help='use wandb to log the training',type=bool)
    parser.add_argument('-cont', '--continue_train',   help='Should contine training?',type=bool)
    parser.add_argument('-seed',help='Use the same seed>',type=bool)
    parser.add_argument('-wep', '--which_epoch',   help='which epoch to continue training from?',type=int)
    parser.add_argument('-maxlr', '--max_lr',   help='maximum learning rate for cyclic learning',  type=float)
    parser.add_argument('-bs', '--batchSize',   help='batch size',type=int)
    parser.add_argument('-cv', '--cross_val',   help='Cross validation folds',type=int,default=1)
    parser.add_argument('-ep', '--n_epochs',   help='number of epochs', type=int)
    parser.add_argument('-img', '--img_size',   help='number of epochs', type=int)
    parser.add_argument('-out', '--output_nc',   help='Number of output classes', type=int)
    parser.add_argument('-pretrain', '--path_pre_trained_model',   help='path to pre trained model', type=str)
    parser.add_argument('-tag',   help='tags passed to wandb' , type=str,default="")
    parser.add_argument('--gpu_ids',   help='gpu id to use for trianing' , type=int,default=0)
    args = parser.parse_args()

    train(args)


import torch.nn as nn
from models import models

def freezeResNet(model):
    for name, p in model.named_parameters():
        if 'fc' not in name:
            p.required_grad = False
    return model #이거 필요한가?

def freezeDenseNet(model):
    for name, p in model.named_parameters():
        if 'classifier' not in name:
            p.required_grad = False
    return model

def freezeVGG(model):
    for name, p in model.named_parameters():
        if 'classifier.6' not in name:
            p.required_grad = False
    return model

def fineTuningModel(name, num_classes, is_freeze, pretrained = True): #freeze #true true시 r

    model = models(name, pretrained)
    if 'resnet' in name:
        input_features = model.fc.in_features
        model.fc = nn.Linear(in_features = input_features, out_features = num_classes, bias=True)
        if is_freeze and pretrained :
            model = freezeResNet(model)
    elif 'vgg' in name:
        input_features = model.classifier[-1].in_features
        model.classifier[-1] = nn.Linear(in_features = input_features, out_features = num_classes, bias=True)
        if is_freeze and pretrained:
            model = freezeVGG(model)
    elif 'densenet' in name:
        input_features = model.classifier.in_features
        model.classifier = nn.Linear(in_features = input_features, out_features = num_classes, bias=True)
        if is_freeze and pretrained:
            model = freezeDenseNet(model)

    return model


#!/usr/bin/env python3
#
# Parses gutenberg.org RDF files into JSON format.

import argparse
import json
import re
from lxml import etree

NAMESPACES = {
    'dcterms': 'http://purl.org/dc/terms/',
    'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
    'pgterms': 'http://www.gutenberg.org/2009/pgterms/',
}

EXTRACTORS = [
    {
        'key': 'language',
        'xpath': './/dcterms:language//rdf:value',
        'xform': lambda node: node.text,
        'first': True,
    },
    {
        'key': 'title',
        'xpath': './/dcterms:title',
        'xform': lambda node: node.text,
        'first': True,
    },
    {
        'key': 'author',
        'xpath': './/dcterms:creator//pgterms:name',
        'xform': lambda node: node.text,
        'first': True,
    },
    {
        'key': 'url',
        'xpath': './/pgterms:file/@rdf:about',
        'xform': lambda node: node,
        'filter': lambda item: re.match(r'.*\d+\.zip', item)
    },
]
'''Each "action" defines how a piece of data is extracted from an RDF file
and transformed to JSON.

Properties:
  key       [string]    Target JSON property name.
  xpath     [string]    Target RDF nodes, conforming to `lxml.xpath`.
  xform     [function]  Transformation applied to nodes satisfying xpath.
  filter    [function]  (Optional) Selects elements from xform-ed nodes.
  first     [boolean]   (Optional) Replaces list with first element (or None).
'''

def extract(node, key, xpath, xform, **kwargs):
    '''Applies an EXTRACTOR action to the input node, returning a list of
    key-value pairs.
    '''
    filter_ = kwargs.get('filter')
    data = list(filter(filter_,
        map(xform, node.xpath(xpath, namespaces=NAMESPACES))))
    if kwargs.get('first', False):
        data = (data + [None])[0]
    return (key, data)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', help='xml:base="http://www.gutenberg.org/"')
    args = parser.parse_args()

    root = etree.parse(args.infile)
    data = dict([extract(root, **kwargs) for kwargs in EXTRACTORS])
    print(json.dumps(data))


from django.contrib.auth import authenticate, login
from django.db import models
from django.contrib.auth.models import User
import requests
import simplejson
import constants
from django.http import QueryDict
from django.shortcuts import redirect
import logging

from lib.Errors import Errors

class Profile(User):
    fb_id = models.IntegerField(default=0)
    access_token = models.CharField(max_length=400)

    class Meta:
        app_label = "humbert"

    @classmethod
    def create_new_fb_user(klass, fb_id, access_token):
        if fb_id not in [None, ''] and access_token not in [None, '']:
            fb_user = klass.get_fb_user_dict(access_token)
            last_name = fb_user.get('last_name')
            first_name = fb_user.get('first_name')
            username= fb_user.get('username')
            profile = klass(fb_id=fb_id, username=username, access_token=access_token, first_name=first_name, last_name=last_name)
            profile.save()
            return profile

    @classmethod
    def get_fb_user_dict(klass, access_token):
        #make a server side query to fb api and get the user info
        url = 'https://graph.facebook.com/me?access_token=%s' % (access_token)
        response = requests.get(url).text
        user_dict = simplejson.loads(response)

        if user_dict.get('error') is not None:
            raise Errors.fb_error

        logging.info(user_dict)
        return user_dict

    """
    Takes the auth user and returns a Profile object.
    """
    @classmethod
    def get_profile(klass, user):
        return Profile.objects.get(id=user.id)

    @classmethod
    def init_session(klass, request):
        if 'profile' not in request.session:
            request.session['profile'] = Profile.get_profile(request.user)
            try:
                fb_info = Profile.get_fb_user_dict(request.session['profile'].access_token)
                request.session.update(fb_info)
            except Errors.fb_error:
                redirect('/logout')

    @classmethod
    def handle_fb_errors(klass, error):
        pass

    def extend_token(self, access_token):
        url = "https://graph.facebook.com/oauth/access_token?client_id=%s&client_secret=%s&grant_type=fb_exchange_token&fb_exchange_token=%s" % (constants.client_id, constants.client_secret, access_token)
        response = requests.get(url)
        qd = QueryDict(response.text)
        access_token = qd.get('access_token')
        expiry_date = qd.get('expires')

        if access_token is not None:
            self.access_token = access_token
            self.save()

        return access_token, expiry_date


import  airflow
import datetime
from airflow import DAG
from airflow.models import Variable
from airflow.operators import bash_operator, dummy_operator, python_operator

default_args = {
    'owner': 'Nitin Ware',
    'depends_on_past': False,
    'retries': 1,
    'retry_delay': datetime.timedelta(minutes=5),
    'start_date': airflow.utils.dates.days_ago(1),
}

dag = DAG('ariflow_variables', 'catchup=False', default_args=default_args, schedule_interval="@once",)

def calc():
    var = Variable.get("var2")
    nv = 5 + int(var)
    print(nv)

start_dag = dummy_operator.DummyOperator(
    task_id='start',
    default_args=default_args,
    dag=dag,
)

read_var_bash = bash_operator.BashOperator(
    task_id='read_value_bash',
    bash_command='echo {{var.value.var3}}',
    dag=dag
)

read_var_python = python_operator.PythonOperator(
    task_id='read_value_python',
    python_callable=calc,
    dag=dag
)

end_dag = dummy_operator.DummyOperator(
    task_id='end',
    default_args=default_args,
    dag=dag,
)

start_dag >> [read_var_bash, read_var_python]

end_dag << [read_var_bash, read_var_python]


import paddle
from coco import build_coco
from coco import get_loader
from detr import build_detr

def main():
    model, criterion, postprocessors = build_detr()
    model_state = paddle.load('./detr_resnet50.pdparams')
    model.set_dict(model_state)
    model.eval()

    # 2. Create val dataloader
    dataset_val = build_coco('val', '/dataset/coco/')
    dataloader_val = get_loader(dataset_val,
                                batch_size=4,
                                mode='val',
                                multi_gpu=False)

    with paddle.no_grad():
        for batch_id, data in enumerate(dataloader_val):
            samples = data[0]
            targets = data[1]
            outputs = model(samples)
            loss_dict = criterion(outputs, targets)
            orig_target_sizes = paddle.stack([t['orig_size'] for t in targets], axis=0)
            results = postprocessors['bbox'](outputs, orig_target_sizes)
            res = {target['image_id']: output for target, output in zip(targets, results)}

            print(f'{batch_id}/{len(dataloader_val)} done')

    print('all done')

if __name__ == '__main__':
    main()


import argparse
import numpy as np
import random

import torch
from torch.autograd import Variable

import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

#this code gets the namespace from the directory above
import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir)

from models import load_models, generate
from utils import to_gpu, Corpus, batchify

parser = argparse.ArgumentParser(description='PyTorch ARAE for Text Eval')

###############################################################
# Load required models:
### ARAE
### Inverter
### "black box classifier"
##############################################################
parser.add_argument('--load_path', type=str, required = True,
                    help='load path for ARAE model')
parser.add_argument('--inverter_path', type = str, required = True, help = 'load path for inverter')
parser.add_argument('--classifier_path', type = str, required = True, help = 'load path for classifier')

parser.add_argument('--batch_size', type=int, default=50, metavar='N',
                    help='batch size')
parser.add_argument('--epochs' , type= int, default= 15, help = 'Number of epochs' )
parser.add_argument('--cuda', type = bool, default = True, help = 'cuda')
args = parser.parse_args()
print(vars(args))

if args.cuda:
    gpu = True
else:
    gpu = False

################################################################
#HYPER PARAMS
################################################################
GAMMA = 0.1
LEARNING_RATE = 1.0

###############################################################
# Models
###############################################################

class Q_function(nn.Module):
    '''
    is an MLP
    takes the current state and parameterizes Q(s,a)
    '''
    def __init__(state_dim,action_dim, layers, vocab_size, activation=nn.ReLU(), gpu=True):
        super(Q_function, self).__init__()

        #MLP for latent space code
        self.ninput = state_dim + action_dim
        self.noutput= noutput
        layer_sizes = [self.ninput] + [int(x) for x in layers.split('-')]
        self.layers = []

        for i in range(len(layer_sizes)-1):
            layer = nn.Linear(layer_sizes[i], layer_sizes[i+1])
            self.layers.append(layer)
            self.add_module("layer"+str(i+1), layer)

            # No batch normalization after first layer
            self.layers.append(activation)
            self.add_module("activation"+str(i+1), activation)
        layer = nn.Linear(layer_sizes[-1], 1)
        self.layers.append(layer)
        self.add_module("layer"+str(len(self.layers)), layer)
    def forward(self, state, action):
        for layer in self.layers:
            z = layer(z)
        return(z)

#######Training code

#load generator, classifier, inverter, autoencoder
def load_inverter(inverter_path):
    model_args = json.load(open("{}/args.json".format(load_path), "r"))
    word2idx = json.load(open("{}/vocab.json".format(load_path), "r"))
    idx2word = {v: k for k, v in word2idx.items()}

    inverter = MLP_I(...)

    #delete this stuff once we know what the inverter hyperparams are
    autoencoder = Seq2Seq(emsize=model_args['emsize'],
                          nhidden=model_args['nhidden'],
                          ntokens=model_args['ntokens'],
                          nlayers=model_args['nlayers'],
                          hidden_init=model_args['hidden_init'])
    gan_gen = MLP_G(ninput=model_args['z_size'],
                    noutput=model_args['nhidden'],
                    layers=model_args['arch_g'])
    gan_disc = MLP_D(ninput=model_args['nhidden'],
                     noutput=1,
                     layers=model_args['arch_d'])

    print('Loading models from'+load_path)
    ae_path = os.path.join(load_path, "autoencoder_model.pt")
    gen_path = os.path.join(load_path, "gan_gen_model.pt")
    disc_path = os.path.join(load_path, "gan_disc_model.pt")

    autoencoder.load_state_dict(torch.load(ae_path))
    gan_gen.load_state_dict(torch.load(gen_path))
    gan_disc.load_state_dict(torch.load(disc_path))
    return model_args, idx2word, autoencoder, gan_gen, gan_disc

model_args, idx2word, autoencoder, gan_gen, gan_disc = load_models(args.load_path)
inverter_args, inverter = load_inverter(args.inverter_path)

if args.cuda:
    autoencoder= autoencoder.cuda()
    gan_gen = gan_gen.cuda()
    gan_disc = gan_disc.cuda()
    inverter = inverter.cuda()

corpus = Corpus(args.data_path,maxlen=args.maxlen,vocab_size=args.vocab_size,lowercase=args.lowercase)
eval_batch_size = 10
test_data = batchify(corpus.test, eval_batch_size, shuffle=False)
train_data = batchify(corpus.train, args.batch_size, shuffle=True)
print("Loaded data!")

def reward(s,a,label):
    '''
    basically pseudocode
    '''
    new_z = s+a
    new_code = generator(new_z)
    new_sentence = autoencoder.decode(new_code)
    return -1* classifier(new_sentence)[label]

def train_search(batch, mag):
    '''
    training function for search
    '''
    #psuedocode bassically -- first zero gradients
    sentence, label = batch
    encoded = autoencoder.encode(sentence).detach()
    latent_code = inverter(encoded)
    delta = search(latent_code,sentence,mag)
    perturbation = latent_code + delta
    new_sent = autoencode.decode(perturbation)

    out = classifier(new_sent)

    #some kind of polcy grad here
    return


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

import os
import numpy as np
import awkward as ak
import particle
from matplotlib import pyplot as plt
import argparse
import logging

from atar.utils import geometry
from core.io import get_array
from core.selector import select_atar_dar
from core.utils import get_pion_rz
from atar.utils import compute_atar_ids
from core.identification import rnn_model

import tensorflow as tf
from keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from sklearn import metrics

if __name__ == '__main__':

    debug    = False
    do_fit   = False
    do_plots = True

    from core import log; log.getChild(__name__)
    if debug:
        log.setLevel(logging.DEBUG)
        from core import ch;
        ch.setLevel(logging.DEBUG)

    log.info('Starting basic analysis!')

    _pimunu = get_array(
        'data_v5/test_uniform_beam',
        # '/Users/qbuat/pioneer/data_65_2.5_degrader0.5/',
        'pimudif',
        debug=debug)

    _pienu = get_array(
        'data_v5/test_uniform_beam',
        # '/Users/qbuat/pioneer/data_65_2.5_degrader0.5/',
        'pienu',
        debug=debug)

    compute_atar_ids(_pimunu)
    compute_atar_ids(_pienu)
    _pimunu = select_atar_dar(_pimunu, evt_type='pimudif', verbose=True)
    _pienu = select_atar_dar(_pienu, evt_type='pienu', verbose=True)

    # atar only stuff
    _pimunu_atar = ak.zip({
        _f: _pimunu[_f] for _f in filter(lambda n: 'atar.' in n, _pimunu.fields)})
    _pienu_atar = ak.zip({
        _f: _pienu[_f] for _f in filter(lambda n: 'atar.' in n, _pienu.fields)})

    _fields = ['atar.planeid', 'atar.pixelid', 'atar.time', 'atar.edep']

    #----
    X_pimunu_odd = []
    X_pimunu_eve = []
    _pimunu_atar_odd = _pimunu_atar[_pimunu_atar['atar.planeid'] % 2 != 0]
    _pimunu_atar_eve = _pimunu_atar[_pimunu_atar['atar.planeid'] % 2 == 0]
    for field in _fields:
        _odd =  ak.fill_none(ak.pad_none(_pimunu_atar_odd[field], 300, clip=True), -999)
        _odd = ak.to_numpy(_odd).reshape(len(_odd), 300, 1)
        X_pimunu_odd += [_odd]
        _eve =  ak.fill_none(ak.pad_none(_pimunu_atar_eve[field], 300, clip=True), -999)
        _eve = ak.to_numpy(_eve).reshape(len(_eve), 300, 1)
        X_pimunu_eve += [_eve]
    X_pimunu_odd = np.concatenate(X_pimunu_odd, axis=2)
    X_pimunu_eve = np.concatenate(X_pimunu_eve, axis=2)

    #----
    X_pienu_odd = []
    X_pienu_eve = []
    _pienu_atar_odd = _pienu_atar[_pienu_atar['atar.planeid'] % 2 != 0]
    _pienu_atar_eve = _pienu_atar[_pienu_atar['atar.planeid'] % 2 == 0]
    for field in _fields:
        _odd =  ak.fill_none(ak.pad_none(_pienu_atar_odd[field], 300, clip=True), -999)
        _odd = ak.to_numpy(_odd).reshape(len(_odd), 300, 1)
        X_pienu_odd += [_odd]
        _eve =  ak.fill_none(ak.pad_none(_pienu_atar_eve[field], 300, clip=True), -999)
        _eve = ak.to_numpy(_eve).reshape(len(_eve), 300, 1)
        X_pienu_eve += [_eve]
    X_pienu_odd = np.concatenate(X_pienu_odd, axis=2)
    X_pienu_eve = np.concatenate(X_pienu_eve, axis=2)

    X_odd = np.concatenate([X_pienu_odd, X_pimunu_odd])
    X_eve = np.concatenate([X_pienu_eve, X_pimunu_odd])

    _target = np.concatenate(
        [
            np.ones(len(_pienu)),
            np.zeros(len(_pimunu)),
        ]
    )

    if not (len(X_odd) == len(X_eve) == len(_target)):
        raise ValueError

    _train_idx, _test_idx = train_test_split(
        np.arange(len(X_odd)),
        test_size=0.2,
        random_state=42)

    X_odd_train = X_odd[_train_idx]
    X_odd_test  = X_odd[_test_idx]
    X_eve_train = X_eve[_train_idx]
    X_eve_test  = X_eve[_test_idx]
    y_train = _target[_train_idx]
    y_test = _target[_test_idx]

    log.info('Ready for analysis')

    log.info('creating and compiling the neural network')
    _nn_model = rnn_model()
    optimizer = Adam(learning_rate=1e-5)
    _nn_model.compile(
        loss='binary_crossentropy',
        optimizer=optimizer,
        metrics=['accuracy']
    )

    _model_file = 'cache/rnn_pimudif.h5'
    if do_fit:
        try:
            _history = _nn_model.fit(
                [X_odd_train, X_eve_train],
                y_train,
                epochs=100,
                validation_split=0.1,
                callbacks=[
                    tf.keras.callbacks.EarlyStopping(verbose=True, patience=20, monitor='val_loss'),
                    tf.keras.callbacks.ModelCheckpoint(
                        _model_file,
                        monitor='val_loss',
                        verbose=True,
                        save_best_only=True)])
            _nn_model.save(_model_file)
        # Allow keyboard interupt to not go over all epochs
        except KeyboardInterrupt:
            print('Ended early...')
    else:
        _nn_model = tf.keras.models.load_model(_model_file)

    if do_plots:
        y_pred = _nn_model.predict([X_odd_test, X_eve_test])

        pienu_score = y_pred[y_test == 1]
        pimunu_score = y_pred[y_test == 0]
        fig = plt.figure()
        ax = fig.add_subplot()
        ax.set_xlabel('RNN Discriminant Score')
        ax.set_ylabel('Entries')

        plt.hist(
            pienu_score,
            bins=100,
            range=(0.8, 1),
            color='blue',
            label='pi-e')
        plt.hist(
            pimunu_score,
            bins=100,
            range=(0.8, 1),
            color='red',
            alpha=0.5,
            label='pi - mu [dif] - e')
        plt.yscale('log')
        plt.legend()

        fpr, tpr, thresholds = metrics.roc_curve(y_test, y_pred)
        fpr = fpr[fpr>0]
        tpr = tpr[np.where(fpr>0)]
        rej = 1 / fpr
        fig = plt.figure()
        ax = fig.add_subplot()
        ax.set_xlabel('pi-e-nu efficiency')
        ax.set_ylabel('pi [dar] - mu [dif] - e rejection')
        plt.plot(tpr, rej)
        # plt.yscale('log')

        plt.show()