'''Interactions that leverage the Empirical Interpolation Method (EIM) to allow
the emulation of parameters in which the coordinate-space potential is not
affine.
'''

from typing import Callable
import numpy as np
from scipy.stats import qmc

from .interaction import Interaction, InteractionSpace, couplings
from .constants import HBARC, DEFAULT_RHO_MESH
from .spin_orbit import SpinOrbitTerm

def max_vol(basis, indxGuess):
    r'''basis looks like a long matrix, the columns are the "pillars" V_i(x):
        [   V_1(x)
            V_2(x)
            .
            .
            .
        ]
        indxGuess is a first guess of where we should "measure", or ask the questions

    '''
    nbases = basis.shape[1]
    interpBasis = np.copy(basis)

    for ij in range(len(indxGuess)):
        interpBasis[[ij,indxGuess[ij]],:] = interpBasis[[indxGuess[ij],ij],:]
    indexing = np.array(range(len(interpBasis)))

    for ij in range(len(indxGuess)):
        indexing[[ ij,indxGuess[ij] ]] = indexing[[ indxGuess[ij],ij ]]

    for iIn in range(1, 100):
        B = np.dot(interpBasis, np.linalg.inv(interpBasis[:nbases]))
        b = np.max(B)
        if b > 1:

            p1, p2 = np.where(B == b)[0][0], np.where(B == b)[1][0]
            interpBasis[[p1,p2],:] = interpBasis[[p2,p1],:]
            indexing[[p1,p2]] = indexing[[p2,p1]]
        else:
            break
        #this thing returns the indexes of where we should measure
    return np.sort(indexing[:nbases])

class InteractionEIM(Interaction):
    def __init__(self,
        coordinate_space_potential: Callable[[float, np.array], float], # V(r, theta)
        n_theta: int, # How many parameters does the interaction have?
        mu: float, # reduced mass (MeV)
        energy: float, # E_{c.m.}
        ell: int,
        training_info: np.array,
        Z_1: int = 0, # atomic number of particle 1
        Z_2: int = 0, # atomic number of particle 2
        R_C: float = 0.0, # Coulomb "cutoff"
        is_complex: bool = False,
        spin_orbit_term: SpinOrbitTerm = None,
        n_basis: int = None,
        explicit_training: bool = False,
        n_train: int = 1000,
        rho_mesh: np.array = DEFAULT_RHO_MESH,
        match_points: np.array = None
    ):
        r'''
        Parameters:
            coordinate_space_potential (Callable[[float,ndarray],float]): V(r,
                theta) where theta are the interaction parameters
            n_theta (int): number of interaction parameters
            mu (float): reduced mass (MeV); converted to 1/fm
            energy (float): center-of-mass scattering energy
            ell (int): angular momentum
            training_info (ndarray): Either (1) parameters bounds or (2)
                explicit training points

                If (1):
                    This is a 2-column matrix. The first column are the lower
                    bounds. The second are the upper bounds. Each row maps to a
                    single parameter.

                If (2):
                    This is an MxN matrix. N is the number of parameters. M is
                    the number of samples.
            Z_1 (int): charge of particle 1
            Z_2 (int): charge of particle 2
            R_C (float): Coulomb "cutoff" radius
            is_complex (bool): Is the interaction complex (e.g. optical
                potentials)?
            spin_orbit_term (SpinOrbitTerm): spin-orbit part of the interaction
            n_basis (int): number of basis states, or "pillars" in $\hat{U}$ approximation
            explicit_training (bool): Is training_info (1) or (2)? (1) is
                default
            n_train (int): How many snapshots to generate? Ignored if
                explicit_training is True.
            rho_mesh (ndarray): coordinate-space points at which the interaction
                is generated (used for training)
            match_points (ndarray): $\rho$ points where agreement with the true
                potential is enforced

        Attributes:
            s_mesh (ndarray): $s$ points
            singular_values (ndarray): `S` in `U, S, Vt = numpy.linalg.svd(...)`
            snapshots (ndarray): pillars, columns of `U`
            match_indices (ndarray): indices of points in $\rho$ mesh that are
                matched to the true potential
            match_points (ndarray): points in $\rho$ mesh that are matched to
                the true potential
            r_i (ndarray): copy of `match_points` (???)
            Ainv (ndarray): inverse of A matrix (Ax = b)
        '''

        super().__init__(coordinate_space_potential, n_theta, mu, energy, ell,
            Z_1=Z_1, Z_2=Z_2, R_C=R_C, is_complex=is_complex, spin_orbit_term=spin_orbit_term)

        self.s_mesh = rho_mesh.copy()
        # Generate a basis used to approximate the potential.
        # Did the user specify the training points?
        if explicit_training:
            snapshots = np.array([self.tilde(rho_mesh, theta) for theta in training_info]).T
        else:
            # Generate training points using the user-provided bounds.
            sampler = qmc.LatinHypercube(d=len(training_info))
            sample = sampler.random(n_train)
            train = qmc.scale(sample, training_info[:, 0], training_info[:, 1])
            snapshots = np.array([self.tilde(rho_mesh, theta) for theta in train]).T

        U, S, _ = np.linalg.svd(snapshots, full_matrices=False)
        self.singular_values = np.copy(S)

        if match_points is None:
            if n_basis is None:
                n_basis = n_theta
            self.snapshots = np.copy(U[:, :n_basis])
            # random r points between 0 and 2π fm
            i_max = self.snapshots.shape[0] // 2
            di = i_max // (n_basis - 1)
            i_init = np.arange(0, i_max + 1, di)
            self.match_indices = max_vol(self.snapshots, i_init)
                # np.random.randint(0, self.snapshots.shape[0], size=self.snapshots.shape[1]))
            self.match_points = rho_mesh[self.match_indices]
            self.r_i = np.copy(self.match_points)
        else:
            n_basis = match_points.size
            self.snapshots = np.copy(U[:, :n_basis])
            self.match_points = np.copy(match_points)
            self.match_indices = np.array([np.argmin(np.abs(rho_mesh - ri)) for ri in self.match_points])
            self.r_i = rho_mesh[self.match_indices]

        self.Ainv = np.linalg.inv(self.snapshots[self.match_indices])

    def coefficients(self,
        alpha: np.array
    ):
        r'''Computes the EIM expansion coefficients.

        Parameters:
            alpha (ndarray): interaction parameters

        Returns:
            coefficients (ndarray): EIM expansion coefficients

        '''
        u_true = self.tilde(self.r_i, alpha)
        return 1/self.k, self.Ainv @ u_true

    def tilde_emu(self,
        alpha: np.array
    ):
        r'''Emulated interaction = $\hat{U}(s, \alpha, E)$

        Parameters:
            alpha (ndarray): interaction parameters

        Returns:
            u_hat (ndarray): emulated interaction

        '''
        _, x = self.coefficients(alpha)
        emu = np.sum(x * self.snapshots, axis=1)
        return emu

    def basis_functions(self, s_mesh: np.array):
        r'''$u_j$ in $\tilde{U} \approx \hat{U} \equiv \sum_j \beta_j(\alpha) u_j$

        Parameters:
            s_mesh (ndarray): $s$ mesh points

        Returns:
            u_j (ndarray): "pillars" (MxN matrix; M = number of mesh points; N = number of pillars)

        '''
        return np.copy(self.snapshots)

