import tempfile

import h5py
import imageio

def create_video_file(suffix=".mp4", byte_contents=None):
    # Create Temporary File #
    temp_file = tempfile.NamedTemporaryFile(suffix=suffix)
    filename = temp_file.name

    # If Byte Contents Provided, Write To File #
    if byte_contents is not None:
        with open(filename, "wb") as binary_file:
            binary_file.write(byte_contents)

    return filename

def get_hdf5_length(hdf5_file, keys_to_ignore=[]):
    length = None

    for key in hdf5_file.keys():
        if key in keys_to_ignore:
            continue

        curr_data = hdf5_file[key]
        if isinstance(curr_data, h5py.Group):
            curr_length = get_hdf5_length(curr_data, keys_to_ignore=keys_to_ignore)
        elif isinstance(curr_data, h5py.Dataset):
            curr_length = len(curr_data)
        else:
            raise ValueError

        if length is None:
            length = curr_length
        assert curr_length == length

    return length

def load_hdf5_to_dict(hdf5_file, index, keys_to_ignore=[]):
    data_dict = {}

    for key in hdf5_file.keys():
        if key in keys_to_ignore:
            continue

        curr_data = hdf5_file[key]
        if isinstance(curr_data, h5py.Group):
            data_dict[key] = load_hdf5_to_dict(curr_data, index, keys_to_ignore=keys_to_ignore)
        elif isinstance(curr_data, h5py.Dataset):
            data_dict[key] = curr_data[index]
        else:
            raise ValueError

    return data_dict

class TrajectoryReader:
    def __init__(self, filepath, read_images=True):
        self._hdf5_file = h5py.File(filepath, "r")
        is_video_folder = "observations/videos" in self._hdf5_file
        self._read_images = read_images and is_video_folder
        self._length = get_hdf5_length(self._hdf5_file)
        self._video_readers = {}
        self._index = 0

    def length(self):
        return self._length

    def read_timestep(self, index=None, keys_to_ignore=[]):
        # Make Sure We Read Within Range #
        if index is None:
            index = self._index
        else:
            assert not self._read_images
            self._index = index
        assert index < self._length

        # Load Low Dimensional Data #
        keys_to_ignore = [*keys_to_ignore.copy(), "videos"]
        timestep = load_hdf5_to_dict(self._hdf5_file, self._index, keys_to_ignore=keys_to_ignore)

        # Load High Dimensional Data #
        if self._read_images:
            camera_obs = self._uncompress_images()
            timestep["observations"]["image"] = camera_obs

        # Increment Read Index #
        self._index += 1

        # Return Timestep #
        return timestep

    def _uncompress_images(self):
        # WARNING: THIS FUNCTION HAS NOT BEEN TESTED. UNDEFINED BEHAVIOR FOR FAILED READING. #
        video_folder = self._hdf5_file["observations/videos"]
        camera_obs = {}

        for video_id in video_folder:
            # Create Video Reader If One Hasn't Been Made #
            if video_id not in self._video_readers:
                serialized_video = video_folder[video_id]
                filename = create_video_file(byte_contents=serialized_video)
                self._video_readers[video_id] = imageio.get_reader(filename)

            # Read Next Frame #
            camera_obs[video_id] = yield self._video_readers[video_id]
            # Future Note: Could Make Thread For Each Image Reader

        # Return Camera Observation #
        return camera_obs

    def close(self):
        self._hdf5_file.close()


#!/usr/bin/env python3
"""This script is used from inside the submit/run slurm scripts to store metadata in a
json file.
Example:
python3 log_metadata.py ./log_dir LF cores=12 run_time=12.5
"""
import os
import sys
import json
import argparse
from typing import Dict, List
from datetime import datetime
from logging import Logger

import pandas as pd
from filelock import SoftFileLock, Timeout

from qcore import utils
import qcore.constants as const
from qcore.srf import get_nsub_stoch
from qcore.qclogging import get_basic_logger

METADATA_VALUES = "metadata_values"
LOCK_FILENAME = "{}.lock".format(const.METADATA_LOG_FILENAME)

METACONST_TO_ADD = [const.MetadataField.run_time.value]

class KeyValuePairsAction(argparse.Action):
    """Allows passing key=value pairs to the parser."""

    def __call__(self, parser, namespace, values, option_string=None):
        values_dict = {}
        for value in values:
            if "=" not in value:
                print(
                    "The metadata key=value, {}, was in the incorrect format. "
                    "Not written!".format(value),
                    file=sys.stderr,
                )
                continue
            k, v = value.split("=")
            if k in values_dict.keys():
                print(
                    "The metadata key {} already exists. There should never be any"
                    "duplicate metadata key=value pairs. "
                    "Pair {}, {} skipped!".format(k, k, v)
                )
                continue
            values_dict[k] = v
        setattr(namespace, METADATA_VALUES, values_dict)

def convert_to_numeric(str_value):
    """Attempts to convert the string value to an integer or float"""
    try:
        return int(str_value)
    except ValueError:
        try:
            return float(str_value)
        except ValueError:
            pass

    return str_value

def store_metadata(
    log_file: str,
    proc_type: str,
    metadata_dict: Dict[str, str],
    sim_name: str = None,
    metaconst_to_add: List[str] = METACONST_TO_ADD,
    logger: Logger = get_basic_logger(),
):
    """Store metadata values in the specified json log file for a specific process type.

    Metadata values are stored as key, value pairs if a key already exists,
    it is not changed and instead new values are added with a postfix such as _1, _2, etc
    The exception are keys that are in the metaconst_to_add list, additional keys are
    also stored with a prefix, however their value is also added to the primary
    key (i.e. the one without a postfix). This is only allowed for values that can be
    converted to int or float.

    To prevent locking or any race condition the a lock for the log file is
    aquired at the start of the function and released at the end of it.
    The lock is kept for the full duration of the function and not just the read/write
    part as the file is overwritten and not updated.

    Parameters
    ----------
    log_file: str
        The absolute log file path
    proc_type: str
        The process type this is for, one of LF/HF/BB/IM
    metadata_dict: Dictionary with string keys and values
        The metadata key and value pairs
    sim_name: str
        The simulation/realisation name for the data provided is added
        to the json log file at the top level
    metaconst_to_add: List of strings
        Metadata keys for which their values are added (e.g. run_time)
    logger:
        Logger to pass log messages to. If None all messages will be printed to stdout or stderr depending on level
    """
    # Check that it is a valid process type
    if not const.ProcessType.has_str_value(proc_type):
        logger.warning(
            "{} is not a valid process type. Logged anyway.".format(proc_type)
        )

    lock_file = os.path.join(os.path.dirname(log_file), LOCK_FILENAME)
    lock = SoftFileLock(lock_file)

    # Attempt to acquire the lock
    try:
        lock.acquire(timeout=20)
    except Timeout:
        logger.error(
            "Failed to acquire the lock for the metadata log file, "
            "giving up on logging data. This should be investigated!"
            "The metadata that was unable to be logged is attached: {}".format(
                metadata_dict
            )
        )
        return

    # Read the existing content if the log file exists
    json_data, proc_data = None, None
    if os.path.isfile(log_file):
        with open(log_file, "r") as f:
            json_data = json.load(f)
        proc_data = json_data.get(proc_type, None)
    # File doesn't exist yet
    else:
        json_data = {}

    # Add the simulation to the log file
    if (
        sim_name is not None
        and const.MetadataField.sim_name.value not in json_data.keys()
    ):
        json_data[const.MetadataField.sim_name.value] = sim_name
    elif (
        sim_name is not None
        and json_data.get(const.MetadataField.sim_name.value) != sim_name
    ):
        logger.warning(
            "Sim name {} does not match already existing sim name {} in metadata log file {}".format(
                sim_name, json_data.get(const.MetadataField.sim_name.value), log_file
            )
        )

    if proc_data is None:
        proc_data = {}
        json_data[proc_type] = proc_data

    for k, v in metadata_dict.items():
        if type(v) is str:
            v = convert_to_numeric(v)

        # Key doesn't exists yet
        if k not in proc_data.keys():
            proc_data[k] = v
            print("{} not in proc_Data.keys(),value {}\n".format(k, v))
            continue

        # Key already exists
        if k in proc_data.keys():
            k_count = sum([1 for cur_k in proc_data.keys() if k in cur_k])

            # Key has only been added once before (i.e. primary value)
            # Duplicate and add _1 postfix
            if k_count == 1:
                proc_data["{}_1".format(k)] = proc_data[k]

                # Add new value
                proc_data["{}_2".format(k)] = v
            # Several keys already exists, just add additional with count postfix
            else:
                # Don't need a +1 as the count includes the primary value
                proc_data["{}_{}".format(k, k_count)] = v

    # Write the json
    with open(log_file, "w") as f:
        json.dump(json_data, f)

    lock.release()

def main(args):
    # This should come from constants
    log_dir = os.path.join(args.sim_dir, "ch_log", const.METADATA_LOG_FILENAME)

    metadata_dict = getattr(args, METADATA_VALUES)
    # Determine run_time from start and end time
    if (
        const.MetadataField.start_time.value in metadata_dict.keys()
        and const.MetadataField.end_time.value in metadata_dict.keys()
    ):
        tdelta = datetime.strptime(
            metadata_dict[const.MetadataField.end_time.value],
            const.METADATA_TIMESTAMP_FMT,
        ) - datetime.strptime(
            metadata_dict[const.MetadataField.start_time.value],
            const.METADATA_TIMESTAMP_FMT,
        )
        metadata_dict[const.MetadataField.run_time.value] = tdelta.total_seconds()

    # Skip loading sim_params/fault_params/vm_params, as there are yet to exist
    if args.proc_type not in [
        const.ProcessType.SRF_GEN.str_value,
        const.ProcessType.INSTALL_REALISATION.str_value,
        const.ProcessType.VM_PARAMS.str_value,
        const.ProcessType.VM_GEN.str_value,
        const.ProcessType.VM_PERT.str_value,
        const.ProcessType.NO_VM_PERT.str_value,
    ]:
        # Load the params
        params = utils.load_sim_params(
            os.path.join(args.sim_dir, "sim_params.yaml"),
            load_vm=True,
        )

        if "dt" in params["bb"]:
            bb_dt = params["bb"]["dt"]
        else:
            bb_dt = min(params["dt"], params["hf"]["dt"])

        # params metadata for LF
        if args.proc_type == const.ProcessType.EMOD3D.str_value:
            metadata_dict[const.MetadataField.nt.value] = int(
                float(params["sim_duration"]) / float(params["dt"])
            )
            metadata_dict[const.MetadataField.nx.value] = params["nx"]
            metadata_dict[const.MetadataField.ny.value] = params["ny"]
            metadata_dict[const.MetadataField.nz.value] = params["nz"]
        # HF
        elif args.proc_type == const.ProcessType.HF.str_value:
            metadata_dict[const.MetadataField.nt.value] = int(
                float(params["sim_duration"]) / float(params["hf"]["dt"])
            )
            metadata_dict[const.MetadataField.nsub_stoch.value] = get_nsub_stoch(
                params["hf"]["slip"], get_area=False
            )
        # BB
        elif args.proc_type == const.ProcessType.BB.str_value:
            metadata_dict[const.MetadataField.dt.value] = bb_dt
        # IM_calc
        elif args.proc_type == const.ProcessType.IM_calculation.str_value:
            metadata_dict[const.MetadataField.nt.value] = int(
                float(params["sim_duration"]) / float(bb_dt)
            )
            # This should come from a constants file
            im_calc_csv_file = os.path.join(
                args.sim_dir, "IM_calc", "{}.csv".format(os.path.basename(args.sim_dir))
            )
            im_comp = list(pd.read_csv(im_calc_csv_file).component.unique().astype("U"))

            metadata_dict[const.MetadataField.im_comp.value] = im_comp
            metadata_dict[const.MetadataField.im_comp_count.value] = len(im_comp)
        # Advanced_IM
        elif args.proc_type == const.ProcessType.advanced_IM.str_value:
            metadata_dict[const.MetadataField.nt.value] = int(
                float(params["sim_duration"]) / float(bb_dt)
            )

    store_metadata(
        log_dir, args.proc_type, metadata_dict, sim_name=os.path.basename(args.sim_dir)
    )

