"""
SwiftFormer
"""
import os
import copy
import torch
import torch.nn as nn
from timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD
from timm.models.layers import DropPath, trunc_normal_
from timm.models.registry import register_model
from timm.models.layers.helpers import to_2tuple
import einops

SwiftFormer_width = {
    'XS': [48, 56, 112, 220],
    'S': [48, 64, 168, 224],
    'l1': [48, 96, 192, 384],
    'l3': [64, 128, 320, 512],
}

SwiftFormer_depth = {
    'XS': [3, 3, 6, 4],
    'S': [3, 3, 9, 6],
    'l1': [4, 3, 10, 5],
    'l3': [4, 4, 12, 6],
}

def stem(in_chs, out_chs):
    """
    Stem Layer that is implemented by two layers of conv.
    Output: sequence of layers with final shape of [B, C, H/4, W/4]
    """
    return nn.Sequential(
        nn.Conv2d(in_chs, out_chs // 2, kernel_size=3, stride=2, padding=1),
        nn.BatchNorm2d(out_chs // 2),
        nn.ReLU(),
        nn.Conv2d(out_chs // 2, out_chs, kernel_size=3, stride=2, padding=1),
        nn.BatchNorm2d(out_chs),
        nn.ReLU(), )

class Embedding(nn.Module):
    """
    Patch Embedding that is implemented by a layer of conv.
    Input: tensor in shape [B, C, H, W]
    Output: tensor in shape [B, C, H/stride, W/stride]
    """

    def __init__(self, patch_size=16, stride=16, padding=0,
                 in_chans=3, embed_dim=768, norm_layer=nn.BatchNorm2d):
        super().__init__()
        patch_size = to_2tuple(patch_size)
        stride = to_2tuple(stride)
        padding = to_2tuple(padding)
        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size,
                              stride=stride, padding=padding)
        self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()

    def forward(self, x):
        x = self.proj(x)
        x = self.norm(x)
        return x

class ConvEncoder(nn.Module):
    """
    Implementation of ConvEncoder with 3*3 and 1*1 convolutions.
    Input: tensor with shape [B, C, H, W]
    Output: tensor with shape [B, C, H, W]
    """

    def __init__(self, dim, hidden_dim=64, kernel_size=3, drop_path=0., use_layer_scale=True):
        super().__init__()
        self.dwconv = nn.Conv2d(dim, dim, kernel_size=kernel_size, padding=kernel_size // 2, groups=dim)
        self.norm = nn.BatchNorm2d(dim)
        self.pwconv1 = nn.Conv2d(dim, hidden_dim, kernel_size=1)
        self.act = nn.GELU()
        self.pwconv2 = nn.Conv2d(hidden_dim, dim, kernel_size=1)
        self.drop_path = DropPath(drop_path) if drop_path > 0. \
            else nn.Identity()
        self.use_layer_scale = use_layer_scale
        if use_layer_scale:
            self.layer_scale = nn.Parameter(torch.ones(dim).unsqueeze(-1).unsqueeze(-1), requires_grad=True)
        self.apply(self._init_weights)

    def _init_weights(self, m):
        if isinstance(m, nn.Conv2d):
            trunc_normal_(m.weight, std=.02)
            if m.bias is not None:
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        input = x
        x = self.dwconv(x)
        x = self.norm(x)
        x = self.pwconv1(x)
        x = self.act(x)
        x = self.pwconv2(x)
        if self.use_layer_scale:
            x = input + self.drop_path(self.layer_scale * x)
        else:
            x = input + self.drop_path(x)
        return x

class Mlp(nn.Module):
    """
    Implementation of MLP layer with 1*1 convolutions.
    Input: tensor with shape [B, C, H, W]
    Output: tensor with shape [B, C, H, W]
    """

    def __init__(self, in_features, hidden_features=None,
                 out_features=None, act_layer=nn.GELU, drop=0.):
        super().__init__()
        out_features = out_features or in_features
        hidden_features = hidden_features or in_features
        self.norm1 = nn.BatchNorm2d(in_features)
        self.fc1 = nn.Conv2d(in_features, hidden_features, 1)
        self.act = act_layer()
        self.fc2 = nn.Conv2d(hidden_features, out_features, 1)
        self.drop = nn.Dropout(drop)
        self.apply(self._init_weights)

    def _init_weights(self, m):
        if isinstance(m, nn.Conv2d):
            trunc_normal_(m.weight, std=.02)
            if m.bias is not None:
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        x = self.norm1(x)
        x = self.fc1(x)
        x = self.act(x)
        x = self.drop(x)
        x = self.fc2(x)
        x = self.drop(x)
        return x

class EfficientAdditiveAttnetion(nn.Module):
    """
    Efficient Additive Attention module for SwiftFormer.
    Input: tensor in shape [B, N, D]
    Output: tensor in shape [B, N, D]
    """

    def __init__(self, in_dims=512, token_dim=256, num_heads=2):
        super().__init__()

        self.to_query = nn.Linear(in_dims, token_dim * num_heads)
        self.to_key = nn.Linear(in_dims, token_dim * num_heads)

        self.w_g = nn.Parameter(torch.randn(token_dim * num_heads, 1))
        self.scale_factor = token_dim ** -0.5
        self.Proj = nn.Linear(token_dim * num_heads, token_dim * num_heads)
        self.final = nn.Linear(token_dim * num_heads, token_dim)

    def forward(self, x):
        query = self.to_query(x)
        key = self.to_key(x)

        query = torch.nn.functional.normalize(query, dim=-1) #BxNxD
        key = torch.nn.functional.normalize(key, dim=-1) #BxNxD

        query_weight = query @ self.w_g # BxNx1 (BxNxD @ Dx1)
        A = query_weight * self.scale_factor # BxNx1

        A = torch.nn.functional.normalize(A, dim=1) # BxNx1

        G = torch.sum(A * query, dim=1) # BxD

        G = einops.repeat(
            G, "b d -> b repeat d", repeat=key.shape[1]
        ) # BxNxD

        out = self.Proj(G * key) + query #BxNxD

        out = self.final(out) # BxNxD

        return out

class SwiftFormerLocalRepresentation(nn.Module):
    """
    Local Representation module for SwiftFormer that is implemented by 3*3 depth-wise and point-wise convolutions.
    Input: tensor in shape [B, C, H, W]
    Output: tensor in shape [B, C, H, W]
    """

    def __init__(self, dim, kernel_size=3, drop_path=0., use_layer_scale=True):
        super().__init__()
        self.dwconv = nn.Conv2d(dim, dim, kernel_size=kernel_size, padding=kernel_size // 2, groups=dim)
        self.norm = nn.BatchNorm2d(dim)
        self.pwconv1 = nn.Conv2d(dim, dim, kernel_size=1)
        self.act = nn.GELU()
        self.pwconv2 = nn.Conv2d(dim, dim, kernel_size=1)
        self.drop_path = DropPath(drop_path) if drop_path > 0. \
            else nn.Identity()
        self.use_layer_scale = use_layer_scale
        if use_layer_scale:
            self.layer_scale = nn.Parameter(torch.ones(dim).unsqueeze(-1).unsqueeze(-1), requires_grad=True)
        self.apply(self._init_weights)

    def _init_weights(self, m):
        if isinstance(m, nn.Conv2d):
            trunc_normal_(m.weight, std=.02)
            if m.bias is not None:
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        input = x
        x = self.dwconv(x)
        x = self.norm(x)
        x = self.pwconv1(x)
        x = self.act(x)
        x = self.pwconv2(x)
        if self.use_layer_scale:
            x = input + self.drop_path(self.layer_scale * x)
        else:
            x = input + self.drop_path(x)
        return x

class SwiftFormerEncoder(nn.Module):
    """
    SwiftFormer Encoder Block for SwiftFormer. It consists of (1) Local representation module, (2) EfficientAdditiveAttention, and (3) MLP block.
    Input: tensor in shape [B, C, H, W]
    Output: tensor in shape [B, C, H, W]
    """

    def __init__(self, dim, mlp_ratio=4.,
                 act_layer=nn.GELU,
                 drop=0., drop_path=0.,
                 use_layer_scale=True, layer_scale_init_value=1e-5):

        super().__init__()

        self.local_representation = SwiftFormerLocalRepresentation(dim=dim, kernel_size=3, drop_path=0.,
                                                                   use_layer_scale=True)
        self.attn = EfficientAdditiveAttnetion(in_dims=dim, token_dim=dim, num_heads=1)
        self.linear = Mlp(in_features=dim, hidden_features=int(dim * mlp_ratio), act_layer=act_layer, drop=drop)
        self.drop_path = DropPath(drop_path) if drop_path > 0. \
            else nn.Identity()
        self.use_layer_scale = use_layer_scale
        if use_layer_scale:
            self.layer_scale_1 = nn.Parameter(
                layer_scale_init_value * torch.ones(dim).unsqueeze(-1).unsqueeze(-1), requires_grad=True)
            self.layer_scale_2 = nn.Parameter(
                layer_scale_init_value * torch.ones(dim).unsqueeze(-1).unsqueeze(-1), requires_grad=True)

    def forward(self, x):
        x = self.local_representation(x)
        B, C, H, W = x.shape
        if self.use_layer_scale:
            x = x + self.drop_path(
                self.layer_scale_1 * self.attn(x.permute(0, 2, 3, 1).reshape(B, H * W, C)).reshape(B, H, W, C).permute(
                    0, 3, 1, 2))
            x = x + self.drop_path(self.layer_scale_2 * self.linear(x))

        else:
            x = x + self.drop_path(
                self.attn(x.permute(0, 2, 3, 1).reshape(B, H * W, C)).reshape(B, H, W, C).permute(0, 3, 1, 2))
            x = x + self.drop_path(self.linear(x))
        return x

def Stage(dim, index, layers, mlp_ratio=4.,
          act_layer=nn.GELU,
          drop_rate=.0, drop_path_rate=0.,
          use_layer_scale=True, layer_scale_init_value=1e-5, vit_num=1):
    """
    Implementation of each SwiftFormer stages. Here, SwiftFormerEncoder used as the last block in all stages, while ConvEncoder used in the rest of the blocks.
    Input: tensor in shape [B, C, H, W]
    Output: tensor in shape [B, C, H, W]
    """
    blocks = []

    for block_idx in range(layers[index]):
        block_dpr = drop_path_rate * (block_idx + sum(layers[:index])) / (sum(layers) - 1)

        if layers[index] - block_idx <= vit_num:
            blocks.append(SwiftFormerEncoder(
                dim, mlp_ratio=mlp_ratio,
                act_layer=act_layer, drop_path=block_dpr,
                use_layer_scale=use_layer_scale,
                layer_scale_init_value=layer_scale_init_value))

        else:
            blocks.append(ConvEncoder(dim=dim, hidden_dim=int(mlp_ratio * dim), kernel_size=3))

    blocks = nn.Sequential(*blocks)
    return blocks

class SwiftFormer(nn.Module):

    def __init__(self, layers, embed_dims=None,
                 mlp_ratios=4, downsamples=None,
                 act_layer=nn.GELU,
                 num_classes=1000,
                 down_patch_size=3, down_stride=2, down_pad=1,
                 drop_rate=0., drop_path_rate=0.,
                 use_layer_scale=True, layer_scale_init_value=1e-5,
                 fork_feat=False,
                 init_cfg=None,
                 pretrained=None,
                 vit_num=1,
                 distillation=True,
                 **kwargs):
        super().__init__()

        if not fork_feat:
            self.num_classes = num_classes
        self.fork_feat = fork_feat

        self.patch_embed = stem(3, embed_dims[0])

        network = []
        for i in range(len(layers)):
            stage = Stage(embed_dims[i], i, layers, mlp_ratio=mlp_ratios,
                          act_layer=act_layer,
                          drop_rate=drop_rate,
                          drop_path_rate=drop_path_rate,
                          use_layer_scale=use_layer_scale,
                          layer_scale_init_value=layer_scale_init_value,
                          vit_num=vit_num)
            network.append(stage)
            if i >= len(layers) - 1:
                break
            if downsamples[i] or embed_dims[i] != embed_dims[i + 1]:
                # downsampling between two stages
                network.append(
                    Embedding(
                        patch_size=down_patch_size, stride=down_stride,
                        padding=down_pad,
                        in_chans=embed_dims[i], embed_dim=embed_dims[i + 1]
                    )
                )

        self.network = nn.ModuleList(network)

        if self.fork_feat:
            # add a norm layer for each output
            self.out_indices = [0, 2, 4, 6]
            for i_emb, i_layer in enumerate(self.out_indices):
                if i_emb == 0 and os.environ.get('FORK_LAST3', None):
                    layer = nn.Identity()
                else:
                    layer = nn.BatchNorm2d(embed_dims[i_emb])
                layer_name = f'norm{i_layer}'
                self.add_module(layer_name, layer)
        else:
            # Classifier head
            self.norm = nn.BatchNorm2d(embed_dims[-1])
            self.head = nn.Linear(
                embed_dims[-1], num_classes) if num_classes > 0 \
                else nn.Identity()
            self.dist = distillation
            if self.dist:
                self.dist_head = nn.Linear(
                    embed_dims[-1], num_classes) if num_classes > 0 \
                    else nn.Identity()

        # self.apply(self.cls_init_weights)
        self.apply(self._init_weights)

        self.init_cfg = copy.deepcopy(init_cfg)
        # load pre-trained model
        if self.fork_feat and (
                self.init_cfg is not None or pretrained is not None):
            self.init_weights()

    # init for mmdetection or mmsegmentation by loading
    # imagenet pre-trained weights
    def init_weights(self, pretrained=None):
        logger = get_root_logger()
        if self.init_cfg is None and pretrained is None:
            logger.warn(f'No pre-trained weights for '
                        f'{self.__class__.__name__}, '
                        f'training start from scratch')
            pass
        else:
            assert 'checkpoint' in self.init_cfg, f'Only support ' \
                                                  f'specify `Pretrained` in ' \
                                                  f'`init_cfg` in ' \
                                                  f'{self.__class__.__name__} '
            if self.init_cfg is not None:
                ckpt_path = self.init_cfg['checkpoint']
            elif pretrained is not None:
                ckpt_path = pretrained

            ckpt = _load_checkpoint(
                ckpt_path, logger=logger, map_location='cpu')
            if 'state_dict' in ckpt:
                _state_dict = ckpt['state_dict']
            elif 'model' in ckpt:
                _state_dict = ckpt['model']
            else:
                _state_dict = ckpt

            state_dict = _state_dict
            missing_keys, unexpected_keys = \
                self.load_state_dict(state_dict, False)

    def _init_weights(self, m):
        if isinstance(m, (nn.Conv2d, nn.Linear)):
            trunc_normal_(m.weight, std=.02)
            if m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, (nn.LayerNorm)):
            nn.init.constant_(m.bias, 0)
            nn.init.constant_(m.weight, 1.0)

    def forward_tokens(self, x):
        outs = []
        for idx, block in enumerate(self.network):
            x = block(x)
            if self.fork_feat and idx in self.out_indices:
                norm_layer = getattr(self, f'norm{idx}')
                x_out = norm_layer(x)
                outs.append(x_out)
        if self.fork_feat:
            return outs
        return x

    def forward(self, x):
        x = self.patch_embed(x)
        x = self.forward_tokens(x)
        if self.fork_feat:
            # Output features of four stages for dense prediction
            return x

        x = self.norm(x)
        if self.dist:
            cls_out = self.head(x.flatten(2).mean(-1)), self.dist_head(x.flatten(2).mean(-1))
            if not self.training:
                cls_out = (cls_out[0] + cls_out[1]) / 2
        else:
            cls_out = self.head(x.mean(-2))
        # For image classification
        return cls_out

def _cfg(url='', **kwargs):
    return {
        'url': url,
        'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': None,
        'crop_pct': .95, 'interpolation': 'bicubic',
        'mean': IMAGENET_DEFAULT_MEAN, 'std': IMAGENET_DEFAULT_STD,
        'classifier': 'head',
        **kwargs
    }

@register_model
def SwiftFormer_XS(pretrained=False, **kwargs):
    model = SwiftFormer(
        layers=SwiftFormer_depth['XS'],
        embed_dims=SwiftFormer_width['XS'],
        downsamples=[True, True, True, True],
        vit_num=1,
        **kwargs)
    model.default_cfg = _cfg(crop_pct=0.9)
    return model

@register_model
def SwiftFormer_S(pretrained=False, **kwargs):
    model = SwiftFormer(
        layers=SwiftFormer_depth['S'],
        embed_dims=SwiftFormer_width['S'],
        downsamples=[True, True, True, True],
        vit_num=1,
        **kwargs)
    model.default_cfg = _cfg(crop_pct=0.9)
    return model

@register_model
def SwiftFormer_L1(pretrained=False, **kwargs):
    model = SwiftFormer(
        layers=SwiftFormer_depth['l1'],
        embed_dims=SwiftFormer_width['l1'],
        downsamples=[True, True, True, True],
        vit_num=1,
        **kwargs)
    model.default_cfg = _cfg(crop_pct=0.9)
    return model

@register_model
def SwiftFormer_L3(pretrained=False, **kwargs):
    model = SwiftFormer(
        layers=SwiftFormer_depth['l3'],
        embed_dims=SwiftFormer_width['l3'],
        downsamples=[True, True, True, True],
        vit_num=1,
        **kwargs)
    model.default_cfg = _cfg(crop_pct=0.9)
    return model


import datetime
import unittest
import logging
from asciiserialcom.message import ASC_Message
from asciiserialcom.host import Host
from asciiserialcom.errors import *
from asciiserialcom.utilities import Tracer
from asciiserialcom.tty_utils import setup_tty
import trio
import termios
import time

class TestRxCounterFromDevice(unittest.TestCase):
    """
    Requires firmware:

        openocd -f /usr/share/openocd/scripts/board/st_nucleo_f0.cfg -c "program build/cortex-m0_gcc_debug/stm32f091nucleo64_write_pattern_to_serial.elf verify reset exit"

    """

    def setUp(self):
        self.baud = 9600
        self.dev_path = "/dev/ttyACM0"
        # self.dev_path = "/dev/ttyACM1"

        logging.basicConfig(
            # filename="test_asciiSerialCom.log",
            # level=logging.INFO,
            # level=logging.DEBUG,
            level=logging.WARNING,
            # format="%(asctime)s %(levelname)s L%(lineno)d %(funcName)s: %(message)s"
            format="%(message)s",
        )
        setup_tty(self.dev_path, self.baud)

    def test_just_device(self):
        async def receiver(chan, f):
            while True:
                data = await f.read(1)
                if len(data) == 0:
                    continue
                await chan.send(data)

        async def data_checker(self, chan, data_checker_finished):
            last = None
            logging.debug("Starting data_checker")
            for i in range(400):
                await chan.receive()
            for i in range(2000):
                data = await chan.receive()
                num = int(data)
                logging.debug(f"{i:5} {num:2}")
                if last == 9:
                    self.assertEqual(num, 0)
                elif last:
                    self.assertEqual(num, last + 1)
                last = num
            data_checker_finished.set()

        async def run_test(self):
            logging.info("Starting run_test")
            send_chan, recv_chan = trio.open_memory_channel(100)
            data_checker_finished = trio.Event()
            got_to_cancel = False
            with trio.move_on_after(10):
                logging.info("About to open file...")
                async with await trio.open_file(self.dev_path, "br") as portr:
                    termios.tcflush(portr.wrapped, termios.TCIFLUSH)
                    logging.debug("flushed input buffer")
                    await portr.read(400)
                    async with trio.open_nursery() as nursery:
                        nursery.start_soon(receiver, send_chan, portr)
                        nursery.start_soon(
                            data_checker, self, recv_chan, data_checker_finished
                        )
                        await data_checker_finished.wait()
                        nursery.cancel_scope.cancel()
            self.assertTrue(data_checker_finished.is_set())

        trio.run(run_test, self)

class TestRxASCCounterFromDevice(unittest.TestCase):
    """
    Requires firmware:

        openocd -f /usr/share/openocd/scripts/board/st_nucleo_f0.cfg -c "program build/cortex-m0_gcc_debug/stm32f091nucleo64_adc_streaming.elf verify reset exit"

    """

    def setUp(self):
        self.baud = 9600
        # self.baud = 19200
        self.dev_path = "/dev/ttyACM0"
        # self.dev_path = "/dev/ttyACM1"

        logging.basicConfig(
            # filename="test_asciiSerialCom.log",
            # level=logging.INFO,
            # level=logging.DEBUG,
            level=logging.WARNING,
            format="%(levelname)s L%(lineno)d %(funcName)s: %(message)s",
        )
        setup_tty(self.dev_path, self.baud)
        self.max32bits = 2 ** 32 - 1

    def test_host_device(self):
        nRegisterBits = 32

        async def data_checker(self, chan, data_checker_finished):
            logging.debug("Starting data_checker",)
            last = None
            starttime = time.time()
            nMessages = 200
            messageLen = 0
            for iMessage in range(nMessages):
                nMissed, data = await chan.receive()
                logging.info(f"message received: {nMissed} {data}")
                num = int(data.decode()[0], 16)
                if last == self.max32bits:
                    self.assertEqual(num, 0)
                elif last:
                    self.assertEqual(num, last + 1)
                last = num
                if iMessage == 0:
                    messageLen = len(data) + 10
            endtime = time.time()
            deltat = endtime - starttime
            tpermessage = deltat / nMessages
            tperbyte = tpermessage / messageLen
            bitpers = 1 / tperbyte * 8
            logging.warning(
                f"Time spent per message: {tpermessage} s, per byte: {tperbyte}, per bit: {1./bitpers}"
            )
            logging.warning(
                f"Message per second {1./tpermessage}, byte per second: {1./tperbyte}, bit per second: {bitpers}"
            )
            data_checker_finished.set()

        async def run_test(self):
            logging.info("Starting run_test")
            send_chan, recv_chan = trio.open_memory_channel(100)
            data_checker_finished = trio.Event()
            with trio.move_on_after(10) as cancel_scope:
                logging.info("About to open file...")
                async with await trio.open_file(self.dev_path, "br") as portr:
                    async with await trio.open_file(self.dev_path, "bw") as portw:
                        logging.debug("files opened")
                        async with trio.open_nursery() as nursery:
                            logging.debug("About to startup host")
                            host = Host(nursery, portr, portw, nRegisterBits)
                            logging.debug("Host started")
                            host.forward_received_s_messages_to(send_chan)
                            logging.debug("messages now forwarded to send_chan")
                            nursery.start_soon(
                                data_checker, self, recv_chan, data_checker_finished
                            )
                            await host.write_register(2, 1)  # set to counter mode
                            await host.start_streaming()
                            logging.debug(
                                "data_checker starting soon, waiting for it to finish"
                            )
                            await data_checker_finished.wait()
                            logging.debug("data_checker_finished")
                            await host.stop_streaming()
                            await host.write_register(
                                2, 0
                            )  # set back to default ADC mode
                            nursery.cancel_scope.cancel()
            self.assertTrue(data_checker_finished.is_set())

        trio.run(run_test, self)


import datetime
import os

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

#log level warning.
loglevel = 2 # 0 Info 1 Warning 2 Error 3 Important 4 Critical

def error(message):
    print(f"{bcolors.FAIL}[-]   {message}{bcolors.ENDC}")
    if loglevel <= 2:
        log(message, 2)

def important(message):
    print(f"{bcolors.UNDERLINE}[!]  {message}{bcolors.ENDC}")
    if loglevel <= 3:
        log(message, 3)

def warning(message):
    print(f"{bcolors.WARNING}[*]    {message}{bcolors.ENDC}")
    if loglevel <= 1:
        log(message, 1)

def success(message):
    print(f"{bcolors.OKGREEN}[+]    {message}{bcolors.ENDC}")
    if loglevel <= 0:
        log(message, 0)

def header(message):
    print(f"{bcolors.OKBLUE}{message}{bcolors.ENDC}")

def intrusionDetected(message):
    print(f"{bcolors.UNDERLINE}{bcolors.FAIL}[INTRUSION ALERT]  {message}{bcolors.ENDC}")
    log(message, 4)

def log(message, severity):

    try:
        os.mkdir('/var/log/IDS')
    except OSError:
        pass

    with open('/var/log/IDS/alert.log', 'a') as file:
        file.write('[{0}] Severity: {1}, {2}\n'.format(datetime.datetime.now(), severity, message))


from pathlib import Path
import pandas as pd
from prefect import flow, task
from prefect_gcp.cloud_storage import GcsBucket
from prefect_gcp import GcpCredentials

def extract_from_gcs(color: str, year: int, month: int) -> Path:
    """ Download trip data from GCS """
    gcs_path = f"data/{color}/{color}_tripdata_{year}-{month:02}.parquet"
    gcs_block = GcsBucket.load("dez-gcs")
    gcs_block.get_directory(from_path=gcs_path, local_path=f"./")
    return Path(f"./{gcs_path}")

@task()
def write_bq(df: pd.DataFrame) -> None:
    """Write DataFrame to BiqQuery"""
    gcp_credentials_block = GcpCredentials.load("dez-gcp-creds")

    df.to_gbq(
        destination_table="trips_data_all.rides",
        project_id="sage-nucleus-376020",
        credentials=gcp_credentials_block.get_credentials_from_service_account(),
        chunksize=500_000,
        if_exists="append"
    )

@flow(log_prints=False)
def etl_gcs_to_bq(months: list[int] = [1, 2], year: int = 2021, color: str = "yellow"):
    """Main ETL flow to lad data into Big Query"""
    total_rows = 0
    for month in months:
        path = extract_from_gcs(color=color, year=year, month=month)
        df = pd.read_parquet(path)
        total_rows += len(df)
        write_bq(df)
    print(f"Total number of rows processed: {total_rows}.")

if __name__ == "__main__":
    color = "yellow"
    months = [2,3]
    year = 2019
    etl_gcs_to_bq(months, year, color)


"""
Views for the course home page.
"""

from django.contrib.auth.decorators import login_required
from django.core.context_processors import csrf
from django.template.loader import render_to_string
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control
from django.views.decorators.csrf import ensure_csrf_cookie
from opaque_keys.edx.keys import CourseKey
from web_fragments.fragment import Fragment

from courseware.courses import get_course_info_section, get_course_with_access
from lms.djangoapps.courseware.views.views import CourseTabView
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from util.views import ensure_valid_course_key

from ..utils import get_course_outline_block_tree
from .course_dates import CourseDatesFragmentView
from .course_outline import CourseOutlineFragmentView
from .course_sock import CourseSockFragmentView
from .welcome_message import WelcomeMessageFragmentView

class CourseHomeView(CourseTabView):
    """
    The home page for a course.
    """
    @method_decorator(login_required)
    @method_decorator(ensure_csrf_cookie)
    @method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True))
    @method_decorator(ensure_valid_course_key)
    def get(self, request, course_id, **kwargs):
        """
        Displays the home page for the specified course.
        """
        return super(CourseHomeView, self).get(request, course_id, 'courseware', **kwargs)

    def render_to_fragment(self, request, course=None, tab=None, **kwargs):
        course_id = unicode(course.id)
        home_fragment_view = CourseHomeFragmentView()
        return home_fragment_view.render_to_fragment(request, course_id=course_id, **kwargs)

class CourseHomeFragmentView(EdxFragmentView):
    """
    A fragment to render the home page for a course.
    """

    def _get_resume_course_info(self, request, course_id):
        """
        Returns information relevant to resume course functionality.

        Returns a tuple: (has_visited_course, resume_course_url)
            has_visited_course: True if the user has ever visted the course, False otherwise.
            resume_course_url: The URL of the last accessed block if the user has visited the course,
                otherwise the URL of the course root.

        """

        def get_last_accessed_block(block):
            """
            Gets the deepest block marked as 'last_accessed'.
            """
            if not block['last_accessed']:
                return None
            if not block.get('children'):
                return block
            for child in block['children']:
                last_accessed_block = get_last_accessed_block(child)
                if last_accessed_block:
                    return last_accessed_block
            return block

        course_outline_root_block = get_course_outline_block_tree(request, course_id)
        last_accessed_block = get_last_accessed_block(course_outline_root_block)
        has_visited_course = bool(last_accessed_block)
        if last_accessed_block:
            resume_course_url = last_accessed_block['lms_web_url']
        else:
            resume_course_url = course_outline_root_block['lms_web_url']

        return (has_visited_course, resume_course_url)

    def render_to_fragment(self, request, course_id=None, **kwargs):
        """
        Renders the course's home page as a fragment.
        """
        course_key = CourseKey.from_string(course_id)

        # Render the outline as a fragment
        outline_fragment = CourseOutlineFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)

        # Get resume course information
        has_visited_course, resume_course_url = self._get_resume_course_info(request, course_id)

        # Render the welcome message as a fragment
        welcome_message_fragment = WelcomeMessageFragmentView().render_to_fragment(
            request, course_id=course_id, **kwargs
        )

        # Render the course dates as a fragment
        dates_fragment = CourseDatesFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)

        # TODO: Use get_course_overview_with_access and blocks api
        course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)

        # Render the verification sock as a fragment
        course_sock_fragment = CourseSockFragmentView().render_to_fragment(request, course=course, **kwargs)

        # Get the handouts
        handouts_html = get_course_info_section(request, request.user, course, 'handouts')

        # Render the course home fragment
        context = {
            'request': request,
            'csrf': csrf(request)['csrf_token'],
            'course': course,
            'course_key': course_key,
            'outline_fragment': outline_fragment,
            'handouts_html': handouts_html,
            'has_visited_course': has_visited_course,
            'resume_course_url': resume_course_url,
            'dates_fragment': dates_fragment,
            'welcome_message_fragment': welcome_message_fragment,
            'course_sock_fragment': course_sock_fragment,
            'disable_courseware_js': True,
            'uses_pattern_library': True,
        }
        html = render_to_string('course_experience/course-home-fragment.html', context)
        return Fragment(html)


