import math
import random
import functools
import operator

import torch
from torch import nn
from torch.nn import functional as F
from torch.autograd import Function

from op import FusedLeakyReLU, fused_leaky_relu, upfirdn2d, conv2d_gradfix

class PixelNorm(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, input):
        return input * torch.rsqrt(torch.mean(input ** 2, dim=1, keepdim=True) + 1e-8)

def make_kernel(k):
    k = torch.tensor(k, dtype=torch.float32)

    if k.ndim == 1:
        k = k[None, :] * k[:, None]

    k /= k.sum()

    return k

class Upsample(nn.Module):
    def __init__(self, kernel, factor=2):
        super().__init__()

        self.factor = factor
        kernel = make_kernel(kernel) * (factor ** 2)
        self.register_buffer("kernel", kernel)

        p = kernel.shape[0] - factor

        pad0 = (p + 1) // 2 + factor - 1
        pad1 = p // 2

        self.pad = (pad0, pad1)

    def forward(self, input):
        out = upfirdn2d(input, self.kernel, up=self.factor, down=1, pad=self.pad)

        return out

class Downsample(nn.Module):
    def __init__(self, kernel, factor=2):
        super().__init__()

        self.factor = factor
        kernel = make_kernel(kernel)
        self.register_buffer("kernel", kernel)

        p = kernel.shape[0] - factor

        pad0 = (p + 1) // 2
        pad1 = p // 2

        self.pad = (pad0, pad1)

    def forward(self, input):
        out = upfirdn2d(input, self.kernel, up=1, down=self.factor, pad=self.pad)

        return out

class Blur(nn.Module):
    def __init__(self, kernel, pad, upsample_factor=1):
        super().__init__()

        kernel = make_kernel(kernel)

        if upsample_factor > 1:
            kernel = kernel * (upsample_factor ** 2)

        self.register_buffer("kernel", kernel)

        self.pad = pad

    def forward(self, input):
        out = upfirdn2d(input, self.kernel, pad=self.pad)

        return out

class EqualConv2d(nn.Module):
    def __init__(
        self, in_channel, out_channel, kernel_size, stride=1, padding=0, bias=True
    ):
        super().__init__()

        self.weight = nn.Parameter(
            torch.randn(out_channel, in_channel, kernel_size, kernel_size)
        )
        self.scale = 1 / math.sqrt(in_channel * kernel_size ** 2)

        self.stride = stride
        self.padding = padding

        if bias:
            self.bias = nn.Parameter(torch.zeros(out_channel))

        else:
            self.bias = None

    def forward(self, input):
        out = conv2d_gradfix.conv2d(
            input,
            self.weight * self.scale,
            bias=self.bias,
            stride=self.stride,
            padding=self.padding,
        )

        return out

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.weight.shape[1]}, {self.weight.shape[0]},"
            f" {self.weight.shape[2]}, stride={self.stride}, padding={self.padding})"
        )

class EqualLinear(nn.Module):
    def __init__(
        self, in_dim, out_dim, bias=True, bias_init=0, lr_mul=1, activation=None
    ):
        super().__init__()

        self.weight = nn.Parameter(torch.randn(out_dim, in_dim).div_(lr_mul))

        if bias:
            self.bias = nn.Parameter(torch.zeros(out_dim).fill_(bias_init))

        else:
            self.bias = None

        self.activation = activation

        self.scale = (1 / math.sqrt(in_dim)) * lr_mul
        self.lr_mul = lr_mul

    def forward(self, input):
        if self.activation:
            out = F.linear(input, self.weight * self.scale)
            out = fused_leaky_relu(out, self.bias * self.lr_mul)

        else:
            out = F.linear(
                input, self.weight * self.scale, bias=self.bias * self.lr_mul
            )

        return out

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.weight.shape[1]}, {self.weight.shape[0]})"
        )

class ModulatedConv2d(nn.Module):
    def __init__(
        self,
        in_channel,
        out_channel,
        kernel_size,
        style_dim,
        demodulate=True,
        upsample=False,
        downsample=False,
        blur_kernel=[1, 3, 3, 1],
        fused=True,
    ):
        super().__init__()

        self.eps = 1e-8
        self.kernel_size = kernel_size
        self.in_channel = in_channel
        self.out_channel = out_channel
        self.upsample = upsample
        self.downsample = downsample

        if upsample:
            factor = 2
            p = (len(blur_kernel) - factor) - (kernel_size - 1)
            pad0 = (p + 1) // 2 + factor - 1
            pad1 = p // 2 + 1

            self.blur = Blur(blur_kernel, pad=(pad0, pad1), upsample_factor=factor)

        if downsample:
            factor = 2
            p = (len(blur_kernel) - factor) + (kernel_size - 1)
            pad0 = (p + 1) // 2
            pad1 = p // 2

            self.blur = Blur(blur_kernel, pad=(pad0, pad1))

        fan_in = in_channel * kernel_size ** 2
        self.scale = 1 / math.sqrt(fan_in)
        self.padding = kernel_size // 2

        self.weight = nn.Parameter(
            torch.randn(1, out_channel, in_channel, kernel_size, kernel_size)
        )

        self.modulation = EqualLinear(style_dim, in_channel, bias_init=1)

        self.demodulate = demodulate
        self.fused = fused

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.in_channel}, {self.out_channel}, {self.kernel_size}, "
            f"upsample={self.upsample}, downsample={self.downsample})"
        )

    def forward(self, input, style):
        batch, in_channel, height, width = input.shape

        if not self.fused:
            weight = self.scale * self.weight.squeeze(0)
            style = self.modulation(style)

            if self.demodulate:
                w = weight.unsqueeze(0) * style.view(batch, 1, in_channel, 1, 1)
                dcoefs = (w.square().sum((2, 3, 4)) + 1e-8).rsqrt()

            input = input * style.reshape(batch, in_channel, 1, 1)

            if self.upsample:
                weight = weight.transpose(0, 1)
                out = conv2d_gradfix.conv_transpose2d(
                    input, weight, padding=0, stride=2
                )
                out = self.blur(out)

            elif self.downsample:
                input = self.blur(input)
                out = conv2d_gradfix.conv2d(input, weight, padding=0, stride=2)

            else:
                out = conv2d_gradfix.conv2d(input, weight, padding=self.padding)

            if self.demodulate:
                out = out * dcoefs.view(batch, -1, 1, 1)

            return out

        # print(style.size())

        style = self.modulation(style).view(batch, 1, in_channel, 1, 1)
        weight = self.scale * self.weight * style

        if self.demodulate:
            demod = torch.rsqrt(weight.pow(2).sum([2, 3, 4]) + 1e-8)
            weight = weight * demod.view(batch, self.out_channel, 1, 1, 1)

        weight = weight.view(
            batch * self.out_channel, in_channel, self.kernel_size, self.kernel_size
        )

        if self.upsample:
            input = input.view(1, batch * in_channel, height, width)
            weight = weight.view(
                batch, self.out_channel, in_channel, self.kernel_size, self.kernel_size
            )
            weight = weight.transpose(1, 2).reshape(
                batch * in_channel, self.out_channel, self.kernel_size, self.kernel_size
            )
            out = conv2d_gradfix.conv_transpose2d(
                input, weight, padding=0, stride=2, groups=batch
            )
            _, _, height, width = out.shape
            out = out.view(batch, self.out_channel, height, width)
            out = self.blur(out)

        elif self.downsample:
            input = self.blur(input)
            _, _, height, width = input.shape
            input = input.view(1, batch * in_channel, height, width)
            out = conv2d_gradfix.conv2d(
                input, weight, padding=0, stride=2, groups=batch
            )
            _, _, height, width = out.shape
            out = out.view(batch, self.out_channel, height, width)

        else:
            input = input.view(1, batch * in_channel, height, width)
            out = conv2d_gradfix.conv2d(
                input, weight, padding=self.padding, groups=batch
            )
            _, _, height, width = out.shape
            out = out.view(batch, self.out_channel, height, width)

        return out

class NoiseInjection(nn.Module):
    def __init__(self):
        super().__init__()

        self.weight = nn.Parameter(torch.zeros(1))

    def forward(self, image, noise=None):
        if noise is None:
            batch, _, height, width = image.shape
            noise = image.new_empty(batch, 1, height, width).normal_()

        return image + self.weight * noise

class ConstantInput(nn.Module):
    def __init__(self, channel, size=4):
        super().__init__()

        self.input = nn.Parameter(torch.randn(1, channel, size, size))

    def forward(self, input):
        batch = input.shape[0]
        # print(batch)
        out = self.input.repeat(batch, 1, 1, 1)

        return out

class StyledConv(nn.Module):
    def __init__(
        self,
        in_channel,
        out_channel,
        kernel_size,
        style_dim,
        upsample=False,
        blur_kernel=[1, 3, 3, 1],
        demodulate=True,
    ):
        super().__init__()

        self.conv = ModulatedConv2d(
            in_channel,
            out_channel,
            kernel_size,
            style_dim,
            upsample=upsample,
            blur_kernel=blur_kernel,
            demodulate=demodulate,
        )

        self.noise = NoiseInjection()
        # self.bias = nn.Parameter(torch.zeros(1, out_channel, 1, 1))
        # self.activate = ScaledLeakyReLU(0.2)
        self.activate = FusedLeakyReLU(out_channel)

    def forward(self, input, style, mask = None, noise=None):
        # print('jfnksdjfdkjfkjsf')
        # print(style.size())
        out = self.conv(input, style)
        # print(out.size())
        out = self.noise(out, noise=noise)
        # out = out + self.bias
        out = self.activate(out)

        # print(out.size(), 'point22')

        if mask is not None:
          # print(mask.size(), 'mask size orig')
          bs, c, h, w = out.size()
          # print(w,h)
          # print(out.size(), 'out size in layer')
          mask = F.interpolate(mask, size = (h,w), mode = 'nearest')
          # print(mask.size(), 'mask_size dfksfkdskfksdkfs')
          mask = mask.repeat(1, c, 1,1)
          # print(mask.size(), 'mask size after unsqueeze')
          out = out*mask

        # print(out.size())

        return out

