# -*- coding: utf-8 -*-
import os
import cv2
import shutil
import copy
import json
from mbhk_get_eye import get_label
from PIL import Image,ImageDraw
import numpy as np
labelDst = {"close_eyes": "闭眼", "yawn": "打哈欠", "phone": "打电话", "smoking": "吸烟", "sunglasses_block": "红外阻断",
            "drink_water": "喝水", "toothpick": "叼牙签", "eat_something": "吃东西", \
            "speaking": "张嘴说话", "wear_mask": "戴口罩", "look_down": "往下看", "unclear_eyes": "眼部不清晰",
            "glasses_noBlocking": "戴眼睛", "face_occlusion": "脸部遮挡", "face_big": "脸部姿态过大"
            }

keys_106 = ['contour_left1', 'contour_left2', 'contour_left3', 'contour_left4', 'contour_left5', 'contour_left6',
            'contour_left7', 'contour_left8',
            'contour_left9', 'contour_left10', 'contour_left11', 'contour_left12', 'contour_left13', 'contour_left14',
            'contour_left15', 'contour_left16',
            'contour_chin', 'contour_right16', 'contour_right15', 'contour_right14', 'contour_right13',
            'contour_right12', 'contour_right11', 'contour_right10',
            'contour_right9', 'contour_right8', 'contour_right7', 'contour_right6', 'contour_right5', 'contour_right4',
            'contour_right3', 'contour_right2',
            'contour_right1',
            'nose_bridge1', 'nose_bridge2',
            'nose_bridge3', 'nose_tip', 'nose_left_contour1', 'nose_left_contour2', 'nose_left_contour3',
            'nose_left_contour4', 'nose_left_contour5',
            'nose_middle_contour', 'nose_right_contour5', 'nose_right_contour4', 'nose_right_contour3',
            'nose_right_contour2', 'nose_right_contour1',
            'left_eyebrow_left_corner', 'left_eyebrow_upper_left_quarter', 'left_eyebrow_upper_middle',
            'left_eyebrow_upper_right_quarter',
            'left_eyebrow_upper_right_corner', 'left_eyebrow_lower_right_corner', 'left_eyebrow_lower_right_quarter',
            'left_eyebrow_lower_middle',
            'left_eyebrow_lower_left_quarter',
            'right_eyebrow_upper_left_corner', 'right_eyebrow_upper_left_quarter',
            'right_eyebrow_upper_middle', 'right_eyebrow_upper_right_quarter', 'right_eyebrow_right_corner',
            'right_eyebrow_lower_right_quarter',
            'right_eyebrow_lower_middle', 'right_eyebrow_lower_left_quarter', 'right_eyebrow_lower_left_corner',
            'left_eye_left_corner', 'left_eye_upper_left_quarter', 'left_eye_top', 'left_eye_upper_right_quarter',
            'left_eye_right_corner',
            'left_eye_lower_right_quarter', 'left_eye_bottom', 'left_eye_lower_left_quarter', 'left_eye_pupil',
            'left_eye_center',
            'right_eye_left_corner', 'right_eye_upper_left_quarter', 'right_eye_top', 'right_eye_upper_right_quarter',
            'right_eye_right_corner',
            'right_eye_lower_right_quarter', 'right_eye_bottom', 'right_eye_lower_left_quarter', 'right_eye_pupil',
            'right_eye_center',
            'mouth_left_corner', 'mouth_upper_lip_left_contour2', 'mouth_upper_lip_left_contour1',
            'mouth_upper_lip_top', 'mouth_upper_lip_right_contour1',
            'mouth_upper_lip_right_contour2', 'mouth_right_corner', 'mouth_lower_lip_right_contour2',
            'mouth_lower_lip_right_contour3',
            'mouth_lower_lip_bottom', 'mouth_lower_lip_left_contour3', 'mouth_lower_lip_left_contour2',
            'mouth_upper_lip_left_contour3',
            'mouth_upper_lip_left_contour4', 'mouth_upper_lip_bottom', 'mouth_upper_lip_right_contour4',
            'mouth_upper_lip_right_contour3',
            'mouth_lower_lip_right_contour1', 'mouth_lower_lip_top', 'mouth_lower_lip_left_contour1']

colorDst = {"face": (0, 0, 255), "body": (0, 255, 0), "phone": (255, 0, 0), "telephone": (255, 255, 255),
            "smoke": (0, 255, 255), "smokewithhand": (255, 255, 0), "SafetyBelt": (255, 0, 255)}

def read_img_path(img_dir):
    # name.jpg
    # {"name":path}
    # n*2数组
    # lst = []
    # with open(txtname,"r") as f:
    #     a = f.readlines()
    #     for line in a:
    #         lst.append(line.strip())
    img_path = []
    for curdir, subdir, files in os.walk(img_dir):
        for img in (file for file in files if file.endswith('jpg')):
            l_path = os.path.join(curdir, img)
            # if os.path.splitext(img)[0] not in lst:
            img_path.append([os.path.splitext(img)[0], l_path])
    return img_path

def read_json_path(json_dir):
    # name.json
    # {name:path}
    json_path = {}
    for curdir, subdir, files in os.walk(json_dir):
        for l_json in (file for file in files if file.endswith('json')):
            l_path = os.path.join(curdir, l_json)
            json_path[os.path.splitext(l_json)[0]] = l_path
    return json_path

def search_img(img_dir):
    dst = {}
    for curdir, subdir, files in os.walk(img_dir):
        for img in (file for file in files if file.endswith('jpg')):
            l_path = os.path.join(curdir, img)
            dst[img] = l_path

    return dst

def read_json(directory):
    sumlst = []
    attrDst, keyDst, infoDst = {}, {}, {}
    try:
        with open(directory, "r", encoding="utf8") as fp:
            json_data = json.load(fp)
            for j in range(len(json_data)):
                sublst = []
                if "name" in json_data[j]:
                    if json_data[j]["name"] == "dangerous_driving":
                        # 属性
                        attr = json_data[j]["attributes"]
                        for key in attr:
                            attrDst[key] = attr[key]
                            # attrDst[labelDst[key]] = attr[key]

                        # 人脸
                        cc = json_data[j]["points"]
                        if cc[0][0] is not None:
                            xmin = int(min(cc[0][0], cc[1][0]))
                            ymin = int(min(cc[0][1], cc[1][1]))
                            xmax = int(max(cc[0][0], cc[1][0]))
                            ymax = int(max(cc[0][1], cc[1][1]))
                            w = xmax - xmin
                            h = ymax - ymin
                            if xmin < 0:
                                xmin = 0
                            if ymin < 0:
                                ymin = 0
                            if w < 0:
                                w = -w
                            if h < 0:
                                h = -h
                            sublst.append(xmin)
                            sublst.append(ymin)
                            sublst.append(w)
                            sublst.append(h)
                            if "face" not in infoDst:
                                infoDst["face"] = []
                            infoDst["face"].append(sublst)

                    if json_data[j]["name"] == "humanbody":
                        cc = json_data[j]["points"]
                        xmin = int(min(cc[0][0], cc[1][0]))
                        ymin = int(min(cc[0][1], cc[1][1]))
                        xmax = int(max(cc[0][0], cc[1][0]))
                        ymax = int(max(cc[0][1], cc[1][1]))
                        w = xmax - xmin
                        h = ymax - ymin
                        if xmin < 0:
                            xmin = 0
                        if ymin < 0:
                            ymin = 0
                        if w < 0:
                            w = -w
                        if h < 0:
                            h = -h
                        sublst.append(xmin)
                        sublst.append(ymin)
                        sublst.append(w)
                        sublst.append(h)
                        if "body" not in infoDst:
                            infoDst["body"] = []
                        infoDst["body"].append(sublst)

                    if json_data[j]["name"] == "callwithhand":
                        cc = json_data[j]["points"]
                        xmin = int(min(cc[0][0], cc[1][0]))
                        ymin = int(min(cc[0][1], cc[1][1]))
                        xmax = int(max(cc[0][0], cc[1][0]))
                        ymax = int(max(cc[0][1], cc[1][1]))
                        w = xmax - xmin
                        h = ymax - ymin
                        if xmin < 0:
                            xmin = 0
                        if ymin < 0:
                            ymin = 0
                        if w < 0:
                            w = -w
                        if h < 0:
                            h = -h
                        sublst.append(xmin)
                        sublst.append(ymin)
                        sublst.append(w)
                        sublst.append(h)
                        if "phone" not in infoDst:
                            infoDst["phone"] = []
                        infoDst["phone"].append(sublst)

                    if json_data[j]["name"] == "telephone":
                        cc = json_data[j]["points"]
                        xmin = int(min(cc[0][0], cc[1][0]))
                        ymin = int(min(cc[0][1], cc[1][1]))
                        xmax = int(max(cc[0][0], cc[1][0]))
                        ymax = int(max(cc[0][1], cc[1][1]))
                        w = xmax - xmin
                        h = ymax - ymin
                        if xmin < 0:
                            xmin = 0
                        if ymin < 0:
                            ymin = 0
                        if w < 0:
                            w = -w
                        if h < 0:
                            h = -h
                        sublst.append(xmin)
                        sublst.append(ymin)
                        sublst.append(w)
                        sublst.append(h)
                        if "telephone" not in infoDst:
                            infoDst["telephone"] = []
                        infoDst["telephone"].append(sublst)

                    if json_data[j]["name"] == "smoke":
                        cc = json_data[j]["points"]
                        xmin = int(min(cc[0][0], cc[1][0]))
                        ymin = int(min(cc[0][1], cc[1][1]))
                        xmax = int(max(cc[0][0], cc[1][0]))
                        ymax = int(max(cc[0][1], cc[1][1]))
                        w = xmax - xmin
                        h = ymax - ymin
                        if xmin < 0:
                            xmin = 0
                        if ymin < 0:
                            ymin = 0
                        if w < 0:
                            w = -w
                        if h < 0:
                            h = -h
                        sublst.append(xmin)
                        sublst.append(ymin)
                        sublst.append(w)
                        sublst.append(h)
                        if "smoke" not in infoDst:
                            infoDst["smoke"] = []
                        infoDst["smoke"].append(sublst)

                    if json_data[j]["name"] == "smokewithhand":
                        cc = json_data[j]["points"]
                        xmin = int(min(cc[0][0], cc[1][0]))
                        ymin = int(min(cc[0][1], cc[1][1]))
                        xmax = int(max(cc[0][0], cc[1][0]))
                        ymax = int(max(cc[0][1], cc[1][1]))
                        w = xmax - xmin
                        h = ymax - ymin
                        if xmin < 0:
                            xmin = 0
                        if ymin < 0:
                            ymin = 0
                        if w < 0:
                            w = -w
                        if h < 0:
                            h = -h
                        sublst.append(xmin)
                        sublst.append(ymin)
                        sublst.append(w)
                        sublst.append(h)
                        if "smokewithhand" not in infoDst:
                            infoDst["smokewithhand"] = []
                        infoDst["smokewithhand"].append(sublst)

                    if json_data[j]["name"] == "SafetyBelt":
                        cc = json_data[j]["points"]
                        xmin = int(min(cc[0][0],cc[1][0]))
                        ymin = int(min(cc[0][1],cc[1][1]))
                        xmax = int(max(cc[0][0],cc[1][0]))
                        ymax = int(max(cc[0][1],cc[1][1]))
                        w = xmax - xmin
                        h = ymax - ymin
                        if xmin < 0:
                            xmin = 0
                        if ymin < 0:
                            ymin = 0
                        if w < 0:
                            w = -w
                        if h < 0:
                            h = -h
                        sublst.append(xmin)
                        sublst.append(ymin)
                        sublst.append(w)
                        sublst.append(h)
                        if "SafetyBelt" not in infoDst:
                            infoDst["SafetyBelt"] = []
                        infoDst["SafetyBelt"].append(sublst)

                    if json_data[j]["name"] in keys_106:
                        keyDst[json_data[j]["name"]] = [int(x) for x in json_data[j]["points"][0]]

        sumlst.append(infoDst)
        sumlst.append(attrDst)
        sumlst.append(keyDst)
        return sumlst

    except:
        f = open("error.txt", "a")
        f.write("{}\n".format(directory))
        f.close()
        return 0

