#!/usr/bin/python3
"""
Add unit test for the class Base
"""
import os
import unittest
from models.base import Base
from models.rectangle import Rectangle
from models.square import Square

class TestBaseInstance(unittest.TestCase):
    """
    This class test the class Base about the instance.
    """

    def tests_instance(self):
        """
        Tests about:
            - positive integers
            - negative integers
            - boolean
            - string
            - tuple
            - set
            - list
            - empty
            - None
        """
        b = Base(1)
        self.assertEqual(b.id, 1)
        b = Base(12)
        self.assertEqual(b.id, 12)
        b = Base(201)
        self.assertEqual(b.id, 201)

        b = Base(-1)
        self.assertEqual(b.id, -1)
        b = Base(-12)
        self.assertEqual(b.id, -12)

        b = Base(True)
        self.assertEqual(b.id, True)

        b = Base('hello')
        self.assertEqual(b.id, 'hello')

        b = Base((1, 2, 3))
        self.assertEqual(b.id, (1, 2, 3))
        b = Base({1, 2, 3})
        self.assertEqual(b.id, {1, 2, 3})
        b = Base([1, 2, 3])
        self.assertEqual(b.id, [1, 2, 3])
        b = Base({'name': 'holberton', 'age': 6})
        self.assertEqual(b.id, {'name': 'holberton', 'age': 6})

        b = Base()
        self.assertEqual(b.id, 1)
        b = Base(None)
        self.assertEqual(b.id, 2)

    def tests_instance_error(self):
        """
        TESTS EXCEPTIONS:
            - more than one argument
        A test about the message is implemented.
        """
        with self.assertRaises(TypeError) as m:
            Base(1, 1)
        error_message = '__init__() takes from 1 to 2 positional arguments' \
                        ' but 3 were given'
        self.assertEqual(error_message, str(m.exception))

class TestBaseToJsonString(unittest.TestCase):
    """
    This class test the class Base about the function 'to_json_string()'.
    """

    def tests_to_json_string(self):
        """
        Tests about:
            - if the return value of 'to_dictionary()' is type(dict)
            - if the return value of 'to_json_string()' is type(str)
            - if the return value of 'to_json_string()' is list of dictionary
            - if the list is empty, return []
            - if the list is None, return []
        The function 'reset_id()' was added to the class Base. It's necessary
        for restart the id and permits making other tests.
        """

        Base.reset_id()
        r1 = Rectangle(10, 7, 2, 8)
        dictionary = r1.to_dictionary()
        json_dictionary = Base.to_json_string([dictionary])
        self.assertEqual(type(dictionary), dict)
        self.assertEqual(type(json_dictionary), str)
        self.assertEqual(json_dictionary, '[{"x": 2, "y": 8, "id": 1,'
                                          ' "height": 7, "width": 10}]')

        r1 = []
        list_dictionaries = Base.to_json_string(r1)
        self.assertEqual(list_dictionaries, '[]')

        r1 = None
        list_dictionaries = Base.to_json_string(r1)
        self.assertEqual(list_dictionaries, '[]')

    def tests_to_json_string_error(self):
        """
         TESTS EXCEPTIONS:
             - without argument
             - with too much argument
         """
        with self.assertRaises(TypeError):
            Base.to_json_string()

        with self.assertRaises(TypeError):
            Base.to_json_string([{1, 2, 3}], [{4, 5, 6}])

class TestBaseSaveToFile(unittest.TestCase):
    """
    This class test the class Base about the function 'save_to_file()'.
    """

    def tests_save_to_file(self):
        """
        Tests about:
            - list of Rectangle
            - list of Square
        The function os.remove() is necessary to delete the file
        and permits making other tests.
        """
        Base.reset_id()
        r1 = Rectangle(10, 7, 2, 8)
        r2 = Rectangle(2, 4)
        Rectangle.save_to_file([r1, r2])
        list_objs = ('[{"x": 2, "y": 8, "id": 1, "height": 7, "width": 10}, ' +
                     '{"x": 0, "y": 0, "id": 2, "height": 4, "width": 2}]')
        with open("Rectangle.json", "r", encoding='utf-8') as f:
            self.assertEqual(f.read(), list_objs)
        os.remove('Rectangle.json')

        Base.reset_id()
        r1 = Square(10, 7, 2, 8)
        r2 = Square(2, 4)
        Square.save_to_file([r1, r2])
        list_objs = ('[{"id": 8, "x": 7, "size": 10, "y": 2}, ' +
                     '{"id": 1, "x": 4, "size": 2, "y": 0}]')
        with open('Square.json', 'r', encoding='utf-8') as f:
            self.assertEqual(f.read(), list_objs)
        os.remove('Square.json')

    def tests_save_to_file_error(self):
        """
        TESTS EXCEPTIONS:
            - if list_objs is None for Rectangle file
            - if list_objs is None for Square file
        """
        Rectangle.save_to_file(None)
        list_objs = '[]'
        with open('Rectangle.json', 'r', encoding='utf-8') as f:
            self.assertEqual(f.read(), list_objs)
        os.remove('Rectangle.json')

        Square.save_to_file(None)
        list_objs = '[]'
        with open('Square.json', 'r', encoding='utf-8') as f:
            self.assertEqual(f.read(), list_objs)
        os.remove('Square.json')


import sys
_module = sys.modules[__name__]
del sys
anchors = _module
dataloader = _module
detect = _module
eval_widerface = _module
losses = _module
model = _module
pose = _module
datasets = _module
detect_image = _module
hopenet = _module
test_alexnet = _module
test_hopenet = _module
test_on_video = _module
test_on_video_dlib = _module
test_on_video_dockerface = _module
test_resnet50_regression = _module
train_alexnet = _module
train_hopenet = _module
train_resnet50_regression = _module
utils = _module
pose_detect = _module
torchvision_model = _module
train = _module
utils = _module
video_detect = _module

from _paritybench_helpers import _mock_config, patch_functional
from unittest.mock import mock_open, MagicMock
from torch.autograd import Function
from torch.nn import Module
import abc, collections, copy, enum, functools, inspect, itertools, logging, math, matplotlib, numbers, numpy, pandas, queue, random, re, scipy, sklearn, string, tensorflow, time, torch, torchaudio, torchtext, torchvision, types, typing, uuid, warnings
import numpy as np
from torch import Tensor
patch_functional()
open = mock_open()
yaml = logging = sys = argparse = MagicMock()
ArgumentParser = argparse.ArgumentParser
_global_config = args = argv = cfg = config = params = _mock_config()
argparse.ArgumentParser.return_value.parse_args.return_value = _global_config
yaml.load.return_value = _global_config
sys.argv = _global_config
__version__ = '1.0.0'
xrange = range
wraps = functools.wraps

import numpy as np

import torch

import torch.nn as nn

import torchvision.transforms as transforms

from torch.utils.data.sampler import Sampler

from torch.utils.data import Dataset

import torch.nn.functional as F

import random

import math

import torchvision

import torchvision.ops as ops

import numpy as numpy

import time

import torch.utils.model_zoo as model_zoo

import pandas as pd

from torch.utils.data.dataset import Dataset

from torchvision import transforms

import matplotlib.pyplot as plt

from torch.autograd import Variable

from torch.utils.data import DataLoader

import torch.backends.cudnn as cudnn

import scipy.io as sio

from math import cos

from math import sin

import torchvision.models.detection.backbone_utils as backbone_utils

import torchvision.models.resnet as resnet

import torchvision.models._utils as _utils

from collections import OrderedDict

import torch.optim as optim

from torchvision import datasets

from torchvision import models

from torch.optim import lr_scheduler

import torch.distributed as dist

from torch.utils.data.distributed import DistributedSampler

def generate_anchors(base_size=16, ratios=None, scales=None):
    """
    Generate anchor (reference) windows by enumerating aspect ratios X
    scales w.r.t. a reference window.
    """
    if ratios is None:
        ratios = np.array([1, 1, 1])
    if scales is None:
        scales = np.array([2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)])
    num_anchors = len(scales)
    anchors = np.zeros((num_anchors, 4))
    anchors[:, 2:] = base_size * np.tile(scales, (2, 1)).T
    anchors[:, 0::2] -= np.tile(anchors[:, (2)] * 0.5, (2, 1)).T
    anchors[:, 1::2] -= np.tile(anchors[:, (3)] * 0.5, (2, 1)).T
    return anchors

def shift(shape, stride, anchors):
    shift_x = (np.arange(0, shape[1]) + 0.5) * stride
    shift_y = (np.arange(0, shape[0]) + 0.5) * stride
    shift_x, shift_y = np.meshgrid(shift_x, shift_y)
    shifts = np.vstack((shift_x.ravel(), shift_y.ravel(), shift_x.ravel(), shift_y.ravel())).transpose()
    A = anchors.shape[0]
    K = shifts.shape[0]
    all_anchors = anchors.reshape((1, A, 4)) + shifts.reshape((1, K, 4)).transpose((1, 0, 2))
    all_anchors = all_anchors.reshape((K * A, 4))
    return all_anchors