class InteractionEIMSpace(InteractionSpace):
    def __init__(self,
        coordinate_space_potential: Callable[[float, np.array], float], # V(r, theta)
        n_theta: int, # How many parameters does the interaction have?
        mu: float, # reduced mass (MeV)
        energy: float, # E_{c.m.}
        l_max: int,
        training_info: np.array,
        Z_1: int = 0, # atomic number of particle 1
        Z_2: int = 0, # atomic number of particle 2
        R_C: float = 0.0, # Coulomb "cutoff"
        is_complex: bool = False,
        spin_orbit_potential: Callable[[float, np.array, float], float] = None, #V_{SO}(r, theta, l•s)
        n_basis: int = None,
        explicit_training: bool = False,
        n_train: int = 1000,
        rho_mesh: np.array = DEFAULT_RHO_MESH,
        match_points: np.array = None
    ):
        r'''Generates a list of $\ell$-specific, EIMed interactions.

        Parameters:
            coordinate_space_potential (Callable[[float,ndarray],float]): V(r, theta)
            n_theta (int): number of parameters
            mu (float): reduced mass
            energy (float): center-of-mass, scattering energy
            l_max (int): maximum angular momentum
            training_info (ndarray): See `InteractionEIM` documentation.
            Z_1 (int): charge of particle 1
            Z_2 (int): charge of particle 2
            R_C (float): Coulomb "cutoff" radius
            is_complex (bool): Is the interaction complex?
            spin_orbit_potential (Callable[[float, np.array, float], float]):
                used to create a `SpinOrbitTerm`
            n_basis (int): number of pillars --- basis states in $\hat{U}$ expansion
            explicit_training (bool): See `InteractionEIM` documentation.
            n_train (int): number of training samples
            rho_mesh (ndarray): discrete $\rho$ points
            match_points (ndarray): $\rho$ points where agreement with the true
                potential is enforced

        Returns:
            instance (InteractionEIMSpace): instance of InteractionEIMSpace

        Attributes:
            interactions (list): list of `InteractionEIM`s
        '''
        self.interactions = []
        if spin_orbit_potential is None:
            for l in range(l_max+1):
                self.interactions.append(
                    [InteractionEIM(coordinate_space_potential, n_theta, mu,
                        energy, l, training_info, Z_1=Z_1, Z_2=Z_2, R_C=R_C,
                        is_complex=is_complex, n_basis=n_basis, explicit_training=explicit_training,
                        n_train=n_train, rho_mesh=rho_mesh, match_points=match_points)]
                )
        else:
            for l in range(l_max+1):
                self.interactions.append(
                    [InteractionEIM(coordinate_space_potential, n_theta, mu,
                        energy, l, training_info, Z_1=Z_1, Z_2=Z_2, R_C=R_C,
                        is_complex=is_complex,
                        spin_orbit_term=SpinOrbitTerm(spin_orbit_potential,
                        lds), n_basis=n_basis,
                        explicit_training=explicit_training, n_train=n_train,
                        rho_mesh=rho_mesh, match_points=match_points) for lds in
                        couplings(l)]
                )


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

import pandas as pd
import numpy as np
from glob import glob
from os.path import basename, isfile, join
from time_event import trialdef, cumulative_changes

def session_info(f):
    f = basename(f).split(".")[0]
    subject = int(f[3:6])
    session = int(f[6:])
    return subject, session

def read_session(f):
    df = pd.read_csv(f, sep="\t", engine="c",
                     header=None, names=["time", "event"])
    df["subject"], df["session"] = session_info(f)
    return df