class ToRGB(nn.Module):
    def __init__(self, in_channel, style_dim, upsample=True, blur_kernel=[1, 3, 3, 1]):
        super().__init__()

        if upsample:
            self.upsample = Upsample(blur_kernel)

        self.conv = ModulatedConv2d(in_channel, 3, 1, style_dim, demodulate=False)
        self.bias = nn.Parameter(torch.zeros(1, 3, 1, 1))

    def forward(self, input, style, mask = None,  skip=None):

        out = self.conv(input, style)
        out = out + self.bias

        if skip is not None:
            skip = self.upsample(skip)

            out = out + skip
        # print(out.size())

        if mask is not None:
          bs, c, h, w = out.size()
          # print(h, w)
          mask = F.interpolate(mask, [h,w], mode = 'nearest')

          mask = mask.repeat(1, c, 1,1)
          # print(mask.size())
          out = out*mask

        return out

class Generator(nn.Module):
    def __init__(
        self,
        size,
        style_dim,
        n_mlp,
        channel_multiplier=2,
        blur_kernel=[1, 3, 3, 1],
        lr_mlp=0.01,
    ):
        super().__init__()

        self.size = size

        self.style_dim = style_dim

        self.feature_extractor = FeatureExtractor(size)
        layers = nn.ModuleList()
        layers.append(PixelNorm())
        # layers = [PixelNorm()]

        layers.append(
            EqualLinear(
                    style_dim+3, style_dim, lr_mul=lr_mlp, activation="fused_lrelu"
                ))

        for i in range(n_mlp-1):
            layers.append(
                EqualLinear(
                    style_dim, style_dim, lr_mul=lr_mlp, activation="fused_lrelu"
                )
            )

        self.style = nn.Sequential(*layers)

        self.channels = {
            4: 512,
            8: 512,
            16: 512,
            32: 512,
            64: 256 * channel_multiplier,
            128: 128 * channel_multiplier,
            256: 64 * channel_multiplier,
            512: 32 * channel_multiplier,
            1024: 16 * channel_multiplier,
        }

        self.input = ConstantInput(self.channels[4])
        self.conv1 = StyledConv(
            self.channels[4], self.channels[4], 3, style_dim, blur_kernel=blur_kernel
        )
        self.to_rgb1 = ToRGB(self.channels[4], style_dim, upsample=False)

        self.log_size = int(math.log(size, 2))
        self.num_layers = (self.log_size - 2) * 2 + 1

        self.convs = nn.ModuleList()
        self.upsamples = nn.ModuleList()
        self.to_rgbs = nn.ModuleList()
        self.noises = nn.Module()

        in_channel = self.channels[4]

        for layer_idx in range(self.num_layers):
            res = (layer_idx + 5) // 2
            shape = [1, 1, 2 ** res, 2 ** res]
            self.noises.register_buffer(f"noise_{layer_idx}", torch.randn(*shape))

        for i in range(3, self.log_size + 1):
            out_channel = self.channels[2 ** i]

            if i%2==0:
              in_channel1 = in_channel*2
            else:
              in_channel1 = in_channel #----------------------------------------hbhjbbhjbhjbb

            self.convs.append(
                StyledConv(
                    in_channel1,
                    out_channel,
                    3,
                    style_dim,
                    upsample=True,
                    blur_kernel=blur_kernel,
                )
            )

            self.convs.append(
                StyledConv(
                    out_channel, out_channel, 3, style_dim, blur_kernel=blur_kernel
                )
            )

            self.to_rgbs.append(ToRGB(out_channel, style_dim))

            in_channel = out_channel

        self.n_latent = self.log_size * 2 - 2

    def forward(
        self,
        styles,
        mask,
        target_img,
        return_latents=False,
        inject_index=None,
        truncation=1,
        truncation_latent=None,
        input_is_latent=False,
        noise=None,
        randomize_noise=False,
    ):

        # print(styles.size())
        # print(target_img.size(), 'here is the size of the tgt')

        target_features = self.feature_extractor(target_img)#.reverse()
        # target_features.reverse()

        # print(target_features)

        if not input_is_latent:
            styles = self.style(styles) #[self.style(s) for s in styles]

        # if not input_is_latent:
        # styles = [self.style(s) for s in styles]
        # print(styles.size(), 'latent_sizeggggg')

        if noise is None:
            if randomize_noise:
                noise = [None] * self.num_layers
            else:
                noise = [
                    getattr(self.noises, f"noise_{i}") for i in range(self.num_layers)
                ]

        latent = styles.unsqueeze(1).repeat(1,self.num_layers,1)

        # print(latent.size(), 'latent_sizeggggg')

        out = self.input(latent)

        out = self.conv1(out, latent[:, 0], noise=None)

        skip = self.to_rgb1(out, latent[:, 1])

        i = 1

        for conv1, noise1 in zip(
            self.convs, noise
        ):
              if (i+1)%4==0:
                feat = target_features[i//2]
                out = torch.cat((out, feat), dim = 1)

              out = conv1(out, latent[:, i], mask = mask, noise=None)

              i+=1

        out =  self.to_rgbs[-1](out, latent[:, 0])

        return out

class ConvLayer(nn.Sequential):
    def __init__(
        self,
        in_channel,
        out_channel,
        kernel_size,
        downsample=False,
        blur_kernel=[1, 3, 3, 1],
        bias=True,
        activate=True,
    ):
        layers = nn.ModuleList()

        if downsample:
            factor = 2
            p = (len(blur_kernel) - factor) + (kernel_size - 1)
            pad0 = (p + 1) // 2
            pad1 = p // 2

            layers.append(Blur(blur_kernel, pad=(pad0, pad1)))

            stride = 2
            self.padding = 0

        else:
            stride = 1
            self.padding = kernel_size // 2

        layers.append(
            EqualConv2d(
                in_channel,
                out_channel,
                kernel_size,
                padding=self.padding,
                stride=stride,
                bias=bias and not activate,
            )
        )

        if activate:
            layers.append(FusedLeakyReLU(out_channel, bias=bias))

        super().__init__(*layers)

class ResBlock(nn.Module):
    def __init__(self, in_channel, out_channel, blur_kernel=[1, 3, 3, 1]):
        super().__init__()

        self.conv1 = ConvLayer(in_channel, in_channel, 3)
        self.conv2 = ConvLayer(in_channel, out_channel, 3, downsample=True)

        self.skip = ConvLayer(
            in_channel, out_channel, 1, downsample=True, activate=False, bias=False
        )

    def forward(self, input):
        out = self.conv1(input)
        out = self.conv2(out)

        skip = self.skip(input)
        out = (out + skip) / math.sqrt(2)

        return out

class FeatureExtractor(nn.Module):
    def __init__(self, size, channel_multiplier=2, blur_kernel=[1, 3, 3, 1]):
        super().__init__()

        channels = {
            4: 512,
            8: 512,
            16: 512,
            32: 512,
            64: 256 * channel_multiplier,
            128: 128 * channel_multiplier,
            256: 64 * channel_multiplier,
            512: 32 * channel_multiplier,
            1024: 16 * channel_multiplier,
        }

        convs = nn.ModuleList()
        convs.append(ConvLayer(3, channels[size], 1))

        log_size = int(math.log(size, 2))

        in_channel = channels[size]

        for i in range(log_size, 2, -1):
            out_channel = channels[2 ** (i - 1)]

            convs.append(ResBlock(in_channel, out_channel, blur_kernel))

            in_channel = out_channel

        self.convs = convs #nn.Sequential(*convs)

    def forward(self, out):
        out_l = nn.ModuleList()
        for cn in self.convs:
          out = cn(out)
          out_l.insert(0,out)

        return out_l #, out_l

if __name__=="__main__":
    g = Generator(256, 512, 4).to('cuda')
    o = torch.ones((3,512)).to('cuda')
    tgt = torch.ones((3, 3, 256, 256)).to('cuda')
    mask = torch.ones((3,1,256,256)).to('cuda')
    im = g(o, mask, tgt)
    print(im.size(), im.device)


class Solution:
    def cbu(self,n):
        s = 0
        while n:
            if n&1:
                s += 1
            n>>=1
        return s

    def countBits(self, n: int) -> List[int]:
        res = []
        for i in range(n+1):
            res.append(self.cbu(i))
        return res


# 10988
target = input()
if target == target[::-1]:
    print(1)
else:
    print(0)

# 2711
for _ in range(int(input())):
    target = list(map(str,input().split()))
    print(target[1][:int(target[0])-1]+target[1][int(target[0]):])

# 17249
import sys
input = sys.stdin.readline
target = input()
target_sp = target.split('(^0^)')
print(target_sp[0].count('@'),target_sp[1].count('@'))

# 2789
erase = ' '.join('CAMBRIDGE').split()
target = input()
ans = ''
for i in target:
    if i in erase:
        pass
    else:
        ans += i
print(ans)


from time import time

import numpy as np
from PyQt5.QtCore import QItemSelectionModel, Qt
from PyQt5.QtWidgets import QApplication

class OnpickEvent(object):
    def __init__(self, ax, x, y, tableview=None):
        """
        Args:
            ax: objet Axes.
            x: abscisse x1 du graphe (f(x1) = y1) à tracer.
            y: ordonnée y1 du graphe (f(x1) = y1) à tracer.
            tableview: tableau (de type QTableView) 'associé' au grahique.
        """
        self.ax = ax
        self.x = x
        self.y = y

        self.tableView = tableview
        self.counter_onclick = 0
        self.count = 0
        self.plot_selec()

        self.list_selected_points = []
        self.tableView.selectionModel().selectionChanged.connect(self.update_select_point_point)

    def select_row_pt_clicked(self, ind: int = 0):
        """
        Args:
             ind: Indice de la ligne où se trouve le point le plus proche 'visé'.
        Returns: Sélectionne la ligne (du tableau) correspondant au point le plus proche 'visé' à la suite de l'événement onpick.
        """
        if self.tableView is not None:
            selection_model = self.tableView.selectionModel()
            index = self.tableView.model().index(ind, 0)
            selection_model.select(index,
                                   QItemSelectionModel.Rows | QItemSelectionModel.ClearAndSelect |
                                   QItemSelectionModel.Select)
            # In general for all the classes that inherit from QAbstractItemView(like QTableView, QTableWidget,
            # QListView, etc) there is the scrollTo method that is used internally to scrollToItem
            self.tableView.scrollTo(index)

    def select_qtableview_row(self, event):
        if self.tableView is not None:
            self.tableView.setFocus()
            ind = self.indice_points_onpick(event)
            dataidx_ecran = self.index_pt_plus_proche_ecran(event)
            self.select_row_pt_clicked(ind[dataidx_ecran])

    def update_select_point_point(self):
        if self.tableView is not None:
            rows = list(set([index.row() for index in self.tableView.selectedIndexes()]))
            if len(rows) > 1:
                for row in rows:
                    point = self.ax.plot(self.x[row], self.y[row], '+', c='Blue', markersize=8)
                    self.list_selected_points.append(point)
                    self.update_select_point_point_bis(self.x[row], self.y[row])

            elif len(rows) == 1:
                for row in rows:  #
                    # self.select_plot.set_data(self.x[row], self.y[row]
                    # self.ax.plot(self.x[row], self.y[row],'+', c='Blue', markersize=7)
                    # print(self.pt)
                    # if len(self.pt) > 0:
                    try:
                        [pl[0].set_data([], []) for pl in self.list_selected_points if
                         len(self.list_selected_points) > 1]
                    #  [pl[0].remove() for pl in self.pt[0:-2]]

                    except:
                        print("Probleme  de mise à jour ... update_select_point_point()")
                    try:
                        self.update_select_point_point_bis(self.x[row], self.y[row])
                    except:
                        print("index introuvable pour la mise à jour de l'affichage de la sélection du point."
                              "Editer les cases en 'nan'.")

            self.ax.figure.canvas.draw_idle()

    def plot_selec(self):
        try:
            self.selected_point, = self.ax.plot(self.x[0], self.y[0], '+', c='blue', markersize=8)
            self.selected_point.set_visible(False)
        except:
            print("tableau vide pour l'instant")

    # self.ax.figure.canvas.draw_idle()

    def update_select_point_point_bis(self, x_ind, y_ind):
        # if self.tableView is not None:
        #     rows = list(set([index.row() for index in self.tableView.selectedIndexes()]))
        #     for row in rows:  #
        self.selected_point.set_data(x_ind, y_ind)  # ,'+', c='Blue', markersize=7)
        self.selected_point.set_visible(True)
        self.ax.figure.canvas.draw_idle()  # nécessaire pour la mise à jour de l'affichage

    def plot_selection_point(self, x, y):
        """
        Args:
            x: abscisse
            y: ordonnée
        Returns: sélectionne le point du graphique correspond à la ligne sélectionnée dans le tableau.
        """
        if self.tableView is not None:
            self.select_point, = self.ax.plot(x, y, '+', c='Blue', markersize=7)
        else:
            self.select_point, = self.ax.plot([], [])

    @property
    def delta_x(self):
        """"
        Returns: la longueur entre les limites de la vue sur l'axe des x, c'est-à-dire |x_max_visible - x_min_visible|.
        """
        xgauche, xdroite = self.ax.get_xlim()
        delta_x = abs(xdroite - xgauche)
        return delta_x

    @property
    def delta_y(self):
        """
        Returns: la longueur entre les limites de la vue sur l'axe des y, c'est à dire |y_max_visible - y_min_visible|.
        """
        ybas, yhaut = self.ax.get_ylim()
        delta_y = abs(yhaut - ybas)
        return delta_y

    @staticmethod
    def indice_points_onpick(event):
        """
        Args: event
        Returns: le(s) indexe(s) du/des point(s) (plus précisement les coordonnées de points) capturé(s)
                 par l'événement onpick (voir picker)
        """
        return event.ind

    def points_onpick(self, event):
        """
        Args:
            event:
        Returns: une array contenant les coordonées des points qui se trouvent dans la zone définie par l'événement
        onpick (voir picker)

        """
        thisline = event.artist
        xdata = thisline.get_xdata()
        ydata = thisline.get_ydata()
        points_onpick = np.array([(xdata[i], ydata[i]) for i in self.indice_points_onpick(event)])
        return points_onpick

    def distance_normee(self, event):
        """
        Args:
            event:
        Returns: la liste des distances normées (en m) entre les points situés dans la région définie par l'événement
         onpick (voir picker).
        """
        ind = event.ind
        thisline = event.artist
        xdata = thisline.get_xdata()
        ydata = thisline.get_ydata()
        points_onpick = np.array([(xdata[i], ydata[i]) for i in ind])
        distances_normees = [(((x - event.mouseevent.xdata) / self.delta_x) ** 2 +
                              ((y - event.mouseevent.ydata) / self.delta_y) ** 2) ** (1 / 2) for (x, y) in
                             points_onpick]
        return distances_normees

    def position_souris(self, event):
        """
        Args:
            event:
        Returns: la position de la souris
        """
        pos_souris = [(event.mouseevent.xdata, event.mouseevent.ydata)]
        return pos_souris

    def distance_ecran(self, event):
        """
        Args:
            event:
        Returns: la liste des distances 'visuelles' entre les points situés dans la région définie par l'événement
        onpick (voir picker).
        """
        # self.ax.get_window_extent() retourne la boîte de délimitation des axes dans l'espace d'affichage ; args et
        # kwargs sont vides.
        # bbox : bounding box
        bbox = self.ax.get_window_extent().transformed(self.ax.figure.dpi_scale_trans.inverted())

        # bbox = self.ax.get_window_extent().transformed(self.ax.figure.dpi_scale_trans.inverted())
        ratio_w_sur_h = bbox.width / bbox.height  # le graphique est "ratio_w_sur_h fois plus large que haut"
        distances_ecran = [(((x - event.mouseevent.xdata) / (self.delta_x * ratio_w_sur_h)) ** 2 +
                            ((y - event.mouseevent.ydata) / self.delta_y) ** 2) ** (1 / 2) for (x, y) in
                           self.points_onpick(event)]
        return distances_ecran

    def distances(self, event):
        """
        Args: event:
        Returns: la liste des distances entre la position de la souris et tous les points se trouvant dans
        la zone définie par l'événement onpick ( voir picker)
        """
        distances = np.linalg.norm(self.points_onpick(event) - self.position_souris(event), axis=1)
        return distances

    def index_pt_plus_proche_ecran(self, event):
        """
         Args:
             event:
         Returns: indice du point le plus proche visuellement de la position du click.
         """
        dataidx_ecran = np.argmin(self.distance_ecran(event))
        return dataidx_ecran

    def point_plus_proche_ecran(self, event):
        point_onpick = self.points_onpick(event)
        datapos_ecran = point_onpick[self.index_pt_plus_proche_ecran(event)]
        return self.points_onpick(event)[self.index_pt_plus_proche_ecran(event)]  # datapos_ecran

    def index_pt_plus_proche(self, event):
        """
        Args:
            event:
        Returns: indice du point le plus proche de la position du click.
        """
        dataidx = np.argmin(self.distances(event))
        return dataidx

    def point_plus_proche(self, event):
        """
        Args:
            event:
        Returns: point le plus proche de la position du click
        """
        point_onpick = self.points_onpick(event)
        datapos = point_onpick[self.index_pt_plus_proche(event)]
        return datapos

    def annotate_onpick(self, x, y):
        """
        Args:
            x: abscisse du point à annoter.
            y: ordonnée du point à annoter.
        Returns: annote le point xy avec du texte text = xytext.
        """
        annotate_onpick = self.ax.annotate("X", xytext=(x, y),
                                           xy=(x, y), fontsize=9,
                                           bbox=dict(boxstyle='round,pad=0.8', fc='yellow', alpha=0.75),
                                           arrowprops=dict(arrowstyle='->',
                                                           connectionstyle='arc3,rad=0.',
                                                           color='blue'))
        return annotate_onpick

    def on_ylims_change(self, event_ax):
        print("updated ylims: ", event_ax.get_ylim())
        return event_ax.get_ylim()

    def onpick(self, event):
        modifiers = QApplication.keyboardModifiers()

        if modifiers == Qt.ControlModifier:
            start = time()
            print("******************************************")
            print("Onpick, nb points :", len(self.x))
            if event.mouseevent.inaxes == self.ax:
                # if event.mouseevent.xdata :# is not None and event.mouseevent.ydata is not None:
                self.select_qtableview_row(event)
                # self.update_select_point_point_bis(event.mouseevent.xdata, event.mouseevent.ydata)
                x_proche, y_proche = self.point_plus_proche_ecran(event)
                self.update_select_point_point_bis(x_proche, y_proche)
                # self.ax.figure.canvas.draw_idle()

            end = time()
            duree = end - start
            print("temps écoulé : ", duree)
            self.ax.figure.canvas.draw_idle()


#!/usr/bin/env python3
def m2w(nnnnnn):
    n=tuple(nnnnnn)
    r=n[::-1]
    if len(n)<4:return n2w(nnnnnn)
    else:
        centenas=n2w('{}{}{}'.format(r[2],r[1],r[0]))
        if len(n)==4:millares=n2w('{}'.format(r[3]))
        elif len(n)==5:millares=n2w('{}{}'.format(r[4],r[3]))
        else:millares=n2w('{}{}{}'.format(r[5],r[4],r[3]))
        if r[2]=='0':add=' and '
        else:add=' '
        return '{} thousand{}{}'.format(millares,add,centenas)
def n2w(nnn):
    n=tuple(nnn)
    if len(n)==1:c='0';d='0';u=n[0]
    elif len(n)==2:c='0';d=n[0];u=n[1]
    else:c=n[0];d=n[1];u=n[2]
    ones=(None,'one','two','three','four','five','six','seven','eight','nine')
    tens=(None,'ten','twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety')
    teen=(None,'eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen')
    if d=='0':decenas=ones[int(u)]
    elif u=='0':decenas=tens[int(d)]
    elif d=='1':decenas=teen[int(u)]
    else:decenas='{}-{}'.format(tens[int(d)],ones[int(u)])
    if c=='0':return decenas
    else:return '{} hundred and {}'.format(ones[int(c)],decenas)
class t2w:
    def __init__(self,time):
        _t=time.split(':');self._hour=_t[0];self._minute=_t[1]
    def hour(self):return self._hour
    def minute(self):return self._minute
    def h2w(self):
        _H=self.hour();_h=int(_H)
        if int(self.minute())<=30:
            if _h==0:return 'midnight'
            elif _h==12:return 'noon'
            else:return n2w(_H)
        else:
            if _h==23:return 'midnight'
            elif _h==11:return 'noon'
            else:return n2w(str(1+_h))
    def m2w(self):
        _M=self.minute();_m=int(_M)
        if _m==0:return "o'clock"
        elif _m==30:return 'half past'
        elif _m==15:return 'quarter past'
        elif _m==45:return 'quarter to'
        elif _m<30:return '{} past'.format(n2w(_M))
        else:return '{} to'.format(n2w(str(60-_m)))
    def __str__(self):
        if self.minute()=='00':return '{} {}'.format(self.h2w(),self.m2w())
        else:return '{} {}'.format(self.m2w(),self.h2w())


from utils.config import *
from models.GraphDialog import *
import tensorflow as tf
import pdb
import os

os.environ['CUDA_VISIBLE_DEVICES'] = "-1"
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)