class Anchors(nn.Module):

    def __init__(self, pyramid_levels=None, strides=None, sizes=None, ratios=None, scales=None):
        super(Anchors, self).__init__()
        if pyramid_levels is None:
            self.pyramid_levels = [3, 4, 5]
        if strides is None:
            self.strides = [(2 ** x) for x in self.pyramid_levels]
        if sizes is None:
            self.sizes = [2 ** 4.0, 2 ** 6.0, 2 ** 8.0]
        if ratios is None:
            self.ratios = np.array([1, 1, 1])
        if scales is None:
            self.scales = np.array([2 ** 0, 2 ** (1 / 2.0), 2 ** 1.0])

    def forward(self, image):
        image_shape = image.shape[2:]
        image_shape = np.array(image_shape)
        image_shapes = [((image_shape + 2 ** x - 1) // 2 ** x) for x in self.pyramid_levels]
        all_anchors = np.zeros((0, 4)).astype(np.float32)
        for idx, p in enumerate(self.pyramid_levels):
            anchors = generate_anchors(base_size=self.sizes[idx], ratios=self.ratios, scales=self.scales)
            shifted_anchors = shift(image_shapes[idx], self.strides[idx], anchors)
            all_anchors = np.append(all_anchors, shifted_anchors, axis=0)
        all_anchors = np.expand_dims(all_anchors, axis=0)
        return torch.from_numpy(all_anchors.astype(np.float32))

def calc_iou(a, b):
    area = (b[:, (2)] - b[:, (0)]) * (b[:, (3)] - b[:, (1)])
    iw = torch.min(torch.unsqueeze(a[:, (2)], dim=1), b[:, (2)]) - torch.max(torch.unsqueeze(a[:, (0)], 1), b[:, (0)])
    ih = torch.min(torch.unsqueeze(a[:, (3)], dim=1), b[:, (3)]) - torch.max(torch.unsqueeze(a[:, (1)], 1), b[:, (1)])
    iw = torch.clamp(iw, min=0)
    ih = torch.clamp(ih, min=0)
    ua = torch.unsqueeze((a[:, (2)] - a[:, (0)]) * (a[:, (3)] - a[:, (1)]), dim=1) + area - iw * ih
    ua = torch.clamp(ua, min=1e-08)
    intersection = iw * ih
    IoU = intersection / ua
    return IoU

class LossLayer(nn.Module):

    def __init__(self):
        super(LossLayer, self).__init__()
        self.smoothl1 = nn.SmoothL1Loss()

    def forward(self, classifications, bbox_regressions, ldm_regressions, anchors, annotations):
        batch_size = classifications.shape[0]
        classification_losses = []
        bbox_regression_losses = []
        ldm_regression_losses = []
        anchor = anchors[(0), :, :]
        anchor_widths = anchor[:, (2)] - anchor[:, (0)]
        anchor_heights = anchor[:, (3)] - anchor[:, (1)]
        anchor_ctr_x = anchor[:, (0)] + 0.5 * anchor_widths
        anchor_ctr_y = anchor[:, (1)] + 0.5 * anchor_heights
        positive_indices_list = []
        for j in range(batch_size):
            classification = classifications[(j), :, :]
            bbox_regression = bbox_regressions[(j), :, :]
            ldm_regression = ldm_regressions[(j), :, :]
            annotation = annotations[(j), :, :]
            annotation = annotation[annotation[:, (0)] > 0]
            bbox_annotation = annotation[:, :4]
            ldm_annotation = annotation[:, 4:]
            if bbox_annotation.shape[0] == 0:
                bbox_regression_losses.append(torch.tensor(0.0, requires_grad=True))
                classification_losses.append(torch.tensor(0.0, requires_grad=True))
                ldm_regression_losses.append(torch.tensor(0.0, requires_grad=True))
                positive_indices_list.append([])
                continue
            IoU = calc_iou(anchors[(0), :, :], bbox_annotation[:, :4])
            IoU_max, IoU_argmax = torch.max(IoU, dim=1)
            targets = torch.ones(classification.shape) * -1
            targets = targets
            negative_indices = torch.lt(IoU_max, 0.3)
            targets[(negative_indices), :] = 0
            targets[negative_indices, 1] = 1
            positive_indices = torch.ge(IoU_max, 0.5)
            positive_indices_list.append(positive_indices)
            num_positive_anchors = positive_indices.sum()
            keep_negative_anchors = num_positive_anchors * 3
            bbox_assigned_annotations = bbox_annotation[(IoU_argmax), :]
            ldm_assigned_annotations = ldm_annotation[(IoU_argmax), :]
            targets[(positive_indices), :] = 0
            targets[positive_indices, 0] = 1
            ldm_sum = ldm_assigned_annotations.sum(dim=1)
            ge0_mask = ldm_sum > 0
            ldm_positive_indices = ge0_mask & positive_indices
            negative_losses = classification[negative_indices, 1] * -1
            sorted_losses, _ = torch.sort(negative_losses, descending=True)
            if sorted_losses.numel() > keep_negative_anchors:
                sorted_losses = sorted_losses[:keep_negative_anchors]
            positive_losses = classification[positive_indices, 0] * -1
            focal_loss = False
            if focal_loss:
                alpha = 0.25
                gamma = 2.0
                alpha_factor = torch.ones(targets.shape) * alpha
                alpha_factor = torch.where(torch.eq(targets, 1.0), alpha_factor, 1.0 - alpha_factor)
                focal_weight = torch.where(torch.eq(targets, 1.0), 1.0 - classification, classification)
                focal_weight = alpha_factor * torch.pow(focal_weight, gamma)
                bce = -(targets * torch.log(classification) + (1.0 - targets) * torch.log(1.0 - classification))
                cls_loss = focal_weight * bce
                cls_loss = torch.where(torch.ne(targets, -1.0), cls_loss, torch.zeros(cls_loss.shape))
                classification_losses.append(cls_loss.sum() / torch.clamp(num_positive_anchors.float(), min=1.0))
            elif positive_indices.sum() > 0:
                classification_losses.append(positive_losses.mean() + sorted_losses.mean())
            else:
                classification_losses.append(torch.tensor(0.0, requires_grad=True))
            if positive_indices.sum() > 0:
                bbox_assigned_annotations = bbox_assigned_annotations[(positive_indices), :]
                anchor_widths_pi = anchor_widths[positive_indices]
                anchor_heights_pi = anchor_heights[positive_indices]
                anchor_ctr_x_pi = anchor_ctr_x[positive_indices]
                anchor_ctr_y_pi = anchor_ctr_y[positive_indices]
                gt_widths = bbox_assigned_annotations[:, (2)] - bbox_assigned_annotations[:, (0)]
                gt_heights = bbox_assigned_annotations[:, (3)] - bbox_assigned_annotations[:, (1)]
                gt_ctr_x = bbox_assigned_annotations[:, (0)] + 0.5 * gt_widths
                gt_ctr_y = bbox_assigned_annotations[:, (1)] + 0.5 * gt_heights
                targets_dx = (gt_ctr_x - anchor_ctr_x_pi) / (anchor_widths_pi + 1e-14)
                targets_dy = (gt_ctr_y - anchor_ctr_y_pi) / (anchor_heights_pi + 1e-14)
                targets_dw = torch.log(gt_widths / anchor_widths_pi)
                targets_dh = torch.log(gt_heights / anchor_heights_pi)
                bbox_targets = torch.stack((targets_dx, targets_dy, targets_dw, targets_dh))
                bbox_targets = bbox_targets.t()
                bbox_targets = bbox_targets / torch.Tensor([[0.1, 0.1, 0.2, 0.2]])
                bbox_regression_loss = self.smoothl1(bbox_targets, bbox_regression[(positive_indices), :])
                bbox_regression_losses.append(bbox_regression_loss)
            else:
                bbox_regression_losses.append(torch.tensor(0.0, requires_grad=True))
            if ldm_positive_indices.sum() > 0:
                ldm_assigned_annotations = ldm_assigned_annotations[(ldm_positive_indices), :]
                anchor_widths_l = anchor_widths[ldm_positive_indices]
                anchor_heights_l = anchor_heights[ldm_positive_indices]
                anchor_ctr_x_l = anchor_ctr_x[ldm_positive_indices]
                anchor_ctr_y_l = anchor_ctr_y[ldm_positive_indices]
                l0_x = (ldm_assigned_annotations[:, (0)] - anchor_ctr_x_l) / (anchor_widths_l + 1e-14)
                l0_y = (ldm_assigned_annotations[:, (1)] - anchor_ctr_y_l) / (anchor_heights_l + 1e-14)
                l1_x = (ldm_assigned_annotations[:, (2)] - anchor_ctr_x_l) / (anchor_widths_l + 1e-14)
                l1_y = (ldm_assigned_annotations[:, (3)] - anchor_ctr_y_l) / (anchor_heights_l + 1e-14)
                l2_x = (ldm_assigned_annotations[:, (4)] - anchor_ctr_x_l) / (anchor_widths_l + 1e-14)
                l2_y = (ldm_assigned_annotations[:, (5)] - anchor_ctr_y_l) / (anchor_heights_l + 1e-14)
                l3_x = (ldm_assigned_annotations[:, (6)] - anchor_ctr_x_l) / (anchor_widths_l + 1e-14)
                l3_y = (ldm_assigned_annotations[:, (7)] - anchor_ctr_y_l) / (anchor_heights_l + 1e-14)
                l4_x = (ldm_assigned_annotations[:, (8)] - anchor_ctr_x_l) / (anchor_widths_l + 1e-14)
                l4_y = (ldm_assigned_annotations[:, (9)] - anchor_ctr_y_l) / (anchor_heights_l + 1e-14)
                ldm_targets = torch.stack((l0_x, l0_y, l1_x, l1_y, l2_x, l2_y, l3_x, l3_y, l4_x, l4_y))
                ldm_targets = ldm_targets.t()
                scale = torch.ones(1, 10) * 0.1
                ldm_targets = ldm_targets / scale
                ldm_regression_loss = self.smoothl1(ldm_targets, ldm_regression[(ldm_positive_indices), :])
                ldm_regression_losses.append(ldm_regression_loss)
            else:
                ldm_regression_losses.append(torch.tensor(0.0, requires_grad=True))
        return torch.stack(classification_losses), torch.stack(bbox_regression_losses), torch.stack(ldm_regression_losses)

class PyramidFeatures(nn.Module):

    def __init__(self, C2_size, C3_size, C4_size, C5_size, feature_size=256):
        super(PyramidFeatures, self).__init__()
        self.P5_1 = nn.Conv2d(C5_size, feature_size, kernel_size=1, stride=1, padding=0)
        self.P5_upsampled = nn.Upsample(scale_factor=2, mode='nearest')
        self.P5_2 = nn.Conv2d(feature_size, feature_size, kernel_size=3, stride=1, padding=1)
        self.P4_1 = nn.Conv2d(C4_size, feature_size, kernel_size=1, stride=1, padding=0)
        self.P4_upsampled = nn.Upsample(scale_factor=2, mode='nearest')
        self.P4_2 = nn.Conv2d(feature_size, feature_size, kernel_size=3, stride=1, padding=1)
        self.P3_1 = nn.Conv2d(C3_size, feature_size, kernel_size=1, stride=1, padding=0)
        self.P3_upsampled = nn.Upsample(scale_factor=2, mode='nearest')
        self.P3_2 = nn.Conv2d(feature_size, feature_size, kernel_size=3, stride=1, padding=1)
        self.P6 = nn.Conv2d(C5_size, feature_size, kernel_size=3, stride=2, padding=1)
        self.P2_1 = nn.Conv2d(C2_size, feature_size, kernel_size=1, stride=1, padding=0)
        self.P2_2 = nn.Conv2d(feature_size, feature_size, kernel_size=3, stride=1, padding=1)

    def forward(self, inputs):
        C2, C3, C4, C5 = inputs
        P5_x = self.P5_1(C5)
        P5_upsampled_x = self.P5_upsampled(P5_x)
        P5_x = self.P5_2(P5_x)
        P4_x = self.P4_1(C4)
        P4_x = P5_upsampled_x + P4_x
        P4_upsampled_x = self.P4_upsampled(P4_x)
        P4_x = self.P4_2(P4_x)
        P3_x = self.P3_1(C3)
        P3_x = P3_x + P4_upsampled_x
        P3_upsampled_x = self.P3_upsampled(P3_x)
        P3_x = self.P3_2(P3_x)
        P2_x = self.P2_1(C2)
        P2_x = P2_x + P3_upsampled_x
        P2_x = self.P2_2(P2_x)
        P6_x = self.P6(C5)
        return [P2_x, P3_x, P4_x, P5_x, P6_x]

class ClassHead(nn.Module):

    def __init__(self, inchannels=512, num_anchors=3):
        super(ClassHead, self).__init__()
        self.num_anchors = num_anchors
        self.conv1x1 = nn.Conv2d(inchannels, self.num_anchors * 2, kernel_size=(1, 1), stride=1, padding=0)
        self.output_act = nn.LogSoftmax(dim=-1)

    def forward(self, x):
        out = self.conv1x1(x)
        out = out.permute(0, 2, 3, 1)
        b, h, w, c = out.shape
        out = out.view(b, h, w, self.num_anchors, 2)
        out = self.output_act(out)
        return out.contiguous().view(out.shape[0], -1, 2)

class BboxHead(nn.Module):

    def __init__(self, inchannels=512, num_anchors=3):
        super(BboxHead, self).__init__()
        self.conv1x1 = nn.Conv2d(inchannels, num_anchors * 4, kernel_size=(1, 1), stride=1, padding=0)

    def forward(self, x):
        out = self.conv1x1(x)
        out = out.permute(0, 2, 3, 1)
        return out.contiguous().view(out.shape[0], -1, 4)

class LandmarkHead(nn.Module):

    def __init__(self, inchannels=512, num_anchors=3):
        super(LandmarkHead, self).__init__()
        self.conv1x1 = nn.Conv2d(inchannels, num_anchors * 10, kernel_size=(1, 1), stride=1, padding=0)

    def forward(self, x):
        out = self.conv1x1(x)
        out = out.permute(0, 2, 3, 1)
        return out.contiguous().view(out.shape[0], -1, 10)

class ClassHead_(nn.Module):

    def __init__(self, inchannels=256, num_anchors=3):
        super(ClassHead_, self).__init__()
        self.num_anchors = num_anchors
        self.feature_head = self._make_head(self.num_anchors * 2)
        self.output_act = nn.LogSoftmax(dim=-1)

    def _make_head(self, out_size):
        layers = []
        for _ in range(4):
            layers += [nn.Conv2d(256, 256, 3, padding=1), nn.ReLU(inplace=True)]
        layers += [nn.Conv2d(256, out_size, 3, padding=1)]
        return nn.Sequential(*layers)

    def forward(self, x):
        out = self.feature_head(x)
        out = out.permute(0, 2, 3, 1)
        b, h, w, c = out.shape
        out = out.view(b, h, w, self.num_anchors, 2)
        out = self.output_act(out)
        return out.contiguous().view(out.shape[0], -1, 2)

class BboxHead_(nn.Module):

    def __init__(self, inchannels=256, num_anchors=3):
        super(BboxHead_, self).__init__()
        self.num_anchors = num_anchors
        self.feature_head = self._make_head(self.num_anchors * 4)

    def _make_head(self, out_size):
        layers = []
        for _ in range(4):
            layers += [nn.Conv2d(256, 256, 3, padding=1), nn.ReLU(inplace=True)]
        layers += [nn.Conv2d(256, out_size, 3, padding=1)]
        return nn.Sequential(*layers)

    def forward(self, x):
        out = self.feature_head(x)
        out = out.permute(0, 2, 3, 1)
        return out.contiguous().view(out.shape[0], -1, 4)

class LandmarkHead_(nn.Module):

    def __init__(self, inchannels=256, num_anchors=3):
        super(LandmarkHead_, self).__init__()
        self.num_anchors = num_anchors
        self.feature_head = self._make_head(self.num_anchors * 10)

    def _make_head(self, out_size):
        layers = []
        for _ in range(4):
            layers += [nn.Conv2d(256, 256, 3, padding=1), nn.ReLU(inplace=True)]
        layers += [nn.Conv2d(256, out_size, 3, padding=1)]
        return nn.Sequential(*layers)

    def forward(self, x):
        out = self.feature_head(x)
        out = out.permute(0, 2, 3, 1)
        return out.contiguous().view(out.shape[0], -1, 10)

class CBR(nn.Module):

    def __init__(self, inchannels, outchannels):
        super(CBR, self).__init__()
        self.conv3x3 = nn.Conv2d(inchannels, outchannels, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn = nn.BatchNorm2d(outchannels)
        self.relu = nn.ReLU(inplace=True)
        for m in self.modules():
            if isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')

    def forward(self, x):
        x = self.conv3x3(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

class CB(nn.Module):

    def __init__(self, inchannels):
        super(CB, self).__init__()
        self.conv3x3 = nn.Conv2d(inchannels, inchannels, kernel_size=3, stride=1, padding=1, bias=False)
        self.bn = nn.BatchNorm2d(inchannels)
        for m in self.modules():
            if isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')

    def forward(self, x):
        x = self.conv3x3(x)
        x = self.bn(x)
        return x

class Concat(nn.Module):

    def forward(self, *feature):
        out = torch.cat(feature, dim=1)
        return out

class Context(nn.Module):

    def __init__(self, inchannels=256):
        super(Context, self).__init__()
        self.context_plain = inchannels // 2
        self.conv1 = CB(inchannels)
        self.conv2 = CBR(inchannels, self.context_plain)
        self.conv2_1 = CB(self.context_plain)
        self.conv2_2_1 = CBR(self.context_plain, self.context_plain)
        self.conv2_2_2 = CB(self.context_plain)
        self.concat = Concat()
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        f1 = self.conv1(x)
        f2_ = self.conv2(x)
        f2 = self.conv2_1(f2_)
        f3 = self.conv2_2_1(f2_)
        f3 = self.conv2_2_2(f3)
        out = self.concat(f1, f2, f3)
        out = self.relu(out)
        return out

class ResNet(nn.Module):

    def __init__(self, block, layers, num_classes=1000):
        self.inplanes = 64
        super(ResNet, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, 64, layers[0])
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
        self.avgpool = nn.AvgPool2d(7)
        self.fc_angles = nn.Linear(512 * block.expansion, num_classes)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2.0 / n))
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

    def _make_layer(self, block, planes, blocks, stride=1):
        downsample = None
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(planes * block.expansion))
        layers = []
        layers.append(block(self.inplanes, planes, stride, downsample))
        self.inplanes = planes * block.expansion
        for i in range(1, blocks):
            layers.append(block(self.inplanes, planes))
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.fc_angles(x)
        return x

class Hopenet(nn.Module):

    def __init__(self, block, layers, num_bins):
        self.inplanes = 64
        super(Hopenet, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(64)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, 64, layers[0])
        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
        self.avgpool = nn.AvgPool2d(7)
        self.fc_yaw = nn.Linear(512 * block.expansion, num_bins)
        self.fc_pitch = nn.Linear(512 * block.expansion, num_bins)
        self.fc_roll = nn.Linear(512 * block.expansion, num_bins)
        self.fc_finetune = nn.Linear(512 * block.expansion + 3, 3)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
                m.weight.data.normal_(0, math.sqrt(2.0 / n))
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

    def _make_layer(self, block, planes, blocks, stride=1):
        downsample = None
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, bias=False), nn.BatchNorm2d(planes * block.expansion))
        layers = []
        layers.append(block(self.inplanes, planes, stride, downsample))
        self.inplanes = planes * block.expansion
        for i in range(1, blocks):
            layers.append(block(self.inplanes, planes))
        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        pre_yaw = self.fc_yaw(x)
        pre_pitch = self.fc_pitch(x)
        pre_roll = self.fc_roll(x)
        return pre_yaw, pre_pitch, pre_roll