from collections import defaultdict
from itertools import permutations
def solution(A):
    if len(A) > 0:
        digitSum = defaultdict(list)
        for number in A:
            tmpSum = 0
            for digit in str(number):
               tmpSum += int(digit)

            digitSum[tmpSum].append(number)
        result = -1
        for key,value in digitSum.items():
            if len(value) >=2:
                value = sorted(value , reverse=True)
                result = max(result,value[0]+value[1])
        return result
    else:
        return -1

A = [51,71,17,42]
print(solution(A))


import sys
from collections import deque
sys.stdin = open("input.txt", "r")
input = sys.stdin.readline

def bfs(x, y):
    dx = [-1, -1, 0, 1, 1, 1, 0, -1]
    dy = [0, 1, 1, 1, 0, -1, -1, -1]

    dq = deque()
    dq.append((x, y, 0))
    check_set = set()
    check_set.add((x, y))

    while dq:
        t = dq.popleft()
        if board[t[0]][t[1]] == 1:
            return t[2]
        for h in range(8):
            xx = t[0] + dx[h]
            yy = t[1] + dy[h]
            if 0 <= xx < n and 0 <= yy < m and (xx, yy) not in check_set:
                dq.append((xx, yy, t[2] + 1))
                check_set.add((xx, yy))

if __name__ == "__main__":
    n, m = map(int, input().split())
    board = [list(map(int, input().split())) for _ in range(n)]
    max_cnt = 0

    for i in range(n):
        for j in range(m):
            if board[i][j] != 1:
                max_cnt = max(max_cnt, bfs(i, j))
    print(max_cnt)


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