def gtrialdef(events, pattern):
    return trialdef(events.as_matrix(), np.array(pattern))

def gcumulative_changes(trial):
    idx = trial > 0
    trial[idx] = cumulative_changes(trial[idx])
    return trial

def relative_time(t):
    return t - t.iloc[0]

def create_modular_theory_file(how="acquisition", overwrite=False):
    path = "../data/modular_theory2007"
    filename = "Data_Modular_Theory2007.csv"
    if overwrite or not isfile(join(path, filename)):
        files = glob(join(path, "raw_data", "*.txt"))

        print("Loading files...", end="")
        df = pd.concat([read_session(f) for f in files])
        print("done.")

        print("Assigning conditions...", end="")
        assign_phase(df, 1, 30, "acquisition")
        assign_phase(df, 31, 65, "extinction")
        assign_phase(df, 66, 75, "reacquisition")
        assign_phase(df, 76, 120, "repeated_extinction")
        assign_extinction_conditions(df, [437, 440, 444, 445], "FI30")
        assign_extinction_conditions(df, [434, 435, 439, 443], "FI60")
        assign_extinction_conditions(df, [433, 438, 441, 442], "FI120")

        df["phase"] = df.phase.astype("category")
        df["extinction_condition"] = df.extinction_condition.astype("category")
        print("done.")

        if how == "acquisition":
            df = df[df.phase=="acquisition"]

        print("Defining trials...", end="")
        trial_types = {"FI30": 50, "FI60": 51, "FI120": 52}
        for trialname in trial_types:
            startcode = trial_types[trialname]
            df["trial_"+trialname] = df.groupby(["subject", "session"]).event.transform(gtrialdef, [startcode, 53])
            df["trial_"+trialname] = df.groupby("subject")["trial_"+trialname].transform(gcumulative_changes)
            df["time_"+trialname] = df.groupby(["subject", "trial_"+trialname]).time.transform(relative_time)
        print("done.")

        print("Saving...", end="")
        df.to_csv(join(path, filename), index=False)
        print("done.")
    else:
        print("Creating file...done (already present)")

def assign_phase(df, start, stop, name):
    if "phase" not in df.columns:
        df["phase"] = ""
    df.ix[(df.session >= start) & (df.session <= stop), "phase"] = name

def assign_extinction_conditions(df, subjects, name):
    if "extinction_condition" not in df.columns:
        df["extinction_condition"] = ""
    df.ix[df.subject.isin(subjects), "extinction_condition"] = name

if __name__ == "__main__":
    create_modular_theory_file()


from itertools import combinations
import copy

SPACE = 0
WALL = 1
VIRUS = 2

n, m = map(int, input().split())

lab_map = []

for _ in range(n):
    lab_map.append(list(map(int, input().split())))

# 빈 벽의 위치와 개수를 모두 확인
# 모든 바이러스의 위치와 개수 확인
number_space = 0
spaces = []
viruses = []

for i in range(n):
    for j in range(m):
        if lab_map[i][j] == VIRUS:
            viruses.append((i, j))
            continue
        if lab_map[i][j] == SPACE:
            number_space += 1
            spaces.append((i, j))

# 3개 벽을 세우는 모든 경우의 수 반복
x_plus = [1, 0, 0, -1]
y_plus = [0, 1, -1, 0]
answer = 0
for random_spaces in combinations(spaces, 3):
    simulation_map = copy.deepcopy(lab_map)
    for random_space in random_spaces:
        i, j = random_space
        simulation_map[i][j] = WALL

    stack = copy.deepcopy(viruses)

    # 각 경우 중 바이러스와 연결된 빈 방을 바이러스로 바꿈

    convert_count = 0
    while stack:
        x, y = stack.pop()
        for i in range(0, 4):
            tmp_x = x + x_plus[i]
            tmp_y = y + y_plus[i]
            if tmp_x >= n or tmp_y >= m or tmp_x < 0 or tmp_y < 0:
                continue
            if simulation_map[tmp_x][tmp_y] == SPACE:
                simulation_map[tmp_x][tmp_y] = VIRUS
                stack.append((tmp_x, tmp_y))
                convert_count += 1

    # 최대 빈 방 개수 갱신
    # print(convert_count)
    # print(answer)
    answer = max(answer, number_space - convert_count - 3)

print(answer)


from itertools import cycle
from typing import Tuple, List, Optional, Union, Any, Sequence

import numpy as np
import torch
import torch.utils.data
import torchvision
from torch import nn
from torchvision import transforms

"""
Датасеты могут быть двух типов:
1. Элемент - число или тензор. В этом случае элемент рассматривается как x в GAN
2. Элемент - tuple длины 2. В этом случае 1-ый элемент tuple - x, 2-й - y (условие)
y - либо число, либо тензор, либо tuple с числами/тензорами

Обёртка в виде UnifiedDatasetWrapper приводит оба типа датасетов ко 2-му (для датасета 1-го типа y = None).
Обёртку следует использовать пользователю.
"""

class RandomDataloader(torch.utils.data.DataLoader):
    def __init__(self, dataset: torch.utils.data.Dataset, batch_size: int, *args, **kwargs):
        sampler = torch.utils.data.sampler.RandomSampler(dataset, replacement=True)
        random_sampler = torch.utils.data.sampler.BatchSampler(sampler, batch_size=batch_size,
                                                               drop_last=False)

        super().__init__(dataset, batch_sampler=random_sampler, *args, **kwargs)