if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument("sim_dir", type=str, help="The log directory")
    parser.add_argument(
        "proc_type",
        type=str,
        help="The process type to log metadata for. Has to be one of LF/HF/BB/IM",
    )
    parser.add_argument(
        METADATA_VALUES,
        action=KeyValuePairsAction,
        nargs="+",
        help="The key=value pairs (no space), pairs separated by space",
    )

    args = parser.parse_args()

    main(args)


from te import tik
from topi.cce import util
from te import platform as tbe_platform
from impl import decoded_bbox
from impl import nms
from impl import topk
from te import platform as tbe_platform

def get_dtype_size(input_dtype):
    """
    :param input_dtype:
    :return:
    """
    if input_dtype == "float16":
        size = 2
    else:
        size = 4

    return size

def get_ub_size():
    """
    :return:
    """
    ub_size = tbe_platform.cce_conf.get_soc_spec(tbe_platform.cce_conf.UB_SIZE)
    return ub_size

def filte_device_core(batch):
    """
    :param batch:
    :return:
    """
    device_core_num = \
        tbe_platform.cce_conf.get_soc_spec(tbe_platform.cce_conf.CORE_NUM)
    if batch >= device_core_num:
        batch_factor = batch//device_core_num
        batch_factor_tail = batch - batch_factor*device_core_num
    else:
        batch_factor = batch
        batch_factor_tail = 0
        device_core_num = 1

    return device_core_num, batch_factor, batch_factor_tail

def call_topk_sort(tik_instance, input_data, output):
    """
    :param tik_instance:
    :param input_data:
    :param output:
    :return:
    """

    score_threshold = 0
    k = input_data[0]
    regions_orig = input_data[1]
    mem_swap = input_data[2]
    proposal_num = input_data[3]

    batch_id = output[0]
    regions_sorted = output[1]
    proposal_actual_num = output[2]

    topk_input = {
        "proposal_num": proposal_num,
        "k": k,
        "score_threshold": score_threshold,
        "regions_orig": regions_orig,
        "mem_swap": mem_swap,
    }

    topk_out = {
        "batch_id": batch_id,
        "regions_sorted": regions_sorted,
        "proposal_actual_num": proposal_actual_num,
    }

    topk.tik_topk(tik_instance, topk_input, topk_out)

class InitProposalProcess:
    """
    Init Proposal Process
    """

    def __init__(self, input_data):
        """
        :param input_data:
        """
        self.tik_instance = input_data[0]
        feature_dic = input_data[1]
        self.im_info_dic = input_data[2]
        self.min_box_size = input_data[3]
        self.pre_nms_topn = input_data[4]
        self.post_nms_topn = input_data[5]
        self.nms_threshold = input_data[6]
        self.output_actual_rois_num = input_data[7]

        self.input_shape = feature_dic.get('shape')
        input_dtype = feature_dic.get('dtype')
        self.input_dtype = input_dtype

        channel = self.input_shape[1]
        height = self.input_shape[2]
        width = self.input_shape[3]
        num_anchor = channel//4
        num = (num_anchor*height*width + 127) // 128
        self.num = num