class AlexNet(nn.Module):

    def __init__(self, num_bins):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2), nn.Conv2d(64, 192, kernel_size=5, padding=2), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2), nn.Conv2d(192, 384, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(256, 256, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2))
        self.classifier = nn.Sequential(nn.Dropout(), nn.Linear(256 * 6 * 6, 4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(4096, 4096), nn.ReLU(inplace=True))
        self.fc_yaw = nn.Linear(4096, num_bins)
        self.fc_pitch = nn.Linear(4096, num_bins)
        self.fc_roll = nn.Linear(4096, num_bins)

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), 256 * 6 * 6)
        x = self.classifier(x)
        yaw = self.fc_yaw(x)
        pitch = self.fc_pitch(x)
        roll = self.fc_roll(x)
        return yaw, pitch, roll

class ContextModule(nn.Module):

    def __init__(self, in_channels=256):
        super(ContextModule, self).__init__()
        self.det_conv1 = nn.Sequential(nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(in_channels))
        self.det_context_conv1 = nn.Sequential(nn.Conv2d(in_channels, in_channels // 2, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(in_channels // 2), nn.ReLU(inplace=True))
        self.det_context_conv2 = nn.Sequential(nn.Conv2d(in_channels // 2, in_channels // 2, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(in_channels // 2))
        self.det_context_conv3_1 = nn.Sequential(nn.Conv2d(in_channels // 2, in_channels // 2, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(in_channels // 2), nn.ReLU(inplace=True))
        self.det_context_conv3_2 = nn.Sequential(nn.Conv2d(in_channels // 2, in_channels // 2, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(in_channels // 2))
        self.det_concat_relu = nn.ReLU(inplace=True)

    def forward(self, x):
        x1 = self.det_conv1(x)
        x_ = self.det_context_conv1(x)
        x2 = self.det_context_conv2(x_)
        x3_ = self.det_context_conv3_1(x_)
        x3 = self.det_context_conv3_2(x3_)
        out = torch.cat((x1, x2, x3), 1)
        act_out = self.det_concat_relu(out)
        return act_out

class FeaturePyramidNetwork(nn.Module):

    def __init__(self, in_channels_list, out_channels):
        super(FeaturePyramidNetwork, self).__init__()
        self.lateral_blocks = nn.ModuleList()
        self.context_blocks = nn.ModuleList()
        self.aggr_blocks = nn.ModuleList()
        for i, in_channels in enumerate(in_channels_list):
            if in_channels == 0:
                continue
            lateral_block_module = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True))
            aggr_block_module = nn.Sequential(nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(out_channels), nn.ReLU(inplace=True))
            context_block_module = ContextModule(out_channels)
            self.lateral_blocks.append(lateral_block_module)
            self.context_blocks.append(context_block_module)
            if i > 0:
                self.aggr_blocks.append(aggr_block_module)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_uniform_(m.weight, a=1)
                nn.init.constant_(m.bias, 0)

    def forward(self, x):
        names = list(x.keys())
        x = list(x.values())
        last_inner = self.lateral_blocks[-1](x[-1])
        results = []
        results.append(self.context_blocks[-1](last_inner))
        for feature, lateral_block, context_block, aggr_block in zip(x[:-1][::-1], self.lateral_blocks[:-1][::-1], self.context_blocks[:-1][::-1], self.aggr_blocks[::-1]):
            if not lateral_block:
                continue
            lateral_feature = lateral_block(feature)
            feat_shape = lateral_feature.shape[-2:]
            inner_top_down = F.interpolate(last_inner, size=feat_shape, mode='nearest')
            last_inner = lateral_feature + inner_top_down
            last_inner = aggr_block(last_inner)
            results.insert(0, context_block(last_inner))
        out = OrderedDict([(k, v) for k, v in zip(names, results)])
        return out

class RegressionTransform(nn.Module):

    def __init__(self, mean=None, std_box=None, std_ldm=None):
        super(RegressionTransform, self).__init__()
        if mean is None:
            self.mean = torch.from_numpy(np.array([0, 0, 0, 0]).astype(np.float32))
        else:
            self.mean = mean
        if std_box is None:
            self.std_box = torch.from_numpy(np.array([0.1, 0.1, 0.2, 0.2]).astype(np.float32))
        else:
            self.std_box = std_box
        if std_ldm is None:
            self.std_ldm = torch.ones(1, 10) * 0.1

    def forward(self, anchors, bbox_deltas, ldm_deltas, img):
        widths = anchors[:, :, (2)] - anchors[:, :, (0)]
        heights = anchors[:, :, (3)] - anchors[:, :, (1)]
        ctr_x = anchors[:, :, (0)] + 0.5 * widths
        ctr_y = anchors[:, :, (1)] + 0.5 * heights
        ldm_deltas = ldm_deltas * self.std_ldm
        bbox_deltas = bbox_deltas * self.std_box
        bbox_dx = bbox_deltas[:, :, (0)]
        bbox_dy = bbox_deltas[:, :, (1)]
        bbox_dw = bbox_deltas[:, :, (2)]
        bbox_dh = bbox_deltas[:, :, (3)]
        pred_ctr_x = ctr_x + bbox_dx * widths
        pred_ctr_y = ctr_y + bbox_dy * heights
        pred_w = torch.exp(bbox_dw) * widths
        pred_h = torch.exp(bbox_dh) * heights
        pred_boxes_x1 = pred_ctr_x - 0.5 * pred_w
        pred_boxes_y1 = pred_ctr_y - 0.5 * pred_h
        pred_boxes_x2 = pred_ctr_x + 0.5 * pred_w
        pred_boxes_y2 = pred_ctr_y + 0.5 * pred_h
        pred_boxes = torch.stack([pred_boxes_x1, pred_boxes_y1, pred_boxes_x2, pred_boxes_y2], dim=2)
        pt0_x = ctr_x + ldm_deltas[:, :, (0)] * widths
        pt0_y = ctr_y + ldm_deltas[:, :, (1)] * heights
        pt1_x = ctr_x + ldm_deltas[:, :, (2)] * widths
        pt1_y = ctr_y + ldm_deltas[:, :, (3)] * heights
        pt2_x = ctr_x + ldm_deltas[:, :, (4)] * widths
        pt2_y = ctr_y + ldm_deltas[:, :, (5)] * heights
        pt3_x = ctr_x + ldm_deltas[:, :, (6)] * widths
        pt3_y = ctr_y + ldm_deltas[:, :, (7)] * heights
        pt4_x = ctr_x + ldm_deltas[:, :, (8)] * widths
        pt4_y = ctr_y + ldm_deltas[:, :, (9)] * heights
        pred_landmarks = torch.stack([pt0_x, pt0_y, pt1_x, pt1_y, pt2_x, pt2_y, pt3_x, pt3_y, pt4_x, pt4_y], dim=2)
        B, C, H, W = img.shape
        pred_boxes[:, :, ::2] = torch.clamp(pred_boxes[:, :, ::2], min=0, max=W)
        pred_boxes[:, :, 1::2] = torch.clamp(pred_boxes[:, :, 1::2], min=0, max=H)
        pred_landmarks[:, :, ::2] = torch.clamp(pred_landmarks[:, :, ::2], min=0, max=W)
        pred_landmarks[:, :, 1::2] = torch.clamp(pred_landmarks[:, :, 1::2], min=0, max=H)
        return pred_boxes, pred_landmarks

class RetinaFace(nn.Module):

    def __init__(self, backbone, return_layers, anchor_nums=3):
        super(RetinaFace, self).__init__()
        assert backbone, 'Backbone can not be none!'
        assert len(return_layers) > 0, 'There must be at least one return layers'
        self.body = _utils.IntermediateLayerGetter(backbone, return_layers)
        in_channels_stage2 = 256
        in_channels_list = [in_channels_stage2 * 2, in_channels_stage2 * 4, in_channels_stage2 * 8]
        out_channels = 256
        self.fpn = FeaturePyramidNetwork(in_channels_list, out_channels)
        self.ClassHead = self._make_class_head()
        self.BboxHead = self._make_bbox_head()
        self.LandmarkHead = self._make_landmark_head()
        self.anchors = Anchors()
        self.regressBoxes = RegressionTransform()
        self.losslayer = losses.LossLayer()

    def _make_class_head(self, fpn_num=3, inchannels=512, anchor_num=3):
        classhead = nn.ModuleList()
        for i in range(fpn_num):
            classhead.append(ClassHead(inchannels, anchor_num))
        return classhead

    def _make_bbox_head(self, fpn_num=3, inchannels=512, anchor_num=3):
        bboxhead = nn.ModuleList()
        for i in range(fpn_num):
            bboxhead.append(BboxHead(inchannels, anchor_num))
        return bboxhead

    def _make_landmark_head(self, fpn_num=3, inchannels=512, anchor_num=3):
        landmarkhead = nn.ModuleList()
        for i in range(fpn_num):
            landmarkhead.append(LandmarkHead(inchannels, anchor_num))
        return landmarkhead

    def freeze_bn(self):
        """Freeze BatchNorm layers."""
        for layer in self.modules():
            if isinstance(layer, nn.BatchNorm2d):
                layer.eval()

    def forward(self, inputs):
        if self.training:
            img_batch, annotations = inputs
        else:
            img_batch = inputs
        out = self.body(img_batch)
        features = self.fpn(out)
        bbox_regressions = torch.cat([self.BboxHead[i](feature) for i, feature in enumerate(features.values())], dim=1)
        ldm_regressions = torch.cat([self.LandmarkHead[i](feature) for i, feature in enumerate(features.values())], dim=1)
        classifications = torch.cat([self.ClassHead[i](feature) for i, feature in enumerate(features.values())], dim=1)
        anchors = self.anchors(img_batch)
        if self.training:
            return self.losslayer(classifications, bbox_regressions, ldm_regressions, anchors, annotations)
        else:
            bboxes, landmarks = self.regressBoxes(anchors, bbox_regressions, ldm_regressions, img_batch)
            return classifications, bboxes, landmarks

def conv3x3(in_planes, out_planes, stride=1):
    """3x3 convolution with padding"""
    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=False)

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm2d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)
        if self.downsample is not None:
            residual = self.downsample(x)
        out += residual
        out = self.relu(out)
        return out

class Bottleneck(nn.Module):
    expansion = 4

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(Bottleneck, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
        self.bn3 = nn.BatchNorm2d(planes * 4)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        residual = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)
        out = self.conv3(out)
        out = self.bn3(out)
        if self.downsample is not None:
            residual = self.downsample(x)
        out += residual
        out = self.relu(out)
        return out

import torch
from torch.nn import MSELoss, ReLU
from _paritybench_helpers import _mock_config, _mock_layer, _paritybench_base, _fails_compile

TESTCASES = [
    # (nn.Module, init_args, forward_args, jit_compiles)
    (Anchors,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 4, 4, 4])], {}),
     False),
    (BasicBlock,
     lambda: ([], {'inplanes': 4, 'planes': 4}),
     lambda: ([torch.rand([4, 4, 4, 4])], {}),
     True),
    (BboxHead,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 512, 64, 64])], {}),
     True),
    (BboxHead_,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 256, 64, 64])], {}),
     True),
    (CB,
     lambda: ([], {'inchannels': 4}),
     lambda: ([torch.rand([4, 4, 4, 4])], {}),
     True),
    (CBR,
     lambda: ([], {'inchannels': 4, 'outchannels': 4}),
     lambda: ([torch.rand([4, 4, 4, 4])], {}),
     True),
    (ClassHead,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 512, 64, 64])], {}),
     True),
    (ClassHead_,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 256, 64, 64])], {}),
     True),
    (Context,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 256, 64, 64])], {}),
     False),
    (ContextModule,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 256, 64, 64])], {}),
     True),
    (LandmarkHead,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 512, 64, 64])], {}),
     True),
    (LandmarkHead_,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 256, 64, 64])], {}),
     True),
    (LossLayer,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 4, 4]), torch.rand([4, 4, 4]), torch.rand([4, 4, 4]), torch.rand([4, 4, 4]), torch.rand([4, 4, 4])], {}),
     False),
    (RegressionTransform,
     lambda: ([], {}),
     lambda: ([torch.rand([4, 4, 4]), torch.rand([4, 4, 4]), torch.rand([4, 4, 10]), torch.rand([4, 4, 4, 4])], {}),
     True),
]