def get_random_infinite_dataloader(dataset: torch.utils.data.Dataset, batch_size: int, *args, **kwargs):
    return cycle(RandomDataloader(dataset, batch_size=batch_size, *args, **kwargs))

def collate_fn(els_list: Sequence[Union[Tuple, int, torch.Tensor]]):
    if isinstance(els_list[0], tuple):
        return tuple(collate_fn(list(a)) for a in zip(*els_list))
    elif isinstance(els_list[0], int):
        return torch.Tensor(els_list)
    elif isinstance(els_list[0], torch.Tensor):
        return torch.stack(tuple(els_list))
    elif els_list[0] is None:
        return None
    else:
        raise RuntimeError

def stack_batches(batches_list):
    if isinstance(batches_list[0], tuple):
        return tuple(stack_batches(list(a)) for a in zip(*batches_list))
    elif isinstance(batches_list[0], torch.Tensor):
        return torch.concat(batches_list, dim=0)
    elif batches_list[0] is None:
        return None

def move_batch_to(batch, device):
    if isinstance(batch, tuple):
        return tuple(move_batch_to(subbatch, device) for subbatch in batch)
    elif batch is None:
        return None
    else:
        return batch.to(device)

class LinearTransform(nn.Module):
    def __init__(self, min_to: float, max_to: float, dim: int) -> None:
        super().__init__()
        self.min_to = min_to
        self.max_to = max_to
        self.dim = dim

    def forward(self, X) -> torch.Tensor:
        mins = X.min(dim=self.dim).values
        maxs = X.max(dim=self.dim).values

        coefs = (self.max_to - self.min_to) / (maxs - mins)
        biases = self.min_to - coefs * mins

        shape = list(X.shape)
        shape[self.dim] = 1

        coefs = coefs.reshape(*shape)
        biases = biases.reshape(*shape)

        y = coefs * X + biases
        y = torch.clip(y, self.min_to, self.max_to)  # clipping for making sure

        return y

class ExtractIndicesDataset(torch.utils.data.Dataset):
    def __init__(self, dataset, indices: Union[Tuple[int], int]):
        self.dataset = dataset
        self.indices = indices

    def __len__(self):
        return len(self.dataset)

    def __getitem__(self, n: int):
        obj = self.dataset[n]
        if isinstance(self.indices, int):
            return obj[self.indices]
        else:
            return tuple(obj[i] for i in self.indices)

class UnifiedDatasetWrapper(torch.utils.data.Dataset):
    """
    Обёртка для поддержки датасетов обоих типов
    """
    def __init__(self, dataset: torch.utils.data.Dataset):
        self.dataset = dataset
        self.inverse_transform = getattr(dataset, 'inverse_transform', None)

    def __len__(self) -> int:
        return len(self.dataset)

    def __getitem__(self, n: int) -> Tuple[Any, Any]:
        element = self.dataset[n]
        if isinstance(element, tuple):
            assert len(element) == 2
            x, y = element
        else:
            x, y = element, None
        return x, y

def get_default_image_transform(dim: int) -> transforms.Compose:
    return transforms.Compose([
        transforms.ToTensor(),
        # Переводим цвета пикселей в отрезок [-1, 1] афинным преобразованием, изначально они в отрезке [0, 1]
        transforms.Normalize(tuple(0.5 for _ in range(dim)), tuple(0.5 for _ in range(dim)))
    ])

default_image_transform = get_default_image_transform(3)

def get_cifar_10_dataset(root='./cifar10', train: bool = True, keep_labels: bool = True, kept_labels: Optional[List[int]] = None):
    """
    :param kept_labels: images with which labels should be used
    """
    cifar_dataset = torchvision.datasets.CIFAR10(root=root, train=train, download=True,
                                                 transform=default_image_transform, )

    if kept_labels is not None:
        kept_indices = []
        for i in range(len(cifar_dataset)):
            if cifar_dataset[i][1] in kept_labels:
                kept_indices.append(i)

        cifar_dataset = torch.utils.data.Subset(cifar_dataset, kept_indices)

    if not keep_labels:
        cifar_dataset = ExtractIndicesDataset(cifar_dataset, indices=0)
    return cifar_dataset

def get_mnist_dataset(root='./mnist', train: bool = True, keep_labels: bool = True):
    mnist_dataset = torchvision.datasets.MNIST(root=root, train=train, download=True,
                                               transform=get_default_image_transform(1))

    if not keep_labels:
        mnist_dataset = ExtractIndicesDataset(mnist_dataset, indices=0)
    return mnist_dataset

class PhysicsDataset(torch.utils.data.Dataset):
    """
    one element: (energy deposit, (point, momentum))
    """
    def __init__(self, energy: torch.Tensor, point: torch.Tensor, momentum: torch.Tensor,
                 transform=None, inverse_transform=None) -> None:
        """
        TODO: указать сигнатуры transform и inverse_transform через typing
        transform(energy, point, momentum) - tensors as batches or single
        inverse_transform(energy, point, momentum)
        """
        self.transform = transform
        self.inverse_transform = inverse_transform  # for outer use

        if transform is not None:
            energy = self.transform(energy)

        self.energy = energy
        self.point = point
        self.momentum = momentum

    def __getitem__(self, idx: int) -> tuple:
        return self.energy[idx], (self.point[idx], self.momentum[idx])

    def __len__(self) -> int:
        return self.energy.shape[0]