# In[1]:

import os
import time
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
import torch
import torchvision
import torch.nn as nn
import torch.nn.functional as F
from torchvision.utils import make_grid
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import TensorDataset, DataLoader
from torch.utils.data.dataloader import DataLoader
import torch.optim as optim
from sklearn.metrics import confusion_matrix

from google_drive_downloader import GoogleDriveDownloader as gdd

# https://drive.google.com/file/d/1vQLLGjVa2HAcxUba2o-C1SLpMAlPyC9u/view?usp=sharing

def test_func(X):
    gdd.download_file_from_google_drive( file_id='1vQLLGjVa2HAcxUba2o-C1SLpMAlPyC9u',
                                    dest_path='../trained-model.ckpt',
                                    unzip=False, showsize = True)
    predicted_labels=[]
    X=X.reshape(X.shape[0],1,150,150)
    X=X/255
    device=torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    class ConvolutionalNetwork(nn.Module):
        def __init__(self):
            super().__init__()
            self.conv1=nn.Conv2d(1, 6, (3,3), 1)
            self.conv2=nn.Conv2d(6, 16, (3,3), 1)
            self.conv3=nn.Conv2d(16, 32, (3,3), 1)
            self.conv4=nn.Conv2d(32, 96, (3,3), 1)
    #         self.conv1=nn.Conv2d(1, 6, (3,3), 1)
    #         self.conv2=nn.Conv2d(6, 16, (3,3), 1)
    #         self.conv3=nn.Conv2d(16, 30, (3,3), 1)
    #         self.conv4=nn.Conv2d(30, 48, (3,3), 1)
            self.fc1=nn.Linear(7*7*96, 84)
            self.fc2=nn.Linear(84, 84)
            self.fc3=nn.Linear(84,84)
            self.fc4=nn.Linear(84,25)

        def forward(self, X):
            X=F.relu(self.conv1(X))
            X=F.max_pool2d(X, 2, 2)
            X=F.relu(self.conv2(X))
            X=F.max_pool2d(X, 2, 2)
            X=F.relu(self.conv3(X))
            X=F.max_pool2d(X, 2, 2)
            X=F.relu(self.conv4(X))
            X=F.max_pool2d(X, 2, 2)
            X=X.view(-1, 7*7*96)
            X=F.relu(self.fc1(X))
            X=F.relu(self.fc2(X))
            X=F.relu(self.fc3(X))
            X=self.fc4(X)
            return F.log_softmax(X, dim=1)
    # create your dataloader
    dataloader=DataLoader(torch.Tensor(X),batch_size=10, shuffle=False)
    model=ConvolutionalNetwork()
    model.load_state_dict(torch.load('../trained-model.ckpt'))
    model.eval()
    with torch.no_grad():
        for images in dataloader:
            #print(images)
            images=images.to(device)
            outputs=model(images)
            _, predicted=torch.max(outputs.data, 1)
            #print(predicted)
            predicted_labels.append(predicted.tolist())
    #print(predicted_labels)
    predicted_labels=[item for sublist in predicted_labels for item in sublist]
        #     true_values=[item for sublist in true_values for item in sublist]
    return predicted_labels

