from uuid import uuid4, UUID
from enum import Enum
from json import dumps, JSONEncoder, loads
from re import compile as re_compile
from collections import OrderedDict
from functools import partial
from openvsp import vsp
try:
    from IPython.display import display_javascript, display_html
except ImportError:
    display_html, display_javascript = None, None

regex_listname = re_compile(r"^(?P<name>[a-zA-Z]+)_*(?P\d*)")
EXCLUDE_GROUPS = ('BBox',)
INCLUDE_GROUPS = ('Design',)  # Not currently used for filtering groups
PARAM_KEYS = ('upper', 'lower', 'value')

Enum0 = partial(Enum, start=0)
ParamType = Enum0('ParamType', 'PARM_DOUBLE_TYPE PARM_INT_TYPE PARM_BOOL_TYPE PARM_FRACTION_TYPE PARM_STRING_TYPE ')
ErrorCode = Enum0('ErrorCode', 'VSP_OK VSP_INVALID_PTR VSP_CANT_FIND_TYPE VSP_CANT_FIND_PARM VSP_CANT_FIND_NAME ' +
                  'VSP_INVALID_GEOM_ID VSP_FILE_DOES_NOT_EXIST VSP_FILE_WRITE_FAILURE VSP_WRONG_XSEC_TYPE ' +
                  'VSP_WRONG_FILE_TYPE VSP_INDEX_OUT_RANGE VSP_INVALID_XSEC_ID')
SymCode = Enum0('SymCode', 'SYM_XY SYM_XZ SYM_YZ SYM_ROT_X SYM_ROT_Y SYM_ROT_Z SYM_PLANAR_TYPES SYM_NUM_TYPES')
ExportCode = Enum0('ExportCode', 'EXPORT_FELISA EXPORT_XSEC EXPORT_STL EXPORT_AWAVE EXPORT_NASCART EXPORT_POVRAY ' +
                   'EXPORT_CART3D EXPORT_VORXSEC EXPORT_XSECGEOM EXPORT_GMSH EXPORT_X3D')

class VspEncoder(JSONEncoder):
    # TODO: remove keys that start with '_'
    def default(self, obj):
        if isinstance(obj, VspElement):
            return obj.json

        if isinstance(obj, Enum):
            return {"__enum__": str(obj)}

        if isinstance(obj, UUID):
            return {"__uuid__": str(obj)}

        return JSONEncoder.default(self, obj)