# принимают batch-и x-ов
def log1p_transform(x: torch.Tensor):
    return torch.log1p(x)

def log1p_inverse_transform(x: torch.Tensor):
    return torch.expm1(x)

def get_physics_dataset(path: str, train: bool = True, val_ratio: float = 0.5,
                        log1p_energy: bool = True) -> torch.utils.data.Dataset:
    TRAIN_VAL_SPLIT_SEED = 0x3df3fa

    data_train = np.load(path)

    np.random.seed(TRAIN_VAL_SPLIT_SEED)
    dataset_size = len(data_train['EnergyDeposit'])
    val_size = int(dataset_size * val_ratio)

    all_indices = np.arange(dataset_size)
    val_indices = np.random.choice(all_indices, size=val_size, replace=False)
    val_mask = np.zeros(dataset_size, dtype=bool)
    val_mask[val_indices] = True
    train_indices = all_indices[~val_mask]
    indices = train_indices if train else val_indices

    energy = torch.tensor(data_train['EnergyDeposit'][indices]).float()
    energy = torch.permute(energy, dims=(0, 3, 1, 2))
    point = torch.tensor(data_train['ParticlePoint'][:, :2][indices]).float()
    momentum = torch.tensor(data_train['ParticleMomentum'][indices]).float()

    transform, inverse_transform = None, None
    if log1p_energy:
        transform = log1p_transform
        inverse_transform = log1p_inverse_transform

    return PhysicsDataset(energy, point, momentum,
                          transform=transform, inverse_transform=inverse_transform)


#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from scapy.all import *
import time
import os

hostip = os.environ['HOST_IP']
destip = os.environ['DEST_IP']

print("Container started")
while True:
	send(IP(src=hostip, dst=destip)/ICMP())
	print("Sent from", hostip, "to", destip,"sleep 2.5 mins")
	time.sleep(150)


# coding: utf-8

import numpy as np
import matplotlib.pyplot as plt
from multiprocessing import Pool
import os

def draw_dual(i, top, bottom):
    fig = plt.figure(figsize=(4.56, 1.44))
    # ax = fig.add_subplot(111)
    ax = fig.add_axes([0, 0, 1, 1])
    ax.patch.set_facecolor('k')
    ax.plot(top[:, 0], top[:, 1], color='r', linewidth=0.5, zorder=10)
    ax.plot(bottom[:, 0], bottom[:, 1], color='c', linewidth=0.5, zorder=10)
    ax.scatter(top[i, 0], top[i, 1], color='r', linewidth=1, zorder=20)
    ax.scatter(bottom[i, 0], bottom[i, 1], color='c', linewidth=1, zorder=20)
    ylim = ax.get_ylim()
    ylim = max(map(abs, ylim))
    ax.set_ylim(-1.1 * ylim, 1.1 * ylim)
    xlim = ax.get_xlim()
    ax.set_xlim(-3, xlim[1])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_position(('data', 0))
    ax.spines['left'].set_linewidth(0.5)
    ax.spines['left'].set_color('w')
    ax.spines['bottom'].set_position(('data', 0))
    ax.spines['bottom'].set_linewidth(0.5)
    ax.spines['bottom'].set_color('w')
    plt.savefig('./series/time_history' + str(i), dpi=600, facecolor='none')
    plt.clf()
    plt.close()

def draw_single(i, eq):
    fig = plt.figure(figsize=(4.56, 1.44))
    # ax = fig.add_subplot(111)
    ax = fig.add_axes([0, 0, 1, 1])
    ax.patch.set_facecolor('k')
    ax.plot(eq[:, 0], eq[:, 1], color='c', linewidth=0.5, zorder=10)
    ax.scatter(eq[i, 0], eq[i, 1], color='r', linewidth=1, zorder=20)
    ylim = ax.get_ylim()
    ylim = max(map(abs, ylim))
    ax.set_ylim(-1.1 * ylim, 1.1 * ylim)
    xlim = ax.get_xlim()
    ax.set_xlim(-3, xlim[1])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_position(('data', 0))
    ax.spines['left'].set_linewidth(0.5)
    ax.spines['left'].set_color('w')
    ax.spines['bottom'].set_position(('data', 0))
    ax.spines['bottom'].set_linewidth(0.5)
    ax.spines['bottom'].set_color('w')
    plt.savefig('./series/time_history' + str(i), dpi=600, facecolor='none')
    plt.clf()
    plt.close()

def read_config():
    with open('config.txt', 'r', encoding='utf-8') as fConfig:
        temp = fConfig.readline()
        threads = int(fConfig.readline().strip())
        temp = fConfig.readline()
        gms = int(fConfig.readline().strip())
        if gms != 1 and gms != 2:
            return (threads, gms, False)
        else:
            return (threads, gms, True)

def main():
    config = read_config()
    if not config[2]:
        print('Number of GMs should be 1 or 2!')
        return
    threads = config[0]
    gms = config[1]

    if not os.path.exists('./series'):
        os.makedirs('./series')

    print('Parent process %s. ' % os.getpid())
    p = Pool(threads)  # 多进程数

    if gms == 1:
        # draw_single
        eq = np.loadtxt('./EW.txt', skiprows=1)
        cj = eq[:, 0].size
        cj = 1  # for testing
        for i in range(cj):
            p.apply_async(draw_single, args=(i, eq))

    elif gms == 2:
        # draw_dual
        top = np.loadtxt('./top.txt', skiprows=0)
        bottom = np.loadtxt('./bottom.txt', skiprows=0)
        cj = max(top[:, 0].size, bottom[:, 0].size)
        cj = 1  # For testing
        for i in range(cj):
            p.apply_async(draw_dual, args=(i, top, bottom))

    p.close()
    p.join()
    print('Done!')

