import torch
from functools import partial
from ..utils.ema import EMA
from tu.utils.training import get_children_grad_norm, get_children_grad_norm_safe, get_optimizer_lr
from tu.ddp import check_ddp_consistency
from tu.utils.training import process_batch
import time
import torch.distributed as dist
from ..utils.unit_sphere import UnitSphere
from tu.utils.visualize import dump_helper
from ..utils.plot import normalize_batched_tensor
import os
from tu.utils.config import build_from_config
from tu.loggers.utils import setup_vi
from ..utils.checkpoint import CheckpointIO

import logging
logger = logging.getLogger(__name__)

def toggle_grad(model, requires_grad):
    for p in model.parameters():
        p.requires_grad_(requires_grad)

MODULE_KEYS = ['generator', 'discriminator', 'mask_discriminator']
MODULE_KEYS_TO_DATA_KEYS = {
    'generator': ['image'],
    'discriminator': ['image'],
    'mask_discriminator': ['mask'],
}

class Trainer:
    def __init__(
            self,
            modules,
            writer, loss_weight,
            loss_modules,
            it=-1,
    ):
        self.modules = modules
        self.module_keys = MODULE_KEYS
        self.module_keys_to_data_keys = MODULE_KEYS_TO_DATA_KEYS
        for k in self.module_keys:
            setattr(self, k, self.modules[k])
            setattr(self, f'opt_{k}', self.modules[f'opt_{k}'])
            setattr(self, f'sch_{k}', self.modules[f'sch_{k}'])

        self.loss_weight = dict()
        for k, v in loss_weight.items():
            if isinstance(v, dict):
                self.loss_weight[k] = build_from_config(v)
            else:
                self.loss_weight[k] = v
        self.loss_modules = {k: build_from_config(v) for k, v in loss_modules.items()}

        self.writer = writer
        self.it = it
        if self.writer is not None:
            self.vi, self.vi_helper = setup_vi(self.writer.get_logdir())
            self.vis_dir = self.writer.get_logdir
            checkpoint_dir = os.path.join(writer.log_dir, 'checkpoints')
        else:
            checkpoint_dir = None
            self.vi = None

        self.checkpoint_io = CheckpointIO(
            checkpoint_dir,
            **self.modules,
        )
        generator_module = self.generator
        if dist.is_initialized():
            generator_module = generator_module.module
        self.light_sphere = UnitSphere(generator_module.resolution, scale=.5).cuda()

    def train_step(self, data):
        self.it += 1

        for k in self.module_keys:
            self.modules[k].train()

        loss_gen = self.train_step_generator(data)
        with torch.no_grad():
            out = self.generator(bs=data['image'].shape[0], it=self.it, data=data, return_raw=False)
        loss_disc = self.train_step_discriminator_core('discriminator', data, {**out['box']['render_out'], 'c2b': out['box']['prior_info']['c2b']})

        with torch.no_grad():
            out = self.generator(bs=data['image'].shape[0], it=self.it, data=data, return_raw=False)
        loss_mask_dist = self.train_step_discriminator_core('mask_discriminator', data, out['box']['render_out'])

        loss = {**loss_gen, **loss_disc, **loss_mask_dist}

        stats = {}
        for k in self.module_keys:
            for kk, v in get_optimizer_lr(self.modules[f'opt_{k}']).items():
                stats[f'lr/opt_{k}/{kk}'] = v

        for k in self.module_keys:
            self.modules[f'sch_{k}'].step()
        return {**loss, **stats}

    def train_step_generator(self, data):
        ret = dict()
        for k in self.module_keys:
            toggle_grad(self.modules[k], requires_grad=k == 'generator')

        self.opt_generator.zero_grad()

        out = self.generator(bs=data['image'].shape[0], it=self.it, data={}, return_raw=False)
        blob = out['box']

        x_fake = torch.cat([blob['render_out'][k] for k in self.module_keys_to_data_keys['discriminator']], dim=-3)
        d_fake = self.discriminator(x_fake, it=self.it)
        d_fake = d_fake[:, :1]
        loss_disc = self.loss_modules['gan'](d_fake, 1)

        mask_x_fake = torch.cat([blob['render_out'][k] for k in self.module_keys_to_data_keys['mask_discriminator']], dim=-3)
        mask_d_fake = self.mask_discriminator(mask_x_fake, it=self.it)
        # mask_d_fake = mask_d_fake[:, :1]
        loss_mask_disc = self.loss_modules['gan'](mask_d_fake, 1)

        loss_final = loss_disc * self.loss_weight['disc_in_gen'] + loss_mask_disc * self.loss_weight['mask_disc_in_gen']

        ret.update({
            'generator/loss': loss_disc,
            'generator/loss_mask': loss_mask_disc,
        })

        for _, blob in out.items():
            for k in blob['loss'].keys():
                loss_extra = blob['loss'][k]
                loss_final += self.loss_weight[k] * loss_extra
                assert f'generator/{k}' not in ret, (k, ret.keys())
                ret[f'generator/{k}'] = loss_extra

        for prefix, blob in out.items():
            for k in blob['stats'].keys():
                ret[f'{prefix}_stats/{k}'] = blob['stats'][k]

        loss_final.backward()
        self.opt_generator.step()

        m = self.generator
        if dist.is_initialized():
            m = m.module
        for k, grad_norm in get_children_grad_norm_safe(m, verbose=self.it == 0).items():
            if grad_norm is None:
                grad_norm = -1
            ret[f'grad_stats/{k}'] = grad_norm

        return ret

    def train_step_discriminator_core(self, module_key: str, real_data, fake_data):
        ret = dict()
        for k in self.module_keys:
            toggle_grad(self.modules[k], requires_grad=k == module_key)

        discriminator = self.modules[module_key]
        opt_discriminator = self.modules[f'opt_{module_key}']
        opt_discriminator.zero_grad()

        x_real = torch.cat([real_data[k] for k in self.module_keys_to_data_keys[module_key]], dim=-3)
        x_real.requires_grad_()
        d_real = discriminator(x_real, it=self.it)
        d_real = d_real[:, :1]
        loss_real = self.loss_modules['gan'](d_real, 1)

        loss_reg = self.loss_modules['reg'](d_real, x_real)

        x_fake = torch.cat([fake_data[k] for k in self.module_keys_to_data_keys[module_key]], dim=-3)
        x_fake.requires_grad_()
        d_fake = discriminator(x_fake, it=self.it)
        if d_fake.size(1) > 1:
            generator_module = self.generator
            if dist.is_initialized():
                generator_module = generator_module.module

            d_fake, d_fake_aux = torch.split(d_fake, (1, generator_module.pose_prior.repr_dim), dim=1)

            pose_target = fake_data['c2b']
            pose_target = generator_module.pose_prior.pose_to_vec_repr(pose_target)
            loss_aux_pose = self.loss_modules['aux_pose'](d_fake_aux, pose_target)
        else:
            loss_aux_pose = 0

        loss_fake = self.loss_modules['gan'](d_fake, 0)

        loss = loss_real + loss_fake + loss_reg * self.loss_weight['reg'] + loss_aux_pose * self.loss_weight['aux_pose'](self.it)
        loss.backward()
        opt_discriminator.step()

        ret.update({
            f'{module_key}/loss': loss_fake + loss_real,
            f'{module_key}/reg': loss_reg,
            f'{module_key}/fake': loss_fake,
            f'{module_key}/real': loss_real,
            f'{module_key}/aux_pose': loss_aux_pose,
            f'{module_key}/fake_sign': d_fake.sign().mean(),
            f'{module_key}/real_sign': d_real.sign().mean(),
        })
        return ret

    def visualize(self, data):
        if self.vi is not None:
            self.vi.title = f'It {self.it}'
            self.vi.end_html()
            self.vi.begin_html()

        for k in self.module_keys:
            self.modules[k].eval()
        with torch.no_grad():
            out = self.generator(bs=data['image'].shape[0], data=data, it=None, return_raw=True)

        self.visualize_core(out['box']['render_out'], prefix='fake')
        self.visualize_core(data, prefix='real')

    def visualize_core(self, maps, prefix=None):
        generator = self.generator
        discriminator = self.discriminator
        if dist.is_initialized():
            generator = generator.module
            discriminator = discriminator.module
        dump = partial(dump_helper, self, prefix=prefix)
        for k in ['image', 'image_comp', 'image_comp_sphere', 'mask', 'background', 'background_sphere_map', 'color_map', 'specular_map', 'no_specular_map', 'shading_map', 'diff_shading_map', 'amb_shading_map']:
            if k in maps:
                dump(k, maps[k])
        if 'normal_map' in maps:
            dump('normal_map', maps['normal_map'].flip(-3) * 0.5 + 0.5)
        for k in ['diff_shading_map', 'amb_shading_map']:
            if k not in maps:
                continue
            dump(k, maps[k])
        if prefix == 'fake':
            dump('z', normalize_batched_tensor(maps['z_map'], xmin=maps['z_min'][:, None, None, None]))
            dump('light', self.light_sphere.render(generator.light)['shading_map'][None])
        dump(f"{self.module_keys_to_data_keys['discriminator'][0]}_aug", discriminator.aug(maps[self.module_keys_to_data_keys['discriminator'][0]]))

    def save_checkpoint(self, overwrite=True, **kwargs):
        if dist.is_initialized():
            rank = dist.get_rank()
            if rank != 0:
                return
        self.checkpoint_io.save('model.pt', it=self.it, **kwargs)
        logger.info('saving checkpoint to model.pt')
        if not overwrite:
            self.checkpoint_io.save(f'it_{self.it:08d}.pt', it=self.it, **kwargs)
            logger.info(f'saving checkpoint to it_{self.it:08d}.pt')

    def load_checkpoint(self, path, strict=False):
        assert strict is False
        # FIXME this is very hacky
        state_dict = torch.load(path)
        logger.info(str(state_dict.keys()))
        state_dict = {k: v for k, v in state_dict.items() if k in self.module_keys or k in ['epoch', 'it']}
        # FIXME some buffer parameters might be overwritten
        unused = self.checkpoint_io.load(state_dict, strict=strict)
        logger.info(str(unused.keys()))
        logger.info(str({k: v for k, v in unused.items() if not k.startswith('ema') and not isinstance(v, dict)}))
        self.it = unused['it']
        logger.info(f'resuming from it: {self.it}')
        return unused