class ProposalProcess(InitProposalProcess):
    """
    Proposal Process
    """

    def __init__(self, input_data):
        """
        :param input_data:
        """
        super(ProposalProcess, self).__init__(input_data)
        feature_dic = input_data[1]
        input_dtype = feature_dic.get('dtype')
        input_shape = feature_dic.get('shape')
        batch, channel, height, width = input_shape
        num_anchor = channel//4
        num = (num_anchor*height*width + 127) // 128

        self.cls_prob = self.tik_instance.Tensor(input_dtype,
                                                 (batch, channel//2,
                                                  height, width),
                                                 name="cls_prob",
                                                 scope=tik.scope_gm)
        self.bbox_delta = self.tik_instance.Tensor(input_dtype,
                                                   self.input_shape,
                                                   name="bbox_delta",
                                                   scope=tik.scope_gm)
        self.rpn_bbox = self.tik_instance.Tensor(input_dtype,
                                                 self.input_shape,
                                                 name="rpn_bbox",
                                                 scope=tik.scope_gm)

        self.im_info = self.tik_instance.Tensor(input_dtype,
                                                self.im_info_dic.get('shape'),
                                                name="im_info",
                                                scope=tik.scope_gm)

        size = get_dtype_size(self.input_dtype)
        burst = ((num*128 - num_anchor*height*width)*8*size + 31)//32
        tail = burst*32//(8*size) - (num*128 - num_anchor*height*width)
        self.output_region_proposal = \
            self.tik_instance.Tensor(input_dtype,
                                     (batch, num*128+tail, 8),
                                     name="output_region_proposal",
                                     is_workspace=True,
                                     scope=tik.scope_gm)

        self.mem_swap = self.tik_instance.Tensor(input_dtype,
                                                 (batch, num*128+tail, 8),
                                                 name="mem_swap",
                                                 is_workspace=True,
                                                 scope=tik.scope_gm)

        self.topk_output_proposal = \
            self.tik_instance.Tensor(input_dtype,
                                     (batch,
                                      ((self.pre_nms_topn+15)//16)*16 + 4, 8),
                                     name="topk_output_proposal",
                                     is_workspace=True,
                                     scope=tik.scope_gm)

        self.temp_proposal_out = \
            self.tik_instance.Tensor(input_dtype,
                                     (batch, ((self.post_nms_topn + 15) // 16)*16, 8),
                                     name="temp_proposal_out",
                                     is_workspace=True,
                                     scope=tik.scope_gm)

        self.rois = self.tik_instance.Tensor(input_dtype,
                                             (batch, 5, ((self.post_nms_topn + 15) // 16)*16),
                                             name="rois",
                                             scope=tik.scope_gm)
        if self.output_actual_rois_num == 1:
            self.actual_rois_num = self.tik_instance.Tensor("int32", (batch, 8),
                                                            name="actual_rois_num",
                                                            scope=tik.scope_gm)
        else:
            self.actual_rois_num = self.tik_instance.Tensor("int32", (batch, 8),
                                                            name="actual_rois_num",
                                                            is_workspace=True,
                                                            scope=tik.scope_gm)

    def init_tail_zero(self, batch_id, size):
        """
        :param batch_id:
        :param size:
        :return:
        """
        if self.input_dtype == "float16":
            ratio = 1
        else:
            ratio = 2

        channel = self.input_shape[1]
        height = self.input_shape[2]
        width = self.input_shape[3]

        num_anchor = channel//4
        num = (num_anchor*height*width + 127) // 128

        tik_instance = self.tik_instance

        if num*128 > num_anchor*height*width:
            with tik_instance.if_scope(True):
                burst = ((num*128 - num_anchor*height*width)*8*size + 31)//32

                tmp_ub = tik_instance.Tensor(self.input_dtype, (128, 8),
                                             name="tmp_ub",
                                             scope=tik.scope_ubuf)
                tik_instance.vector_dup(128//ratio, tmp_ub, 0, 8*ratio, 1, 8)
                tik_instance.data_move(
                    self.output_region_proposal[batch_id,
                                                num_anchor*height*width, 0],
                    tmp_ub, 0, 1, burst, 0, 0)

    def cce_proposal(self, kernel_name="proposal"):
        """
        :param kernel_name:
        :return:
        """

        device_core_num, batch_factor, batch_factor_tail = \
            filte_device_core(self.input_shape[0])

        size = get_dtype_size(self.input_dtype)

        with self.tik_instance.for_range(
                0, device_core_num, block_num=device_core_num) as block_id:

            ub_size = get_ub_size()
            one_core_process_object = \
                decoded_bbox.OneCoreProcess((self.tik_instance,
                                             self.min_box_size,
                                             self.input_dtype, size,
                                             self.input_shape,
                                             device_core_num, batch_factor,
                                             ub_size))

            with self.tik_instance.for_range(0, batch_factor) as batch_index:
                batch_id = block_id*batch_factor + batch_index

                one_core_process_object.one_core_process_decode_bbox(
                    batch_id, self.cls_prob, self.bbox_delta, self.rpn_bbox, self.im_info,
                    self.output_region_proposal)

                self.init_tail_zero(batch_id, size)

                topk_output_actual_proposal_num = \
                    self.tik_instance.Scalar(dtype="int32")

                call_topk_sort(self.tik_instance,
                               (self.pre_nms_topn, self.output_region_proposal,
                                self.mem_swap, self.num*128),
                               (batch_id, self.topk_output_proposal,
                                topk_output_actual_proposal_num))

                input_offset = batch_id*(((self.pre_nms_topn+15)//16)*16 + 4)*8
                nms.cce_nms((self.input_dtype, ub_size,
                             self.nms_threshold, batch_id,
                             self.pre_nms_topn, self.post_nms_topn,
                             input_offset, self.im_info,
                             self.tik_instance),
                            self.temp_proposal_out,
                            self.topk_output_proposal,
                            topk_output_actual_proposal_num,
                            self.actual_rois_num, self.rois)

            with self.tik_instance.if_scope(block_id < batch_factor_tail):
                batch_id = batch_factor*device_core_num + block_id

                one_core_process_object.one_core_process_decode_bbox(
                    batch_id, self.cls_prob, self.bbox_delta, self.rpn_bbox, self.im_info,
                    self.output_region_proposal)

                self.init_tail_zero(batch_id, size)

                topk_output_actual_proposal_num = \
                    self.tik_instance.Scalar(dtype="int32")

                call_topk_sort(self.tik_instance,
                               (self.pre_nms_topn, self.output_region_proposal,
                                self.mem_swap, self.num*128),
                               (batch_id, self.topk_output_proposal,
                                topk_output_actual_proposal_num))

                input_offset = batch_id*(((self.pre_nms_topn+15)//16)*16 + 4)*8
                nms.cce_nms((self.input_dtype, ub_size,
                             self.nms_threshold, batch_id,
                             self.pre_nms_topn, self.post_nms_topn,
                             input_offset, self.im_info,
                             self.tik_instance),
                            self.temp_proposal_out,
                            self.topk_output_proposal,
                            topk_output_actual_proposal_num,
                            self.actual_rois_num, self.rois)
        if self.output_actual_rois_num == 1:
            self.tik_instance.BuildCCE(
                kernel_name,
                inputs=[self.cls_prob, self.bbox_delta, self.im_info, self.rpn_bbox],
                outputs=[self.rois, self.actual_rois_num])
        else:
            self.tik_instance.BuildCCE(
                kernel_name,
                inputs=[self.cls_prob, self.bbox_delta, self.im_info, self.rpn_bbox],
                outputs=[self.rois])

        return self.tik_instance

def check_dtype(tik_name, dtype):
    """
    :param tik_name:
    :param dtype:
    :return:
    """
    if tik_name in ("Ascend310",):
        util.check_dtype_rule(dtype.lower(), ["float16"])
    elif tik_name in ("Ascend910",):
        util.check_dtype_rule(dtype.lower(), ["float16"])
    elif tik_name in ("Hi3796CV300ES",):
        util.check_dtype_rule(dtype.lower(), ["float16"])
    elif tik_name in ("Hi3796CV300CS",):
        util.check_dtype_rule(dtype.lower(), ["float16"])
    elif tik_name in ("Ascend610","Ascend620"):
        util.check_dtype_rule(dtype.lower(), ["float16", "float32"])

@util.check_input_type(dict, dict, dict, dict, dict, dict, float,
                       float, float, (tuple, list), (tuple, list),
                       int, int, float, bool, str)
def proposal_d(cls_prob_dic, bbox_delta_dic, im_info_dic, rpn_bbox_dic,
               rois_dic, actual_rois_num_dic,
               feat_stride, base_size, min_size,
               ratio, scale, pre_nms_topn,
               post_nms_topn, iou_threshold, output_actual_rois_num, kernel_name="cce_proposal"):
    """
    :param feature_dic:
    :param im_info:
    :param min_box_size:
    :param pre_nms_topn:
    :param post_nms_topn:
    :param iou_threshold:
    :param kernel_name:
    :return:
    """
    input_dtype = rpn_bbox_dic.get('dtype')
    input_shape = rpn_bbox_dic.get('shape')
    channel = input_shape[1]

    feature_dic = {"shape" : input_shape, "dtype" : input_dtype}

    tik_instance = tik.Tik(tik.Dprofile())
    tik_name = tbe_platform.cce_conf.get_soc_spec("SOC_VERSION")
    check_dtype(tik_name, input_dtype)

    if min_size <= 0:
        raise RuntimeError("height and width of min_box must be greater than 0")

    min_box_size = [min_size, min_size]

    for ratio_value in ratio:
        if ratio_value <= 0:
            raise RuntimeError("ratio must be greater than 0")

    for scale_value in scale:
        if scale_value <= 0:
            raise RuntimeError("scale must be greater than 0")

    if feat_stride <= 0 or base_size <= 0 or \
            pre_nms_topn <= 0 or post_nms_topn <= 0:
        raise RuntimeError("feat_stride, base_size, pre_nms_topn "
                           "and post_nms_topn must be greater than 0")

    if pre_nms_topn > 6000 or post_nms_topn > 6000:
        raise RuntimeError("the pre_nms_topn or post_nms_topn is too big!")

    if tik_name in ("Hi3796CV300ES",) and \
            (pre_nms_topn > 3000 or post_nms_topn > 3000):
        raise RuntimeError("pre_nms_topn and post_nms_topn "
                           "must be <=3000 on hisi-es!")

    if channel % 4 != 0:
        raise RuntimeError("the channel must be multiples of 16!")

    if iou_threshold <= 0 or iou_threshold >= 1:
        raise RuntimeError("iou_threshold should be within (0, output_actual_rois_num1)!")

    proposal_result = ProposalProcess((tik_instance, feature_dic, im_info_dic,
                                       min_box_size,
                                       pre_nms_topn,
                                       post_nms_topn, iou_threshold, output_actual_rois_num))

    return proposal_result.cce_proposal(kernel_name)


class Solution:
    def punishmentNumber(self, n: int) -> int:
        summation = 0
        for i in range(1, n + 1):
            if self.can_have_sum(str(i ** 2), i):
                summation += (i ** 2)
        return summation

    def can_have_sum(self, s: str, n: int) -> bool:
        if int(s) == n:
            return True

        if len(s) == 1:
            return int(s) == n

        for i in range(1, len(s)):
            new_number = int(s[:i])
            print(s, s[:i], new_number, n)
            if new_number > n:
                return False

            if self.can_have_sum(s[i:], n - new_number):
                return True

        return False

# print(Solution().can_have_sum(str(45*45), 45))
print(Solution().punishmentNumber(45))  # 3503


#!/usr/bin/env python3
from controler import Flight_controller
import time
import rospy
if __name__ == '__main__':
    ic = Flight_controller()
    rate = rospy.Rate(10)
    ic.toggle_arm(True)
    #ic.set_mode('STABILIZE')
    ic.set_offboard_mode()
    # time.sleep(2)
    # ic.takeoff(3)
    ic.move_to(10,1,3)

    x= 1
    for i in range (0,1000):
        ic.accel_command(x,0,0)
        rate.sleep()


"""Program to download covid19 reports of Karnataka.
"""
import logging
import os
from pathlib import Path
from . import helpers as h

logger = logging.getLogger(__name__)

URL = "https://karunadu.karnataka.gov.in/hfw/kannada/Pages/covid-19.aspx"
ROOT = "archive/ka"
LINK_PATTERN = r"/\d\d-\d\d-\d\d\d\d\(.*\).pdf"

def get_links():
    logger.info("finding links from %s", URL)
    return h.find_links(URL, LINK_PATTERN)

def exists(url):
    filename = url.split("/")[-1]
    return os.path.exists(os.path.join(ROOT, filename))

def main():
    h.setup_logger()
    Path(ROOT).mkdir(parents=True, exist_ok=True)
    links = get_links()
    for link in links:
        if not exists(link):
            h.download(link, download_root=ROOT)

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-

import sys
import argparse

from maestral.daemon import freeze_support as freeze_support_daemon

def main():
    """
    This is the main entry point. It starts the GUI with the given config.
    """

    from .app import run

    parser = argparse.ArgumentParser()
    parser.add_argument("-c", "--config-name", default="maestral")
    parsed_args, _ = parser.parse_known_args()

    run(parsed_args.config_name)

def freeze_support_cli():
    """
    Provides support to start the CLI from a frozen executable.
    """

    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("--cli", action="store_true")
    parsed_args, remaining = parser.parse_known_args()

    if parsed_args.cli:
        from maestral.cli import main

        sys.argv = ["maestral"] + remaining
        main(prog_name="maestral")
        sys.exit()

if __name__ == "__main__":
    freeze_support_cli()
    freeze_support_daemon()
    main()


from pygame import *
from random import *

# Úlohy obdĺžky, kruhy vedľa seba, v sebe, s posunom
WHITE = Color(255, 255, 255)
BLACK = Color(0, 0, 0)
PINK = Color(168, 50, 166)

WIDTH = 600
HEIGHT = 400

screen = display.set_mode([WIDTH, HEIGHT])
circles = []
r = 20

screen.fill(WHITE)

while len(circles) < 100:
    circle = Vector2(randrange(WIDTH), randrange(WIDTH))

    overlaping = False
    for c in circles:
        if circle.distance_to(c) < 2*r:
            overlaping = True
            break
    if not overlaping:
        circles.append(circle)

for circle in circles:
    draw.circle(screen, PINK, [int(circle.x), int(circle.y)], r)
display.update()
time.delay(16)


num11=input()
kk=1
for i in range(len(num11)-1):
    ss1=num11[i]+num11[i+1]
    pp=int(ss1)
    if pp<=26 and num11[i]!="0":
        kk+=1
if kk==3:
    print(kk)
else:
    print(kk+(kk-1)//2)


#main test ve tests classlarim in icinde jsondaki butun tanimli elemanlar var. Main_test.parse_from_json(json_object)

#methodu icine bi json aldiginda json objesindeki gerekli elemanlari okuyup bu elemanlari kullanarak

#bir main_test objesi yaratir.

#Test classim da bu json dosyasindaki tests kismindaki elemanlar icin yarattim onun da kendine ozel parse json methodu var

#ve yine ayni islemi yapiyor.

#Main_Test.parse_from_json(json_object):

#input: json objesi (filepath ile alinabilir vs.)

#parsed_json maintest tipindeki obje icinde bir tane test listesi var, bu test listesinin icinde de testler var o testlerin id name ve commands i var
#bu commandslerde ayri bir liste her bir test icin o yuzden commandsden bi eleman cagirmak parsed_json.test[0].commands[] istedigimiz indexdeki elemani cagirabiliyoruz.
import json
#Reading a file
# f = open('jhipster.side', 'r+')
# # read()
# text = f.read()
# print(text)
# f.close()

class Main_Test:

    def __init__(self, id, version, url, tests, suites, urls, plugins):

        self.id = id
        self.version = version
        self.url = url
        self.tests = tests
        self.suites = suites
        self.urls = urls
        self.plugins = plugins

    def parse_from_json(json_object):

        if json_object is None:
            return None

        json_tests_list = json_object['tests']
        object_tests_list = []
        for json_test in json_tests_list:

            object_tests_list.append(Test.parse_from_json(json_test))

            return Main_Test(json_object["id"],
            json_object["version"],
            json_object["url"],
            object_tests_list,
            json_object["suites"],
            json_object["urls"],
            json_object["plugins"])

class Test:

    def __init__(self, id, name, commands):

        self.id = id
        self.name = name
        self.commands = commands

    def parse_from_json(json_object):

        if json_object is None:
            return None

        json_commands_list = json_object['commands']
        object_commands_list = []
        for json_test in json_commands_list:
            object_commands_list.append(Commands.parse_from_json(json_test))

        return Test(json_object["id"],
                    json_object["name"],
                    object_commands_list)

class Commands:

    def __init__(self, id, comment, command, target, targets, value):
        self.id = id
        self.comment = comment
        self.command = command
        self.target = target
        self.targets = targets
        self.value = value

    def parse_from_json(json_object):

        if json_object is None:
            return None

        return Commands(json_object["id"],
        json_object["comment"],
        json_object["command"],
        json_object["target"],
        json_object["targets"],
        json_object["value"])

with open("jhipster.side", "r") as read_file:

    data = json.load(read_file)
    parsed_json = Main_Test.parse_from_json(data)

    print(parsed_json.tests[0].commands[0].id)
    print(parsed_json.tests[0].id)
    print(parsed_json.tests[0].name)
    print(parsed_json.url)


# from tensorboardX import SummaryWriter

def log_grads(module, tb_writer, tb_index, tb_name):
    """
    log a particular module grad
    input:
        module   : Class(nn.module),
        tb_writer: tb_writer,
        tb_index : epoch/step,
        tb_name  : module_name
    """
    def weights_grads(module):
        """
        get moudle's grad and weights
        imput:
            module: Class(nn.module)
        return:
            grad: {name:grad}, weights: {name:weight}
        """
        grad = {}
        weights = {}
        for name, param in module.named_parameters():
            if param.grad is not None:
                grad[name] = param.grad
                weights[name] = param.data
        return grad, weights
    # get module's grad and weights
    grad, weights = weights_grads(module)
    tot_norm = 0
    for k, g in grad.items():
        _norm = g.data.norm(2)
        weight = weights[k]
        w_norm = weight.norm(2)
        tot_norm += _norm ** 2

        tb_writer.add_scalar('grad_weight/grad_{}/'.format(tb_name)+k.replace('.', '/'),
                             _norm, tb_index)
        tb_writer.add_scalar('grad_weight/weight_{}/'.format(tb_name)+k.replace('.', '/'),
                             w_norm, tb_index)
        tb_writer.add_scalar('grad_weight/w-g_{}/'.format(tb_name)+k.replace('.', '/'),
                             w_norm/(1e-20 + _norm), tb_index)
    tot_norm = tot_norm ** 0.5

    tb_writer.add_scalar('grad_weight/grad_{}_total/'.format(tb_name), tot_norm, tb_index)


import othellogame as nn
import random as rand
import numpy as np
import functions as func

class OthelloGamer(object):
    def __init__(self):
        self.weights1 = np.array([[nn.WEIGHTFACTOR*(rand.random()-0.5)
                                   for i in range(nn.INPUTSIZE+1)]
                                    for j in range(nn.HIDDENSIZE)])
        self.weights2 = np.array([[nn.WEIGHTFACTOR*(rand.random()-0.5)
                                   for i in range(nn.HIDDENSIZE+1)]
                                    for j in range(nn.OUTPUTSIZE)])

    # Performs matrix multiplication to perform the forward pass
    def forwardpass(self, board, player):
        known = np.array(board)
        if player == -1:
            for i in range(nn.BOARDSIZE):
                known[i] = 0-known[i]
        known = np.append(known, 1)
        # hin =  the inputs times the weights matrix
        hin = np.matmul(self.weights1,known)
        # normalize the values
        hout = np.array([func.sigmoid(x) for x in hin])
        hout = np.append(hout,1)
        # outin = outputs of hidden layer times the weights matrix
        outin = np.matmul(self.weights2,hout)
        # normalize
        outout = [func.sigmoid(x) for x in outin]
        return outout

    # Create an asexually reproduced child of itself with mutations
    def createChild(self):
        child = OthelloGamer()
        for i in range(nn.HIDDENSIZE):
            for j in range(nn.INPUTSIZE+1):
                num = rand.random()
                if num < nn.MUTATIONRATE/2: # Mutation 1: Create new weight
                    child.weights1[i][j] = nn.WEIGHTFACTOR*(rand.random()-0.5)
                elif num < nn.MUTATIONRATE: # Mutation 2: Add to parent weight
                    child.weights1[i][j] = self.weights1[i][j] + \
                                            nn.WEIGHTFACTOR*(rand.random()-0.5)
                else:
                    child.weights1[i][j] = self.weights1[i][j]
        for i in range(nn.OUTPUTSIZE):
            for j in range(nn.HIDDENSIZE+1):
                num = rand.random()
                if num < nn.MUTATIONRATE/2: # Mutation 1: Create new weight
                    child.weights2[i][j] = nn.WEIGHTFACTOR*(rand.random()-0.5)
                elif num < nn.MUTATIONRATE: # Mutation 2: Add to parent weight
                    child.weights2[i][j] = self.weights2[i][j] + \
                                            nn.WEIGHTFACTOR*(rand.random()-0.5)
                else:
                    child.weights2[i][j] = self.weights2[i][j]
        return child

    # Performs a game of othello between two systems
    def runSim(self, player2, printMovement = False):
        board = func.generateBoard()
        totalPieces = nn.BOARDSIZE-4
        currPlayer = (2*rand.randint(0,1))-1

        while totalPieces != 0: # Go until there are no moves or no pieces
            moves = func.possibleMoves(currPlayer, board)
            if not moves: # No moves available for the current player, switch
                currPlayer = 0 - currPlayer
                moves = func.possibleMoves(currPlayer, board)
                if not moves: # No moves for either player, end the game
                    break

            # Get the list of decisions from the playing network
            decisions = {}
            if currPlayer == 1:
                decisions = self.forwardpass(board, currPlayer)
            else:
                decisions = player2.forwardpass(board, currPlayer)

            # Find the highest prioritized move that is valid
            bestchoice = np.argmax(decisions)
            while bestchoice not in moves:
                decisions[bestchoice] = 0
                bestchoice = np.argmax(decisions)

            # Update the board, current player, and total pieces
            board = func.placePiece(currPlayer,board,bestchoice,moves[bestchoice])
            currPlayer = 0 - currPlayer
            totalPieces -= 1
        return sum(board)

    # Play a game of Othello against the network.
    def playGame(self):
        board = func.generateBoard()
        totalPieces = nn.BOARDSIZE-4
        currPlayer = 1
        func.visualizeBoard(board)

        while totalPieces != 0:
            # Check that there are valid moves and switch if necessary
            moves = func.possibleMoves(currPlayer, board)
            if not moves:
                currPlayer = 0 - currPlayer
                moves = func.possibleMoves(currPlayer, board)
                if not moves:
                    break

            choice = -1
            if currPlayer == 1: # Human playing
                print("Your move! (You are X)")
                while choice not in moves:
                    x = int(input("Input x (Upper left is (0,0)): "))
                    y = int(input("Input y (Upper left is (0,0)): "))
                    choice = func.translate(x,y)
            else: # Follow the procedure to produce network output
                print("Opponent's move:")
                decisions = self.forwardpass(board, currPlayer)
                bestchoice = np.argmax(decisions)
                while bestchoice not in moves:
                    decisions[bestchoice] = 0
                    bestchoice = np.argmax(decisions)
                choice = bestchoice

            # Update board, current player, and number of pieces. Then print
            # the board
            board = func.placePiece(currPlayer,board,choice,moves[choice])
            func.visualizeBoard(board)
            currPlayer = 0 - currPlayer
            totalPieces -= 1

        return sum(board)
        #func.visualizeBoard()


import collections
import copy

import numpy as np
import re

def toInt(c):
    return [int(e) for e in c]

def toList(c):
    return [list(r) for r in c]

def msplit(s, ds=None):

    if ds is None:
        ds = ' '

    patt = '|'.join(ds)
    res = re.split(patt, s)
    res = [e for e in res if e != '']
    res = [int(e) if e.isnumeric() else e for e in res]

    return res

def f01():
    with open('input') as file:
        rows = toList(file.read().splitlines())
        nrows = len(rows)
        ncols = len(rows[0])

        def count_all():
            return sum(sum((c == '#') for c in row) for row in rows)

        def count_occupied(row, col):
            count = 0
            for ro in range(-1, 2):
                for co in range(-1, 2):
                    if ro == 0 and co == 0:
                        continue
                    r = row + ro
                    c = col + co
                    if 0 <= r < nrows and 0 <= c < ncols and rows[r][c] == '#':
                        count += 1
            return count

        changed = True
        while changed:
            changed = False
            new = copy.deepcopy(rows)
            for r in range(nrows):
                for c in range(ncols):

                    cnt = count_occupied(r, c)
                    if rows[r][c] == 'L' and cnt == 0:
                        new[r][c] = '#'
                        changed = True
                    if rows[r][c] == '#' and cnt >= 4:
                        new[r][c] = 'L'
                        changed = True

            rows = copy.deepcopy(new)

        result = count_all()
        assert(result == 2243)
        print(result)

def f02():
    with open('input') as file:
        rows = toList(file.read().splitlines())
        nrows = len(rows)
        ncols = len(rows[0])

        def count_all():
            return sum(sum((c == '#') for c in row) for row in rows)

        def count_occupied(row, col):
            dirs = [(1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1)]

            count = 0
            for d in dirs:
                r = row
                c = col
                rd, cd = d
                while True:
                    r += rd
                    c += cd
                    if r < 0 or r >= nrows or c < 0 or c >= ncols:
                        break
                    if rows[r][c] == '#':
                        count += 1
                        break
                    if rows[r][c] == 'L':
                        break

            return count

        changed = True
        while changed:
            changed = False
            new = copy.deepcopy(rows)
            for r in range(nrows):
                for c in range(ncols):

                    cnt = count_occupied(r, c)
                    if rows[r][c] == 'L' and cnt == 0:
                        new[r][c] = '#'
                        changed = True
                    if rows[r][c] == '#' and cnt >= 5:
                        new[r][c] = 'L'
                        changed = True

            rows = copy.deepcopy(new)

        result = count_all()
        assert(result == 2027)
        print(result)

def main():
    f01()
    f02()

if __name__ == "__main__":
    """ This is executed when run from the command line """
    main()


"""
HogwartsCode - 当前Project名称;
XuZhu - 在创建文件的对话框中指定的文件名;
galaxy - 当前用户名;
2021/2/10 5:57 下午
"""
from second_python.work2.TongLao import TongLao

class XuZhu(TongLao):

    def read(self):
        print('罪过罪过')

xuzhu = XuZhu(1000,300)
xuzhu.read()


def anagram(s):
    if len(s) == 1:
        return s
    a = []
    subanagrams = anagram(s[1:])             # O(N!) asume anagram(s[1:]) will somehow solve the solution -1 char.
    for permutation in subanagrams:
        for i in range(len(permutation)+1):
            c = permutation[:]
            c = list(c)
            c.insert(i, s[0])
            a.append(''.join(c))
    return a

print(*anagram('abc'), sep='\n')

print(*anagram('abcde'), sep='\n')
print('Total combinations: ', len(anagram('abcde')))


import time

def readfile(filepath):
    fileObj = open(filepath, "r")
    measurements = list(map(get_measurement_value,fileObj.read().splitlines()))
    fileObj.close()
    return measurements

def check_part_one(file):
    measurements = readfile(file)
    total = 0
    before = measurements[0]
    for i in range(len(measurements)):
        current = measurements[i]
        res = current - before
        if res > 0:
            total = total + 1
        before = current

    return total

def get_measurement_value(measurement):
    return int(measurement.split()[0])

def check_part_two(file):
    measurements = readfile(file)
    total = 0
    before = measurements[0] + measurements[1] + measurements[2]
    for i in range(len(measurements) - 2):
        current = measurements[i] + measurements[i + 1] + measurements[i + 2]

        res = current - before
        if res > 0:
            total = total + 1
        before = current

    return total

## Asserts
assert check_part_one("../inputs/input1_test.txt") == 7
assert check_part_two("../inputs/input2_test.txt") == 5

start_time = time.time()
print("- Part one: " + str(check_part_one("../inputs/input1.txt")) + " [%s seconds]" % (time.time() - start_time))

start_time = time.time()
print("- Part two: " + str(check_part_two("../inputs/input2.txt")) + " [%s seconds]" % (time.time() - start_time))


import frrpc

# 与机器人控制器建立连接，连接成功返回一个机器人对象
robot = frrpc.RPC('192.168.58.2')

level = [1.0,2.0,3.0,4.0,5.0,6.0]
robot.SetAnticollision(0,level,1)
level = [50.0,20.0,30.0,40.0,50.0,60.0]
robot.SetAnticollision(1,level,1)
robot.SetCollisionStrategy(1)

p_limit = [170.0,80.0,150.0,80.0,170.0,160.0]
n_limit = [-170.0,-260.0,-150.0,-260.0,-170.0,-160.0]
robot.SetLimitPositive(p_limit)
robot.SetLimitNegative(n_limit)

robot.ResetAllError()

robot.FrictionCompensationOnOff(1)

lcoeff = [0.9,0.9,0.9,0.9,0.9,0.9]
wcoeff = [0.4,0.4,0.4,0.4,0.4,0.4]
ccoeff = [0.6,0.6,0.6,0.6,0.6,0.6]
fcoeff = [0.5,0.5,0.5,0.5,0.5,0.5]
robot.SetFrictionValue_level(lcoeff)
robot.SetFrictionValue_wall(wcoeff)
robot.SetFrictionValue_ceiling(ccoeff)
robot.SetFrictionValue_freedom(fcoeff)


from goodmap.config import Config, languages_dict

def test_parse_template_config() -> None:
    """Test that the template config can be parsed."""
    config = Config.parse_yaml("config-template.yml")
    langs_dict = languages_dict(config.languages)

    wanted_dict = {
        "en": {"domain": None, "flag": "uk", "name": "English"},
        "pl": {"domain": None, "flag": "pl", "name": "polski"},
    }
    assert langs_dict == wanted_dict


"""
Dados de entrada no script

experimento : Define quais pesos deverão ser utilizados. Exemplo: experimento = "YOLOv5_UAVDT_0"

input_folder : Define a pasta contendo as imagens a serem classificadas pela rede treinada no experimento.
               Pode ser uma pasta com imagens.
               Pode ser uma pasta com outras pastas em seu interior contendo imagens. Como se fosse uma
               espécie de dataset, contendo vários vídeos.

output_folder : Pasta para guardar o arquivo de texto único contendo informações a respeito
                das bounding boxes para cada frame. O nome do arquivo de texto é dado automaticamente:
                nome_do_filme_sendo_analisado + "results.txt"    dataset_name = input_folder.split("/")[-2]

Filosofia:
    Dado um input_path contendo imagens ou pastas com imagens, para cada vídeo analisado será criado um arquivo
    txt com os bounding boxes detectados pela rede e será colocado na pasta output_path. Simples assim.
    Demais rotinas devem ser executadas pelo usuário que chama este script.

Padrões utilizados:
    1) Todos as imagens possuem em seu nome o frame a que correspondem.
        O número do frame está localizado imediatamente antes do "." que separa o nome do formato da imagem.
        Exemplos: img_00001.jpg => Frame = 1
                  img3013uav000021.png => Frame = 21
    2) Os frames começam a ser contados do número 1 e não do número zero.
    3) Supor que todas as images de um vídeo possuem as mesmas dimensões de altura e largura.

Exemplo de execução:

    experimento = "YOLOv5_UAVDT_0"
    input_folder = "../Datasets/UAVDT/UAV-benchmark-M/M0101"
    output_folder = "./YOLOv5_UAVDT_0/results/inference/UAVDT_Inference/"

$ python this_file_name.py -e {experimento} -i {input_folder} -o {output_folder}

# Futuro:
Carregar o endereço dos pesos a partir de um banco de dados local.
Dado o experimento, localizar o endereço dos pesos no banco de dados.

# Debug:
    python exec_inference.py -e YOLOv5_UAVDT_0 -i ./TesteFolder -o ./TesteFolder
"""

import os
import shutil
import subprocess
import pathlib
import tempfile
import re
import argparse
from PIL import Image as PILImage
from glob import glob
import random

data_yaml = """
# train and val datasets (image directory or *.txt file with image paths)

train: ../../../Datasets/UAVDT_YOLOv5/train/images/
test: ../../../Datasets/UAVDT_YOLOv5_Dataset/test/images/

# number of classes
nc: 3

# class names
names: ['car', 'truck', 'bus']
"""

# Weights Relatitve Paths "Database"
yv5_weigth_path = lambda exp, date: os.path.join(".",exp,"YOLOv5_UAVDT_train",f"{exp}-{date}","weights","best.pt")

weight_paths = {"YOLOv5_UAVDT_0" : yv5_weigth_path("YOLOv5_UAVDT_0", "21_Feb_2021_18h_17m"),
                "YOLOv5_UAVDT_1" : yv5_weigth_path("YOLOv5_UAVDT_1", "21_Feb_2021_19h_26m")}

# Argument Parser
opt = argparse.ArgumentParser()
opt.add_argument('-o', '--output', action='store', dest="output_folder", default="")
opt.add_argument('-i', '--input', action='store', dest="input_folder", default="")
opt.add_argument('-e', '--experiment', action='store', dest="experiment", default="")

opt.add_argument('-r', '--resolution', action='store', dest="resolution", default= 640,
                help="Resolução da imagem para utilizar na detecção. Default = 640.")
opt.add_argument('-t', '--iou-threshold', action='store', dest="iou_thresh", default= 0.5,
                help="IOU threshold para utilizar na detecção. Default = 0.5.")
opt.add_argument('-c', '--conf-threshold', action='store', dest="conf_thresh", default= 0.5,
                help="Detection confidende para utilizar na detecção. Default = 0.5.")
opt.add_argument('-b', '--batch-size', action='store', dest="batch_size", default= 16,
                help="Batch size para utilizar na detecção. Default = 16.")
opt.add_argument('--task', action='store', dest="task", default= "test",
                help="Detection task: test, study, speed. Default = test")
                # Study task: Varia as resoluções das imagens e anota o mAP para cada size.
                # Sizes estudados: range(256, 1536 + 128, 128))  # x axis (image sizes)
opt.add_argument('-d','--device', action='store', dest="device", default= "cpu",
                help="Detection using device: cpu, 0, 1, 2, 3. Default = cpu")
opt.add_argument('-s','--single class', action='store_true', dest="single_class",
                help="Detection trear the dataset as single class")
opt.add_argument('--verbose', action='store_true', help='report mAP by class')
opt.add_argument('--save-txt', action='store_false', help='save results to *.txt')
opt.add_argument('--save-conf', action='store_false', help='save confidences in --save-txt labels')
opt.add_argument('--save-json', action='store_false', help='save a cocoapi-compatible JSON results file')
opt.add_argument('--project', default='runs/test', help='save to project/name')
opt.add_argument('--name', default='exp', help='save to project/name')

opt = opt.parse_args()

if opt.output_folder == "" or opt.input_folder == "" or opt.experiment == "":
    raise Exception("The input, output or experiment is an empty strings.")

# Main Function
class main():

    def __init__(self, opt, clear_io=True):
        self.opt = opt
        self.experimento = self.opt.experiment
        if self.experimento not in weight_paths.keys():
            raise Exception(f"Experimento '{self.experimento}' não encontrado." +\
                             "Experimentos disponíveis: {weight_paths.keys()}.")

        self.input_folder = opt.proje
        self.output_folder = self.opt.output_folder
        self.clear_io = clear_io #Clear ouput folder before saving new files
        self.package = False # False: Not a folder inside a folder. True, otherwise.
        self.videos_paths = None

    def check_input_and_output_dirs(self):
        """
        Verify if the folders are ok. If they aren't, raise an Exception or fix the problem.
        """
        # Check if the folders paths terminate with a os.sep. If don't, force it.
        if not self.input_folder[-1] == os.sep: self.input_folder += os.sep
        if not self.output_folder[-1] == os.sep: self.output_folder += os.sep

        # Check if input folder is a valid folder, i.e, it exists.
        if not os.path.isdir(self.input_folder):
            raise Exception(f'O caminho do input_folder "{self.input_folder}" não é um diretório.')

        else:
            ## Check for files/ folders inside input path
            ## If there is files and folders, raise an Exception.
            ## The folder should contain only files or only folders.
            objects = glob(self.input_folder + "*")
            self.package = os.path.isdir(objects[0])
            for obj in objects:
                # not XOR to check if all file are equals.
                if not (package ^ os.path.isdir(obj)):
                    pass
                else:
                    raise Exception(f"There is files and folders mixed together inside" +\
                                     "'{self.input_folder}'. That isn't permitted.")

            videos_paths = []
            if self.package:
                for directory in objects:
                    self.videos_paths.append(directory)
            else:
                self.videos_paths.append(self.input_folder)

        # Analysis of each video
        for video_path in videos_paths:
            # Check if the output folder exists. If doesn't, create it.
            self.craete_empty_folder(self.output_folder)

            # Create the output file path
            video_name = video_path.split(os.sep)[-2]
            output_file_path = self.output_folder + video_name + "_results.txt"

            # If for some reason the output file already exists, remove it.
            # If it's non empty directory, raise an Exception.
            if os.path.isdir(output_file_path):
                os.remove(output_file_path)
            if os.path.isfile(output_file_path):
                if self.clear_io:
                    os.remove(output_file_path)
                else:
                    raise Exception(f"{output_file_path} already exists and clear_io == False.")

        # Create output dir
        if os.path.exists(self.output_folder):
            if os.path.isdir(self.output_folder):
                if not os.listdir(self.output_folder):
                    # Empty directory, ok..
                    pass
                elif self.clear_io:
                    # Clear output directory
                    shutil.rmtree(self.output_folder)
                    pathlib.Path(self.output_folder).mkdir(parents=True, exist_ok=True)
                else:
                    raise Exception(f"{self.output_folder} not empty and clear_io == False.")
            if os.path.isfile(self.output_folder):
                raise Exception(f"{self.output_folder} is a file, not a directory.")
        else:
            raise Exception(f"Unknown output folder/file: '{self.output_folder}'.")

    def run_inference(self):
        """
        This function makes the things happen.
        """
        # Check input and output dirs
        self.check_input_and_output_dirs()

        # Check experiment neural network model name:
        network = self.experimento.split("_")[0]

        if network == "YOLOv5":
            try:
                for video_path in self.videos_paths:
                    # Remove old yolov5 files and replace by a new one copy.
                    yv5_path = os.path.join(".", self.experimento, f"yolov5_w_det_temp")
                    if os.path.exists(yv5_path):
                        shutil.rmtree(yv5_path)
                    os.symlink(os.path.join("..","..","Submodules","yolov5_w",), yv5_path)

                # Create a temporary directory to store intermediate results
                    tempdir = tempfile.mkdtemp()
                    print("\nDiretório temporário: ", tempdir)

                    # Now, run the inference
                    weights_file_path = weight_paths[self.experimento]
                    detect_py_path = os.path.join(yv5_path, "detect.py")
                    data_yaml_path = os.path.join(".", self.experimento, "data_detection.yaml")
                    with open(data_yaml_path, 'w') as arq:
                        arq.write(data_yaml)

                    opt = self.opt
                    original_path = os.getcwd()
                    os.chdir(yv5_path)
                    shell_command = ["python", detect_py_path,
                                    "--weights", weights_file_path,
                                    "--data", data_yaml_path,
                                    "--batch-size", opt.batch_size,
                                    "--img-size", opt.resolution,
                                    "--conf_thres", opt.conf_thresh,
                                    "--iou-thres", opt.iou_thres,
                                    "--task", opt.task,
                                    "--device", opt.device,
                                    "--single-cls",opt.single_cls,
                                    "--verbose", opt.verbose,
                                    "--save-txt", opt.save_txt,
                                    "--save-conf", opt.save_conf,
                                    "--save-json", opt.save_json,
                                    "--project", opt.project,
                                    "--name", opt.name]

                    process = subprocess.Popen(shell_command,
                                    stdout=subprocess.PIPE,
                                    universal_newlines=True)

                    while True:
                        output = process.stdout.readline()
                        print(output.strip())
                        return_code = process.poll()
                        if return_code is not None:
                            print('RETURN CODE', return_code)
                            # Process has finished, read rest of the output
                            for output in process.stdout.readlines():
                                print(output.strip())
                            break
                    os.chdir(original_path)
                    # Resume all outputs to one txt file
                    txt_files_paths = glob(os.path.join(tempdir, "*.txt"))
                    img_files_paths = glob(os.path.join(tempdir, "*.jpg"))

                    pattern = re.compile("\d+\.")
                    frame_number_aux = lambda name: pattern.search(name)
                    frame_number = lambda name: int(frame_number_aux(name).group()[:-1])

                    txt_files_paths.sort(key = frame_number)
                    img_files_paths.sort(key = frame_number)

                    frame_boxes = {}
                    for txt_path, img_path in zip(txt_files_paths, img_files_paths):
                        if frame_number(txt_path) != frame_number(img_path):
                            raise Exception("Problema com a numeração das imagens e files preditos pela rede.")
                        frame = frame_number(txt_path)

                        with PILImage.open(img_path) as img:
                            width, height = img.size

                        with open(txt_path) as arq:
                            lines = arq.readlines()
                            for line in lines:
                                if line == "": continue
                                line = line.split(" ")
                                classe, x, y, w, h = int(line[0]), float(line[1]), float(line[2]), float(line[3]), float(line[4])
                                x = x - w/2
                                y = y - h/2
                                x, w = x*width, w*width
                                y, h = y*height, h*height
                                if frame in frame_boxes:
                                    frame_boxes[frame].append([frame, x, y, w, h, classe + 1])
                                else:
                                    frame_boxes[frame] =[ [frame, x, y, w, h, classe + 1] ]

                    print(f"[INFO] Salvando resultados em {self.output_file_path}")
                    counter = 0
                    with open(self.output_file_path, 'a') as arq:
                        for boxes in frame_boxes.values():
                            for box in boxes:
                                box = [str(i) for i in box]
                                if counter == 0:
                                    arq.write(",".join(box))
                                    counter += 1
                                else: arq.write("\n" +",".join(box))

            except Exception as e:
                print(e)

            finally:
                print("[INFO] Limpando arquivos...")
                # Clear all outputs txt files, except the resume file
                print("[INFO] Removendo diretório temporário.")
                shutil.rmtree(tempdir)
                # Clear yolov5 folder
                print(f"[INFO] Removendo o subdretório yolov5 do experimento {self.experimento}.")
                shutil.rmtree(yv5_path)
                # Final msg
                print("[INFO] Fim da execução.")

        ### Debug mode for Visual Studio Code..
        debug_mode = False
        if debug_mode:
            print("\n\nCurrent dir: ", os.getcwd())
            os.chdir("./RedesNeurais")
            opt.parse_args() # Put the args here
        ###

        run_inference(opt= opt)


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumEvenGrandparent(self, root: TreeNode) -> int:
        res=0
        def dfs(node,parents):
            nonlocal res
            if not node:
                return
            # print(node.val,parents)
            if len(parents)>=2 and parents[-2]%2==0:
                res+=node.val
            china=parents.copy()
            china.append(node.val)
            if node.left:
                dfs(node.left,china)
            if node.right:
                dfs(node.right,china)
        dfs(root,[])
        return res


#This program finds the factorial of a number without using the math module.

number = int(input('Enter a nonnegative integer:'))
#Thinking about the cases which are not acceptable:
while number < 0:
    number = int(input('Invalid entry. Enter a nonnegative integer:'))

if number == 0:
    print('The factorial of 0 is 1')

else:
    list = []   #Making a list
    for i in range(1,number+1):
        list.append(i)

    #print(list)

    #Calculating the factorial:
    product = 1
    for n in list:
        product = product * n
    print(f'The factorial of {number} is {product:,}')
    #The :, format specifier is used to add a comma as a thousands separator to the product value.


from __future__ import print_function

import argparse
import sys
import time
import os
import glob
import re
import multiprocessing
import errno
from itertools import tee
from functools import partial

from jscodestyle.errorrecord import check_path, fix_path
from jscodestyle.error_check import STRICT_DOC, JSLINT_ERROR_DOC
from jscodestyle.error_fixer import ErrorFixer

GJSLINT_ONLY_FLAGS = ['--unix_mode', '--beep', '--nobeep', '--time',
                      '--check_html', '--summary', '--quiet']

# Comment - Below are all the arguments from gjslint. There are way
# too many, we should think what is really useful and cull some.

# Perhaps we should rely more on a config file for advance setups

class JsCodeStyle(object):
    """This class is a front end that parses arguments and flags."""
    def __init__(self):
        parser = argparse.ArgumentParser()

        parser.add_argument(
            'paths',
            help='the files to check',
            type=str,
            nargs='*',
            default=sys.stdin)

        parser.add_argument(
            '-u', '--unix_mode',
            help='emit warnings in standard unix format e.g. for Emacs',
            action='store_true')

        parser.add_argument(
            '-b', '--beep',
            help='do not beep when errors are found',
            action='store_false')

        parser.add_argument(
            '-t', '--time',
            help='emit timing statistics',
            action='store_true')

        parser.add_argument(
            '-c', '--check_html',
            help='check javascript in html files',
            action='store_true')

        parser.add_argument(
            '-s', '--summary',
            help='show an error count summary',
            action='store_true')

        parser.add_argument(
            '-q', '--quiet',
            help=('minimize logged messages. '
                  'Most useful for per-file linting, such as that '
                  'performed by the presubmit linter service.'),
            action='store_true')

        parser.add_argument(
            '-p', '--singleprocess',
            help=('disable parallelised linting using the '
                  'multiprocessing module; this may make debugging easier.'),
            action='store_true')

        parser.add_argument(
            '-a', '--additional_extensions',
            help=('Additional file extensions (not js) that should '
                  'be treated as JavaScript files e.g. es, es6 or ts.'),
            metavar='ext',
            nargs='+')

        parser.add_argument(
            '-r', '--recurse',
            help=('recurse in to the subdirectories of the given path'),
            action='append',
            nargs='+',
            metavar='dir')

        parser.add_argument(
            '-e', '--exclude_directories',
            help=('exclude the specified directories '
                  '(only applicable along with -r'),
            type=str,
            action='append',
            nargs='+',
            metavar='dir')

        parser.add_argument(
            '-x', '--exclude_files',
            type=str,
            nargs='*',
            help='exclude the specified files',
            action='append',
            metavar='file')

        parser.add_argument(
            '--limited_doc_files',
            help=('List of files with relaxed documentation checks. Will not '
                  'report errors for missing documentation, some missing '
                  'descriptions, or methods whose @return tags don\'t have a '
                  'matching return statement.'),
            action='append',
            nargs='*',
            metavar="filename")

        parser.add_argument(
            '--error_trace',
            help='show error exceptions.',
            action='store_true')

        parser.add_argument(
            '--closurized_namespaces',
            help=('namespace prefixes, used for testing of'
                  'goog.provide/require'),
            action='append',
            nargs='*',
            metavar="prefix")

        parser.add_argument(
            '--ignored_extra_namespaces',
            help=('Fully qualified namespaces that should be not be reported '
                  'as extra by the linter.'),
            action='append',
            nargs='*',
            metavar="namespace")

        parser.add_argument(
            '--custom_jsdoc_tags',
            help=('extra jsdoc tags to allow'),
            action='append',
            nargs='*',
            metavar="tagname")

        parser.add_argument(
            '--dot_on_next_line',
            help=('Require dots to be'
                  'placed on the next line for wrapped expressions'),
            action='store_true')

        parser.add_argument(
            '--check_trailing_comma',
            help=('check trailing commas '
                  '(ES3, not needed from ES5 onwards)'),
            action='store_true')

        parser.add_argument(
            '--debug_indentation',
            help='print debugging information for indentation',
            action='store_true')

        # Comment - watch this one, backwards internally than before
        parser.add_argument(
            '--jsdoc',
            help='disable reporting errors for missing JsDoc.',
            action='store_true')

        # Comment - this should change to named errors
        parser.add_argument(
            '--disable',
            help=('Disable specific error. Usage Ex.: gjslint --disable 1 '
                  '0011 foo.js.'),
            action='append',
            nargs='*',
            metavar='error_num')

        # Comment - old version checked for minimum of N=1,
        # so maybe check for negative later
        parser.add_argument(
            '--max_line_length',
            type=int,
            help=('Maximum line length allowed '
                  'without warning (default 80).'),
            metavar='N',
            default=80)

        parser.add_argument(
            '--strict',
            help=STRICT_DOC,
            action='store_true')

        parser.add_argument(
            '--jslint_error',
            help=JSLINT_ERROR_DOC,
            action='append',
            nargs='+')

        parser.add_argument(
            '--dry_run',
            help='(fixjscodestyle) do not modify the file, only print it.',
            action='store_true')

        parser.add_argument(
            '--disable_indentation_fixing',
            help='(fixjscodestyle) disable automatic fixing of indentation.',
            action='store_true')

        parser.add_argument(
            '--fix_error_codes',
            help=('(fixjscodestyle) list of specific error codes to '
                  'fix. Defaults to all supported error codes when empty. '
                  'See errors.py for a list of error codes.'),
            action='append',
            nargs='+',
            metavar='error_num')

        self.args = parser.parse_args()

        # Emacs sets the environment variable INSIDE_EMACS in the subshell.
        # Request Unix mode as emacs will expect output to be in Unix format
        # for integration.
        # See https://www.gnu.org/software/emacs/manual/html_node/emacs/
        # Interactive-Shell.html

        if 'INSIDE_EMACS' in os.environ:
            self.args.unix_mode = True

        self.suffixes = ['.js']
        if self.args.additional_extensions:
            self.suffixes += ['.%s' % ext for ext in self.args.additional_extensions]
        if self.args.check_html:
            self.suffixes += ['.html', '.htm']
        self.paths = None
        self._get_paths()
        self.start_time = time.time()

    def matches_suffixes(self, filename):
        """Returns whether the given filename matches one of the given suffixes.

        Args:
          filename: Filename to check.

        Returns:
          Whether the given filename matches one of the given suffixes.
        """
        suffix = filename[filename.rfind('.'):]
        return suffix in self.suffixes

    def get_user_specified_files(self):
        """Returns files to be linted, specified directly on the command line.

        Can handle the '*' wildcard in filenames, but no other wildcards.

        Args:
          argv: Sequence of command line arguments. The second and following arguments
            are assumed to be files that should be linted.
          suffixes: Expected suffixes for the file type being checked.

        Returns:
          A sequence of files to be linted.
        """
        all_files = []
        lint_files = []

         # Perform any necessary globs.
        for filename in self.args.paths:
            if filename.find('*') != -1:
                for result in glob.glob(filename):
                    all_files.append(result)
            else:
                all_files.append(filename)

        for filename in all_files:
            if self.matches_suffixes(filename):
                lint_files.append(filename)
        return lint_files

    def get_recursive_files(self):
        """Returns files to be checked specified by the --recurse flag.

        Returns:
          A list of files to be checked.
        """
        lint_files = []
        # Perform any request recursion
        if self.args.recurse:
            for start in self.args.recurse:
                for root, _, files in os.walk(start):
                    for filename in files:
                        if self.matches_suffixes(filename):
                            lint_files.append(os.path.join(root, filename))
        return lint_files

    def filter_files(self, files):
        """Filters the list of files to be linted be removing any excluded files.

        Filters out files excluded using --exclude_files and  --exclude_directories.

        Args:
          files: Sequence of files that needs filtering.

        Returns:
          Filtered list of files to be linted.
        """
        num_files = len(files)

        ignore_dirs_regexs = []

        excluded_dirs = (self.args.exclude_directories if
                         self.args.exclude_directories else [])

        excluded_files = (self.args.exclude_files if
                          self.args.exclude_files else [])

        for ignore in excluded_dirs:
            ignore_dirs_regexs.append(re.compile(r'(^|[\\/])%s[\\/]' % ignore))

        result_files = []
        for filename in files:
            add_file = True
            for exclude in excluded_files:
                if filename.endswith('/' + exclude) or filename == exclude:
                    add_file = False
                    break
            for ignore in ignore_dirs_regexs:
                if ignore.search(filename):
                    # Break out of ignore loop so we don't add to
                    # filtered files.
                    break
            if add_file:
                # Convert everything to absolute paths so we can easily remove duplicates
                # using a set.
                result_files.append(os.path.abspath(filename))

        skipped = num_files - len(result_files)
        if skipped:
            print('Skipping %d file(s).' % skipped)

        self.paths = set(result_files)

    def _get_paths(self):
        """Finds all files specified by the user on the commandline."""
        files = self.get_user_specified_files()

        if self.args.recurse:
            files += self.get_recursive_files()

        self.filter_files(files)

    def _multiprocess_check_paths(self, check_fn):
        """Run _check_path over mutltiple processes.

        Tokenization, passes, and checks are expensive operations.  Running in a
        single process, they can only run on one CPU/core.  Instead,
        shard out linting over all CPUs with multiprocessing to parallelize.

        Args:
          paths: paths to check.

        Yields:
          errorrecord.ErrorRecords for any found errors.
        """

        pool = multiprocessing.Pool()

        path_results = pool.imap(check_fn, self.paths)
        for results in path_results:
            for result in results:
                yield result

        # Force destruct before returning, as this can sometimes raise spurious
        # "interrupted system call" (EINTR), which we can ignore.
        try:
            pool.close()
            pool.join()
            del pool
        except OSError as err:
            if err.errno is not errno.EINTR:
                raise err

    def _check_paths(self, check_fn):
        """Run _check_path on all paths in one thread.

        Args:
          paths: paths to check.

        Yields:
          errorrecord.ErrorRecords for any found errors.
        """

        for path in self.paths:
            results = check_fn(path)
            for record in results:
                yield record

    def _print_file_summary(self, records):
        """Print a detailed summary of the number of errors in each file."""

        paths = list(self.paths)
        paths.sort()

        for path in paths:
            path_errors = [e for e in records if e.path == path]
            print('%s: %d' % (path, len(path_errors)))

    @staticmethod
    def _print_file_separator(path):
        print('----- FILE  :  %s -----' % path)

    def _print_error_records(self, error_records):
        """Print error records strings in the expected format."""

        current_path = None
        for record in error_records:

            if current_path != record.path:
                current_path = record.path
                if not self.args.unix_mode:
                    self._print_file_separator(current_path)

            print(record.error_string)

    def _print_summary(self, paths, error_records):
        """Print a summary of the number of errors and files."""

        error_count = len(error_records)
        all_paths = set(paths)
        all_paths_count = len(all_paths)

        if error_count is 0:
            print ('%d files checked, no errors found.' % all_paths_count)

        new_error_count = len([e for e in error_records if e.new_error])

        error_paths = set([e.path for e in error_records])
        error_paths_count = len(error_paths)
        no_error_paths_count = all_paths_count - error_paths_count

        if (error_count or new_error_count) and not self.args.quiet:
            error_noun = 'error' if error_count == 1 else 'errors'
            new_error_noun = 'error' if new_error_count == 1 else 'errors'
            error_file_noun = 'file' if error_paths_count == 1 else 'files'
            ok_file_noun = 'file' if no_error_paths_count == 1 else 'files'
            print('Found %d %s, including %d new %s, in %d %s (%d %s OK).' %
                  (error_count,
                   error_noun,
                   new_error_count,
                   new_error_noun,
                   error_paths_count,
                   error_file_noun,
                   no_error_paths_count,
                   ok_file_noun))

    @staticmethod
    def _format_time(duration):
        """Formats a duration as a human-readable string.

        Args:
          duration: A duration in seconds.

        Returns:
          A formatted duration string.
        """
        if duration < 1:
            return '%dms' % round(duration * 1000)
        return '%.2fs' % duration

    def check(self):
        """Check the JavaScript files for style."""
        check_path_p = partial(
            check_path,
            unix_mode=self.args.unix_mode,
            limited_doc_files=self.args.limited_doc_files,
            error_trace=self.args.error_trace,
            closurized_namespaces=self.args.closurized_namespaces,
            ignored_extra_namespaces=self.args.ignored_extra_namespaces,
            custom_jsdoc_tags=self.args.custom_jsdoc_tags,
            dot_on_next_line=self.args.dot_on_next_line,
            check_trailing_comma=self.args.check_trailing_comma,
            debug_indentation=self.args.debug_indentation,
            jslint_error = self.args.jslint_error,
            strict = self.args.strict,
            jsdoc=self.args.jsdoc,
            disable=self.args.disable,
            max_line_length=self.args.max_line_length)

        if self.args.singleprocess:
            records_iter = self._check_paths(check_path_p)
        else:
            records_iter = self._multiprocess_check_paths(check_path_p)

        records_iter, records_iter_copy = tee(records_iter, 2)
        self._print_error_records(records_iter_copy)

        error_records = list(records_iter)
        self._print_summary(self.paths, error_records)

        exit_code = 0

        # If there are any errors
        if error_records:
            exit_code += 1

        # If there are any new errors
        if [r for r in error_records if r.new_error]:
            exit_code += 2

        if exit_code:
            if self.args.summary:
                self._print_file_summary(error_records)

            if self.args.beep:
                # Make a beep noise.
                sys.stdout.write(chr(7))

            # Write out instructions for using fixjsstyle script to fix some of the
            # reported errors.
            fix_args = []
            for flag in sys.argv[1:]:
                for go_flag in GJSLINT_ONLY_FLAGS:
                    if flag.startswith(go_flag):
                        break
                else:
                    fix_args.append(flag)

            if not self.args.quiet:
                print("""
          Some of the errors reported by GJsLint may be auto-fixable using the
          command fixjsstyle. Please double check any changes it makes and report
          any bugs. The command can be run by executing:

          fixjsstyle %s """ % ' '.join(fix_args))

        if self.args.time:
            print ('Done in %s.' % self._format_time(time.time() -
                                                     self.start_time))

        sys.exit(exit_code)

    def fix(self):
        """Fix the code style of the JavaScript files."""

        fixer = ErrorFixer(
            dry_run=self.args.dry_run,
            disable_indentation_fixing=self.args.disable_indentation_fixing,
            fix_error_codes=self.args.fix_error_codes)

        # Check the list of files.
        for path in self.paths:
            fix_path(
                path,
                fixer,
                None,
                limited_doc_files=self.args.limited_doc_files,
                error_trace=self.args.error_trace,
                closurized_namespaces=self.args.closurized_namespaces,
                ignored_extra_namespaces=self.args.ignored_extra_namespaces,
                custom_jsdoc_tags=self.args.custom_jsdoc_tags,
                dot_on_next_line=self.args.dot_on_next_line,
                check_trailing_comma=self.args.check_trailing_comma,
                debug_indentation=self.args.debug_indentation,
                jslint_error = self.args.jslint_error,
                strict = self.args.strict,
                jsdoc=self.args.jsdoc,
                disable=self.args.disable,
                max_line_length=self.args.max_line_length)

def fix():
    """Automatically fix simple style guide violations."""
    style_checker = JsCodeStyle()
    style_checker.fix()

def main():
    """Used when called as a command line script."""
    style_checker = JsCodeStyle()
    style_checker.check()

if __name__ == '__main__':
    main()


def find_missing(sequence: list) -> int:
    try:
        cur_prog = []
        for i in range(len(sequence) - 1):
            cur_prog.append(sequence[i + 1] - sequence[i])
        if min(cur_prog) > 0:
            real_list = [i for i in range(min(sequence), max(sequence), min(cur_prog))]
            return list(set(real_list) - set(sequence))[0]
        else:
            real_list = [i for i in range(max(sequence), min(sequence), max(cur_prog))]
            return list(set(real_list) - set(sequence))[0]
    except:
        return 0

print(find_missing([-1, -3, -4, -5, -6, -7, -8, -9]))

Find the missing term in an Arithmetic Progression.py


# importing the modules
import numpy as np
import matplotlib.pyplot as plt

# data to be plotted
x = np.arange(1, 11)
print(x)

y = x * x
print(y)

# plotting
plt.title("Line graph")

plt.xlabel("X axis")
plt.ylabel("Y axis")

plt.plot(x, y, color="red")
plt.show()


# Let's correct the code and try running it again.
import random

def assign_people_to_game(df_people, people_per_game, number_of_games, remainder_processing):
    # Initialize games
    games = [[] for _ in range(number_of_games)]

    # Sort people based on previous_status_ok
    sorted_people = sorted(df_people, key=lambda x: x['previous_status_ok'])

    # Calculate total game slots and compare with total people
    total_slots = people_per_game * number_of_games
    total_people = len(sorted_people)
    remainder = total_people - total_slots

    # Assign people with priority (previous_status_ok=False) to games
    for person in sorted_people:
        if total_slots <= 0:
            break  # Stop if all slots are filled

        # Find the least filled game to add the person to
        min_filled_game = min(games, key=len)
        min_filled_game.append(person['person_id'])
        total_slots -= 1

    # Handle remainder
    if remainder > 0:
        # More people than game slots; do nothing as excess people are already excluded
        pass
    else:
        remainder = abs(remainder)  # Convert to positive for easier handling
        if remainder_processing == 'extend2':
            # Add extra people to the last game
            min_filled_game = min(games, key=len)
            min_filled_game.extend([person['person_id'] for person in sorted_people[:remainder]])
        elif remainder == 3 or remainder_processing == 'split':
            # Create a new game with 2 or 3 people
            games.append([person['person_id'] for person in sorted_people[:remainder]])
        else:
            # Add the remaining person to an existing game
            min_filled_game = min(games, key=len)
            min_filled_game.append(sorted_people[0]['person_id'])

    return games

# Test the function
test_people = [
    {'person_id': 1, 'previous_status_ok': True},
    {'person_id': 2, 'previous_status_ok': True},
    {'person_id': 3, 'previous_status_ok': False},
    {'person_id': 4, 'previous_status_ok': True},
    {'person_id': 5, 'previous_status_ok': False},
    {'person_id': 6, 'previous_status_ok': True},
]

result = assign_people_to_game(test_people, 2, 3, 'extend2')
print(result)


from datetime import datetime

""""

If the subtotal is $50 or greater and today is Tuesday or , your program must subtract 10% from the subtotal. Your program must then compute the total amount due by adding sales tax of 6% to the subtotal. Your program must print the discount amount if applicable, the sales tax amount, and the total amount due.

"""

subtotal=float(input("Please enter the subtotal: "))
# get current datetime
dt = datetime.now()

# get weekday name
day=dt.strftime('%A')
applydiscount=False
if day in ("Tuesday","Wednesday"):
    if subtotal>=50:
        applydiscount=True

if applydiscount==True:
    print(f"Today you have a discount because today is {day} and your amount is more than $50")
    discount=subtotal*0.1
    print(f"Discount amount: {discount:.2f}")
    tax=(subtotal-discount)*.06
    print (f"Sales tax amount: {tax:.2f}")
    total=subtotal-discount+tax
    print (f"Total: {total:.2f}")
else:
    tax=subtotal*.06
    print (f"Sales tax amount: {tax:.2f}")
    total=subtotal+tax
    print (f"Total: {total:.2f}")

print("")


#!python3.6.6
import random
import numpy as np
import chainer
import matplotlib.pyplot as plt
from chainer.datasets import cifar
from chainer.datasets import split_dataset_random
from chainer import iterators
import chainer.links as L
import chainer.functions as F
from chainer import optimizers
from chainer import training
from chainer.training import extensions
from chainer.cuda import to_cpu

#############################################################
def reset_seed(seed=0):
    random.seed(seed)
    np.random.seed(seed)
    if chainer.cuda.available:
        chainer.cuda.cupy.random.seed(seed)

class DeepCNN(chainer.ChainList):

    def __init__(self, n_output):
        super(DeepCNN, self).__init__(
            ConvBlock(64),
            ConvBlock(64, True),
            ConvBlock(128),
            ConvBlock(128, True),
            ConvBlock(256),
            ConvBlock(256),
            ConvBlock(256),
            ConvBlock(256, True),
            LinearBlock(),
            LinearBlock(),
            L.Linear(None, n_output)
        )

    def __call__(self, x):
        for f in self:
            x = f(x)
        return x

class ConvBlock(chainer.Chain):

    def __init__(self, n_ch, pool_drop=False):
        w = chainer.initializers.HeNormal()
        super(ConvBlock, self).__init__()
        with self.init_scope():
            self.conv = L.Convolution2D(None, n_ch, 3, 1, 1, nobias=True, initialW=w)
            self.bn = L.BatchNormalization(n_ch)
        self.pool_drop = pool_drop

    def __call__(self, x):
        h = F.relu(self.bn(self.conv(x)))
        if self.pool_drop:
            h = F.max_pooling_2d(h, 2, 2)
            h = F.dropout(h, ratio=0.25)
        return h

class LinearBlock(chainer.Chain):

    def __init__(self, drop=False):
        w = chainer.initializers.HeNormal()
        super(LinearBlock, self).__init__()
        with self.init_scope():
            self.fc = L.Linear(None, 1024, initialW=w)
        self.drop = drop

    def __call__(self, x):
        h = F.relu(self.fc(x))
        if self.drop:
            h = F.dropout(h)
        return h

class MyNet(chainer.Chain):

    def __init__(self, n_out):
        super(MyNet, self).__init__()
        with self.init_scope():
            self.conv1 = L.Convolution2D(None, 32, 3, 3, 1)
            self.conv2 = L.Convolution2D(32, 64, 3, 3, 1)
            self.conv3 = L.Convolution2D(64, 128, 3, 3, 1)
            self.fc4 = L.Linear(None, 1000)
            self.fc5 = L.Linear(1000, n_out)

    def __call__(self, x):
        h = F.relu(self.conv1(x))
        h = F.relu(self.conv2(h))
        h = F.relu(self.conv3(h))
        h = F.relu(self.fc4(h))
        h = self.fc5(h)
        return h

def train(network_object, batchsize=128, gpu_id=0, max_epoch=20, train_dataset=None, valid_dataset=None, test_dataset=None, postfix='', base_lr=0.01, lr_decay=None):

    # 1. Dataset
    if train_dataset is None and valid_dataset is None and test_dataset is None:
        train_val, test = cifar.get_cifar10()
        train_size = int(len(train_val) * 0.9)
        train, valid = split_dataset_random(train_val, train_size, seed=0)
    else:
        train, valid, test = train_dataset, valid_dataset, test_dataset

    # 2. Iterator
    train_iter = iterators.SerialIterator(train, batchsize)
    valid_iter = iterators.SerialIterator(valid, batchsize, False, False)

    # 3. Model
    net = L.Classifier(network_object)

    # 4. Optimizer
    optimizer = optimizers.MomentumSGD(lr=base_lr).setup(net)
    optimizer.add_hook(chainer.optimizer.WeightDecay(0.0005))

    # 5. Updater
    updater = training.StandardUpdater(train_iter, optimizer, device=gpu_id)

    # 6. Trainer
    trainer = training.Trainer(updater, (max_epoch, 'epoch'), out='{}_cifar10_{}result'.format(network_object.__class__.__name__, postfix))

    # 7. Trainer extensions
    trainer.extend(extensions.LogReport())
    trainer.extend(extensions.observe_lr())
    trainer.extend(extensions.Evaluator(valid_iter, net, device=gpu_id), name='val')
    trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'main/accuracy', 'val/main/loss', 'val/main/accuracy', 'elapsed_time', 'lr']))
    trainer.extend(extensions.PlotReport(['main/loss', 'val/main/loss'], x_key='epoch', file_name='loss.png'))
    trainer.extend(extensions.PlotReport(['main/accuracy', 'val/main/accuracy'], x_key='epoch', file_name='accuracy.png'))
    if lr_decay is not None:
        trainer.extend(extensions.ExponentialShift('lr', 0.1), trigger=lr_decay)
    trainer.run()
    del trainer

    # 8. Evaluation
    test_iter = iterators.SerialIterator(test, batchsize, False, False)
    test_evaluator = extensions.Evaluator(test_iter, net, device=gpu_id)
    results = test_evaluator()
    print('Test accuracy:', results['main/accuracy'])

    return net
#######################################################
# set random seed
reset_seed(0)

chainer.cuda.set_max_workspace_size(256 * 1024 * 1024)
chainer.config.autotune = True

model = train(MyNet(10), max_epoch=100, base_lr=0.1, lr_decay=(30, 'epoch'))


import cv2
import numpy as np

src = cv2.imread('cat.bmp', cv2.IMREAD_GRAYSCALE)

blr = cv2.GaussianBlur(src, (0, 0), 2)
dst = np.clip(2.0*src - blr, 0, 255).astype(np.uint8)

cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()

cv2.destroyAllWindows()


class Solution:
    def convert(self, s: str, numRows: int) -> str:

        if numRows == 1:
                end = 1
        elif numRows == 2:
            end = 2
        else:
            end = 2*numRows-2

        mapper = [[""] for _ in range(numRows)]

        for i in range(len(s)):
            if i%end >= numRows:
                mapper[end-i%end].append(s[i])
            else:
                mapper[i%end].append(s[i])

        res = ""
        for x in range(len(mapper)):
            for i in range(len(mapper[x])):
                res = res+ mapper[x][i]

        return res