if __name__ == '__main__':
    main()


import os
import re
import tempfile

from devil.utils import cmd_helper
from pylib import constants

_PROGUARD_CLASS_RE = re.compile(r'\s*?- Program class:\s*([\S]+)$')
_PROGUARD_SUPERCLASS_RE = re.compile(r'\s*?  Superclass:\s*([\S]+)$')
_PROGUARD_SECTION_RE = re.compile(
    r'^(Interfaces|Constant Pool|Fields|Methods|Class file attributes) '
    r'\(count = \d+\):$')
_PROGUARD_METHOD_RE = re.compile(r'\s*?- Method:\s*(\S*)[(].*$')
_PROGUARD_ANNOTATION_RE = re.compile(r'^(\s*?)- Annotation \[L(\S*);\]:$')
_ELEMENT_PRIMITIVE = 0
_ELEMENT_ARRAY = 1
_ELEMENT_ANNOTATION = 2
_PROGUARD_ELEMENT_RES = [
  (_ELEMENT_PRIMITIVE,
   re.compile(r'^(\s*?)- Constant element value \[(\S*) .*\]$')),
  (_ELEMENT_ARRAY,
   re.compile(r'^(\s*?)- Array element value \[(\S*)\]:$')),
  (_ELEMENT_ANNOTATION,
   re.compile(r'^(\s*?)- Annotation element value \[(\S*)\]:$'))
]
_PROGUARD_INDENT_WIDTH = 2
_PROGUARD_ANNOTATION_VALUE_RE = re.compile(r'^(\s*?)- \S+? \[(.*)\]$')

def _GetProguardPath():
  return os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'proguard',
                      'lib', 'proguard603.jar')

def Dump(jar_path):
  """Dumps class and method information from a JAR into a dict via proguard.

  Args:
    jar_path: An absolute path to the JAR file to dump.
  Returns:
    A dict in the following format:
      {
        'classes': [
          {
            'class': '',
            'superclass': '',
            'annotations': {/* dict -- see below */},
            'methods': [
              {
                'method': '',
                'annotations': {/* dict -- see below */},
              },
              ...
            ],
          },
          ...
        ],
      }

    Annotations dict format:
      {
        'empty-annotation-class-name': None,
        'annotation-class-name': {
          'field': 'primitive-value',
          'field': [ 'array-item-1', 'array-item-2', ... ],
          'field': {
            /* Object value */
            'field': 'primitive-value',
            'field': [ 'array-item-1', 'array-item-2', ... ],
            'field': { /* Object value */ }
          }
        }
      }

    Note that for top-level annotations their class names are used for
    identification, whereas for any nested annotations the corresponding
    field names are used.

    One drawback of this approach is that an array containing empty
    annotation classes will be represented as an array of 'None' values,
    thus it will not be possible to find out annotation class names.
    On the other hand, storing both annotation class name and the field name
    would produce a very complex JSON.
  """

  with tempfile.NamedTemporaryFile() as proguard_output:
    cmd_helper.GetCmdStatusAndOutput([
        'java',
        '-jar', _GetProguardPath(),
        '-injars', jar_path,
        '-dontshrink', '-dontoptimize', '-dontobfuscate', '-dontpreverify',
        '-dump', proguard_output.name])
    return Parse(proguard_output)

class _AnnotationElement(object):
  def __init__(self, name, ftype, depth):
    self.ref = None
    self.name = name
    self.ftype = ftype
    self.depth = depth