'''
Command:

python myTest.py -ds= -path=

'''

directory = args['path'].split("/")
task = directory[2].split('HDD')[0]
HDD = directory[2].split('HDD')[1].split('BSZ')[0]
L = directory[2].split('L')[1].split('lr')[0].split("-")[0]
decoder = directory[1].split('-')[0]
BSZ = int(directory[2].split('BSZ')[1].split('DR')[0])
DS = 'multiwoz' if 'multiwoz' in directory[1].split('-')[1].lower() else 'kvr'

early_stop = args['earlyStop']
if DS=='kvr':
	from utils.utils_tensorflow_Ent_knowledge_graph import *
elif DS=='multiwoz':
	from utils.utils_tensorflow_Ent_multiwoz_knowledge_graph import *
else:
    print("You need to provide the --dataset information")

train, dev, test, testOOV, lang, max_resp_len, train_length, dev_length, test_length = prepare_data_seq(task, batch_size=BSZ)

model = GraphDialog(int(HDD),
			 lang,
			 max_resp_len,
			 args['path'],
			 "",
			 lr=0.0,
			 n_layers=int(L),
			 graph_hidden_size=int(args['graphhdd']),
			 nheads=int(args['nheads']),
			 alpha=float(args['alpha']),
			 dropout=0.0,
			 graph_dr=float(args['graph_dr']),
		     n_graph_layers=int(args['graph_layer']))