# Now load the labels here for checking the accuracy of the test data.
test_images=np.load('Path for Test Images')
predicted_val=test_func(test_images)
labels=np.load('Path for Test Labels').T
true_val=labels
correct_count=0
for i in range(len(true_val)):
      if(predicted_val[i]==true_val[i]):
             correct_count += 1
accuracy=(correct_count / len(true_val))*100
print('Accuracy on Test Data = ', accuracy)

# In[ ]:


import functools
import warnings
import numpy as np
from .base import Decomposition, svd
from ...core.structures import Tensor, TensorCPD, residual_tensor
from ...core.operations import khatri_rao, hadamard

# TODO: Need to add option of sorting vectors in the factor matrices and making them sign invariant
class BaseCPD(Decomposition):

    def __init__(self, init, max_iter, epsilon, tol, random_state, verbose):
        super(BaseCPD, self).__init__()
        self.init = init
        self.max_iter = max_iter
        self.epsilon = epsilon
        self.tol = tol
        self.random_state = random_state
        self.verbose = verbose

    def copy(self):
        """ Copy of the Decomposition as a new object """
        new_object = super(BaseCPD, self).copy()
        return new_object

    @property
    def name(self):
        """ Name of the decomposition

        Returns
        -------
        decomposition_name : str
        """
        decomposition_name = super(BaseCPD, self).name
        return decomposition_name

    def decompose(self, tensor, rank, keep_meta):
        raise NotImplementedError('Not implemented in base (BaseCPD) class')

    @property
    def converged(self):
        """ Checks convergence

        Returns
        -------
        is_converged : bool
        """
        try:  # This insures that the cost has been computed at least twice without checking number of iterations
            is_converged = abs(self.cost[-2] - self.cost[-1]) <= self.tol
        except IndexError:
            is_converged = False
        return is_converged

    def _init_fmat(self, tensor, rank):
        """ Initialisation of factor matrices

        Parameters
        ----------
        tensor : Tensor
            Multidimensional data to be decomposed
        rank : tuple
            Should be of shape (R,1), where R is the desired tensor rank. It should be passed as tuple for consistency.

        Returns
        -------
        fmat : list[np.ndarray]
            List of factor matrices
        """
        self.cost = []  # Reset cost every time when method decompose is called
        t_rank = rank[0]
        fmat = [np.array([])] * tensor.order
        # Check if all dimensions are greater then kryskal rank
        dim_check = (np.array(tensor.shape) >= t_rank).sum() == tensor.order
        if dim_check:
            if self.init is 'svd':
                for mode in range(tensor.order):
                    # TODO: don't really like this implementation
                    fmat[mode], _, _ = svd(tensor.unfold(mode, inplace=False).data, t_rank)
            elif self.init is 'random':
                fmat = [np.random.randn(mode_size, t_rank) for mode_size in tensor.shape]
            else:
                raise NotImplementedError('The given initialization is not available')
        else:
            fmat = [np.random.randn(mode_size, t_rank) for mode_size in tensor.shape]
            if self.verbose and self.init != 'random':
                warnings.warn(
                    "Specified rank value is greater then one of the dimensions of a tensor ({} > {}).\n"
                    "Factor matrices have been initialized randomly.".format(t_rank, tensor.shape), RuntimeWarning
                )
        return fmat

    def plot(self):
        raise NotImplementedError('Not implemented in base (BaseCPD) class')

class CPD(BaseCPD):
    """ Canonical Polyadic Decomposition.

    Computed via alternating least squares (ALS)

    Parameters
    ----------
    init : str
        Type of factor matrix initialisation. Available options are `svd` and `random`
    max_iter : int
        Maximum number of iteration
    epsilon : float
        Threshold for the relative error of approximation.
    tol : float
        Threshold for convergence of factor matrices
    random_state : int
    verbose : bool
        If True, enable verbose output

    Attributes
    ----------
    cost : list
        A list of relative approximation errors at each iteration of the algorithm.
    """

    def __init__(self, init='svd', max_iter=50, epsilon=10e-3, tol=10e-5,
                 random_state=None, verbose=False) -> None:
        super(CPD, self).__init__(init=init,
                                  max_iter=max_iter,
                                  epsilon=epsilon,
                                  tol=tol,
                                  random_state=random_state,
                                  verbose=verbose)
        self.cost = []

    def copy(self):
        """ Copy of the CPD algorithm as a new object """
        new_object = super(CPD, self).copy()
        new_object.cost = []
        return new_object

    @property
    def name(self):
        """ Name of the decomposition

        Returns
        -------
        decomposition_name : str
        """
        decomposition_name = super(CPD, self).name
        return decomposition_name

    def decompose(self, tensor, rank, keep_meta=0, kr_reverse=False):
        """ Performs CPD-ALS on the `tensor` with respect to the specified `rank`

        Parameters
        ----------
        tensor : Tensor
            Multidimensional data to be decomposed
        rank : tuple
            Desired Kryskal rank for the given `tensor`. Should contain only one value.
            If it is greater then any of dimensions then random initialisation is used
        keep_meta : int
            Keep meta information about modes of the given `tensor`.
            0 - the output will have default values for the meta data
            1 - keep only mode names
            2 - keep mode names and indices
        kr_reverse : bool

        Returns
        -------
        tensor_cpd : TensorCPD
            CP representation of the `tensor`

        Notes
        -----
        khatri-rao product should be of matrices in reversed order. But this will duplicate original data (e.g. images)
        Probably this has something to do with data ordering in Python and how it relates to kr product
        """
        if not isinstance(tensor, Tensor):
            raise TypeError("Parameter `tensor` should be an object of `Tensor` class!")
        if not isinstance(rank, tuple):
            raise TypeError("Parameter `rank` should be passed as a tuple!")
        if len(rank) != 1:
            raise ValueError("Parameter `rank` should be tuple with only one value!")

        tensor_cpd = None
        fmat = self._init_fmat(tensor, rank)
        core_values = np.repeat(np.array([1]), rank)
        norm = tensor.frob_norm
        for n_iter in range(self.max_iter):

            # Update factor matrices
            for mode in range(tensor.order):
                kr_result = khatri_rao(fmat, skip_matrix=mode, reverse=kr_reverse)
                hadamard_result = hadamard([np.dot(mat.T, mat) for i, mat in enumerate(fmat) if i != mode])
                # Do consecutive multiplication of np.ndarray
                update = functools.reduce(np.dot, [tensor.unfold(mode, inplace=False).data,
                                                   kr_result,
                                                   np.linalg.pinv(hadamard_result)])
                fmat[mode] = update

            # Update cost
            tensor_cpd = TensorCPD(fmat=fmat, core_values=core_values)
            residual = residual_tensor(tensor, tensor_cpd)
            self.cost.append(abs(residual.frob_norm / norm))
            if self.verbose:
                print('Iter {}: relative error of approximation = {}'.format(n_iter, self.cost[-1]))

            # Check termination conditions
            if self.cost[-1] <= self.epsilon:
                if self.verbose:
                    print('Relative error of approximation has reached the acceptable level: {}'.format(self.cost[-1]))
                break
            if self.converged:
                if self.verbose:
                    print('Converged in {} iteration(s)'.format(len(self.cost)))
                break
        if self.verbose and not self.converged and self.cost[-1] > self.epsilon:
            print('Maximum number of iterations ({}) has been reached. '
                  'Variation = {}'.format(self.max_iter, abs(self.cost[-2] - self.cost[-1])))

        if keep_meta == 1:
            mode_names = {i: mode.name for i, mode in enumerate(tensor.modes)}
            tensor_cpd.set_mode_names(mode_names=mode_names)
        elif keep_meta == 2:
            tensor_cpd.copy_modes(tensor)
        else:
            pass
        return tensor_cpd

    @property
    def converged(self):
        """ Checks convergence of the CPD-ALS algorithm.

        Returns
        -------
        bool
        """
        is_converged = super(CPD, self).converged
        return is_converged

    def _init_fmat(self, tensor, rank):
        fmat = super(CPD, self)._init_fmat(tensor=tensor,
                                           rank=rank)
        return fmat

    def plot(self):
        print('At the moment, `plot()` is not implemented for the {}'.format(self.name))