class _ParseState(object):
  _INITIAL_VALUES = (lambda: None, list, dict)
  # Empty annotations are represented as 'None', not as an empty dictionary.
  _LAZY_INITIAL_VALUES = (lambda: None, list, lambda: None)

  def __init__(self):
    self._class_result = None
    self._method_result = None
    self._parse_annotations = False
    self._annotation_stack = []

  def ResetPerSection(self, section_name):
    self.InitMethod(None)
    self._parse_annotations = (
      section_name in ['Class file attributes', 'Methods'])

  def ParseAnnotations(self):
    return self._parse_annotations

  def CreateAndInitClass(self, class_name):
    self.InitMethod(None)
    self._class_result = {
      'class': class_name,
      'superclass': '',
      'annotations': {},
      'methods': [],
    }
    return self._class_result

  def HasCurrentClass(self):
    return bool(self._class_result)

  def SetSuperClass(self, superclass):
    assert self.HasCurrentClass()
    self._class_result['superclass'] = superclass

  def InitMethod(self, method_name):
    self._annotation_stack = []
    if method_name:
      self._method_result = {
        'method': method_name,
        'annotations': {},
      }
      self._class_result['methods'].append(self._method_result)
    else:
      self._method_result = None

  def InitAnnotation(self, annotation, depth):
    if not self._annotation_stack:
      # Add a fake parent element comprising 'annotations' dictionary,
      # so we can work uniformly with both top-level and nested annotations.
      annotations = _AnnotationElement(
        '<<<top level>>>', _ELEMENT_ANNOTATION, depth - 1)
      if self._method_result:
        annotations.ref = self._method_result['annotations']
      else:
        annotations.ref = self._class_result['annotations']
      self._annotation_stack = [annotations]
    self._BacktrackAnnotationStack(depth)
    if not self.HasCurrentAnnotation():
      self._annotation_stack.append(
        _AnnotationElement(annotation, _ELEMENT_ANNOTATION, depth))
    self._CreateAnnotationPlaceHolder(self._LAZY_INITIAL_VALUES)

  def HasCurrentAnnotation(self):
    return len(self._annotation_stack) > 1

  def InitAnnotationField(self, field, field_type, depth):
    self._BacktrackAnnotationStack(depth)
    # Create the parent representation, if needed. E.g. annotations
    # are represented with `None`, not with `{}` until they receive the first
    # field.
    self._CreateAnnotationPlaceHolder(self._INITIAL_VALUES)
    if self._annotation_stack[-1].ftype == _ELEMENT_ARRAY:
      # Nested arrays are not allowed in annotations.
      assert not field_type == _ELEMENT_ARRAY
      # Use array index instead of bogus field name.
      field = len(self._annotation_stack[-1].ref)
    self._annotation_stack.append(_AnnotationElement(field, field_type, depth))
    self._CreateAnnotationPlaceHolder(self._LAZY_INITIAL_VALUES)

  def UpdateCurrentAnnotationFieldValue(self, value, depth):
    self._BacktrackAnnotationStack(depth)
    self._InitOrUpdateCurrentField(value)

  def _CreateAnnotationPlaceHolder(self, constructors):
    assert self.HasCurrentAnnotation()
    field = self._annotation_stack[-1]
    if field.ref is None:
      field.ref = constructors[field.ftype]()
      self._InitOrUpdateCurrentField(field.ref)

  def _BacktrackAnnotationStack(self, depth):
    stack = self._annotation_stack
    while len(stack) > 0 and stack[-1].depth >= depth:
      stack.pop()

  def _InitOrUpdateCurrentField(self, value):
    assert self.HasCurrentAnnotation()
    parent = self._annotation_stack[-2]
    assert not parent.ref is None
    # There can be no nested constant element values.
    assert parent.ftype in [_ELEMENT_ARRAY, _ELEMENT_ANNOTATION]
    field = self._annotation_stack[-1]
    if isinstance(value, str) and not field.ftype == _ELEMENT_PRIMITIVE:
      # The value comes from the output parser via
      # UpdateCurrentAnnotationFieldValue, and should be a value of a constant
      # element. If it isn't, just skip it.
      return
    if parent.ftype == _ELEMENT_ARRAY and field.name >= len(parent.ref):
      parent.ref.append(value)
    else:
      parent.ref[field.name] = value

def _GetDepth(prefix):
  return len(prefix) // _PROGUARD_INDENT_WIDTH

def Parse(proguard_output):
  results = {
    'classes': [],
  }

  state = _ParseState()

  for line in proguard_output:
    line = line.strip('\r\n')

    m = _PROGUARD_CLASS_RE.match(line)
    if m:
      results['classes'].append(
        state.CreateAndInitClass(m.group(1).replace('/', '.')))
      continue

    if not state.HasCurrentClass():
      continue

    m = _PROGUARD_SUPERCLASS_RE.match(line)
    if m:
      state.SetSuperClass(m.group(1).replace('/', '.'))
      continue

    m = _PROGUARD_SECTION_RE.match(line)
    if m:
      state.ResetPerSection(m.group(1))
      continue

    m = _PROGUARD_METHOD_RE.match(line)
    if m:
      state.InitMethod(m.group(1))
      continue

    if not state.ParseAnnotations():
      continue

    m = _PROGUARD_ANNOTATION_RE.match(line)
    if m:
      # Ignore the annotation package.
      state.InitAnnotation(m.group(2).split('/')[-1], _GetDepth(m.group(1)))
      continue

    if state.HasCurrentAnnotation():
      m = None
      for (element_type, element_re) in _PROGUARD_ELEMENT_RES:
        m = element_re.match(line)
        if m:
          state.InitAnnotationField(
            m.group(2), element_type, _GetDepth(m.group(1)))
          break
      if m:
        continue
      m = _PROGUARD_ANNOTATION_VALUE_RE.match(line)
      if m:
        state.UpdateCurrentAnnotationFieldValue(
          m.group(2), _GetDepth(m.group(1)))
      else:
        state.InitMethod(None)

  return results


import csv
import os

from datetime import datetime

from django.core.management.base import BaseCommand

from www.recordings.models import Organisation, Site, Recorder, Deployment

DIR = 'fixtures'

class Command(BaseCommand):
    def handle(self, **options):
        organisation = csv.DictReader(open(os.path.join(DIR, 'Organisations.csv')))
        for row in organisation:
            o = Organisation(code=row['Code'], name=row['Name'])
            o.save()

        rfpt_org = Organisation.objects.get(code='RFPT')
        sites = csv.DictReader(open(os.path.join(DIR, 'Sites.csv')))
        for row in sites:
            if not row['Latitude'].strip():
                row['Latitude'] = None
            if not row['Longitude'].strip():
                row['Longitude'] = None

            o = Site(code=row['Code'], latitude=row['Latitude'], longitude=row['Longitude'], description=row['Comments'], organisation=rfpt_org)
            o.save()

        recorders = csv.DictReader(open(os.path.join(DIR, 'Recorders.csv')))
        for row in recorders:
            o = Recorder(code=row['Code'], organisation=rfpt_org)
            o.save()

        deployments = csv.DictReader(open(os.path.join(DIR, 'Deployments.csv')))
        for row in deployments:
            site = Site.objects.get(code=row['Site'])
            recorder = Recorder.objects.get(code=row['Recorder'].strip())

            if not row['Deploy_time']:
                row['Deploy_time'] = '00:00:00'
            if not row['Recovery_time']:
                row['Recovery_time'] = '00:00:00'
            start = datetime.strptime(row['Deploy_date'] + ' ' + row['Deploy_time'], '%d/%m/%Y %H:%M:%S')
            if row['Recovery_date'].strip():
                end = datetime.strptime(row['Recovery_date'] + ' ' + row['Recovery_time'], '%d/%m/%Y %H:%M:%S')
            else:
                end = None
            o = Deployment(site=site, recorder=recorder, start=start, end=end, comments=row['Comments'], owner=rfpt_org)
            o.save()