def train_loops(
        eval_every, print_every, visualize_every, checkpoint_every, checkpoint_overwrite,
        cfg, trainer, train_loader, val_loader, max_epoch, max_it, epoch=-1):
    assert max_epoch is None or max_it is not None, f'infinite loop'
    ema_modules = [
        EMA(trainer.generator, beta=beta, m_ema=None)
        for beta in ([0.99, 0.9] if os.getenv('DEBUG') != '1' else [])
    ]
    ema_modules = {str(ema): ema for ema in ema_modules}

    t0b = time.time()
    while True:
        if max_epoch is not None and epoch > max_epoch:
            logger.info(f'final epoch = {epoch}, it ={trainer.it}, exceeding max epoch {max_epoch}')
            return
        if max_it is not None and trainer.it > max_it:
            logger.info(f'final epoch = {epoch}, it ={trainer.it}, exceeding max it {max_it}')
            return
        epoch += 1
        if dist.is_initialized():
            train_loader.sampler.set_epoch(epoch)
        for batch in train_loader:
            batch = process_batch(batch)
            if os.getenv('RECON_OBJ') == '1':
                loss = trainer.train_step_recon(batch)
            else:
                loss = trainer.train_step(batch)

            for ema in ema_modules.values():
                ema.update(trainer.it)

            if os.getenv('DEBUG') == '1' and dist.is_initialized() and trainer.it < 10:
                for k in sorted(trainer.module_keys):
                    check_ddp_consistency(trainer.modules[k], ignore_regex=r'(.*\.[^.]+_(avg|ema))')

            if print_every > 0 and trainer.it % print_every == 0:
                info_txt = '[Epoch %02d] it=%03d, time=%.3f' % (epoch, trainer.it, time.time() - t0b)
                for (k, v) in loss.items():
                    info_txt += ', %s: %.4f' % (k, v)
                if trainer.it <= 100:
                    logger.info(info_txt)
                t0b = time.time()

                if trainer.writer is not None:
                    for k, v in loss.items():
                        trainer.writer.add_scalar(k, v, trainer.it)

            if visualize_every > 0 and trainer.it % visualize_every == 0:
                trainer.visualize(batch)

            if checkpoint_every > 0 and trainer.it % checkpoint_every == 0:
                trainer.save_checkpoint(
                    overwrite=checkpoint_overwrite, epoch=epoch, loss=loss,
                    **{k: v.get_state_dict() for k, v in ema_modules.items()},
                )


from keras.models import Model
from keras.layers.convolutional import Convolution2D, MaxPooling2D, Conv2DTranspose
from keras.layers import Input
from keras.layers import Lambda
from keras.layers import concatenate

class ConvolutionalNeuralNetwork:

    def get_model(self,
                  input_dimentions,
                  metrics,
                  configuration
                  ):

        total_deconvolutional_filters = self._get_deconvolutional_filters(configuration.total_convolutional_layers,
                                                                          configuration.total_convolutional_filters)
        total_deconvolutional_layers = configuration.total_convolutional_layers - 1

        inputs = Input(input_dimentions)
        input_layer = Lambda(lambda x: x / 255)(inputs)

        convolutional_layers = self._setup_convolution(input_layer, configuration)
        last_layer = self._setup_deconvolution(convolutional_layers, total_deconvolutional_layers,
                                               total_deconvolutional_filters, configuration)

        outputs = Convolution2D(1, (1, 1), activation=configuration.output_activation)(last_layer)

        model = Model(inputs=[inputs], outputs=[outputs])
        model.compile(optimizer=configuration.optimizer, loss=configuration.loss, metrics=metrics)

        return model

    def _setup_convolution(self, input_layer, configuration):

        previous_layer = input_layer

        convolutional_layers = []

        total_filters = configuration.total_convolutional_filters

        for layer_index in range(0, configuration.total_convolutional_layers):
            convolutional_layer = Convolution2D(total_filters, configuration.filter_size_convolution,
                                                activation=configuration.activation, padding=configuration.padding)(previous_layer)
            convolutional_layer = Convolution2D(total_filters, configuration.filter_size_convolution,
                                                activation=configuration.activation, padding=configuration.padding)(convolutional_layer)

            if layer_index < configuration.total_convolutional_layers - 1:
                pooling_layer = MaxPooling2D(configuration.pool_size)(convolutional_layer)
                previous_layer = pooling_layer
            else:
                previous_layer = convolutional_layer

            convolutional_layers.append(convolutional_layer)
            total_filters = total_filters * 2

        return convolutional_layers

    def _setup_deconvolution(self, covolutional_layers, total_layers, total_filters, configuration):

        previous_layer = covolutional_layers[len(covolutional_layers) - 1]

        deconvolutional_layers = []
        merged_layers = []

        for layer_index in range(0, total_layers):
            merged_layer = Conv2DTranspose(total_filters, configuration.filter_size_deconvolution,
                                           strides=configuration.strides, padding=configuration.padding)(previous_layer)
            convolution_to_reverse = covolutional_layers[len(covolutional_layers) - layer_index - 2]
            merged_layer = concatenate([merged_layer, convolution_to_reverse])

            convolution_layer = Convolution2D(total_filters, configuration.filter_size_convolution, activation=configuration.activation,
                                              padding=configuration.padding)(merged_layer)
            convolution_layer = Convolution2D(total_filters, configuration.filter_size_convolution, activation=configuration.activation,
                                              padding=configuration.padding)(convolution_layer)

            deconvolutional_layers.append(convolution_layer)
            merged_layers.append(merged_layer)

            previous_layer = merged_layer
            total_filters = int(total_filters / 2)

        last_layer = previous_layer

        return last_layer

    def _get_deconvolutional_filters(self, total_convolutional_layers, total_convolutional_filters):
        return [i * 2 ** exp
                for exp in range(0, total_convolutional_layers - 1)
                for i in range(total_convolutional_filters, total_convolutional_filters + 1)][-1]


import cv2
import numpy as np

img = cv2.imread('../img/taekwonv1.jpg')
img_draw = img.copy()
mask = np.zeros(img.shape[:2], dtype=np.uint8)  # 마스크 생성
rect = [0,0,0,0]    # 사각형 영역 좌표 초기화
mode = cv2.GC_EVAL  # 그랩컷 초기 모드
# 배경 및 전경 모델 버퍼
bgdmodel = np.zeros((1,65),np.float64)
fgdmodel = np.zeros((1,65),np.float64)

# 마우스 이벤트 처리 함수
def onMouse(event, x, y, flags, param):
    global mouse_mode, rect, mask, mode
    if event == cv2.EVENT_LBUTTONDOWN : # 왼쪽 마우스 누름
        if flags <= 1: # 아무 키도 안 눌렀으면
            mode = cv2.GC_INIT_WITH_RECT # 드래그 시작, 사각형 모드 ---①
            rect[:2] = x, y # 시작 좌표 저장
    # 마우스가 움직이고 왼쪽 버튼이 눌러진 상태
    elif event == cv2.EVENT_MOUSEMOVE and flags & cv2.EVENT_FLAG_LBUTTON :
        if mode == cv2.GC_INIT_WITH_RECT: # 드래그 진행 중 ---②
            img_temp = img.copy()
            # 드래그 사각형 화면에 표시
            cv2.rectangle(img_temp, (rect[0], rect[1]), (x, y), (0,255,0), 2)
            cv2.imshow('img', img_temp)
        elif flags > 1: # 키가 눌러진 상태
            mode = cv2.GC_INIT_WITH_MASK    # 마스크 모드 ---③
            if flags & cv2.EVENT_FLAG_CTRLKEY :# 컨트롤 키, 분명한 전경
                # 흰색 점 화면에 표시
                cv2.circle(img_draw,(x,y),3, (255,255,255),-1)
                # 마스크에 GC_FGD로 채우기      ---④
                cv2.circle(mask,(x,y),3, cv2.GC_FGD,-1)
            if flags & cv2.EVENT_FLAG_SHIFTKEY : # 쉬프트키, 분명한 배경
                # 검정색 점 화면에 표시
                cv2.circle(img_draw,(x,y),3, (0,0,0),-1)
                # 마스크에 GC_BGD로 채우기      ---⑤
                cv2.circle(mask,(x,y),3, cv2.GC_BGD,-1)
            cv2.imshow('img', img_draw) # 그려진 모습 화면에 출력
    elif event == cv2.EVENT_LBUTTONUP: # 마우스 왼쪽 버튼 뗀 상태 ---⑥
        if mode == cv2.GC_INIT_WITH_RECT : # 사각형 그리기 종료
            rect[2:] =x, y # 사각형 마지막 좌표 수집
            # 사각형 그려서 화면에 출력 ---⑦
            cv2.rectangle(img_draw, (rect[0], rect[1]), (x, y), (255,0,0), 2)
            cv2.imshow('img', img_draw)
        # 그랩컷 적용 ---⑧
        cv2.grabCut(img, mask, tuple(rect), bgdmodel, fgdmodel, 1, mode)
        img2 = img.copy()
        # 마스크에 확실한 배경, 아마도 배경으로 표시된 영역을 0으로 채우기
        img2[(mask==cv2.GC_BGD) | (mask==cv2.GC_PR_BGD)] = 0
        cv2.imshow('grabcut', img2) # 최종 결과 출력
        mode = cv2.GC_EVAL # 그랩컷 모드 리셋
# 초기 화면 출력 및 마우스 이벤트 등록
cv2.imshow('img', img)
cv2.setMouseCallback('img', onMouse)
while True:
    if cv2.waitKey(0) & 0xFF == 27 : # esc
        break
cv2.destroyAllWindows()


from typing import Dict

from src.GameObject import GameObject

class Box(GameObject):
    def __init__(
        self,
        i: int,
        j: int,
        width: int,
        height: int,
        frame_index: int,
        soliness: Dict[str, bool],
    ) -> None:
        self.i = i
        self.j = j
        self.spawned_key = False
        super().__init__(
            self.j * width,
            self.i * height,
            width,
            height,
            "tiles",
            frame_index,
            soliness,
        )


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

from models.networkLib._utils import _SimpleSegmentationModel

__all__ = ["DeepLabV3"]