import pytest
import time
from selenium import webdriver
import chromedriver_binary
from core.MainPage.page import MainPage

@pytest.mark.ui
class TestLoad:

    name = "Bulbasaur"

    def setup(self):
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument("--no-sandbox")
        chrome_options.add_argument("--headless")
        self.driver = webdriver.Chrome(chrome_options=chrome_options)
        self.driver.get("https://egarciasec.github.io/pdex/")

    def teardown(self):
        self.driver.quit()

    def test_simple_load(self):
        driver = self.driver
        MainPage(driver).assert_page_title()

    def test_pokemon_search(self):
        driver = self.driver
        MainPage(driver).search(self.name)
        for _ in range(0, 3):
            try:
                MainPage(driver).assert_expected_name("#1 Bulbasaur")
                break
            except Exception:
                time.sleep(1)

    def test_pokemon_image(self):
        driver = self.driver
        MainPage(driver).search(self.name)
        for _ in range(0, 3):
            try:
                MainPage(driver).assert_pokemon_image()
                break
            except Exception:
                time.sleep(1)


from appMedica.models import Cita
from django import forms
from django.forms import ModelForm, Form
from .models import Boleta

class DateInput(forms.DateInput):
    input_type = 'date'

class TimeInput(forms.TimeInput):
    input_type = 'time'

class registroCitaFormSec(ModelForm):
    class Meta:
        model = Cita
        fields = [
            "fechaCita",
            "horaInicioCita",
            "duracionCita",
            "pacienteCita",
            "medicoCita"
        ]
        widgets = {
            'fechaCita': DateInput(),
            'horaInicioCita': TimeInput()
        }

class BoletaForm(ModelForm):
    comisionDelMedico = forms.IntegerField(max_value=100)
    class Meta:
        model = Boleta
        fields = [
            "cita",
            "valorDeLaCita",
            "comisionDelMedico"
        ]


# coding=utf-8
import requests
from bs4 import BeautifulSoup
import json
import os
import os.path
import re
def get_special(time_messege):
    print(time_messege)
    time = re.findall('\d',time_messege)
    if(len(time) == 2):
        left_time = int(time[0])
        right_time = int(time[1])
    elif(len(time) == 3):
        left_time = int(time[0])
        right_time = int(time[1]+time[2])
    elif(len(time) == 4):
        left_time = int(time[0]+time[1])
        right_time = int(time[2]+time[3])
    else:
        special = ["error"]
        return special
    special = [i for i in range(1,left_time)]
    if(time_messege[-2] == "单"):
        for i in range(left_time,right_time+1):
            if i%2 == 0:
                special.append(i)
    if(time_messege[-2] == "双"):
        for i in range(left_time,right_time+1):
            if i%2 == 1:
                special.append(i)
    special = special+[i for i in range(right_time+1,16)]
    return special
week_day = ['Mon','Tue','Wed','Thu','Fri']

file_rootdir = 'file/'
lists = os.listdir(file_rootdir)
for eachstation in lists:
    station_dir = os.path.join(file_rootdir,eachstation)
    html_dir = os.path.join(station_dir,"class_messege")
    list = os.listdir(html_dir)
    for eachone in list:
        path = os.path.join(html_dir, eachone)
        class_file = open(path, "r", encoding="utf-8")
        class_file = class_file.read()
        json_path = os.path.join(station_dir,"json",eachone[0]+".json")
        json_file = open(json_path, "a", encoding="utf-8")
        day = week_day[int(eachone[0])-1]
        data = [{"_id":day}]
        soup = BeautifulSoup(class_file,'lxml')
        tabel = soup.find('table',"portlet-table")
        class_rooms = tabel.find_all('tr')
        for eachone in class_rooms[2:]:
           all_mesege = eachone.find_all('td')
           class_room = all_mesege[0].text[-4:].strip()
           data[0][class_room] = []
           time = 1
           flag = 0
           for class_messege in all_mesege[1:]:
               list = {}
               #去除空白字符
               if(len(class_messege.text.strip()) == 0):
                   if(flag):
                       flag = 0
                       continue
                   if(time > 9):
                       continue
                   list['flag'] = True
                   if(time == 9):
                       list['time'] = "9-11"
                   else:
                       list['time'] = str(time)+"-"+str(time+1)
                   list['special'] = []
                   data[0][class_room].append(list)
                   time += 2
                   flag = 1
                   continue
               messege = re.findall('[(].*[)]',class_messege.text)[0]
               time_messege = re.findall('\d-\d.*周',messege)[0][:-1]
               special = get_special(time_messege)
               timing_messege = re.findall('第.*节',messege)[0][1:-1]
               left_time = timing_messege[0]
               right_time = timing_messege[2:]
               time = int(right_time)+1
               if(left_time == '9'):
                   real_time = "9-11"
               else:
                   real_time = str(left_time)+"-"+str(right_time)
               list['flag'] = False
               list['time'] = real_time
               list['special'] = special
               data[0][class_room].append(list)
        json_file.write(json.dumps(data[0], indent=4, separators=(',', ': ')))
        json_file.close()


import cv2
import argparse

# RgbVideo_address = "/media/hkuit164/Backup/rgb.mp4"
# thermalVideo_address = "/media/hkuit164/Backup/thermal.mp4"

def parse_args():
    parser = argparse.ArgumentParser(description='RtspDataCollection')
    # general
    parser.add_argument('--folder',
                        help='folder name',
                        required=True,
                        type=str)

    parser.add_argument('--name',
                        help="file name",
                        required=True,
                        type=str)
    args = parser.parse_args()
    return args

args = parse_args()

RgbVideo_address = args.folder + args.name + "_rgb.mp4"
thermalVideo_address = args.folder + args.name + "_thermal.mp4"

if __name__ == '__main__':

    # 開啟 RTSP 串流
    RgbVideoCap = cv2.VideoCapture('rtsp://admin:fyp202020@192.168.8.111:554/Streaming/Channels/101/?transportmode=unicast --input-rtsp-latency=0')
    TherVideoCap = cv2.VideoCapture('rtsp://admin:fyp202020@192.168.8.111:554/Streaming/Channels/201/?transportmode=unicast --input-rtsp-latency=0')

    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    fps = 15

    save_size = (1080,720)
    RgbVideo = cv2.VideoWriter(RgbVideo_address, fourcc, fps, save_size)
    thermalVideo = cv2.VideoWriter(thermalVideo_address, fourcc, fps, save_size)
    #thermalVideo.set(cv2.CAP_PROP_BUFFERSIZE,0)
    #concatVideo = cv2.VideoWriter("/media/hkuit164/Backup/concatVideo.mp4", fourcc, fps, save_size)
    # 建立視窗
    cv2.namedWindow('Rgb_display', cv2.WINDOW_AUTOSIZE)
    cv2.namedWindow('Thermal_display', cv2.WINDOW_AUTOSIZE)

    for i in range(30):
        ret, Rgbimage = RgbVideoCap.read()

    while True:
        # 從 RTSP 串流讀取一張影像
        ret, Rgbimage = RgbVideoCap.read()
        ret, Therimage = TherVideoCap.read()
        if ret:
            # 顯示影像
            #im_v = cv2.vconcat([Rgbimage, Therimage])
            cv2.imshow('Rgb_display', cv2.resize(Rgbimage, (720, 540)))
            RgbVideo.write(cv2.resize(Rgbimage, save_size))
            #concatVideo.write(cv2.resize(im_v, (1080, 720)))
            cv2.moveWindow('Rgb_display', 0,0)
            cv2.imshow('Thermal_display', cv2.resize(Therimage,  (720, 540)))
            thermalVideo.write(cv2.resize(Therimage, save_size))
            cv2.moveWindow('Thermal_display', 740,0)
            key = cv2.waitKey(1)
        if key == ord('q'):
            # 若沒有影像跳出迴圈
            break

    # 釋放資源
    RgbVideoCap.release()
    TherVideoCap.release()

    # 關閉所有 OpenCV 視窗
    cv2.destroyAllWindows()


#!/usr/bin/python

import os
import sys
import dbus
import dbus.service
import time
import json
import bluetooth
import SocketServer
from bluetooth import *
from SimpleHTTPServer import SimpleHTTPRequestHandler
from dbus.mainloop.glib import DBusGMainLoop

class Hid:
    MY_ADDRESS="B8:27:EB:60:2E:1E"
    MY_DEV_NAME="ARemote_Controller"

    P_CTRL =17
    P_INTR =19
    PROFILE_DBUS_PATH="/bluez/acontrol/bthid_profile"
    SDP_RECORD_PATH = sys.path[0] + "/sdp_record.xml"
    UUID="00001124-0000-1000-8000-00805f9b34fb"
    CONTROL_CMDS=[
            0x10, # previous track
            0x40, # next track
            0x20, # play / pause
            ]
    def read_sdp_service_record(self):
        try:
            fh = open(Hid.SDP_RECORD_PATH, "r")
        except:
            sys.exit("SDP record ERROR!")
        return fh.read()

    def close(self):
        self.ccontrol.close()
        self.cinterrupt.close()

    def send_cmd(self, key):
        self.input_report[2] = self.CONTROL_CMDS[key]
        self.cinterrupt.send(str(self.input_report));

    def release_cmd(self):
        self.input_report[2] = 0x00
        self.cinterrupt.send(str(self.input_report));

    def __init__(self):
        self.input_report=bytearray([
                0xa1,
                0x03,
                0x00,
                0x00,
                0x00])
        os.system("hciconfig hcio class 0x00250c")
        os.system("hciconfig hcio name " + self.MY_DEV_NAME)
        os.system("hciconfig hcio piscan")

        service_record=self.read_sdp_service_record()

        opts = {
            "ServiceRecord": service_record,
            "Role":"server",
            "RequireAuthentication": False,
            "RequireAuthorization": False
        }

        bus = dbus.SystemBus()
        manager = dbus.Interface(bus.get_object("org.bluez","/org/bluez"), "org.bluez.ProfileManager1")

        profile = dbus.service.Object(bus, Hid.PROFILE_DBUS_PATH)

        manager.RegisterProfile(Hid.PROFILE_DBUS_PATH, Hid.UUID, opts)

        bus_name = dbus.service.BusName("org.acontrol.bthidservice", bus=dbus.SystemBus())
        dbus.service.Object(bus_name, "/org/acontrol/bthidservice")

        self.scontrol=BluetoothSocket(L2CAP)
        self.sinterrupt=BluetoothSocket(L2CAP)

        self.scontrol.bind((self.MY_ADDRESS, self.P_CTRL))
        self.sinterrupt.bind((self.MY_ADDRESS, self.P_INTR))

        self.scontrol.listen(1)
        self.sinterrupt.listen(1)

        self.ccontrol,cinfo = self.scontrol.accept()
        self.cinterrupt,cinfo = self.sinterrupt.accept()

class JsonResponseHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        content_len = int(self.headers.get("content-length"))
        requestBody = self.rfile.read(content_len).decode('UTF-8')
        jsonData = json.loads(requestBody)
        self.send_response(200)
        self.send_header("Content-type", "Application/json")
        self.end_headers()
        hid.send_cmd(jsonData["control"])
        time.sleep(0.01)
        hid.release_cmd()

if __name__ == "__main__":
    try:
        DBusGMainLoop(set_as_default=True)
        hid = Hid()
        server = SocketServer.TCPServer(("", 8000), JsonResponseHandler)
        server.serve_forever()
    except KeyboardInterrupt as ex:
        server.server_close()
        hid.close()
    except BluetoothError as ex:
        print("Bluetooth ERROR!")


import cv2
import time
import os
import numpy as np
import hand_tracking_module as htm

red=(0,25,225)
green=(0,217,0)
blue=(225,128,0)
black=(10,10,10)
white=(255,255,255)

folderpath="paint"
mylist=os.listdir(folderpath)
overlay=[]
for im in mylist:
	image=cv2.imread(f'{folderpath}/{im}')
	overlay.append(image)

header=overlay[0]

cap=cv2.VideoCapture(0)
detector=htm.HandDetector(detectionCon=0.75)

color=red

brushthickness=15
eraserthickness=25
xp,yp=0,0
imgCanvas=np.zeros((480,640,3),np.uint8)

while True:
	success,img=cap.read()
	w=int((img.shape[0]*960)/img.shape[1])
	img=cv2.resize(img,(960,w))
	imgCanvas=cv2.resize(imgCanvas,(960,w))
	#flip image
	img=cv2.flip(img,1)

	img=detector.findHands(img)
	lmlist=detector.findPosition(img,draw=False)

	if len(lmlist)!=0:
		x1,y1= lmlist[8][1:]
		x2,y2= lmlist[12][1:]
		fingers=detector.fingersUp()

		if fingers[1] and fingers[2]:
			xp,yp=x1,y1
			if all(x>=1 for x in fingers)==False:
				cv2.rectangle(img, (x1,y1),(x2,y2),color,cv2.FILLED)

			colors=[red,green,blue,black,white]

			for count,c in enumerate(colors):
				if y1<82:
					if count*180<x1<(count+1)*180:
						header=overlay[count]
						color=c

		if fingers[1] and fingers[2]==False:
			if color==white:
				cv2.circle(img,(x1,y1),25,color,2)
				cv2.line(imgCanvas,(xp,yp),(x1,y1),(0,0,0),eraserthickness)

			else:
				cv2.circle(img,(x1,y1),15,color,cv2.FILLED)
				cv2.line(img,(xp,yp),(x1,y1),color,brushthickness)
				cv2.line(imgCanvas,(xp,yp),(x1,y1),color,brushthickness)
			xp,yp=x1,y1
		if all(x>=1 for x in fingers):
			imgCanvas=np.zeros((480,640,3),np.uint8)
			imgCanvas=cv2.resize(imgCanvas,(960,w))

	# adding images img and imgCanvas ->>
	imgGray=cv2.cvtColor(imgCanvas, cv2.COLOR_BGR2GRAY)
	_,imgInv=cv2.threshold(imgGray,5,255,cv2.THRESH_BINARY_INV)
	imgInv= cv2.cvtColor(imgInv,cv2.COLOR_GRAY2BGR)
	img=cv2.bitwise_and(img, imgInv)
	img=cv2.bitwise_or(img, imgCanvas)

	img[0:82,0:]=header
	cv2.imshow('image',img)
	if cv2.waitKey(1)==27:
		break
cap.release()


import argparse
import cv2
import numpy as np
import yaml

parser = argparse.ArgumentParser()
parser.add_argument('file', help='video file to be scanned')
parser.add_argument('-l', '--loglevel', dest='loglevel', action='store', metavar='L',
    default = "info", help = 'specify log level, defalt to INFO')
args = parser.parse_args()

cap = cv2.VideoCapture(args.file)
video_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)   # float
video_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # float
fps = cap.get(cv2.CAP_PROP_FPS)

resize_width = 480
resize_height = 480

if resize_width/video_width <= resize_height/video_height:
    resize_factor = resize_width/video_width
    resize_height = int(video_height * resize_factor)
else:
    resize_factor = resize_height/video_height
    resize_width = int(video_width * resize_factor)

frame_count = 0
grid_size = 24

def mouse_event_handler(event, x, y, flags, param):
    global start_x, start_y
    if event == cv2.EVENT_LBUTTONDOWN:
        start_x = x
        start_y = y

while(1):
    ret, frame = cap.read()

    if not ret:
        break

    frame_count += 1

    img_resized = cv2.resize(frame, (0,0), fx=resize_factor, fy=resize_factor)

    debug_info = 'frame: %d' % (frame_count)
    cv2.putText(img_resized, debug_info, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 0, 255))

    # output grid
    for x in xrange(grid_size, resize_width, grid_size):
        pt1 = (x, 0)
        pt2 = (x, resize_height)
        cv2.line(img_resized, pt1, pt2, (150, 0, 150))
    for y in xrange(grid_size, resize_height, grid_size):
        pt1 = (0, y)
        pt2 = (resize_width, y)
        cv2.line(img_resized, pt1, pt2, (150, 0, 150))

    cv2.imshow('frame', img_resized)
    key = cv2.waitKey(100000) & 0xff
    if key == 27:
        break


import re
import string

import torch
from torch.utils.data import Dataset, DataLoader

vocab = string.ascii_lowercase + ' .'

def one_hot(s: str):
    """
    Converts a string into a one-hot encoding
    :param s: a string with characters in vocab (all other characters will be ignored!)
    :return: a once hot encoding Tensor r (len(vocab), len(s)), with r[j, i] = (s[i] == vocab[j])
    """
    import numpy as np
    if len(s) == 0:
        return torch.zeros((len(vocab), 0))
    return torch.as_tensor(np.array(list(s.lower()))[None, :] == np.array(list(vocab))[:, None]).float()

class SpeechDataset(Dataset):
    """
    Creates a dataset of strings from a text file.
    All strings will be of length max_len and padded with '.' if needed.

    By default this dataset will return a string, this string is not directly readable by pytorch.
    Use transform (e.g. one_hot) to convert the string into a Tensor.
    """

    def __init__(self, dataset_path, transform=None, max_len=250):
        with open(dataset_path) as file:
            Data = file.read()

        #code below seems to just make text lower case, remove spacing after period.  Tokenize?
        Data = Data.lower()
        reg = re.compile('[^%s]' % vocab)
        period = re.compile(r'[ .]*\.[ .]*')
        space = re.compile(r' +')
        sentence = re.compile(r'[^.]*\.')
        self.data = space.sub(' ',period.sub('.',reg.sub('', Data)))  #removes spacing after period?

        #print (f'the size of data is {len(self.data)}')
        if max_len is None:
            self.range = [(m.start(), m.end()) for m in sentence.finditer(self.data)]
        else:
            self.range = [(m.start(), m.start()+max_len) for m in sentence.finditer(self.data)]
            self.data += self.data[:max_len]

        if transform is not None:

            self.data = transform(self.data)

    def __len__(self):
        return len(self.range)

    def __getitem__(self, idx):
        s, e = self.range[idx]
        #print (f'self range is {self.range[idx]}')
        #print (f'index is {idx}, s is {s}, and e is {e}')
        #print (f'self.range[idx] is {self.range[idx]}, and e-s is {e-s}')
        #index is 752, s is 79351, and e is 79418
        if isinstance(self.data, str):
            #print (f'Based on above numbers, returning self.data[s:e]: {self.data[s:e]} ')
            return self.data[s:e]        #if it's a string, return s to e substring only
        #print ("NOT A STRING")
        #print (f'returning self.data[:, s:e]  : {self.data[:, s:e].shape}')
        #shape of self.data[:, s:e] is ([28, s-e])
        return self.data[:, s:e]   #how to randomize this?

def load_data(dataset_path, num_workers=0, batch_size=32, **kwargs):
    dataset = SpeechDataset(dataset_path, **kwargs)
    print("load_data()------->LOADED DATASET SANTOS, this one below:")
    print(dataset_path)
    return DataLoader(dataset, num_workers=num_workers, batch_size=batch_size, shuffle=True, drop_last=True)

if __name__ == "__main__":
    print ("Starting execution of utils.py")

    """
    data = SpeechDataset('data/valid.txt', max_len=None)
    print('Dataset size BEFORE TRANSFORM is ', len(data))

    print (f'data[0] is {data[0]}')
    print (f'data[1] is {data[1]}')  #is i did not know mr.
    print (f'data[2] is {data[2]}')  #is cronkite personally.
    print (f'data[1][x] is {data[1][14]}')
    print (f'data[2][x] is {data[2][15]}')

    print (f'data[0] size is {len(data[0])}')
    print (f'data[1] size is {len(data[1])}')  #data[1] size is 18
    print (f'data[2] size is {len(data[2])}')  #data[2] size is 20

    #for i in range(min(len(data), 10)):
     #   print(data[i])

    print("-------------------------------")

    #print("From main()------>tranforming data to one hot now")

    data = SpeechDataset('data/valid.txt', transform=one_hot, max_len=None)

    print (f'data[0] size is {data[0].shape}')
    print (f'data[1] size is {data[1].shape}')
    print (f'data[2] size is {data[2].shape}')

    print('TRANSFORMED Dataset size ', len(data))  #856
    #print('TRANSFORMED Dataset shape ', data.dtype)

    #for i in range(min(len(data), 3)):
     #   print(data[i])

     """

    print("--------------------------------------------------------------------")
    print ("USING THE LOADER NOW")
    train_data = load_data('data/train.txt',  transform=one_hot)

    #train_data = load_data('data/valid.txt',  max_len=None)
    #Transform did not work, raised stack exception: load_data('data/valid.txt',  transform=one_hot, max_len=None)
    for s in train_data:
      print (s.shape)#torch.Size([32, 28, 250])