# len = int(test_length / int(BSZ))
test_length_ = compute_dataset_length(test_length, int(BSZ))
acc_test = model.evaluate(test, test_length_, 1e7)
if testOOV!=[]:
    acc_oov_test = model.evaluate(testOOV, 1e7)


"""IMPORT PACKAGES"""
import os
import json
import numpy as np
import pandas as pd
from skimage.measure import label
from scipy import ndimage
from PIL import Image
from numba import jit
import shutil

"""SPECIFY EXTENSIONS AND DATA ROOTS"""
EXT_VID = ['.mp4', '.m4v',  '.avi']
EXT_IMG = ['.jpg', '.png', '.tiff', '.tif', '.bmp', '.jpeg']

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"""DEFINE SET OF FUNCTIONS FOR SELECTING ROI IN RAW ENDOSCOPE IMAGES"""
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

# Define function for minimum pooling the images
@jit(nopython=True)
def min_pooling(img, g=8):

    # Copy Image
    out = img.copy()

    # Determine image shape and compute step size for pooling
    h, w = img.shape
    nh = int(h / g)
    nw = int(w / g)

    # Perform minimum pooling
    for y in range(nh):
        for x in range(nw):
            out[g * y:g * (y + 1), g * x:g * (x + 1)] = np.min(out[g * y:g * (y + 1), g * x:g * (x + 1)])

    return out

# Define function for finding largest connected region in images
def getlargestcc(segmentation):

    # Use built-in label method, to label connected regions of an integer array
    labels = label(segmentation)

    # Assume at least 1 CC
    assert (labels.max() != 0)  # assume at least 1 CC

    # Find the largest of connected regions, return as True and False
    largestcc = labels == np.argmax(np.bincount(labels.flat)[1:]) + 1

    return largestcc

# Define function for finding bounding box coordinates for ROI in images
def bbox(img):

    # Find rows and columns where a True Bool is encountered
    rows = np.any(img, axis=1)
    cols = np.any(img, axis=0)

    # Find the first and last row/column for the bounding box coordinates
    # cmin = left border, cmax = right border, rmin = top border, rmax = bottom border
    # Usage Image.crop((left, top, right, bottom))
    rmin, rmax = np.where(rows)[0][[0, -1]]
    cmin, cmax = np.where(cols)[0][[0, -1]]

    return rmin, rmax, cmin, cmax

# Define Complete function for finding ROI bounding box coordinates, by combining previous functions
def find_roi(img):

    # Open image as numpy array
    image = np.array(img, dtype=np.uint8)

    # Compute L1 norm of the image
    norm_org = np.linalg.norm(image, axis=-1)

    # Use Gaussian Filter to capture low-frequency information
    img_gauss = ndimage.gaussian_filter(norm_org, sigma=5)

    # Scale pixel values
    img_scaled = ((norm_org - np.min(img_gauss)) / (np.max(img_gauss) - np.min(img_gauss))) * 255

    # Use minimum pooling
    img_norm = min_pooling(img_scaled, g=8)

    # Find largest connected region with threshold image as input
    th = 10
    largestcc = getlargestcc(img_norm >= th)

    # Obtain cropping coordinates
    rmin, rmax, cmin, cmax = bbox(largestcc)

    return rmin, rmax, cmin, cmax

# Define a function for finding which expert readers to ignore when > 4 delineations are available
def find_ignore_readers(path):

    # Find targets
    maskdict = dict()
    for root, dirs, files in os.walk(path):

        # Loop over filenames in files
        for file in files:

            # Extract filename before .ext
            maskcase = os.path.splitext(file)[0]

            # Append filename to mask dictionary if already existing key; otherwise create key and append to list
            if maskcase in maskdict.keys():
                maskdict[maskcase].append(os.path.join(root, file))
            else:
                maskdict[maskcase] = list()
                maskdict[maskcase].append(os.path.join(root, file))

    target_list = list()
    for key in maskdict:
        if len(maskdict[key]) > 4:
            target_list.append(key)

    # Instantiate list
    folders_oi = dict()

    # Loop over all folders
    for roots, dirs, files in os.walk(path):
        # Loop over roots
        for dir in dirs:
            # Loop over target list
            for i in range(len(target_list)):
                # Find target list variables
                if target_list[i] == dir:
                    if os.path.exists(os.path.join(roots, dir, 'Higherlikelihood')) and os.path.exists(os.path.join(roots, dir, 'Lowerlikelihood')):
                        folders_oi[target_list[i]] = [os.path.join(roots, dir, 'Higherlikelihood'), os.path.join(roots, dir, 'Lowerlikelihood')]

    # Loop over targets and corresponding folders of interest
    for target in folders_oi:

        # Find HL delineations
        for roots, dirs, files in os.walk(folders_oi[target][0]):
            for file in files:
                if 'Expert_0' in os.path.join(roots, file):
                    exp0 = np.array(Image.open(os.path.join(roots, file)).convert('1'))*1
                    print('\nExpert 0: {}'.format(os.path.join(roots, file)))
                elif 'Expert_1' in os.path.join(roots, file):
                    exp1 = np.array(Image.open(os.path.join(roots, file)).convert('1'))*1
                    print('Expert 1: {}'.format(os.path.join(roots, file)))
                elif 'Expert_2' in os.path.join(roots, file):
                    exp2 = np.array(Image.open(os.path.join(roots, file)).convert('1'))*1
                    print('Expert 2: {}'.format(os.path.join(roots, file)))
                else:
                    raise Exception('No predefined expert found...')

        # Compute dice score for the combinations
        intersection01 = np.sum(np.multiply(exp0, exp1)) * 2.0
        intersection02 = np.sum(np.multiply(exp0, exp2)) * 2.0
        intersection12 = np.sum(np.multiply(exp1, exp2)) * 2.0
        dice01 = (intersection01 + 1e-7) / (np.sum(exp0) + np.sum(exp1) + 1e-7)
        dice02 = (intersection02 + 1e-7) / (np.sum(exp0) + np.sum(exp2) + 1e-7)
        dice12 = (intersection12 + 1e-7) / (np.sum(exp1) + np.sum(exp2) + 1e-7)

        print('file: {}, dice01: {:.4f}, dice02: {:.4f}, dice12: {:.4f}'.
              format(os.path.split(os.path.join(roots, file))[1], dice01, dice02, dice12))

        # Compute the highest dice score and delete folders
        if (dice01 >= dice02) and (dice01>= dice12):
            largest = dice01
            string = 'Highest Similarity between Expert 0 and Expert 1, Delete Expert 2'
            delete = 'Expert_2'
        elif (dice02 >= dice01) and (dice02 >= dice12):
            largest = dice02
            string = 'Highest Similarity between Expert 0 and Expert 2, Delete Expert 1'
            delete = 'Expert_1'
        else:
            largest = dice12
            string = 'Highest Similarity between Expert 1 and Expert 2, Delete Expert 0'
            delete = 'Expert_0'
        print(string)

        # Delete corresponding folders for Higher and Lower likelihoods
        if os.path.exists(os.path.join(folders_oi[target][0], delete)):
            shutil.rmtree(os.path.join(folders_oi[target][0], delete))
        if os.path.exists(os.path.join(folders_oi[target][1], delete)):
            shutil.rmtree(os.path.join(folders_oi[target][1], delete))

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"""DEFINE FUNCTION FOR CREATING CACHE WITH METADATA FOR AVAILABLE IMAGES"""
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

