import os
import os.path as osp
import random
import glob
import gast as ast

import torch
import numpy as np
from tqdm import tqdm
import scipy.stats as stats

from networkx.algorithms.isomorphism import GraphMatcher
from torch_geometric.data import Dataset
from torch.utils.data import DataLoader
from typing import Optional, Callable, List

from codescholar.utils.graph_utils import save_as_json, program_graph_to_nx
from codescholar.utils.train_utils import featurize_graph
from codescholar.sast.simplified_ast import get_simplified_ast

def my_collate(batch):
    """dummy collate fn to just return data as is"""
    return batch

class Corpus:
    """Generator for graphs saved in a dataset file to train models.

    Iteratively, new batch of graphs (positive and negative)
    are generated by sampling from the dataset.
    """

    def __init__(self, dataset, n_train, n_test, train=True, save_json=False):
        if train:
            self.train_dataset = ProgramDataset(
                root=f"./tmp/{dataset}/train", name=dataset, task="train", n_samples=n_train, save_json=save_json
            )

        self.test_dataset = ProgramDataset(root=f"./tmp/{dataset}/test", name=dataset, task="test", n_samples=n_test, save_json=save_json)

    def gen_data_loader(self, batch_size, train=True):
        if train:
            return DataLoader(self.train_dataset, collate_fn=my_collate, batch_size=batch_size, sampler=None, shuffle=False)
        else:
            return DataLoader(self.test_dataset, collate_fn=my_collate, batch_size=batch_size, sampler=None, shuffle=False)

class ProgramDataset(Dataset):
    def __init__(
        self,
        root: str,
        name: str,
        task: str,
        n_samples: int,
        transform: Optional[Callable] = None,
        pre_transform: Optional[Callable] = None,
        pre_filter: Optional[Callable] = None,
        save_json: Optional[bool] = False,
        min_size=2,
        max_size=20,
    ):
        if not os.path.exists(root):
            raise ValueError(f"Dataset for {name} not found in {root}")

        self.name = name
        self.graph_dir = osp.join(root, "graphs")

        if not os.path.exists(self.graph_dir):
            os.makedirs(self.graph_dir)

        self.task = task
        self.n_samples = n_samples
        self.min_size = min_size
        self.max_size = max_size
        self.save_json = save_json
        self.json_dir = osp.join(root, "networkx")

        if self.save_json and not os.path.exists(self.json_dir):
            os.makedirs(self.json_dir)

        super().__init__(root, transform, pre_transform, pre_filter)

    def download(self):
        pass

    @property
    def num_node_labels(self) -> int:
        return self.sizes["num_node_labels"]

    @property
    def num_node_attributes(self) -> int:
        return self.sizes["num_node_attributes"]

    @property
    def num_edge_labels(self) -> int:
        return self.sizes["num_edge_labels"]

    @property
    def num_edge_attributes(self) -> int:
        return self.sizes["num_edge_attributes"]

    @property
    def raw_file_names(self) -> List[str]:
        names = sorted(glob.glob(osp.join(self.raw_dir, "*.py")))
        names = [os.path.basename(file) for file in names]
        return names

    @property
    def processed_file_names(self) -> str:
        names = sorted(glob.glob(osp.join(self.processed_dir, "*.pt")))
        names = [os.path.basename(file) for file in names]
        return names
        # return 'not_implemented.pt'

    def pre_transform(self, data):
        return data

    def process(self):
        """process and store python graphs as a Data object onto the disk"""
        count = 0
        program_size = []

        # Convert each python file to networkx graphs and save in self.graph_dir
        for raw_path in tqdm(self.raw_paths, desc=f"Preprocess-{self.task}"):
            data = self.create_prog_datapoint(raw_path)

            if data is None:
                continue

            if self.pre_filter is not None and self.prefilter(data):
                continue

            if self.pre_transform is not None:
                data = self.pre_transform(data)

            if self.save_json is True:
                save_as_json(data, osp.join(self.json_dir, f"data_{count}.json"))

            torch.save(data, osp.join(self.graph_dir, f"data_{count}.pt"))
            program_size.append(len(data))
            count += 1

        # Create randomly mutated examples and store in self.processed_dir
        self.random_samples_generator(program_size, count)

    def random_samples_generator(self, program_size, count):
        """Steps:
        1. choose a random size for graph
        2. choose a random target graph
        3. perform random bfs traversal in neighborhood = size
        4. choose a random but anchored query = positive e.g.
        5. repeat for negative e.g. but with different random graph
        for the query"""

        idx = 0
        pbar = tqdm(total=self.n_samples + 1, desc=f"RandBFSSample-{self.task}")

        while idx < self.n_samples:
            size = random.randint(self.min_size + 1, self.max_size)
            graph, t = self.sample_neigh(program_size, count, size)
            q = t[: random.randint(self.min_size, len(t) - 1)]

            anchor = list(graph.nodes)[0]
            pos_t_anchor = anchor
            pos_q_anchor = anchor
            pos_t, pos_q = graph.subgraph(t), graph.subgraph(q)

            size = random.randint(self.min_size + 1, self.max_size)
            graph_t, t = self.sample_neigh(program_size, count, size)
            graph_q, q = self.sample_neigh(program_size, count, random.randint(self.min_size, size - 1))

            neg_t_anchor = list(graph_t.nodes)[0]
            neg_q_anchor = list(graph_q.nodes)[0]
            neg_t, neg_q = graph_t.subgraph(t), graph_q.subgraph(q)

            # translate to DeepSnap Graph
            pos_t = featurize_graph(pos_t, pos_t_anchor)
            pos_q = featurize_graph(pos_q, pos_q_anchor)
            neg_t = featurize_graph(neg_t, neg_t_anchor)
            neg_q = featurize_graph(neg_q, neg_q_anchor)

            data = [pos_t, pos_q, neg_t, neg_q]
            torch.save(data, osp.join(self.processed_dir, f"data_{idx}.pt"))
            idx += 1
            pbar.update(1)

    def sample_neigh(self, ps, count, size):
        """random bfs walk to find neighborhood graphs of a set size"""
        ps = np.array(ps, dtype=np.float)
        ps /= np.sum(ps)
        dist = stats.rv_discrete(values=(np.arange(count), ps))

        while True:
            idx = dist.rvs()
            graph = torch.load(osp.join(self.graph_dir, f"data_{idx}.pt"))

            start_node = random.choice(list(graph.nodes))
            neigh = [start_node]
            frontier = list(set(graph.neighbors(start_node)) - set(neigh))
            visited = set([start_node])

            while len(neigh) < size and frontier:
                new_node = random.choice(list(frontier))

                assert new_node not in neigh

                neigh.append(new_node)
                visited.add(new_node)
                frontier += list(graph.neighbors(new_node))
                frontier = [x for x in frontier if x not in visited]

            if len(neigh) == size:
                return graph, neigh

    def create_prog_datapoint(self, path):
        with open(path, "r") as fp:
            source = fp.read()
        try:
            program = ast.parse(source)
        except:
            return None

        # prog_graph = program_graph.get_program_graph(path)
        prog_graph = get_simplified_ast(source, dfg=False, cfg=False)
        if prog_graph is None:
            return None

        digraph = program_graph_to_nx(prog_graph, directed=True)

        return digraph

    def len(self):
        return self.n_samples

    def get(self, idx):
        """load a python method (graph) from disk."""
        data = torch.load(osp.join(self.processed_dir, f"data_{idx}.pt"))
        return data


#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import mozunit
import pytest
from jsonschema.exceptions import ValidationError

from mozperftest.metrics.utils import validate_intermediate_results

def test_results_with_directory():
    test_result = {"results": "path-to-results", "name": "the-name"}
    validate_intermediate_results(test_result)

def test_results_with_measurements():
    test_result = {
        "results": [
            {"name": "metric-1", "values": [0, 1, 1, 0]},
            {"name": "metric-2", "values": [0, 1, 1, 0]},
        ],
        "name": "the-name",
    }
    validate_intermediate_results(test_result)