import base64
import time

# Function that decodes the bytes of payload from the wearable device
def decodeMACPayload(payload):
    # Value of MAC Payload in hex format
    mac_payload = base64.b64decode(payload).hex()

    # Get the integer part and the decimal part of the air temperature from the payload
    integer_temperature = int(str(int(mac_payload[-8:-4], 16))[:2])
    decimal_temperature = int(str(int(mac_payload[-8:-4], 16))[2:])

    # Determine the value of air temperature
    air_temperature = integer_temperature + 0.01*decimal_temperature

    # Get the integer part and the decimal part of the relative humidity from the payload
    integer_humidity = int(str(int(mac_payload[-4:], 16))[:2])
    decimal_humidity = int(str(int(mac_payload[-4:], 16))[2:])

    # Determine the value of relative humidity
    relative_humidity = integer_humidity + 0.01*decimal_humidity

    # Value of total energy expenditure in kCal
    decimal_energy_exp = int(mac_payload[34:42], 16) * 0.1

    # Get the value of VOC index from the payload
    voc_index = int(mac_payload[-16:-12], 16)

    # Get the value of current timestamp in UNIX format
    unix_timestamp = int(time.time())

    return [air_temperature, relative_humidity, voc_index, unix_timestamp, decimal_energy_exp]


#########################
# DESARROLLADOR
# RMPG - LUIS ANGEL VALLEJO PEREZ
#########################
import sys
import os
import shutil
from resources import *
from PyQt5 import  *
from PyQt5.QtCore import QPropertyAnimation, Qt
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QPixmap, QMouseEvent
from VPrincipal import *
# comment importamos concesionarios
from Reports_Logic.Rio_Bravo.Home_KWRB import *
from Reports_Logic.KenworthEste.Home_KWESTE import *
from Reports_Logic.KREI.Home_KREI import *
from Reports_Logic.Kenworth_Sonora.Home_KWSonora import *
#------------
from datetime import *
import webbrowser

class my_app(QMainWindow, Variables):
    def __init__(self):
        super(my_app, self).__init__()
        self.ui = Ui_VPrincipal()
        self.ui.setupUi(self)
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowTitle("Menu de Sucursales")
        # self.ui.centralwidget.setStyleSheet("background-color:rgb(255, 255, 255);")
        self.ui.imgPrincipalMenu.setPixmap(QPixmap(":/Source/LOGO_KREI.png"))
        self.setWindowIcon(QIcon(":/Source/LOGO_KREI_3.ico"))
        self.ui.btc_btc_cerrar.setIcon(QIcon(":Source/Icon_Close.png"))
        self.ui.btc_btc_minimizar.setIcon(QIcon(":Source/Icon_Minimize.png"))
        self.ui.panel_encabezado.setStyleSheet("margin-top:5px;")
        self.ui.btn_btn_kwrb.clicked.connect(self.VentanaRioBravo)
        self.ui.btn_btn_kweste.clicked.connect(self.VentanaKWESTE)
        self.ui.btn_btn_kwkrei.clicked.connect(self.VentanaKREI)
        self.ui.btn_btn_kwsonora.clicked.connect(self.VentanaSonora)

        self.ui.btc_btc_cerrar.clicked.connect(self.cerrar)
        self.ui.btc_btc_minimizar.clicked.connect(self.minimizar)

#-------------------------------------------------
    def VentanaRioBravo(self):
        self.Ventana = Home_KWRB()
        self.Ventana.show()
#-------------------------------------------------
    def VentanaKWESTE(self):
        self.Ventana = Home_KWESTE()
        self.Ventana.show()
#-------------------------------------------------
    def VentanaKREI(self):
        self.Ventana = Home_KREI()
        self.Ventana.show()
#-------------------------------------------------
    def VentanaSonora(self):
        self.Ventana = Home_KenworthSonora()
        self.Ventana.show()
#-------------------------------------------------
    def cerrar(self):
        self.close()

    def minimizar(self):
        self.showMinimized()
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = my_app()
    window.show()
    sys.exit(app.exec_())


#!/usr/bin/env python3
import argparse
import os
from colorama import init
from termcolor import colored
from lib import *

def look_for_elements(name, origin, type):
    result = [] # It will store the paths of the files found.
    try:
        elements = os.listdir(origin)
    except PermissionError:
        return result

    for element in elements:
        if (os.path.isfile(os.path.join(origin, element)) and type == "file" or type == "both") and element == name:
            result.append(os.path.join(origin, element))

        elif os.path.isdir(os.path.join(origin, element)):

            # Add folders as well
            if  type == "dir" or type == "both" and element == name:
                result.append(os.path.join(origin, element))

            result2 = look_for_elements(name, os.path.join(origin, element), type)

            # Append the results from the other directories
            for r in result2:
                result.append(r)

    return result

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("file", type=str,help="File to look for")
    parser.add_argument("-o", "--origin", type=str, required=False, default=os.getcwd(), help="Directory where the search will start")
    parser.add_argument("-t", "--type", type=str, required=False, default="both", help="The type of the element to look for. (file, directory or both)")
    arguments = parser.parse_args()

    # Turn the origin path into an absolute path
    arguments.origin = os.path.abspath(arguments.origin)

    if not arguments.type in ["file", "directory", "both"]:
        error("Invalid element type to look for.", "(it can only be 'file/directory/both')")

    elif not os.path.isdir(arguments.origin):
        error(f"The origin directory its not a directory or doesn't exist: '{arguments.origin}'")

    else:
        result = look_for_elements(arguments.file, arguments.origin, arguments.type)

        t = table(["Index", "Name", "Type"])
        for index, x in enumerate(result):
            type = "UNKNOWN"
            if os.path.isfile(x):
                type = "FILE"

            elif os.path.isdir(x):
                type = "DIRECTORY"

            else:
                type = "SYMBOLIC LINK"

            t.addContent([index+1, x, type])

        t.printTable()

if __name__ == "__main__":
    main()


from email.mime import audio
from pytube import YouTube
from moviepy.editor import *

def download_from_yt():
    file1 = open('myfile.txt', 'r')
    Lines = file1.readlines()

    for line in Lines:
        yt = YouTube(line)
        stream = yt.streams.get_audio_only()
        stream.download()
        print(f'Done {stream.title}')

def convert_to_mp3():
    for filename in os.listdir("files"):
        clip = AudioFileClip(f'files/{filename}')
        clip.write_audiofile(f'files/ready/{filename}.mp3')
        print(f'Done {filename}.mp3')

print("1. Download\n2.Convert")
x = input()

if (x == "1"):
    download_from_yt()
else:
    convert_to_mp3()


import math
import random
import numpy as np
from sklearn.datasets import load_iris

## Arvore de decisao ##
iris = load_iris()

def prob_esquerda(corte,atributo,data_info): ## estuda o valor de corte para o filho da esquerda ##
  samples = 0
  classe = [0,0,0]
  data_filho = []
  for w in range(len(iris.data)):
    if w not in data_info:
      continue
    else:
      if iris.data[w][atributo] <= corte:
        data_filho.append(w)
        samples += 1
        if iris.target[w] == 0:
          classe[0] += 1
        elif iris.target[w] == 1:
          classe[1] += 1
        else:
          classe[2] += 1

  value = [classe[0], classe[1], classe[2]]
  probabilidade = [p/samples for p in classe if p]
  return probabilidade,samples,data_filho,value

def prob_direita(corte,atributo,data_info): ## estuda o valor de corte para o filho da direita ##
  samples = 0
  classe = [0,0,0]
  data_filho = []
  for w in range(len(iris.data)):
    if w not in data_info:
      continue
    else:
      if iris.data[w][atributo] > corte:
        data_filho.append(w)
        samples += 1
        if iris.target[w] == 0:
          classe[0] += 1
        elif iris.target[w] == 1:
          classe[1] += 1
        else:
          classe[2] += 1

  value = [classe[0], classe[1], classe[2]]
  probabilidade = [p/samples for p in classe if p]
  return probabilidade,samples,data_filho,value

def entropia(probabilidades): ## calculo da entropia ##
  return sum(-p * math.log(p,2) for p in probabilidades if p)

def ganho_informacao(entropia_pai,entropia_esq,entropia_dir,n_pai,n_esq,n_dir): ## ganho de informacao ##
  peso1 = n_esq/n_pai
  peso2 = n_dir/n_pai
  return entropia_pai - (peso1*entropia_esq  + peso2*entropia_dir)

def buid_tree(info,data_filho,u,t,info_data,atributo,X_train,y_train): ## constrói a arvore de decisao ##
  P = []
  I = []
  for w in range(4):
    v = []
    indice = []
    i = 0
    for i in y_train:
      if i not in data_filho:
        continue
      else:
        v.append(iris.data[i][w])
        indice.append(iris.target[i])

    k = 0
    while k < (len(v)-1):
      l = k+1
      while l < (len(v)):
        if v[k] >= v[l]:
          aux = v[k]
          v[k] = v[l]
          v[l] = aux

          aux = indice[k]
          indice[k] = indice[k]
          indice[k] = aux
        l += 1
      k += 1

    media = (v[indice.index(indice[0]+1)-1] + v[indice.index(indice[0]+1)]) / 2
    P.append(media)
    probabilidades_esq,n_esq,data_esq,value_esq = prob_esquerda(P[w],w,data_filho)
    probabilidades_dir,n_dir,data_dir,value_dir = prob_direita(P[w],w,data_filho)

    n_pai = info[u][1]
    entropia_pai = info[u][0]
    entropia_esq = entropia(probabilidades_esq)
    entropia_dir = entropia(probabilidades_dir)

    I.append(ganho_informacao(entropia_pai,entropia_esq,entropia_dir,n_pai,n_esq,n_dir))

    info[t+1] = [entropia_esq,n_esq,value_esq,value_esq.index(max(value_esq))]
    info[t+2] = [entropia_dir,n_dir,value_dir,value_dir.index(max(value_dir))]

    info_data[t+1] = data_esq
    info_data[t+2] = data_dir

  atributo[u] = [I.index(max(I)),P[I.index(max(I))]]