class VspElement(OrderedDict):
    """An object that can represent an manipulate OpenVSP elements."""

    def __init__(self, is_param=False, **kwargs):
        super().__init__()
        self.__uuid = uuid4()
        self.__is_param = is_param
        for key, value in kwargs.items():
            if isinstance(value, dict):
                value = VspElement(**value)
            self[key] = value

    def __hash__(self):
        return hash(id(self))

    def __getitem__(self, key):
        try:
            if key[0] == '_':
                return super().__getitem__(key)
        except TypeError:
            pass

        try:
            item = super().__getitem__(key)
        except KeyError:
            return None

        if isinstance(item, VspElement) and item.__is_param:
            return item.value
        else:
            return item

    def __lt__(self, other):
        if self.__is_param:
            return self.value < other
        else:
            return super().__lt__(other)

    def __gt__(self, other):
        if self.__is_param:
            return self.value > other
        else:
            return super().__gt__(other)

    def __eq__(self, other):
        if self.__is_param:
            return self.value == other
        else:
            return super().__eq__(other)

    def __setitem__(self, key, value):
        try:
            item = super().__getitem__(key)
        except KeyError:
            item = []
        if isinstance(item, VspElement) and item.__is_param:
            if value < item.lower or value > item.upper:
                msg = "{lower}<={name}<={upper}, value={_new}"
                raise ValueError(msg.format(_new=value, **item))
            item.value = value
            vsp.Update()
        else:
            super().__setitem__(key, value)

    __getattr__ = __getitem__
    __setattr__ = __setitem__
    __delattr__ = OrderedDict.__delitem__

    def __dir__(self):
        return super().__dir__() + list(self.keys())

    def __repr__(self):
        rep_dict = {'name': 'VSP Element'}
        rep_dict.update(**dict(self))
        return "{name}".format(**rep_dict)

    def _ipython_display_(self):
        if display_html is not None:
            display_html('

'.format(self.__uuid), raw=True)

            display_javascript("""
                require(["https://rawgit.com/caldwell/renderjson/master/renderjson.js"], function() {
                  document.getElementById('%s').appendChild(renderjson(%s))
                });
                """ % (self.__uuid, self.json), raw=True)

    @property
    def json(self):
        return dumps(self, cls=VspEncoder, indent=2, sort_keys=True)

class VspModel(VspElement):
    """An object that can represent and manipulate OpenVSP aircraft."""

    def __init__(self, filename=None, threejs=False, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__filename = filename
        self.__threejs = threejs
        self.__param_map = {}
        self.design = None

        if filename:
            self._load_from_file(filename)

    def load_design(self, filename):
        design_vars = VspElement()
        vsp.ReadApplyDESFile(filename)
        for i in range(vsp.GetNumDesignVars()):
            param_id = vsp.GetDesignVar(i)
            if param_id in self.__param_map:
                param = self.__param_map[param_id]
            else:
                param = self._make_parameter(param_id)
            design_vars[param.name] = param
        self.design = design_vars

    def _make_parameter(self, param_id):
        kind = vsp.GetParmType(param_id)
        if kind < len(ParamType):
            kind = ParamType(kind)
        param = VspElement(_id=param_id,
                           name=vsp.GetParmName(param_id),
                           kind=kind,
                           value=vsp.GetParmVal(param_id),
                           lower=vsp.GetParmLowerLimit(param_id),
                           upper=vsp.GetParmUpperLimit(param_id),
                           )
        self.__param_map[param_id] = param
        return param

    @staticmethod
    def _update_list(lst, idx):
        idx = int(idx)
        if len(lst) <= idx:
            lst.extend([None] * (1 + idx - len(lst)))
        if lst[idx] is None:
            lst[idx] = VspElement()
        return lst, lst[idx]

    def _load_from_file(self, filename):
        vsp.ClearVSPModel()
        vsp.ReadVSPFile(filename)

        for geom_id in vsp.FindGeoms():
            geom_name_raw = vsp.GetGeomName(geom_id)
            geom_name, geom_idx = regex_listname.findall(geom_name_raw)[0]

            if geom_name not in self:
                if geom_idx:
                    self[geom_name] = []
                else:
                    self[geom_name] = VspElement()

            if geom_idx != '':
                geom = self._update_list(self[geom_name], geom_idx)
            else:
                geom = self[geom_name]

            geom._id = geom_id

            for param_id in vsp.GetGeomParmIDs(geom_id):
                group_name_raw = vsp.GetParmDisplayGroupName(param_id)
                group_name, group_idx = regex_listname.findall(group_name_raw)[0]
                if group_name not in EXCLUDE_GROUPS:
                    if group_name not in geom:
                        if group_idx:
                            geom[group_name] = []
                        else:
                            geom[group_name] = VspElement()

                    if group_idx != '':
                        geom[group_name], group = self._update_list(geom[group_name], group_idx)
                    else:
                        group = geom[group_name]

                    param = self._make_parameter(param_id)

                    if param['name'] in group:
                        raise ValueError("{} already in <{}:{}>".format(param.name, geom_name, group_name))

                    group[param['name']] = param

    def export(self, filename=None, vsp_set=0, file_format=ExportCode.EXPORT_STL):
        if filename is None:
            # TODO: map extension to file_format
            filename = self.__filename.split('.')[0] + '.stl'
        if isinstance(file_format, ExportCode):
            file_format = file_format.value
        vsp.ExportFile(filename, vsp_set, file_format)

    @property
    def threejs_data(self):
        if '__stl_filename' not in self:
            self.__stl_filename = '_tmp_threejs.stl'
        self.export(filename=self.__stl_filename, file_format=ExportCode.EXPORT_STL.value)
        # read in STL file
        with open(self.__stl_filename) as stl_file:
            stl_data = stl_file.read()

        return dumps([{"id": 2, "polyData": stl_data, "x": 0.0, "y": 0.0, "z": 0.0}])

    @property
    def wetted_areas(self):
        vsp.DeleteAllResults()
        results = {}
        _ = vsp.ComputeCompGeom(0, False, 0)
        result_id = vsp.FindLatestResultsID('Comp_Geom')
        components = vsp.GetStringResults(result_id, 'Comp_Name')
        wetted_areas = vsp.GetDoubleResults(result_id, 'Wet_Area')
        for comp, area in zip(components, wetted_areas):
            results[comp] = area

        results['total'] = sum(wetted_areas)
        return results

    def get_analysis_list(self):
        pass
        for a in vsp.ListAnalysis():
            pass
            print('For ', a)
            print(vsp.GetAnalysisInputNames(a))

    def get_analysis_names(self):
        pass
        print(vsp.GetNumAnalysis())

    def h(self, type='ParasiteDrag', unit='Total_CD_Total'):
        pass
        '''
        run a simulation, and return a specific value associated with the simulation
        '''
        id = vsp.ExecAnalysis(type)
        data = vsp.GetAllDataNames(id)
        results = vsp.GetDoubleResults(id, unit)[0]
        return results

    def set_param(self, id, value):
        pass
        '''
        used to set a specific parameter's value
        '''
        vsp.SetParmVal(id, value)

    def get_param(self, id):
        pass
        '''
        used to obtain a value from a parameter
        '''

    def save_file(self, filename=None):
        pass
        '''
        used to save any changes made. Saves to the same file by default
        '''
        if filename:
            pass
            vsp.WriteVSPFile(filename)
        else:
            pass
            vsp.WriteVSPFile(self.__filename)


# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""Command line tool to perform actions on jupyter notebooks."""
import logging
import os
import subprocess
import sys
import tarfile
import time
from pathlib import Path
import click
from gammapy.utils.scripts import get_images_paths, get_notebooks_paths

log = logging.getLogger(__name__)

OFF = ["GAMMA_CAT", "GAMMAPY_DATA", "GAMMAPY_EXTRA", "GAMMAPY_FERMI_LAT_DATA"]
PATH_DOCS = Path(__file__).resolve().parent / ".." / ".." / "docs"

@click.command(name="run")
@click.pass_context
@click.option(
    "--tutor",
    is_flag=True,
    default=False,
    help="Tutorials environment?",
    show_default=True,
)
@click.option("--kernel", default="python3", help="Kernel name", show_default=True)
def cli_jupyter_run(ctx, tutor, kernel):
    """Execute Jupyter notebooks."""
    with environment(OFF, tutor, ctx):
        for path in ctx.obj["paths"]:
            notebook_run(path, kernel)

def execute_notebook(path, kernel="python3", loglevel=30):
    """Execute a Jupyter notebook."""
    cmd = [
        sys.executable,
        "-m",
        "jupyter",
        "nbconvert",
        "--allow-errors",
        f"--log-level={loglevel}",
        "--ExecutePreprocessor.timeout=None",
        f"--ExecutePreprocessor.kernel_name={kernel}",
        "--to",
        "notebook",
        "--inplace",
        "--execute",
        f"{path}",
    ]
    t = time.time()
    completed_process = subprocess.run(cmd)
    t = time.time() - t
    if completed_process.returncode:
        log.error(f"Error executing notebook: {path.name} in {path.parent}")
        return False
    else:
        log.info(f"   ... DURATION {path.name}: {t:.1f} seconds")
        return True

@click.command(name="strip")
@click.pass_context
def cli_jupyter_strip(ctx):
    """Strip output cells."""
    import nbformat

    for path in ctx.obj["paths"]:
        rawnb = nbformat.read(str(path), as_version=nbformat.NO_CONVERT)

        rawnb["metadata"].pop("pycharm", None)

        for cell in rawnb.cells:
            if cell["cell_type"] == "code":
                cell["metadata"].pop("pycharm", None)
                cell["metadata"].pop("execution", None)
                cell["execution_count"] = None
                cell["outputs"] = []

        nbformat.write(rawnb, str(path))
        log.info(f"Strip output cells in notebook: {path}")

@click.command(name="black")
@click.pass_context
def cli_jupyter_black(ctx):
    """Format code cells with black."""
    import nbformat

    for path in ctx.obj["paths"]:
        rawnb = nbformat.read(str(path), as_version=nbformat.NO_CONVERT)
        blacknb = BlackNotebook(rawnb)
        blacknb.blackformat()
        rawnb = blacknb.rawnb
        nbformat.write(rawnb, str(path))
        log.info(f"Applied black to notebook: {path}")

class BlackNotebook:
    """Manage the process of black formatting.
    Probably this will become available directly in the future.
    See https://github.com/ambv/black/issues/298#issuecomment-476960082
    """

    MAGIC_TAG = "###-MAGIC TAG-"

    def __init__(self, rawnb):
        self.rawnb = rawnb

    def blackformat(self):
        """Format code cells."""
        import black

        for cell in self.rawnb.cells:
            fmt = cell["source"]
            if cell["cell_type"] == "code":
                try:
                    fmt = "\n".join(self.tag_magics(fmt))
                    has_semicolon = fmt.endswith(";")
                    fmt = black.format_str(
                        src_contents=fmt, mode=black.FileMode(line_length=79)
                    ).rstrip()
                    if has_semicolon:
                        fmt += ";"
                except Exception as ex:
                    log.info(ex)
                fmt = fmt.replace(self.MAGIC_TAG, "")
            cell["source"] = fmt

    def tag_magics(self, cellcode):
        """Comment magic commands."""
        lines = cellcode.splitlines(False)
        for line in lines:
            if line.startswith("%") or line.startswith("!"):
                magic_line = self.MAGIC_TAG + line
                yield magic_line
            else:
                yield line

@click.command(name="test")
@click.pass_context
@click.option(
    "--tutor",
    is_flag=True,
    default=False,
    help="Tutorials environment?",
    show_default=True,
)
@click.option("--kernel", default="python3", help="Kernel name", show_default=True)
def cli_jupyter_test(ctx, tutor, kernel):
    """Check if Jupyter notebooks are broken."""
    with environment(OFF, tutor, ctx):
        for path in ctx.obj["paths"]:
            notebook_run(path, kernel)

def notebook_run(path, kernel="python3"):
    """Execute and parse a Jupyter notebook exposing broken cells."""
    import nbformat

    log.info(f"   ... EXECUTING: {path.name} in {path.parent}")
    passed = execute_notebook(path, kernel)
    rawnb = nbformat.read(str(path), as_version=nbformat.NO_CONVERT)
    report = ""

    for cell in rawnb.cells:
        if "outputs" in cell.keys():
            for output in cell["outputs"]:
                if output["output_type"] == "error":
                    passed = False
                    traceitems = ["--TRACEBACK: "]
                    for o in output["traceback"]:
                        traceitems.append(f"{o}")
                    traceback = "\n".join(traceitems)
                    infos = "\n\n{} in cell [{}]\n\n" "--SOURCE CODE: \n{}\n\n".format(
                        output["ename"], cell["execution_count"], cell["source"]
                    )
                    report = infos + traceback
                    break
        if not passed:
            break

    if passed:
        log.info(f"   ... PASSED {path.name}")
        return True
    else:
        log.info(f"   ... FAILED {path.name}")
        log.info(report)
        return False

class environment:
    """Helper for setting environmental variables."""

    def __init__(self, envs, tutor, ctx):
        self.envs = envs
        self.tutor = tutor
        self.ctx = ctx

    def __enter__(self):
        self.old = os.environ
        if self.tutor:
            for item in self.envs:
                if item in os.environ:
                    del os.environ[item]
                    log.info(f"Unsetting {item} environment variable.")
            abspath = self.ctx.obj["pathsrc"].absolute()
            datapath = abspath.parent / "datasets"
            if abspath.is_file():
                datapath = abspath.parent.parent / "datasets"
            os.environ["GAMMAPY_DATA"] = str(datapath)
            log.info(f"Setting GAMMAPY_DATA={datapath}")

    def __exit__(self, type, value, traceback):
        if self.tutor:
            os.environ = self.old
            log.info("Environment variables recovered.")

@click.command(name="tar")
@click.option(
    "--out",
    default="notebooks.tar",
    help="Path and filename for the tar file that will be created.",
    show_default=True,
)
def cli_jupyter_tar(out):
    """Create a tar file with the notebooks in docs."""

    tar_name = Path(out)
    tar_name.parent.mkdir(parents=True, exist_ok=True)

    with tarfile.open(tar_name, "w:") as tar:
        for name in get_notebooks_paths():
            path_tail = str(name).split(str(PATH_DOCS.resolve()))[1]
            tar.add(name, arcname=Path(path_tail))
        for img in get_images_paths():
            tar.add(img, arcname=Path("tutorials/images") / Path(img).name)
    log.info(f"{tar_name} file has been created.")


#!/usr/bin/env python2.7 -W ignore::DeprecationWarning
# -*- coding: utf-8 -*-
import os
import commands
from os.path import join, exists, isdir, dirname, basename, split
import shutil
from multiprocessing import Process
import pandas as pd
import nibabel as nib
import numpy as np
import yaml

from utils import tools
from utils import resources as rsc

def create_simset_simplepet_detector(params_file, output):

    with open(params_file, 'rb') as f:
        params = yaml.load(f.read(), Loader=yaml.FullLoader)

    energy_resolution = params.get("energy_resolution")

    new_file = open(output, "w")

    new_file.write(
        "ENUM detector_type = simple_pet \n\n" +
        "REAL    reference_energy_keV = 511.0 \n" +
        "REAL    energy_resolution_percentage = %s \n" % energy_resolution
        )

    new_file.close()

def create_stir_hs_from_detparams(params_file,output_file, create_projdata_bin, output_format="SimSET"):

    with open(params_file, 'rb') as f:
        params = yaml.load(f.read(), Loader=yaml.FullLoader)

    num_rings = params.get("num_rings")
    max_segment = params.get("max_segment")
    max_z = params.get("max_z")
    min_z = params.get("min_z")
    z_crystal_size = params.get("z_crystal_size")
    gap_size = (max_z-min_z-z_crystal_size*num_rings)/(num_rings-1)
    ring_spacing = z_crystal_size + gap_size

    max_td = params.get("max_td")
    min_td = params.get("min_td")
    td_bins = params.get("num_td_bins")
    bin_size = (max_td-min_td)/float(td_bins)
    matrix_size, ring_difference = generate_segments_lists_stir(num_rings, max_segment)

    if output_format=="SimSET":
        views_coordinate = 2
        axial_coordinate = 3
    else:
        views_coordinate = 3
        axial_coordinate = 2

    new_file = open(output_file, "w")
    new_file.write(
        "!INTERFILE  :=\n" +
        "!imaging modality := PT\n" +
        "name of data file := " + output_file[0:-2] + "s" + "\n" +
        "originating system := " + params.get("scanner_name") + "\n" +
        "!version of keys := STIR3.0\n" +
        "!GENERAL DATA :=\n" +
        "!GENERAL IMAGE DATA :=\n" +
        "!type of data := PET\n" +
        "imagedata byte order := LITTLEENDIAN\n" +
        "!PET STUDY (General) :=\n" +
        "!PET data type := Emission\n" +
        "applied corrections := {None}\n" +
        "!number format := float\n" +
        "!number of bytes per pixel := 4\n" +
        "number of dimensions := 4\n" +
        "matrix axis label [4] := segment\n"
        "!matrix size [4] := " + str(2*max_segment+1) + "\n" +
        "matrix axis label [" + str(views_coordinate) +"] := view\n"
        "!matrix size [" + str(views_coordinate) +"] :=" + str(params.get("num_aa_bins")) + "\n" +
        "matrix axis label ["+ str(axial_coordinate) +"] := axial coordinate\n" +
        "!matrix size [" + str(axial_coordinate) + "] := " + matrix_size + "\n" +
        "matrix axis label [1] := tangential coordinate\n" +
        "!matrix size [1] :=" + str(td_bins) + "\n" +
        "minimum ring difference per segment := " + ring_difference + "\n" +
        "maximum ring difference per segment := " + ring_difference + "\n" +
        "Scanner parameters:= \n" +
        "Scanner type := " + params.get("scanner_name") + "\n" +
        "Number of rings := " + str(num_rings) + "\n" +
        "Number of detectors per ring := " + str(params.get("num_aa_bins")*2) + "\n" +
        "Inner ring diameter (cm) := " + str(params.get("radio_scanner")*2) + "\n" +
        "Average depth of interaction (cm) := " + str(params.get("average_doi")) + "\n" +
        "Distance between rings (cm) := " + str(ring_spacing) + "\n" +
        "Default bin size (cm) := " + str(bin_size) + "\n" +
        "View offset (degrees) := 0\n" +
        "Maximum number of non-arc-corrected bins := " + str(td_bins) + "\n" +
        "Default number of arc-corrected bins := " + str(td_bins) + "\n" +
        "Energy_resolution := " + str(params.get("energy_resolution")*5.11) + "\n" +
        "Reference energy (in keV) := 511\n" +
        "Number of blocks per bucket in transaxial direction := 1\n" +
        "Number of blocks per bucket in axial direction := 1\n" +
        "Number of crystals per block in axial direction := 1\n" +
        "Number of crystals per block in transaxial direction := 1\n" +
        "Number of crystals per singles unit in axial direction := 1\n" +
        "Number of crystals per singles unit in transaxial direction := 1\n" +
        "end scanner parameters:=\n" +
        "effective central bin size (cm) := " + str(bin_size) + "\n" +
        "number of time frames := 1\n" +
        "start vertical bed position (mm) := 0\n" +
        "start horizontal bed position (mm) := 0\n" +
        "!END OF INTERFILE :=\n"
        )

def generate_segments_lists_stir(nrings, max_segment):

    last_segment_sinograms = nrings-max_segment
    my_matrix_size = " "
    my_matrix_ring_difference = " "
    for i in range(last_segment_sinograms, nrings):
        my_matrix_size = my_matrix_size + str(i) + ","
        my_matrix_ring_difference = my_matrix_ring_difference + str(i-nrings) + ","
    for i in range(nrings, last_segment_sinograms-1,-1):
        my_matrix_size = my_matrix_size + str(i) + ","
        my_matrix_ring_difference = my_matrix_ring_difference + str(nrings-i) + ","

    my_matrix_size = "{" + my_matrix_size [0:-1] + "}"
    my_matrix_ring_difference = "{" + my_matrix_ring_difference [0:-1] + "}"

    return my_matrix_size, my_matrix_ring_difference


from smac.env import StarCraft2Env
import numpy as np
import random
import pickle
import matplotlib.pyplot as plt
from tqdm import tqdm

def choose_action(states, possible_ja):
    if random.uniform(0, 1) < (1 - epsilon):
        action = np.random.choice(possible_ja)
    else:
        qt_arr1 = np.zeros(len(possible_ja))
        qt_arr2 = np.zeros(len(possible_ja))

        keys = np.arange(len(possible_ja))
        act_ind_decode = dict(zip(keys, possible_ja))

        for act_ind in range(len(possible_ja)):
            qt_arr1[act_ind] = q_table[states[0], act_ind_decode[act_ind]]
            qt_arr2[act_ind] = q_table[states[1], act_ind_decode[act_ind]]

        action1 = act_ind_decode[np.argmax(qt_arr1)]
        q_value1 = max(qt_arr1)

        action2 = act_ind_decode[np.argmax(qt_arr2)]
        q_value2 = max(qt_arr2)

        if q_value1 > q_value2:
            action = action1
        else:
            action = action2

    return action

def learn(state, state2, reward, action):
    q_table[state, action] = q_table[state, action] + alpha * \
                             (reward + gamma * np.max(q_table[state2, :]) - q_table[state, action])

def my_get_state(agent_id):
    unit = env.get_unit_by_id(agent_id)
    target_items = env.enemies.items()
    shoot_range = env.unit_shoot_range(agent_id)
    can_attack = False

    for t_id, t_unit in target_items:
        if t_unit.health > 0:
            dist = env.distance(
                unit.pos.x, unit.pos.y, t_unit.pos.x, t_unit.pos.y
            )
            if dist <= shoot_range:
                can_attack = True

    if not can_attack:
        state = (unit.pos.x - map_size[0]) * env_states_range[1] + (unit.pos.y - map_size[2])
    else:
        state = (unit.pos.x - map_size[0]) * env_states_range[1] + (unit.pos.y - map_size[2]) + \
                n_states // 2 - 1

    if state > q_table.shape[0] - 1:
        print('Agent position when out of bounds with state', unit.pos.x, unit.pos.y, state)
        state = q_table.shape[0] - 1

    return int(state)

def jal_encoder(action1, action2):
    return action1 * n_actions + action2

def jal_decoder(action):
    return [action // n_actions, action % n_actions]

def avail_joint_actions(avail_actions_array):
    """
    Takes array of shape [[agent0_avail_actions], [agent1_avail_actions]]

    Returns all available joint actions
    """

    if avail_actions_array[0][0] == 0:
        return avail_actions_array[1]

    if avail_actions_array[1][0] == 0:
        return avail_actions_array[0] * n_actions

    all_actions = []

    for agent0_act in range(len(avail_actions_array[0])):
        for agent1_act in range(len(avail_actions_array[1])):
            all_actions.append(jal_encoder(avail_actions_array[0][agent0_act],
                                           avail_actions_array[1][agent1_act]))
    return all_actions

method_name = "JAL"
env = StarCraft2Env(map_name="2m_vs_2zg")
env_info = env.get_env_info()

map_size = (8, 24, 25, 28)  # x1, x2, y1, y2
env_states_range = (map_size[1] - map_size[0], map_size[3] - map_size[2])
n_actions = env_info["n_actions"]
n_agents = env_info["n_agents"]
episode_limit = env_info["episode_limit"]

n_episodes = 10_200
n_states = env_states_range[0] * env_states_range[1] * 2

alpha = 0.2
gamma = 0.95
EPSILON = 0.6
q_table = np.zeros([n_states, n_actions * n_actions])

epsilon_values = []
total_steps = []
ep_reward = []
mean_total_steps = []
mean_ep_reward = []
ep_reward_agent1 = []
ep_reward_agent2 = []
mean_ep_reward_agent1 = []
mean_ep_reward_agent2 = []

epsilon = EPSILON

for e in tqdm(range(1, n_episodes + 1), ascii=True, unit="episode"):
    env.reset()
    terminated = False
    episode_reward = 0
    episode_reward1 = 0
    episode_reward2 = 0
    n_steps = 1

    if e < 500:
        epsilon = EPSILON
    elif e < 2000:
        epsilon += ((1 - epsilon) ** 0.5) * 0.8 / 1000
    elif e < 3000:
        epsilon -= ((1 - epsilon) ** 0.5) * 1.03 / 1000
    elif e < 3500:
        epsilon = EPSILON + 0.1
    elif e < 5000:
        epsilon += ((1 - epsilon) ** 0.5) * 0.7 / 1000
    elif e < 6000:
        epsilon -= ((1 - epsilon) ** 0.5) * 0.85 / 1000
    elif e < 6500:
        epsilon = EPSILON + 0.2
    elif e < 8000:
        epsilon += ((1 - epsilon) ** 0.5) * 0.58 / 1000
    elif e < 8500:
        epsilon -= ((1 - epsilon) ** 0.5) * 1.2 / 1000
    elif e < 9000:
        epsilon = EPSILON + 0.3
    elif e < 10000:
        epsilon += ((1 - epsilon) ** 0.5) * 0.6 / 1000
    else:
        epsilon = 1

    while not terminated:
        states = []
        all_avail_actions = []
        next_states = []
        actions = []
        rewards = []

        for agent_id in range(n_agents):
            state = my_get_state(agent_id)
            states.append(state)

            avail_actions = env.get_avail_agent_actions(agent_id)
            avail_actions[1] = 0
            avail_actions_ind = np.nonzero(avail_actions)[0]
            all_avail_actions.append(avail_actions_ind)

        possible_joint_actions = avail_joint_actions(all_avail_actions)

        joint_action = choose_action(states, possible_joint_actions)

        actions_pair = jal_decoder(joint_action)

        for agent_id in range(n_agents):
            action = actions_pair[agent_id]
            if action > 5:
                rewards.append(10)
            else:
                rewards.append(-2)
            actions.append(action)

        _, terminated, _ = env.step(actions)

        for i in range(len(rewards)):
            rewards[i] = rewards[i] * ((episode_limit - n_steps + 50) / episode_limit) ** 6

        for agent_id in range(n_agents):
            next_state = my_get_state(agent_id)
            next_states.append(next_state)

        for agent_id in range(n_agents):
            learn(states[agent_id], next_states[agent_id], sum(rewards), joint_action)

            if (states[0] == states[1]) and (next_states[0] == next_states[1]):
                break

        episode_reward1 += rewards[0]
        episode_reward2 += rewards[1]
        episode_reward += sum(rewards)
        n_steps += 1

    ep_reward.append(episode_reward)
    total_steps.append(n_steps)
    ep_reward_agent1.append(episode_reward1)
    ep_reward_agent2.append(episode_reward2)

    if not e % 10:
        epsilon_values.append(epsilon)
        mean_ep_reward.append(np.mean(ep_reward[-10:]))
        mean_total_steps.append(np.mean(total_steps[-10:]))
        mean_ep_reward_agent1.append(np.mean(ep_reward_agent1[-10:]))
        mean_ep_reward_agent2.append(np.mean(ep_reward_agent2[-10:]))

    if (not e % 100) and (e != 0):
        with open(f'2v2_jal_ep{e}.pkl', 'wb') as f:
            pickle.dump(q_table, f)

    game_stats = env.get_stats()
    print()
    print('Episode ', e)
    print('Steps: {}   Reward: {}'.format(n_steps, round(episode_reward, 3)))
    print('Won: {}    Played: {}    Win rate: {}'.format(game_stats['battles_won'],
                                                         game_stats['battles_game'],
                                                         round(game_stats['win_rate'], 3)))

with open("2v2_jal_final.pkl", 'wb') as f:
    pickle.dump(q_table, f)

x = np.linspace(0, n_episodes, n_episodes // 10)

with open(f"{method_name}_plot_mean_ep_reward_agent1", 'wb') as f:
    pickle.dump(mean_ep_reward_agent1, f)

with open(f"{method_name}_plot_mean_ep_reward_agent2", 'wb') as f:
    pickle.dump(mean_ep_reward_agent2, f)

with open(f"{method_name}_plot_mean_ep_reward", 'wb') as f:
    pickle.dump(mean_ep_reward, f)

with open(f"{method_name}_plot_mean_total_steps", 'wb') as f:
    pickle.dump(mean_total_steps, f)

with open(f"{method_name}_plot_x", 'wb') as f:
    pickle.dump(x, f)

fig, ax = plt.subplots(1, 3)
ax1, ax2, ax3 = ax.flatten()

ax1.plot(x, epsilon_values)
ax1.set_title('Epsilon')
ax2.plot(x, mean_ep_reward)
ax2.set_title('Rewards')
ax3.plot(x, mean_total_steps)
ax3.set_title('Steps')
fig.set_size_inches(15, 4)
fig.subplots_adjust(hspace=0.2, wspace=0.2)
plt.show()

env.close()


import pytest

from .....checkout import calculations
from .....checkout.utils import add_variant_to_checkout
from .....payment import ChargeStatus, TransactionKind
from .....payment.models import Payment

@pytest.fixture
def customer_checkout(customer_user, checkout_with_voucher_percentage_and_shipping):
    checkout_with_voucher_percentage_and_shipping.user = customer_user
    checkout_with_voucher_percentage_and_shipping.save()
    return checkout_with_voucher_percentage_and_shipping

@pytest.fixture()
def checkout_with_variant(checkout, stock):
    variant = stock.product_variant
    add_variant_to_checkout(checkout, variant, 1)

    checkout.save()
    return checkout

@pytest.fixture()
def checkout_with_shipping_address(checkout_with_variant, address):
    checkout = checkout_with_variant

    checkout.shipping_address = address.get_copy()
    checkout.save()

    return checkout

@pytest.fixture()
def checkout_with_shipping_method(checkout_with_shipping_address, shipping_method):
    checkout = checkout_with_shipping_address

    checkout.shipping_method = shipping_method
    checkout.save()

    return checkout

@pytest.fixture()
def checkout_with_billing_address(checkout_with_shipping_method, address):
    checkout = checkout_with_shipping_method

    checkout.billing_address = address
    checkout.save()

    return checkout

@pytest.fixture()
def checkout_with_charged_payment(checkout_with_billing_address):
    checkout = checkout_with_billing_address

    taxed_total = calculations.checkout_total(checkout=checkout, lines=list(checkout))
    payment = Payment.objects.create(
        gateway="mirumee.payments.dummy",
        is_active=True,
        total=taxed_total.gross.amount,
        currency="USD",
    )

    payment.charge_status = ChargeStatus.FULLY_CHARGED
    payment.captured_amount = payment.total
    payment.checkout = checkout_with_billing_address
    payment.save()

    payment.transactions.create(
        amount=payment.total,
        kind=TransactionKind.CAPTURE,
        gateway_response={},
        is_success=True,
    )

    return checkout


# uncompyle6 version 3.7.4
# Python bytecode 2.6 (62161)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /usr/local/lib/python2.6/dist-packages/vision/visualize.py
# Compiled at: 2011-01-26 16:25:37
import ImageDraw, itertools, random
defaultwidth = 2
colors = ['#FF00FF',
 '#FF0000',
 '#FF8000',
 '#FFD100',
 '#008000',
 '#0080FF',
 '#0000FF',
 '#000080',
 '#800080']

def highlight_box(image, box, color=colors[0], width=defaultwidth):
    """
    Highlights the bounding box on the given image.
    """
    draw = ImageDraw.Draw(image)
    for i in range(width):
        draw.rectangle((box[0] + i, box[1] + i, box[2] - i, box[3] - i), outline=color)

    return image

def highlight_boxes(image, boxes, colors=colors, width=defaultwidth):
    """
    Highlights an iterable of boxes.
    """
    for (box, color) in zip(boxes, itertools.cycle(colors)):
        highlight_box(image, box, color, width)

    return image

def highlight_path(images, path, color=colors[0], width=defaultwidth):
    """
    Highlights a path across many images. The images must be indexable
    by the frame. Produces a generator.
    """
    for box in path:
        try:
            lost = box.lost
        except:
            lost = False

        if not lost:
            image = images[box.frame]
            highlight_box(image, box, color, width)
            yield (image, box.frame)

def highlight_paths(images, paths, colors=colors, width=defaultwidth):
    """
    Highlights multiple paths across many images. The images must be indexable
    by the frame. Produces a generator.
    """
    boxmap = {}
    paths = zip(paths, itertools.cycle(colors))
    for (path, color) in paths:
        for box in path:
            if box.frame not in boxmap:
                boxmap[box.frame] = [
                 (
                  box, color)]
            else:
                boxmap[box.frame].append((box, color))

    for (frame, boxes) in sorted(boxmap.items()):
        im = images[frame]
        for (box, color) in boxes:
            try:
                lost = box.lost
            except:
                lost = False

            if not lost:
                highlight_box(im, box, color, width)

        yield (
         im, frame)

def save(images, output):
    """
    Saves images produced by the path iterators.
    """
    for (image, frame) in images:
        image.save(output(frame))


import logging
import datetime
from itertools import combinations

from django.db.models import Count
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy

from draw.models import Debate
from tournaments.utils import get_side_name

logger = logging.getLogger(__name__)

def graphable_debate_statuses(ballots, round):
    # For each debate, find (a) the first non-discarded submission time, and
    # (b) the last confirmed confirmation time. (Note that this means when
    # a ballot is discarded, the graph will change retrospectively.)
    total_debates = round.debate_set.count()

    # These two dictionaries record when a particular debate was first
    # entered or drafted. These can then be compared to given time intervals
    drafts = {}
    confirmations = {}
    for ballot in ballots:
        d_id = ballot.debate_id
        if ballot.timestamp and (d_id not in drafts or drafts[d_id] > ballot.timestamp):
            drafts[d_id] = ballot.timestamp
        if ballot.confirmed and ballot.confirm_timestamp and (d_id not in confirmations or
                confirmations[d_id] < ballot.confirm_timestamp):
            confirmations[d_id] = ballot.confirm_timestamp

    # Collate timestamps into a single list.
    timestamps = [t for t in drafts.values()] + [t for t in confirmations.values()]
    if len(timestamps) == 0:
        return []
    timestamps = sorted(timestamps) # Order by time

    # Create the spaced intervals
    intervals = 20 # IE numbner of bars on the graph
    start_of_entry = timestamps[0]
    end_of_entry = timestamps[-1]
    time_span = end_of_entry - start_of_entry
    minutes_span_interval = (time_span.total_seconds() / 60.0) / intervals

    intervals_with_stats = []
    for i in range(0, intervals):
        delta = (i * minutes_span_interval) + minutes_span_interval
        interval_time = start_of_entry + datetime.timedelta(minutes=delta)

        # Count up the number of drafts at this point by reviewing timestamps
        interval_stat = {"time": interval_time.isoformat(),
                         "total": total_debates,
                         "none": total_debates, "draft": 0, "confirmed": 0}

        # Count up the number of confirms/drafts at this point
        recorded_ids = []
        for dID, timestamp in confirmations.items():
            if timestamp <= interval_time:
                interval_stat['confirmed'] += 1
                interval_stat['none'] -= 1
                recorded_ids.append(dID)

        for dID, timestamp in drafts.items():
            if dID not in recorded_ids:
                if drafts[dID] <= interval_time:
                    interval_stat['draft'] += 1
                    interval_stat['none'] -= 1

        intervals_with_stats.append(interval_stat)

    return intervals_with_stats

def readable_ballotsub_result(ballotsub):
    """ Make a human-readable representation of a debate result """

    def format_dt(dt, t):
        # Translators: e.g. "{Melbourne 1} as {OG}", "{Cape Town 1} as {CO}"
        return _("%(team_name)s as %(side_abbr)s") % {
            'team_name': dt.team.short_name,
            'side_abbr': dt.get_side_name(t, 'abbr')
        }

    t = ballotsub.debate.round.tournament
    team_scores = ballotsub.teamscore_set.all()

    try:
        if t.pref('teams_in_debate') == 'two':
            winner = None
            loser = None
            for teamscore in team_scores:
                if teamscore.win:
                    winner = teamscore.debate_team
                else:
                    loser = teamscore.debate_team

            result_winner = _("%(winner)s (%(winner_side)s) won")
            result_winner = result_winner % {
                'winner': winner.team.short_name,
                'winner_side': winner.get_side_name(t, 'abbr'),
            }
            result = _("vs %(loser)s (%(loser_side)s)")
            result = result % {
                'loser': loser.team.short_name,
                'loser_side': loser.get_side_name(t, 'abbr'),
            }

        elif ballotsub.debate.round.is_break_round:
            advancing = []
            eliminated = []
            for teamscore in team_scores:
                if teamscore.win:
                    advancing.append(teamscore.debate_team)
                else:
                    eliminated.append(teamscore.debate_team)

            result_winner = _("Advancing: %(advancing_list)s
\n")
            result_winner = result_winner % {
                'advancing_list': ", ".join(format_dt(dt, t) for dt in advancing)
            }
            result = _("Eliminated: %(eliminated_list)s")
            result = result % {
                'eliminated_list': ", ".join(format_dt(dt, t) for dt in eliminated),
            }

        else:  # BP preliminary round
            ordered = [None] * 4
            for teamscore in team_scores:
                ordered[teamscore.points] = teamscore.debate_team

            result_winner = _("1st: %(first_team)s
\n")
            result_winner = result_winner % {'first_team':  format_dt(ordered[3], t)}
            result = _("2nd: %(second_team)s
\n"
                       "3rd: %(third_team)s
\n"
                       "4th: %(fourth_team)s")
            result = result % {
                'second_team': format_dt(ordered[2], t),
                'third_team':  format_dt(ordered[1], t),
                'fourth_team': format_dt(ordered[0], t),
            }

    except (IndexError, AttributeError):
        logger.warning("Error constructing latest result string", exc_info=True)
        result_winner = _("Error with result for %(debate)s") % {'debate': ballotsub.debate.matchup}
        result = ""

    return result_winner, result

def set_float_or_int(number, step_value):
    """Used to ensure the values sent through to the frontend <input> are
    either Ints or Floats such that the validation can handle them properly"""
    if step_value.is_integer():
        return int(number)
    else:
        return number

def get_result_status_stats(round):
    """Returns a dict where keys are result statuses of debates; values are the
    number of debates in the round with that status.

    There is also an additional key 'B' that denotes those with ballots checked
    in, but whose results are not entered."""

    # query looks like: [{'result_status': 'C', 'result_status__count': 8}, ...]
    query = round.debate_set.values('result_status').annotate(Count('result_status')).order_by()

    # The query doesn't return zeroes where appropriate - for statuses with no
    # debates, it just omits the item altogether. So initialize a dict:
    choices = [code for code, name in Debate.STATUS_CHOICES]
    stats = dict.fromkeys(choices, 0)
    for item in query:
        stats[item['result_status']] = item['result_status__count']

    return stats

def populate_identical_ballotsub_lists(ballotsubs):
    """Sets an attribute `identical_ballotsub_versions` on each BallotSubmission
    in `ballotsubs` to a list of version numbers of the other BallotSubmissions
    that are identical to it.

    Two ballot submissions are identical if they share the same debate, motion,
    speakers and all speaker scores."""

    from .prefetch import populate_results
    populate_results(ballotsubs)

    for ballotsub in ballotsubs:
        ballotsub.identical_ballotsub_versions = []

    for ballotsub1, ballotsub2 in combinations(ballotsubs, 2):
        if ballotsub1.result.identical(ballotsub2.result):
            ballotsub1.identical_ballotsub_versions.append(ballotsub2.version)
            ballotsub2.identical_ballotsub_versions.append(ballotsub1.version)

    for ballotsub in ballotsubs:
        ballotsub.identical_ballotsub_versions.sort()

_ORDINALS = {
    1: gettext_lazy("1st"),
    2: gettext_lazy("2nd"),
    3: gettext_lazy("3rd"),
    4: gettext_lazy("4th"),
    5: gettext_lazy("5th"),
    6: gettext_lazy("6th"),
    7: gettext_lazy("7th"),
    8: gettext_lazy("8th"),
}

_BP_POSITION_NAMES = [
    # Translators: Abbreviation for Prime Minister
    [gettext_lazy("PM"),
    # Translators: Abbreviation for Deputy Prime Minister
     gettext_lazy("DPM")],
    # Translators: Abbreviation for Leader of the Opposition
    [gettext_lazy("LO"),
    # Translators: Abbreviation for Deputy Leader of the Opposition
     gettext_lazy("DLO")],
    # Translators: Abbreviation for Member for the Government
    [gettext_lazy("MG"),
    # Translators: Abbreviation for Government Whip
     gettext_lazy("GW")],
    # Translators: Abbreviation for Member for the Opposition
    [gettext_lazy("MO"),
    # Translators: Abbreviation for Opposition Whip
     gettext_lazy("OW")]
]

def side_and_position_names(tournament):
    """Yields 2-tuples (side, positions), where position is a list of position
    names, all being translated human-readable names. This should eventually
    be extended to return an appropriate list for the tournament configuration.
    """
    sides = [get_side_name(tournament, side, 'full').title() for side in tournament.sides]

    if tournament.pref('teams_in_debate') == 'bp' \
            and tournament.last_substantive_position == 2 \
            and tournament.reply_position is None:

        for side, positions in zip(sides, _BP_POSITION_NAMES):
            yield side, positions

    else:
        for side in sides:
            positions = [_("Reply") if pos == tournament.reply_position
                else _ORDINALS[pos]
                for pos in tournament.positions]
            yield side, positions


# coding: utf-8

# In[126]:

from graphviz import Digraph
import tempfile
import collections, sys
from Bio import Seq, SeqIO, SeqRecord
from copy import deepcopy

# In[127]:

def read_data(filename):
    seq = []
    reads = SeqIO.parse(filename,'fastq')
    for read in reads:
        seq_s = str(read.seq)
        seq_l = seq_s.split('N')
        seq.append(seq_s)
    return seq

# In[128]:

def dummy_data():
    return ["ACGTCCGTAA"]

# In[129]:

def build_graph(nodeA, nodeB, edges_dict, edges_data, has_parent_nodes, has_child_nodes, child_dict, parent_dict):

    if nodeA in edges_dict:
        edges_dict[nodeA].add(nodeB)
    else:
        edges_dict[nodeA] = set([nodeB])

    data_key = (nodeA, nodeB)
    if data_key in edges_data:
        data = edges_data[data_key]
        data[0] += 1
        edges_data[data_key] = data
    else:
        edges_data[data_key] = [1.0, 1.0]

    has_parent_nodes.add(nodeB)
    has_child_nodes.add(nodeA)
    if nodeA in child_dict:
        child_dict[nodeA].add(nodeB)
    else:
        child_dict[nodeA] = set([nodeB])
    if nodeB in parent_dict:
        parent_dict[nodeB].add(nodeA)
    else:
        parent_dict[nodeB] = set([nodeA])

# In[130]:

def run_de_bruijn(k, seq, nodes, edges_dict, edges_data, has_parent_nodes, has_child_nodes, child_dict, parent_dict):
    for reading in seq:
        for i in range(len(reading) - k + 1):
            nodeA = reading[i:i+k-1]
            nodeB = reading[i+1:i+k]
            nodes.add(nodeA)
            nodes.add(nodeB)
            build_graph(nodeA, nodeB, edges_dict, edges_data, has_parent_nodes, has_child_nodes, child_dict, parent_dict)

# In[131]:

def show_graph(edges_data, name, should_save = False):
    dot = Digraph(comment=name)
    dot.graph_attr['rankdir'] = 'LR'
    for edge, data in edges_data.items():
        label_value = str(data[0]) + ", " + str(data[1])
        dot.edge(edge[0], edge[1], label=label_value)
    dot.view(tempfile.mktemp('.gv'))
    if should_save:
        filename = name + ".gv"
        dot.render(filename, view=False)

# In[169]:

def save_graph(edges_data, name):
    dot = Digraph(comment=name)
    dot.graph_attr['rankdir'] = 'LR'
    for edge, data in edges_data.items():
        label_value = str(data[0]) + ", " + str(data[1])
        dot.edge(edge[0], edge[1], label=label_value)
    file_name = name + "-graph.dot"
    dot.save(filename=file_name)
    dot.render(file_name, view=False)
    print("Result saved as: " + str(file_name))

# In[170]:

def save_edges(edges_data, name):
    file_name = name + "-edges.fastq"
    with open(file_name, 'w') as file:
        for edge, data in edges_data.items():
            line = edge[0] + ", " + edge[1] + "\n"
            file.write(line)
    print("Edges saved as: " + str(file_name))

# In[133]:

def is_condense(child, child_dict, parent_dict):
    return child in child_dict and len(child_dict[child]) == 1 and child in parent_dict and len(parent_dict[child]) == 1

# In[134]:

def merge(head, end, merged, visited, edges_data, edges_dict, child_dict, parent_dict):
    nodes = [head] + merged + [end]
    visited.update(merged)

    length_sum = 0
    for i in range(len(nodes) - 1):
        edge_key = (nodes[i], nodes[i+1])
        if edge_key in edges_data:
            data = edges_data.pop(edge_key)
            length_sum += data[0]

    edges_data[(head, end)] = [1.0, length_sum / len(merged)]
    edges_dict[head].remove(merged[0])
    edges_dict[head].add(end)

    child_dict[head].remove(merged[0])
    child_dict[head].add(end)
    parent_dict[end].remove(merged[-1])
    parent_dict[end].add(head)

    for node in merged:
        edges_dict.pop(node)
        child_dict.pop(node)
        parent_dict.pop(node)

# In[135]:

def do_condense(nodes, edges_data, edges_dict, child_dict, parent_dict, has_parent_nodes):
    visited = set()
    to_be_visit = nodes - has_parent_nodes

    while (len(to_be_visit) != 0):
        node = to_be_visit.pop()
        if node in visited:
            continue;
        visited.add(node)
#         print("visiting: " + str(node))
        if node not in edges_dict:
#             print("reached end!")
            continue;
        childs = deepcopy(edges_dict[node])
        for child in childs:
#             print("child: " + str(child))
            if child in visited:
                continue
            should_merge = False
            to_be_merged = []
            while (is_condense(child, child_dict, parent_dict)):
#                 print("i am here")
                should_merge = True
                to_be_merged.append(child)
                child = list(child_dict[child])[0]
            if should_merge:
                head = node
                end = child
#                 print(to_be_merged)
                merge(head, end, to_be_merged, visited, edges_data, edges_dict, child_dict, parent_dict)
#             else:
#                 print("dont merge")
            to_be_visit.add(child)

# In[164]:

def main(seq, k, need_display=False, result_filename="test"):
    edges_dict = {}
    edges_data = {}
    edges = []
    nodes = set()
    parent_dict = {}
    has_parent_nodes = set()
    child_dict = {}
    has_child_nodes = set()

    print("Building De Bruijn Graph ...")
    run_de_bruijn(k, seq, nodes, edges_dict, edges_data, has_parent_nodes, has_child_nodes, child_dict, parent_dict)
    if need_display:
        show_graph(edges_data, "before")

    print("Condensing De Bruijn Graph ...")
    do_condense(nodes, edges_data, edges_dict, child_dict, parent_dict, has_parent_nodes)
    if need_display:
        show_graph(edges_data, "after")

    print("Saving Edges ...")
    save_edges(edges_data, result_filename)

    print("Saving Graph ...")
    save_graph(edges_data, result_filename)

# In[165]:

def run_simple_example():
    k = 3
    seq = dummy_data()
    main(seq, k, True)

# In[151]:

def run_real_data():
    k = 55
    seq = read_data("s_6.first100000.fastq")
    main(seq, k, False)

# In[152]:

def run():
    filename = sys.argv[1]
    k = int(sys.argv[2])
    print("Reading Data ...")
    seq = read_data(filename)
    main(seq, k, False, filename)

# In[167]:

# run_simple_example()

# In[168]:

# run_real_data()

# In[ ]:

if __name__ == "__main__":
    run()


import os
import json

fileName=os.listdir('./assets')

def getResources(fileName):
	resources=[]
	for x in fileName:
		arr=x.split('.')
		T='image'
		if arr[0][-2:]=='SS' and arr[1]=='json':
			T='sheet'
			arr[0]+='Sheet'
		elif arr[1]=='fnt':
			T='font'
			arr[0]+='Font'
		elif arr[1]=='json':
			T='json'
			arr[0]+='MC'

		d={'name':arr[0],'type':T,'url':'assets/'+x}
		resources.append(d)
	return resources

def getKeys(resources):
	keys=''
	for x in resources:
		keys+=x['name']+','
	return keys[0:-1]

jsonDict={'resources':getResources(fileName),'groups':[{'name':'preload','keys':getKeys(getResources(fileName))}]}
with open('resource.json','w') as f:
	f.write(json.dumps(jsonDict))

print ('ok')


from keras.preprocessing.image import img_to_array
from keras.models import load_model
import numpy as np
import argparse
import imutils
import pickle
import cv2
import os
import sys

def classify(modelPath,labelPath,count):
        if(count==0):
                modelPath = input("Where is the model?")
                labelPath = input("Where are the labels?")
                testImage = input("What image do you want to classify?")
        else:
                testImage = input("What image do you want to classify?")
        image = cv2.imread(testImage)
        output = image.copy()
        image = cv2.resize(image, (200, 200))
        image = image.astype("float") / 255.0
        image = img_to_array(image)
        image = np.expand_dims(image, axis=0)
        print("[INFO] loading network...")
        model = load_model(modelPath)
        lb = pickle.loads(open(labelPath, "rb").read())

        # classify the input image
        print("[INFO] classifying image...")
        proba = model.predict(image)[0]
        idx = np.argmax(proba)
        label = lb.classes_[idx-1]

        filename = testImage.split("/")[-2]
        correct = "correct" if filename.rfind(label) != -1 else "incorrect"

        # build the label and draw the label on the image
        label = "{}: {:.2f}% ({})".format(label, proba[idx] * 100, correct)
        output = imutils.resize(output, width=400)
        cv2.putText(output, label, (10, 25),  cv2.FONT_HERSHEY_SIMPLEX,0.7, (0, 255, 0), 2)
        if(correct=="incorrect"):
           print("[REAL] {}: {:.2f}%".format(filename,proba[int(filename)]*100))
        # show the output image
        print("[INFO] {}".format(label))
        cv2.imshow("Output", output)
        cv2.waitKey(0)
        cont = input("Do you have another image? y/n ")
        if(cont!='n'):
                classify(modelPath,labelPath,count+1)
        else:
                sys.exit(1)

classify('','',0)


8# -*- coding: utf-8 -*-
"""
Created on Tue 26 Feb 16:05:01 2019

@author: heyu1
"""

import numpy as np, pandas as pd
from collections import deque
import re, requests
from bs4 import BeautifulSoup
isCSVinput = False
WIKI_LEN = len("/wiki/")
while True:
    choice = input("Import search terms from a .CSV (Y/N)?: ")
    if re.match(re.compile("^([YN]|Yes|No)$", re.I), choice) != None:
        if re.match(re.compile("^Y$", re.I), choice[0]) != None:
            isCSVinput = True
        break

enWikiRoot="https://en.wikipedia.org/wiki/"
def hasArticle(searchTerm):
    if searchTerm.strip() == "":
        return False
    reqAttempt = requests.get(enWikiRoot + searchTerm)
    return(reqAttempt.status_code != 404)

def findActualTitleHelper(soupFromPage):
    linkTitles=soupFromPage.find_all('a', title=True)
    titleText=[elem['title'] for elem in linkTitles]
    hasPerm=[re.search(re.compile("Permanent link"),x) != None for
             x in titleText]
    idxPerm=np.where(hasPerm)
#    assert(len(idxPerm) == 1)
    if len(idxPerm[0]) != 1:
        return None
    permLinkSuffix = linkTitles[idxPerm[0][0]]['href']
    charIdxTitle = re.search(re.compile("title="), permLinkSuffix).end()
    charIdxOldid = re.search(re.compile("&oldid="), permLinkSuffix).start()
    return permLinkSuffix[charIdxTitle:charIdxOldid]

def findActualTitle(s):
    page = requests.get(enWikiRoot + s)
    soupFromPage = BeautifulSoup(page.text, 'html.parser')
    res = findActualTitleHelper(soupFromPage)
    if res == None:
        print("THE FOLLOWING HAD NO PERMANENT REVISION LINK:", s)
    return res

def linksOnPage(searchTerm):
    page = requests.get(enWikiRoot + searchTerm)
    soupFromPage = BeautifulSoup(page.text, 'html.parser')
    aTags=soupFromPage.find_all('a',href=True)
    hrefs=[elem['href'] for elem in aTags]
    wikiRe = re.compile("^/wiki/")
    # exclude non-mainspace article pages on Wiki, i.e. those with the
    # following prefixes:
    prefixes = ['User','Wikipedia','File','MediaWiki','Template','Help',
                'Category','Portal','Book','Draft','Education Program',
                'TimedText','Module','Gadget','Gadget definition']
    prefixTalk = [s + ' talk' for s in prefixes]
    prefixesComplete = prefixes + prefixTalk
    prefixesComplete += ['Special','Talk','MOS']
    pipe = "|"
    regexPrefixes = pipe.join(prefixesComplete)
    # also exclude the Main Page, which changes daily and will lead to
    # unstable results
    nonArticleRe = re.compile("^/wiki/((" + regexPrefixes +
                                        ":)|Main_Page)", re.I)

    articleLinks = list(filter(lambda x: re.search(wikiRe, x) != None and
                               re.search(nonArticleRe, x) == None, hrefs))
    # "/wiki/" is 6 characters
    articles = [lk[WIKI_LEN:] for lk in articleLinks]
    uniqueArticles = set(articles)

    thisSearchTermActualTitle = findActualTitleHelper(soupFromPage)
    if thisSearchTermActualTitle in uniqueArticles:
        uniqueArticles.remove(thisSearchTermActualTitle)
    res = dict(zip(list(uniqueArticles), ["Linked from " + searchTerm
                                    for s in uniqueArticles]))
    return res

# Reasoning adapted from Wikipedia's article on Breadth First Search
def bfs(originTerm, targetArticle, verbose=False):
    futureVertices = deque()
    visited = set()
    pathDict = dict()
    distDict = dict()
    root = originTerm
    # key stores the parent node
    pathDict[root] = None
    distDict[root] = 0
    maxDist = 0
    futureVertices.appendleft(root)
    levels = [1E4, 1E5, 2.5E5, 5E5, 1E6, 1.5E6, 2E6, 2.5E6]
#    pd.DataFrame({'levels': levels, 'visited'})
    attained_levels = set()
#    b10K = False; b100K = False; b250K = False; b500K = False; b1M = False
    while len(futureVertices) > 0:
        subtreeRoot = futureVertices.pop()
        if verbose:
            for size_level in levels:
                if not(size_level in attained_levels) and len(
                        pathDict) >= size_level:
                    print("Built up", str(size_level), "entries in path",
                          "dictionary, having visited", str(len(visited)),
                          "articles with", str(len(futureVertices)),
                          "to be explored.")
                    attained_levels.add(size_level)

        currentDist = distDict[subtreeRoot]
        if verbose and currentDist > maxDist:
            maxDist = currentDist
            print("Reached depth ", currentDist, " with term ", subtreeRoot,
                  ", having visited ", str(len(visited)), " articles and ",
                  "with ", str(len(futureVertices)), " to be explored",
                  sep="")
            # too many lines (684 for depth 1 for Coffee)
#        if verbose and currentDist < 2:
#            print("Examining", subtreeRoot, "at depth =", currentDist)
        if subtreeRoot == targetArticle:
            if verbose:
                print("Found path")
            return constructPath(subtreeRoot, pathDict)
        links = linksOnPage(subtreeRoot)
        if targetArticle in set(links.keys()):
            pathDict[targetArticle] = subtreeRoot
            if verbose:
                print("1st degree connection:", targetArticle, "-->",
                      links[targetArticle])
                print("Visited", str(len(visited)), "articles;", "Added",
                      str(len(pathDict)), "entries to path dictionary")
            return constructPath(targetArticle, pathDict)
        linkChildren = set(links.keys())
        # remove articles that have been previously visited
        linkChildren.difference_update(visited)
        # remove articles that have already been marked for visitation
        linkChildren.difference_update(set(futureVertices))
        for child in linkChildren:
            pathDict[child] = subtreeRoot
            futureVertices.appendleft(child)
            distDict[child] = currentDist+1
        visited.add(subtreeRoot)

def constructPath(destination, pathDict):
    articleList = list()
    node = destination
    while pathDict[node] != None:
        newNode = pathDict[node]
        node = newNode
        articleList.append(newNode)
    articleList.reverse()
    articleList.append(destination)
    return articleList

def process(s1, s2):
    valid1 = hasArticle(s1); valid2 = hasArticle(s2)
    if not(valid1):
        print("No such path exists. English Wikipedia does not have the" +
              "following term: ", s1)
    if not(valid2):
        print("No such path exists. English Wikipedia does not have the" +
              "following term: ", s2)
    if valid1 and valid2:
        article1 = findActualTitle(s1)
        article2 = findActualTitle(s2)
        if article1 == article2:
            print("\'" + s1 + "\'" + " and " + "\'" + s2 + "\'" +
                  " redirect to " + article1)
        else:
            print("PROCESSING", s1, "and", s2)
            resultantPath = bfs(s1, article2, True)
            print(resultantPath)

if isCSVinput:
    dfInput = pd.read_csv("Sample Wikipedia inputs.csv")
    dfInput['concat'] = dfInput['Article1'] + ' ' + dfInput['Article2']
    dfInput['Answer No.'] = list(dfInput.index)
    distinctPairs = dfInput.groupby('concat').agg({'Answer No.': np.min})
    allArticle1 = list(dfInput['Article1'])
    allArticle2 = list(dfInput['Article2'])
    idxs=list(distinctPairs['Answer No.'])
    idxs.sort()
    for k in idxs:
        process(allArticle1[k], allArticle2[k])
else:
    term1 = input("Enter search term 1: ")
    term2 = input("Enter search term 2: ")
    process(term1, term2)


#!/usr/bin/python

import pickle
import sys
import matplotlib.pyplot
sys.path.append("/home/sotoshigoto/workspace/Udacity/introMachineLearning/tools/")
from feature_format import featureFormat, targetFeatureSplit

### read in data dictionary, convert to numpy array
data_dict = pickle.load( open("/home/sotoshigoto/workspace/Udacity/introMachineLearning/final_project/final_project_dataset.pkl", "r") )

features = ["salary", "bonus"]
data = featureFormat(data_dict, features)

### your code below
for point in data:
    salary = point[0]
    bonus = point[1]
    salary_list = []
    bonus_list = []
    salary_list.append(salary)
    bonus_list.append(bonus)
    matplotlib.pyplot.scatter( salary, bonus )

for point in data_dict:
    if data_dict[point] ["salary"] == max(salary_list):
        print(max(salary_list))
        print(point)
# matplotlib.pyplot.xlabel("salary")
# matplotlib.pyplot.ylabel("bonus")
# matplotlib.pyplot.show()


import numpy as np
import os
import cv2
import imutils

#room_sorter.py
#plays back data from a specified folder and allows you to sort into different rooms
#MAKE SURE to move folder containing all data to 'data_management' repo folder

#Reduce Delay to Speed up Playback and vis versa
playback_delay = 10 #ms

def resize(img):
    img = imutils.resize(img, height=256)
    y,x = img.shape[0],img.shape[1]
    x_center = int(x/2)
    y_center = int(y/2)
    img = img[(y_center-128):(y_center+128), (x_center-128):(x_center+128)]
    return img

def restore_file(from_dir, to_dir, file_name):
    joints_file = file_name[:-len('.avi')]+'_joints.tensor'
    try:
        os.rename(os.path.join(from_dir, file_name), os.path.join(to_dir, file_name))
        os.rename(os.path.join(from_dir, joints_file), os.path.join(to_dir, joints_file))
        return True
    except Exception as e:
        #print(e)
        return False

def main(root_dir):
    # Set Up directories
    all_files = os.listdir(root_dir)
    dir_names = ['bad_examples' ,'questionable_examples', 'room_ricky', 'room_ji', 'room_alex','room_alistair','room_other']
    inputs = ['d', 'q', '1', '2', '3', '4', '5']
    dirs = []
    for name in dir_names:
        dirs.append(os.path.join(root_dir,name))

    #Extract video files
    vid_files = []
    for file in all_files:
        if '._' in file: #mac bug
            continue
        if file.endswith('.avi') or file.endswith('.mp4'):
            vid_files.append(file)
    print(len(vid_files),' unsorted videos')

    #
    i=0
    while i < len(vid_files):
        try:
            fname_vid = vid_files[i]
            fname_joints = fname_vid[:-len('.avi')]+'_joints.tensor'

            vid_path = os.path.join(root_dir, fname_vid)
            joints_path = os.path.join(root_dir, fname_joints)
            if not os.path.exists(joints_path):
                print('Did not find associated "_joints.tensor" file for ',fname_vid)
                i += 1
                continue
            cap = cv2.VideoCapture(vid_path)

            if not cap.isOpened():
                i += 1
                continue
            frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
            #print(frame count)
            while(cap.isOpened()):
                ret, frame = cap.read()
                if ret:
                    frame = resize(frame)
                    cv2.imshow(fname_vid,frame)
                else:
                    break
                cv2.waitKey(playback_delay)
            cap.release()
            print(fname_vid+'\n')
            inp = input('[enter] replay?\n[p] replay previous?\n[d] delete?\n[q] questionable?\n[1] Ricky_s  \n[2] Ji_s\n[3] Alex_s \n[4] Alistair_s \n[5] Other \n[c] exit\n:')
            cv2.destroyAllWindows() # Keep the window open for reference and replay

            if inp in inputs: #Sort
                target_direc = dirs[inputs.index(inp)]
                if not os.path.exists(target_direc):
                    os.mkdir(target_direc)
                os.rename(vid_path, os.path.join(target_direc,fname_vid))
                os.rename(joints_path, os.path.join(target_direc,fname_joints))

            elif inp == 'p': #Replay Previous
                for directory in dirs:
                    flag = restore_file(directory, root_dir, vid_files[i-1])
                    if flag:
                        i-=1
                        break
                continue

            elif inp == 'c': #Exit
                break
            else:
                continue    #Replay Current

        except Exception as e:
            raise
            print(e)

        i += 1

if __name__ == '__main__':
    root_dir = os.getcwd()
    sort_name = input('Path of folder to sort (within data_manaegment): ')
    sort_dir = os.path.join(root_dir,sort_name)
    print('Sorting From:',sort_dir,'\n')
    main(sort_dir)


print('enter __init__')
import dash
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

server = Flask(__name__)
server.config['DEBUG'] = True
server.config['SQLALCHEMY_ECHO'] = False
server.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///replays.db'
server.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(server)
db.session.configure(autoflush=False)
app = dash.Dash(__name__, server = server, url_base_pathname = '/dashboard/')
app.config['suppress_callback_exceptions'] = True

print('exit __init__')


#
#                    Copyright (c) Microolap Technologies LTD#
#
#    Author: Sergey Surkov
#    Date:
#
#    Decription:
#
# -*- coding: utf-8 -*-

from sqlalchemy import Column, Integer, Unicode

from utils.modelling import Model
from models import Base

class TaskType(Model, Base):

    __tablename__ = "task_types"
    __table_args__ = {'extend_existing': True}

    id = Column('id', Integer, primary_key=True, index=True)
    name = Column(Unicode(128), index=True)

def add_default_tasks_types(db):
    default_tasks_types = [
        'Разработка',
        'Пилот',
        'Демонстрация',
        'Проект',
        'Интеграция'
        'R&D',
        'Маркетинг',
    ]
    for t in default_tasks_types:
        if not db.query(TaskType).filter(TaskType.name == t).first():
            db.add(TaskType(name=t))
            db.commit()


import logging
from functools import wraps
from typing import Any, Dict, List, Union

from django.db.models import Model
from django.http import HttpRequest, JsonResponse
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.http import require_POST

import orjson
from bs4 import BeautifulSoup

from .call_method_parser import InvalidKwarg, parse_call_method_name, parse_kwarg
from .components import UnicornField, UnicornView
from .decorators import timed
from .errors import UnicornViewError
from .message import ComponentRequest, Return
from .serializer import dumps, loads
from .utils import generate_checksum

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

def handle_error(view_func):
    def wrapped_view(*args, **kwargs):
        try:
            return view_func(*args, **kwargs)
        except UnicornViewError as e:
            return JsonResponse({"error": str(e)})
        except AssertionError as e:
            return JsonResponse({"error": str(e)})

    return wraps(view_func)(wrapped_view)

@timed
def _set_property_from_data(
    component_or_field: Union[UnicornView, UnicornField, Model], name: str, value,
) -> None:
    """
    Sets properties on the component based on passed-in data.
    """

    if hasattr(component_or_field, name):
        field = getattr(component_or_field, name)

        # UnicornField and Models are always a dictionary (can be nested)
        if isinstance(field, UnicornField) or isinstance(field, Model):
            if isinstance(value, dict):
                for key in value.keys():
                    key_value = value[key]
                    _set_property_from_data(field, key, key_value)
            else:
                _set_property_from_data(field, field.name, value)
        else:
            if hasattr(component_or_field, "_set_property"):
                # Can assume that `component_or_field` is a component
                component_or_field._set_property(name, value)
            else:
                setattr(component_or_field, name, value)

@timed
def _set_property_value(
    component: UnicornView, property_name: str, property_value: Any, data: Dict = {}
) -> None:
    """
    Sets properties on the component.
    Also updates the data dictionary which gets set back as part of the payload.

    Args:
        param component: Component to set attributes on.
        param property_name: Name of the property.
        param property_value: Value to set on the property.
        param data: Dictionary that gets sent back with the response. Defaults to {}.
    """

    assert property_name is not None, "Property name is required"
    assert property_value is not None, "Property value is required"

    component.updating(property_name, property_value)

    """
    Handles nested properties. For example, for the following component:

    class Author(UnicornField):
        name = "Neil"

    class TestView(UnicornView):
        author = Author()

    `payload` would be `{'name': 'author.name', 'value': 'Neil Gaiman'}`

    The following code updates UnicornView.author.name based the payload's `author.name`.
    """
    property_name_parts = property_name.split(".")
    component_or_field = component
    data_or_dict = data  # Could be an internal portion of data that gets set

    for (idx, property_name_part) in enumerate(property_name_parts):
        if hasattr(component_or_field, property_name_part):
            if idx == len(property_name_parts) - 1:
                if hasattr(component_or_field, "_set_property"):
                    # Can assume that `component_or_field` is a component
                    component_or_field._set_property(property_name_part, property_value)
                else:
                    # Handle calling the updating/updated method for nested properties
                    property_name_snake_case = property_name.replace(".", "_")
                    updating_function_name = f"updating_{property_name_snake_case}"
                    updated_function_name = f"updated_{property_name_snake_case}"

                    if hasattr(component, updating_function_name):
                        getattr(component, updating_function_name)(property_value)

                    setattr(component_or_field, property_name_part, property_value)

                    if hasattr(component, updated_function_name):
                        getattr(component, updated_function_name)(property_value)

                data_or_dict[property_name_part] = property_value
            else:
                component_or_field = getattr(component_or_field, property_name_part)
                data_or_dict = data_or_dict.get(property_name_part, {})
        elif isinstance(component_or_field, dict):
            if idx == len(property_name_parts) - 1:
                component_or_field[property_name_part] = property_value
                data_or_dict[property_name_part] = property_value
            else:
                component_or_field = component_or_field[property_name_part]
                data_or_dict = data_or_dict.get(property_name_part, {})

    component.updated(property_name, property_value)

@timed
def _get_property_value(component: UnicornView, property_name: str) -> Any:
    """
    Gets property value from the component based on the property name.
    Handles nested property names.

    Args:
        param component: Component to get property values from.
        param property_name: Property name. Can be "dot-notation" to get nested properties.
    """

    assert property_name is not None, "property_name name is required"

    # Handles nested properties
    property_name_parts = property_name.split(".")
    component_or_field = component

    for (idx, property_name_part) in enumerate(property_name_parts):
        if hasattr(component_or_field, property_name_part):
            if idx == len(property_name_parts) - 1:
                return getattr(component_or_field, property_name_part)
            else:
                component_or_field = getattr(component_or_field, property_name_part)
        elif isinstance(component_or_field, dict):
            if idx == len(property_name_parts) - 1:
                return component_or_field[property_name_part]
            else:
                component_or_field = component_or_field[property_name_part]

@timed
def _call_method_name(
    component: UnicornView, method_name: str, params: List[Any]
) -> Any:
    """
    Calls the method name with parameters.

    Args:
        param component: Component to call method on.
        param method_name: Method name to call.
        param params: List of arguments for the method.
    """

    if method_name is not None and hasattr(component, method_name):
        func = getattr(component, method_name)

        if params:
            return func(*params)
        else:
            return func()

@timed
@handle_error
@csrf_protect
@require_POST
def message(request: HttpRequest, component_name: str = None) -> JsonResponse:
    """
    Endpoint that instantiates the component and does the correct action
    (set an attribute or call a method) depending on the JSON payload in the body.

    Args:
        param request: HttpRequest for the function-based view.
        param: component_name: Name of the component, e.g. "hello-world".

    Returns:
        JSON with the following structure:
        {
            "id": component_id,
            "dom": html,  // re-rendered version of the component after actions in the payload are completed
            "data": {},  // updated data after actions in the payload are completed
        }
    """

    assert component_name, "Missing component name in url"

    component_request = ComponentRequest(request)
    component = UnicornView.create(
        component_id=component_request.id,
        component_name=component_name,
        request=request,
    )
    validate_all_fields = False

    # Get a copy of the data passed in to determine what fields are updated later
    original_data = component_request.data.copy()

    # Set component properties based on request data
    for (property_name, property_value) in component_request.data.items():
        _set_property_from_data(component, property_name, property_value)
    component.hydrate()

    is_reset_called = False
    return_data = None
    partials = []

    for action in component_request.action_queue:
        action_type = action.get("type")
        payload = action.get("payload", {})
        partials.append(action.get("partial"))

        if action_type == "syncInput":
            property_name = payload.get("name")
            property_value = payload.get("value")
            _set_property_value(
                component, property_name, property_value, component_request.data
            )
        elif action_type == "dbInput":
            model = payload.get("model")
            db = payload.get("db", {})
            db_model_name = db.get("name")
            pk = db.get("pk")

            DbModel = None
            db_defaults = {}

            if model:
                model_class = getattr(component, model)

                if hasattr(model_class, "model"):
                    DbModel = model_class.model

                    if hasattr(component, "Meta"):
                        for m in component.Meta.db_models:
                            if m.model_class == model_class.model:
                                db_defaults = m.defaults
                                break

            if not DbModel and db_model_name:
                assert hasattr(component, "Meta") and hasattr(
                    component.Meta, "db_models"
                ), f"Missing Meta.db_models list in component"

                for m in component.Meta.db_models:
                    if m.name == db_model_name:
                        DbModel = m.model_class
                        db_defaults = m.defaults
                        break

            fields = payload.get("fields", {})

            assert (
                DbModel
            ), f"Missing {model}.model and {db_model_name} in Meta.db_models"
            assert issubclass(
                DbModel, Model
            ), "Model must be an instance of `django.db.models.Model"

            if fields:
                fields_to_update = db_defaults
                fields_to_update.update(fields)

                if pk:
                    DbModel.objects.filter(pk=pk).update(**fields_to_update)
                else:
                    instance = DbModel(**fields_to_update)
                    instance.save()
                    pk = instance.pk
        elif action_type == "callMethod":
            call_method_name = payload.get("name", "")
            assert call_method_name, "Missing 'name' key for callMethod"

            (method_name, params) = parse_call_method_name(call_method_name)
            return_data = Return(method_name, params)
            setter_method = {}

            if "=" in call_method_name:
                try:
                    setter_method = parse_kwarg(
                        call_method_name, raise_if_unparseable=True
                    )
                except InvalidKwarg:
                    pass

            if setter_method:
                property_name = list(setter_method.keys())[0]
                property_value = setter_method[property_name]

                _set_property_value(component, property_name, property_value)
                return_data = Return(property_name, [property_value])
            else:
                if method_name == "$refresh":
                    # Handle the refresh special action
                    component = UnicornView.create(
                        component_id=component_request.id,
                        component_name=component_name,
                        use_cache=True,
                        request=request,
                    )
                elif method_name == "$reset":
                    # Handle the reset special action
                    component = UnicornView.create(
                        component_id=component_request.id,
                        component_name=component_name,
                        use_cache=False,
                        request=request,
                    )

                    #  Explicitly remove all errors and prevent validation from firing before render()
                    component.errors = {}
                    is_reset_called = True
                elif method_name == "$toggle":
                    for property_name in params:
                        property_value = _get_property_value(component, property_name)
                        property_value = not property_value

                        _set_property_value(component, property_name, property_value)
                elif method_name == "$validate":
                    # Handle the validate special action
                    validate_all_fields = True
                else:
                    component.calling(method_name, params)
                    return_data.value = _call_method_name(
                        component, method_name, params
                    )
                    component.called(method_name, params)
        else:
            raise UnicornViewError(f"Unknown action_type '{action_type}'")

    # Re-load frontend context variables to deal with non-serializable properties
    component_request.data = orjson.loads(component.get_frontend_context_variables())

    if not is_reset_called:
        if validate_all_fields:
            component.validate()
        else:
            model_names_to_validate = []

            for key, value in original_data.items():
                if value != component_request.data.get(key):
                    model_names_to_validate.append(key)

            component.validate(model_names=model_names_to_validate)

    rendered_component = component.render()
    partial_doms = []

    if partials and all(partials):
        soup = BeautifulSoup(rendered_component, features="html.parser")

        for partial in partials:
            partial_found = False
            only_id = False
            only_key = False

            target = partial.get("target")

            if not target:
                target = partial.get("key")

                if target:
                    only_key = True

            if not target:
                target = partial.get("id")

                if target:
                    only_id = True

            assert target, "Partial target is required"

            if not only_id:
                for element in soup.find_all():
                    if (
                        "unicorn:key" in element.attrs
                        and element.attrs["unicorn:key"] == target
                    ):
                        partial_doms.append({"key": target, "dom": str(element)})
                        partial_found = True
                        break

            if not partial_found and not only_key:
                for element in soup.find_all():
                    if "id" in element.attrs and element.attrs["id"] == target:
                        partial_doms.append({"id": target, "dom": str(element)})
                        partial_found = True
                        break

    res = {
        "id": component_request.id,
        "data": component_request.data,
        "errors": component.errors,
        "checksum": generate_checksum(orjson.dumps(component_request.data)),
    }

    if partial_doms:
        res.update({"partials": partial_doms})
    else:
        res.update({"dom": rendered_component})

    if return_data:
        res.update(
            {"return": return_data.get_data(),}
        )

        if return_data.redirect:
            res.update(
                {"redirect": return_data.redirect,}
            )

        if return_data.poll:
            res.update(
                {"poll": return_data.poll,}
            )

    parent_component = component.parent

    if parent_component:
        parent_frontend_context_variables = loads(
            parent_component.get_frontend_context_variables()
        )
        parent_checksum = generate_checksum(dumps(parent_frontend_context_variables))

        parent = {
            "id": parent_component.component_id,
            "checksum": parent_checksum,
        }

        if not partial_doms:
            parent_dom = parent_component.render()

            parent.update(
                {
                    "dom": parent_dom,
                    "data": parent_frontend_context_variables,
                    "errors": parent_component.errors,
                }
            )

        res.update({"parent": parent})

    return JsonResponse(res)


import argparse
import os

import cv2
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

import kornia as dgm

def load_homography(file_name):
    """Loads an homography from text file."""
    assert os.path.isfile(file_name), "Invalid file {}".format(file_name)
    return torch.from_numpy(np.loadtxt(file_name)).float()

def load_image(file_name):
    """Loads the image with OpenCV and converts to torch.Tensor"""
    assert os.path.isfile(file_name), "Invalid file {}".format(file_name)

    # load image with OpenCV
    img = cv2.imread(file_name, cv2.IMREAD_COLOR)

    # convert image to torch tensor
    tensor = dgm.utils.image_to_tensor(img).float() / 255.0
    tensor = tensor.view(1, *tensor.shape)  # 1xCxHxW

    return tensor, img

class MyHomography(nn.Module):
    def __init__(self):
        super(MyHomography, self).__init__()
        self.homo = nn.Parameter(torch.Tensor(3, 3))

        self.reset_parameters()

    def reset_parameters(self):
        torch.nn.init.eye_(self.homo)

    def forward(self):
        return torch.unsqueeze(self.homo, dim=0)  # 1x3x3

def HomographyRegressionApp():
    # Training settings
    parser = argparse.ArgumentParser(description='Homography Regression with photometric loss.')
    parser.add_argument('--input-dir', type=str, required=True, help='the path to the directory with the input data.')
    parser.add_argument('--output-dir', type=str, required=True, help='the path to output the results.')
    parser.add_argument(
        '--num-iterations', type=int, default=1000, metavar='N', help='number of training iterations (default: 1000)'
    )
    parser.add_argument('--lr', type=float, default=1e-3, metavar='LR', help='learning rate (default: 1e-3)')
    parser.add_argument('--cuda', action='store_true', default=False, help='enables CUDA training')
    parser.add_argument('--seed', type=int, default=666, metavar='S', help='random seed (default: 666)')
    parser.add_argument(
        '--log-interval',
        type=int,
        default=10,
        metavar='N',
        help='how many batches to wait before logging training status',
    )
    parser.add_argument(
        '--log-interval-vis',
        type=int,
        default=100,
        metavar='N',
        help='how many batches to wait before visual logging training status',
    )
    args = parser.parse_args()

    # define the device to use for inference
    use_cuda = args.cuda and torch.cuda.is_available()
    device = torch.device('cuda' if use_cuda else 'cpu')

    torch.manual_seed(args.seed)

    # load the data
    img_src, _ = load_image(os.path.join(args.input_dir, 'img1.ppm'))
    img_dst, _ = load_image(os.path.join(args.input_dir, 'img2.ppm'))
    dst_homo_src_gt = load_homography(os.path.join(args.input_dir, 'H1to2p'))

    # instantiate the homography warper from `kornia`
    height, width = img_src.shape[-2:]
    warper = dgm.HomographyWarper(height, width)

    # create the homography as the parameter to be optimized
    dst_homo_src = MyHomography().to(device)

    # create optimizer
    optimizer = optim.Adam(dst_homo_src.parameters(), lr=args.lr)

    # main training loop

    for iter_idx in range(args.num_iterations):
        # send data to device
        img_src, img_dst = img_src.to(device), img_dst.to(device)

        # warp the reference image to the destiny with current homography
        img_src_to_dst = warper(img_src, dst_homo_src())

        # compute the photometric loss
        loss = F.l1_loss(img_src_to_dst, img_dst, reduction='none')

        # propagate the error just for a fixed window
        w_size = 100  # window size
        h_2, w_2 = height // 2, width // 2
        loss = loss[..., h_2 - w_size : h_2 + w_size, w_2 - w_size : w_2 + w_size]
        loss = torch.mean(loss)

        # compute gradient and update optimizer parameters
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if iter_idx % args.log_interval == 0:
            print('Train iteration: {}/{}\tLoss: {:.6}'.format(iter_idx, args.num_iterations, loss.item()))
            print(dst_homo_src.homo)

        def draw_rectangle(image, dst_homo_src):
            height, width = image.shape[:2]
            pts_src = torch.FloatTensor(
                [[[-1, -1], [1, -1], [1, 1], [-1, 1]]]  # top-left  # bottom-left  # bottom-right  # top-right
            ).to(dst_homo_src.device)
            # transform points
            pts_dst = dgm.transform_points(torch.inverse(dst_homo_src), pts_src)

            def compute_factor(size):
                return 1.0 * size / 2

            def convert_coordinates_to_pixel(coordinates, factor):
                return factor * (coordinates + 1.0)

            # compute convertion factor
            x_factor = compute_factor(width - 1)
            y_factor = compute_factor(height - 1)
            pts_dst = pts_dst.cpu().squeeze().detach().numpy()
            pts_dst[..., 0] = convert_coordinates_to_pixel(pts_dst[..., 0], x_factor)
            pts_dst[..., 1] = convert_coordinates_to_pixel(pts_dst[..., 1], y_factor)

            # do the actual drawing
            for i in range(4):
                pt_i, pt_ii = tuple(pts_dst[i % 4]), tuple(pts_dst[(i + 1) % 4])
                image = cv2.line(image, pt_i, pt_ii, (255, 0, 0), 3)
            return image

        if iter_idx % args.log_interval_vis == 0:
            # merge warped and target image for visualization
            img_src_to_dst = warper(img_src, dst_homo_src())
            img_vis = 255.0 * 0.5 * (img_src_to_dst + img_dst)
            img_vis_np = dgm.utils.tensor_to_image(img_vis)
            image_draw = draw_rectangle(img_vis_np, dst_homo_src())
            # save warped image to disk
            file_name = os.path.join(args.output_dir, 'warped_{}.png'.format(iter_idx))
            cv2.imwrite(file_name, image_draw)

if __name__ == "__main__":
    HomographyRegressionApp()


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

# PM (Probabilistic Multileave) 16.9.3

import numpy
from tqdm import tqdm

# ######10########20########30########40########50########60########70##

class PM(object):
    '''performs probabilistic multileaving.'''
    _has_instance = False
    numpy.random.seed()

    class MemberCache(dict):
        '''is a dict where r -> 1 / r^3 .'''
        TAU = 3

        def __missing__(self, r):
            self[r] = 1.0 / r ** self.TAU
            return self[r]

    class SumCache(dict):
        '''is a dict where n -> Sum of 1 / r^3 where r is in [1, n] .'''

        def __missing__(self, n):
            self[n] = sum([PM._member_cache[r] for r in range(1, n + 1)])
            return self[n]

    class CumulationCache(dict):
        '''is a dict where n -> List l

        where the item at an index i is selected in probability of
        l[i] - l[i - 1] (or just l[i] if l[i - 1] does not exist).
        '''

        def __missing__(self, l):
            result = []
            numerator = 0.0
            denominator = PM._sum_cache[l]
            for r in range(1, l):
                numerator += PM._member_cache[r]
                result.append(numerator / denominator)
            result.append(1)
            self[l] = result
            return result

    def __init__(self):
        if not PM._has_instance:
            PM._member_cache = PM.MemberCache()
            PM._sum_cache = PM.SumCache()
            PM._cumulation_cache = PM.CumulationCache()
            PM._has_instance = True

    def create(self, original_rankings, k):
        '''creates a list of [document_index, ranking_index] .'''

        def select_one_document_in(ranking):
            n = len(ranking)
            if n <= 0:
                raise IndexError('Ran out of an original ranking')
            f = numpy.random.random()
            cumulation = PM._cumulation_cache[n]
            for i in range(0, n):
                if f < cumulation[i]:
                    return ranking[i]
        rankings = []
        for original in original_rankings:
            rankings.append(original[:])
        result = []
        while True:
            ranking_indexes = [i for i in range(0, len(rankings))]
            numpy.random.shuffle(ranking_indexes)
            while(0 < len(ranking_indexes)):
                i = ranking_indexes.pop()
                ranking_i = rankings[i]
                document = select_one_document_in(ranking_i)
                result.append([document, i])
                if k <= len(result):
                    return result
                for r_j in rankings:
                    try:
                        r_j.remove(document)
                    except ValueError:
                        continue

if __name__ == '__main__':
    ranking = ['d%s' % i for i in range(10)]
    rankings = [ranking] * 20
    pm = PM()
    for i in tqdm(range(86000000)):
        pm.create(rankings, 10)


import numpy as np
import pandas as pd
from sklearn.base import TransformerMixin
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import MinMaxScaler, RobustScaler, StandardScaler

def split_sequence(sequence, look_back_window: int, forecast_horizon: int, stride: int = 1):
    X, y = [], []
    for i in range(0, len(sequence), stride):
        # find the end x and y
        end_ix = i + look_back_window
        end_iy = end_ix + forecast_horizon

        # check if there is enough elements to fill this x, y pair
        if end_iy > len(sequence):
            break

        X.append(sequence[i:end_ix])
        y.append(sequence[end_iy - 1 if forecast_horizon == 1 else end_ix:end_iy])
    return np.asarray(X), np.asarray(y)

class TimeSeriesImputer(TransformerMixin):
    def __init__(self, method: str = 'linear', fail_save: TransformerMixin = SimpleImputer()):
        self.method = method
        self.fail_save = fail_save

    def fit(self, data):
        if self.fail_save:
            self.fail_save.fit(data)
        return self

    def transform(self, data):
        # Interpolate missing values in columns
        if not isinstance(data, pd.DataFrame):
            data = pd.DataFrame(data)
        data = data.interpolate(method=self.method, limit_direction='both')
        # spline or time may be better?

        if self.fail_save:
            data = self.fail_save.transform(data)

        return data

def difference(dataset, interval=1, relative=False, min_price=1e-04):
    delta = []
    for i in range(interval, len(dataset)):
        value = dataset[i] - dataset[i - interval]
        if relative:
            prev_price = dataset[i - interval]
            prev_price[prev_price == 0] = min_price
            value /= prev_price
        delta.append(value)
    return np.asarray(delta)

class ARIMAPreprocessor(TransformerMixin):
    def __init__(self, look_back_window: int, forecast_horizon: int, stride: int, diff_order: int,
                 relative_diff: bool = True, splitXy: bool = True, scaling: str = 'minmax'):
        if not (look_back_window > 0 and forecast_horizon > 0 and stride > 0):
            raise ValueError('look_back_window, forecast_horizon and stride must be positive')
        super().__init__()
        self.look_back_window = look_back_window
        self.forecast_horizon = forecast_horizon
        self.stride = stride
        self.diff_order = diff_order
        self.relative_diff = relative_diff
        self.splitXy = splitXy
        self.interpolation_imputer = TimeSeriesImputer(method='linear')

        if scaling == 'minmax':
            self.scaler = MinMaxScaler()
        elif scaling == 'standard':
            self.scaler = StandardScaler()
        elif scaling == 'robust':
            self.scaler = RobustScaler()
        else:
            raise ValueError('Invalid value for scaling')

    def fit_transform(self, data, **fit_params):
        # Fill missing values via interpolation
        data = self.interpolation_imputer.fit_transform(data)

        # Differencing
        diff = np.array(data)
        for d in range(1, self.diff_order + 1):
            diff = difference(diff, relative=self.relative_diff)
            data = np.append(data, np.pad(diff, pad_width=((d, 0), (0, 0))), axis=1)
        if self.diff_order > 0:
            data = data[:, diff.shape[1]:]

        # Scale
        # if self.diff_order < 1:
        data = self.scaler.fit_transform(data)

        if not self.splitXy:
            return data

        # Extract X, y from time series
        X, y = split_sequence(data, self.look_back_window, self.forecast_horizon, self.stride)

        return X, y

    def transform(self, data):
        # Fill missing values via interpolation
        data = self.interpolation_imputer.transform(data)

        # Differencing
        diff = np.array(data)
        for d in range(1, self.diff_order + 1):
            diff = difference(diff, relative=self.relative_diff)
            data = np.append(data, np.pad(diff, pad_width=((d, 0), (0, 0))), axis=1)
        if self.diff_order > 0:
            data = data[:, diff.shape[1]:]

        # Scale
        # if self.diff_order < 1:
        data = self.scaler.transform(data)

        if not self.splitXy:
            return data

        # Extract X, y
        X, y = split_sequence(data, self.look_back_window, self.forecast_horizon, self.stride)

        return X, y


import os
import time

import pycuda.autoinit
import pycuda.driver as drv
import numpy as np

from pycuda.compiler import SourceModule

def  vec_multi(query, test):
	grid_dim=len(test)
	test=np.array(test)
	mod = SourceModule("""
	__global__ void multiply_them(float *dest, float *a, float *b)
	{
		const int blockId = blockIdx.x + blockIdx.y * gridDim.x;
		const int idx = threadIdx.y * blockDim.x + threadIdx.x;
		const int i = blockId * (blockDim.x * blockDim.y)*2 + idx;
		int mul=(a[idx] -b[i]);
	  	dest[i] = mul*mul;

		mul= a[idx+1024] - b[i+1024];
		dest[i+1024] = mul*mul;

		__syncthreads (); //syncthreads  in  block

		  for(int s = 1; s < blockDim.x; s*=2){
			if(i%(2*s)==0){dest[i]+= dest[i+s];dest[i+1024]+= dest[i+s+1024];}
			__syncthreads();
		}
		dest[i]+=dest[i+1024];
		}
	""")
	multiply_them = mod.get_function("multiply_them")

	#query = 3*np.ones([2048,1]).astype(np.float32)
	#test = 2*np.ones([grid_dim,2048]).astype(np.float32)

	dest = np.zeros_like(test)
	multiply_them(
		    drv.Out(dest), drv.In(query), drv.In(test),
		    block=(1024,1,1), grid=(grid_dim,1,1))

	return dest[:,0]
#vec_multi(0, 0)

def rename(target_probe_path="./person_csv/ped"):
	ID_len=6
	for x in os.listdir(target_probe_path):
		arr = x.split('_')
		ID = arr[1][0:-4]
		ID = (ID_len-len(ID))*"0"+ID
		new_name = "ID_"+ID+".jpg"
		os.rename(target_probe_path+"/"+x,target_probe_path+"/"+new_name)

def safe_remove(path):
	if os.path.exists(path):
		os.remove(path)
		return True
	else:
		return False

def sort_similarity(query_f, test_f):
	result = vec_multi(query_f[0], test_f)

	result_argsort = np.argsort(result)
	return result, result_argsort