def plot_img(image, info):
    h, w, _ = image.shape
    font = cv2.FONT_HERSHEY_SIMPLEX
    # 画框
    infoDst = info[0]
    y_axis_face = 0
    for key in infoDst:
        color = colorDst[key]
        for subInfo in infoDst[key]:
            cv2.putText(image, key, (int(w * (42 / 1280)), int(h * (131 / 720)) + y_axis_face), font, 1.2, color, 2)
            cv2.rectangle(image, (subInfo[0], subInfo[1]), (subInfo[0] + subInfo[2], subInfo[1] + subInfo[3]), color, 1)
            y_axis_face += 50

    # 属性
    attrDst = info[1]
    y_axis = 0
    for key in attrDst:
        if attrDst[key]:
            # key = key.decode('utf8')
            # if not isinstance(key,unicode):
            #     key = key.decode('utf8')
            cv2.putText(image, key, (int(w * (1056 / 1280)), int(h * (159 / 720)) + y_axis), font, 1.2, (0, 255, 0), 2)
            y_axis += 50

    # 关键点
    keyDst = info[2]
    for key in keyDst:
        cv2.circle(image, (keyDst[key][0], keyDst[key][1]), 1, (0, 255, 0))

    return image

def get_change_label(label):
    '''

    '''

    # 扩大眼睛框
    eye_point = [label[0:4],label[4:8]]
    label_min_max = []
    for tdata in eye_point:
        xmin,ymin,xmax,ymax = tdata
        # cv2.rectangle(img,(int(xmin),int(ymin)),(int(xmax),int(ymax)),(255,0,50),2)
        w,h = xmax - xmin, ymax - ymin
        k = np.random.random_sample()*0.1+0.05
        ratio = h/w
        if ratio > 1:
            ratio = ratio - 1
            xmin -= (ratio/2*w+k*h)
            ymin -= (k*h)
            xmax += (ratio/2*w+k*h)
            ymax += (k*h)
            label_min_max.extend([int(xmin),int(ymin),int(xmax),int(ymax)])
            # crop_img.append(img.crop((int(xmin),int(ymin),int(xmax),int(ymax))))
        else:
            ratio = w/h - 1
            xmin -= (k*w)
            ymin -= (ratio/2*h+k*w)
            xmax += (k*w)
            ymax += (ratio/2*h + k*w)
            label_min_max.extend([int(xmin),int(ymin),int(xmax),int(ymax)])
    return label_min_max

def main():
    path = "error_class/change_img/close_eye"
    dst = search_img(path)
    string = "error_class/change_img/close_eye"
    a = read_json(string)
    # jpgname = os.path.basename(string)
    # image = cv2.imread(dst[jpgname.replace("json","jpg")])

    # plot_img(image,a)

    # # cc = a[0]["face"]
    # # for i in cc:
    # #     cv2.rectangle(image,(i[0],i[1]),(i[0] + i[2],i[1] + i[3]),(0,255,0),1)
    # cv2.imshow("a",image)
    # cv2.waitKey(0)
    # # print(cc)

def show():
    path = "error_class/change_img/close_eye"
    isEyePath = "error_class/temp"
    isHongPath = "error_class/temp"
    isLookDownPath = "error_class/temp"
    sumPath = "error_class/temp"
    big_head_pose = "error_class/temp"
    if not os.path.exists("error_class/temp"):
        os.mkdir("error_class/temp")
    # if not os.path.exists(isEyePath):
    #     os.mkdir(isEyePath)
    # if not os.path.exists(isHongPath):
    #     os.mkdir(isHongPath)
    # if not os.path.exists(isLookDownPath):
    #     os.mkdir(isLookDownPath)
    # if not os.path.exists(sumPath):
    #     os.mkdir(sumPath)
    # if not os.path.exists(big_head_pose):
    #     os.mkdir(big_head_pose)

    # name path
    # text_save_path = os.path.join(r"C:\Users\Mic_hu\Desktop\headpose_test_data\20210122_data","finish.txt")
    # f_finish = open(text_save_path,"a")
    img_path = read_img_path(path)
    json_path = read_json_path(path)
    count = 0
    while count < len(img_path):
        img = cv2.imread(img_path[count][1])
        # img_write = cv2.imread(img_path[count][1])
        img_name = img_path[count][0]
        json_info = read_json(json_path[img_name])
        tlabel_min_max = get_label(json_path[img_name])
        label_min_max = get_change_label(tlabel_min_max)
        left_eye,right_eye = label_min_max[0:4],label_min_max[4:8]

        if json_info:
            plot_img(img,json_info)
            cv2.rectangle(img,(int(left_eye[0]),int(left_eye[1])),(int(left_eye[2]),int(left_eye[3])),(0,255,0),2)
            cv2.rectangle(img,(int(right_eye[0]),int(right_eye[1])),(int(right_eye[2]),int(right_eye[3])),(0,255,0),2)
            cv2.imshow("test",img)
            # cv2.imshow("source",img_write)
            get_input = cv2.waitKey(0)
            count += 1
        #     if chr(get_input) == "q":
        #         # f_finish.close()
        #         pass
        #         break
        #     elif chr(get_input) == " ":
        #         # f_finish.write("{}\n".format(img_name))
        #         count += 1
        #     elif chr(get_input) == "f":
        #         count -= 1
        #         if count <= 0:
        #             count = 0
        #     #赋予你选择错误路径的权力
        #     # elif chr(get_input) == "a":
        #     #     f_finish.write("{}\n".format(img_name))
        #     #     count += 1
        #     #     input_mode = input("eye:1,hong:2,look:3,sum:4  --->:")

        #     elif chr(get_input) == "v":
        #         cv2.imwrite(os.path.join(isEyePath,img_name + ".jpg"),img_write)
        #         # f_finish.write("{}\n".format(img_name))
        #         count += 1
        #         print("eye:{}".format(img_name))
        #     elif chr(get_input) == "b":
        #         cv2.imwrite(os.path.join(isHongPath,img_name + ".jpg"),img_write)
        #         # f_finish.write("{}\n".format(img_name))
        #         count += 1
        #         print("red_block:{}".format(img_name))
        #     elif chr(get_input) == "n":
        #         #向下看
        #         cv2.imwrite(os.path.join(isLookDownPath,img_name + ".jpg"),img_write)
        #         # f_finish.write("{}\n".format(img_name))
        #         count += 1
        #         print("look_down:{}".format(img_name))
        #     elif chr(get_input) == "m":
        #         #其他
        #         cv2.imwrite(os.path.join(sumPath,img_name + ".jpg"),img_write)
        #         # f_finish.write("{}\n".format(img_name))
        #         count += 1
        #         print("sume:{}".format(img_name))
        #     elif chr(get_input) == "c":
        #         #大姿态
        #         cv2.imwrite(os.path.join(big_head_pose,img_name + ".jpg"),img_write)
        #         # f_finish.write("{}\n".format(img_name))
        #         count += 1
        #         print("big_head_pose:{}".format(img_name))
        #     else:
        #         print("input error....")
        #         pass
        #         # input("输错啦,只能是1,2,3,4某个值！--->:")
        # else:
        #     count += 1
        #     # f_finish.write("{}\n".format(img_name))
        # print("img:{}/{}".format(count,len(img_path)))

show()


import logging
import os

import torch

logger = logging.getLogger(__name__)

class Checkpointer:
    """A simple pytorch checkpointer.

    Parameters
    ----------

    model : torch.nn.Module
        Network model, eventually loaded from a checkpointed file

    optimizer : :py:mod:`torch.optim`, Optional
        Optimizer

    scheduler : :py:mod:`torch.optim`, Optional
        Learning rate scheduler

    path : :py:class:`str`, Optional
        Directory where to save checkpoints.
    """

    def __init__(self, model, optimizer=None, scheduler=None, path="."):
        self.model = model
        self.optimizer = optimizer
        self.scheduler = scheduler
        self.path = os.path.realpath(path)

    def save(self, name, **kwargs):
        data = {}
        data["model"] = self.model.state_dict()
        if self.optimizer is not None:
            data["optimizer"] = self.optimizer.state_dict()
        if self.scheduler is not None:
            data["scheduler"] = self.scheduler.state_dict()
        data.update(kwargs)

        name = f"{name}.pth"
        outf = os.path.join(self.path, name)
        logger.info(f"Saving checkpoint to {outf}")
        torch.save(data, outf)
        with open(self._last_checkpoint_filename, "w") as f:
            f.write(name)

    def load(self, f=None):
        """Loads model, optimizer and scheduler from file.

        Parameters
        ==========

        f : :py:class:`str`, Optional
            Name of a file (absolute or relative to ``self.path``), that
            contains the checkpoint data to load into the model, and optionally
            into the optimizer and the scheduler.  If not specified, loads data
            from current path.
        """

        if f is None:
            f = self.last_checkpoint()

        if f is None:
            # no checkpoint could be found
            logger.warning("No checkpoint found (and none passed)")
            return {}

        # loads file data into memory
        logger.info(f"Loading checkpoint from {f}...")
        checkpoint = torch.load(f, map_location=torch.device("cpu"))

        # converts model entry to model parameters
        self.model.load_state_dict(checkpoint.pop("model"))

        if self.optimizer is not None:
            self.optimizer.load_state_dict(checkpoint.pop("optimizer"))
        if self.scheduler is not None:
            self.scheduler.load_state_dict(checkpoint.pop("scheduler"))

        return checkpoint

    @property
    def _last_checkpoint_filename(self):
        return os.path.join(self.path, "last_checkpoint")

    def has_checkpoint(self):
        return os.path.exists(self._last_checkpoint_filename)

    def last_checkpoint(self):
        if self.has_checkpoint():
            with open(self._last_checkpoint_filename) as fobj:
                return os.path.join(self.path, fobj.read().strip())
        return None


#====================================================================#
# File Information
#====================================================================#
"""
    SelfCheck.py
    =============
    Summary:
    --------
    This file contains functions specific to Driver.py that allows
    it to correctly perform an in depth check of it's own integrity.

    Functions:
    ----------
"""
#====================================================================#
# Loading Logs
#====================================================================#
from Libraries.BRS_Python_Libraries.BRS.Debug.LoadingLog import LoadingLog
LoadingLog.Start("SelfCheck.py")
#====================================================================#
# Imports
#====================================================================#
#region ------------------------------------------------------ Python
LoadingLog.Import("Python")
#endregion
#region --------------------------------------------------------- BRS
LoadingLog.Import("Libraries")
from Libraries.BRS_Python_Libraries.BRS.Debug.consoleLog import Debug
from Libraries.BRS_Python_Libraries.BRS.Utilities.Enums import Execution, FileIntegrity
from Libraries.BRS_Python_Libraries.BRS.Utilities.FileHandler import CompareList, IsPathValid
#endregion
#region -------------------------------------------------------- Kivy
LoadingLog.Import("Kivy")
#endregion
#region ------------------------------------------------------ KivyMD
LoadingLog.Import('KivyMD')
#endregion
#====================================================================#
# Variables
#====================================================================#