def cria_grafo(lista_de_vertices, lista_de_arestas):
    grafo = {}
    for vertice in lista_de_vertices:
        grafo[vertice] = []
    for aresta in lista_de_arestas:
        grafo[aresta[0]].append(aresta[1])
    return grafo

def decisao(grafo,vertice,visitados,fila,Q,dados,atributo,info,profundidade,classe):
  while Q:
    vertice = Q.pop(0)

    if info[vertice][0] == 0.0:
      classe.append(info[vertice][3])

    elif profundidade == 4:
      classe.append(info[vertice][3])

    for u in grafo[vertice]:
      if dados[atributo[vertice][0]] <= atributo[vertice][1]:
        visitados.append(u)
        Q.append(u)
        fila.append(u)
        profundidade += 1
        decisao(grafo,vertice,visitados,fila,Q,dados,atributo,info,profundidade,classe)

      else:
        visitados.append(grafo[vertice][1])
        Q.append(grafo[vertice][1])
        fila.append(grafo[vertice][1])
        profundidade += 1
        decisao(grafo,vertice,visitados,fila,Q,dados,atributo,info,profundidade,classe)

      if Q:
        del(fila[len(fila)-1])
        a = fila[len(fila)-1]
        Q = [a]
        decisao(grafo,a,visitados,fila,Q,dados,atributo,info,profundidade,classe)

  return visitados

def train_test_dados(data,tam_treino,total):
    y_train = []
    x_train = []
    y_test = []
    x_test = []

    y_train = random.sample(range(0, total), tam_treino)
    y_train.sort()
    for w in y_train:
        x_train.append(data[w])

    for j in range(total):
      if j not in y_train:
        y_test.append(j)
        x_test.append(data[j])

    return x_train, y_train, x_test, y_test

def accuracy(classification,target):
  total = 0
  acertos = 0
  for i in range(len(classification)):
    if classification[i] == -1:
      continue
    else:
      if classification[i] == target[i]:
        acertos += 1
      total += 1

  return acertos/total

tamData = len(iris.data)
porcentagem_treino = 0.7 # porcentagem de treino
tamTreino = int(tamData*porcentagem_treino)

X_train, y_train, X_test, y_test = train_test_dados(iris.data,tamTreino,tamData)
if porcentagem_treino == 1:
  X_test, y_test = X_train, y_train

print('Conjunto treino:',y_train)
print('Conjunto teste:', y_test)
print()

target = [0,0,0]
for i in y_train:
  if iris.target[i] == 0:
    target[0] += 1
  elif iris.target[i] == 1:
    target[1] += 1
  else:
    target[2] += 1

prob_raiz = [target[0]/len(y_train),target[1]/len(y_train),target[2]/len(y_train)]
entropia_raiz = sum(-p * math.log(p,2) for p in prob_raiz if p)
info = {0:[entropia_raiz,len(y_train),[target[0],target[1],target[2]], target.index(max(target))]} ## no raiz ##
vertices = [0]
arestas = []
info_data = {}
atributo = {}
profundidade_no = 5

u = 0
tam = 0
while u < profundidade_no:
  if u == 0:
    data_filho = y_train
    buid_tree(info,data_filho,u,tam,info_data,atributo,X_train,y_train)
  elif info[u][0] == 0.0:
    u += 1
    continue
  else:
    buid_tree(info,info_data[u],u,tam,info_data,atributo,X_train,y_train)

  arestas.append((u,tam+1))
  arestas.append((u,tam+2))
  vertices.append(tam+1)
  vertices.append(tam+2)
  tam += 2

  u += 1
grafo = cria_grafo(vertices, arestas)

classification = []
for i in range(len(iris.data)):
  if i not in y_test:
    classification.append(-1)
    continue
  else:
    visitados = [0]
    Q = [0]
    fila = [0]
    vertice = []
    profundidade = 0
    classe = []

    decisao(grafo,vertice,visitados,fila,Q,iris.data[i],atributo,info,profundidade,classe)
    classification.append(classe[0])

j = 0
for i in range(len(classification)):
  if classification[i] == -1:
    continue
  else:
    print(y_test[j], '-', iris.target_names[classification[i]])
    j += 1

print()
print("Acurácia:", accuracy(classification,iris.target))


import sys
sys.path.insert(0, "/Users/tom/Dropbox/msc-ml/project/src/")
sys.path.insert(0, "/cs/student/msc/ml/2017/thosking/dev/msc-project/src/")

from tqdm import tqdm
import numpy as np
import json

import helpers.loader as loader
import helpers.metrics as metrics
import helpers.preprocessing as preprocessing
import tensorflow as tf

import flags

from langmodel.lm import LstmLmInstance
# from qa.mpcm import MpcmQaInstance
from qa.qanet.instance import QANetInstance
from discriminator.instance import DiscriminatorInstance

FLAGS = tf.app.flags.FLAGS

class FileLoaderModel():
    def __init__(self, path):
        self.path = path
        with open(path+'/squad_dev_baseline.txt', 'r', encoding='utf-8') as fp:
            self.questions = [line.strip() for line in fp.readlines()]
        with open(path+'/dev.txt.shuffle.combined.id', 'r', encoding='utf-8') as fp:
            self.ids = [line.strip() for line in fp.readlines()]
        print(len(self.questions), len(self.ids))

    def get_q(self, id):
        if id in self.ids:
            ix = self.ids.index(id)
            return self.questions[ix]
        else:
            return None

def main(_):
    model = FileLoaderModel('./models/BASELINE')
    squad = loader.load_squad_triples(FLAGS.data_path, True, as_dict=True)

    disc_path = FLAGS.model_dir+'saved/discriminator-trained-latent'

    glove_embeddings = loader.load_glove(FLAGS.data_path)

    if FLAGS.eval_metrics:
        lm = LstmLmInstance()
        # qa = MpcmQaInstance()
        qa = QANetInstance()

        lm.load_from_chkpt(FLAGS.model_dir+'saved/lmtest')
        # qa.load_from_chkpt(FLAGS.model_dir+'saved/qatest')
        qa.load_from_chkpt(FLAGS.model_dir+'saved/qanet')

        discriminator = DiscriminatorInstance(trainable=False, path=disc_path)

    f1s=[]
    bleus=[]
    qa_scores=[]
    qa_scores_gold=[]
    lm_scores=[]
    nlls=[]
    disc_scores=[]
    sowe_similarities=[]

    qgolds=[]
    qpreds=[]
    ctxts=[]
    answers=[]
    ans_positions=[]

    metric_individuals=[]
    res=[]

    missing=0

    for id,el in tqdm(squad.items()):

        unfilt_ctxt_batch = [el[0]]
        a_text_batch = [el[2]]
        a_pos_batch = [el[3]]

        ctxts.extend(unfilt_ctxt_batch)
        answers.extend(a_text_batch)
        ans_positions.extend(a_pos_batch)

        pred_str = model.get_q(id)

        if pred_str is None:
            missing +=1
            continue
        gold_str = el[1]

        if FLAGS.eval_metrics:
            qa_pred = qa.get_ans(unfilt_ctxt_batch, [pred_str])
            gold_qa_pred = qa.get_ans(unfilt_ctxt_batch, [gold_str])

            qa_score = metrics.f1(el[2].lower(), qa_pred[0].lower())
            qa_score_gold = metrics.f1(el[2].lower(), gold_qa_pred[0].lower())
            lm_score = lm.get_seq_perplexity([pred_str]).tolist()
            disc_score = discriminator.get_pred(unfilt_ctxt_batch, [pred_str], a_text_batch, a_pos_batch).tolist()[0]

        f1s.append(metrics.f1(gold_str, pred_str))
        bleus.append(metrics.bleu(gold_str, pred_str))
        qgolds.append(gold_str)
        qpreds.append(pred_str)

        # calc cosine similarity between sums of word embeddings
        pred_sowe = np.sum(np.asarray([glove_embeddings[w] if w in glove_embeddings.keys() else np.zeros((FLAGS.embedding_size,)) for w in preprocessing.tokenise(pred_str ,asbytes=False)]) ,axis=0)
        gold_sowe = np.sum(np.asarray([glove_embeddings[w] if w in glove_embeddings.keys() else np.zeros((FLAGS.embedding_size,)) for w in preprocessing.tokenise(gold_str ,asbytes=False)]) ,axis=0)
        this_similarity = np.inner(pred_sowe, gold_sowe)/np.linalg.norm(pred_sowe, ord=2)/np.linalg.norm(gold_sowe, ord=2)

        sowe_similarities.append(this_similarity)

        this_metric_dict={
            'f1':f1s[-1],
            'bleu': bleus[-1],
            'nll': 0,
            'sowe': sowe_similarities[-1]
            }
        if FLAGS.eval_metrics:
            this_metric_dict={
            **this_metric_dict,
            'qa': qa_score,
            'lm': lm_score,
            'disc': disc_score}
            qa_scores.append(qa_score)
            lm_scores.append(lm_score)
            disc_scores.append(disc_score)
        metric_individuals.append(this_metric_dict)

        res.append({
            'c': el[0],
            'q_pred': pred_str,
            'q_gold': gold_str,
            'a_pos': el[3],
            'a_text': el[2],
            'metrics': this_metric_dict
        })

    metric_dict={
        'f1':np.mean(f1s),
        'bleu':np.mean(bleus),
        'nll':0,
        'sowe': np.mean(sowe_similarities)
        }
    if FLAGS.eval_metrics:
        metric_dict={**metric_dict,
        'qa':np.mean(qa_scores),
        'lm':np.mean(lm_scores),
        'disc': np.mean(disc_scores)}
    # print(res)
    with open(FLAGS.log_dir+'out_eval_BASELINE'+("_train" if not FLAGS.eval_on_dev else "")+'.json', 'w', encoding='utf-8') as fp:
        json.dump({"metrics":metric_dict, "results": res}, fp)

    print("F1: ", np.mean(f1s))
    print("BLEU: ", np.mean(bleus))
    print("NLL: ", 0)
    print("SOWE: ", np.mean(sowe_similarities))
    if FLAGS.eval_metrics:
        print("QA: ", np.mean(qa_scores))
        print("LM: ", np.mean(lm_scores))
        print("Disc: ", np.mean(disc_scores))

    print(missing," ids were missing")

if __name__ == "__main__":
    tf.app.run()