class DeepLabV3(_SimpleSegmentationModel):
    """
    Implements DeepLabV3 model from
    `"Rethinking Atrous Convolution for Semantic Image Segmentation"
    <https://arxiv.org/abs/1706.05587>`_.

    Arguments:
        backbone (nn.Module): the network used to compute the features for the model.
            The backbone should return an OrderedDict[Tensor], with the key being
            "out" for the last feature map used, and "aux" if an auxiliary classifier
            is used.
        classifier (nn.Module): module that takes the "out" element returned from
            the backbone and returns a dense prediction.
        aux_classifier (nn.Module, optional): auxiliary classifier used during training
    """
    pass

class DeepLabHeadV3Plus(nn.Module):
    def __init__(self, in_channels, num_classes, low_level_channels=256, aspp_dilate=[12, 24, 36]):
        super(DeepLabHeadV3Plus, self).__init__()
        self.project = nn.Sequential(
            nn.Conv2d(low_level_channels, 48, 1, bias=False),
            nn.BatchNorm2d(48),
            nn.ReLU(inplace=True),
        )

        self.aspp = ASPP(in_channels, aspp_dilate)

        self.classifier = nn.Sequential(
            nn.Conv2d(304, 256, 3, padding=1, bias=False),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, num_classes, 1)
        )
        self._init_weight()

    def forward(self, feature):
        low_level_feature = self.project(feature['low_level'])
        output_feature = self.aspp(feature['out'])
        output_feature = F.interpolate(output_feature, size=low_level_feature.shape[2:], mode='bilinear',
                                       align_corners=False)
        return self.classifier(torch.cat([low_level_feature, output_feature], dim=1))

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

class DeepLabHead(nn.Module):
    def __init__(self, in_channels, num_classes, aspp_dilate=[12, 24, 36]):
        super(DeepLabHead, self).__init__()

        self.classifier = nn.Sequential(
            ASPP(in_channels, aspp_dilate),
            nn.Conv2d(256, 256, 3, padding=1, bias=False),
            nn.BatchNorm2d(256),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, num_classes, 1)
        )
        self._init_weight()

    def forward(self, feature):
        return self.classifier(feature['out'])

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