#====================================================================#
# Functions
#====================================================================#
def CheckContent() -> FileIntegrity:
    """
        CheckContent:
        =============
        Summary:
        --------
        This function compares all the folders and sub folders of this
        device driver for any problems or mismatches or unexpected
        data.

        Returns:
        --------
        Returns a value from the `FileIntegrity` enumeration.
    """
    Debug.Start("CheckFolders")
    #region ------------------------------------- [0] - Imports
    import os
    from Libraries.BRS_Python_Libraries.BRS.Utilities.FileHandler import AppendPath, CompareList
    from Libraries.BRS_Python_Libraries.BRS.Utilities.LanguageHandler import _
    from Local.Drivers.Batiscan.Driver import variables
    #endregion
    #region ------------------------------------- [1] - Define content & paths
    Debug.Log("[0]: Defining variables")

    expectedContent = {
        # Main content
        "/Local/Drivers/Batiscan/" : [
            ".git",
            ".gitignore",
            "Libraries",
            "Local",
            "Pages",
            "Programs",
            "__init__.py",
            "Config.json",
            "Driver.py"
        ],

        # Library folder content
        "/Local/Drivers/Batiscan/Libraries/" : [
            "Backgrounds"
        ],

        # Backgrounds folder content
        "/Local/Drivers/Batiscan/Libraries/Backgrounds/" : [
            "Menu"
        ],

        # Menu folder content
        "/Local/Drivers/Batiscan/Libraries/Backgrounds/Menu/" : [
            "Dark.png",
            "Light.png"
        ],

        # Page folder content
        "/Local/Drivers/Batiscan/Pages/" : [
            "BatiscanMenu.py",
            "DebuggerMenu.py",
            "AboutMenu.py",
            "BatiscanValuesMenu.py",
            "sea-monkey.gif",
            "submarine.obj",
            "submarine.glsl"
        ],

        # Local folder content
        "/Local/Drivers/Batiscan/Local/" : [
            "Cache",
            "Languages",
            "Profiles"
        ],

        # Program folder content
        "/Local/Drivers/Batiscan/Programs/" : [
            "FileHandler",
            "GUI",
            "Communications",
            "Controls"
        ],

        # FileHandler folder content
        "/Local/Drivers/Batiscan/Programs/FileHandler/" : [
            "SelfCheck.py"
        ],

        # GUI folder content
        "/Local/Drivers/Batiscan/Programs/GUI/" : [
            "Navigation.py",
            "joystick",
            "Cards.py"
        ]
    }

    exceptions = [
        "__pycache__"
    ]

    #endregion
    #region ------------------------------------- [2] - Compare lists with expected content
    Debug.Log("[2]: Checking contents")
    variables.errorMessage = _("The driver's content did not match the expected content.")
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # For loop that checks each path's expected
    # content with the actual content found at that
    # path.
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    for path in expectedContent.keys():
        # [0] --------------------------- Create path
        key = path
        path = AppendPath(os.getcwd(), path)

        # [1] --------------------------- Path validity
        valid = IsPathValid(path)
        if(not valid):
            Debug.Error(">>> INVALID PATH:")
            Debug.Error(f">>> {path}")
            Debug.End()
            return FileIntegrity.Corrupted

        # [3] --------------------------- Actual content
        content = os.listdir(path)

        # [2] --------------------------- List comparaison
        execution = CompareList(expectedContent[key], content, exceptions=exceptions, DontDebug=False)
        if(execution != Execution.Passed):
            Debug.Error(f">>> {key}:\t FAILED")
            Debug.Log(f">>> Expected: {expectedContent[key]}")
            Debug.Log(f">>> Gotten:  {content}")
            Debug.End()
            return FileIntegrity.Corrupted
        else:
            Debug.Log(f">>> {key}:\t PASSED")
    #endregion
    Debug.End()
    return FileIntegrity.Good
#====================================================================#
# Classes
#====================================================================#

#====================================================================#
LoadingLog.End("SelfCheck.py")


import numpy

with open("input.txt", "r") as f:
    lines = f.readlines()
p0 = []
p1 = []
for line in lines:
    points = line.split(" -> ")
    p0.append(list(map(int, points[0].split(","))))
    p1.append(list(map(int, points[1].split(","))))

p0 = numpy.array(p0)
p1 = numpy.array(p1)
#find max
max = ( numpy.amax(p0) if numpy.amax(p0) > numpy.amax(p1) else numpy.amax(p1) ) + 1
map = numpy.zeros((max, max))
indices = numpy.where((p0[:,0] == p1[:,0]) | (p0[:,1] == p1[:,1]))[0]
indices_diag = numpy.where((numpy.abs(p0[:,0] - p1[:,1]) == numpy.abs(p0[:,1] - p1[:,0])) |  (numpy.abs(p0[:,0] - p1[:,0]) == numpy.abs(p0[:,1] - p1[:,1])))[0]
for i in indices:
    y1 = p0[i,0]
    y2 = p1[i,0]
    x1 = p0[i,1]
    x2 = p1[i,1]
    if x1 == x2:
        if y1 < y2:
            map[x1, y1:y2+1] += 1
        else:
            map[x1, y2:y1+1] += 1
    else:
        if x1 < x2:
            map[x1:x2+1, y1] += 1
        else:
            map[x2:x1+1, y1] += 1
for i in indices_diag:
    y1 = p0[i,0]
    y2 = p1[i,0]
    x1 = p0[i,1]
    x2 = p1[i,1]
    #get rightmost start point
    if y1 < y2:
        start_x = x1
        start_y = y1
        end_x = x2
        end_y = y2
        if x1 < x2:
            m = 1
        else:
            m = -1
    else:
        start_x = x2
        start_y = y2
        end_x = x1
        end_y = y1
        if x1 < x2:
            m = -1
        else:
            m = 1
    while(start_x != end_x):
        map[start_x, start_y] += 1
        start_x += m
        start_y += 1
    map[start_x, start_y] += 1
    #print(map)

print(map)
times = numpy.where(map >= 2)
print(numpy.shape(times))


from cursor.path import Path
from cursor.position import Position
from cursor.collection import Collection
from cursor.bb import BoundingBox

def test_bb_center():
    bb = BoundingBox(100, 200, 300, 400)
    cx, cy = bb.center()
    assert cx == 200
    assert cy == 300

def test_bb_center2():
    bb = BoundingBox(-100, -100, 100, 100)
    cx, cy = bb.center()
    assert cx == 0
    assert cy == 0

def test_bb_center3():
    bb = BoundingBox(0, 0, 300, 300)
    cx, cy = bb.center()
    assert cx == 150
    assert cy == 150

def test_bb_scale():
    bb = BoundingBox(0, 0, 100, 100)
    bb.scale(0.5)

    assert bb.x == 25
    assert bb.y == 25
    assert bb.x2 == 75
    assert bb.y2 == 75
    assert bb.w == 50
    assert bb.h == 50

def test_bb_subdiv():
    bb = BoundingBox(0, 0, 300, 300)
    subdivided = bb.subdiv(10, 10)

    assert len(subdivided) == 100

    for _bb in subdivided:
        assert _bb.w == 30
        assert _bb.h == 30

def test_inside_pos():
    bb = BoundingBox(0, 0, 300, 300)
    pos1 = Position(10, 10)
    pos2 = Position(10, 301)
    assert pos1.inside(bb)
    assert not pos2.inside(bb)

    pa = Path()
    pa.add(0, 300)
    pa.add(300, 280)

    assert pa.inside(bb)

    pa.add(-10, 10)
    assert not pa.inside(bb)

    pc = Collection()
    pc.add(pa)
    assert not pc.inside(bb)

    pc2 = Collection()
    p1 = Path()
    p1.add(100, 100)
    p1.add(100, 200)

    p2 = Path()
    p2.add(0, 0)
    p2.add(300, 300)
    pc2.add(p1)
    pc2.add(p2)

    assert pc2.inside(bb)

def test_paths_from_bb():
    bb = BoundingBox(0, 0, 300, 300)
    paths = bb.paths()

    assert len(paths) == 4
    assert paths[0] == (0, 0, 300, 0)
    assert paths[1] == (300, 0, 300, 300)
    assert paths[2] == (300, 300, 0, 300)
    assert paths[3] == (0, 300, 0, 0)


import re
import helper

# Sample public reports as a single string
reports = "Critical water shortage in our town demands immediate attention. Ministry of Environment, we need assistance night safety street"

# Define ministry agencies and their associated keywords
ministries = {
    "Kementerian Pendidikan, Kebudayaan, Riset dan Teknologi": helper.generate_keyword("kementerianPendidikan.txt"),
    "Kementerian Komunikasi dan Informatika": helper.generate_keyword("kementerianKomunikasi.txt"),
    "Kementerian Sosial": helper.generate_keyword("kementerianSosial.txt"),
    "Kepolisian Negara Republik Indonesia": helper.generate_keyword("kepolisianNegara.txt"),
    "Kementerian Kelautan dan Perikanan": helper.generate_keyword("kementerianKelautan.txt"),
    "Badan Kepegawaian Negara": helper.generate_keyword("kepegawaianNegara.txt"),
    "Kementerian Dalam Negeri": helper.generate_keyword("kementerianDalamNegeri.txt"),
    "Kementerian Pekerjaan Umum dan Perumahan Rakyat": helper.generate_keyword("kementerianPekerjaan.txt"),
    "Kementrian Agama": helper.generate_keyword("kementerianAgama.txt"),
    "Otoritas Jasa Keuangan": helper.generate_keyword("otoritasJasaKeuangan.txt"),
}

# Function to filter reports to ministries based on keywords and count the matches
def filter_reports(report):
    filtered_reports = {ministry: {"keyword_count": 0} for ministry in ministries}

    report = report.lower()  # Convert report to lowercase for case-insensitive matching

    for ministry, keywords in ministries.items():
        keyword_count = 0
        for keyword in keywords:
            matches = re.findall(rf"\b{re.escape(keyword)}\b", report)
            keyword_count += len(matches)

        filtered_reports[ministry]["keyword_count"] = keyword_count

    # Find the ministry with the highest keyword count
    max_keyword_count = max(filtered_reports.values(), key=lambda x: x["keyword_count"])["keyword_count"]

    # Print only the ministries with the highest keyword count
    for ministry, data in filtered_reports.items():
        if max_keyword_count == 0:
            return "Tidak menemukan kementerian dan lembaga yang dapat dituju."
        elif data["keyword_count"] == max_keyword_count:
            return ministry

# Filter the reports and count the keywords
# filtered_reports = filter_reports(reports, ministries)


import pathlib
import zipfile
from io import BytesIO

import pandas as pd
import requests
from disentanglement_lib.config.unsupervised_study_v1.sweep import get_config

configs = get_config()

def get_model_info():
    """Retrieve information about the pre-trained models of "Challenging Common Assumptions in the Unsupervised Learning
    of Disentangled Representations" (http://proceedings.mlr.press/v97/locatello19a.html) from disentanglement lib
    (https://github.com/google-research/disentanglement_lib).

    :return: A dataframe containing the datasets and models types used along with model indexes matching each
    (model type, dataset) pair
    """
    df = pd.DataFrame(configs)
    results = {"dataset": [], "model": [], "start_idx": [], "end_idx": []}
    for model in df['model.name'].unique():
        for dataset in df['dataset.name'].unique():
            idxs = df.index[(df['model.name'] == model) & (df['dataset.name'] == dataset)]
            results["dataset"].append(dataset)
            results["model"].append(model)
            results["start_idx"].append(idxs.min())
            results["end_idx"].append(idxs.max())
    df2 = pd.DataFrame.from_dict(results)
    return df2

def download_models(base_path, save_space=False, overwrite=False):
    """ Download all the pretrained models of "Challenging Common Assumptions in the Unsupervised Learning
    of Disentangled Representations" (http://proceedings.mlr.press/v97/locatello19a.html), unzip and save them
    in <base_path>.

    :param base_path: The path where the models will be saved
    :param save_space: If true, only the metrics will be saved to use less space, otherwise, all the content will be saved
    :param overwrite: If true, any existing saved model in <base_path> will be override, otherwise, if any model is present
    in the base_path, download is skipped.
    :return: None
    """
    file = pathlib.Path("{}/0".format(base_path))
    if file.exists() and not overwrite:
        return
    base_url = "https://storage.googleapis.com/disentanglement_lib/unsupervised_study_v1"
    for i, url in [(i, "{}/{}.zip".format(base_url, i)) for i in range(10800)]:
        print("Downloading model {} from {}".format(i, url))
        r = requests.get(url)
        raw_content = BytesIO(r.content)
        z = zipfile.ZipFile(raw_content)
        members = [n for n in z.namelist() if n.startswith("{}/metrics/".format(i))] if save_space is True else None
        z.extractall(path=base_path, members=members)