def test_results_with_suite_perfherder_options():
    test_result = {
        "results": [
            {"name": "metric-1", "values": [0, 1, 1, 0]},
            {"name": "metric-2", "values": [0, 1, 1, 0]},
        ],
        "name": "the-name",
        "extraOptions": ["an-extra-option"],
        "value": 9000,
    }
    validate_intermediate_results(test_result)

def test_results_with_subtest_perfherder_options():
    test_result = {
        "results": [
            {"name": "metric-1", "shouldAlert": True, "values": [0, 1, 1, 0]},
            {"name": "metric-2", "alertThreshold": 1.0, "values": [0, 1, 1, 0]},
        ],
        "name": "the-name",
        "extraOptions": ["an-extra-option"],
        "value": 9000,
    }
    validate_intermediate_results(test_result)

def test_results_with_bad_suite_property():
    test_result = {
        "results": "path-to-results",
        "name": "the-name",
        "I'll cause a failure,": "an expected failure",
    }
    with pytest.raises(ValidationError):
        validate_intermediate_results(test_result)

def test_results_with_bad_subtest_property():
    test_result = {
        "results": [
            # Error is in "shouldalert", it should be "shouldAlert"
            {"name": "metric-1", "shouldalert": True, "values": [0, 1, 1, 0]},
            {"name": "metric-2", "alertThreshold": 1.0, "values": [0, 1, 1, 0]},
        ],
        "name": "the-name",
        "extraOptions": ["an-extra-option"],
        "value": 9000,
    }
    with pytest.raises(ValidationError):
        validate_intermediate_results(test_result)

def test_results_with_missing_suite_property():
    test_result = {
        # Missing "results"
        "name": "the-name"
    }
    with pytest.raises(ValidationError):
        validate_intermediate_results(test_result)

def test_results_with_missing_subtest_property():
    test_result = {
        "results": [
            # Missing "values"
            {"name": "metric-2", "alertThreshold": 1.0}
        ],
        "name": "the-name",
        "extraOptions": ["an-extra-option"],
        "value": 9000,
    }
    with pytest.raises(ValidationError):
        validate_intermediate_results(test_result)

if __name__ == "__main__":
    mozunit.main()


import logging, json, struct, traceback

from ..peer.peerinfo import PeerInfo

class Protocol:

    def __init__(self, name, peer, messages={}):
        if name is None or peer is None:
            raise ValueError('Name and Peer parameter can not be None.')
        self._name = name
        self._peer = peer
        self._peersInfo = {}
        self._messages = messages

        self._messageRegister(self._messages)
        self._protocolValidator()

    def _messageRegister(self, _messages, force=False):
        for (name, message) in _messages.items():
            if not hasattr(self, name) or force:
                setattr(self, name, message(self))
                self._messages[name] = getattr(self, name)
                logging.debug('Registered message %s' % name)
            else:
                logging.debug('Message %s duplicated. ignored.' % name)

    def _protocolValidator(self):
        if self._messages == {}:
            logging.warning('Protocol initialized with no any loaded messages.')
            logging.warning('Consider there is _messageExtand() method to add messages?')

    def _wrap(self, *msg):
        (msgLen, msgType, msgData), = msg
        return struct.pack('!12s4sL%ds' % msgLen, self._name.encode(), msgType.encode(), msgLen, msgData.encode())

    def handler(self, peerConn, msgType, msgData):
        try:
            message = getattr(self, msgType)
            message.handler(peerConn, msgData)
            return True
        except:
            return False

    def getPeerInfoBy(self, *data):
        (query, ) = data
        if ':' in query:
            query = (query.split(':')[0], int(query.split(':')[1]))
        for (pid, peerInfo) in self._peersInfo.items():
            if peerInfo.host == query or query in peerInfo.pid:
                return (pid, peerInfo)
        return (None, None)

    def addPeer(self, *data):
        pid, addr, port = data
        if pid not in self._peersInfo and pid != str(self._peer.id):
            self._peersInfo[pid] = PeerInfo(pid, (addr, port), 'Active')
            return True
        else:
            return False

    def removePeer(self, *data):
        (target, ) = data
        try:
            if ':' in target:
                for (pid, peerInfo) in self._peersInfo.items():
                    if peerInfo.host == (target.split(':')[0], int(target.split(':')[1])):
                        self._peersInfo.pop(pid)
                        return True
            elif target in self._peersInfo:
                self._peersInfo.pop(target)
                return True
        except:
            traceback.print_exc()
        return False

    def broadcast(self, message, waitReply=False):
        raise NotImplementedError

    def exit(self):
        raise NotImplementedError


# -*- coding: utf-8 -*-
"""
-------------------------------------------------
  File: test.py
  Desc: 新闻类
  Author: CoderPig
  Date: 2019/3/22 0022 14:46
-------------------------------------------------
"""

import time
from collections import OrderedDict

class News:
    def __init__(self, _id, title=None, overview=None, url=None, image=None, publish_time=None, origin=None,
                 create_time=int(round(time.time() * 1000)), update_time=None):
        self._id = _id    # 新闻id
        self.title = title  # 新闻标题
        self.overview = overview  # 新闻概述
        self.url = url  # 新闻链接
        self.image = image  # 新闻配图
        self.publish_time = publish_time  # 新闻发布时间
        self.origin = origin  # 新闻来源
        self.create_time = create_time  # 新闻创建时间
        self.update_time = update_time  # 新闻更新时间

    def to_dict(self):
        news_dict = OrderedDict()
        news_dict['_id'] = self._id
        news_dict['title'] = self.title
        news_dict['overview'] = self.overview
        news_dict['url'] = self.url
        news_dict['image'] = self.image
        news_dict['publish_time'] = self.publish_time
        news_dict['origin'] = self.origin
        news_dict['create_time'] = self.create_time
        news_dict['update_time'] = self.update_time
        return news_dict


#!/usr/bin/env python
import numba
import numpy as np

__all__ = ["frame", "closing", "opening", "resample", "dcm", "overlapsave", "hamming"]

def frame(x, frame_length, frame_step, pad=True, pad_value=0j):
    """
    Creates frames out of the 1D array x that are frame_length
    long, and by stepping frame_step samples.

    Parameters
    ----------
    x : numpy array of shape (N,) where N is the number of samples

    frame_length : int
        Length of each frame

    frame_step : int
        Specifies how many samples to step for each frame
        this does not have to be equal to frame_length

    pad : bool (optional, default is True)
        Whether the end of x should be padded before forming the
        frames. If false, the frames will only be created out to the
        last frame that contains samples, if true it will be padded out
        so that all samples are contained in a frame but the last frame
        may contain some pad values

    pad_value : float or complex (optional, defaults to 0j)
        If ``pad`` is True, this is the value that should be used to pad

    Returns
    -------
    x_frame : a (M, frame_length) sized array
        the framed data

    Examples
    --------
    >>> import numpy as np
    >>> from siglib import frame
    >>> x = np.arange(10)
    >>> frame(x, 5, 5)
    array([[0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j],
           [5.+0.j, 6.+0.j, 7.+0.j, 8.+0.j, 9.+0.j]])
    """
    if pad:
        n_frames = int(np.ceil((x.shape[-1] - frame_length) / frame_step) + 1)
        n_pad = int((n_frames - 1) * frame_step + frame_length - x.shape[-1])
        x = np.concatenate([x, np.full(n_pad, pad_value)], axis=-1)
    else:
        n_frames = int(np.floor((x.shape[-1] - frame_length) / frame_step) + 1)

    # Explanation for the below:
    # * ``np.arange(frame_length).reshape(1, -1)`` creates a row vector from [0, frame_length)
    # * ``np.arange(n_frames).reshape(-1, 1)`` creates a column vector from [0, n_frames)
    # * multiplying by frame_step makes the sliding window slide frame_steps at a time
    # * adding the two together gives us a n_frames x frame_length matrix,
    #   where each row is a window
    x_frame_idx = np.arange(frame_length).reshape(1, -1) + frame_step * np.arange(
        n_frames
    ).reshape(-1, 1)
    return x[x_frame_idx]