def cache_wle(root_dir, mask_dir, subtlety_dir, quality_dir, storing_folder):

    # Create directory
    print('Generating cache...')
    os.makedirs(os.path.join(os.getcwd(), '..', storing_folder))

    # Create empty dictionary for  image files
    img_files = list()

    # Loop over roots (folders in root_dir), dirs (folders in roots), files (files in dirs)
    for root, dirs, files in os.walk(root_dir):

        # Loop over filenames in files
        for name in files:

            # Check for .extension of the files; append to video files or image files accordingly
            # os.path.splitext splits name in filename and .ext; [1] will correspond to .ext
            if os.path.splitext(name.lower())[1] in EXT_IMG:
                img_files.append(os.path.join(root, name))
            elif name == 'Thumbs.db':
                os.remove(os.path.join(root, name))
            else:
                print('FILE NOT SUPPORTED: {}'.format(os.path.join(root, name)))

    # Create empty dictionary for image files
    maskdict = dict()

    # Loop over roots (folders in OTMASKDIR), dirs (folders in roots), files (files in dirs)
    for root, dirs, files in os.walk(mask_dir):
        if 1:  # 'Lowerlikelihood' in root:

            # Loop over filenames in files
            for file in files:

                # Extract filename before .ext
                maskcase = os.path.splitext(file)[0]

                # Append filename to mask dictionary if already existing key; otherwise create key and append to list
                if maskcase in maskdict.keys():
                    maskdict[maskcase].append(os.path.join(root, file))
                else:
                    maskdict[maskcase] = list()
                    maskdict[maskcase].append(os.path.join(root, file))

    # Read Subtlety database as excel file; Create empty dictionary for subtlety
    subtlety_df = pd.read_excel(subtlety_dir)
    subtlety_dict = dict()

    # Iterate over rows in excel file; initialize img name key in subtlety dict, set value based on subtlety
    for idx, frame in subtlety_df.iterrows():
        subtlety_dict[os.path.splitext(frame['Imagename'])[0]] = frame['Subtlety (0=easy, 1=medium, 2=hard)']

    # Read Quality database as excel file; Create empty dictionary for quality
    quality_df = pd.read_excel(quality_dir)
    quality_dict = dict()

    # Iterate over rows in excel file; initialize img name key in quality dict, set value based on quality
    # It can happen that multiple same key occurs multiple times in the dict
    for idx, frame in quality_df.iterrows():
        if not os.path.splitext(frame['Imagename'])[0] in quality_dict.keys():
            quality_dict[os.path.splitext(frame['Imagename'])[0]] = list()
            quality_dict[os.path.splitext(frame['Imagename'])[0]].append(frame['Quality'])
        elif os.path.splitext(frame['Imagename'])[0] in quality_dict.keys():
            quality_dict[os.path.splitext(frame['Imagename'])[0]].append(frame['Quality'])

    """"""""""""""""""""""""""""""""""""""
    """CREATE JSON FILE FOR EVERY IMAGE """
    """"""""""""""""""""""""""""""""""""""

    # Loop over list of img_files, which was created by appending the roots of all images in root_dir
    for img in img_files:
        print('Reading image: ', img)

        # Extract imagename from the path to image (img)
        imgname = os.path.split(img)[1]

        # Create empty dictionary for metadata
        data = dict()

        # Extract information from filename and place in dictionary with corresponding key
        data['patient'] = '_'.join(os.path.split(img)[1].split('_')[:2])  # hospital_patID
        data['file'] = img  # path to file
        data['dataset'] = os.path.split(os.path.split(os.path.split(os.path.split(os.path.split(img)[0])[0])[0])[0])[1]  # training/validatie
        data['source'] = os.path.split(os.path.split(img)[0])[1]  # image/frames
        data['class'] = os.path.split(os.path.split(os.path.split(img)[0])[0])[1]  # ndbe/neo
        data['protocol'] = os.path.split(os.path.split(os.path.split(os.path.split(img)[0])[0])[0])[1]
        data['modality'] = os.path.split(img)[1].split('_')[2]  # modality
        data['clinic'] = os.path.split(img)[1].split('_')[0]  # hospital
        data['subtlety'] = subtlety_dict[os.path.splitext(os.path.split(img)[1])[0]] if \
                           os.path.splitext(os.path.split(img)[1])[0] in subtlety_dict.keys() else 0
        if 'subtle' in img:
            data['subtlety'] = 2
        data['quality'] = quality_dict[os.path.splitext(os.path.split(img)[1])[0]] if \
                          os.path.splitext(os.path.split(img)[1])[0] in quality_dict.keys() else []

        # Open the image as numpy array; extract height and width and place in data dictionary
        frame = np.array(Image.open(img))
        data['height'] = frame.shape[0]
        data['width'] = frame.shape[1]
        print('Frame shape: ', frame.shape)

        # Extract bounding box coordinates, store in dictionary as rmin, rmax, cmin, cmax
        roi = find_roi(frame)
        data['roi'] = [float(x) for x in roi]

        # Create new key in data dictionary for masks and initialize as list; instantiate with maskdict list
        data['masks'] = list()
        if os.path.splitext(os.path.split(img)[1])[0] in maskdict.keys():
            data['masks'] = maskdict[os.path.splitext(os.path.split(img)[1])[0]]
        print('Number of masks: {}'.format(len(data['masks'])))

        # Print final version of data dictionary with all keys and values in there
        print('Data: ', data)

        # Check whether there is already a json file for this particular image; otherwise create file
        if not os.path.exists(os.path.join(os.getcwd(), '..', storing_folder, os.path.splitext(imgname)[0] + '.json')):
            jsonfile = os.path.join(os.getcwd(), '..', storing_folder, os.path.splitext(imgname)[0] + '.json')
        elif not os.path.exists(os.path.join(os.getcwd(), '..', storing_folder, os.path.splitext(imgname)[0] + '_2.json')):
            jsonfile = os.path.join(os.getcwd(), '..', storing_folder, os.path.splitext(imgname)[0] + '_2.json')
        elif not os.path.exists(os.path.join(os.getcwd(), '..', storing_folder, os.path.splitext(imgname)[0] + '_3.json')):
            jsonfile = os.path.join(os.getcwd(), '..', storing_folder, os.path.splitext(imgname)[0] + '_3.json')
        else:
            raise ValueError

        # For every img in img_files write dictionary data into corresponding json file
        with open(jsonfile, 'w') as outfile:
            json.dump(data, outfile, indent=4)

""""""""""""""""""""""""""
"""EXECUTION OF FUNCTIONS"""
""""""""""""""""""""""""""
if __name__ == '__main__':

    # Define paths to the folders for WLE (Images, Masks, Subtlety, Quality)
    wle_dir = ''
    wle_mask_dir_plausible = ''
    wle_mask_dir = ''
    wle_subtle_dir = ''
    wle_quality_dir = ''

    # Define storing folders for NBI and WL
    wle_plausible_store = 'cache'

    # Execute functions
    cache_wle(root_dir=wle_dir, mask_dir=wle_mask_dir_plausible, subtlety_dir=wle_subtle_dir,
              quality_dir=wle_quality_dir, storing_folder=wle_plausible_store)


# coding: utf-8

from __future__ import absolute_import

from flask import json
from six import BytesIO

from swagger_server.models.matter_properties import MatterProperties  # noqa: E501
from swagger_server.models.matter_response import MatterResponse  # noqa: E501
from swagger_server.test import BaseTestCase

class TestFSMController(BaseTestCase):
    """FSMController integration test stubs"""

    def test_add_matter(self):
        """Test case for add_matter

        Add a new State Machine to the pool
        """
        body = MatterProperties()
        response = self.client.open(
            '/v1/matter',
            method='POST',
            data=json.dumps(body),
            content_type='application/json')
        self.assert200(response,
                       'Response body is : ' + response.data.decode('utf-8'))

    def test_get_by_id(self):
        """Test case for get_by_id

        Info for a specific Matter object
        """
        response = self.client.open(
            '/v1/matter/{Id}'.format(id=1.2),
            method='GET')
        self.assert200(response,
                       'Response body is : ' + response.data.decode('utf-8'))

if __name__ == '__main__':
    import unittest
    unittest.main()


from django.conf.urls import url
from longclaw.basket import api
from longclaw.basket import views
from longclaw.settings import API_URL_PREFIX

basket_list = api.BasketViewSet.as_view({
    'get': 'list',
    'post': 'create',
    'put': 'bulk_update'
})

basket_detail = api.BasketViewSet.as_view({
    'delete': 'destroy'
})

item_count = api.BasketViewSet.as_view({
    'get': 'item_count'
})

total_items = api.BasketViewSet.as_view({
    'get': 'total_items'
})

urlpatterns = [

    url(API_URL_PREFIX + r'basket/$',
        basket_list,
        name='longclaw_basket_list'),
    url(API_URL_PREFIX + r'basket/count/$',
        total_items,
        name="longclaw_basket_total_items"),
    url(API_URL_PREFIX + r'basket/(?P<variant_id>[0-9]+)/$',
        basket_detail,
        name='longclaw_basket_detail'),
    url(API_URL_PREFIX + r'basket/(?P<variant_id>[0-9]+)/count/$',
        item_count,
        name='longclaw_basket_item_count'),

    url(r'basket/$',
        views.BasketView.as_view(),
        name="longclaw_basket")
]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 12 10:01:20 2017

@author: viche
"""

# Data Preprocessing
# Structure the folders for the pictures - readable by by Keras library.
# Folder structure: parent -> training_set & test_set -> individual categories

# ---------------------------------
# Build the CNN model --- starts ---

# Import the Keras libraries and packages
import keras
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.preprocessing.image import ImageDataGenerator

# Initialize the CNN
classifier = Sequential()

# Add Layer - Convolution
# convo: 32=number of filters, 3*3 pixel grid filter
# input_shape: 3=color pic; 256*256 pixels
classifier.add(Convolution2D(32,kernel_size=(3,3),input_shape=(64,64,3),activation='relu'))

# Add Layer - Max Pooling
# pool size: 2*2 pixel grid
classifier.add(MaxPooling2D(pool_size=(2,2)))

# Add Layer - Convolution - 2nd
# convo: 32=number of filters, 3*3 pixel grid filter
# input_shape: 3=color pic; 256*256 pixels
classifier.add(Convolution2D(32,kernel_size=(3,3),activation='relu'))

# Add Layer - Max Pooling - 2nd
# pool size: 2*2 pixel grid
classifier.add(MaxPooling2D(pool_size=(2,2)))

# Add Layer - Flattern
classifier.add(Flatten())

# Add Layer - Full Connected
# Hidden Layer
classifier.add(Dense(128, activation='relu'))
# Output Layer
classifier.add(Dense(1, activation='sigmoid'))

# Compile the model
classifier.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])

train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory('cnn_dataset/training_set',
        target_size=(64, 64),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory('cnn_dataset/test_set',
                    target_size=(64, 64),
                    batch_size=32,
                    class_mode='binary')

classifier.fit_generator(train_generator,
                        steps_per_epoch=8000,
                        epochs=25,
                        validation_data=validation_generator,
                        validation_steps=2000)


"""6-6. Polling
Combining list and dictionary"""

#code from the book (the exercise asks you to use it)
favorite_languages = {
    "jen": "python",
    "sarah": "c",
    "edward": "ruby",
    "phil": "python",
    }

#list of people who should take a favorite languages poll.
should_poll = ["jen", "ken", "edward", "carl"]

#loop
for name in should_poll:
    if name in favorite_languages:
        print("Thank you, " + name.title() + ", for taking the poll.")
    else:
        print(name.title() + ", you should take the poll!")


from selenium.webdriver.common.by import By

from .base_element import BaseElement

class PageWithOpens(object):
    url = None

    def __init__(self, driver, automation_nr):
        self.driver = driver
        self.url ="https://thethirdwave.activehosted.com/report/#/campaign/" + str(automation_nr) + "/opens"

    def go(self):
        self.driver.get(self.url)

    @property
    def prop_total_number(self):
        locator = (By.CSS_SELECTOR, '#open_total_t')
        return BaseElement(
            driver = self.driver,
            by = locator[0],
            value = locator[1])

    @property
    def prop_unique_opens(self):
        locator = (By.CSS_SELECTOR, '#open_unique_t')
        return BaseElement(
            driver = self.driver,
            by = locator[0],
            value = locator[1])


from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval

__all__ = ['Production']

class Production(metaclass=PoolMeta):
    __name__ = 'production'

    origin = fields.Reference('Origin', selection='get_origin',
        states={
            'readonly': ~Eval('state').in_(['request', 'draft']),
            },
        depends=['state'])

    @classmethod
    def _get_origin(cls):
        'Return list of Model names for origin Reference'
        return []

    @classmethod
    def get_origin(cls):
        pool = Pool()
        Model = pool.get('ir.model')
        models = cls._get_origin()
        models = Model.search([
                ('model', 'in', models),
                ])
        return [('', '')] + [(m.model, m.name) for m in models]


"""