def get_file(path):
    """Returns path relative to file."""
    from pkg_resources import resource_filename
    return resource_filename("tc_study", path)


# Sergii Logosha, 22 Jun 22

# Program copies child continuously asking questions

from random import choice

questions = ["Why the water is wet?\n", "Why the Sun is so bright?\n", "Why my dog can't talk?\n"]
question = choice(questions)
answer = input(question).lower().strip()

while answer != "just because":
    answer = input("Why?\n").strip().lower()
print("Oh... Okay")


import multiprocessing
import queue

def worker_func(worker_index, input_queue, output_queue):

    import time

    while True:
        try:
            input = input_queue.get(timeout=5)
            print("worker_index:" + str(worker_index) + " ")
            print(input)
            output_queue.put((worker_index, input))
            time.sleep(3)
        except queue.Empty:
            # キューが空になった
            print("worker index:" + str(worker_index) + " End : Queue is empty.")
            break
    return

if __name__ == '__main__':
    m = multiprocessing.Manager()
    input_queue = m.Queue()
    output_queue = m.Queue()

    input_queue.put( [ 1, 2] )
    input_queue.put( "Heelo" )
    input_queue.put( 3 )
    input_queue.put( (4, 5) )
    input_queue.put( 6.0 )
    input_queue.put( "Bye" )

    num_worker = 3

    # Pool
    pool = multiprocessing.Pool()
    for worker_index in range(0, num_worker):
        pool.apply_async(worker_func, args=(worker_index, input_queue, output_queue))

    pool.close()
    pool.join()

    print("All processes end.")
    while output_queue.empty() == False:
        q = output_queue.get()
        print(q)

    # Process
    input_queue.put( [ 1, 2] )
    input_queue.put( "Heelo" )
    input_queue.put( 3 )
    input_queue.put( (4, 5) )
    input_queue.put( 6.0 )
    input_queue.put( "Bye" )

    process_list = []
    for worker_index in range(0, num_worker):
        p = multiprocessing.Process(
            target=worker_func,
            args=(worker_index, input_queue, output_queue))
        p.start()
        process_list.append(p)

    for p in process_list:
        p.join()

    print("All processes end.")
    while output_queue.empty() == False:
        q = output_queue.get()
        print(q)


import sys
from get_first_link import get_first_link, WIKIPEDIA
from constants import WIKIPEDIA, WIKIPATH, PHILOSOPHY, MAX_HOPS

def is_valid_wikipedia(url):
    if not url.startswith(WIKIPEDIA + WIKIPATH):
        return False
    return True

def main(curr_url):
    if not is_valid_wikipedia(curr_url):
        print("Invalid url. Must be a url to an English Wikipedia page")
        return

    hop_num = 0
    visited = []
    while hop_num <= MAX_HOPS:
        print(curr_url)
        if curr_url == PHILOSOPHY:
            print(f"{hop_num} hops")
            return
        next = get_first_link(curr_url, visited)
        if next:
            hop_num += 1
            visited.append(next)
            curr_url = next
        else:
            print("No valid url to hop to!")
            print(f"{hop_num} hops")
            return
    print("Ran out of hops!")
    print(f"{MAX_HOPS} hops")
    return

starting_url = sys.argv[1]
main(starting_url)


from django.urls import path

from .views import (
    index,
    CarListView,
    CarDetailView,
    CarCreateView,
    CarUpdateView,
    CarDeleteView,
    assign_user_to_car,
    delete_user_from_car,
    DriverListView,
    DriverDetailView,
    DriverCreateView,
    ManufacturerListView,
    ManufacturerCreateView,
    ManufacturerUpdateView,
    ManufacturerDeleteView,
    DriverUpdateLicenseView,
    DriverDeleteView
)

urlpatterns = [
    path("", index, name="index"),
    path("manufacturers/",
         ManufacturerListView.as_view(),
         name="manufacturer-list"),
    path("manufacturers/create/",
         ManufacturerCreateView.as_view(),
         name="manufacturer-create"),
    path("manufacturers/update/<int:pk>/",
         ManufacturerUpdateView.as_view(),
         name="manufacturer-update"),
    path("manufacturers/delete/<int:pk>/",
         ManufacturerDeleteView.as_view(),
         name="manufacturer-delete"),
    path("cars/", CarListView.as_view(), name="car-list"),
    path("cars/<int:pk>/", CarDetailView.as_view(), name="car-detail"),
    path("cars/create/", CarCreateView.as_view(), name="car-create"),
    path("cars/update/<int:pk>/", CarUpdateView.as_view(), name="car-update"),
    path("cars/delete/<int:pk>/", CarDeleteView.as_view(), name="car-delete"),
    path("cars/add/user/<int:pk>/", assign_user_to_car, name="car-add-user"),
    path("cars/delete/user/<int:pk>/",
         delete_user_from_car,
         name="car-delete-user"),
    path("drivers/", DriverListView.as_view(), name="driver-list"),
    path("drivers/<int:pk>/",
         DriverDetailView.as_view(),
         name="driver-detail"),
    path("drivers/create/",
         DriverCreateView.as_view(),
         name="driver-create"),
    path("drivers/licencse/update/<int:pk>/",
         DriverUpdateLicenseView.as_view(),
         name="driver-update-license"),
    path("drivers/delete/<int:pk>/",
         DriverDeleteView.as_view(),
         name="driver-delete"),
]

app_name = "taxi"


import requests
from bs4 import BeautifulSoup
import time
import csv
import Sendmail
from datetime import date

urls = ["https://finance.yahoo.com/quote/AAPL?p=AAPL", "https://finance.yahoo.com/quote/AMZN?p=AMZN&ncid=yahooproperties_peoplealso_km0o32z3jzm" , "https://finance.yahoo.com/quote/GOOG?p=GOOG&ncid=yahooproperties_peoplealso_km0o32z3jzm"]
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36'}

today = str(date.today()) + ".csv"
csv_file = open(today, 'w')
csv_writer = csv.writer(csv_file)
csv_writer.writerow(['Stock Name', 'Current Value', 'Previous Close', 'Open' , 'Bid' , 'Ask' , 'Days Range', '52 Week Range' , 'Volume' , 'Avg Volume'])

for url in urls:
    stock = []
    html_page = requests.get(url , headers= headers)
    soup = BeautifulSoup(html_page.content , 'lxml')

    header_info = soup.find_all("div", id ="quote-header-info")[0]
    stock_title = header_info.find("h1").get_text()
    stock_price = header_info.find("div" , class_ ="My(6px) Pos(r) smartphone_Mt(6px) W(100%)").find("fin-streamer").get_text()

    stock.append(stock_title)
    stock.append(stock_price)

    table_info = soup.find_all("div" , class_="D(ib) W(1/2) Bxz(bb) Pend(12px) Va(t) ie-7_D(i) smartphone_D(b) smartphone_W(100%) smartphone_Pend(0px) smartphone_BdY smartphone_Bdc($seperatorColor)")[0].find_all("tr")

    for i in range(0,8):
        value = table_info[i].find_all("td")[1].get_text()
        stock.append(value)

    csv_writer.writerow(stock)
    time.sleep(5)

csv_file.close()
Sendmail.send(filename= today)


import numpy as np
np.random.seed(0)

from bokeh.io import curdoc
from bokeh.layouts import widgetbox, row, column, gridplot
from bokeh.models import ColumnDataSource, Select, Slider
from bokeh.plotting import figure
from bokeh.palettes import Greys256
from bokeh.models.callbacks import CustomJS

from skimage.feature import blob_doh
from skimage.io import imread
from skimage.color import rgb2gray
from skimage.util import invert

# define some helper functions
def Load_image(path):
    """
    :param path     path to image file

    Function that reads image, takes a patch, converts to gray
    Returns processed image and inverted image
    """
    # read test image
    im = imread(path)
    # take patch of image and convert to grayscale
    im = im[:256,:256]
    #im = im[:256,:256]
    im = rgb2gray(im)

    # prepare an inverted image for comparison
    # search for white blobs on black background AND black blobs on white background
    imIn = invert(im)
    return im, imIn

#Real Callback function
def blob_detector(imIn, overlap, threshold, min_sigma, max_sigma, log_scale):
    """

    :param imIn:        Inverted Image grayscale patch
    :param:             Hyper-Parameters for blob detector
        :overlap
        :threshold
        :min_sigma
        :max_sigma
        log_scale
    :return:
    """
    # Initialize and Invoke DoH blob detector
    blobs_doh = blob_doh(imIn, overlap=overlap, threshold=threshold, min_sigma=min_sigma,
                         max_sigma=max_sigma, log_scale=log_scale)
    #blobs_y, blobs_x, blobs_r = [],[],[]
    blobs_y = blobs_doh[:,0]
    blobs_x = blobs_doh[:,1]
    blobs_r = blobs_doh[:,2]
    """for blob in blobs_doh:
        y, x, r = blob # This code can be made better
        blobs_y.append(y)
        blobs_x.append(x)
        blobs_r.append(r)"""
    return blobs_y, blobs_x, blobs_r

# set up more callbacks
def update_blob_detector(attrname, old, new):
    global imIn
    logscale = logscale_select.value
    maxSigma = maxSigma_slider.value
    minSigma = minSigma_slider.value
    threshold = threshold_slider.value
    overlap = overlap_slider.value
    print("Calculating Blobs ..........")
    print("params are",logscale,maxSigma,minSigma,overlap)
    blobs_y, blobs_x, blobs_r = blob_detector(imIn, overlap, threshold, minSigma, maxSigma, logscale)
    source.data = dict(x=blobs_x, y= blobs_y, r=blobs_r)
    print("blobs updated")

def save_params(attrname, old, new):
    logscale = logscale_select.value
    maxSigma = maxSigma_slider.value
    minSigma = minSigma_slider.value
    threshold = threshold_slider.value
    overlap = overlap_slider.value
    input = str(logscale) +','+ str(maxSigma) +','+ str(minSigma) +','+ str(threshold) +','+ str(overlap)+'\n'
    if button.value:
        with open('./Flask_parameter_update/output.txt', 'a') as file:
            file.writelines(input)
    print('Params saved')

# set up widgets
logscale_vals=['True', 'False']
logscale_select = Select(value='True',
                          title='Logscale',
                          width=200,
                          options=logscale_vals)
overlap_slider = Slider(title="Overlap Parameter",
                        value=0.5,
                        start=0.0,
                        end=1.0,
                        step=0.1,
                        width=200)

threshold_slider = Slider(title="Filter Threshold",
                         value=0.005,
                         start=0.001,
                         end=0.1,
                         step=0.005,
                         width=200)

minSigma_slider = Slider(title="min_Sigma",
                         value=5,
                         start=0.0,
                         end=500.0,
                         step=2,
                         width=200)

maxSigma_slider = Slider(title="max_Sigma",
                         value=50,
                         start=0.0,
                         end=500.0,
                         step=2,
                         width=200,)

button_vals=['True', 'False']
button = Select(value='False',
                          title='Save Hyperparameters?',
                          width=200,
                          options=button_vals)

# set up plot (styling in theme.yaml)
path = './Flask_parameter_update/static/B4_2_test_500x.tif'
im, imIn = Load_image(path)
blobs_y, blobs_x, blobs_r = blob_detector(imIn, 0.5,0.005,5,50,True)
im_x = im.shape[0]
im_y = im.shape[1]