def closing(x, ntaps):
    """
    Computes the closing morphological filter over ntaps of the input x

    Parameters
    -----------
    x : array of shape (N,)

    ntaps : int
        The width over which the min/max functions are calculated

    Returns
    --------
    y: array of shape (N,)
        The closing function over x

    Examples
    --------
    >>> import numpy as np
    >>> from siglib import closing
    >>> x = np.arange(10)
    >>> closing(x, 5)
    array([4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j,
           8.+0.j, 9.+0.j])
    """
    x = np.concatenate([x, np.ones(ntaps - 1) * x[-1]])
    xf = frame(x, frame_length=ntaps, frame_step=1, pad=False)
    d = np.max(xf, axis=-1)
    d = np.concatenate([np.ones(ntaps - 1) * d[0], d])
    df = frame(np.flip(d), frame_length=ntaps, frame_step=1, pad=False)
    c = np.min(df, axis=-1)
    return np.flip(c)

def opening(x, ntaps):
    """
    Computes the opening morphological filter over ntaps of the input x

    Parameters
    -----------
    x: array of shape (N,)

    ntaps: int
        The width over which the min max functions  are calculated

    Returns
    --------
    y: array of shape (N,)
        The opening function over x

    Examples
    --------
    >>> import numpy as np
    >>> from siglib import opening
    >>> x = np.arange(10)
    >>> opening(x, 5)
    array([0.+0.j, 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j,
           8.+0.j, 9.+0.j])
    """
    x = np.concatenate([x, np.ones(ntaps - 1) * x[-1]])
    xf = frame(x, frame_length=ntaps, frame_step=1, pad=False)
    e = np.min(xf, axis=-1)
    e = np.concatenate([np.ones(ntaps - 1) * e[0], e])
    ef = frame(np.flip(e), frame_length=ntaps, frame_step=1, pad=False)
    o = np.max(ef, axis=-1)
    return np.flip(o)

def resample(x, idx, ntaps):
    """
    Resamples the array x to the indicies in idx using sinc interpolation with
    ntaps number of points

    Parameters
    -----------
    x: array of shape (N,)

    idx: array of shape (M,)

    ntaps: int
        How many points to use for the sinc interpolation

    Returns
    --------
    y: array of shape (M,)
        The sinc interpolated signal at the indicies idx

    Example
    -------
    >>> import numpy as np
    >>> from siglib import resample
    >>> x = np.arange(10**2)
    >>> idx = np.array([45.567])
    >>> resample(x, idx, 5)
    array([44.96565413])
    """
    d_idx = np.ceil(np.arange(-ntaps / 2, ntaps / 2))
    idx_array = np.round(idx[:, np.newaxis]) + d_idx
    idx_array = np.asarray(idx_array, dtype=np.int32)
    sinc_array = idx[:, np.newaxis] - idx_array

    y = np.sum(x[idx_array] * np.sinc(sinc_array), axis=-1)
    return y

@numba.njit(fastmath=True)
def dcm(x, delay=1, pad=True, pad_value=1 + 0j):
    """
    Perform a delay-conjugate-multiply on
    some input signal ``x`` with delay ``delay``

    Parameters
    ----------
    x : array of shape (N,)

    delay : int (optional, defaults to 1)

    pad : bool (optional, defaults to True)
        Whether or not to pad the right end of ``x``

    pad_value : complex (optional, defaults to 1+0j)
        If ``pad`` is True, this is the value that should be used to pad.
        Note: defaults to ``1+0j`` to avoid issues in subsequent ``np.atan2``.

    Returns
    -------
    y : array of shape (N,)
        Delay-conjugate-multiply result

    Example
    -------
    >>> from siglib import dcm
    >>> x = np.array([1 + 3j, 4 + 2j, 5 + 6j, 1 + 0j])
    >>> dcm(x)
    array([10.-10.j, 32.+14.j,  5. -6.j,  1. +0.j])
    """
    if pad:
        x_pad = np.concatenate((x, np.full(delay, pad_value)), axis=-1)
        return x_pad[delay:] * np.conjugate(x_pad[:-delay])
    else:
        return x[delay:] * np.conjugate(x[:-delay])

def overlapsave(x, H, step):
    """
    Perform convolution of the 1D array x with a bank of fourier domain filters
    H. The convolution is done (as you might expect) by the overlapsave method.
    I know I could have the zero pad and fourier operations to get to H in this
    function, but this way you have to know a little about what you are doing.

    Parameters
    ----------
    x : array of shape (N,)

    H : array of shape (L,M,)
        The rows are zero padded and Fourier Transformed filters. There are L
        different filters each of length M << N. M specifies the length of the
        frames into which x is broken.

    step : int
        Specifies what the step is for each of the frame

    Returns
    -------
    xh : array of shape (L, N+M-step,)
        Each row is the convolution of x with the respective filter in H.

    Example
    -------
    >>> from siglib import overlapsave
    >>> x = np.array([ 0.+3.j, -4.+2.j, -4.+1.j, -5.+2.j, -4.-3.j,  2.+1.j,
    ...               -1.-2.j,  3.+3.j, -3.-1.j, -3.+2.j, -4.+0.j, -4.-4.j,
    ...               -3.-4.j, -4.-3.j, -4.+3.j, -3.+4.j, -4.-1.j, -5.+0.j,
    ...                4.+2.j,  2.-3.j])
    >>> h = np.array([-4.+4.j, -4.+3.j])
    >>> overlap = h.shape[-1] - 1
    >>> len_fft = int(2**(np.ceil(np.log2(8 * overlap))))
    >>> H = np.fft.fft(np.concatenate([h, np.zeros(len_fft - h.shape[-1])]))
    >>> step = H.shape[-1] - overlap
    >>> overlapsave(x, H, step)
    array([[-12.-12.j,  -1.-36.j,  22.-40.j,  25.-44.j,  42.-27.j,  13. +4.j,
          1. +6.j, -14. +5.j,  -5.-11.j,  19.-25.j,  22.-33.j,  48.-12.j,
         56. +8.j,  52. +3.j,  29.-28.j,   3.-52.j,  20.-37.j,  39.-28.j,
         -4. -7.j, -18.+24.j,   1.+18.j]])
    """
    # lets accept a 1D, 2D, or 3D H, in the first two cases we need to add a
    #   dimension for the array broadcasting in the X * H operation
    if H.ndim == 1:
        H = H[np.newaxis, np.newaxis, :]
    elif H.ndim == 2:
        H = H[:, np.newaxis, :]

    overlap = H.shape[-1] - step

    # since we will drop the first overlap samples in each row, lets zero pad
    # x by the overlap value, this will also make it so that the output
    # matches that of scipy.signal
    x = np.concatenate([np.zeros(overlap), x], axis=-1)

    N = x.shape[-1]

    x = frame(x, H.shape[-1], step, pad=True, pad_value=0j)
    X = np.fft.fft(x, axis=-1)
    XH = X * H
    xh = np.fft.ifft(XH, axis=-1)

    # for each row and for each filter take from index overlap till the end
    xh = xh[:, :, overlap:]

    # now reshape to get L rows and then drop the padding that happend at the
    # end during the frame operation
    xh = np.reshape(xh, (H.shape[0], xh.shape[-1] * xh.shape[-2]))
    xh = xh[:, :N]
    return xh

@numba.njit(fastmath=True)
def hamming(window_length):
    """
    A simple hamming window generator, I know, I know it is in scipy.signal
    with a bunch more OO windows and such but I just wanted something simple

    Parameters
    ----------
    window_length : int
        Length of the window

    Returns
    -------
    h : array of shape (N,)
        Contains the coeficients of the Hamming window

    Example
    -------
    >>> from siglib import hamming
    >>> hamming(5)
    array([0.08, 0.54, 1.  , 0.54, 0.08])
    """
    n = np.arange(0, window_length)
    return 0.54 - 0.46 * np.cos(2 * np.pi * n / (window_length - 1))


#**********************************************************************
# FILE: mpi_pi_reduce.py
# DESCRIPTION:
#   MPI pi Calculation Example - Python mpi4py version.
#   Collective Communication example:
#   This program calculates pi using a "dartboard" algorithm.  See
#   Fox et al.(1988) Solving Problems on Concurrent Processors, vol.1
#   page 207.  All processes contribute to the calculation, with the
#   master averaging the values for pi. This version uses mpi_reduce to
#   collect results
# AUTHOR: Blaise Barney. Adapted from Ros Leibensperger, Cornell Theory
#   Center. Converted to MPI: George L. Gusciora, MHPCC (1/95)
# LAST REVISED: 06/13/13 Blaise Barney
#   Adapted to Python / mpi4py by SH (27/10/18)
#**********************************************************************
from mpi4py import MPI
import numpy as np