class Test_supernotman_RetinaFace_Pytorch(_paritybench_base):
    def test_000(self):
        self._check(*TESTCASES[0])

    def test_001(self):
        self._check(*TESTCASES[1])

    def test_002(self):
        self._check(*TESTCASES[2])

    def test_003(self):
        self._check(*TESTCASES[3])

    def test_004(self):
        self._check(*TESTCASES[4])

    def test_005(self):
        self._check(*TESTCASES[5])

    def test_006(self):
        self._check(*TESTCASES[6])

    def test_007(self):
        self._check(*TESTCASES[7])

    def test_008(self):
        self._check(*TESTCASES[8])

    def test_009(self):
        self._check(*TESTCASES[9])

    def test_010(self):
        self._check(*TESTCASES[10])

    def test_011(self):
        self._check(*TESTCASES[11])

    def test_012(self):
        self._check(*TESTCASES[12])

    def test_013(self):
        self._check(*TESTCASES[13])


"""!
@file
Script for testing the matrix utilities of PyPO.
"""

import unittest
import numpy as np

from PyPO.MatUtils import findConnectedSubsets

class Test_MatUtils(unittest.TestCase):
    def test_findConnectedSubsets(self):
        mat = np.zeros((6,6))
        mat[1,2] = 1
        mat[0,2] = 1
        mat[2,2] = 1
        mat[1,3] = 1
        mat[1,1] = 1

        lims_0_check = [0, 1, 2]
        lims_1_check = [1, 2, 3]

        mat[5,5] = 1
        mat[5,4] = 1
        mat[5,3] = 1
        mat[5,2] = 1

        component = 1
        idx_start = [1,2]

        x, y = findConnectedSubsets(mat, component, idx_start)
        for l0, xx in zip(lims_0_check, x):
            self.assertEqual(l0, xx)
        for l1, yy in zip(lims_1_check, y):
            self.assertEqual(l1, yy)

if __name__ == "__main__":
    import nose2
    nose2.main()


from cv_2 import tr
import pandas as pd
from feat_select import select_features
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
import numpy as np
from sklearn import svm
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import f1_score

# this does cross validation and iterates over different number of features
def do_cv(X, y, X_test, y_test, f_sel, modality,n_feats,split):
    max_n_feats = n_feats
    feat_iters = []
    X2 = pd.DataFrame(X, copy=True)  # copies the original feature dataframe
    y2 = pd.DataFrame(y, copy=True)  # copies the original feature dataframe
    feat_selected = select_features(X, y, modality, f_sel, max_n_feats)

    test_acc = []
    train_acc = []
    test_auc = []
    train_auc = []
    num_feats = []

    res = []
    bff = []
    best_clfs = []
    best_feats = []
    best_params = []
    if modality == 'CNV':
        hmap_data = np.array(['min_samples_split','min_samples_leaf','max_features','num_feats','score'])
    else:
        hmap_data = np.array(['kernel', 'C', 'num_feats', 'score'])

    for i in range(2, max_n_feats, split):
        print(i)
        num_feats.append(i)
        X3 = pd.DataFrame(X2, copy=True)  # copies the original feature dataframe
        y3 = pd.DataFrame(y2, copy=True)  # copies the original feature dataframe

        if modality == 'CNV':
            # # clf = DecisionTreeClassifier(min_samples_split=2,min_samples_leaf=5)
            # clf = DecisionTreeClassifier(min_samples_split=10,min_samples_leaf=1)
            # clf.fit(X3[feat_selected[0:i]],y3.values.ravel())
            # sc = clf.score(X_test[feat_selected[0:i]],y_test)
            # print(sc)
            # # fsc = f1_score(y_test, clf.predict(X_test[feat_selected[0:i]]))
            # # print(fsc)
            # probas_ = clf.predict_proba(X_test[feat_selected[0:i]])
            # c1, c2, thresholds = roc_curve(y_test, probas_[:, 1])
            # area = auc(c1, c2)
            # print(area)
            # res.append(sc)
            # bff.append(area)
            # # print(clf.predict(X_test[feat_selected[0:i]]))
            # # print(y_test.values.ravel())

            clf, fea_ = tr(X3, y3, modality, f_sel, 'none', feat_selected[0:i])
            res.append(clf.best_score_)
            best_feats.append(fea_)
            best_params.append([clf.best_params_, i])
            for param, score in zip(clf.cv_results_['params'], clf.cv_results_['mean_test_score']):
                hmap_data = np.vstack((hmap_data, np.array([param['min_samples_split'],
                                                            param['min_samples_leaf'],param['max_features'],
                                                            i, score])))

            # do this is picking clf from f1 score or cohens kappa. makes it give an accuracy output
            X5 = X2[fea_]
            clf = DecisionTreeClassifier(min_samples_split=clf.best_params_['min_samples_split'],
                                         min_samples_leaf=clf.best_params_['min_samples_leaf'],
                                         max_features=clf.best_params_['max_features'],class_weight='balanced')
            # TRY WITH WITHOUT CLASS WEIGHT = BALANCED!!!!! ALSO WOULD NEED TO CHANGE IT IN CV_2
            clf.fit(X5, y2.values.ravel())
            best_clfs.append(clf)  # this is list from which final clf is selected

            # stuff for test
            X4 = X2[fea_]
            X_test2 = X_test[fea_]
            train_acc.append(clf.score(X4, y2))
            test_acc.append(clf.score(X_test2, y_test))
            probas_ = clf.predict_proba(X4)
            c1, c2, thresholds = roc_curve(y2.values.ravel(), probas_[:, 1])
            train_auc.append(auc(c1, c2))
            probas_ = clf.predict_proba(X_test2)
            c1, c2, _ = roc_curve(y_test.values.ravel(), probas_[:, 1])
            test_auc.append(auc(c1, c2))

        else:
            clf, fea_ = tr(X3, y3, modality, f_sel, 'none', feat_selected[0:i])

            res.append(clf.best_score_)
            best_feats.append(fea_)
            best_params.append([clf.best_params_,i])
            for param, score in zip(clf.cv_results_['params'], clf.cv_results_['mean_test_score']):
                hmap_data = np.vstack((hmap_data,np.array([param['kernel'],param['C'],i,score])))

            # do this is picking clf from f1 score or cohens kappa. makes it give an accuracy output
            X5 = X2[fea_]
            clf = svm.SVC(gamma='auto',class_weight='balanced',C=clf.best_params_['C'],kernel=clf.best_params_['kernel'],probability=True)
            # clf = svm.SVC(gamma='auto',C=clf.best_params_['C'],kernel=clf.best_params_['kernel'])
            clf.fit(X5, y2.values.ravel())
            best_clfs.append(clf) #this is list from which final clf is selected

            # stuff for test
            X4 = X2[fea_]
            X_test2 = X_test[fea_]
            train_acc.append(clf.score(X4, y2))
            test_acc.append(clf.score(X_test2, y_test))
            c1, c2, _ = roc_curve(y2.values.ravel(), clf.decision_function(X4).ravel())
            train_auc.append(auc(c1, c2))
            c1, c2, _ = roc_curve(y_test.values.ravel(), clf.decision_function(X_test2).ravel())
            test_auc.append(auc(c1, c2))

    # print(max(res))
    # print(max(bff))
    print(res)
    print(best_feats)
    ndx = np.argmax(res)
    print(hmap_data)
    print('acc',test_acc[ndx])
    print('auc',test_auc[ndx])
    print(best_params[ndx])
    print('max',res[ndx])

    fig = plt.figure()
    ax1 = fig.add_axes([0.1, 0.6, 0.85, .2], ylim=(0, 1))
    ax2 = fig.add_axes([0.1, 0.1, 0.85, .2], ylim=(0, 1))
    # ax1.tick_params(labelsize=10)
    # ax1.tick_params(labelsize=10)

    ax1.plot(num_feats, train_acc, 'r',label='train')
    ax1.plot(num_feats, test_acc, 'b',label='test')
    ax1.set_title('CNV Accuracy', fontsize=15)
    ax1.set_xlabel('Number of Features', fontsize=10)
    ax1.set_ylabel('Accuracy', fontsize=10)
    ax1.legend(loc='bottom left')

    ax2.plot(num_feats, train_auc, 'r')
    ax2.plot(num_feats, test_auc, 'b')
    ax2.set_title('CNV AUC', fontsize=15)
    ax2.set_xlabel('Number of Features', fontsize=10)
    ax2.set_ylabel('AUC', fontsize=10)

    plt.show()

    return best_clfs[ndx],best_feats[ndx],hmap_data