A* grid planning

author: Atsushi Sakai(@Atsushi_twi)
        Nikos Kanargias (nkana@tee.gr)

See Wikipedia article (https://en.wikipedia.org/wiki/A*_search_algorithm)

"""

import math

import matplotlib.pyplot as plt

show_animation = True

class AStarPlanner:

    # def __init__(self, ox, oy, resolution, rr):
    #     """
    #     Initialize grid map for a star planning

    #     ox: x position list of Obstacles [m]
    #     oy: y position list of Obstacles [m]
    #     resolution: grid resolution [m]
    #     rr: robot radius[m]
    #     """

    #     self.resolution = resolution
    #     self.rr = rr
    #     self.min_x, self.min_y = 0, 0
    #     self.max_x, self.max_y = 0, 0
    #     self.obstacle_map = None
    #     self.x_width, self.y_width = 0, 0
    #     self.motion = self.get_motion_model()
    #     self.calc_obstacle_map(ox, oy)

    def __init__(self, ox, oy, resolution, rr = None, min_x = None, min_y = None, max_x = None, max_y = None, list_x = None, list_y = None, list_z = None):
        """
        Initialize grid map for a star planning

        Args:
            ox: x position list of Obstacles [m]
            oy: y position list of Obstacles [m]
            resolution: grid resolution [m]
            rr (optional): robot radius[m]. If an obstacle is within robot radius of a cell, the robot cannot go through this cell. If None, only the cell containing the obstacle is set as obstacle cell. Defaults to None.
            min_x : Minimum x value in the map [m]
            min_y : Minimum y value in the map [m]
            max_x : Maximum x value in the map [m]
            max_y : Maximum y value in the map [m]
            list_x: x position list for height values [m]
            list_y: y position list for height values [m]
            list_z: z height list for height values [m]
        """
        # if rr is specified, use calc_obstacle_map to build the map. Time consuming.
        if rr is not None:
            self.resolution = resolution
            self.rr = rr
            self.min_x, self.min_y = 0, 0
            self.max_x, self.max_y = 0, 0
            self.obstacle_map = None
            self.x_width, self.y_width = 0, 0
            self.motion = self.get_motion_model()
            self.calc_obstacle_map(ox, oy)
        else:
            self.resolution = resolution
            self.rr = rr
            self.min_x, self.min_y = min_x, min_y
            self.max_x, self.max_y = max_x, max_y

            print("min_x:", self.min_x)
            print("min_y:", self.min_y)
            print("max_x:", self.max_x)
            print("max_y:", self.max_y)
            self.obstacle_map = None
            # self.x_width, self.y_width = 0, 0
            self.motion = self.get_motion_model()
            self.x_width = round((self.max_x - self.min_x) / self.resolution) + 1
            self.y_width = round((self.max_y - self.min_y) / self.resolution) + 1
            print("resolution:", self.resolution)
            print("x_width:", self.x_width)
            print("y_width:", self.y_width)

            # obstacle map generation
            self.obstacle_map = [[False for _ in range(self.y_width)]
                                    for _ in range(self.x_width)]
            # print(len(self.obstacle_map))
            # print(len(self.obstacle_map[0]))

            for iox, ioy in zip(ox, oy):
                # print(self.calc_xy_index(iox, self.min_x))
                # print(self.calc_xy_index(ioy, self.min_y))
                self.obstacle_map[self.calc_xy_index(iox, self.min_x)][self.calc_xy_index(ioy, self.min_y)] = True

        # height
        self.height = [[0 for _ in range(self.y_width)]
                                for _ in range(self.x_width)]
        if list_z is not None:
            for ix, iy, iz in zip(list_x, list_y, list_z):
            # print(self.calc_xy_index(iox, self.min_x))
            # print(self.calc_xy_index(ioy, self.min_y))
                self.height[self.calc_xy_index(ix, self.min_x)][self.calc_xy_index(iy, self.min_y)] = iz

    class Node:
        def __init__(self, x, y, cost, parent_index):
            self.x = x  # index of grid
            self.y = y  # index of grid
            self.cost = cost
            self.parent_index = parent_index

        def __str__(self):
            return str(self.x) + "," + str(self.y) + "," + str(
                self.cost) + "," + str(self.parent_index)

    def is_in_obstacle_cell(self, x, y):
        # ind_x = self.calc_xy_index(x, self.min_x)
        # ind_x = self.calc_xy_index(x, self.min_y)
        return self.obstacle_map[self.calc_xy_index(x, self.min_x)][self.calc_xy_index(y, self.min_y)]

    def reset(self, ox_reset, oy_reset):
        """
        Reset some cells as non-obstacle

        Args:
            ox_reset (list of float): the list of x position to be reset
            oy_reset (list of float): the list of x position to be reset
        """
        for x,y in zip(ox_reset, oy_reset):
            self.obstacle_map[self.calc_xy_index(x, self.min_x)][self.calc_xy_index(y, self.min_y)] = False

    def planning(self, sx, sy, gx, gy):
        """
        A star path search

        input:
            s_x: start x position [m]
            s_y: start y position [m]
            gx: goal x position [m]
            gy: goal y position [m]

        output:
            rx: x position list of the final path
            ry: y position list of the final path
            path_length: the length of the final path
            3D_path_length: the 3D length of the final path
        """

        start_node = self.Node(self.calc_xy_index(sx, self.min_x),
                               self.calc_xy_index(sy, self.min_y), 0.0, -1)
        goal_node = self.Node(self.calc_xy_index(gx, self.min_x),
                              self.calc_xy_index(gy, self.min_y), 0.0, -1)

        open_set, closed_set = dict(), dict()
        open_set[self.calc_grid_index(start_node)] = start_node

        while 1:
            if len(open_set) == 0:
                # print("Open set is empty..")
                break

            c_id = min(
                open_set,
                key=lambda o: open_set[o].cost + self.calc_heuristic(goal_node,
                                                                     open_set[
                                                                         o]))
            current = open_set[c_id]

            # show graph
            if show_animation:  # pragma: no cover
                plt.plot(self.calc_grid_position(current.x, self.min_x),
                         self.calc_grid_position(current.y, self.min_y), "xc")
                # for stopping simulation with the esc key.
                plt.gcf().canvas.mpl_connect('key_release_event',
                                             lambda event: [exit(
                                                 0) if event.key == 'escape' else None])
                if len(closed_set.keys()) % 10 == 0:
                    plt.pause(0.001)

            if current.x == goal_node.x and current.y == goal_node.y:
                # print("Find goal")
                goal_node.parent_index = current.parent_index
                goal_node.cost = current.cost
                break

            # Remove the item from the open set
            del open_set[c_id]

            # Add it to the closed set
            closed_set[c_id] = current

            # expand_grid search grid based on motion model
            for i, _ in enumerate(self.motion):
                node = self.Node(current.x + self.motion[i][0],
                                 current.y + self.motion[i][1],
                                 current.cost + self.motion[i][2], c_id)
                n_id = self.calc_grid_index(node)

                # If the node is not safe, do nothing
                if not self.verify_node(node):
                    continue

                if n_id in closed_set:
                    continue

                if n_id not in open_set:
                    open_set[n_id] = node  # discovered a new node
                else:
                    if open_set[n_id].cost > node.cost:
                        # This path is the best until now. record it
                        open_set[n_id] = node

        rx, ry = self.calc_final_path(goal_node, closed_set)
        cost_2D = goal_node.cost * self.resolution
        cost_3D = self.calc_final_path_3D_cost(goal_node, closed_set)
        return rx, ry, cost_2D, cost_3D

    def calc_final_path(self, goal_node, closed_set):
        # generate final course
        rx, ry = [self.calc_grid_position(goal_node.x, self.min_x)], [
            self.calc_grid_position(goal_node.y, self.min_y)]
        parent_index = goal_node.parent_index
        while parent_index != -1:
            n = closed_set[parent_index]
            rx.append(self.calc_grid_position(n.x, self.min_x))
            ry.append(self.calc_grid_position(n.y, self.min_y))
            parent_index = n.parent_index

        return rx, ry

    def get_height_grid_index(self, ind_x, ind_y):
        return self.height[ind_x][ind_y]

    # def get_3D_distance_two_nodes():

    def calc_final_path_3D_cost(self, goal_node, closed_set):
        cost_3D = 0.0
        pre_n = goal_node

        parent_index = goal_node.parent_index
        while parent_index != -1:
            n = closed_set[parent_index]
            horizontal_cost = math.sqrt(math.pow(pre_n.x - n.x,2) + math.pow(pre_n.y - n.y,2)) * self.resolution
            vertical_cost = self.get_height_grid_index(pre_n.x, pre_n.y) - self.get_height_grid_index(n.x, n.y)
            cost_3D += math.sqrt(math.pow(horizontal_cost, 2) + math.pow(vertical_cost, 2))
            parent_index = n.parent_index
            pre_n = n
        return cost_3D

    @staticmethod
    def calc_heuristic(n1, n2):
        w = 1.0  # weight of heuristic
        d = w * math.hypot(n1.x - n2.x, n1.y - n2.y)
        return d

    def calc_grid_position(self, index, min_position):
        """
        calc grid position

        :param index:
        :param min_position:
        :return:
        """
        pos = index * self.resolution + min_position
        return pos

    def calc_xy_index(self, position, min_pos):
        return round((position - min_pos) / self.resolution)

    def calc_grid_index(self, node):
        # return (node.y - self.min_y) * self.x_width + (node.x - self.min_x)
        return node.y * self.x_width + node.x

    def verify_node(self, node):
        px = self.calc_grid_position(node.x, self.min_x)
        py = self.calc_grid_position(node.y, self.min_y)
        # print("px, py:{}, {}".format(px, py))

        if px < self.min_x:
            return False
        elif py < self.min_y:
            return False
        elif px >= self.max_x:
            return False
        elif py >= self.max_y:
            return False

        # collision check
        if self.obstacle_map[node.x][node.y]:
            return False
        # print("Verify node success")
        return True

    def verify_xy(self, px, py):
        if px < self.min_x:
            return False
        elif py < self.min_y:
            return False
        elif px >= self.max_x:
            return False
        elif py >= self.max_y:
            return False
        return True

    def calc_obstacle_map(self, ox, oy):

        self.min_x = round(min(ox))
        self.min_y = round(min(oy))
        self.max_x = round(max(ox))
        self.max_y = round(max(oy))
        print("min_x:", self.min_x)
        print("min_y:", self.min_y)
        print("max_x:", self.max_x)
        print("max_y:", self.max_y)

        self.x_width = round((self.max_x - self.min_x) / self.resolution)
        self.y_width = round((self.max_y - self.min_y) / self.resolution)
        print("x_width:", self.x_width)
        print("y_width:", self.y_width)

        # obstacle map generation
        self.obstacle_map = [[False for _ in range(self.y_width)]
                             for _ in range(self.x_width)]
        for ix in range(self.x_width):
            x = self.calc_grid_position(ix, self.min_x)
            for iy in range(self.y_width):
                y = self.calc_grid_position(iy, self.min_y)
                for iox, ioy in zip(ox, oy):
                    d = math.hypot(iox - x, ioy - y)
                    if d <= self.rr:
                        self.obstacle_map[ix][iy] = True
                        break

    @staticmethod
    def get_motion_model():
        # dx, dy, cost
        motion = [[1, 0, 1],
                  [0, 1, 1],
                  [-1, 0, 1],
                  [0, -1, 1],
                  [-1, -1, math.sqrt(2)],
                  [-1, 1, math.sqrt(2)],
                  [1, -1, math.sqrt(2)],
                  [1, 1, math.sqrt(2)]]

        return motion

def main():
    print(__file__ + " start!!")

    # start and goal position
    sx = 10.0  # [m]
    sy = 10.0  # [m]
    gx = 50.0  # [m]
    gy = 50.0  # [m]
    grid_size = 2.0  # [m]
    robot_radius = 1.0  # [m]

    # set obstacle positions
    ox, oy = [], []
    for i in range(-10, 60):
        ox.append(i)
        oy.append(-10.0)
    for i in range(-10, 60):
        ox.append(60.0)
        oy.append(i)
    for i in range(-10, 61):
        ox.append(i)
        oy.append(60.0)
    for i in range(-10, 61):
        ox.append(-10.0)
        oy.append(i)
    for i in range(-10, 40):
        ox.append(20.0)
        oy.append(i)
    for i in range(0, 40):
        ox.append(40.0)
        oy.append(60.0 - i)

    if show_animation:  # pragma: no cover
        plt.plot(ox, oy, ".k")
        plt.plot(sx, sy, "og")
        plt.plot(gx, gy, "xb")
        plt.grid(True)
        plt.axis("equal")

    a_star = AStarPlanner(ox, oy, grid_size, robot_radius)
    rx, ry, route_len, route_len_3D = a_star.planning(sx, sy, gx, gy)
    print("len of route:", route_len)
    print("len of route in 3D:", route_len_3D)

    if show_animation:  # pragma: no cover
        plt.plot(rx, ry, "-r")
        plt.pause(0.001)
        plt.show()

if __name__ == '__main__':
    main()


import importlib
import os
from collections import OrderedDict
from lib.test.evaluation.environment import env_settings
import time
import cv2 as cv

from lib.utils.lmdb_utils import decode_img
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
from segment_anything import build_sam, SamPredictor,sam_model_registry

def show_mask(mask, ax, random_color=False):
    if random_color:
        color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)
    else:
        color = np.array([30 / 255, 144 / 255, 255 / 255, 0.6])
    h, w = mask.shape[-2:]
    mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)
    ax.imshow(mask_image)