DARTS = 50000     # number of throws at dartboard
ROUNDS = 100      # number of times "darts" is iterated
MASTER = 0        # task ID of master task

#**************************** functions ************************************

def dboard (darts):
    """
    Used in pi calculation example codes.
    Throw darts at board.  Done by generating random numbers
    between 0 and 1 and converting them to values for x and y
    coordinates and then testing to see if they "land" in
    the circle."  If so, score is incremented.  After throwing the
    specified number of darts, pi is calculated.  The computed value
    of pi is returned as the value of this function, dboard.
    """
    r = np.random.rand(darts,2)  # generate set of random numbers for x and y
    score = 0
    for n in range(darts):  # "throw darts at board"
        x_coord = (2.0 * r[n,0]) - 1.0
        y_coord = (2.0 * r[n,1]) - 1.0
        if (x_coord*x_coord + y_coord*y_coord) <= 1.0:
            score += 1  # if dart lands in circle, increment score
    pi = 4.0 * score/darts
    return pi

#**************************** initializations ************************************
#
comm = MPI.COMM_WORLD
numtasks = comm.Get_size()
taskid = comm.Get_rank()
print ("MPI task %d has started..." % taskid)
#
# Set seed for random number generator equal to task ID, to get different
# random numbers for each task.
#
np.random.seed(taskid)
#
#**************************** all tasks ************************************
avepi = 0
for i in range(ROUNDS):
#
# All tasks calculate pi using dartboard algorithm
#
    homepi = dboard(DARTS)
#
# Use MPI_Reduce to sum values of homepi across all tasks
# Master will store the accumulated value in pisum
# homepi is the send buffer
# pisum is the receive buffer (used by the receiving task only)
#
#    pisum = comm.reduce(homepi, None, root=MASTER)
    pisum = comm.reduce(homepi, op=MPI.SUM, root=MASTER)
#
# Master computes average for this iteration and all iterations
#
    if (taskid == MASTER):
        pi = pisum/numtasks
        avepi = ((avepi * i) + pi)/(i + 1)
        print("   After %8d throws, average value of pi = %10.8f" % (DARTS * (i + 1)*numtasks,avepi))

if (taskid == MASTER):
    print ("Real value of PI: 3.1415926535897")


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from __future__ import division
import numpy as np
import pandas as pd
import json
from pymystem3 import Mystem
import re
import io
import itertools

analyzer = Mystem()
strip_characters = '!`«»‰~@\'▲▼„"#$%^&*()_-+=[]\{\}°:;|•.,<>?/————–'
split_reg = re.compile('[\s\(\)\.,;"«»\'\[\]&<>]+')
punctuation = set(strip_characters)
num_reg = re.compile(r'[0-9)(:\-/№#]+?')
pos_map = {'A': 'ADJ',
            'ADV': 'ADV',
            'ADVPRO': 'PRON',
            'ANUM': 'ADJ',
            'APRO': 'PRON',
            'COM': 'NOUN',
            'CONJ': 'CCONJ',
            'INTJ': 'PART',
            'NUM': 'NUM',
            'PART': 'PART',
            'PR': 'ADP',
            'S': 'NOUN',
            'SPRO':'PRON',
            'V': 'VERB'}

with open('stop_words.json') as file:
        stop_words = json.load(file)

adress_reg = re.compile('(?:г\.|город|ул\.|улица|дом|д\.|стр\.|строение|проезд|бульвар)\s*[А-ЯЁа-яёa-z0-9\-\.]+?[,\s$][0-9]*')
adress_keywords_reg = re.compile('(?:г\.|город|ул\.|улица|дом|д\.|стр\.|строение|проезд|бульвар)')
nickname_reg = re.compile('@[a-zA-Z_\-0-9]+?[\s\.,]')

def remove_nickname_(string):
    string = nickname_reg.sub(string=string, repl=' ')
    return string

def tokenize(string, need_pos=False, remove_nickname=True):
    if remove_nickname:
        tokens = [lemmatize_pos_tag(i.lower().strip(strip_characters), need_pos=need_pos)
                  for i in re.split(split_reg, remove_nickname_(string)) if i.strip(strip_characters) and i not in punctuation
                  and i not in stop_words and not num_reg.match(i)]
    else:
        tokens = [lemmatize_pos_tag(i.lower().strip(strip_characters), need_pos=need_pos)
                  for i in re.split(split_reg, string) if i.strip(strip_characters) and i not in punctuation
                  and i not in stop_words and not num_reg.match(i)]
    valid_tokens = [token for token in tokens if token]
    return valid_tokens

def lemmatize_pos_tag(token, need_pos):
    if need_pos:
        analysis = analyzer.analyze(token)
        try:
            lemma = analysis[0]['analysis'][0]['lex']
            pre_pos = re.split('[,=]+?', analysis[0]['analysis'][0]['gr'])[0]
            pos = pos_map[pre_pos]
            lemma = lemma+'_'+pos
        except (KeyError, IndexError) as e:
            lemma = token
            pos = 'NOUN'
            lemma = lemma+'_'+pos
    else:
        try:
            lemma = analyzer.lemmatize(token)[0]
        except (KeyError, IndexError) as e:
            lemma = token
    return lemma


# Importing the tkinter module
from tkinter import*
from tkinter import ttk
from turtle import clear
from PIL import Image,ImageTk
import csv
from face_recognition import*
from tkinter import messagebox as mess

criminal_dict = {}      # --------> This dictionary will store & display the criminal's information