source = ColumnDataSource(data=dict(x=blobs_x, y= blobs_y, r=blobs_r))

# create a new plot
s2 = figure(plot_width=900, plot_height= 900, title='With Blobs', x_range= (0,im_x), y_range=(0,im_y))
# Superimpose DoH blobs on image
s2.image(image=[imIn], x=[0], y=[0], dw=[im_x], dh=[im_y], palette=list(reversed(Greys256)))
s2.circle( 'x', 'y', size= 'r', line_color='green', fill_color= None, line_width=1, fill_alpha=0.8, source=source)

#Callback Functions
logscale_select.on_change('value', update_blob_detector)
overlap_slider.on_change('value', update_blob_detector)
threshold_slider.on_change('value', update_blob_detector)
minSigma_slider.on_change('value', update_blob_detector)
maxSigma_slider.on_change('value', update_blob_detector)
button.on_change('value', save_params)

# set up layout
selects = row(logscale_select, width=200)
inputs = column(selects, widgetbox(overlap_slider, threshold_slider, minSigma_slider, maxSigma_slider, button))

# add to document
curdoc().add_root(row(inputs,s2))

#Inputs
#wbox = widgetbox(overlap_slider, threshold_slider, minSigma_slider, maxSigma_slider, width=200)
#curdoc().add_root(row(wbox,s1,s2))
curdoc().title = "Bokeh Parameter Search"


import pandas as pd
import numpy as np
import matplotlib
import random
from matplotlib import pyplot as plt
matplotlib.use("Agg")

np.random.seed(42)
class Scaler():
	def __call__(self,features, is_train=False):
		'''
		Arguments : features N X D all are numeric
		'''
		min=features.min(0)
		ptp=features.ptp(0)
		features_normed=(features-min)/ptp
		return features_normed

# Polynomial Basis function

def polyBasis(X):
	for x in range(X.shape[1]):
		X[:,x] = X[:,x]**x
	return X

# Square Basis function

def squareBasis(X):
	np.power(X,2)
	return X

def get_features(csv_path,is_train=False,scaler=None):
	feaures = ["scan","track","bright_t31","daynight","latitude","longitude","brightness","confidence","satellite"]
	data = pd.read_csv(csv_path)[feaures]
	X = data

	# Onehot encoding for Daynight
	temp = pd.get_dummies(X["daynight"])
	X = X.drop("daynight",axis=1)
	X["day"]=temp.iloc[:,0]
	X["night"]=temp.iloc[:,1]
	# Onehot encoding for satellite
	temp = pd.get_dummies(X["satellite"])
	X = X.drop("satellite",axis=1)
	X["aqua"]=temp.iloc[:,0]
	X["terra"]=temp.iloc[:,1]
	u = np.mean(X,0)
	std = np.std(X,0)
	X = (X-u)/std

	one = np.ones((X.shape[0],1))
	X = np.hstack((one,X))

	# X = polyBasis(X)			#uncomment to apply basis function 1
	# X = squareBasis(X)		#uncomment to apply basis function 2

	return X

def get_targets(csv_path):
	'''
	Description:
	read target outputs from the csv file
	return a numpy array of shape m x 1
	m is number of examples
	'''
	df = pd.read_csv(csv_path)
	return df.frp

def analytical_solution(feature_matrix, targets, C=0.0):
	A = np.linalg.inv(np.dot(feature_matrix.T,feature_matrix)+C*l2_regularizer(targets))
	B = np.dot(feature_matrix.T,targets)
	W = np.dot(A,B)
	return W

def get_predictions(feature_matrix, weights):
	Ypred=np.dot(feature_matrix,weights)
	return abs(Ypred)

def mse_loss(feature_matrix, weights, targets):
	Ypred  = get_predictions(feature_matrix,weights)
	targets = targets.values
	targets.reshape(targets.shape[0],1)
	loss = np.sum((Ypred - targets)**2)/(2*(feature_matrix.shape[0]))
	return loss

def l2_regularizer(weights):
	reg = np.sum(weights**2)**(0.5)
	return reg

def loss_fn(feature_matrix, weights, targets, C=0.0):
	mse = mse_loss(feature_matrix,weights,targets)
	l2 = l2_regularizer(weights)
	loss = mse + C*l2
	return loss

def compute_gradients(feature_matrix, weights, targets, C=0.0):
	predictions = get_predictions(feature_matrix,weights)
	predictions = predictions.reshape(predictions.shape[0],1)
	targets = targets.reshape(predictions.shape[0],1)
	temp = (np.dot(feature_matrix.T,np.subtract(predictions,targets)))
	reg = (C*l2_regularizer(weights))
	gradients = (temp+reg)/(2*feature_matrix.shape[0])
	return gradients

def sample_random_batch(feature_matrix, targets, batch_size):
	sampled_targets=[]
	indexes=random.sample(range(0, feature_matrix.shape[0]), batch_size)
	new_feature_matrix=[]
	for i in indexes:
	  new_feature_matrix.append(feature_matrix[i])
	  count = 0
	  sampled_targets.append(targets[i])
	return np.array(new_feature_matrix),np.array(sampled_targets)

def initialize_weights(n):
	w = np.zeros(n)
	return w

def update_weights(weights, gradients, lr):
	N=weights.shape[0]

	for i in range(0,N):
		weights[i] = weights[i] - lr*(1/N)*gradients[i]

	return weights

def early_stopping(patience=0):
	if patience >700:
	   return True
	return False

def plot_trainsize_losses(x_data, y_data,t):
	# %matplotlib inline
	print(x_data,y_data)
	plt.plot(x_data, y_data)
	plt.xlabel('Training Samples Count')
	plt.ylabel('Dev Loss')
	plt.title(t)
	plt.savefig('plot1.png')
	plt.show()
	return

def do_gradient_descent(train_feature_matrix,
						train_targets,
						dev_feature_matrix,
						dev_targets,
						lr=1.0,
						C=0.0,
						batch_size=32,
						max_steps=1000,
						eval_steps=5):
	check = 0
	loss =np.inf
	best_weights= None
	n = len(train_feature_matrix[0])
	weights = initialize_weights(n)
	dev_loss = mse_loss(dev_feature_matrix, weights, dev_targets)
	train_loss = mse_loss(train_feature_matrix, weights, train_targets)
	print("step {} \t dev loss: {} \t train loss: {}".format(0,dev_loss,train_loss))
	for step in range(1,max_steps+1):

		#sample a batch of features and gradients
		features,targets = sample_random_batch(train_feature_matrix,train_targets,batch_size)

		#compute gradients
		gradients = compute_gradients(features, weights, targets, C)

		#update weights
		weights = update_weights(weights, gradients, lr)

		if step%eval_steps == 0:
			dev_loss = mse_loss(dev_feature_matrix, weights, dev_targets)
			train_loss = mse_loss(train_feature_matrix, weights, train_targets)
			print("step {} \t dev loss: {} \t train loss: {}".format(step,dev_loss,train_loss))
		if early_stopping(check):
				print(f'Stopping at {step} steps')
				break
		if loss <= dev_loss:
			  check += 1
		else:
				loss = dev_loss
				best_weights = weights
				check= 0
	return best_weights

def do_evaluation(feature_matrix, targets, weights):
	predictions = get_predictions(feature_matrix, weights)
	loss =  mse_loss(feature_matrix, weights, targets)
	return loss
if __name__ == '__main__':
	scaler = False
	train_features, train_targets = get_features('./data/train.csv',True,scaler), get_targets('./data/train.csv')
	dev_features, dev_targets = get_features('./data/dev.csv',False,scaler), get_targets('./data/dev.csv')
	test_features = get_features('./data/test.csv',False,scaler)
	a_solution = analytical_solution(train_features, train_targets, C=1e-8)
	print('evaluating analytical_solution...')
	dev_loss=do_evaluation(dev_features, dev_targets, a_solution)
	train_loss=do_evaluation(train_features, train_targets, a_solution)
	print('analytical_solution \t train loss: {}, dev_loss: {} '.format(train_loss, dev_loss))
	print('training LR using gradient descent...')

	gradient_descent_soln = do_gradient_descent(train_features,
						train_targets,
						dev_features,
						dev_targets,
						lr=0.0009,
						C=1e-8,
						batch_size=50,
						max_steps=400000,
						eval_steps=20)

	print('evaluating iterative_solution...')
	dev_loss=do_evaluation(dev_features, dev_targets, gradient_descent_soln)
	train_loss=do_evaluation(train_features, train_targets, gradient_descent_soln)

	print('gradient_descent_soln \t train loss: {}, dev_loss: {} '.format(train_loss, dev_loss))


'''
   File used to extract members of UNEP FI. From the extracted list, this file will determine whether a company is a member of UNEP FI
'''

# Install Relevant Libraries
# pip install openpyxl --upgrade --pre
# pip install fuzzywuzzy

# Import Libraries and UNEP FI data
import requests
import fuzzywuzzy as fw
from fuzzywuzzy import fuzz
from bs4 import BeautifulSoup

url = 'https://www.unepfi.org/members/'
page = requests.get(url)
soup = BeautifulSoup(page.content, "html.parser")
lst = soup.find_all("td")
membership_lst = []

for x in range(len(lst)):
    if x%5 == 0:
        curr = str(lst[x]).split('/">')[1]
        curr = curr.split("</")[0]
        membership_lst.append(curr)

## name = input("Input the company name: ")

# Function to detect UNEP FI members

def is_member_unepfi(name):
    '''
   Function used to check whether a company is member of UNEP FI

   Parameters
   ----------
   arg1 : name
       Name of company

   Returns
   -------
   boolean
       True if a company is member of UNEP FI, False otherwise
   '''

    for x in membership_lst:
        if x.lower() == 'ing' or x.lower() == 'tal' or x.lower() == 'an post':
            continue
        if fuzz.partial_ratio(x.lower(), name.lower()) >= 95:
            return True
    return False

# Output
## is_member(name)


import argparse
import logging
import os
import sys
from pathlib import Path

import numpy as np
import torch

sys.path.append(".")

from config import cfg
from train_ctl_model import CTLModel

from inference_utils import (
    ImageDataset,
    ImageFolderWithPaths,
    calculate_centroids,
    create_pid_path_index,
    make_inference_data_loader,
    run_inference,
)

### Prepare logging
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
log = logging.getLogger(__name__)

### Functions used to extract pair_id
exctract_func = (
    lambda x: (x).rsplit(".", 1)[0].rsplit("_", 1)[0]
)  ## To extract pid from filename. Example: /path/to/dir/product001_04.jpg -> pid = product001
exctract_func = lambda x: Path(
    x
).parent.name  ## To extract pid from parent directory of an iamge. Example: /path/to/root/001/image_04.jpg -> pid = 001

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Create embeddings for images that will serve as the database (gallery)"
    )
    parser.add_argument(
        "--config_file", default="", help="path to config file", type=str
    )
    parser.add_argument(
        "--images-in-subfolders",
        help="if images are stored in the subfloders use this flag. If images are directly under DATASETS.ROOT_DIR path do not use it.",
        action="store_true",
    )
    parser.add_argument(
        "--print_freq",
        help="number of batches the logging message is printed",
        type=int,
        default=10,
    )
    parser.add_argument(
        "opts",
        help="Modify config options using the command-line",
        default=None,
        nargs=argparse.REMAINDER,
    )
    args = parser.parse_args()
    if args.config_file != "":
        cfg.merge_from_file(args.config_file)
    cfg.merge_from_list(args.opts)

    ### Data preparation
    if args.images_in_subfolders:
        dataset_type = ImageFolderWithPaths
    else:
        dataset_type = ImageDataset
    log.info(f"Preparing data using {dataset_type} dataset class")
    val_loader = make_inference_data_loader(cfg, cfg.DATASETS.ROOT_DIR, dataset_type)
    if len(val_loader) == 0:
        raise RuntimeError("Lenght of dataloader = 0")

    ### Build model
    model = CTLModel.load_from_checkpoint(cfg.MODEL.PRETRAIN_PATH)
    use_cuda = True if torch.cuda.is_available() and cfg.GPU_IDS else False

    ### Inference
    log.info("Running inference")
    embeddings, paths = run_inference(
        model, val_loader, cfg, print_freq=args.print_freq, use_cuda=use_cuda
    )

    ### Create centroids
    log.info("Creating centroids")
    if cfg.MODEL.USE_CENTROIDS:
        pid_path_index = create_pid_path_index(paths=paths, func=exctract_func)
        embeddings, paths = calculate_centroids(embeddings, pid_path_index)

    ### Save
    SAVE_DIR = Path(cfg.OUTPUT_DIR)
    SAVE_DIR.mkdir(exist_ok=True, parents=True)

    log.info(f"Saving embeddings and index to {str(SAVE_DIR)}")
    np.save(SAVE_DIR / "embeddings.npy", embeddings)
    np.save(SAVE_DIR / "paths.npy", paths)