'''
four approaches are there

 approach 1 - simply do a linear search to find the target element
 Time - 0(n^2) Space - 0(1)

 approach 2 - use an axtra 1d array of size n*m
 step 1 - copy all the ele from original to temp 1d arr
 step 2 - do a binary search on temp arr
 Time - 0(n^2) + 0(logn) Space - 0(n*m)

 approach 3 - ask the interviewer if rows and col both are sorted if it,
 than
 step 1 - start from first row last col index
 step 2 - if target > currIndexEle move bottom else move left
 step 3 - do this until we hit the target element or we run out of bounds

 approach 4 - the most optimal approach
 intusion - think of converting the 2d array in 1d array , how to do that?
 well idea is simple ( mid//m = i , mid%m = j ) where n,m = len(matrix), len(matrix[0])
 and do the binary search
 Time - 0(log(n*m)) since we are doing a binary search on length (n*m) , Space - 0(1)

'''

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix:
            return False

        n = len(matrix)
        m = len(matrix[0])

        low, high = 0, (n * m) - 1

        while low <= high:

            mid = (low + high) // 2

            if matrix[mid // m][mid % m] == target:
                return True
            if matrix[mid // m][mid % m] < target:
                low = mid + 1
            else:
                high = mid - 1

        return False


# Licensed under a 3-clause BSD style license - see LICENSE.rst

from astropy import log
import pytest

from sofia_redux.scan.configuration.conditions import Conditions
from sofia_redux.scan.configuration.configuration import Configuration

def test_init():
    d = Conditions(allow_error=False, verbose=False)
    assert isinstance(d, Conditions)
    assert not d.allow_error
    assert not d.verbose
    d = Conditions(allow_error=True, verbose=True)
    assert d.allow_error
    assert d.verbose

def test_len(initialized_conditions):
    assert len(initialized_conditions) == 5
    d = Conditions()
    d.options = None
    assert len(d) == 0

def test_set_item():
    d = Conditions()
    d['cond1=True'] = 'foo'
    assert d['cond1=True'] == {'add': 'foo'}

def test_str():
    d = Conditions()
    assert str(d) == 'Contains 0 conditions.'
    d['cond1=True'] = 'foo'
    assert str(d) == 'Contains 1 condition.'

def test_repr():
    d = Conditions()
    s = repr(d)
    assert 'sofia_redux.scan.configuration.conditions.Conditions' in s
    assert 'Contains 0 conditions.' in s

def test_size(initialized_conditions):
    assert initialized_conditions.size == 5

def test_copy(initialized_conditions):
    d = initialized_conditions
    d2 = d.copy()
    assert d.options is not d2.options
    assert d.options == d2.options

def test_set():
    d = Conditions()
    with pytest.raises(ValueError) as err:
        d.set('cond1', None)
    assert 'Could not parse condition' in str(err.value)
    d.allow_error = True
    d.set('cond1', None)
    assert d.size == 0

    d.set('cond1=True', 'set_this')
    assert d.options['cond1=True'] == {'add': 'set_this'}

def test_update():
    d = Conditions()
    d.allow_error = True
    options = {}
    d.update(options)
    assert d.size == 0
    options['conditionals'] = 1

    with log.log_to_list() as log_list:
        d.update(options)
    assert "Supplied conditionals" in log_list[0].msg

    switches = {'a=1': {'add': 'foo'}, 'a>2': {'forget': 'foo'}}
    options['conditionals'] = switches
    d.update(options)
    assert d.options == switches

def test_check_requirement():
    c = Configuration()
    c.options['str'] = 'value'
    c.options['num'] = '5'
    c.options['bool'] = 'True'
    d = Conditions()
    d.allow_error = True

    with log.log_to_list() as log_list:
        assert not d.check_requirement(c, 'str=')
    assert 'Bad conditional requirement' in log_list[0].msg

    assert d.check_requirement(c, 'bool')
    assert not d.check_requirement(c, 'missing')

    # Check string value equal and not equal
    assert d.check_requirement(c, 'str==value')
    assert d.check_requirement(c, 'str=value')
    assert not d.check_requirement(c, 'str=wrong')
    assert d.check_requirement(c, 'str!=wrong')

    # Check number value equal and not equal
    assert d.check_requirement(c, 'num=5.0')
    assert d.check_requirement(c, 'num==5')
    assert d.check_requirement(c, 'num!=4')
    assert d.check_requirement(c, 'num!=value')
    assert not d.check_requirement(c, 'num=4')

    # Check inequality operators
    test_num = [4, 5, 6]
    for num in test_num:
        expected = 5 > num
        assert d.check_requirement(c, f'num>{num}') is expected
        expected = 5 < num
        assert d.check_requirement(c, f'num<{num}') is expected
        expected = 5 >= num
        assert d.check_requirement(c, f'num>={num}') is expected
        expected = 5 <= num
        assert d.check_requirement(c, f'num<={num}') is expected

    # Check missing value
    assert not d.check_requirement(c, 'foo<1')

    # Check bad inequality
    assert not d.check_requirement(c, 'num<a')

def test_get_met_conditions():
    c = Configuration()
    d = Conditions()
    d.options['always'] = 'add=foo'
    d.options['num>4'] = {'add': 'bar', 'forget': 'foo', 'baz': '3'}
    d.options['num>6'] = {'add': 'high_value'}
    c.options['num'] = '5'
    apply = d.get_met_conditions(c)
    assert apply == {'always': [{'add': 'foo'}],
                     'num>4': [{'add': 'bar', 'forget': 'foo', 'baz': '3'}]}

    # Test bad non-requirement condition
    d.options['bad'] = 'add='
    d.allow_error = True
    with log.log_to_list() as log_list:
        apply = d.get_met_conditions(c)
    assert 'Bad condition' in log_list[0].msg
    assert apply == {'always': [{'add': 'foo'}],
                     'num>4': [{'add': 'bar', 'forget': 'foo', 'baz': '3'}]}

def test_process_conditionals():
    c = Configuration()
    d = Conditions()
    c.options['num'] = '4'
    d.options['num>4'] = {'add': 'foo'}
    d.options['foo'] = {'add': 'bar'}
    d.process_conditionals(c)
    assert 'foo' not in c
    assert 'bar' not in c
    c.put('num', '5')
    d.process_conditionals(c)
    assert 'foo' in c
    assert 'bar' in c

def test_update_configuration():
    c = Configuration()
    c.options['num'] = '5'
    d = Conditions()
    assert not d.update_configuration(c)
    seen = set([])
    d.options['num>3'] = {'add': 'foo'}
    d.options['num>4'] = {'add': 'bar'}
    d.options['foo'] = {'key1': 'value1'}
    d.options['bar'] = {'key2': 'value2', 'key3': 'value3'}
    assert d.update_configuration(c, seen=seen)
    assert c['foo']
    assert c['bar']
    assert 'key1' not in c and 'key2' not in c and 'key3' not in c
    assert d.update_configuration(c, seen=seen)
    assert (c['key1'] == 'value1' and c['key2'] == 'value2'
            and c['key3'] == 'value3')
    assert not d.update_configuration(c, seen=seen)


'''import datetime
import pyttsx3

time = datetime.datetime.now().strftime('%I:%M %p')
s = pyttsx3.init()
voices = s.getProperty('voices')
s.setProperty('voice', voices[1].id)
s.say("current time is "+time)
s.runAndWait()'''
'''
import speech_recognition as sr

r=sr.Recognizer()
harvard = sr.AudioFile('aud.wav')
with harvard as source:
    audio = r.record(source)
    this=r.recognize_google(audio)
    print(this)
    '''

import speech_recognition as sr
import wikipedia
import pyttsx3
import datetime
import pywhatkit
import pyjokes
import pyscreenshot
import cv2 as cv

r = sr.Recognizer()
def getcommand():
    try:
        with sr.Microphone() as source:
                        print('listening...')
                        voice = r.listen(source)
                        r.pause_threshold = 1
                        r.adjust_for_ambient_noise(source, duration=1)
                        command = r.recognize_google(voice)
                        print(command)
                        if "hey assistant" in command:
                            command=command.replace("hey assistant","")

                        return command
    except sr.UnknownValueError:
        return "not found"

s = pyttsx3.init()
def reply():
    c=getcommand()
    print(c)
    if "search" in c:
        c=c.replace("search","")
        info=wikipedia.summary(c,2)
        s.say(info)
        s.runAndWait()
    elif "current time" in c:
        s.say("current time is "+ datetime.datetime.now().strftime('%I:%M %p'))
        s.runAndWait()
    elif "play song" in c:
        c=c.replace("play song","")
        pywhatkit.playonyt(c)
    elif "say a joke"  in c:
        s.say(pyjokes.get_joke())
        s.runAndWait()
    elif "take screenshot" in c:
        img=pyscreenshot.grab()
        img.save("name.png")
        s.say("screenchot taken")
        s.runAndWait()
    elif("take my picture") in c:
        cam = cv.VideoCapture(0)
        result, image = cam.read()
        if result:
            s.say("taking picture")
            s.runAndWait()
            cv.imwrite("mypic.png", image)  #saving image in local storage
            s.say("picture taken")
            s.runAndWait()
        else:
            s.say("No image detected. Please! try again")
            s.runAndWait()
    else:
        s.say("i could not understand the command")
        s.runAndWait()

while True:
    reply()


Import('env', 'daemon_objs')

# Add OS specific daemon_objs
os_objs = env.Object(['ProximityScanner.cc','Socket.cc'])

# Build the posix daemon and service launcher helper.
if env['OS'] != 'darwin':
    daemon = env.Program('alljoyn-daemon', ['daemon-main.cc'] + daemon_objs + os_objs)
else:
    daemon = []

#
# On Android, build a static library that can be linked into a JNI dynamic
# library to implement the daemon as a Service
#
if env['OS'] == 'android':
   libenv = env.Clone(CCFLAGS = '-DDAEMON_LIB')
   libenv.Object(target = 'alljoyn-daemon', source = 'daemon-main.cc')
   libdaemon = env.StaticLibrary(['alljoyn-daemon'] + daemon_objs + os_objs)
   dlibs = env.Install('$CPP_DISTDIR/lib', libdaemon)

#progs = daemon + servicehelper
progs = daemon, os_objs
Return('progs')


import os
import codecs

import util as ut
import json

TMP_DIR = ut.TMP_DIR
CSV_DIR = TMP_DIR + 'csv/'

# csv header's column name
NAME = 'name'
ADDRESS = 'address'
TEL = 'tel'
FAX = 'fax'
URL = 'url'
MEMO = 'memo'
ALT = 'alt'
LON = 'lon'

def parseCsv(dirName, fileName):
    dirInPath = CSV_DIR + dirName + '/'
    ut.mkDir(CSV_DIR)
    ut.mkDir(dirInPath)

    JSON_DIR = TMP_DIR + 'json/'
    dirOutPath = JSON_DIR + dirName + '/'
    ut.mkDir(JSON_DIR)
    ut.mkDir(dirOutPath)

    fileNameIn = dirInPath + fileName
    fileNameOut = dirOutPath + fileName.replace('.csv', '.json')

    jsnObj = []
    fin = None
    fout = None
    try:
        fin  = codecs.open(fileNameIn, 'r', 'shift_jis', 'ignore')
        fout = codecs.open(fileNameOut, 'w', 'utf-8', 'ignore')
        print("convert to json..")

        idxs = {
            NAME : None,
            ADDRESS : None,
            TEL : None,
            FAX : None,
            URL : None,
            MEMO : None,
            ALT : None,
            LON : None
        }

        for i, row in enumerate(fin):
            if i == 0:
                heads = row.split(',')
                for idx, item in enumerate(heads):
                    head = getHead(item)
                    if head is not None:
                        idxs[head] = idx
            else:
                dt = row.split(',')
                j = {
                    NAME : getColValue(NAME, idxs, dt),
                    ADDRESS : getColValue(ADDRESS, idxs, dt),
                    TEL : getColValue(TEL, idxs, dt),
                    FAX : getColValue(FAX, idxs, dt),
                    URL : getColValue(URL, idxs, dt),
                    MEMO : getColValue(MEMO, idxs, dt),
                    ALT : getColValue(ALT, idxs, dt),
                    LON : getColValue(LON, idxs, dt)
                }
                jsnObj.append(j)

        jsonStr = json.dumps(jsnObj, ensure_ascii=False, indent=4)
        fout.write(jsonStr)
        return fileNameOut
    except Exception as e:
        print(e)
        return
    finally:
        if fout is not None:
            fout.close()
        if fin is not None:
            fin.close()

def getHead(item):
    item = item.replace('"','').replace("'",'').rstrip('\n').strip()

    # colmun candidates
    name = ['名称', '施設名', '分団名']
    address = ['住所', '地番', '機庫所在地']
    tel = ['TEL', '電話番号']
    fax = ['FAX']
    url = ['URL']
    memo = ['設置場所', '備考', '備考1']
    alt = ['世界_10進_Y']
    lon = ['世界_10進_X']

    if item in name:
        return NAME
    if item in address:
        return ADDRESS
    if item in tel:
        return TEL
    if item in fax:
        return FAX
    if item in url:
        return URL
    if item in memo:
        return MEMO
    if item in alt:
        return ALT
    if item in lon:
        return LON

    return None

def getColValue(key, idxs, row):
    idx = idxs[key]
    if idx == None:
        return None
    else:
        val = row[idx].replace('"','').replace("'",'').rstrip('\n').strip()
        return val


from rest_framework import serializers

from django.contrib.auth.models import User, Group
from .models import Team, Skill, Teammate
from .models import Category, Project, Task, Work

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'url',
                  'username', 'email', 'groups')

class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('id', 'url',
                  'name')

class TeamSerializer(serializers.ModelSerializer):
    class Meta:
        model = Team
        fields = ('id', 'url', 'created_at', 'updated_at',
                  'desc')

class SkillSerializer(serializers.ModelSerializer):
    class Meta:
        model = Skill
        fields = ('id', 'url', 'created_at', 'updated_at',
                  'desc')

class TeammateSerializer(serializers.ModelSerializer):
    skills_urls = serializers.HyperlinkedRelatedField(source='skills', many=True, read_only=True, view_name='skill-detail')
    team_url = serializers.HyperlinkedRelatedField(source='team', read_only=True, view_name='team-detail')
    half_days_per_week = serializers.IntegerField(required=True, min_value=1, max_value=10)

    class Meta:
        model = Teammate
        fields = ('id', 'url', 'created_at', 'updated_at',
                  'name', 'external', 'half_days_per_week', 'team', 'team_url', 'skills', 'skills_urls')

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ('id', 'url', 'created_at', 'updated_at',
                  'desc')

class ProjectSerializer(serializers.ModelSerializer):
    category_url = serializers.HyperlinkedRelatedField(source='category', read_only=True, view_name='category-detail')

    class Meta:
        model = Project
        fields = ('id', 'url', 'created_at', 'updated_at',
                  'desc', 'priority',
                  'category', 'category_url')

class TaskSerializer(serializers.ModelSerializer):
    project_url = serializers.HyperlinkedRelatedField(source='project', read_only=True, view_name='project-detail')
    teams_urls = serializers.HyperlinkedRelatedField(source='teams', many=True, read_only=True, view_name='team-detail')

    class Meta:
        model = Task
        fields = ('id', 'url', 'created_at', 'updated_at',
                  'desc', 'priority',
                  'project', 'project_url', 'teams', 'teams_urls')

class WorkSerializer(serializers.ModelSerializer):
    task_url = serializers.HyperlinkedRelatedField(source='task', read_only=True, view_name='task-detail')
    skill_url = serializers.HyperlinkedRelatedField(source='skill', read_only=True, view_name='skill-detail')
    man_days = serializers.IntegerField(required=True, min_value=1)
    project = serializers.IntegerField(source='task.project.id', read_only=True)
    project_url = serializers.HyperlinkedRelatedField(source='task.project', read_only=True, view_name='project-detail')

    class Meta:
        model = Work
        fields = ('id', 'url', 'created_at', 'updated_at',
                  'desc',
                  'man_days', 'priority',
                  'skill', 'skill_url',
                  'task', 'task_url',
                  'project', 'project_url')


#!/usr/bin/python

# import guacamole libraries
import avango
import avango.gua
import avango.script
from avango.script import field_has_changed

# import application libraries
from lib.KeyboardInput import KeyboardInput
from lib.Intersection import Intersection

# import python libraries
import time

class Mover(avango.script.Script):

    ## output field
    sf_mat = avango.gua.SFMatrix4()

    ## constructor
    def __init__(self):
        self.super(Mover).__init__()

    def my_constructor( self
                      , SCENEGRAPH = None
                      , START_MATRIX = avango.gua.make_identity_mat()
                      , VIEWER = None
                      ):

        ## init internal classes
        self.input = KeyboardInput()
        self.input.my_constructor(VIEWER = VIEWER)

        self.accumulator = Accumulator()
        self.accumulator.my_constructor(START_MATRIX = START_MATRIX)

        self.groundFollowing = GroundFollowing()
        self.groundFollowing.my_constructor(SCENEGRAPH = SCENEGRAPH, START_MATRIX = START_MATRIX)

        ## init field connections
        self.accumulator.sf_move_vec.connect_from(self.input.sf_move_vec) # connect input into accumulator

        self.sf_mat.connect_from(self.accumulator.sf_mat) # connect output of accumulator to mover output matrix

        # ToDo: integrate the groundFollowing into the dataflow
        # evtl. replace existing field connections with new one
        # pay attention to potential loops in the dataflow --> use weak field connections to prevent loops
        # ...

################################
## Movement accumulator takes the (relative) movement vector of a KeyboardInput instance and applies
## it to an accumulated (absolute) matrix.
################################

class Accumulator(avango.script.Script):

    ## input fields
    sf_move_vec = avango.gua.SFVec3()

    ## output field
    sf_mat = avango.gua.SFMatrix4()

    ## constructor
    def __init__(self):
        self.super(Accumulator).__init__()

    def my_constructor( self
                      , START_MATRIX = avango.gua.make_identity_mat()
                      ):

        ## set initial state
        self.sf_mat.value = START_MATRIX

    ###  callback functions ###
    def evaluate(self): # evaluated once every frame if any input field has changed
        print("movement input", self.sf_move_vec.value)

        # ToDO: accumulate movement input to output matrix
        # self.sf_mat.value = ...

        pass

################################
## GroundFollowing takes a matrix from an MovementAccumulator instance and corrects it with
## respect to gravity in the scene. The result can then be applied to the avatar's transformation node.
################################

class GroundFollowing(avango.script.Script):

    ## input fields
    sf_mat = avango.gua.SFMatrix4()

    ## ouput fields
    sf_modified_mat = avango.gua.SFMatrix4()

    ## internal fields
    mf_pick_result = avango.gua.MFPickResult()

    ## constructor
    def __init__(self):
        self.super(GroundFollowing).__init__()

    def my_constructor( self
                      , SCENEGRAPH = None
                      , START_MATRIX = avango.gua.make_identity_mat()
                      ):

        ### parameters ###
        self.fall_velocity = 0.004 # in meter/sec

        self.pick_length = 1.0 # in meter
        self.pick_direction = avango.gua.Vec3(0.0,-1.0,0.0)

        ### variables ###
        self.fall_vec = avango.gua.Vec3(0.0, 0.0, 0.0)

        self.sav_time = time.time()

        ## init internal classes
        self.gravity_intersection = Intersection()
        self.gravity_intersection.my_constructor(SCENEGRAPH, self.sf_mat, self.pick_length, self.pick_direction)

        ## init field connections
        self.mf_pick_result.connect_from(self.gravity_intersection.mf_pick_result)

        ## set initial state
        self.sf_modified_mat.value = START_MATRIX

    ###  callback functions ###
    def evaluate(self): # evaluated once every frame if any input field has changed

        ## compute gravity response
        #print(len(self.mf_pick_result.value))
        if len(self.mf_pick_result.value) > 0: # intersection found
            _pick_result = self.mf_pick_result.value[0] # get first intersection target from list

            _distance = _pick_result.Distance.value # distance from ray matrix to intersection point
            _distance -= 0.025 # subtract half avatar height from distance
            _distance -= self.fall_velocity

            if _distance > 0.01: # avatar above ground
                self.fall_vec = avango.gua.Vec3(0.0, self.fall_velocity * -1.0, 0.0)

            else: # avatar (almost) on ground
                self.fall_vec.y = 0.0

            #print(self.fall_vec)

            self.sf_modified_mat.value = avango.gua.make_trans_mat(self.fall_vec) * \
                                         self.sf_mat.value

        else: # no intersection found
            self.sf_modified_mat.value = self.sf_mat.value # no changes needed


from time import sleep

import pymem
import pymem.process

class Excel:
    dwEntityList = 0x4DFFEF4
    m_bSpotted = 0x93D

    def __init__(self):
        self.pm = pymem.Pymem('csgo.exe')
        self.client = self.get_client(self)
        self.entity = None

    @staticmethod
    def get_client(self):
        return pymem.process.module_from_name(self.pm.process_handle, "client.dll").lpBaseOfDll

    def start(self):
        while True:
            for i in range(1, 32):
                self.entity = self.pm.read_int(self.client + self.dwEntityList + i * 0x10)
                if self.entity:
                    self.pm.write_uchar(self.entity + self.m_bSpotted, 1)
            sleep(1)


# System libraries
import copy

# PyPi libraries
import numpy as np

# Local libraries
from libraries import common
from libraries import day4

if __name__ == '__main__':
    draws_fn = 'day4/draws'
    draws_file_handler = common.FileHandler(draws_fn)
    draws = draws_file_handler.read_csv()[0]

    boards_fn = 'day4/boards'
    bingo = day4.Bingo(np.loadtxt(boards_fn, dtype=int))
    board_count = int(bingo.get_boards_count(5))
    for i in range(1, board_count + 1):
        board = day4.Board(i, bingo.get_board_data(i))
        bingo.add_board(board)

    complete_counter = 0
    for draw in draws:
        for board in bingo.boards:
            try:
                bingo.complete_boards[board.board_id]
            except KeyError:
                board_complete = False
            else:
                board_complete = True

            if not board_complete:
                board.mark_match(int(draw))
                check_complete = board.check_win()
                if check_complete:
                    complete_counter += 1
                    bingo.complete_boards[board.board_id] = int(draw)

    # Get last complete board
    last_winning_board = list(bingo.complete_boards.keys())[-1]
    last_draw = bingo.complete_boards[last_winning_board]
    board = bingo.get_board_by_id(last_winning_board)
    unmarked_sum = board.get_unmarked_sum()

    print(unmarked_sum*last_draw)


import random
from itertools import chain
from collections import Counter, OrderedDict

num_trials = 1000000

print(f'Testing each scenario {num_trials} times')

class OrderedCounter(Counter, OrderedDict):
    pass

def roll_dice(num_dice, num_faces, reroll_ones=False):
    results = []
    i = 0
    while i < num_dice:
        thisResult = random.randint(1, num_faces)
        if reroll_ones:
            while thisResult == 1:
                thisResult = random.randint(1, num_faces)
        results.append(thisResult)
        i += 1
    return results

def drop_lowest(dice_rolls, num_to_drop):
    dice_rolls.sort()
    return dice_rolls[num_to_drop:]

def count_and_print(dice_rolls):
    dice_rolls.sort()
    dice_counts = Counter(dice_rolls)
    for result, count in dice_counts.items():
        pct = count / dice_counts.total() * 100
        print(f'Number of {result}s: {count} - ({pct:.2f}%)')

def roll_and_drop(num_dice, num_faces, num_dropped, reroll_ones=False):
    dice_rolls = roll_dice(num_dice, num_faces, reroll_ones=reroll_ones)
    return drop_lowest(dice_rolls, num_dropped)

# Roll 4d6, drop 1; do this six times
print('### 4d6, drop 1 for each stat ###')
all_dice = []
for i in range(num_trials):
    single_char = [roll_and_drop(4, 6, 1) for i in range(6)]
    single_char = list(chain(*single_char))
    all_dice.append(single_char)
all_dice = list(chain(*all_dice))
assert len(all_dice) == 18*num_trials
count_and_print(all_dice)

# Roll 20d6, drop 2; combine any way
print('### 20d6, drop 2; combine any way ###')
all_dice = []
for i in range(num_trials):
    all_dice.append(roll_and_drop(20, 6, 2))
all_dice = list(chain(*all_dice))
assert len(all_dice) == 18*num_trials
count_and_print(all_dice)

# Roll 25d6, rerolling 1s; drop lowest 7; combine any way
print('### 25d6, drop 7, reroll 1s; combine any way ###')
all_dice = []
for i in range(num_trials):
    all_dice.append(roll_and_drop(25, 6, 7, reroll_ones=True))
all_dice = list(chain(*all_dice))
assert len(all_dice) == 18*num_trials
count_and_print(all_dice)


from typing import List, Tuple
import torch
from torch import Tensor
import torch.nn.functional as F
import numpy as np
from PIL import Image

from habitat import Config
from habitat.core.simulator import Observations

import submission.utils.pose_utils as pu
from submission.utils.constants import (
    frame_color_palette,
    goal_id_to_goal_name,
    goal_id_to_coco_id,
    MIN_DEPTH_REPLACEMENT_VALUE,
    MAX_DEPTH_REPLACEMENT_VALUE
)

class ObsPreprocessor:
    """
    This class preprocesses observations - it can either be integrated in the
    agent or an environment.
    """

    def __init__(self,
                 config: Config,
                 num_environments: int,
                 device: torch.device):
        self.num_environments = num_environments
        self.device = device
        self.precision = torch.float16 if config.MIXED_PRECISION else torch.float32
        self.num_sem_categories = config.ENVIRONMENT.num_sem_categories
        self.frame_height = config.ENVIRONMENT.frame_height
        self.frame_width = config.ENVIRONMENT.frame_width
        self.min_depth = config.ENVIRONMENT.min_depth
        self.max_depth = config.ENVIRONMENT.max_depth
        self.ground_truth_semantics = config.GROUND_TRUTH_SEMANTICS

        if not self.ground_truth_semantics:
            # from .detectron2_segmentation import Detectron2Segmentation
            # self.segmentation = Detectron2Segmentation(
            #     sem_pred_prob_thr=0.9,
            #     sem_gpu_id=(-1 if device == torch.device("cpu") else device.index),
            #     visualize=True
            # )

            from .mmdetection_segmentation import MMDetectionSegmentation
            self.segmentation = MMDetectionSegmentation(
                sem_pred_prob_thr=0.9,
                device=self.device,
                visualize=True
            )

        self.one_hot_encoding = torch.eye(
            self.num_sem_categories, device=self.device)
        self.color_palette = [int(x * 255.) for x in frame_color_palette]

        self.last_poses = None
        self.last_actions = None
        self.instance_id_to_category_id = None

    def reset(self):
        self.last_poses = [np.zeros(3)] * self.num_environments
        self.last_actions = [None] * self.num_environments
        self.instance_id_to_category_id = None

    def set_instance_id_to_category_id(self, instance_id_to_category_id):
        self.instance_id_to_category_id = instance_id_to_category_id.to(self.device)

    def preprocess(self,
                   obs: List[Observations],
                   ) -> Tuple[Tensor, np.ndarray, Tensor, Tensor, List[str]]:
        """
        Preprocess observations of a single timestep batched across
        environments.

        Arguments:
            obs: list of observations of length num_environments

        Returns:
            obs_preprocessed: frame containing (RGB, depth, segmentation) of
             shape (num_environments, 3 + 1 + num_sem_categories, frame_height,
             frame_width)
            semantic_frame: semantic frame visualization of shape
             (num_environments, frame_height, frame_width, 3)
            pose_delta: sensor pose delta (dy, dx, dtheta) since last frame
             of shape (num_environments, 3)
            goal: semantic goal category of shape (num_environments,)
            goal_name: list of semantic goal strings of length num_environments
        """
        obs_preprocessed, semantic_frame = self.preprocess_frame(obs)
        pose_delta, self.last_poses = self.preprocess_pose(obs, self.last_poses)
        goal, goal_name = self.preprocess_goal(obs)
        return (
            obs_preprocessed,
            semantic_frame,
            pose_delta,
            goal,
            goal_name
        )

    def preprocess_sequence(self,
                            seq_obs: List[Observations]
                            ) -> Tuple[Tensor, np.ndarray, Tensor, Tensor, str]:
        """
        Preprocess observations of a single environment batched across time.

        Arguments:
            seq_obs: list of observations of length sequence_length

        Returns:
            seq_obs_preprocessed: frame containing (RGB, depth, segmentation) of
             shape (sequence_length, 3 + 1 + num_sem_categories, frame_height,
             frame_width)
            seq_semantic_frame: semantic frame visualization of shape
             (sequence_length, frame_height, frame_width, 3)
            seq_pose_delta: sensor pose delta (dy, dx, dtheta) since last frame
             of shape (sequence_length, 3)
            goal: semantic goal category ID
            goal_name: semantic goal category
        """
        assert self.num_environments == 1
        sequence_length = len(seq_obs)
        seq_obs_preprocessed, seq_semantic_frame = self.preprocess_frame(seq_obs)

        seq_pose_delta = torch.zeros(sequence_length, 3)
        for t in range(sequence_length):
            seq_pose_delta[t], self.last_poses = self.preprocess_pose(
                [seq_obs[t]], self.last_poses)

        goal, goal_name = self.preprocess_goal([seq_obs[0]])
        goal_name = goal_name[0] if goal_name is not None else goal_name
        return (
            seq_obs_preprocessed,
            seq_semantic_frame,
            seq_pose_delta,
            goal,
            goal_name
        )

    def preprocess_goal(self, obs: List[Observations]) -> Tuple[Tensor, List[str]]:
        if "objectgoal" in obs[0]:
            goal = torch.tensor([
                goal_id_to_coco_id[ob["objectgoal"][0]] for ob in obs])
            goal_name = [goal_id_to_goal_name[ob["objectgoal"][0]] for ob in obs]
        else:
            goal, goal_name = None, None
        return goal, goal_name

    def preprocess_frame(self, obs: List[Observations]) -> Tuple[Tensor, np.ndarray]:
        """Preprocess frame information in the observation."""
        def preprocess_depth(depth):
            # Rescale depth from [0.0, 1.0] to [min_depth, max_depth]
            rescaled_depth = self.min_depth * 100. + depth * (self.max_depth - self.min_depth) * 100.

            # Depth at the boundaries of [min_depth, max_depth] has been
            # thresholded and should not be considered in the point cloud
            # and semantic map - the lines below ensure it's beyond
            # vision_range and does not get considered in the semantic map
            rescaled_depth[depth == 0.0] = MIN_DEPTH_REPLACEMENT_VALUE
            rescaled_depth[depth == 1.0] = MAX_DEPTH_REPLACEMENT_VALUE

            return rescaled_depth

        def downscale(rgb, depth, semantic):
            h_downscaling = env_frame_height // self.frame_height
            w_downscaling = env_frame_width // self.frame_width
            assert h_downscaling == w_downscaling
            assert type(h_downscaling) == int
            if h_downscaling == 1:
                return rgb, depth, semantic
            else:
                rgb = F.interpolate(
                    rgb, scale_factor=1. / h_downscaling, mode='bilinear')
                depth = F.interpolate(
                    depth, scale_factor=1. / h_downscaling, mode='bilinear')
                semantic = F.interpolate(
                    semantic, scale_factor=1. / h_downscaling, mode='nearest')
                return rgb, depth, semantic

        env_frame_height, env_frame_width = obs[0]["rgb"].shape[:2]

        rgb = torch.from_numpy(np.stack([ob["rgb"] for ob in obs])).to(self.device)
        depth = torch.from_numpy(np.stack([ob["depth"] for ob in obs])).to(self.device)

        depth = preprocess_depth(depth)

        if (self.ground_truth_semantics
                and "semantic" in obs[0]
                and self.instance_id_to_category_id is not None):
            # Ground-truth semantic segmentation (useful for debugging)
            # TODO Allow multiple environments with ground-truth segmentation
            assert "semantic" in obs[0]
            semantic = torch.from_numpy(
                np.stack([ob["semantic"] for ob in obs]
            ).squeeze(-1).astype(np.int64)).to(self.device)
            semantic = self.instance_id_to_category_id[semantic]
            semantic = self.one_hot_encoding[semantic]

            # Also need depth filtering on ground-truth segmentation
            for i in range(semantic.shape[-1]):
                depth_ = depth[0, :, :, -1]
                semantic_ = semantic[0, :, :, i]
                depth_md = torch.median(depth_[semantic_ == 1])
                if depth_md != 0:
                    filter_mask = ((depth_ >= depth_md + 50) |
                                   (depth_ <= depth_md - 50))
                    # pixels = int(semantic_[filter_mask].sum().item())
                    # if pixels > 0:
                    #     print(f"Filtering out {pixels} pixels")
                    semantic[0, :, :, i][filter_mask] = 0.

            semantic_vis = self._get_semantic_frame_vis(
                rgb[0].cpu().numpy(), semantic[0].cpu().numpy())
            semantic_vis = np.expand_dims(semantic_vis, 0)

        else:
            # Predicted semantic segmentation
            semantic, semantic_vis = self.segmentation.get_prediction(
                rgb.cpu().numpy(),
                depth.cpu().squeeze(-1).numpy()
            )
            semantic = torch.from_numpy(semantic).to(self.device)

        rgb = rgb.permute(0, 3, 1, 2)
        depth = depth.permute(0, 3, 1, 2)
        semantic = semantic.permute(0, 3, 1, 2)

        rgb, depth, semantic = downscale(rgb, depth, semantic)
        obs_preprocessed = torch.cat([rgb, depth, semantic], dim=1)
        obs_preprocessed = obs_preprocessed.to(self.precision)

        return obs_preprocessed, semantic_vis

    def _get_semantic_frame_vis(self, rgb: np.ndarray, semantics: np.ndarray):
        """Visualize first-person semantic segmentation frame."""
        width, height = semantics.shape[:2]
        vis_content = semantics
        vis_content[:, :, -1] = 1e-5
        vis_content = vis_content.argmax(-1)
        vis = Image.new("P", (height, width))
        vis.putpalette(self.color_palette)
        vis.putdata(vis_content.flatten().astype(np.uint8))
        vis = vis.convert("RGB")
        vis = np.array(vis)
        vis = np.where(vis != 255, vis, rgb)
        vis = vis[:, :, ::-1]
        return vis

    def preprocess_pose(self,
                        obs: List[Observations],
                        last_poses: List[np.ndarray]
                        ) -> Tuple[Tensor, List[np.ndarray]]:
        """Preprocess sensor pose information in the observation."""
        curr_poses = []
        pose_deltas = []

        for e in range(self.num_environments):
            curr_pose = np.array([
                obs[e]["gps"][0],
                -obs[e]["gps"][1],
                obs[e]["compass"][0]
            ])
            pose_delta = pu.get_rel_pose_change(curr_pose, last_poses[e])
            curr_poses.append(curr_pose)
            pose_deltas.append(pose_delta)

        return torch.tensor(pose_deltas), curr_poses


import numpy as np
import matplotlib.pyplot as plt

def histogram(x,normalisering = False):
    """
    Et histogram teller antall hendelser. X aksen er hendelsen f.eks. om du har
    kastet mynt eller krone. Y aksen er hvor mange ganger du har fått enten mynt eller krone.
    """
    bin_count = int(np.ceil(np.log2(len(x)) + 1))  #Sturge's regel
    plt.hist(x, bins=bin_count,density = normalisering, facecolor = '#2ab0ff', edgecolor='#169acf', linewidth=0.5)
    plt.xlabel('Bins')
    plt.ylabel('Values')

"""
Vi tar for oss en uniform sannsynlighetsfordeling mellom 0 og 1.
Dvs. At det er like sannsynlig å få 0, 1 og alt mellom.
"""

plt.style.use('seaborn')
num_measurements = np.array([10,1e2,1e3])
for index,n in enumerate(num_measurements):
    x = np.random.uniform(0,1,int(n))
    plt.subplot(1,3,index+1)
    plt.title("{} målinger".format(num_measurements[index]))
    histogram(x)
plt.show()

"""
Vi ser at med flere målinger nærmer det seg den uniforme fordelingen.
Det vi skal se på nå er fordelingen av gjennomsnittene for økende antall målinger.
"""

num_measurements = np.array([2,3,5,200])
reps = 1000
meanSim = np.zeros([4,reps])
for index,n in enumerate(num_measurements):
    meanSim[index] = [np.mean(np.random.uniform(0,1,n)) for j in range(reps)]
    plt.subplot(2,2,index+1)
    plt.title("Gjennomsnitts fordeling n = {}".format(num_measurements[index]))
    histogram(meanSim[index])
plt.xlim(0,1)
plt.show()

"""
Her ser vi at selv om målingene i seg selv ikke er normalfordelt,
så blir fordelingen av gjennomsnittene normalfordelt, og følger dermed sentralgrenseteoremet.
"""

"""
En tydeligere måte å illustrere om målinger er normalfordelt er ved å plotte et QQ plot.
Som sammenligner fordelingens kvantiler med teoretiske kvantiler.
Dersom det er et lineært forhold mellom dem, vil målingene være normalfordelt.
"""

from scipy import stats

for i in range(len(num_measurements)):
    plt.subplot(2,2,i+1)
    stats.probplot(np.random.uniform(0,1,num_measurements[i]),plot = plt)
    plt.title("QQ plot med")
plt.show()

"""
Vi ser i plottene at målingene tatt fra en uniform fordeling ikke er normalfordelt,
ettersom de ikke følger linja.
Men hva om vi lager de samme plottene, med gjennomsnittene i steden.
"""

for i in range(len(num_measurements)):
    plt.subplot(2,2,i+1)
    stats.probplot(meanSim[i],plot = plt)
plt.show()

"""
Her ser vi at fordelingen av gjennomsnittene er normalfordelte, dersom
antall målinger er tilstrekkelig.
"""


import re
from odoo import api, models, _
from odoo.exceptions import UserError
import logging

log = logging.getLogger(__name__)

class AccountInvoiceFinnish(models.Model):
    _inherit = 'account.move'

    @api.model
    def number2numeric(self, number):

        invoice_number = re.sub(r'\D', '', number)

        if invoice_number == '' or invoice_number is False:
            raise UserError(_('Invoice number must contain numeric characters'))

        # Make sure the base number is 3...19 characters long
        if len(invoice_number) < 3:
            invoice_number = ('11' + invoice_number)[-3:]
        elif len(invoice_number) > 19:
            invoice_number = invoice_number[:19]

        return invoice_number

    @api.model
    def get_finnish_check_digit(self, base_number):
        # Multiply digits from end to beginning with 7, 3 and 1 and
        # calculate the sum of the products
        total = sum((7, 3, 1)[idx % 3] * int(val) for idx, val in
                    enumerate(base_number[::-1]))

        # Subtract the sum from the next decade. 10 = 0
        return str((10 - (total % 10)) % 10)

    @api.model
    def get_rf_check_digits(self, base_number):
        check_base = base_number + 'RF00'
        # 1. Convert all non-digits to digits
        # 2. Calculate the modulo 97
        # 3. Subtract the remainder from 98
        # 4. Add leading zeros if necessary
        return ''.join(
            ['00', str(98 - (int(''.join(
                [x if x.isdigit() else str(ord(x) - 55) for x in
                 check_base])) % 97))])[-2:]

    @api.model
    def compute_payment_reference_finnish(self, number):
        # Drop all non-numeric characters
        invoice_number = self.number2numeric(number)

        # Calculate the Finnish check digit
        check_digit = self.get_finnish_check_digit(invoice_number)

        return invoice_number + check_digit

    @api.model
    def compute_payment_reference_finnish_rf(self, number):
        # Drop all non-numeric characters
        invoice_number = self.number2numeric(number)

        # Calculate the Finnish check digit
        invoice_number += self.get_finnish_check_digit(invoice_number)

        # Calculate the RF check digits
        rf_check_digits = self.get_rf_check_digits(invoice_number)

        return 'RF' + rf_check_digits + invoice_number

    def _get_invoice_reference_fi_rf_invoice(self):
        self.ensure_one()
        return self.compute_payment_reference_finnish_rf(self.name)

    def _get_invoice_reference_fi_rf_partner(self):
        self.ensure_one()
        return self.compute_payment_reference_finnish_rf(str(self.partner_id.id))

    def _get_invoice_reference_fi_invoice(self):
        self.ensure_one()
        return self.compute_payment_reference_finnish(self.name)

    def _get_invoice_reference_fi_partner(self):
        self.ensure_one()
        return self.compute_payment_reference_finnish(str(self.partner_id.id))


# -*- coding: UTF-8 -*-

# 从外部文件data.txt导入数据集
def load_data_set():
    data_set = []
    # 读取数据
    fd = open("data.txt", "r")
    # 处理数据
    for line in fd.readlines():
        # 先按行分割字符串
        line = line.strip('\n')
        # 再按列分割字符串
        data_set.append(list(line.split(', ')))
    return data_set

# 从数据集构造1-候选集
def create_C1(data_set):
    C1 = set()
    for t in data_set:
        for item in t:
            # frozenset可hash利于排序
            item_set = frozenset([item])
            C1.add(item_set)
    return C1

# 判断是否满足
def is_apriori(Ck_item, Lksub1):
    for item in Ck_item:
        sub_Ck = Ck_item - frozenset([item])
        if sub_Ck not in Lksub1:
            return False
    return True

# 生成各个候选集Ck
def create_Ck(Lksub1, k):
    Ck = set()
    len_Lksub1 = len(Lksub1)
    list_Lksub1 = list(Lksub1)
    for i in range(len_Lksub1):
        for j in range(1, len_Lksub1):
            l1 = list(list_Lksub1[i])
            l2 = list(list_Lksub1[j])
            l1.sort()
            l2.sort()
            if l1[0:k-2] == l2[0:k-2]:
                Ck_item = list_Lksub1[i] | list_Lksub1[j]
                if is_apriori(Ck_item, Lksub1):
                    Ck.add(Ck_item)
    return Ck

# 通过候选集Ck生成频繁集Lk
def generate_Lk_by_Ck(data_set, Ck, min_support, support_data):
    Lk = set()
    item_count = {}
    for t in data_set:
        for item in Ck:
            if item.issubset(t):
                if item not in item_count:
                    item_count[item] = 1
                else:
                    item_count[item] += 1
    # 转换成浮点数，便于求支持度
    t_num = float(len(data_set))
    for item in item_count:
        if (item_count[item] / t_num) >= min_support:
            Lk.add(item)
            support_data[item] = item_count[item] / t_num
    return Lk

# 生成各频繁项集，最小支持度为0.5
def generate_L(data_set, k, min_support):
    support_data = {}
    # 创建候选1项集
    C1 = create_C1(data_set)
    # 通过候选项1集生成频繁1项集
    L1 = generate_Lk_by_Ck(data_set, C1, min_support, support_data)
    Lksub1 = L1.copy()
    L = []
    L.append(Lksub1)
    for i in range(2, k+1):
        Ci = create_Ck(Lksub1, i)
        Li = generate_Lk_by_Ck(data_set, Ci, min_support, support_data)
        Lksub1 = Li.copy()
        L.append(Lksub1)
    return L, support_data

# 生成从频繁集关联规则分析
def generate_big_rules(L, support_data, min_conf):
    strong_rule_list = []  # 保存强关联规则
    sub_set_list = []   #
    for i in range(0, len(L)):
        for freq_set in L[i]:
            for sub_set in sub_set_list:
                if sub_set.issubset(freq_set):
                    conf = support_data[freq_set] \
                           / support_data[freq_set - sub_set]
                    big_rule = (freq_set - sub_set, sub_set, conf)
                    if conf >= min_conf and big_rule not in strong_rule_list:
                        strong_rule_list.append(big_rule)
            sub_set_list.append(freq_set)
    return strong_rule_list

if __name__ == "__main__":
    # 加载数据集
    data_set = load_data_set()
    # 生成频繁项集及支持度集
    L, support_data = generate_L(data_set, k=3, min_support=0.5)
    # 生成强关联规则
    strong_rules_list = generate_big_rules(L, support_data, min_conf=0.7)
    print ('最小支持度: 0.5\t最小置信度: 0.7')
    # 遍历处理好的频繁项集
    for Lk in L:
        print ("频繁" + str(len(list(Lk)[0])) + "项集") # 输出各频繁项集
        for freq_set in Lk:
            fset = []   # 转换成set
            for i in freq_set:  # 导入到新set
                fset.append(i)
            print (fset, '\t支持度:', support_data[freq_set]) # 输出

    print("强关联规则")
    # 转换成set
    for item in strong_rules_list:
        item0, item1 = [], []
        for i in item[0]:
            item0.append(i)
        for i in item[1]:
            item1.append(i)
        # 输出强关联规则及置信度
        print (item0, "=>", item1, '\t置信度:', item[2])