# Creating a class
class Criminal:

    def __init__(self,root) :      # --------> A constructor
        self.root=root
        self.root.geometry('1530x790+0+0')
        self.root.title('CRIMINAL MANAGEMENT SYSTEM')

        # variables
        self.var_case_id=StringVar()
        self.var_criminal_name=StringVar()
        self.var_criminal_no=StringVar()
        self.var_criminal_ide=StringVar()
        self.var_crime_date=StringVar()
        self.var_arrest_date=StringVar()
        self.var_criminal_nickname=StringVar()
        self.var_crime_location=StringVar()
        self.var_criminal_address=StringVar()
        self.var_criminal_gen=StringVar()
        self.var_criminal_age=StringVar()
        self.var_crime_type=StringVar()

        def prepare_dict():         # --------> A function

            with open('data.csv') as file_obj:

                # Create reader object by passing the file
                # object to reader method
                reader_obj = csv.reader(file_obj)

                # Iterate over each row in the csv
                # file using reader object
                for row in reader_obj:

                    update_dict = {
                        row[0] : {'name':(row[1])
                                    ,'criminal_no':(row[2])
                                    ,'criminal_nickname': (row[3])
                                    ,'crime_date':(row[4])
                                    ,'arrest_date':(row[5])
                                    ,'crime_loc':(row[6])
                                    ,'criminal_add':(row[7])
                                    ,'crime_type':(row[8])
                                    ,'criminal_ide':(row[9])
                                    ,'criminal_age':(row[10])
                                    ,'criminal_gen':(row[11])

                                    }
                    }
                    criminal_dict.update(update_dict)

        def write_criminal_record():
            filename = "criminal_records.csv"

            # writing to csv file
            with open(filename, 'w') as csvfile:
                # creating a csv writer object
                csvwriter = csv.writer(csvfile)

                # writing the data rows
                for k, v in criminal_dict.items():
                    # csvwriter.writerow(k)
                    lis = []
                    lis.append(k)
                    for i, l in criminal_dict[k].items():
                        # csvwriter.writerow([i, l])
                        lis.append(l)
                    csvwriter.writerow(lis)
            print(criminal_dict)
            print('\n')

        def add_record():      # -------------> A function which will add the criminal's record

            if(len(case_entry.get())==0):
                mess._show(title='Error!', message="Please Enter Case Id!!")
                return
            update_dict = {
                case_entry.get() : {'name':(criminal_name_entry.get())
                              ,'criminal_no':(criminal_no_entry.get())
                              ,'criminal_nickname': (criminal_nickname_entry.get())
                              ,'crime_date':(crime_date_entry.get())
                              ,'arrest_date':(arrest_date_entry.get())
                              ,'crime_loc':(crime_loc_entry.get())
                              ,'criminal_add':(criminal_add_entry.get())
                              ,'crime_type':(crime_type_entry.get())
                              ,'criminal_ide':(criminal_ide_entry.get())
                              ,'criminal_age':(criminal_age_entry.get())
                              ,'criminal_gen':(criminal_gen_entry.get())

                              }
            }
            criminal_dict.update(update_dict)

            write_criminal_record()

            mess._show(title='Status', message="Record Updated/Saved successfully!")
            print(criminal_dict)
            print('\n')

        def Clear():    # ----------> A function which will clear the criminal's data written in entry boxes
            case_entry.delete(0,'end')
            criminal_no_entry.delete(0,'end')
            criminal_name_entry.delete(0,'end')
            criminal_nickname_entry.delete(0,'end')
            crime_date_entry.delete(0,'end')
            arrest_date_entry.delete(0,'end')
            crime_loc_entry.delete(0,'end')
            criminal_add_entry.delete(0,'end')
            crime_type_entry.delete(0,'end')
            criminal_ide_entry.delete(0,'end')
            criminal_age_entry.delete(0,'end')
            criminal_gen_entry.delete(0,'end')

        def delete():    # ----------> A function which will delete the criminal's data
            key= case_entry.get()
            isPresent= criminal_dict.get(key)
            if( isPresent == None):
                mess._show(title='Delete Error!', message="Record Not Found!")
                return
            criminal_dict.pop(key)
            write_criminal_record()
            mess._show(title='Status', message="Record Deleted successfully!")

        prepare_dict()    # --------> Calling this function to read the criminal's data

        # Naming
        lbl_title=Label(self.root,text='CRIMINAL MANAGEMENT SYSTEM SOFTWARE',font=('times new roman',40,'bold'),bg='black',fg='gold')
        lbl_title.place(x=0,y=0,width=1530,height=70)

        # ncr logo

        img_logo=Image.open('Images/ncrlogo.png')
        img_logo=img_logo.resize((60,60),Image.ANTIALIAS)
        self.photo_logo=ImageTk.PhotoImage(img_logo)

        self.logo=Label(self.root,image=self.photo_logo)
        self.logo.place(x=80,y=5,width=60,height=60)

        # image framing

        img_frame=Frame(self.root,bd=2,relief=RIDGE,bg='white')
        img_frame.place(x=0,y=70,width=1530,height=130)

        # Image1

        img1=Image.open('Images/police1.png')
        img1=img1.resize((540,160),Image.ANTIALIAS)
        self.photo1=ImageTk.PhotoImage(img1)

        self.img_1=Label(img_frame,image=self.photo1)
        self.img_1.place(x=0,y=0,width=540,height=160)

        # Image2

        img2=Image.open('Images/police2.png')
        img2=img2.resize((540,160),Image.ANTIALIAS)
        self.photo2=ImageTk.PhotoImage(img2)

        self.img_2=Label(img_frame,image=self.photo2)
        self.img_2.place(x=540,y=0,width=540,height=160)

        # Image3

        img3=Image.open('Images/police3.png')
        img3=img3.resize((540,160),Image.ANTIALIAS)
        self.photo3=ImageTk.PhotoImage(img3)

        self.img_3=Label(img_frame,image=self.photo3)
        self.img_3.place(x=1080,y=0,width=540,height=160)

        # Main frame (starts after the image frame)
        main_frame=Frame(self.root,bd=2,relief=RIDGE,bg='white')
        main_frame.place(x=10,y=200,width=1500,height=560)

        # # Upper frame (inside the main frame)
        upper_frame=LabelFrame(main_frame,bd=2,relief=RIDGE,text='Criminal Information',font=('times new roman',11,'bold'),bg='white',fg='red')
        upper_frame.place(x=10,y=10,width=1480,height=270)

        # Labels Entry (inside the upper frame)
        #  Case ID
        case_id=Label(upper_frame,text='Case ID',font=('times new roman',11,'bold'),bg='white')
        case_id.grid(row=0,column=0,padx=2,sticky=W)

        case_entry=ttk.Entry(upper_frame,textvariable=self.var_case_id,width=22,font=('times new roman',11,'bold'))
        case_entry.grid(row=0,column=1,padx=2,sticky=W)

        #  Criminal Number
        criminal_no=Label(upper_frame,text='Criminal No.',font=('times new roman',11,'bold'),bg='white')
        criminal_no.grid(row=0,column=2,padx=2,sticky=W,pady=7)

        criminal_no_entry=ttk.Entry(upper_frame,textvariable=self.var_criminal_no,width=22,font=('times new roman',11,'bold'))
        criminal_no_entry.grid(row=0,column=3,padx=2,pady=7)

        #  Criminal Name
        criminal_name=Label(upper_frame,text='Criminal Name',font=('times new roman',11,'bold'),bg='white')
        criminal_name.grid(row=1,column=0,padx=2,sticky=W,pady=7)

        criminal_name_entry=ttk.Entry(upper_frame,textvariable=self.var_criminal_name,width=22,font=('times new roman',11,'bold'))
        criminal_name_entry.grid(row=1,column=1,padx=2,sticky=W,pady=7)

        #  Criminal Nickname
        criminal_nickname=Label(upper_frame,text='Criminal Nickname',font=('times new roman',11,'bold'),bg='white')
        criminal_nickname.grid(row=1,column=2,padx=2,sticky=W,pady=7)

        criminal_nickname_entry=ttk.Entry(upper_frame,textvariable=self.var_criminal_nickname,width=22,font=('times new roman',11,'bold'))
        criminal_nickname_entry.grid(row=1,column=3,padx=2,sticky=W,pady=7)

        #  Crime Date
        crime_date=Label(upper_frame,text='Crime Date',font=('times new roman',11,'bold'),bg='white')
        crime_date.grid(row=2,column=0,padx=2,sticky=W,pady=7)

        crime_date_entry=ttk.Entry(upper_frame,textvariable=self.var_crime_date,width=22,font=('times new roman',11,'bold'))
        crime_date_entry.grid(row=2,column=1,padx=2,sticky=W,pady=7)

        #  Arrest Date
        arrest_date=Label(upper_frame,text='Arrest Date',font=('times new roman',11,'bold'),bg='white')
        arrest_date.grid(row=2,column=2,padx=2,sticky=W,pady=7)

        arrest_date_entry=ttk.Entry(upper_frame,textvariable=self.var_arrest_date,width=22,font=('times new roman',11,'bold'))
        arrest_date_entry.grid(row=2,column=3,padx=2,sticky=W,pady=7)

        #  Crime Location
        crime_loc=Label(upper_frame,text='Crime Location',font=('times new roman',11,'bold'),bg='white')
        crime_loc.grid(row=3,column=0,padx=2,sticky=W,pady=7)

        crime_loc_entry=ttk.Entry(upper_frame,textvariable=self.var_crime_location,width=22,font=('times new roman',11,'bold'))
        crime_loc_entry.grid(row=3,column=1,padx=2,sticky=W,pady=7)

        #  Criminal Address
        criminal_add=Label(upper_frame,text='Criminal Address',font=('times new roman',11,'bold'),bg='white')
        criminal_add.grid(row=3,column=2,padx=2,sticky=W,pady=7)

        criminal_add_entry=ttk.Entry(upper_frame,textvariable=self.var_criminal_address,width=22,font=('times new roman',11,'bold'))
        criminal_add_entry.grid(row=3,column=3,padx=2,sticky=W,pady=7)

        #  Crime Type
        crime_type=Label(upper_frame,text='Crime Type',font=('times new roman',11,'bold'),bg='white')
        crime_type.grid(row=0,column=4,padx=2,sticky=W,pady=7)

        crime_type_entry=ttk.Entry(upper_frame,textvariable=self.var_crime_type,width=22,font=('times new roman',11,'bold'))
        crime_type_entry.grid(row=0,column=5,padx=2,sticky=W,pady=7)

        #  Criminal Identification
        criminal_ide=Label(upper_frame,text='Criminal Identification',font=('times new roman',11,'bold'),bg='white')
        criminal_ide.grid(row=1,column=4,padx=2,sticky=W,pady=7)

        criminal_ide_entry=ttk.Entry(upper_frame,textvariable=self.var_criminal_ide,width=22,font=('times new roman',11,'bold'))
        criminal_ide_entry.grid(row=1,column=5,padx=2,sticky=W,pady=7)

        #  Criminal Age
        criminal_age=Label(upper_frame,text='Criminal Age',font=('times new roman',11,'bold'),bg='white')
        criminal_age.grid(row=2,column=4,padx=2,sticky=W,pady=7)

        criminal_age_entry=ttk.Entry(upper_frame,textvariable=self.var_criminal_age,width=22,font=('times new roman',11,'bold'))
        criminal_age_entry.grid(row=2,column=5,padx=2,sticky=W,pady=7)

        #  Criminal Gender
        criminal_gen=Label(upper_frame,text='Criminal Gender',font=('times new roman',11,'bold'),bg='white')
        criminal_gen.grid(row=3,column=4,padx=2,sticky=W,pady=7)

        criminal_gen_entry=ttk.Entry(upper_frame,textvariable=self.var_criminal_gen,width=22,font=('times new roman',11,'bold'))
        criminal_gen_entry.grid(row=3,column=5,padx=2,sticky=W,pady=7)

        # Buttons (inside the upper frame)
        button_frame=Frame(upper_frame,bd=2,relief=RIDGE,bg='white')
        button_frame.place(x=5,y=200,width=620,height=45)

        # Add button

        button_add=Button(button_frame,text='Record Save',command=add_record,font=('times new roman',13,'bold'),width=14,bg='blue',fg='white')
        button_add.grid(row=0,column=0,padx=2,sticky=W,pady=7)

        # Update button

        button_up=Button(button_frame,text='Update',command=add_record,font=('times new roman',13,'bold'),width=14,bg='blue',fg='white')
        button_up.grid(row=0,column=1,padx=2,sticky=W,pady=7)

        # Clear button

        button_clr=Button(button_frame,text='Clear',command= Clear,font=('times new roman',13,'bold'),width=14,bg='blue',fg='white')
        button_clr.grid(row=0,column=2,padx=2,sticky=W,pady=7)

        # Delete button

        button_del=Button(button_frame,text='Delete',command= delete,font=('times new roman',13,'bold'),width=14,bg='blue',fg='white')
        button_del.grid(row=0,column=3,padx=2,sticky=W,pady=7)

        # Criminal image

        img4=Image.open('Images/criminal.png')
        img4=img4.resize((470,245),Image.ANTIALIAS)
        self.photo4=ImageTk.PhotoImage(img4)

        self.img_4=Label(upper_frame,image=self.photo4)
        self.img_4.place(x=1000,y=0,width=470,height=245)

        def reset_img():
            img4=Image.open('Images/criminal.png')
            img4=img4.resize((470,245),Image.ANTIALIAS)
            self.photo4=ImageTk.PhotoImage(img4)
            self.criminal_table.item(0, values=(f'',f'',f'',f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''))
            self.criminal_table.pack(fill=BOTH,expand=1)

            self.img_4=Label(upper_frame,image=self.photo4)
            self.img_4.place(x=1000,y=0,width=470,height=245)

        def criminal_img():  # -------> A function which will place the criminal's image on the GUI interface
            img4=Image.open('criminal.jpg')
            img4=img4.resize((470,245),Image.ANTIALIAS)
            self.photo4=ImageTk.PhotoImage(img4)

            self.img_4=Label(upper_frame,image=self.photo4)
            self.img_4.place(x=1000,y=0,width=470,height=245)

        def take_image_test():   # -------> A function which is used to test and detect the images from the images present in the charac folder
            crim_id=  image_test()
            criminal_img()
            criminal_details(crim_id)

        def take_vid_test():     # -----> A function through which front camera will be switched on and then will take images and then detect
            crim_id= vid_test()
            criminal_img()
            criminal_details(crim_id)

        # # Down frame (inside the main frame)
        down_frame=LabelFrame(main_frame,bd=2,relief=RIDGE,text='Criminal Information Table',font=('times new roman',11,'bold'),bg='white',fg='red')
        down_frame.place(x=10,y=335,width=1480,height=200)

        # Test frame (below the upper frame)

        test_frame=Frame(self.root,bd=2,relief=RIDGE,bg='white')
        test_frame.place(x=1023,y=490,width=475,height=48)

        # test on saved images
        test_imgs=Button(test_frame,text='Test on\nsaved images',command=take_image_test,font=('times new roman',10,'bold'),width=18,bg='blue',fg='white')
        test_imgs.grid(row=0,column=0,padx=1,sticky=W,pady=2)

        # test on front camera
        test_cam=Button(test_frame,text='Test on \nfront cam',command=take_vid_test,font=('times new roman',10,'bold'),width=18,bg='blue',fg='white')
        test_cam.grid(row=0,column=1,padx=1,sticky=W,pady=2)

        # Reset imgages
        reset_but=Button(test_frame,text='Reset\n',command=reset_img,font=('times new roman',10,'bold'),width=18,bg='blue',fg='white')
        reset_but.grid(row=0,column=3,padx=1,sticky=W,pady=2)

        # Table frame (inside the down frame)

        table_frame=Frame(down_frame,bd=2,relief=RIDGE,bg='white')
        table_frame.place(x=0,y=0,width=1470,height=172)

        # treeview functions ( a tabular representation of the data)
        def criminal_details(crim_id):   # -----> A function which will take criminal id , if the criminal id is not present , nothing will be displayed otherwise criminal's data will be displayed
            if(crim_id == -1):
                self.criminal_table.item(0, values=(f'',f'',f'',f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''
                                               ,f''))
            else:
                crime_info = criminal_dict.get(crim_id)
                # print(crime_info["criminal_no"])
                self.criminal_table.item(0, values=(f'{crim_id}',f'{crime_info["criminal_no"]}',f'{crime_info["name"]}',f'{crime_info["criminal_nickname"]}'
                                                ,f'{crime_info["crime_type"]}'
                                                ,f'{crime_info["crime_loc"]}'
                                                ,f'{crime_info["criminal_add"]}'
                                                ,f'{crime_info["criminal_age"]}'
                                                ,f'{crime_info["criminal_gen"]}'
                                                ,f'{crime_info["crime_date"]}'
                                                ,f'{crime_info["arrest_date"]}'
                                                ,f'{crime_info["criminal_ide"]}'))
            self.criminal_table.pack(fill=BOTH,expand=1)

        # Scroll bar (to scroll the horizontal & vertical axes)

        scroll_x=ttk.Scrollbar(table_frame,orient=HORIZONTAL)
        scroll_y=ttk.Scrollbar(table_frame,orient=VERTICAL)

        self.criminal_table=ttk.Treeview(table_frame,column=("1","2","3","4","5","6","7","8","9","10","11","12"),xscrollcommand=scroll_x.set,yscrollcommand=scroll_y.set)
        scroll_x.pack(side=BOTTOM,fill=X)
        scroll_y.pack(side=RIGHT,fill=Y)

        scroll_x.config(command=self.criminal_table.xview)
        scroll_y.config(command=self.criminal_table.yview)

        self.criminal_table.heading("1",text="Case ID")
        self.criminal_table.heading("2",text="Criminal No.")
        self.criminal_table.heading("3",text="Criminal Name")
        self.criminal_table.heading("4",text="Criminal Nickname")
        self.criminal_table.heading("5",text="Crime Type")
        self.criminal_table.heading("6",text="Crime Location")
        self.criminal_table.heading("7",text="Criminal Address")
        self.criminal_table.heading("8",text="Criminal Age")
        self.criminal_table.heading("9",text="Criminal Gender")
        self.criminal_table.heading("10",text="Crime Date")
        self.criminal_table.heading("11",text="Arrest Date")
        self.criminal_table.heading("12",text="Criminal Identification")

        self.criminal_table['show']='headings'

        self.criminal_table.column("1",width=100)
        self.criminal_table.column("2",width=100)
        self.criminal_table.column("3",width=100)
        self.criminal_table.column("4",width=100)
        self.criminal_table.column("5",width=100)
        self.criminal_table.column("6",width=100)
        self.criminal_table.column("7",width=100)
        self.criminal_table.column("8",width=100)
        self.criminal_table.column("9",width=100)
        self.criminal_table.column("10",width=100)
        self.criminal_table.column("11",width=100)
        self.criminal_table.column("12",width=100)

        self.criminal_table.pack(fill=BOTH,expand=1)
        self.criminal_table.insert(parent='', index=0, iid=0, text='', values=('','',''))