import datetime
import ipaddress
import json
import os
import requests
import signal
import sys
import time
import calculate_acf as myacf
import trans
import detect_abnormal as ab
import utils
# from pprint import pprint

class Blocking():
    def __init__(self, ip):
        self.path_all_json = "./all.json"
        self.path_block_ip_time_json = "./log/block_ip_time_dict.json"
        self.path_peak_time = './log/peak_time.json'
        self.path_abnormal = './log/abnormal.json'
        self.path_drop_log = '/var/log/iptables/DROP.log'
        self.path_release = './log/release.json'
        self.path_next_block = './log/next_block.json'
        self.path_current_block_ip = './log/current_block_ip.txt'

        self.ip = ip
        self.ip_time_count_dict = trans.transform_log(open(self.path_all_json), trans.sys_trans_dict(self.path_drop_log), self.ip)

        self.time_list = self.ip_time_count_dict[self.ip]["timestamp"]

        self.now = datetime.datetime.now()

        ## current blocking dict {'ip':'last_attack_time(str)'}
        self.block_ip_time_dict ={}
        if os.path.exists(self.path_block_ip_time_json):
            self.block_ip_time_dict = utils.get_value_dict_time(self.path_block_ip_time_json)
        ## release
        self.release_dict = {}
        if os.path.exists(self.path_release):
            self.release_dict = utils.get_value_dict_time(self.path_release)
        if not self.ip in self.release_dict:
            self.release_dict[self.ip] = self.now + datetime.timedelta(hours = 3)
        ## for periodic block dict {'ip':'datetime(str)'}
        self.next_block_dict ={}
        if os.path.exists(self.path_next_block):
            self.next_block_dict = utils.get_value_dict_time(self.path_next_block)
        if not self.ip in self.next_block_dict:
            self.next_block_dict[self.ip] = self.now + datetime.timedelta(hours = -1)
        ##  {'ip':'peak_time (int)'}
        self.peak_time_dict ={}
        self.peak_time = 60*60*3
        if os.path.exists(self.path_peak_time):
            self.peak_time_dict = utils.get_value_second(self.path_peak_time)
        if self.ip in self.peak_time_dict:
            self.peak_time = self.peak_time_dict[self.ip]
        else:
            self.peak_time_dict[self.ip] = self.peak_time

        ## abnormal detect dict {'ip':'count'}
        self.abnormal_dict = {}
        if os.path.exists(self.path_abnormal):
           self.abnormal_dict = utils.get_value_second(self.path_abnormal)
        else:
            self.abnormal_dict[self.ip] = 0
        if not self.ip in self.abnormal_dict:
            self.abnormal_dict[self.ip] = 0

        ## for periodic release dict {'ip':'datetime(str)'}

        self.current_block_ip_list =[]
        if os.path.exists(self.path_current_block_ip):
            with open(self.path_current_block_ip) as f:
                for line in f:
                    self.current_block_ip_list.append(line.replace('\n', ''))
                    self.current_block_ip_list = list(set(self.current_block_ip_list))

    def update_file(self):
        utils.update_time_file(self.path_block_ip_time_json, self.block_ip_time_dict)
        utils.update_time_file(self.path_release, self.release_dict)
        utils.update_time_file(self.path_next_block, self.next_block_dict)
        utils.update_second_file(self.path_abnormal, self.abnormal_dict)
        utils.update_second_file(self.path_peak_time, self.peak_time_dict)

        with open(self.path_current_block_ip, "w") as f:
            for line in self.current_block_ip_list:
                f.write(line)
                f.write('\n')

    def bool_detect_abnormal(self):
        if ab.bool_abnormal(self.time_list, self.peak_time):
            self.abnormal_dict[self.ip] +=1
        if self.abnormal_dict[self.ip] > 2:
            return True
        return False

    # def log(self):
    #     print('peak')
    #     pprint(self.peak_time_dict)
    #     print('block_last time')
    #     pprint(self.block_ip_time_dict)
    #     print('next_block')
    #     pprint(self.next_block_dict)
    #     print('abnormal')
    #     pprint(self.abnormal_dict)
    #     print('current_block')
    #     pprint(self.current_block_ip_list)
    #     print('release')
    #     pprint(self.release_dict)

    def release(self):
        for ip, last in self.block_ip_time_dict.items():
            last_atack = last
            diff = int((self.now - last_atack).total_seconds())
            tmp_peak_time = self.peak_time_dict[ip]

            if diff > tmp_peak_time*5:
                self.block_ip_time_dict.pop(ip)
                self.release_dict.pop(ip)
                self.next_block_dict.pop(ip)
                self.abnormal_dict.pop(ip)
                utils.unset_block(ip)
                self.current_block_ip_list.remove(ip)
                self.current_block_ip_list = list(set(self.current_block_ip_list))

        #[TODO] bad release time
        for ip, release_time in self.release_dict.items():
            if release_time < self.now:
                self.block_ip_time_dict[ip] = self.now
                self.release_dict[ip] = self.now + datetime.timedelta(seconds = self.peak_time_dict[ip])
                utils.unset_block(ip)
                self.current_block_ip_list.remove(ip)
                self.current_block_ip_list = list(set(self.current_block_ip_list))

    def blocking(self):
        for ip, time in self.next_block_dict.items():
            if not ip in self.current_block_ip_list:
                if time < self.now:
                    self.current_block_ip_list.append(ip)
                    self.current_block_ip_list = list(set(self.current_block_ip_list))
                    utils.set_block(ip)

    def calculation(self):
        if len(self.time_list) == 1:
            ## first attack
            print(self.now)
            print('first attack')
            self.peak_time = 60*60*3
            self.peak_time_dict[self.ip] = self.peak_time
            self.release_dict[self.ip] = self.now + datetime.timedelta(hours = 3)
            self.next_block_dict[self.ip] = self.now + datetime.timedelta(hours = -1)
            self.block_ip_time_dict[self.ip] = self.now
        else:
            if self.ip in self.current_block_ip_list:
                tmp = trans.make_acf_type(self.time_list)
                self.peak_time = myacf.caluculate_peaktime(tmp)
                self.peak_time_dict[self.ip] = self.peak_time
                self.block_ip_time_dict[self.ip] = self.now
                if self.peak_time < 60*10: # for short attack
                    # self.next_block_dict[self.ip] = self.now + datetime.timedelta(days = 1)
                    self.release_dict[self.ip] = self.now + datetime.timedelta(days = 1)
                    self.peak_time = 60*60*3
                else:
                    self.next_block_dict[self.ip] = self.now + datetime.timedelta(seconds = self.peak_time*9/10)
                    self.release_dict[self.ip] = self.now + datetime.timedelta(seconds = self.peak_time/10)

            else:
                ## now blocking, but peak time is innappropriate
                if self.bool_detect_abnormal():
                    print(self.now)
                    print('abnormal is detected')
                    tmp = trans.make_acf_type(self.time_list[-3:])
                    self.peak_time = myacf.caluculate_peaktime(tmp)
                    self.peak_time_dict[self.ip] = self.peak_time
                    self.block_ip_time_dict[self.ip] = self.now
                    self.abnormal_dict[self.ip] = 0

                    if self.peak_time < 60*10: # for short attack
                    # self.next_block_dict[self.ip] = self.now + datetime.timedelta(days = 1)
                        self.release_dict[self.ip] = self.now + datetime.timedelta(days = 1)
                        self.peak_time = 60*60*3
                    else:
                        self.release_dict[self.ip] = self.now + datetime.timedelta(seconds = self.peak_time/10)
                        self.next_block_dict[self.ip] = self.now +datetime.timedelta(hours = -1)

                else:
                    self.block_ip_time_dict[self.ip] = self.now ## failed block -> cowrie.json


from collections import deque
from typing import List

class Solution:
    def removeStones(self, stones: List[List[int]]) -> int:
        visited = set()

        points_by_row = {}
        points_by_col = {}
        for stone in stones:
            points_by_row.setdefault(stone[0], set()).add(tuple(stone))
            points_by_col.setdefault(stone[1], set()).add(tuple(stone))

        move_count = 0
        for row, col in stones:
            stone = (row, col)
            if stone in visited:
                continue
            visited.add(stone)

            queue = deque([stone])
            size = 1
            while queue:
                current_row, current_col = queue.popleft()
                other_stones = (
                    points_by_row[current_row] | points_by_col[current_col]
                ) - visited
                for other_stone in other_stones:
                    visited.add(other_stone)
                    queue.append(other_stone)
                    size += 1
            move_count += size - 1
        return move_count

print(Solution().removeStones([[0, 0], [0, 1], [1, 0], [1, 2], [2, 1], [2, 2]]))
print(Solution().removeStones([[0, 0], [0, 2], [1, 1], [2, 0], [2, 2]]))
print(Solution().removeStones([[0, 0]]))


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)

n,m = map(int, input().split())
graph = [list(map(int, input().split())) for _ in range(n)]
# for i in range(n):
#     graph.append(list(map(int, input().split())))

visited = [[-1] * m for _ in range(n)]
dx = [-1,0,1,0]
dy = [0,1,0,-1]

def dfs(x,y):
    if x == n-1 and y == m-1:
        return 1
    if visited[x][y] == -1:
        visited[x][y] = 0
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < m:
                if graph[x][y] > graph[nx][ny]:
                    visited[x][y] += dfs(nx,ny)
    return visited[x][y]

print(dfs(0,0))

# pypy3로 하면 메모리 초과, python3로 하면 바로 통과...?


"""
Find stratified and balanced data splitting
of development and hold-out test data

balanced for centers and distribution of
updrs tap scores
"""

# import public functions
import numpy as np