# -*- coding: utf-8 -*-
"""
Created on Sat Jan 18 15:47:30 2020

@author: abz1e14
"""

from pandas import read_excel
from pandas import DataFrame
from numpy import log
from numpy import sqrt
from matplotlib import pyplot
series = read_excel('BricksDeliveries.xls', header=0,
              index_col=0, parse_dates=True, squeeze=True)

## Time plot of original time series
pyplot.figure(1)
# line plot
pyplot.subplot(211)
pyplot.plot(series)
pyplot.title('Time plot for brick deliveries data')
# histogram
pyplot.subplot(212)
pyplot.hist(series)
pyplot.show()

#-----------------------
# Log transform
#-----------------------
dataframe1 = DataFrame(series.values)
dataframe1.columns = ['bricks']
dataframe1['bricks'] = log(dataframe1['bricks'])
pyplot.figure(1)
# line plot
pyplot.subplot(211)
pyplot.plot(dataframe1['bricks'])
pyplot.title('Log transform for brick deliveries data')
# histogram
pyplot.subplot(212)
pyplot.hist(dataframe1['bricks'])
pyplot.show()

#-----------------------
# Sqrt transform
#-----------------------
dataframe2 = DataFrame(series.values)
dataframe2.columns = ['bricks']
dataframe2['bricks'] = sqrt(dataframe2['bricks'])
pyplot.figure(1)
# line plot
pyplot.subplot(211)
pyplot.plot(dataframe2['bricks'])
pyplot.title('Sqrt transform for brick deliveries data')
# histogram
pyplot.subplot(212)
pyplot.hist(dataframe2['bricks'])
pyplot.show()

LearningResource/Forecasting/Chapter 1 Demonstrations Material/Chapter 1 Workshop Data/Workshop 1 - Solution codes/Exercise 1.8/TransformsBricksDeliveries.py


from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _

from user.validators import validate_phone

class User(AbstractUser):
    """Пользователь"""

    middle_name = models.CharField(
        'Отчество',
        max_length=100,
        null=True,
        blank=True
    )
    phone = models.CharField(
        'Номер мобильного телефона',
        max_length=10,
        null=True,
        blank=True,
        validators=[validate_phone],
        unique=True
    )
    is_verify_phone = models.BooleanField(
        'Телефон подтвержден',
        default=False
    )
    is_verify_email = models.BooleanField(
        'Почта подтверждена',
        default=False
    )
    department = models.ForeignKey(
        'user.Department',
        verbose_name='Отдел',
        null=True,
        blank=True,
        on_delete=models.CASCADE,
        related_name='users'
    )

    def get_full_name(self):
        return '{0}{1}{2}'.format(
            '%s ' % self.last_name if self.last_name else '',
            '%s ' % self.first_name if self.first_name else '',
            '%s' % self.middle_name if self.middle_name else ''
        )

    def __str__(self):
        return self.get_full_name()

    class Meta:
        verbose_name = _('Пользователь')
        verbose_name_plural = _('Пользователи')

class Department(models.Model):
    """Отдел"""

    name = models.CharField(
        max_length=100,
        verbose_name='Название',
        unique=True
    )
    director = models.ForeignKey(
        'user.User',
        verbose_name='Создатель комментария',
        on_delete=models.CASCADE,
        related_name='departments'
    )

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Отдел')
        verbose_name_plural = _('Отделы')

class Invite(models.Model):
    """Приглашение"""

    invite_from = models.ForeignKey(
        'user.User',
        verbose_name='Кто пригласил',
        on_delete=models.CASCADE,
        related_name='invites'
    )
    invite_to = models.OneToOneField(
        'user.User',
        verbose_name='Кого пригласили',
        on_delete=models.CASCADE,
        unique=True
    )
    invite_date = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата и время приглашения'
    )
    code = models.CharField(
        max_length=32,
        verbose_name='Код приглашения',
        unique=True
    )

    def __str__(self):
        return self.invite_to.email

    class Meta:
        verbose_name = _('Приглашение')
        verbose_name_plural = _('Приглашения')

class VisitHistory(models.Model):
    """История посещений"""

    user = models.ForeignKey(
        'user.User',
        verbose_name='Пользователь',
        on_delete=models.CASCADE,
        related_name='visit_histories'
    )
    visit_date = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата и время посещения'
    )
    ip_address = models.CharField(
        max_length=100,
        verbose_name='IP адрес'
    )

    def __str__(self):
        return '{0} {1}'.format(self.visit_date, self.user.email)

    class Meta:
        verbose_name = _('История посещений')
        verbose_name_plural = _('История посещений')