if __name__=="__main__" :
    root=Tk()
    obj=Criminal(root)
    root.mainloop()


import sys

from math import pi, cos, sin, sqrt
import numpy as np
from geometry_msgs.msg import Pose
from geometry_msgs.msg import Point
from geometry_msgs.msg import Quaternion

from tf.transformations import quaternion_from_matrix as m2q
from tf.transformations import quaternion_matrix as q2m

class DHmatrices:
	def __init__(self):
		""" Initializes 3 rotm and 3 htm and 3 link_vec
		@param number: number of IMUs. 2 for elbow only, 3 for arm only, 4 for include chest"""

		# self.rotm1 = np.zeros((3, 3), dtype = float)
		# self.rotm2 = np.zeros((3, 3), dtype = float)
		# self.rotm3 = np.zeros((3, 3), dtype = float)
		# link_vec1 = np.zeros(3, dtype = float)
		# link_vec2 = np.zeros(3, dtype = float)
		# link_vec3 = np.zeros(3, dtype = float)
		# self.htm1 = np.zeros((4, 4), dtype = float)
		# self.htm2 = np.zeros((4, 4), dtype = float)
		# self.htm3 = np.zeros((4, 4), dtype = float)

		self.rotm = np.zeros((3, 3), dtype = float)
		self.link_vec = np.zeros((3, 1), dtype = float)
		self.htm = np.zeros((4, 4), dtype = float)

		print("Matrices created")

	def angle_to_rotm(self, theta, alpha):
		'''
		https://blog.robotiq.com/how-to-calculate-a-robots-forward-kinematics-in-5-easy-steps
		'''
		self.rotm[0][0] = cos(theta)
		self.rotm[0][1] = -sin(theta) * cos(alpha)
		self.rotm[0][2] = sin(theta) * sin(alpha)
		self.rotm[1][0] = sin(theta)
		self.rotm[1][1] = cos(theta) * cos(alpha)
		self.rotm[1][2] = -cos(theta) * sin(alpha)
		self.rotm[2][1] = sin(alpha)
		self.rotm[2][2] = cos(alpha)
		return self.rotm

	def link_calculate(self, theta, a, d):
		'''
		https://blog.robotiq.com/how-to-calculate-a-robots-forward-kinematics-in-5-easy-steps
		'''
		self.link_vec[0] = a * cos(theta)
		self.link_vec[1] = a * sin(theta)
		self.link_vec[2] = d
		return self.link_vec

	def rotm_to_htm(self, rotm, link_vec):
		null_mat = np.concatenate((rotm, link_vec), axis=1)
		null_vec = np.zeros((1,4), dtype = float)
		null_vec[0][3] = 1.0
		self.htm = np.concatenate((null_mat, null_vec))
		return self.htm

	@staticmethod
	def matmul(mat1, mat2, mat3):
		return np.matmul(mat1, np.matmul(mat2, mat3))

	@staticmethod
	def htm_to_rotm(htm):
		return htm[np.ix_([0,3],[0,3])]

	@staticmethod
	def htm_to_quat(htm):
		quat = m2q(htm) # np.array([x, y, z, w])
		return quat

	@staticmethod
	def quat_to_htm(quat):
		htm = q2m(quat) # np.array([x, y, z, w])
		return htm

	@staticmethod
	def htm_to_vec(htm):
		# vec = htm[:3, 3:4]
		vec = htm[:3, 3]
		return vec

	@staticmethod
	def pose_to_htm(pose):
		pose_quat = np.array([pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w])
		pose_rotm = q2m(pose_quat) # actually 4x4 matrix created (a htm)
		pose_link = np.array([pose.position.x, pose.position.y, pose.position.z])
		pose_rotm[:3, 3] = pose_link
		return pose_rotm

	@staticmethod
	def htm_to_pose(htm):
		htm_quat = m2q(htm)
		pose_quat = Quaternion(htm_quat[0], htm_quat[1], htm_quat[2], htm_quat[3])
		pose_point = Point(htm[0,3], htm[1,3], htm[2,3])
		pose = Pose(pose_point, pose_quat)
		return pose

	@staticmethod
	def to_numpy(msg):
		if type(msg) == Point:
			result = np.array([msg.x, msg.y, msg.z])
		elif type(msg) == Quaternion:
			result = np.array([msg.x, msg.y, msg.z, msg.w])
		elif type(msg) == Pose:
			# basically pose_to_htm but I don't want to change it from static method
			pose_quat = np.array([msg.orientation.x, msg.orientation.y, msg.orientation.z, msg.orientation.w])
			pose_rotm = q2m(pose_quat) # actually 4x4 matrix created (a htm)
			pose_link = np.array([msg.position.x, msg.position.y, msg.position.z])
			pose_rotm[:3, 3] = pose_link
			result = pose_rotm
		else:
			print("unknown type")
			result = None
		return result

	@staticmethod
	def ee_goal_calculate(hand_pose, wrist_pose, r = 0.248050394992, param='c'):  # r calculated from ik
		'''
		Given hand_pose {Pose()}, parametrizes {z} such that it will be on UR5's workspace sphere.
		@returns ee_goal {np.array(4,4)} - then this will be used as Tee for the robot

		Sphere: (x-a)^2 + (y-b)^2 + (z-c)^2 = r2
						(a, b, c): Origin of the sphere -> Wrist origin
						(x, y, z): EE coordinates -> /tool0 position
						r: radius of the workspace
		'''
		ee_goal_htm = DHmatrices.to_numpy(hand_pose)
		wrist_htm = DHmatrices.to_numpy(wrist_pose)
		x, y, z = DHmatrices.htm_to_vec(ee_goal_htm)
		a, b, c = DHmatrices.htm_to_vec(wrist_htm)
		if param == 'x':
			param_x = sqrt(r**2 - (z-c)**2 - (y-b)**2) + a
			return param_x
		elif param == 'y':
			param_y = sqrt(r**2 - (x-a)**2 - (z-c)**2) + b
			return param_y
		elif param == 'z':
			param_z = sqrt(r**2 - (x-a)**2 - (y-b)**2) + c
			return param_z
		else:
			print("Unknown parameter selection")
			return 0