def find_dev_holdout_split(
    feats,
    holdout_split = .2,
    accept_perc_range = 3,
    choose_random_split=None,
    centers = ['BER', 'DUS'],
    splits = ['dev', 'hout'],
    to_print=False,
    subs_excl=[],
    traces_excl=[],
    EXCL_4s = False,
):
    """
    Main script to run to get balanced data splitting
    of development and hold out data sets

    Input:
        - choose_random_split: predefine which datasplit
            is used to reproduce data split and results
    """
    excl_states = [111,]

    print('SPLITTING DATA IN DEV AND HOLD-OUT')
    # get unique subs per center, get score-distribution in full data set
    subs_dict, og_score_distr, og_score_perc = get_population_distribution(
        feats=feats,
        holdout_split=holdout_split,
        centers=centers,
        splits=splits,
        to_print=to_print,
        subs_excl=subs_excl,
        traces_excl=traces_excl,
        EXCL_4s=EXCL_4s,
    )
    # define n samples per center for development set
    n_dev = [len(subs_dict[c]) - int(len(subs_dict[c]) * holdout_split) for c in subs_dict]
    n_dev = min(n_dev) - 1  # -1 to ensure large enough hold out sample

    print(f'Original score distribution: {og_score_distr}')
    print(f'Original score %: {og_score_perc}')

    # loop over random seeds to test different splitting samples
    for rand_state in np.arange(300):
        # if exact random_split is defined, skip all others
        if choose_random_split:
            if rand_state != choose_random_split: continue
        if rand_state in excl_states: continue

        # get random split of subs per center and their scores
        if EXCL_4s:
            subset_subs, subset_updrs, excl_fours = get_random_split_and_scores(
                feats=feats, subs_dict=subs_dict,
                n_dev=n_dev, rand_state=rand_state,
                EXCL_4s=EXCL_4s,
            )
        else:
            subset_subs, subset_updrs = get_random_split_and_scores(
                feats=feats, subs_dict=subs_dict,
                n_dev=n_dev, rand_state=rand_state,
                EXCL_4s=EXCL_4s,
            )

        # determine score-distribution of applied splitting
        split_scores = get_split_score_distr(subset_updrs)

        # test whether distribution is within accepted range
        accept_split = test_split_distr(
            split_scores, og_score_perc, accept_perc_range
        )

        # if all distribution counts of split are within accepted ranges
        if accept_split:
            print(f'Accepted Split: random state {rand_state}')
            # show resulting scores distribution
            print(f'\nResulting distributions in splitted data sets:')
            print()
            data_splits = {}
            for split in split_scores.keys():
                data_splits[split] = []  # empty list to store the subs per split
                for cen in subset_subs.keys():
                    data_splits[split].extend(subset_subs[cen][split])  # add subs to final dict
                # print results as feedback
                n_split = sum(split_scores[split].values())
                print(f'\t{split} data set (n = {n_split}):')
                scores = split_scores[split].keys()

                for s in scores:
                    c = split_scores[split][s]
                    print(f'score {s}: # {c} ({round(c / n_split * 100)} %)')

            if EXCL_4s:
                print(f'\tTraces excl as FOURS: {excl_fours}')
                return data_splits, excl_fours
            else: return data_splits

        else:
            continue

    print('no accepted split found')

    return None

def get_population_distribution(
    feats,
    holdout_split=.2,
    centers=['BER', 'DUS'],
    splits=['dev', 'hout'],
    to_print=True,
    subs_excl=[],
    traces_excl=[],
    EXCL_4s=False,
):
    """

    Input:
        - feats: feature classes per trace
    """

    subs = []
    all_updrs = []
    total_score_distr, total_score_perc = {}, {}

    for trace in feats.incl_traces:

        if getattr(feats, trace).sub in subs_excl: continue
        if trace in traces_excl: continue
        if EXCL_4s:
            if getattr(feats, trace).tap_score == 4: continue

        subs.append(getattr(feats, trace).sub)
        all_updrs.append(getattr(feats, trace).tap_score)

    n_total_traces = len(subs)
    if to_print: print(f'# of total traces included: {n_total_traces}')

    scores, counts = np.unique(all_updrs, return_counts=True)
    for score, count in zip(scores, counts):
        if to_print: print(f'\tscore {score}: # {count}, '
                        f'{round(count / len(all_updrs) * 100)} %')
        total_score_distr[score] = count
        total_score_perc[score] = round(count / len(all_updrs) * 100, 1)

    subs = list(set(subs))
    if to_print: print(f'# of unique subjects included {len(subs)}')

    subs_dict = {}
    for c in centers:
        subs_dict[c] = [s for s in subs if s[:3] == c]
        if to_print: print(f'\t# {c} subs: {len(subs_dict[c])}')

    dev_split = 1 - holdout_split

    if to_print: print(f'Aimed numbers: # dev traces: {n_total_traces * dev_split}'
          f', # of hold-out traces: {n_total_traces * holdout_split}')

    return subs_dict, total_score_distr, total_score_perc

def get_random_split_and_scores(
    feats, subs_dict, n_dev, rand_state,
    EXCL_4s=False,
):
    np.random.seed(rand_state)

    subset_subs, subset_updrs = {}, {}
    excluded_fours = []

    for cen in subs_dict.keys():
        subset_subs[cen], subset_updrs[cen] = {}, {}

        # subset_subs[cen]['dev'] = random.sample(subs_dict[cen], k=n_dev)
        subset_subs[cen]['dev'] = np.random.choice(
            sorted(subs_dict[cen]), n_dev, replace=False
        )
        subset_subs[cen]['hout'] = [
            s for s in subs_dict[cen]
            if s not in subset_subs[cen]['dev']
        ]

        for split in ['dev', 'hout']:
            subset_updrs[cen][split] = []

            for trace in feats.incl_traces:
                if getattr(feats, trace).sub in subset_subs[cen][split]:
                    if EXCL_4s:
                        if getattr(feats, trace).tap_score == 4:
                            excluded_fours.append(trace)
                            continue

                    subset_updrs[cen][split].append(
                        getattr(feats, trace).tap_score
                    )
    if EXCL_4s: return subset_subs, subset_updrs, excluded_fours
    else: return subset_subs, subset_updrs

def get_split_score_distr(subset_updrs):

    split_scores = {}  # create empty dict to store score counts (total together, not per center)

    for split in ['dev', 'hout']:
        split_scores[split] = {}
        for s in range(5): split_scores[split][s] = 0

    # count scores and fill distribution
    for cen in subset_updrs.keys():
        for split in subset_updrs[cen].keys():
            scores, counts = np.unique(subset_updrs[cen][split], return_counts=True)

            # add scores from both centers to same counting dict (dev and holdout seperately)
            for score, count in zip(scores, counts):
                split_scores[split][score] = split_scores[split][score] + count

    return split_scores

def test_split_distr(
    split_scores, og_score_perc, accept_perc_range
):
    accept_split = True  # at beginning of every iteration
    for split in split_scores.keys():

        n_split = sum(split_scores[split].values())

        if split == 'hout':
            if n_split < 73: accept_split = False

        for score in range(4):

            if abs(
                (split_scores[split][score] / n_split * 100) -
                og_score_perc[score]
            ) > accept_perc_range:

                accept_split = False

    return accept_split


from ntpath import join
from os import listdir
from os.path import join, isfile
from olapy.core.mdx.executor import MdxEngine
import pandas as pd
import numpy as np

def ShowRowsTable(path, sep = ","):
    import pandas as pd
    return list(pd.read_csv(path, sep=sep).columns)

def ShowRowsTables(array_table, path_folder_cube, sep = ","):
    result = {}
    for table in array_table:
        result[table.replace(".csv","")] = ShowRowsTable(join(path_folder_cube, table), sep)
    return result

def main():
    EXECUTER = MdxEngine() # instantiate the MdxEngine
    PATH_TO_OLAP_DATA = join(EXECUTER.olapy_data_location,EXECUTER.cubes_folder)
    NAME_CUBE = "sales"
    path_folder_cube = join(PATH_TO_OLAP_DATA, NAME_CUBE)
    array_table = listdir(path_folder_cube)
    EXECUTER.load_cube(NAME_CUBE) # load sales cube

    query1 = """
        SELECT
        {[City]}
        ON COLUMNS,
        {[Year]}
        ON ROWS
        FROM [Black_Friday]
        Where
        [Average Spent By Person]
    """

    query2 = """
        SELECT
        Hierarchize({[Measures].[Amount]}) ON COLUMNS
        FROM [sales]
    """

    query3 = """
        SELECT
        {[Amount]}
        ON COLUMNS
        FROM [sales]
        where
        [Time].[Day].[January 1,2010]
    """

    query4 = """
    SELECT
    {
    [Measures].[Amount]
    } ON COLUMNS
    {[Measures].[Time].[Time].[Month]} ON ROWS
    FROM [sales]
    WHERE [Time].[Time].[Year].[2010]
    """

    query5 = """
      SELECT
		{
		[Geography].[Continent].[America],
		[Geography].[Continent].[Europe]} ON COLUMNS

        FROM [Sales]

        WHERE [Time].[Year].[2011]
    """

    query6 = """
      SELECT
		{
		[Geography].[Continent].[America],
		[Geography].[Continent].[Europe]} ON COLUMNS
        {
		[Measures].[Count],
		[Measures].[Amount]} ON ROWS
        FROM [Sales]

        WHERE [Time].[Year].[2011]
        or
        WHERE [Time].[Year].[2010]
    """

    print("PATH_TO_OLAP_DATA: ", PATH_TO_OLAP_DATA, "\n"*2)

    print(ShowRowsTables(array_table, path_folder_cube, sep = ";"), "\n"*2)

    df = EXECUTER.execute_mdx(query6)["result"]
    print("result query: \n", df)

main()


from typing import List
from itertools import combinations, product

class Solution:
    def beautifulSubsets(self, nums: List[int], k: int) -> int:
        answer = len(nums)
        for i in range(2, len(nums) + 1):
            for comb in combinations(nums, i):
                is_beautiful = True
                for num1, num2 in product(comb, comb):
                    if abs(num1 - num2) == k:
                        is_beautiful = False
                        break
                answer += is_beautiful

        return answer

# TLE
# [15,6,3,25,14,29,21,16,28,23,11,9,4,30,24,12,26,1,27,18]
# 7


import math
import pandas as pd
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
from data_manager import DataManager

JRCODE = 11

class JRMap:
    def __init__(self):
        self.data_manager = DataManager(JRCODE)
        self.graph = nx.Graph()
        self.construct_graph()

    def construct_graph(self):
        stations_df = self.data_manager.get_stations()
        station_cd_g_cd_dict = self.data_manager.generate_station_cd_g_cd_dict()
        joins = self.data_manager.get_joins()
        rows = stations_df.itertuples()

        # Adding nodes
        for row in rows:
            self.graph.add_node(row.station_g_cd)

        # Adding edges
        for line in joins.itertuples():
            src_cd = line.station_cd1
            dst_cd = line.station_cd2
            src_g_cd = station_cd_g_cd_dict[src_cd]
            dst_g_cd = station_cd_g_cd_dict[dst_cd]
            # print(line.line_cd)
            self.graph.add_edge(src_g_cd, dst_g_cd, line_cd=line.line_cd)
        # print(self.graph.edges.data())

    def visualize_nodes(self):
        station_g_cd_dict = self.data_manager.generate_station_g_cd_to_data_dict()
        lon_pts = []
        lat_pts = []
        for node in self.graph.nodes:

            data = station_g_cd_dict[node]
            lon = float(data[7])
            lat = float(data[8])
            lon_pts.append(lon)
            lat_pts.append(lat)

        plt.scatter(lon_pts, lat_pts, s=0.4)
        plt.show()

    def visualize_map(self):
        print("visualize_map")
        station_g_cd_dict = self.data_manager.generate_station_g_cd_to_data_dict()
        line_station_dict = {}

        for edge in self.graph.edges.data():
            src_idx = edge[0]
            dst_idx = edge[1]
            src_data = station_g_cd_dict[src_idx]
            dst_data = station_g_cd_dict[dst_idx]

            line_cd = edge[2]["line_cd"]

            if not line_cd in line_station_dict:
                line_station_dict[line_cd] = {"src": [], "dst": []}

            line_station_dict[line_cd]["src"].append(src_idx)
            line_station_dict[line_cd]["dst"].append(dst_idx)

        for line_cd in line_station_dict:
            # stations = np.unique(line_station_dict[line_cd])
            srcs = line_station_dict[line_cd]["src"]
            dsts = line_station_dict[line_cd]["dst"]
            color = np.random.rand(3, )

            # print(line_cd, stations)
            line_lon = []
            line_lat = []

            for src, dst in zip(srcs, dsts):
                src_data = station_g_cd_dict[src]
                dst_data = station_g_cd_dict[dst]
                # line_lon.append(float(src_data.lon))
                # line_lat.append(float(src_data.lat))
                src_lon = src_data[7]
                src_lat = src_data[8]
                dst_lon = dst_data[7]
                dst_lat = dst_data[8]
                plt.plot([src_lon, dst_lon], [src_lat, dst_lat], c=color)

        plt.show()

    def get_nearest_station(self, lon, lat, nums=1):
        stations_df = self.data_manager.get_stations()
        station_dist_dict = {}
        for station_data in stations_df.itertuples():
            station_lon = station_data.lon
            station_lat = station_data.lat

            squared_diff_lon = math.pow(lon - station_lon, 2)
            squared_diff_lat = math.pow(lat - station_lat, 2)

            station_dist_dict[station_data.station_g_cd] = squared_diff_lon + squared_diff_lat

        dist_sorted = sorted(station_dist_dict.items(), key=lambda x:x[1])

        station_names = []

        for i in range(nums):
            station_g_cd = dist_sorted[i][0]
            station_names.append(self.data_manager.get_station_name_from_g_cd(station_g_cd))

        return station_names