def show_points(coords, labels, ax, marker_size=375):
    pos_points = coords[labels == 1]
    neg_points = coords[labels == 0]
    ax.scatter(pos_points[:, 0], pos_points[:, 1], color='green', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)
    ax.scatter(neg_points[:, 0], neg_points[:, 1], color='red', marker='*', s=marker_size, edgecolor='white',
               linewidth=1.25)

def show_box(box, ax):
    x0, y0 = box[0], box[1]
    w, h = box[2] - box[0], box[3] - box[1]
    ax.add_patch(plt.Rectangle((x0, y0), w, h, edgecolor='green', facecolor=(0, 0, 0, 0), lw=2))

def trackerlist(name: str, parameter_name: str, dataset_name: str, run_ids = None, display_name: str = None,
                result_only=False):
    """Generate list of trackers.
    args:
        name: Name of tracking method.
        parameter_name: Name of parameter file.
        run_ids: A single or list of run_ids.
        display_name: Name to be displayed in the result plots.
    """
    if run_ids is None or isinstance(run_ids, int):
        run_ids = [run_ids]
    return [Tracker(name, parameter_name, dataset_name, run_id, display_name, result_only) for run_id in run_ids]

def to_int(string):
    return int(os.path.basename(string)[:-4])

class Tracker:
    """Wraps the tracker for evaluation and running purposes.
    args:
        name: Name of tracking method.
        parameter_name: Name of parameter file.
        run_id: The run id.
        display_name: Name to be displayed in the result plots.
    """

    def __init__(self, name: str, parameter_name: str, dataset_name: str, run_id: int = None, display_name: str = None,
                 result_only=False):
        assert run_id is None or isinstance(run_id, int)

        self.name = name
        self.parameter_name = parameter_name
        self.dataset_name = dataset_name
        self.run_id = run_id
        self.display_name = display_name
        self.predictor = SamPredictor(sam_model_registry["vit_h"](checkpoint="").to(device="cuda"))

        env = env_settings()
        if self.run_id is None:
            self.results_dir = '{}/{}/{}'.format(env.results_path, self.name, self.parameter_name)
        else:
            self.results_dir = '{}/{}/{}_{:03d}'.format(env.results_path, self.name, self.parameter_name, self.run_id)
        if result_only:
            self.results_dir = '{}/{}'.format(env.results_path, self.name)

        tracker_module_abspath = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                                              '..', 'tracker', '%s.py' % self.name))
        if os.path.isfile(tracker_module_abspath):
            tracker_module = importlib.import_module('lib.test.tracker.{}'.format(self.name))
            self.tracker_class = tracker_module.get_tracker_class()
        else:
            self.tracker_class = None

    def create_tracker(self, params):
        tracker = self.tracker_class(params, self.dataset_name)
        return tracker

    def run_sequence(self, seq, debug=None):
        """Run tracker on sequence.
        args:
            seq: Sequence to run the tracker on.
            visualization: Set visualization flag (None means default value specified in the parameters).
            debug: Set debug level (None means default value specified in the parameters).
            multiobj_mode: Which mode to use for multiple objects.
        """
        params = self.get_parameters()

        debug_ = debug
        if debug is None:
            debug_ = getattr(params, 'debug', 0)

        params.debug = debug_

        init_info = seq.init_info()

        tracker = self.create_tracker(params)

        output = self._track_sequence(tracker, seq, init_info)
        return output

    def _track_sequence(self, tracker, seq, init_info):

        output = {'target_bbox': [],
                  'time': []}
        if tracker.params.save_all_boxes:
            output['all_boxes'] = []
            output['all_scores'] = []

        def _store_outputs(tracker_out: dict, defaults=None):
            defaults = {} if defaults is None else defaults
            for key in output.keys():
                val = tracker_out.get(key, defaults.get(key, None))
                if key in tracker_out or val is not None:
                    output[key].append(val)

        image = self._read_image(seq.frames[0])

        start_time = time.time()
        out = tracker.initialize(image, init_info)
        if out is None:
            out = {}

        prev_output = OrderedDict(out)
        init_default = {'target_bbox': init_info.get('init_bbox'),
                        'time': time.time() - start_time}
        if tracker.params.save_all_boxes:
            init_default['all_boxes'] = out['all_boxes']
            init_default['all_scores'] = out['all_scores']

        _store_outputs(out, init_default)

        for frame_num, frame_path in enumerate(seq.frames[1:], start=1):
            image = self._read_image(frame_path)

            start_time = time.time()

            info = seq.frame_info(frame_num)
            info['previous_output'] = prev_output

            if len(seq.ground_truth_rect) > 1:
                info['gt_bbox'] = seq.ground_truth_rect[frame_num]
            out = tracker.track(image, info)
            prev_output = OrderedDict(out)
            _store_outputs(out, {'time': time.time() - start_time})

        for key in ['target_bbox', 'all_boxes', 'all_scores']:
            if key in output and len(output[key]) <= 1:
                output.pop(key)

        return output

    def mouse_handler(self,event, x, y, flags,param):
        if event == cv.EVENT_LBUTTONDOWN and flags ==cv.EVENT_FLAG_CTRLKEY + cv.EVENT_LBUTTONDOWN:

            self.input_point.append([x,y])
            self.input_lbael.append(int(0))
            self.samflag=True
        elif event == cv.EVENT_LBUTTONDOWN:

            self.input_point.append([x,y])
            self.input_lbael.append(int(1))
            self.samflag=True

    def run_imgdir(self, videofilepath, optional_box=None, debug=None, visdom_info=None, save_results=False,index=None):
        """Run the tracker with the vieofile.
        args:
            debug: Debug level.
        """
        img_list=os.listdir(videofilepath)
        img_list.sort(key=to_int)
        params = self.get_parameters()

        debug_ = debug
        if debug is None:
            debug_ = getattr(params, 'debug', 0)
        params.debug = debug_

        params.tracker_name = self.name
        params.param_name = self.parameter_name

        multiobj_mode = getattr(params, 'multiobj_mode', getattr(self.tracker_class, 'multiobj_mode', 'default'))

        if multiobj_mode == 'default':
            tracker = self.create_tracker(params)

        else:
            raise ValueError('Unknown multi object mode {}'.format(multiobj_mode))

        output_boxes = []

        def _build_init_info(box):
            return {'init_bbox': box}

        display_name = 'Display: ' + tracker.params.tracker_name
        if optional_box is not None:
            frame = cv.imread(videofilepath + '/' + img_list[0])
            frame_disp = frame.copy()
            color_seg = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
            self.predictor.set_image(cv.cvtColor(frame, cv.COLOR_BGR2RGB))
            self.input_point=[]
            self.input_lbael=[]
            self.samflag=False

            while True:
                cv.imshow(display_name,frame_disp*(1-color_seg))
                cv.setMouseCallback(display_name, self.mouse_handler)

                k=cv.waitKey(1)
                if self.samflag==True:
                    color_seg = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
                    masks, scores, logits = self.predictor.predict(
                        point_coords=np.array(self.input_point),
                        point_labels=np.array(self.input_lbael),
                        multimask_output=True,)
                    mask = masks[np.argmax(scores)]
                    inde = np.where(mask == True)
                    xx = inde[0].min()
                    yy = inde[1].min()
                    ww = inde[0].max() - xx
                    hh = inde[1].max() - yy
                    cv.rectangle(color_seg, [yy,xx,hh,ww],(1,1,1), 3)
                    if self.input_lbael[-1]==0:
                        cv.circle(frame_disp, (self.input_point[-1][0], self.input_point[-1][1]), 5, (0, 128, 0), -1)
                    elif self.input_lbael[-1]==1:
                        cv.circle(frame_disp, (self.input_point[-1][0], self.input_point[-1][1]), 5, (0, 0, 128), -1)
                    self.samflag=False
                if k==ord('f'):
                    break
                elif k==ord('r'):
                    frame_disp = frame.copy()
                    self.input_point = []
                    self.input_lbael = []
                    color_seg = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
            init_state = [yy,xx, hh, ww]
            tracker.initialize(frame, _build_init_info(init_state))
            output_boxes.append(init_state)

        else:

            cv.namedWindow(display_name, cv.WINDOW_NORMAL | cv.WINDOW_KEEPRATIO)
            cv.resizeWindow(display_name, 960, 720)

            frame = cv.imread(videofilepath + '/' + img_list[0])
            cv.imshow(display_name, frame)
            while True:

                frame_disp = frame.copy()

                cv.putText(frame_disp, 'Select target ROI and press ENTER', (20, 30), cv.FONT_HERSHEY_COMPLEX_SMALL,
                           1.5, (0, 0, 0), 1)

                x, y, w, h = cv.selectROI(display_name, frame_disp, fromCenter=False)
                init_state = [x, y, w, h]
                tracker.initialize(frame, _build_init_info(init_state))
                output_boxes.append(init_state)
                break

        for img in img_list:
            frame = cv.imread(videofilepath+'/'+img)

            if frame is None:
                break

            img_tosave = frame.copy()

            out = tracker.track(frame)
            state = [int(s) for s in out['target_bbox']]
            output_boxes.append(state)

            cv.rectangle(img_tosave, (state[0], state[1]), (state[2] + state[0], state[3] + state[1]),
                         index, 5)
            self.predictor.set_image(cv.cvtColor(frame, cv.COLOR_BGR2RGB))
            masks, scores, logits = self.predictor.predict(box=np.array([state[0],state[1],state[2] + state[0],state[3] + state[1]]), multimask_output=True, )
            mask = masks[np.argmax(scores)]
            color_seg = np.zeros((mask.shape[0], mask.shape[1], 3), dtype=np.uint8)
            color_seg[mask == True, :] = (0, 0, 255)

            cv.imshow(display_name, (img_tosave*0.5+color_seg*0.5)/255)
            key = cv.waitKey(1)

        cv.destroyAllWindows()

    def get_parameters(self):
        """Get parameters."""
        param_module = importlib.import_module('lib.test.parameter.{}'.format(self.name))
        params = param_module.parameters(self.parameter_name)
        return params

    def _read_image(self, image_file: str):
        if isinstance(image_file, str):
            im = cv.imread(image_file)
            return cv.cvtColor(im, cv.COLOR_BGR2RGB)
        elif isinstance(image_file, list) and len(image_file) == 2:
            return decode_img(image_file[0], image_file[1])
        else:
            raise ValueError("type of image_file should be str or list")