'''
Constraints:

nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109
'''

class Solution(object):
    def merge(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        last = m + n - 1

        # merge in reverse order
        while m > 0 and n > 0:
            if nums1[m - 1] > nums2[n - 1]:
                nums1[last] = nums1[m - 1]
                m -= 1
            else:
                nums1[last] = nums2[n - 1]
                n -= 1
            last -= 1
        # fill nums1 with leftover nums elements
        while n > 0:
            nums1[last] = nums2[n - 1]
            n, last = n - 1, last - 1


import matplotlib.pyplot as plt
import numpy as np
import torch
from torch import nn, optim
from torch.autograd import variable
from torchvision import datasets, models, transforms
from torchvision.datasets import ImageFolder
from PIL import Image
import torch.nn.functional as F
from collections import OrderedDict

import json
from args import get_args

from save_checkpoint import save_checkpoint

def training(model, criterion, optimizer, dataloaders, epochs=3):
    steps = 0
    for e in range(epochs):
        running_loss = 0
        for ii, (inputs, labels) in enumerate(dataloaders[0]):
            steps += 1

            model.cuda()
            inputs, labels = inputs.to('cuda'), labels.to('cuda')

            optimizer.zero_grad()
            outputs = model.forward(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

            running_loss += loss.item()

            if steps % 5 == 0:
                model.eval()
                valloss = 0
                accuracy=0

                for ii, (inputs2,labels2) in enumerate(dataloaders[1]):
                        optimizer.zero_grad()

                        inputs2, labels2 = inputs2.to('cuda') , labels2.to('cuda')
                        model.to('cuda:0')
                        with torch.no_grad():
                            outputs = model.forward(inputs2)
                            valloss = criterion(outputs,labels2)
                            ps = torch.exp(outputs).data
                            equality = (labels2.data == ps.max(1)[1])
                            accuracy += equality.type_as(torch.FloatTensor()).mean()

                valloss = valloss / len(dataloaders[1])
                accuracy = accuracy /len(dataloaders[1])

                print("Epoch: {}/{}... ".format(e+1, epochs),
                      "Training Loss: {:.4f}".format(running_loss/5),
                      "Loss {:.4f}".format(valloss),
                      "Accuracy: {:.4f}".format(accuracy),
                     )

                running_loss = 0

def main():
    args = get_args()

    data_dir = args.data_dir
    train_dir = data_dir + '/train'
    val_dir = data_dir + '/valid'
    test_dir = data_dir + '/test'

    training_transforms = transforms.Compose([transforms.RandomRotation(30), transforms.RandomResizedCrop(224),
                                              transforms.RandomHorizontalFlip(), transforms.ToTensor(),
                                              transforms.Normalize([0.485, 0.456, 0.406],
                                                                   [0.229, 0.224, 0.225])])

    validataion_transforms = transforms.Compose([transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(),
                                                 transforms.Normalize([0.485, 0.456, 0.406],
                                                                      [0.229, 0.224, 0.225])])
    testing_transforms = transforms.Compose([transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(),
                                             transforms.Normalize([0.485, 0.456, 0.406],
                                                                  [0.229, 0.224, 0.225])])

    image_datasets = [ImageFolder(train_dir, transform=training_transforms),
                      ImageFolder(val_dir, transform=validataion_transforms),
                      ImageFolder(test_dir, transform=testing_transforms)]

    dataloaders = [torch.utils.data.DataLoader(image_datasets[0], batch_size=64, shuffle=True),
                   torch.utils.data.DataLoader(image_datasets[1], batch_size=64, shuffle=False),
                   torch.utils.data.DataLoader(image_datasets[2], batch_size=64, shuffle=False)]

    model = getattr(models, args.arch)(pretrained=True)

    for param in model.parameters():
        param.requires_grad = False

    if args.arch == "vgg13":
        feature_num = model.classifier[0].in_features
        classifier = nn.Sequential(OrderedDict([
                                  ('fc1', nn.Linear(feature_num, int(args.hidden_units))),
                                  ('drop', nn.Dropout(p=0.5)),
                                  ('relu', nn.ReLU()),
                                  ('fc2', nn.Linear(int(args.hidden_units), len(image_datasets[0].class_to_idx))),
                                  ('output', nn.LogSoftmax(dim=1))]))
    elif args.arch == "densenet121":
        classifier = nn.Sequential(OrderedDict([
                                  ('fc1', nn.Linear(int(args.hidden_units), 500)),
                                  ('drop', nn.Dropout(p=0.6)),
                                  ('relu', nn.ReLU()),
                                  ('fc2', nn.Linear(int(args.hidden_units), len(image_datasets[0].class_to_idx))),
                                  ('output', nn.LogSoftmax(dim=1))]))

    model.classifier = classifier
    criterion = nn.NLLLoss()
    optimizer = optim.Adam(model.classifier.parameters(), lr=float(args.learning_rate))
    class_index = image_datasets[0].class_to_idx
    training(model, criterion, optimizer, dataloaders)
    model.class_to_idx = class_index
    path = args.save_dir
    save_checkpoint(path, model, optimizer, args, classifier)

if __name__== "__main__":
    main()


from django.conf import settings
from django.conf.urls.defaults import include, patterns, url
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.views.generic import TemplateView

admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    (r'^admin/', include(admin.site.urls)),

    url(r'^$', TemplateView.as_view(template_name='homepage.html'), name="home"),
    url(r'^events/$', TemplateView.as_view(template_name='events.html'), name="events"),
    url(r'^lodging/$', TemplateView.as_view(template_name='lodging.html'), name="lodging"),
    url(r'^gallery/$', TemplateView.as_view(template_name='gallery.html'), name="gallery"),
    url(r'^registry/$', TemplateView.as_view(template_name='registry.html'), name="registry"),
    url(r'^contact/$', 'messages.views.messages', name='contact'),
    url(r'^rsvp/', include('rsvp.urls')),
    url(r'^RSVP/', include('rsvp.urls')),
)

# Static URLs
urlpatterns += staticfiles_urlpatterns()

# Upload URLS
if settings.DEBUG:
    urlpatterns.insert(-2, url(r'^%s(?P<path>.*)' % settings.MEDIA_URL[1:],
        'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}))


fout = open('oops.txt','wt')
print('Oops, I created Imgoos.', file=fout)
fout.close()

import os
os.path.exists('Oops.txt')
os.path.exists('./oops.txt')
os.path.exists('waffles')
os.path.exists('.')
os.path.exists('..')

name = 'oops.txt'
os.path.isfile(name)
os.path.isdir(name)
os.path.isdir('.')
os.path.isabs('name')
os.path.isabs('/big/fake/name')
os.path.isabs('big/fake/name/withoua/a/leading/slash')
import shutil
shutil.copy('oops.txt','ohno.txt')
shutil.move('ohno.txt','ohno2.txt')
os.rename('ohno2.txt', 'ohno.txt')
os.link('oops.txt','yikes.txt')
os.path.isfile('yikes.txt')
os.path.islink('yikes.txt')
os.symlink('oops.txt','jeepers.txt')
os.path.islink('jeepers.txt')
os.chmod('oops.txt',0o400)
import stat
os.chmoe('oops.txt', stat.S_IRUSR)
os.path.abspath('oops.txt')
os.remove('oops.txt')
os.path.exists('oops.txt')
os.mkdir('poems')
os.path.exists('poems')
os.rmdir('poems')
os.path.exists('poems')
os.mkdir('poems')
os.listdir('poems')
os.mkdir('poems/mcintyre')
os.listdir('poems')
fout = open('poems/mcintyre/the_good_man','wt')
fout.write('Imgoos is king')
fout.close()
os.listdir('poems/mcintyre')
os.chdir('poems')
os.listdir('.')
import glob
glob.glob('m*')
glob.glob('??')
glob.glob('m??????e')
glob.glob('[klm]*e')
os.getpid()
os.getcwd()

import subprocess
import multiprocessing
import calendar
calendar.isleap(1900)
from datetime import date
halloween = date(2015,10,31)
halloween
halloween.day
halloween.month
halloween.isoformat()
now = date.today()
from datetime import timedelta
one_day = timedelta(days=1)
tomorrow = now + one_day
tomorrow
now + 17 * one_day
now - one_day
from datetime import time
noon = time(12,0,0)
noon
noon.hour
noon.microsecond
from datetime import datetime
some_day = datetime(2015,1,2,3,4,5,6)
some_day
some_day.isoformat()
now = datetime.now()
now.minute
now.microsecond
noon = time(12)
this_day = date.today()
noon_today = datetime.combine(this_day, noon)
noon_today
noon_today.date()
noon_today.time()
import time
now = time.time()
now
time.ctime(now)
time.localtime(now)
time.gmtime(now)
tm = time.localtime(now)
time.mktime(tm)
time.ctime(time.time())
fmt = "It's %A, %B %d, %Y, local time %I:%M:%S%p"
t = time.localtime()
t
time.strftime(fmt, t)
fmt = "%Y-%m-%d"
time.strptime("2015-06-02", fmt)

import locale
from datetime import date
halloween = date(2015, 10, 31)
for lang_country in ['ko-kr', 'en-us']:
    locale.setlocale(locale.LC_TIME, lang_country)
    halloween.strftime('%A, %B %d')

names = locale.locale_alias.keys()
good_names = [name for name in names if len(name) == 5 and name[2] == '_']
good_names[:5]
de = [name for name in names if name.startswith('de')]
de
# arrow dateutil iso8601 fleming

Python/처음 시작하는 파이썬(Introducing Python)/Chap_10.py