class ASPPConv(nn.Sequential):
    def __init__(self, in_channels, out_channels, dilation):
        modules = [
            nn.Conv2d(in_channels, out_channels, 3, padding=dilation, dilation=dilation, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU()
        ]
        super(ASPPConv, self).__init__(*modules)

class ASPPPooling(nn.Sequential):
    def __init__(self, in_channels, out_channels):
        super(ASPPPooling, self).__init__(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(in_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU())

    def forward(self, x):
        size = x.shape[-2:]
        for mod in self:
            x = mod(x)
        return F.interpolate(x, size=size, mode='bilinear', align_corners=False)

class ASPP(nn.Module):
    def __init__(self, in_channels, atrous_rates, out_channels=256):
        super(ASPP, self).__init__()
        modules = []
        modules.append(nn.Sequential(
            nn.Conv2d(in_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU()))

        rates = tuple(atrous_rates)
        for rate in rates:
            modules.append(ASPPConv(in_channels, out_channels, rate))

        modules.append(ASPPPooling(in_channels, out_channels))

        self.convs = nn.ModuleList(modules)

        self.project = nn.Sequential(
            nn.Conv2d(len(self.convs) * out_channels, out_channels, 1, bias=False),
            nn.BatchNorm2d(out_channels),
            nn.ReLU(),
            nn.Dropout(0.5))

    def forward(self, x):
        res = []
        for conv in self.convs:
            res.append(conv(x))
        res = torch.cat(res, dim=1)
        return self.project(res)


import math
import sys
from datetime import timedelta, datetime
import transaction
import argparse
import psycopg2
from psycopg2.errors import SerializationFailure
import random
import time
import os

TXN_ID = {
    "NEW_ORDER": "N",
    "PAYMENT": "P",
    "DELIVERY": "D",
    "ORDER_STATUS": "O",
    "STOCK_LEVEL": "S",
    "POPULAR_ITEM": "I",
    "TOP_BALANCE": "T",
    "RELATED_CUSTOMER": "R",
}

def get_percentile(data, percentile):
    size = len(data)
    return data[int(math.ceil((size * percentile) / 100)) - 1]

class MetricsManager:
    def __init__(self):
        # Keeps track of time taken for each transaction in milliseconds
        self.transaction_timings = []
        self.total_time = timedelta(0)

    # Takes in a timedelta for a transaction
    def add(self, delta):
        self.transaction_timings.append(delta / timedelta(milliseconds=1))

    def add_total_time(self, delta):
        self.total_time = delta

    def output_metrics(self):
        total_transactions = len(self.transaction_timings)
        sorted_transaction_timings = sorted(self.transaction_timings)
        total_transaction_timings = sum(sorted_transaction_timings)
        sys.stderr.write("Number of executed transactions: {}\n".format(total_transactions))
        sys.stderr.write("Total transaction execution time (in seconds): {}\n".format(self.total_time.total_seconds()))
        sys.stderr.write(
            "Transaction throughput (transactions / s): {}\n".format(
                total_transactions / (self.total_time.total_seconds())))
        sys.stderr.write(
            "Average transaction latency (in milliseconds): {}\n".format(
                total_transaction_timings / total_transactions))
        sys.stderr.write(
            "Median transaction latency (in milliseconds): {}\n".format(get_percentile(sorted_transaction_timings, 50)))
        sys.stderr.write("95th percentile transaction latency (in milliseconds): {}\n".format(
            get_percentile(sorted_transaction_timings, 95)))
        sys.stderr.write("99th percentile transaction latency (in milliseconds): {}\n".format(
            get_percentile(sorted_transaction_timings, 99)))

    def write_metrics(self, filename):
        metrics = []
        total_transactions = len(self.transaction_timings)
        sorted_transaction_timings = sorted(self.transaction_timings)
        total_transaction_timings = sum(sorted_transaction_timings)
        metrics.append(str(total_transactions))
        metrics.append(str(self.total_time.total_seconds()))
        metrics.append(str(total_transactions / (self.total_time.total_seconds())))
        metrics.append(str(total_transaction_timings / total_transactions))
        metrics.append(str(get_percentile(sorted_transaction_timings, 50)))
        metrics.append(str(get_percentile(sorted_transaction_timings, 95)))
        metrics.append(str(get_percentile(sorted_transaction_timings, 99)))
        with open(filename, "w") as f:
            f.write(",".join(metrics))

def setup_transactions(file, conn):
    transactions = []
    line = file.readline()
    while line:
        args = line.rstrip('\n').split(',')
        identifier = args[0]
        if identifier == TXN_ID["NEW_ORDER"]:
            inputs = args[1:]
            # Adds each item as a nested list
            num_items = int(args[-1])
            for i in range(0, num_items):
                item_line = file.readline()
                inputs.append(item_line.rstrip('\n').split(','))
            transactions.append(transaction.NewOrderTransaction(conn, inputs))
        elif identifier == TXN_ID["PAYMENT"]:
            transactions.append(transaction.PaymentTransaction(conn, args[1:]))
        elif identifier == TXN_ID["DELIVERY"]:
            transactions.append(transaction.DeliveryTransaction(conn, args[1:]))
        elif identifier == TXN_ID["ORDER_STATUS"]:
            transactions.append(transaction.OrderStatusTransaction(conn, args[1:]))
        elif identifier == TXN_ID["STOCK_LEVEL"]:
            transactions.append(transaction.StockLevelTransaction(conn, args[1:]))
        elif identifier == TXN_ID["POPULAR_ITEM"]:
            transactions.append(transaction.PopularItemTransaction(conn, args[1:]))
        elif identifier == TXN_ID["TOP_BALANCE"]:
            transactions.append(transaction.TopBalanceTransaction(conn, args[1:]))
        elif identifier == TXN_ID["RELATED_CUSTOMER"]:
            transactions.append(transaction.RelatedCustomerTransaction(conn, args[1:]))
        else:
            print("UNABLE TO PARSE XACT INPUT: ", args)

        line = file.readline()

    return transactions

def main():
    # Usage: python3 client.py <file> <hostNum> <db>
    # Example: python3 client.py 1.txt -hn 2
    # if hostNum not specified, use default host 2 (i.e. xcnc2)
    parser = argparse.ArgumentParser()
    parser.add_argument("file", metavar="F",
                        type=argparse.FileType('r'),
                        help='Transaction file for client')
    parser.add_argument("-hn", '--hostNum',
                        type=int, default=2,
                        help='Host number e.g. 2 for xcnc2. Default is xcnc2.'
                        )
    parser.add_argument("-p", '--port',
                        type=int, default=26260,
                        help='Port e.g. 26260. Default is 26260.'
                        )
    parser.add_argument("-db", '--database',
                        type=str, default="project",
                        help='Database name'
                        )
    args = parser.parse_args()

    host = f'xcnc{args.hostNum}.comp.nus.edu.sg'
    port = args.port
    user = 'root'  # use root so we don't have to grant privileges manually
    database = args.database
    conn = psycopg2.connect(host=host,
                            port=port,
                            user=user,
                            database=database)

    metrics = MetricsManager()
    transactions = setup_transactions(args.file, conn)
    metrics_filename = os.path.splitext(os.path.basename(args.file.name))[0] + ".metrics"
    args.file.close()

    total_execution_start = datetime.now()
    for txn in transactions:
        transaction_start = datetime.now()
        retry_count = 0
        last_error = ""
        while True:
            try:
                txn.run()
                # Flag issue if transactions had retried more than 15 times (sleep time > 5 seconds)
                if retry_count > 10:
                    sys.stderr.write("Transaction of type " + txn.__class__.__name__ + " retried: " + str(retry_count)
                                     + " times before completion with error: " + last_error + " \n")
                break
            except SerializationFailure as e:
                sleep_ms = (2 ** (retry_count % 16)) * 0.1 * (random.random() + 0.5)
                time.sleep(sleep_ms / 1000)
                last_error = str(e)
                retry_count += 1
                continue
        transaction_end = datetime.now()
        metrics.add(transaction_end - transaction_start)

        txn.print_outputs()
    total_execution_end = datetime.now()
    metrics.add_total_time(total_execution_end - total_execution_start)

    metrics.output_metrics()
    metrics.write_metrics(metrics_filename)
    conn.close()

if __name__ == '__main__':
    main()


from django.db import models
from django.core.validators import MinLengthValidator
from django.utils.translation import gettext_lazy as _
from parler.models import TranslatableModel, TranslatedFields
from .validators import *
from auditlog.registry import auditlog
from django.contrib.auth import get_user_model
User = get_user_model()

COMPANY_TYPE = (
    ("ART, PHOTOGRAPHY & CREATIVE SERVICES", "Art, Photography & Creative Services",),
    ("CONSTRUCTION & HOME IMPROVEMENT", "Construction & Home Improvement",),
    ("CONSULTING & PROFESSIONAL SERVICES", "Consulting & Professional Services",),
    ("FINANCIAL SERVICES & INSURANCE", "Financial Services & Insurance",),
    ("HAIR, SPA & AESTHETICS", "Hair, Spa & Aesthetics",),
    ("NON-PROFITS, ASSOCIATIONS & GROUPS", "Non-profits, Associations & Groups",),
    ("REAL ESTATE", "Real Estate",),
    ("RETAILERS, RESELLERS & SALES", "Retailers, Resellers & Sales",),
    ("WEB, TECH & MEDIA", "Web, Tech & Media",),
    ("OTHER: I MAKE OR SELL A PRODUCT", "Other: I make or sell a PRODUCT",),
    ("OTHER: I PROVIDE A SERVICE", "Other: I provide a SERVICE")
)

CUSTOMER_TYPE = (
    ("CUSTOMER", "Customer"),
    ("SUPPLIER", "Supplier"),
    ("INVESTOR", "Investor"),
    ("BORROWER", "Borrower"),
)

LANGUAGE_CHOICES = (
    ("EN", "EN"),
    ("BD", "BD"),
)

CURRENCY_CHOICES = (
    ("USD", "USD"),
    ("BDT", "BDT"),
)

class CompanyType(models.Model):
    company_type = models.CharField(max_length=100, choices=COMPANY_TYPE, blank=True, null=True)

    def __str__(self):
        return self.company_type

    class Meta:
        verbose_name = "Company Type"
        verbose_name_plural = _("Company Types")

auditlog.register(CompanyType)

class Company(models.Model):
    title = models.CharField(max_length=255, blank=True, null=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    company_type = models.ForeignKey(CompanyType, on_delete=models.SET_NULL, blank=True, null=True)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = 'Company'
        verbose_name_plural = _('Companies')

auditlog.register(Company)

class CustomerType(models.Model):
    customer_type = models.CharField(max_length=255, choices=CUSTOMER_TYPE, blank=True, null=True)

    def __str__(self):
        return self.customer_type

    class Meta:
        verbose_name = 'Customer Type'
        verbose_name_plural = _('Customer Types')

auditlog.register(CustomerType)

class Customer(models.Model):
    first_name = models.CharField(max_length=255, null=True, validators=[alphanumeric])
    last_name = models.CharField(max_length=255, null=True, blank=True, validators=[alphanumeric])
    full_name = models.CharField(max_length=255, blank=True, null=True)
    phone = models.CharField(max_length=15, null=True, validators=[phone_regex, MinLengthValidator(11)])
    email = models.EmailField(blank=True, null=True, validators=[email_regex])
    customer_type = models.ForeignKey(CustomerType, on_delete=models.CASCADE, null=True)
    company = models.ForeignKey(Company, on_delete=models.CASCADE, null=True)
    address = models.CharField(max_length=255, blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True, null=True)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE,  null=True)
    total_paid = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, blank=True, null=True)
    total_due = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, blank=True, null=True)

    def save(self, *args, **kwargs):
        if self.first_name and self.last_name:
            self.full_name = str(self.first_name) + " " + str(self.last_name)

        if self.first_name and not self.last_name:
            self.full_name = str(self.first_name)

        if not self.first_name and self.last_name:
            self.full_name = str(self.last_name)

        super(Customer, self).save(*args, **kwargs)

    def __str__(self):
        return str(self.full_name)

auditlog.register(Customer)

class Language(models.Model):
    name = models.CharField(max_length=50, unique=True, choices=LANGUAGE_CHOICES, null=True)
    logo = models.ImageField(upload_to='languages/', blank=True, null=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Language')
        verbose_name_plural = _('Languages')

auditlog.register(Language)

class Currency(models.Model):
    name = models.CharField(max_length=50, unique=True, choices=CURRENCY_CHOICES,  null=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Currency')
        verbose_name_plural = _('Currencies')

auditlog.register(Currency)

class Faqs(TranslatableModel):
    translations = TranslatedFields(
        question=models.TextField(_("question"), max_length=150, blank=True, null=True),
        answer=models.TextField(_("answer"), max_length=555, blank=True, null=True)
    )
    created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)

    def __str__(self):
        return str(self.question)

    class Meta:
        verbose_name = _('FAQ')
        verbose_name_plural = _('FAQs')

auditlog.register(Faqs)

class UserPreference(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, blank=True, null=True)
    company = models.ForeignKey(Company, on_delete=models.SET_NULL, blank=True, null=True)
    language = models.ForeignKey(Language, on_delete=models.SET_NULL, blank=True, null=True)
    currency = models.ForeignKey(Currency, on_delete=models.SET_NULL, blank=True, null=True)

    def __str__(self):
        return str(self.user)

    class Meta:
        verbose_name = 'User Preference'
        verbose_name_plural = 'User Preferences'

auditlog.register(UserPreference)

class CompanyUser(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
    company = models.ForeignKey(Company, on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return str(self.user)

    class Meta:
        verbose_name = 'Company User'
        verbose_name_plural = 'Company Users'

auditlog.register(CompanyUser)


from sklearn import tree
import pandas as pd

data = pd.read_csv("Lab_exp_5/DT.csv")
print(data)
from sklearn.preprocessing import LabelEncoder

Le = LabelEncoder()
data["OL"] = Le.fit_transform(data["OL"])
data["Temp"] = Le.fit_transform(data["Temp"])
data["Hum"] = Le.fit_transform(data["Hum"])
data["Wind"] = Le.fit_transform(data["Wind"])
data["PT"] = Le.fit_transform(data["PT"])
print(data)
y = data["PT"]
X = data.drop(["PT"], axis=1)
clf = tree.DecisionTreeClassifier(criterion="entropy")
clf = clf.fit(X, y)
# To view the tree as a graph
import graphviz

dot_data = tree.export_graphviz(clf, out_file=None)
graph = graphviz.Source(dot_data)
print(graph)
# To view the tree in Text Format
from sklearn.tree import export_text
feature_names = list(X.columns)
r = export_text(clf,feature_names=feature_names)
print(r)


import sys
import datetime

import django
from webalessio.models import User

##########################################
# Little schema to see when to send emails
# F=from, T=to, TD=today
#
#   ---------------------
#   | F | T |  SEND IF  |
#   |   |   |  always   |
#   | A |   |   TD<A    |
#   |   | A |   TD>A    |
#   | A | B | !A<=TD<=B |
#   ---------------------

if __name__ == '__main__':
    #export DJANGO_SETTINGS_MODULE=alessiobot.settings
    django.setup()
    today = datetime.date.today() #time are UTC !
    users_today = []

    for user in User.objects.all():
        if ((not user.suspend_from and not user.suspend_until) or
           (user.suspend_from and today < user.suspend_from) or
           (user.suspend_until and today > user.suspend_until) or
           (user.suspend_from and user.suspend_until and not
           (user.suspend_from <= today <= user.suspend_until))):
            users_today.append(user)

    if users_today:
        print("To: " + ', '.join([user.email for user in users_today]))
        sys.exit(0)
    else:
        sys.exit(1)


import telegram
from telegram import Update, Bot
from telegram.ext import MessageHandler, Updater, CommandHandler, CallbackContext
import requests
import re
bot = telegram.Bot(token="1979535666:AAENGjjo0OXFF7-_5ne5EnMhcJZvfhkf6Yk")
def get_url():
    contents = requests.get('https://api.thecatapi.com/v1/images/search').json()
    image_url = contents[0]['url']
    return image_url

# def get_image_url():
#     allowed_extension = ['jpg','jpeg','png']
#     file_extension = ''
#     while file_extension not in allowed_extension:
#         url = get_url()
#         file_extension = re.search("([^.]*)$",url).group(1).lower()
#     return url

def boop(update: Update, context: CallbackContext):
    url=get_url()
    bot.send_photo(update.effective_message.chat_id, photo=url)

def main():
    updater = Updater('xxxx', use_context = True)
    dp = updater.dispatcher
    dp.add_handler(CommandHandler('boop',boop))
    updater.start_polling()
    updater.idle()

if __name__ == '__main__':
    main()


from selenium import webdriver
from selenium.webdriver.common.by import By

import time

try:
    link = 'http://suninjuly.github.io/registration2.html'
    browser = webdriver.Chrome()
    browser.get(link)

    # Ваш код, который заполняет обязательные поля

    input_1 = browser.find_element(By.CSS_SELECTOR, '.first_block .first')
    input_1.send_keys('test.txt')

    input_2 = browser.find_element(By.CSS_SELECTOR, '.first_block .second')
    input_2.send_keys('test.txt')

    input_3 = browser.find_element(By.CSS_SELECTOR, '.first_block .third')
    input_3.send_keys('test.txt')

    button = browser.find_element(By.CSS_SELECTOR, 'button.btn')
    button.click()

    time.sleep(1)
    welcome_text_elt = browser.find_element(By.TAG_NAME, 'h1')
    welcome_text = welcome_text_elt.text

    assert 'Congratulations! You have successfully registered!' == welcome_text

finally:
    time.sleep(10)
    browser.quit()

section_1/1_6_Уникальность селекторов_2.py

1_6_Уникальность селекторов_2.py


import graphene
from graphene import NonNull, Schema, String
from graphene.test import Client
from graphene_django.utils import GraphQLTestCase

from courses.models.Category import Category
from courses.models.Course import Course
from courses.models.LearningFormat import LearningFormat
from users.models import User
from users.models.Teacher import Teacher

from ...models.Lesson import Lesson
from ...models.LessonTypeChoices import LessonTypeChoices
from ...nodes.LessonTypeNode import LessonTypeNode
from ...schema.PublicLessonType import PublicLessonType

class PublicLessonTypeTestCase(GraphQLTestCase):
    databases = {'master', }

    @classmethod
    def setUpTestData(cls):
        cls.tested_class = PublicLessonType
        cls.model = Lesson

        user = User.objects.create_user(**{
            'email': 'q' * 50 + '@q.qq',
            'password': 'q' * 50,
        })

        teacher = Teacher.objects.create(**{
            'user': user,
            'description': 'q' * 50,
        })

        category = Category.objects.create(**{
            'title': 'q' * 50,
        })

        course = Course.objects.create(**{
            'teacher': teacher,
            'title': 'q' * 50,
            'price': 50.0,
            'count_lectures': 50,
            'count_independents': 50,
            'duration': 50,
            'learning_format': LearningFormat.REMOTE,
            'category': category,
            'preview': 'temporary_img',
            'short_description': 'q' * 50,
        })

        lesson = Lesson.objects.create(**{
            'id': 1,
            'course': course,
            'title': 'q' * 50,
            'description': 'q' * 50,
            'lesson_type': LessonTypeChoices.THEME,
        })

        Lesson.objects.create(**{
            'id': 2,
            'course': course,
            'title': 'q' * 50,
            'description': 'q' * 50,
            'lesson_type': LessonTypeChoices.THEORY,
            'parent': lesson,
        })

        Lesson.objects.create(**{
            'id': 3,
            'course': course,
            'title': 'q' * 50,
            'description': 'q' * 50,
            'lesson_type': LessonTypeChoices.TEST,
            'parent': lesson,
        })

    def setUp(self):
        class PublicLessonQuery(graphene.ObjectType):
            public_lesson = LessonTypeNode.Field(PublicLessonType)

        schema = Schema(query=PublicLessonQuery)
        self.gql_client = Client(schema=schema)

    def test_Should_IncludeDefiniteDjangoModel(self):
        expected_model = self.model
        real_model = self.tested_class._meta.model

        self.assertEqual(expected_model, real_model)

    def test_Should_IncludeDefiniteInterfaces(self):
        expected_interfaces = [
            LessonTypeNode,
        ]
        real_interfaces = list(self.tested_class._meta.interfaces)

        self.assertEqual(expected_interfaces, real_interfaces)

    def test_Should_IncludeDefiniteFieldsFromModel(self):
        expected_fields = [
            'id', 'serial_number', 'title', 'description', 'lesson_type',
        ]
        real_fields = list(self.tested_class._meta.fields)

        self.assertEqual(expected_fields, real_fields)

    def test_Should_SpecificTypeForEachField(self):
        expected_fields = {
            'lesson_type': String,
            'serial_number': String,
        }
        real_fields = {
            key: value.type
            for key, value in self.tested_class._meta.fields.items()
        }

        all_fields_is_nonnull = all([
            real_fields.pop(field).__class__ == NonNull for field in [
                'id', 'title', 'description',
            ]
        ])

        self.assertEqual(expected_fields, real_fields)
        self.assertTrue(all_fields_is_nonnull)

    def test_When_SendQueryWithParentId_Should_ReturnDataWithOutErrors(self):
        response = self.gql_client.execute(
            """
            query {
                publicLesson (id: "UHVibGljTGVzc29uVHlwZTox") {
                    id
                    title
                    description
                    lessonType
                    serialNumber
                }
            }
            """
        )

        expected_response = {
            'data': {
                'publicLesson': {
                    'id': 'TGVzc29uVHlwZTox',
                    'title': 'q' * 50,
                    'description': 'q' * 50,
                    'lessonType': 'Тема',
                    'serialNumber': '1.',
                },
            },
        }
        real_response = response

        self.assertEqual(expected_response, real_response)

    def test_When_SendQueryWithChildrenId_Should_ReturnDataWithOutErrors(self):
        response = self.gql_client.execute(
            """
            query {
                publicLesson (id: "UHVibGljTGVzc29uVHlwZToy") {
                    id
                    title
                    description
                    lessonType
                    serialNumber
                }
            }
            """
        )

        expected_response = {
            'data': {
                'publicLesson': {
                    'id': 'TGVzc29uVHlwZToy',
                    'title': 'q' * 50,
                    'description': 'q' * 50,
                    'lessonType': 'Теория',
                    'serialNumber': '1.1.',
                },
            },
        }
        real_response = response

        self.assertEqual(expected_response, real_response)

    def test_When_SendQueryWithTestId_Should_ReturnDataWithOutErrors(self):
        response = self.gql_client.execute(
            """
            query {
                publicLesson (id: "UHVibGljTGVzc29uVHlwZToz") {
                    lessonType
                }
            }
            """
        )

        expected_response = {
            'data': {
                'publicLesson': {
                    'lessonType': 'Тест',
                },
            },
        }
        real_response = response

        self.assertEqual(expected_response, real_response)


""" The package snap.py works on python 2.7 only """

from collections import Counter, defaultdict

import matplotlib.pyplot as plt

try:
   import cPickle as pickle
except:
   import pickle
import os
from numpy import linspace as lrange

'''
This file create dictionary of categories exists in the database
'''

__author__ = 'slouis'
'''
This file reads in/out degree distributions of the citation graph.
The nodes are from both files: patent.txt & citations.txt files (to ensure we have also nodes of degree 0.

Outputs:
'''

project_dir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', '..'))
input_dir = os.path.join(project_dir, 'data', 'raw')
output_dir = os.path.join(project_dir, 'data', 'processed')
if not os.path.exists(output_dir):
    os.makedirs(output_dir)
LIMIT_NUM_ROWS = float("inf") #float("inf") #

print("Loading the data")
CATEGORIES_FILE_PATH = os.path.join(input_dir, 'categories.txt')

categories = defaultdict(int)
main_categories = defaultdict(int)

print("Reading categories file")
with open(CATEGORIES_FILE_PATH, mode='r') as vf:
    next(vf)
    row_counter = 0
    for line in vf:
        if row_counter % 100000 == 0 : print(row_counter)
        row_counter +=1
        splittedRow = line.strip().split()
        if splittedRow[-1]=="1" : main_categories["".join(splittedRow[1:-1])] += 1
        categories["".join(splittedRow[1:-1])] += 1
        if row_counter >= LIMIT_NUM_ROWS:
            break

pickle.dump(categories,open(os.path.join(output_dir, 'categories_in_db_'+ str(row_counter)+'.pickle'),'wb'))
pickle.dump(main_categories,open(os.path.join(output_dir, 'main_categories_in_db_'+ str(row_counter)+'.pickle'),'wb'))

print('done.')
pass


import numpy
import pyqtgraph as pg
import pyqtgraph.opengl as gl
from pyqtgraph.Qt import QtCore, QtGui
from pyqtgraph.dockarea import *
from pyqtgraph.dockarea import *
from pyqtgraph.parametertree import ParameterTree
from color_dock import *
import logging
from . import planeVector
from ndviewer_options import *

nameToPattern = {
    'SolidPattern': QtCore.Qt.SolidPattern,
    'LinearGradientPattern': QtCore.Qt.LinearGradientPattern,
    'Dense1Pattern': QtCore.Qt.Dense1Pattern,
    'Dense2Pattern': QtCore.Qt.Dense2Pattern,
    'Dense3Pattern': QtCore.Qt.Dense3Pattern,
    'Dense4Pattern': QtCore.Qt.Dense4Pattern,
    'Dense5Pattern': QtCore.Qt.Dense5Pattern,
    'Dense6Pattern': QtCore.Qt.Dense6Pattern,
    'Dense7Pattern': QtCore.Qt.Dense7Pattern,
    'NoBrush': QtCore.Qt.NoBrush,
    'HorPattern': QtCore.Qt.HorPattern,
    'VerPattern': QtCore.Qt.VerPattern,
    'CrossPattern': QtCore.Qt.CrossPattern,
    'BDiagPattern': QtCore.Qt.BDiagPattern,
    'FDiagPattern': QtCore.Qt.FDiagPattern,
    'DiagCrossPattern': QtCore.Qt.DiagCrossPattern
}

class TiledViewBox(pg.ViewBox):
    def __init__(self, ndViewer, plane, parent=None):

        pv = ndViewer.paramValue
        self.bgType  = pv(('ViewBox Options','ViewBox Background','bg-type'))
        self.bgColor1 = pv(('ViewBox Options','ViewBox Background','bg-color 1'))
        self.bgColor2 = pv(('ViewBox Options','ViewBox Background','bg-color 2'))
        super(TiledViewBox,self).__init__(invertY=True,lockAspect=True)
        self.ndViewer = ndViewer
        self.plane = plane
        # connect background parameters
        for c in ndViewer.param('ViewBox Options','ViewBox Background').children():
            c.sigValueChanged.connect(self.backgroundChanged)

        # rect changed
        self.sigXRangeChanged.connect(self.rectChanged)
        self.sigYRangeChanged.connect(self.rectChanged)

        self.updateBackground()
    def rectChanged(self):
        self.updateBackground()

    def backgroundChanged(self, param, changes):
        pv = self.ndViewer.paramValue
        self.bgType  = pv(('ViewBox Options','ViewBox Background','bg-type'))
        self.bgColor1 = pv(('ViewBox Options','ViewBox Background','bg-color 1'))
        self.bgColor2 = pv(('ViewBox Options','ViewBox Background','bg-color 2'))

        self.updateBackground()

    def updateBackground(self):
        self.background.show()
        self.background.setVisible(True)
        if self.bgType == 'LinearGradientPattern':
            g =  QtGui.QLinearGradient(
                                       QtCore.QRectF(self.rect()).topLeft(),
                                       QtCore.QRectF(self.rect()).bottomLeft()
            )
            g.setColorAt(0, self.bgColor1);
            g.setColorAt(1, self.bgColor2);
            brush = QtGui.QBrush(g)
        else:
            brush = QtGui.QBrush()
            brush.setStyle(nameToPattern[str(self.bgType)])
            brush.setColor(self.bgColor1)

        self.background.setBrush(brush)
    def setBackgroundColor(self):
        self.updateBackground()

class ViewBoxWidget(QtGui.QWidget):
    def __init__(self,ndViewer, plane, parent=None):

        super(ViewBoxWidget,self).__init__(parent=parent)
        self.mainLayout = QtGui.QVBoxLayout()
        self.glayout = pg.GraphicsLayout()
        self.graphicsView = pg.GraphicsView()

        # the view box
        self.viewBox = TiledViewBox(ndViewer=ndViewer, plane=plane)

        # the scales
        self.xAxis = pg.AxisItem(orientation='bottom', linkView=self.viewBox)
        self.yAxis = pg.AxisItem(orientation='left', linkView=self.viewBox)
        #self.xScale.setLabel(text=aixsLetters[viewAxis[0]])
        #@self.yScale.setLabel(text=aixsLetters[viewAxis[1]])

        # parameter interaction
        p = ndViewer.param('ViewBox Options','Show Axis')
        def showAxisChanged(param, changes):
            if changes == True:
                self.glayout.addItem(self.xAxis,2,1)
                self.glayout.addItem(self.yAxis,1,0)
            else:
                self.glayout.removeItem(self.xAxis)
                self.glayout.removeItem(self.yAxis)
        p.sigValueChanged.connect(showAxisChanged)

        def setupUI():
            # set the main layout
            self.setLayout(self.mainLayout)

            # make the graphics-view  the central widget
            self.mainLayout.addWidget(self.graphicsView)

            # add layout to graphics-view
            self.graphicsView.setCentralItem(self.glayout)

            # add items to layout
            self.glayout.addItem(self.viewBox,1,1)

        #  layouting etc
        setupUI()

class OpenGl3dWidget(QtGui.QWidget):
    def __init__(self, ndViewer):
        super(OpenGl3dWidget,self).__init__()
        self.ndViewer = ndViewer

        def _setupUI():
            self.mainLayout = QtGui.QHBoxLayout()
            self.setLayout(self.mainLayout)
        _setupUI()

class LayerStackCtrlWidget(QtGui.QWidget):
    def __init__(self, ndViewer):
        super(LayerStackCtrlWidget,self).__init__()
        self.ndViewer = ndViewer

        def _setupUI():
            self.mainLayout = QtGui.QHBoxLayout()
            self.setLayout(self.mainLayout)
        _setupUI()

class SettingsEditorDialog(QtGui.QDialog):

    def __init__(self,ndViewer, parent):
        super(SettingsEditorDialog, self).__init__(parent)

        self.resize(800,600)
        self.ndViewer = ndViewer
        self.layout = QtGui.QVBoxLayout()
        self.setLayout(self.layout)

        self.paramTree = ParameterTree()
        self.paramTree.setParameters(self.ndViewer.options.p, showTop=False)
        self.layout.addWidget(self.paramTree)
    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.hide()
            event.accept()
        else:
            super(QtGui.QDialog, self).keyPressEvent(event)

# http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
class NdViewerCtrlWidget(QtGui.QWidget,object):
    def __init__(self, ndViewer):
        super(NdViewerCtrlWidget,self).__init__()
        self.ndViewer = ndViewer
        self._setupUI()
        self.diag = SettingsEditorDialog(ndViewer=self.ndViewer,parent=self)
    def _setupUI(self):
        self.mainLayout = QtGui.QHBoxLayout()
        self.setLayout(self.mainLayout)

        exitAction = QtGui.QAction(QtGui.QIcon.fromTheme("accessories-text-editor"), 'Settings', self)
        #exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Settings editor')
        exitAction.triggered.connect(self.showSettingsEditor)

        toolbar = QtGui.QToolBar()
        toolbar.addAction(exitAction)
        toolbar.setIconSize(QtCore.QSize(20,20))
        self.mainLayout.addWidget(toolbar)

    def showSettingsEditor(self):
        self.diag.show()

class NdViewerWidget(QtGui.QWidget):
    def __init__(self, globalAxis):
        super(NdViewerWidget,self).__init__()

        # global options object
        self.options = NdViewerOptions(ndViewer=self)

        self.globalAxis = globalAxis
        self.nDim = len(self.globalAxis)
        self.shape = self.globalAxis.shape
        self.planes = planeVector([])

        # widgets
        self.area = MyDockArea()
        self.area.setParent(self)
        self.ctrlWidget = NdViewerCtrlWidget(self)
        self.layerStackCtrlWidget = LayerStackCtrlWidget(ndViewer=self)
        self.layerDock = ColorDock(name="Layers", color=(50,)*3)

        self._setupUI()

    def _setupUI(self):
        self.mainLayout = QtGui.QVBoxLayout()
        self.setLayout(self.mainLayout)
        self.mainLayout.addWidget(self.ctrlWidget)
        self.mainLayout.addWidget(self.area)
        self.layerDock.addWidget(self.layerStackCtrlWidget)
        self.area.addDock(self.layerDock,'right')

    def paramValue(self, key):
        """ get the params value"""
        return self.options[key]

    def param(self, *args, **kwargs):
        """ get the param object"""
        return self.options.param(*args,**kwargs)

    def addOrthogonalPlaneViewer(self, plane, pos=None, otherDock=None):

        # add the plane
        plane.planeIndex = len(self.planes)
        self.planes.addPlane(plane)

        # color of the dock
        color = self._getDockColor(plane)
        # add the dock
        dock = ColorDock(name=plane.name, color=color)
        dock.setParent(self.area)
        # plance the dock
        self._placeDock(dock=dock, pos=pos, otherDock=otherDock)

        # the widget
        viewBoxWidget = ViewBoxWidget(ndViewer=self,plane=plane, parent=dock)
        dock.addWidget(viewBoxWidget)

        return dock

    def add3dViewer(self):
        if(self.ndim <= 2):
            raise RuntimeError("3d viewer needs at least 3 axis")
        assert  False

    def _getDockColor(self, plane):
        """ Helping function to get the color of the dock
        """
        color = (0,0,0)
        if plane.zAxis != -1:
            color = self.globalAxis[plane.zAxis].color[0:3]
        return color

    def _placeDock(self, dock, pos=None, otherDock=None):
        """ Helping function to place the docks
        """
        if otherDock is not None and pos is not None:
            self.area.addDock(dock,pos,otherDock)
        elif pos is not None:
            self.area.addDock(dock,pos,otherDock)
        else:
            self.area.addDock(dock)
        return dock


import keras
from keras.layers import Input, Embedding, LSTM, Dense
from keras.models import Model

class LSTM_M:
    def __init__(self, input_size, input_dim, embedding_size, hidden_size, n_classes, drop_out=0.5,
                 optimizer='rmsprop', loss_function='binary_crossentropy'):
        self.input_size = input_size
        self.input_dim = input_dim
        self.embedding_size = embedding_size
        self.hidden_size = hidden_size
        self.n_classes = n_classes
        self.drop_out = drop_out
        self.optimizer = optimizer
        self.loss_function = loss_function

    def create_model(self):
        # 입력 값
        main_input = Input(shape=(self.input_size,), dtype='int32', name='main_input')

        # 임베딩 층
        x = Embedding(output_dim=self.embedding_size, input_dim=self.input_dim, input_length=self.input_size)(main_input)

        # LSTM 층
        lstm_out = LSTM(self.hidden_size, dropout=self.drop_out)(x)

        # 출력 층
        main_output = Dense(1, activation='sigmoid', name='main_output')(lstm_out)

        # 모델
        model = Model(inputs=main_input, outputs=main_output)

        # 모델 컴파일
        model.compile(optimizer=self.optimizer, loss=self.loss_function, metrics=['acc'])

        return model


import sys
from collections import deque

sys.setrecursionlimit(10**4)
n, m = map(int, sys.stdin.readline().split())
memo = [[0, 0] for _ in range(101)]
queue = deque([])

for _ in range(n):
    x, y = map(int, sys.stdin.readline().split())
    memo[x][1] = y
for _ in range(m):
    u, v = map(int, sys.stdin.readline().split())
    memo[u][1] = v

queue.append((0, 1))

while queue:
    if memo[100][0] != 0:
        break
    point = queue.popleft()
    for i in range(1, 7):
        dx = point[1]+i
        if dx > 100:
            continue
        if memo[dx][0] == 0:
            if memo[dx][1] != 0:
                memo[point[1]] = [point[0] + 1, memo[dx][1]]
                queue.append((point[0] + 1, memo[dx][1]))
                continue
            memo[dx] = [point[0]+1, dx]
            queue.append((point[0]+1, dx))

print(memo[100][0])


import os
import time

import HandTrackingModule as hm
import cv2

wCam, hCam = 640, 488
cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, wCam)

folderPath: str = "finger"
mylist = os.listdir(folderPath)
print(mylist)
overlay = []

for impath in mylist:
    Image = cv2.imread(f'{folderPath}/{impath}')
    overlay.append(Image)
   # print(f'{folderPath}/{impath}')
#print(len(overlay))

pTime = 0

dectector = hm.handDetector()

while True:

    success, img = cap.read()
    img=dectector.findHands(img)

    h, w, c = overlay[3].shape

    img[0:h, 0:w] = overlay[3]

    cTime = time.time()
    fps = 1/(cTime-pTime)
    pTime=cTime

    cv2.putText(img, f'FPS: {int(fps)}', (400,70), cv2.FONT_HERSHEY_PLAIN,
                3, (255,0,0), 3)

    cv2.imshow("Image", img)
    cv2.waitKey(1)


'''
Ganga Nakarmi
West Virginia University
Coding assistance from Llew Williams

This code was used in collecting data for this research paper:
   "A crowdsourced approach to documenting users’ preferences for landscape attributes in the proposed Appalachian Geopark Region in West Virginia"

This was used to download a set of jpg images from Flickr.
The desired image names and urls were placed in a csv file for processing beforehand.
'''
import requests
import csv
import os
# need path to project folder
project_folder = os.path.abspath(os.path.dirname(__file__))

#csv folder
csv_folder = 'DESIRED_FOLDER'
csv_folder_path = os.path.join(project_folder, csv_folder)
csv_file_name = 'DESIRED_FILE_NAME.csv'
csv_folder_path_and_file = os.path.join(csv_folder_path, csv_file_name)

with open(csv_folder_path_and_file) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    line_count = 0
    for row in csv_reader:
        if line_count != 0:
            url = row[4]
            line_count += 1
            trimmed_file_name = os.path.basename(row[4])
            image_download_folder = os.path.join(project_folder,'RELATIVE_PATH_TO_OUTPUT_FOLDER')
            trimmed_file_name_and_path = os.path.join(image_download_folder,trimmed_file_name)
            r = requests.get(url, allow_redirects=True)
        else:
            line_count += 1

    print('Processed ' + str(line_count) + ' lines.')


import os
import json
import requests
from bs4 import BeautifulSoup as bs

from pprint import pprint

dir_path = os.path.dirname(os.path.realpath(__file__))
parent_path = os.path.dirname(dir_path)

# to update the mocs.json uncomment the last script tag in index.html and
# reload the window.
def run_image_get():
    mocs_data = dict()
    with open(dir_path + '/mocs.json', 'r', encoding='latin') as mocs_file:
        mocs_data = json.load(mocs_file)

    base_wiki_url = 'https://en.wikipedia.org'

    for key, moc in mocs_data.items():
        try:
            save_path = (parent_path +
                        '/resources/')

            saved_images = os.listdir(save_path)
            already_stored = any(
                    [str(moc['govtrack_id']) in img for img in saved_images])

            print('already stored:', moc['govtrack_id'], already_stored)

            if moc['in_office'] and not already_stored:
                try:
                    wiki_id = '/wiki/' + moc['wikipedia_id'].replace(' ', '_')
                    url = base_wiki_url + wiki_id
                    r = requests.get(url)
                    soup = bs(r.content, 'html.parser')
                    try:
                        card = soup.find('table', class_='infobox vcard')
                        img_link = card.find('a', class_='image')['href']
                        img_link = base_wiki_url + img_link

                        r = requests.get(img_link)
                        soup = bs(r.content, 'html.parser')
                        file_div = soup.find('div', class_='fullImageLink')
                        link = file_div.find('a')['href']

                        if 'https:' not in link:
                            link = 'https:' + link

                        r = requests.get(link, stream=True)
                        ending = url[-4:]
                        if '.' not in ending:
                            ending = '.jpg'
                        if '_Jr' in ending:
                            ending = '.jpg'

                        save_path += (moc['govtrack_id'] + ending)
                        with open(save_path, 'wb') as f:
                            for chunk in r.iter_content(chunk_size=1024):
                                if chunk:
                                    f.write(chunk)

                        print('stored image for', moc['govtrack_id'])

                    except AttributeError as e:
                        print('failed to find image for:', moc['govtrack_id'], url.encode('latin'))
                except KeyError as e:
                    print('no wiki url:', moc['govtrack_id'], moc['displayName'].encode('latin'))
        except KeyError as e:
            pass

run_image_get()


import numpy as np
import torch
from tsai.all import *
from scipy import io
import wandb
from fastai.callback.wandb import *
from getdata import get_fofu_data
from pathlib import Path

for_export = True

wandb.init()
config = wandb.config

path = Path('learners', config['export_name'])

# Either the condtions will be specified, or take the defaults
try:
    conds = config['desired_conditions']
    labels = config['condition_labels']
except KeyError:
    # Defaults
    conds = ['CL', 'CM', 'CH', 'PL', 'PM', 'PH', 'PRL', 'PRM', 'PRH']
    labels = [0, 0, 0, 1, 1, 1, 2, 2, 2]

# 1D lists with each entry holding a single X, Y pair, splits indicated if it is validation or training
X, Y, splits = get_fofu_data(valid_pct=config["valid_pct"], data_file=config["data_file"], variables=config["variables"], random_labels=config["random_labels"], desired_conditions=conds, condition_labels=labels, valid_subject=config["valid_subject"])

# Datasets needed for FastAI library
tfms = [None, Categorize()]
dsets = TSDatasets(X, Y, tfms=tfms, splits=splits, inplace=True)

# Get data loaders
batch_tfms = None #[TSStandardize(by_var=config["standardize_by_var"], by_sample=config["standardize_by_sample"])]
# Needed for fast ai library, here you can set the things that apply to whole data
dls = TSDataLoaders.from_dsets(dsets.train, dsets.valid, bs=config["batch_size"], batch_tfms=batch_tfms, shuffle=True, num_workers=8)

# Get model
cbs = []
model = InceptionTimePlus(dls.vars, dls.c, nf=config["nf"], bn=config["bn"], ks=config["ks"], bottleneck=config["bottleneck"],
                          conv_dropout=config["conv_dropout"], depth=config["depth"])
# Get learner
learner = Learner(dls, model, opt_func=Adam, metrics=accuracy, wd=config["wd"], cbs=cbs)
# Execute fit one cycle training
learner.fit_one_cycle(config["epochs"], lr_max=config["lr"])

learner.save_all(path='learners', dls_fname='dls', model_fname="model", learner_fname="learner")
print("########################################################################")
print("EXPORT SUCCESS!!!")
print("########################################################################")
wandb.finish()


import time
import pygame as _pygame
from monitor.ui.menu.pgm import config_controls as _ctrl
from monitor.ui.menu.pgm.widgets.widget import Widget
from monitor.ui.menu.pgm import locals as _locals

class KnobSelector(Widget):
    """
    KnobSelector widget.
    """

    def __init__(self,
                 title,
                 min_val,
                 max_val,
                 start_val,
                 incr=0.1,
                 speed_thresh=0.2,
                 alarm_color=(255, 0, 0),
                 off_on_limit=False,
                 selector_id='',
                 sfmt='{:1f}',
                 onchange=None,
                 onreturn=None,
                 **kwargs
                 ):
        """
        Description of the specific paramaters (see Widget class for generic ones):

        :param title: Title of the selector
        :type title: basestring
        :param elements: Elements of the selector
        :type elements: list
        :param selector_id: ID of the selector
        :type selector_id: basestring
        :param default: Index of default element to display
        :type default: int
        :param onchange: Callback when changing the selector
        :type onchange: function, NoneType
        :param onreturn: Callback when pressing return button
        :type onreturn: function, NoneType
        :param kwargs: Optional keyword-arguments for callbacks
        """
        super(KnobSelector, self).__init__(widget_id=selector_id, onchange=onchange,
                                           onreturn=onreturn, kwargs=kwargs)
        self._elements = []
        self._index = 0
        self._sformat = sfmt
        self._labelsize = 0

        # numerical value of selector
        self._min_val = min_val
        self._max_val = max_val
        self._value = start_val
        self._incr = incr
        self._speed_thresh = speed_thresh
        # behaviour when the selector reaches a limit: show "Off"?
        self._off_on_limit = off_on_limit

        # a list of timestamps for the 5 most recent clicks
        self._clicks = []
        # if value has reached min or max
        self._alarm_color = alarm_color

        # Public attributs
        self.label = title

    def _apply_font(self):
        """
        See upper class doc.
        """
        self._labelsize = self._font.size(self.label)[0]

    def draw(self, surface):
        """
        See upper class doc.
        """
        self._render()
        surface.blit(self._surface, self._rect.topleft)

    def get_value(self):
        """
        Return the current value of the selector.

        :return: Value and index as a float
        :rtype: float
        """
        return self._value

    def set_value(self, value):
        """
        Overriden from parent
        """
        self._value = value

    def get_step(self):
        """
        Return the nonlinear step size. This detects scrolling speed
        (via a moving window buffer of "click" timestamps),
        and adjusts the step size:
        step_value = 0.1 (default);
        step_value = 1.0 (fast);

        :return: Value
        :rtype: float
        """
        step_value = None
        # if click window is no yet fully populated
        if (len(self._clicks) < 5):
            step_value = self._incr
        else:
            delta_time = (self._clicks[-1] - self._clicks[0])
            if delta_time > self._speed_thresh:  # slow, more than 0.9 s for the last 5 clicks
                step_value = self._incr
            else:
                step_value = self._incr * 10
        return step_value

    def decrement(self):
        """
        decrement the value.
        The lowest value is capped at min_val

        :return: None
        """
        # update timestamps
        self._clicks.append(time.time())
        while (len(self._clicks) > 5):
            self._clicks.pop(0)
        self._value -= self.get_step()
        if self._value < self._min_val:
            self._value = self._min_val
        self.change()

    def increment(self):
        """
        increment the value
        The highest value is capped at max_val

        :return: None
        """
        # update timestamps
        self._clicks.append(time.time())
        while (len(self._clicks) > 5):
            self._clicks.pop(0)
        self._value += self.get_step()
        if self._value > self._max_val:
            self._value = self._max_val
        self.change()

    def _render(self):
        """
        See upper class doc.
        """
        if self._off_on_limit:
            if self._value == self._min_val or self._value == self._max_val:
                color = self._alarm_color
                string = "Off"
            else:
                color = self._font_selected_color
                string = self._sformat.format(self.get_value())
        else:
            string = self._sformat.format(self.get_value())
            if self.selected:
                color = self._font_selected_color
            else:
                color = self._font_color
            if self._value == self._min_val or self._value == self._max_val:
                color = self._alarm_color

        self._surface = self.render_string(string, color)

    def set_selection_format(self, s):
        """
        Change the text format.

        :param s: Selection text
        :type s: basestring
        :return: None
        """
        self._sformat = s

    def update(self, events):
        """
        See upper class doc.
        """
        updated = False
        for event in events:
            if event.type == _pygame.KEYDOWN:
                if event.key == _ctrl.MENU_CTRL_LEFT:
                    self.decrement()
                    updated = True
                elif event.key == _ctrl.MENU_CTRL_RIGHT:
                    self.increment()
                    updated = True
                elif event.key == _ctrl.MENU_CTRL_ENTER:
                    self.apply()
                    updated = True

            elif self.joystick_enabled and event.type == _pygame.JOYHATMOTION:
                if event.value == _locals.JOY_LEFT:
                    self.decrement()
                    updated = True
                elif event.value == _locals.JOY_RIGHT:
                    self.increment()
                    updated = True

            elif self.joystick_enabled and event.type == _pygame.JOYAXISMOTION:
                if event.axis == _locals.JOY_AXIS_X and event.value < _locals.JOY_DEADZONE:
                    self.decrement()
                    updated = True
                if event.axis == _locals.JOY_AXIS_X and event.value > -_locals.JOY_DEADZONE:
                    self.increment()
                    updated = True

            elif self.mouse_enabled and event.type == _pygame.MOUSEBUTTONUP:
                if self._rect.collidepoint(*event.pos):
                    # Check if mouse collides left or right as percentage, use only X coordinate
                    mousex, _ = event.pos
                    topleft, _ = self._rect.topleft
                    topright, _ = self._rect.topright
                    dist = mousex - (topleft + self._labelsize)  # Distance from label
                    if dist > 0:  # User clicked options, not label

                        # Position in percentage, if <0.5 user clicked left
                        pos = dist / float(topright - topleft - self._labelsize)
                        if pos <= 0.5:
                            self.decrement()
                        else:
                            self.increment()
                        updated = True

        return updated


from argparse import ArgumentParser
import cv2
import sys
import time
import numpy as np
import threading
from imutils.video.filevideostream import FileVideoStream
from mark_detector import MarkDetector
from os_detector import detect_os
from pose_estimator import PoseEstimator
from stabilizer import Stabilizer

# import the Queue class from Python 3
if sys.version_info >= (3, 0):
    from queue import Queue
# otherwise, import the Queue class for Python 2.7
else:
    from Queue import Queue

print("OpenCV version: {}".format(cv2.__version__))
# multiprocessing may not work on Windows and macOS, check OS for safety.
detect_os()

CNN_INPUT_SIZE = 128

# Take arguments from user input.
parser = ArgumentParser()
parser.add_argument("--video", type=str, default="abc.mp4",
                    help="Video file to be processed.")
parser.add_argument("--cam", type=int, default=None,
                    help="The webcam index.")
args = parser.parse_args()

class Main(threading.Thread):

    def __init__(self, cap, box_que, img_que, detector, video_src, sample_frame):
        threading.Thread.__init__(self)
        # self.condition = condition
        self.cap = cap
        self.img_que = img_que
        self.box_que = box_que
        self.mark_detector = detector
        self.video_src = video_src
        self.sample_frame = sample_frame

    def get_face(self, detector, img_queue, box_queue):
        """Get face from image queue. This function is used for multiprocessing"""
        while True:
            image = img_queue.get()
            box = detector.extract_cnn_facebox(image)
            box_queue.put(box)

    def run(self):

        # Introduce mark_detector to detect landmarks.
        box_thread = threading.Thread(target=self.get_face,
                                      args=(self.mark_detector, self.img_que, self.box_que))
        box_thread.start()

        head_thread = threading.Thread(target=self.process_head_pose,
                                       args=(self.sample_frame, self.img_que, self.box_que,
                                             self.cap, self.video_src, self.mark_detector))
        head_thread.start()

    def process_head_pose(self, sample_frame, img_queue, box_queue, cap, video_src, mark_detector):
        height, width = sample_frame.shape[:2]
        pose_estimator = PoseEstimator(img_size=(height, width))

        # Introduce scalar stabilizers for pose.
        pose_stabilizers = [Stabilizer(
            state_num=2,
            measure_num=1,
            cov_process=0.1,
            cov_measure=0.1) for _ in range(6)]

        tm = cv2.TickMeter()
        # cap.start()
        while True:
            # Read frame, crop it, flip it, suits your needs.
            frame = cap.read()
            if frame is None:
                break

            # Crop it if frame is larger than expected.
            # frame = frame[0:480, 300:940]

            # If frame comes from webcam, flip it so it looks like a mirror.
            if video_src == 0:
                frame = cv2.flip(frame, 2)

            # Pose estimation by 3 steps:
            # 1. detect face;
            # 2. detect landmarks;
            # 3. estimate pose

            # Feed frame to image queue.
            img_queue.put(frame)

            # Get face from box queue.
            facebox = box_queue.get()

            if facebox is not None:
                # Detect landmarks from image of 128x128.
                face_img = frame[facebox[1]: facebox[3],
                           facebox[0]: facebox[2]]
                face_img = cv2.resize(face_img, (CNN_INPUT_SIZE, CNN_INPUT_SIZE))
                face_img = cv2.cvtColor(face_img, cv2.COLOR_BGR2RGB)

                tm.start()
                marks = mark_detector.detect_marks([face_img])
                tm.stop()

                # Convert the marks locations from local CNN to global image.
                marks *= (facebox[2] - facebox[0])
                marks[:, 0] += facebox[0]
                marks[:, 1] += facebox[1]

                # Uncomment following line to show raw marks.
                # mark_detector.draw_marks(
                #     frame, marks, color=(0, 255, 0))

                # Uncomment following line to show facebox.
                # mark_detector.draw_box(frame, [facebox])

                # Try pose estimation with 68 points.
                pose = pose_estimator.solve_pose_by_68_points(marks)

                # Stabilize the pose.
                steady_pose = []
                pose_np = np.array(pose).flatten()
                for value, ps_stb in zip(pose_np, pose_stabilizers):
                    ps_stb.update([value])
                    steady_pose.append(ps_stb.state[0])
                steady_pose = np.reshape(steady_pose, (-1, 3))

                # Uncomment following line to draw pose annotation on frame.
                # pose_estimator.draw_annotation_box(
                #     frame, pose[0], pose[1], color=(255, 128, 128))

                # Uncomment following line to draw stabile pose annotation on frame.
                pose_estimator.draw_annotation_box(
                    frame, steady_pose[0], steady_pose[1], color=(128, 255, 128))

                # Uncomment following line to draw head axes on frame.
                # pose_estimator.draw_axes(frame, stabile_pose[0], stabile_pose[1])

            # Show preview.
            cv2.imshow("Preview", frame)
            if cv2.waitKey(1) == 27:
                break

    def stop(self):
        self.join()

def main():
    # Video source from webcam or video file.

    video_src = args.cam if args.cam is not None else args.video
    if video_src is None:
        print("Warning: video source not assigned, default webcam will be used.")
        video_src = 0

    cap = FileVideoStream(video_src, queue_size=200)
    cap.start()
    # time.sleep(0.15)
    if video_src == 0:
        cap.stream.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    sample_frame = cap.read()

    # Setup process and queues for multiprocessing.
    img_queue = Queue()
    box_queue = Queue()
    img_queue.put(sample_frame)
    mark_detector = MarkDetector()
    box_process = Main(cap, box_queue, img_queue, mark_detector, video_src, sample_frame)
    box_process.start()
    # cap.stop()

if __name__ == '__main__':
    # Video source from webcam or video file.
    main()


#!/usr/bin/python3
import csv
import numpy
import seaborn
import sys
import matplotlib.pyplot as plt
import json

def remove_not_values(perf_list):
    return [float(x.replace(',', '.')) for x in perf_list if x not in ['-', '']]

def parse_performances_from_csv_file(data_file):
    result = []
    with open(data_file, 'r') as f:
        reader = csv.reader(f, delimiter=',', quotechar='"')
        for row in reader:
            if len(row):
                result.append((row[0], remove_not_values(row[1:])))
    return result

def parse_performances_from_dict(securities):
    result = []
    for sec in securities:
        if all(i in sec for i in ["security", "performances"]):
            result.append((sec["security"], sec["performances"]))
        else:
            print(f"Invalid object {sec}")
    return result

def correlations_as_list(corr, names_list):
    result = []
    size = len(corr)
    for i in range(size):
        for j in range(size):
            # Not to get duplicates
            if i < j:
                result.append( (corr[i][j], (names_list[i], names_list[j])) )
    return result

def display_correlations(corr_dict, filter_function):
    for corr_val in sorted(corr_dict, reverse=True):
        if filter_function(corr_val):
            [sec_a, sec_b] = corr_dict[corr_val]
            print("{:.2f}: {:60} {:60}".format(corr_val, sec_a, sec_b))

def display_correlation_heatmap(corr, names_list, api_mode):
    mask = numpy.zeros_like(corr)
    mask[numpy.triu_indices_from(mask)] = True
    legends = names_list
    with seaborn.axes_style("white"):
        seaborn.set(rc={'figure.figsize':(40,30)})
        sns_plot = seaborn.heatmap(corr, mask=mask, square=True, center=0, annot=True, cmap="YlGnBu", xticklabels=legends, yticklabels=legends)
        plt.xticks(rotation=30, ha='right')
        plt.yticks(rotation=30)
        if api_mode:
            sns_plot.get_figure().savefig("output.png")
        else:
            plt.show()

def calculate_corr_matrix(perf_list, api_mode):
    perf = []
    names_list = []
    min_size = sys.maxsize
    for _, (name, perf_history) in enumerate(perf_list):
        perf_history_size = len(perf_history)
        # If vector size < 4, we discard it
        if perf_history_size >= 4:
            min_size = min(min_size, perf_history_size)
            names_list.append(name)
            perf.append(perf_history)
    if len(perf) < 2:
        raise Exception("Cannot compute correlations: not enough securities")

    # We normalize the size of all the vectors
    normalized_performances = []
    limiting = []
    for index, val in enumerate(perf):
        normalized_performances.append(val[:min_size])
        if len(val) == min_size:
            limiting.append(names_list[index])
    if not api_mode:
        print(f"\nLimiting: {min_size} quarters")
        for i in limiting:
            print(i)
    return numpy.corrcoef(normalized_performances), names_list, min_size, limiting

# Example input
# [('Security name 1', [2.32, 5.43, 4.65, 2.98, -1.15]), ('Security name 2', [9.47, 3.47, 3.1, 6.75, -7.63])
# api_mode: does not print nicely the results in the console, does not open the plot
def correlations(performances, api_mode=True):
    corr, names_list, min_size, limiting = calculate_corr_matrix(performances, api_mode)
    corr_list = correlations_as_list(corr, names_list)
    if not api_mode:
        print("\nHighly correlated securities")
        display_correlations(corr_list, lambda corr: corr > 0.8)
        print("\nNegatively correlated securities")
        display_correlations(corr_list, lambda corr: corr < -0.5)
        # based on performances by quarter
        history_years = min_size / 4
        print("\nHistory size: {} years".format(history_years))
    display_correlation_heatmap(corr, names_list, api_mode)
    return corr_list, min_size, limiting

if __name__ == '__main__':
    FILENAME = "data/portfolio.csv"
    perf_list = parse_performances_from_csv_file(FILENAME)
    # perf_json = json.loads('[{"security": "name1", "performances": [1, 2, 3, 4]}, {"security": "name2", "performances": [2, 4, 7, 9]}]')
    # perf_list = parse_performances_from_json(perf_json)
    correlations(perf_list, False)