def main():
    jrm = JRMap()
    # jrm.visualize_map()

    lat = 35.534129
    lon = 137.791698

    print(jrm.get_nearest_station(lon, lat, 5))

if __name__ == "__main__":
    main()


c = int(input("Cost of the product :"))
n = int(input("Quantity of product :"))

A = c*n

print("Amount :", A)

D = 10*A/100
N = A - D

print("Net amount :" , N)


def fibonacci(n):
    a = [1,1]
    for i in range(2,n):
        a.append(a[i-1]+a[i-2])
    return a

def sumarr(a):
    sum = 0
    for i in a:
        sum = sum + i
    return sum

array = fibonacci(20)
print(array)
print(sumarr(array))


import urllib
import webapp2
import jinja2
import os
import datetime

from google.appengine.ext import ndb
from google.appengine.api import users
from google.appengine.api import search

jinja_environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__) + "/templates"))

# This part for the front page
class MainPage(webapp2.RequestHandler):
    # Handler for the front page.

    def get(self):
        template = jinja_environment.get_template('front.html')
        self.response.out.write(template.render())

class MainPageUser(webapp2.RequestHandler):
    # Front page for those logged in

    def get(self):
        user = users.get_current_user()
        if user:  # signed in already
            template_values = {
                'user_mail': users.get_current_user().email(),
                'logout': users.create_logout_url(self.request.host_url),
            }
            template = jinja_environment.get_template('frontuser.html')
            self.response.out.write(template.render(template_values))
        else:
            self.redirect(self.request.host_url)

# Datastore definitions
class Items(ndb.Model):
    # Models an item with event_name, event_link, description, and date. Key is item_id.
    item_id = ndb.IntegerProperty()
    event_name = ndb.StringProperty()
    event_link = ndb.StringProperty()
    event_type = ndb.StringProperty()
    description = ndb.TextProperty()
    rsvp = ndb.IntegerProperty()
    date = ndb.DateTimeProperty(auto_now_add=True)

class Persons(ndb.Model):
    # Models a person. Key is the email.
    next_item = ndb.IntegerProperty()  # item_id for the next item

# CurrentPerson is used for many-to-many relationship between Persons and Items
class CurrentPerson(ndb.Model):
    name = ndb.StringProperty()
    event_name = ndb.StringProperty()
    event_link = ndb.StringProperty()
    event_type = ndb.StringProperty()
    description = ndb.TextProperty()
    rsvp = ndb.StringProperty()
    date = ndb.StringProperty()

class WishList(webapp2.RequestHandler):
    """ Form for getting and displaying wishlist items. """

    def show(self):
        # Displays the page. Used by both get and post
        user = users.get_current_user()
        if user:  # signed in already

            # Retrieve person
            parent_key = ndb.Key('Persons', users.get_current_user().email())

            # Retrieve items
            query = ndb.gql("SELECT * "
                            "FROM Items "
                            "WHERE ANCESTOR IS :1 "
                            "ORDER BY date DESC",
                            parent_key)

            person = CurrentPerson.query(CurrentPerson.name == users.get_current_user().email())

            template_values = {
                'user_mail': users.get_current_user().email(),
                'logout': users.create_logout_url(self.request.host_url),
                'items': query,
                'person': person,
            }

            template = jinja_environment.get_template('wishlist.html')
            self.response.out.write(template.render(template_values))
        else:
            self.redirect(self.request.host_url)

    def get(self):
        self.show()

    def post(self):
        # Retrieve person
        parent = ndb.Key('Persons', users.get_current_user().email())
        person = parent.get()
        if person == None:
            person = Persons(id=users.get_current_user().email())
            person.next_item = 1

        item = Items(parent=parent, id=str(person.next_item))
        item.item_id = person.next_item

        item.event_name = self.request.get('event_name')
        item.event_link = self.request.get('event_link')
        item.description = self.request.get('desc')
        item.event_type = self.request.get('eventtype')
        item.rsvp = 0

        person.next_item += 1
        person.put()
        item.put()
        self.show()

class UnGo(webapp2.RequestHandler):
    def post(self):
        person = ndb.Key(urlsafe = self.request.get('itemkey'))
        person.delete()
        eventKey = Items.query(Items.event_name == self.request.get('itemname'))
        event = eventKey.get()
        event.rsvp -= 1
        event.put()
        self.redirect('/wishlist')

# For deleting an item from wish list
class DeleteItem(webapp2.RequestHandler):
    # Delete item specified by user
    def post(self):
        item = ndb.Key('Persons', users.get_current_user().email(), 'Items', self.request.get('itemid'))
        item.delete()
        self.redirect('/wishlist')

class RSVPItem(webapp2.RequestHandler):
    # increment RSVP count when GO button is clicked
    def post(self):
        itemname = self.request.get('itemname')

        person = CurrentPerson(name = users.get_current_user().email(),
                            event_name = self.request.get('itemname'),
                            event_link = self.request.get('itemlink'),
                            event_type = self.request.get('itemtype'),
                            description = self.request.get('itemdesc'),
                            rsvp = self.request.get('itemrsvp'),
                            date = self.request.get('itemdate'))
        person.put()

        query = ndb.gql("SELECT *"
                        "FROM Items")
        for item in query:
            if item.event_name == itemname:
                item.rsvp += 1
                item.put()
        template_values = {'event_name': itemname,}
        template = jinja_environment.get_template('rsvp.html')
        self.response.out.write(template.render(template_values))

# Handler for the Search page
class Search(webapp2.RequestHandler):
    # Display search page
    def get(self):
        user = users.get_current_user()
        if user:  # signed in already
            # Retrieve items
            query = ndb.gql("SELECT * "
                            "FROM Items ")

            template_values = {
                'user_mail': users.get_current_user().email(),
                'logout': users.create_logout_url(self.request.host_url),
                'items': query,
            }
            template = jinja_environment.get_template('search.html')
            self.response.out.write(template.render(template_values))
        else:
            self.redirect(self.request.host_url)

# Handler for returning search result
class Display(webapp2.RequestHandler):
    # Displays search result
    def post(self):
        target = self.request.get('search').rstrip()

        query = ndb.gql("SELECT * "
                        "FROM Items ")

        template_values = {
            'user_mail': users.get_current_user().email(),
            'logout': users.create_logout_url(self.request.host_url),
            'items': query,
            'search': target,
        }
        template = jinja_environment.get_template('display.html')
        self.response.out.write(template.render(template_values))

class Displaytag(webapp2.RequestHandler):
    # Displays search result

    def post(self):
        tags = self.request.get('eventtype')

        query = ndb.gql("SELECT * "
                        "FROM Items ")

        template_values = {
            'user_mail': users.get_current_user().email(),
            'logout': users.create_logout_url(self.request.host_url),
            'items': query,
            'type': tags,
        }
        template = jinja_environment.get_template('displaytag.html')
        self.response.out.write(template.render(template_values))

# Simply redirect to front page
class HandleOpenId(webapp2.RequestHandler):
    def get(self):
        self.redirect(self.request.host_url)

class GetOpenId(webapp2.RequestHandler):
    def get(self):
        self.redirect(users.create_login_url('/giftbook', None, federated_identity='https://openid.nus.edu.sg/'))

app = webapp2.WSGIApplication([('/', MainPage),
                               ('/giftbook', MainPageUser),
                               ('/wishlist', WishList),
                               ('/deleteitem', DeleteItem),
                               ('/search', Search),
                               ('/rsvp', RSVPItem),
                               ('/display', Display),
                               ('/displaytag', Displaytag),
                               ('/ungo', UnGo),
                               ('/getOpenId', GetOpenId),
                               ('/_ah/login_required', HandleOpenId)],
                              debug=True)


#https://www.acmicpc.net/problem/10989
#계수정렬. 임현우란테 스포당함! 시간복잡도는 O(N+K), 데이터 범위가 한정되어있으면 현존하는ㄴㅇ라고리즘 중에 제일 빠르ㄷ 근데 데이터가 0, 99999 2개만 있는 경우에도 100000 까지 배열선언해야된,까 공간복잡도에서 비효율적일수도 그랴서 동일한 값을 가지는 ㄷ이터가 여러개일 때 좋응

import sys

n = int(input())
count = [0 for _ in range(10001)]

for _ in range(n):
  i = int(sys.stdin.readline())
  count[i] += 1

for i in range(10001):
  if count[i] != 0:
    for _ in range(count[i]):
      print(i)


from itertools import permutations

def solution(expression):
    answer = 0
    opers = ["+", "-", "*"]
    priorities = [*map(list, permutations(opers))]

    for priority in priorities:
        first = expression.split(priority[0])
        tmp = []

        for item in first:
            second = item.split(priority[1])
            second = [str(eval(x)) for x in second]
            tmp.append(str(eval(priority[1].join(second))))

        res = abs(eval(priority[0].join(tmp)))
        answer = max(answer, res)

    return answer

print(solution("100-200*300-500+20"))
print(solution("50*6-3*2"))


import unittest
from pyhbasecli import HBaseCli

URL = ""
headers = {"ACCESSKEYID": "root", "ACCESSSIGNATURE": "root"}

class NamespaceOpsTest(unittest.TestCase):

    def setUp(self) -> None:
        self.cli = HBaseCli(
            url=URL,
            headers=headers)
        self.cli.open()
        print("section start")

    def tearDown(self) -> None:
        self.cli.close()
        print("section end")

    def test_namespace_ops(self) -> None:
        print("测试命名空间相关")
        namespace = "recommend_hsz_test_ns"
        nss = self.cli.show_namespaces()
        print(nss)
        if namespace in [i["name"] for i in nss]:
            print(f"已创建命名空间: {namespace}")
            print(f"删除命名空间{namespace}")
            self.cli.delete_namespace(namespace)

        print(f"创建命名空间{namespace}未创建")
        self.cli.create_namespace(namespace)
        print(f"命名空间{namespace}创建完成")
        try:
            nsinfo = self.cli.desc_namespace(namespace)
            print(f"命名空间{namespace}描述如下:")
            print(nsinfo)
            assert nsinfo["name"] == namespace

        finally:
            print(f"删除命名空间{namespace}")
            self.cli.delete_namespace(namespace)

    # def test_namespace_show(self) -> None:
    #     print("测试命名空间相关")
    #     namespace = "recommend_hsz_test"
    #     nss = self.cli.show_namespaces()
    #     print(nss)
    #     if namespace in [i["name"] for i in nss]:
    #         print(f"已创建命名空间: {namespace}")
    #     else:
    #         print(f"命名空间{namespace}未创建,创建...")
    #         cli.create_namespace(namespace)
    #         print(f"命名空间{namespace}创建完成")
    #     try:
    #         nsinfo = cli.desc_namespace(namespace)
    #         print(f"命名空间{namespace}描述如下:")
    #         print(nsinfo)

    #         print("测试表相关")
    #     finally:
    #         print(f"删除命名空间{namespace}")
    #         cli.delete_namespace(namespace)