# Tag: Graph + Binary Tree + Recusion
# 543. Diameter of Binary Tree(Leetcode)
# -----------------------------------------------------------------------------------
# Description:
# Given a binary tree, you need to compute the length of the diameter of the tree.
# The diameter of a binary tree is the length of the longest path between
# any two nodes in a tree. This path may or may not pass through the root.

# -----------------------------------------------------------------------------------
# Assumptions:
#The length of path between two nodes is represented by the number of edges between them.
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# 思路：Recurison+DFS
# 两种可能，从root开始的左右depht相加，或者在同一个subtree 里面的某个左右depht相加
# 要找最长pathway，用recursion的思维做：
# 1. 如果我们知道在每个subtree root node的 Left max Height and Right Height and Maxsum of
# and 到此node为止的Maxsum = LeftmaxHeight + RightMaxHeight
# 2. 我们就知道parent node 的 LeftmaxHeight, RightMaxHeight and Maxsum
# 3. Base case: if not root:
#                   return 0
# -----------------------------------------------------------------------------------
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def diameterOfBinaryTree(self, root):
        # Traverse from root to the leaf record the two
        def maxHeight(root,maxsum):
            LmaxHeight = 0
            RmaxHeight = 0
            if not root:
                return 0

            if root.left:
                LmaxHeight,maxsum = maxHeight(root.left,maxsum)
            if root.right:
                RmaxHeight,maxsum =  maxHeight(root.right,maxsum)
            if LmaxHeight + RmaxHeight >= maxsum:
                maxsum = LmaxHeight + RmaxHeight
            if LmaxHeight>= RmaxHeight:
                return LmaxHeight + 1,maxsum
            if LmaxHeight< RmaxHeight:
                return RmaxHeight + 1,maxsum

        Lsubheight = 0
        Rsubheight = 0
        maxsum = 0
        if not root:
            return 0
        if root.left:
            Lsubheight,maxsum = maxHeight(root.left,maxsum)
        if root.right:
            Rsubheight,maxsum = maxHeight(root.right,maxsum)
        LRsum = Lsubheight + Rsubheight
        if LRsum >= maxsum:
            return LRsum
        else:
            return maxsum


#!/usr/bin/python
# -*- coding: UTF-8 -*-

import tensorflow as tf
DDPG_CFG = tf.app.flags.FLAGS  # alias

def soft_update_online_to_target(online_vars_by_name, target_vars_by_name):
  update_ops = []
  ### theta_prime = tau * theta + (1-tau) * theta_prime
  for (online_var_name, online_var) in online_vars_by_name.items():
    target_var = target_vars_by_name[online_var_name]
    theta_prime = DDPG_CFG.tau * online_var + (1 - DDPG_CFG.tau) * target_var
    assign_op = tf.assign(ref=target_var, value=theta_prime)
    update_ops.append(assign_op)

  return tf.group(*update_ops)

def copy_online_to_target(online_vars_by_name, target_vars_by_name):
  copy_ops = []
  ### theta_q -> theta_q_prime
  for (online_var_name, online_var) in online_vars_by_name.items():
    target_var = target_vars_by_name[online_var_name]
    assign_op = tf.assign(ref=target_var, value=online_var)
    copy_ops.append(assign_op)

  return tf.group(*copy_ops)


# I wrote this because I needed to understand the target redirect URL from a bunch of pages. Not the best, but it did the job.
# This script has not try-catch so it will crash when not finding a URL, expected expressions, etc. I'll improve someday when needed.

from urllib.request import urlopen
import re
import pandas as pd
import time

l = 0

#Download the list of links URLs and format appropriately.
links = [
"http://site.com/page1"
,"http://site.com/page1"
]
redirects = []
UA_list = []

for link in links:
    l=l
    f = urlopen(link)
    print ('fetching link...')
    myfile = f.read().decode()
#for_debug     print(myfile)
    type(myfile)

    url = re.search('http(.?):(.*?)\'',myfile)
    url = url.group(0)
    url = url[:-1]
#for_debug     print (url)
    redirects.append(url)

    UA = re.search('UA-(.*?)\'',myfile)
    UA = UA.group(0)
    UA = UA[:-1]
#for_debug     print (UA)
    UA_list.append(UA)
#for_debug     time.sleep(1) #for troubleshooting

# print (links)
# print (redirects)
# print(UA_list)

df = pd.DataFrame({
    "links": links,
    "UA": UA_list,
    "redirects": redirects,
})

# print(df.to_string())

export_csv = df.to_csv (r'C:\<FILE PATH>\export_dataframe.csv', index = None, header=True) #Don't forget to add '.csv' at the end of the path
print('Done!')


from aqt.qt import *
from anki.hooks import addHook

class Lightbox:
    def __init__(self, mw):
        self.mw = mw
        self.setupMenu()
        addHook('profileLoaded', self.onProfileLoaded)
        addHook('showQuestion', self._wrapLightbox)
        addHook('showAnswer', self._wrapLightbox)

    def setupMenu(self):
        menu = self.mw.form.menuView
        self.cbLightbox = QAction("Lightbox", menu)
        self.cbLightbox.setCheckable(True)
        self.cbLightbox.triggered.connect(self._toggleLightbox)
        menu.addAction(self.cbLightbox)

    def onProfileLoaded(self):
        b = self.mw.pm.profile.get('viewm.lightbox',False)
        self.cbLightbox.setChecked(b)
        self._toggleLightbox()

    def _wrapLightbox(self):
        if self.cbLightbox.isChecked():
            self.mw.web.eval("lightbox_wrap();")

    def _toggleLightbox(self):
        isOn = self.mw.pm.profile['viewm.lightbox'] = self.cbLightbox.isChecked()
        if self.mw.state == "review":
            if isOn:
                b = self.mw.web.page().mainFrame().evaluateJavaScript("lightbox_loaded")
                if b == None: #js not loaded
                    self.mw.reviewer.cardQueue.append(self.mw.reviewer.card)
                    self.mw.reset(guiOnly=True)
                self.mw.web.eval("lightbox_wrap();")
            else:
                self.mw.web.eval("lightbox_unwrap();")

    def isChecked(self):
        return self.cbLightbox.isChecked()