"""
Core tensor operations with MXnet.
"""

# Author: Jean Kossaifi
# License: BSD 3 clause

# First check whether MXNet is installed
try:
    import mxnet as mx
except ImportError as error:
    message = ('Impossible to import MXNet.\n'
               'To use TensorLy with the MXNet backend, '
               'you must first install MXNet!')
    raise ImportError(message) from error

import warnings
import numpy
import scipy.linalg
import scipy.sparse.linalg

from numpy import testing
from mxnet import nd as nd
from mxnet.ndarray import arange, zeros, zeros_like, ones
from mxnet.ndarray import moveaxis, dot, transpose, reshape
from mxnet.ndarray import where, maximum, sign, prod

# Order 0 tensor, mxnet....
from math import sqrt as scalar_sqrt

from . import numpy_backend

def context(tensor):
    """Returns the context of a tensor
    """
    return {'ctx':tensor.context, 'dtype':tensor.dtype}

def tensor(data, ctx=mx.cpu(), dtype='float32'):
    """Tensor class
    """
    if dtype is None and isinstance(data, numpy.ndarray):
        dtype = data.dtype
    return nd.array(data, ctx=ctx, dtype=dtype)

def to_numpy(tensor):
    """Convert a tensor to numpy format

    Parameters
    ----------
    tensor : Tensor

    Returns
    -------
    ndarray
    """
    if isinstance(tensor, nd.NDArray):
        return tensor.asnumpy()
    elif isinstance(tensor, numpy.ndarray):
        return tensor
    else:
        return numpy.array(tensor)

def assert_array_equal(a, b, **kwargs):
    testing.assert_array_equal(to_numpy(a), to_numpy(b), **kwargs)

def assert_array_almost_equal(a, b, decimal=4, **kwargs):
    testing.assert_array_almost_equal(to_numpy(a), to_numpy(b), decimal=decimal, **kwargs)

assert_raises = testing.assert_raises
assert_ = testing.assert_

def assert_equal(actual, desired, err_msg='', verbose=True):
    if isinstance(actual, nd.NDArray):
        actual =  actual.asnumpy()
        if actual.shape == (1, ):
            actual = actual[0]
    if isinstance(desired, nd.NDArray):
        desired =  desired.asnumpy()
        if desired.shape == (1, ):
            desired = desired[0]
    testing.assert_equal(actual, desired)

def shape(tensor):
    return tensor.shape

def ndim(tensor):
    return tensor.ndim

def kron(matrix1, matrix2):
    """Kronecker product"""
    s1, s2 = matrix1.shape
    s3, s4 = matrix2.shape
    return nd.reshape(
                matrix1.reshape((s1, 1, s2, 1))*matrix2.reshape((1, s3, 1, s4)),
                (s1*s3, s2*s4))

def solve(matrix1, matrix2):
    return tensor(numpy.linalg.solve(to_numpy(matrix1), to_numpy(matrix2)), **context(matrix1))

def min(tensor, *args, **kwargs):
    if isinstance(tensor, nd.NDArray):
        return nd.min(tensor, *args, **kwargs).asscalar()
    else:
        return numpy.min(tensor, *args, **kwargs)

def max(tensor, *args, **kwargs):
    if isinstance(tensor, nd.NDArray):
        return nd.max(tensor, *args, **kwargs).asscalar()
    else:
        return numpy.max(tensor, *args, **kwargs)

def abs(tensor, **kwargs):
    if isinstance(tensor, nd.NDArray):
        return nd.abs(tensor, **kwargs)
    else:
        return numpy.abs(tensor, **kwargs)

def norm(tensor, order=2, axis=None):
    """Computes the l-`order` norm of tensor

    Parameters
    ----------
    tensor : ndarray
    order : int
    axis : int or tuple

    Returns
    -------
    float or tensor
        If `axis` is provided returns a tensor.
    """
    # handle difference in default axis notation
    if axis is None:
        axis = ()

    if order == 'inf':
        res = nd.max(nd.abs(tensor), axis=axis)
    elif order == 1:
        res =  nd.sum(nd.abs(tensor), axis=axis)
    elif order == 2:
        res = nd.sqrt(nd.sum(tensor**2, axis=axis))
    else:
        res = nd.sum(nd.abs(tensor)**order, axis=axis)**(1/order)

    if res.shape == (1,):
        return res.asscalar()

    return res

def kr(matrices):
    """Khatri-Rao product of a list of matrices

        This can be seen as a column-wise kronecker product.

    Parameters
    ----------
    matrices : ndarray list
        list of matrices with the same number of columns, i.e.::

            for i in len(matrices):
                matrices[i].shape = (n_i, m)

    Returns
    -------
    khatri_rao_product: matrix of shape ``(prod(n_i), m)``
        where ``prod(n_i) = prod([m.shape[0] for m in matrices])``
        i.e. the product of the number of rows of all the matrices in the product.

    Notes
    -----
    Mathematically:

    .. math::
         \\text{If every matrix } U_k \\text{ is of size } (I_k \\times R),\\\\
         \\text{Then } \\left(U_1 \\bigodot \\cdots \\bigodot U_n \\right) \\text{ is of size } (\\prod_{k=1}^n I_k \\times R)
    """
    if len(matrices) < 2:
        raise ValueError('kr requires a list of at least 2 matrices, but {} given.'.format(len(matrices)))

    n_col = shape(matrices[0])[1]
    for i, e in enumerate(matrices[1:]):
        if not i:
            res = matrices[0]
        s1, s2 = shape(res)
        s3, s4 = shape(e)
        if not s2 == s4 == n_col:
            raise ValueError('All matrices should have the same number of columns.')
        res = reshape(reshape(res, (s1, 1, s2))*reshape(e, (1, s3, s4)),
                      (-1, n_col))
    return res

def partial_svd(matrix, n_eigenvecs=None):
    """Computes a fast partial SVD on `matrix`

        if `n_eigenvecs` is specified, sparse eigendecomposition
        is used on either matrix.dot(matrix.T) or matrix.T.dot(matrix)

    Parameters
    ----------
    matrix : 2D-array
    n_eigenvecs : int, optional, default is None
        if specified, number of eigen[vectors-values] to return

    Returns
    -------
    U : 2D-array
        of shape (matrix.shape[0], n_eigenvecs)
        contains the right singular vectors
    S : 1D-array
        of shape (n_eigenvecs, )
        contains the singular values of `matrix`
    V : 2D-array
        contains the left singular vectors
    """
    # Check that matrix is... a matrix!
    if matrix.ndim != 2:
        raise ValueError('matrix be a matrix. matrix.ndim is {} != 2'.format(
            matrix.ndim))

    # Choose what to do depending on the params
    ctx = context(matrix)
    matrix = to_numpy(matrix)
    dim_1, dim_2 = matrix.shape
    if dim_1 <= dim_2:
        min_dim = dim_1
    else:
        min_dim = dim_2

    if n_eigenvecs is None or n_eigenvecs >= min_dim:
        if n_eigenvecs > min_dim:
            full_matrices = True
        else:
            full_matrices = False
        # Default on standard SVD
        U, S, V = scipy.linalg.svd(matrix, full_matrices=full_matrices)
        U, S, V = U[:, :n_eigenvecs], S[:n_eigenvecs], V[:n_eigenvecs, :]
        return tensor(U, **ctx), tensor(S, **ctx), tensor(V, **ctx)

    else:
        # We can perform a partial SVD
        # First choose whether to use X * X.T or X.T *X
        if dim_1 < dim_2:
            S, U = scipy.sparse.linalg.eigsh(numpy.dot(matrix, matrix.T.conj()), k=n_eigenvecs, which='LM')
            S = numpy.sqrt(S)
            V = numpy.dot(matrix.T.conj(), U * 1/S.reshape((1, -1)))
        else:
            S, V = scipy.sparse.linalg.eigsh(numpy.dot(matrix.T.conj(), matrix), k=n_eigenvecs, which='LM')
            S = numpy.sqrt(S)
            U = numpy.dot(matrix, V) * 1/S.reshape((1, -1))

        # WARNING: here, V is still the transpose of what it should be
        U, S, V = U[:, ::-1], S[::-1], V[:, ::-1]
        return tensor(U, **ctx), tensor(S, **ctx), tensor(V.T.conj(), **ctx)

def qr(matrix):
    try:
        # NOTE - should be replaced with geqrf when available
        Q, L = nd.linalg.gelqf(matrix.T)
        return Q.T, L.T
    except AttributeError:
        warnings.warn('This version of MXNet does not include the linear '
                      'algebra function gelqf(). Substituting with numpy.')
        Q, R = numpy_backend.qr(to_numpy(matrix))
        return tensor(Q), tensor(R)

def clip(tensor, a_min=None, a_max=None, indlace=False):
    if a_min is not None and a_max is not None:
        if indlace:
            nd.max(nd.min(tensor, a_max, out=tensor), a_min, out=tensor)
        else:
            tensor = nd.maximum(nd.minimum(tensor, a_max), a_min)
    elif min is not None:
        if indlace:
            nd.max(tensor, a_min, out=tensor)
        else:
            tensor = nd.maximum(tensor, a_min)
    elif max is not None:
        if indlace:
            nd.min(tensor, a_max, out=tensor)
        else:
            tensor = nd.minimum(tensor, a_max)
    return tensor

def all(tensor):
    return nd.sum(tensor != 0).asscalar()

def mean(tensor, axis=None, **kwargs):
    if axis is None:
        axis = ()
    res = nd.mean(tensor, axis=axis, **kwargs)
    if res.shape == (1,):
        return res.asscalar()
    else:
        return res

def sum(tensor, axis=None, **kwargs):
    if axis is None:
        axis = ()
    res = nd.sum(tensor, axis=axis, **kwargs)
    if res.shape == (1,):
        return res.asscalar()
    else:
        return res

def sqrt(tensor, *args, **kwargs):
    if isinstance(tensor, nd.NDArray):
        return nd.sqrt(tensor, *args, **kwargs)
    else:
        return scalar_sqrt(tensor)

def copy(tensor):
    return tensor.copy()

def concatenate(tensors, axis):
    return nd.concat(*tensors, dim=axis)


import ctypes
import os
import sys
from abc import abstractmethod
from contextlib import contextmanager
from dataclasses import dataclass

build_dir = os.environ.get("KERNEL_EXPLORER_BUILD_DIR", None)
if build_dir is None:
    raise ValueError("Environment variable KERNEL_EXPLORER_BUILD_DIR is required")

if not os.path.exists(build_dir):
    raise ValueError(f"KERNEL_EXPLORER_BUILD_DIR ({build_dir}) points to nonexistent path")

# onnxruntime_pybind11_state and kernel_explorer
sys.path.insert(0, build_dir)

# pylint: disable=wrong-import-position
import onnxruntime_pybind11_state  # noqa: E402

# We need to call some functions to properly initialize so pointers in the library
available_providers = onnxruntime_pybind11_state.get_available_providers()

build_dir = os.path.realpath(build_dir)
search_paths = [build_dir]

# As Kernel Explorer makes use of utility functions in ONNXRuntime, we dlopen all relevant libraries to bring required
# symbols into global namespace, so that we don't need to worry about linking.
library_files_to_load = [
    "onnxruntime_pybind11_state.so",
    "libonnxruntime_providers_shared.so",
]
if "CUDAExecutionProvider" in available_providers:
    library_files_to_load.append("libonnxruntime_providers_cuda.so")
if "ROCMExecutionProvider" in available_providers:
    library_files_to_load.append("libonnxruntime_providers_rocm.so")

library_to_load = []

for lib in library_files_to_load:
    for prefix in search_paths:
        path = os.path.join(prefix, lib)
        if os.path.exists(path):
            library_to_load.append(path)
            continue

        raise OSError(f"cannot found {lib}")

# use RTLD_GLOBAL to bring all symbols to global name space
libraries = [ctypes.CDLL(lib_path, mode=ctypes.RTLD_GLOBAL) for lib_path in library_to_load]

# pylint: disable=wrong-import-position, disable=unused-import
import _kernel_explorer  # noqa: E402, F401

# pylint: disable=wrong-import-position, disable=unused-import, disable=wildcard-import
from _kernel_explorer import *  # noqa: F403, E402

# Benchmark Reporter
@dataclass
class MetricBase:
    name: str
    dtype: str
    milliseconds_duration: float

    def __lt__(self, other):
        if "Tunable" in self.name or other.duration < 0:
            return True
        if "Tunable" in other.name or self.duration < 0:
            return False

        return self.duration < other.duration

    @property
    def duration(self):
        return self.milliseconds_duration * 1000

    @abstractmethod
    def report(self) -> str:
        raise NotImplementedError()

@dataclass
class ComputeMetric(MetricBase):
    FLOPs: int

    @property
    def tflops(self):
        return self.FLOPs * 1e6 / self.duration / 1e12

@dataclass
class BandwidthMetric(MetricBase):
    bytes: int

    @property
    def gbps(self):
        return self.bytes * 1e6 / self.duration / 1e9

@dataclass
class ComputeAndBandwidthMetric(ComputeMetric, BandwidthMetric):
    pass

class InstanceBenchmarkReporter:
    def __init__(self):
        self.sort = False
        self.reporters = []

    def set_sort(self, sort):
        self.sort = sort

    def make_report(self):
        self.reporters.sort()
        for item in self.reporters:
            print(item.report())
        self.reporters.clear()

    def receive(self, status):
        self.reporters.append(status)
        if not self.sort:
            self.make_report()

_reporter = InstanceBenchmarkReporter()

@contextmanager
def benchmark(sort):
    _reporter.set_sort(sort)
    try:
        yield
    finally:
        _reporter.make_report()

def report(status):
    _reporter.receive(status)


# IPython log file

from pydataset import data
df = data('voteincome')
data('voteincome', show_doc=True)
df
df = df.drop(columns=['state', 'year'])
from sklearn.model_selection import train_test_split
df
X = df.drop(columns='vote')
y = df.vote
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=123)
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=4)
knn.fit(X_train, y_train)
knn.score(X_train, y_train)
knn.score(X_test, y_test)
from sklearn.metrics import accuracy_score
accuracy_score(y_train, knn.predict(X_train))
for n in [1, 2, 3, 4]:
    knn = KNeighborsClassifier(n_neighbors=n)
    knn.fit(X_train, y_train)
    print('-------')
    print('n:', n)
    print('train score:', knn.score(X_train, y_train))
    print('test score:', knn.score(X_test, y_test))

knn = KNeighborsClassifier(n_neighbors=1).fit(X_train, y_train)
training_predictions = knn.predict(X_train, y_train)
training_predictions = knn.predict(X_train)
test_predictions = knn.predict(X_test)
from sklearn.metrics import classification_report
X
classification_report(y_train, training_predictions)
print(classification_report(y_train, training_predictions))
from sklearn import __version__
__version__
def test_score(n_neighbors):
    model = KNeighborsClassifier(n_neighbors=n_neighbors)
    model.fit(X_train, y_train)
    return model.score(X_test, y_test)

test_score(3)
{n: test_score(n) for n in range(1, 21)}
pd.Series({n: test_score(n) for n in range(1, 21)})
import pandas as pd
pd.Series({n: test_score(n) for n in range(1, 21)})
pd.Series({n: test_score(n) for n in range(1, 21)}, name='test accuracy')
pd.Series({n: test_score(n) for n in range(1, 21)}, name='test accuracy').plot()
import matplotlib.pyplot as plt
plt.show()
pd.Series({n: test_score(n) for n in range(1, 21)}, name='test accuracy').plot()
plt.xticks(range(1, 21))
plt.ylabel('Accuracy')
plt.xlabel('n_neighbors')
plt.title('Accuracy on test data v n neighbors')
plt.show()


"""Unit tests for cuda helpers"""
import unittest
import numpy as np
import scipy
import scipy.linalg

import torch
import prox_tv
from tv_opt_layers.helpers.cuda import dpttr
from tv_opt_layers.ops import batched_tvl1_op

class TestTVOps(unittest.TestCase):
  def test_batched_tvl1(self):
    sigma = 0.5
    KK = 10
    NN = 5
    for seed in range(0, 10):
      torch.manual_seed(seed)
      y = torch.randn(KK, NN, device='cuda').double()
      lmbd = 1*torch.ones(KK, 1, device='cuda').double()
      out1 = batched_tvl1_op.pn_tv1(y, lmbd, sigma=sigma)
      out2 = []
      for k in range(KK):
        out = prox_tv.tv1_1d(y[k].cpu().numpy(), lmbd[k]
                             [0].item(), method='pn', sigma=sigma)
        out2.append(np.expand_dims(out, 0))
      out2 = np.concatenate(out2, 0)
      np.allclose(out2, out1.cpu().numpy())

class TestDPTTRS(unittest.TestCase):
  """Tests for factorizing and solving symmetric tridiagonal system."""

  def setUp(self):
    batch_size = 10
    input_size = 5
    # Create Positive Definite A.
    A = torch.randn(batch_size, input_size, input_size)
    A = A.bmm(A.transpose(-1, -2))/2 + input_size*torch.eye(input_size)

    self.d_in1 = torch.diagonal(A, dim1=-2, dim2=-1)
    self.e_in1 = torch.diagonal(A, offset=1, dim1=-2, dim2=-1)

  def _copy_from_self(self):
    d_in1 = self.d_in1.clone().double().cuda()
    e_in1 = self.e_in1.clone().double().cuda()
    d_in2 = np.array(d_in1.clone().detach().cpu().numpy())
    e_in2 = np.array(e_in1.clone().detach().cpu().numpy())
    return d_in1, d_in2, e_in1, e_in2

  def test_dpttrf_vs_lapack(self):
    d_in1, d_in2, e_in1, e_in2 = self._copy_from_self()
    dpttr.batch_factorize(d_in1, e_in1)
    for b_idx in range(d_in1.shape[0]):
      scipy.linalg.lapack.dpttrf(
          d_in2[b_idx:b_idx+1], e_in2[b_idx:b_idx+1], True, True)
    diff = d_in1.cpu().numpy()-d_in2
    diff = d_in1.cpu().numpy()-d_in2
    max_idx = np.abs(diff).mean(-1).argmax()
    assert np.allclose(d_in1.cpu().numpy(), d_in2)
    assert np.allclose(e_in1.cpu().numpy(), e_in2)

  def test_dpttrs_vs_lapack(self):
    d_in1, d_in2, e_in1, e_in2 = self._copy_from_self()
    b_in1 = torch.randn(d_in1.shape[0], d_in1.shape[1]).double().cuda()
    b_in2 = b_in1.clone().unsqueeze(-1).cpu().numpy()
    dpttr.batch_solve(d_in1, e_in1, b_in1)
    for b_idx in range(d_in1.shape[0]):
      info = scipy.linalg.lapack.dpttrs(
          d_in2[b_idx], e_in2[b_idx], b_in2[b_idx])
      assert np.allclose(b_in1[b_idx].cpu().numpy(), info[0][..., 0])

if __name__ == '__main__':
  unittest.main()


import os
from glob import glob
from functools import partial
from multiprocessing import Pool, cpu_count
from typing import Callable, List, Sequence, Tuple
import nibabel as nib
import numpy as np
from skimage.exposure import equalize_hist
from skimage.transform import resize
from UPD_study import ROOT

def get_camcan_files(config) -> List[str]:
    """Get all CamCAN file paths in a given sequence (t1, t2, or flair).
    Args:
        config (Namespace): configuration object
    Returns:
        files (List[str]): List of files
    """
    path = os.path.join(ROOT, 'data', 'datasets', 'MRI/CamCAN')
    files = glob(os.path.join(path, '*/',
                              f'*{config.sequence.upper()}w_stripped_registered.*'))

    assert len(files) > 0, "No files found in CamCAN"
    return files

def get_brats_files(config) -> Tuple[List[str], List[str]]:
    """Get all BraTS file paths in a given sequence (t1, t2, or flair).
    Args:
        config (Namespace): configuration object
    Returns:
        files (List[str]): List of files
        seg_files (List[str]): List of segmentation files
    """
    # pt = '/u/home/lagi/thesis/UAD_study/Datasets'

    files = glob(os.path.join(ROOT, 'data', 'datasets', 'MRI/BraTS/MICCAI_BraTS2020_TrainingData/*',
                              f'*{config.sequence.lower()}*registered.*'))

    seg_files = [os.path.join(os.path.dirname(f), 'anomaly_segmentation.nii') for f in files]
    assert len(files) > 0, "No files found in BraTS"
    return files, seg_files

def get_atlas_files(config) -> List[str]:
    """Get all ATLAS file paths
    Args:
        config (Namespace): configuration object
    Returns:
        files (List[str]): List of files
        seg_files (List[str]): List of segmentation files
    """
    if config.get_images:

        path = '/datasets/Datasets/MRI/ATLAS/lesion'
        files = glob(os.path.join(path, '*/*/*stripped_registered*'))
    else:
        path = os.path.join(ROOT, 'data', 'datasets', 'MRI/ATLAS/ATLAS_2/Training')
        files = sorted(glob(os.path.join(path, '*/*/*/*/*stripped_registered*')))
    seg_files = [os.path.join(os.path.dirname(f), 'anomaly_segmentation.nii.gz') for f in files]
    assert len(files) > 0, "No files found in ATLAS"
    return files, seg_files

def load_nii(path: str, size: int = None, primary_axis: int = 0, dtype: str = "float32"):
    """Load a neuroimaging file with nibabel, [w, h, slices]
    https://nipy.org/nibabel/reference/nibabel.html
    Args:
        path (str): Path to nii file
        size (int): Optional. Output size for h and w. Only supports rectangles
        primary_axis (int): Primary axis (the one to slice along, usually 2)
        dtype (str): Numpy datatype
    Returns:
        volume (np.ndarray): Of shape [w, h, slices]
        affine (np.ndarray): Affine coordinates (rotation and translation),
                             shape [4, 4]
    """
    # Load file
    data = nib.load(path, keep_file_open=False)
    volume = data.get_fdata(caching='unchanged')  # [w, h, slices]
    affine = data.affine

    # Squeeze optional 4th dimension
    if volume.ndim == 4:
        volume = volume.squeeze(-1)

    # Resize if size is given and if necessary
    if size is not None and (volume.shape[0] != size or volume.shape[1] != size):
        volume = resize(volume, [size, size, size])

    # Convert
    volume = volume.astype(np.dtype(dtype))

    # Move primary axis to first dimension
    volume = np.moveaxis(volume, primary_axis, 0)

    return volume, affine

def load_nii_nn(path: str, size: int,
                is_atlas: bool = None,
                slice_range: Tuple[int, int] = None,
                normalize: bool = False,
                equalize_histogram: bool = False,
                dtype: str = "float32", segm=False):
    """
    Load a file for training. Slices should be first dimension, volumes are in
    MNI space and center cropped to the shorter side, then resized to size
    """
    vol = load_nii(path, primary_axis=2, dtype=dtype)[0]
    # if segm:
    #     print(np.unique(vol // 1))
    # select specified range of slices
    if slice_range is not None:
        vol = vol[slice_range[0]:slice_range[1]]

    vol = rectangularize(vol)

    # fix interpolation artifacts
    if is_atlas is not None or is_atlas:
        vol[vol < 1e-1] = 0
    else:
        vol[vol < 1e-4] = 0

    if size is not None:
        vol = resize(vol, [vol.shape[0], size, size])

    # percentile normalization
    if normalize:
        vol = normalize_percentile(vol, 99)

    # If not segmentation mask, scale to [0,1]
    if not segm:
        if vol.max() > 0.:
            vol /= vol.max()

    # histogram equilization
    if equalize_histogram:
        vol = histogram_equalization(vol)

    return vol

def load_segmentation(path: str, size: int,
                      slice_range: Tuple[int, int] = None,
                      threshold: float = 0.4):
    """Load a segmentation file"""
    vol = load_nii_nn(path, size=size, slice_range=slice_range,
                      normalize=False, equalize_histogram=False, segm=True)

    return np.where(vol > threshold, 1, 0)

def load_files_to_ram(files: Sequence, load_fn: Callable = load_nii_nn,
                      num_processes: int = cpu_count()) -> List[np.ndarray]:
    with Pool(num_processes) as pool:
        results = pool.map(load_fn, files)

    return results

def histogram_equalization(img):
    # Create equalization mask
    mask = np.where(img > 0, 1, 0)
    # Equalize
    img = equalize_hist(img, nbins=256, mask=mask)
    # Assure that background still is 0
    img *= mask

    return img

def normalize_percentile(img: np.ndarray, percentile: float = 99) -> np.ndarray:
    """Normalize an image or volume to a percentile foreground intensity.
    Args:
        img (np.ndarray): Image to normalize
        percentile (float): Percentile to normalize to
    Returns:
        img (np.ndarray): Normalized image
    """

    foreground = img[img > 0]
    maxi = np.percentile(foreground, percentile)

    img[img > maxi] = maxi

    img /= maxi

    return img

def rectangularize(img: np.ndarray) -> np.ndarray:
    """
    Center crop the image to the shorter side
    Args:
        img (np.ndarray): Image to crop, shape [slices, w, h]
    Returns:
        img (np.ndarray): Cropped image
    """
    # Get image shape
    w, h = img.shape[1:]

    if w < h:
        # Center crop height to width
        img = img[:, :, (h - w) // 2:(h + w) // 2]
    elif h < w:
        # Center crop width to height
        img = img[:, (w - h) // 2:(w + h) // 2, :]
    else:
        # No cropping
        pass

    return img

def get_camcan_slices(config):
    """Get all image slices of the CamCAN brain MRI dataset"""
    # Get all files
    files = get_camcan_files(config)
    hist = config.equalize_histogram if 'equalize_histogram' in config else False
    # Load all files
    volumes = load_files_to_ram(
        files,
        partial(load_nii_nn,
                size=config.image_size,
                slice_range=config.slice_range if 'slice_range' in config else None,
                normalize=config.normalize if 'normalize' in config else False,
                equalize_histogram=hist
                )
    )
    if "return_volumes" in config and config.return_volumes:
        return np.stack(volumes, axis=0)[:, :, None]
    else:
        images = np.concatenate(volumes, axis=0)[:, None]

        return images

def get_brats_slices(config):
    """Get all image slices and segmentations of the BraTS brain MRI dataset"""
    # Get all files
    files, seg_files = get_brats_files(config)
    hist = config.equalize_histogram if 'equalize_histogram' in config else False
    # Load all files
    volumes = load_files_to_ram(
        files,
        partial(load_nii_nn,
                size=config.image_size,
                slice_range=config.slice_range if 'slice_range' in config else None,
                normalize=config.normalize if 'normalize' in config else False,
                equalize_histogram=hist)
    )

    # Load all files
    seg_volumes = load_files_to_ram(
        seg_files,
        partial(load_segmentation,
                size=config.image_size,
                slice_range=config.slice_range if 'slice_range' in config else None)
    )

    if "return_volumes" in config and config.return_volumes:
        return np.stack(volumes, axis=0)[:, :, None], np.stack(seg_volumes, axis=0)[:, :, None]
    else:
        imgs = np.concatenate(volumes, axis=0)[:, None]
        segs = np.concatenate(seg_volumes, axis=0)[:, None]

        return imgs, segs

def get_atlas_slices(config):
    """Get all image slices and segmentations of the ATLAS brain MRI dataset"""
    # Get all files
    files, seg_files = get_atlas_files(config)
    hist = hist = config.equalize_histogram if 'equalize_histogram' in config else False
    # Load all files
    volumes = load_files_to_ram(
        files,
        partial(load_nii_nn,
                is_atlas=True,
                size=config.image_size,
                slice_range=config.slice_range if 'slice_range' in config else None,
                normalize=config.normalize if 'normalize' in config else False,
                equalize_histogram=hist)
    )

    # Load all files
    seg_volumes = load_files_to_ram(
        seg_files,
        partial(load_segmentation,
                size=config.image_size,
                slice_range=config.slice_range if 'slice_range' in config else None)
    )

    if "return_volumes" in config and config.return_volumes:
        imgs = np.stack(volumes, axis=0)[:, :, None]
        segs = np.stack(seg_volumes, axis=0)[:, :, None]

        return imgs, segs
    else:
        imgs = np.concatenate(volumes, axis=0)[:, None]
        segs = np.concatenate(seg_volumes, axis=0)[:, None]

        return imgs, segs

def get_samples(size: int = 128):
    f1, f2 = get_camcan_files(sequence="t1")[:2]
    load_fn = partial(load_nii_nn, size=size, equalize_histogram=True)
    img1 = load_fn(f1)[:, None]
    img2 = load_fn(f2)[:, None]
    return np.stack([img1, img2], axis=0)


## perform imports and set-up
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
from sklearn.preprocessing import scale
PATH = '/home/ec2-user/environment/islr/4_classification/figs/'

# print with precision 4
pd.set_option('precision', 4)

market_df = pd.read_csv('smarket.csv')
market_df = market_df.rename(columns = {'Unnamed: 0':'Day'})
print(market_df.head())
print(market_df.shape)
print(market_df.describe())
print(market_df.corr(method='pearson'))

fig, ax = plt.subplots(figsize = (8,6))
ax.scatter(market_df.Day, market_df.Volume);
ax.set_xlabel('Days');
ax.set_ylabel('Volume in Billions');
plt.savefig(PATH + 'vol.png', dpi=300)
plt.close()

# LOGISTIC REGRSSION
# Encode the response as 0,1 for down/up
market_df['DirCoded'] = [0 if d == 'Down' else 1 for d in market_df.Direction]
print(market_df.head())

logit_fit = smf.logit('DirCoded ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + Volume', market_df).fit()
print(logit_fit.summary())
print(logit_fit.params)

logit_probs = logit_fit.predict(market_df)
print(logit_probs[:10])
logit_pred = pd.Series(['Up' if p > 0.5 else 'Down' for p in logit_probs])
print(logit_pred[:10])
table = logit_fit.pred_table(threshold=0.5)
confusion_df = pd.DataFrame(table, ['Down','Up'], ['Down','Up'])
print(confusion_df)

print('The model made {} correct predictions on the TRAINING SET.'.format((confusion_df.Down[0] + confusion_df.Up[1])/logit_fit.nobs))
print(np.mean(logit_pred == market_df.Direction))
train_df = market_df[market_df.Year < 2005]
test_df = market_df[market_df.Year == 2005]
print(test_df.shape)

train_fit = smf.logit('DirCoded ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + Volume', train_df).fit()
predicted_probs = train_fit.predict(test_df)

test_df['preds'] = ['Up' if p > 0.5 else 'Down' for p in predicted_probs]
print('The model made', np.mean(test_df.preds == test_df.Direction),'% correct predictions on the TEST SET.')

# Stats models doesn't have an option for a confusion matrix for test sets-- we build one by hand
print(pd.crosstab(test_df.preds, test_df.Direction))
print('The model made', np.mean(test_df.preds != test_df.Direction),'% incorrect predictions on the TEST SET.')

# using just last two days lags
train_fit = smf.logit('DirCoded ~ Lag1 + Lag2', train_df).fit()
predicted_probs = train_fit.predict(test_df)
test_df['preds'] = ['Up' if p > 0.5 else 'Down' for p in predicted_probs]
print('The model made', np.mean(test_df.preds == test_df.Direction),'% correct predictions on the TEST SET.')

# Stats models doesn't have an option for a confusion matrix for test sets-- we build one by hand
table = pd.crosstab(test_df.preds, test_df.Direction)
print(table)
print('On days where the prediction day is \'Up\' the probability the market will be \'Up\' is',
      table['Up']['Up']/(table['Down']['Up'] + table['Up']['Up']))

# predict for specific lag vales
print(train_fit.predict(pd.DataFrame({'Lag1':[1.2, 1.5], 'Lag2':[1.1,-0.8]})))

# LINEAR DISCRIMINANT ANALYSIS
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
# use lag 1 and lag 2 as the predictors
predictors = ['Lag1','Lag2']

X_train = train_df[predictors]
Y_train = train_df.DirCoded

# Create Classifier Instance
lda_clf = LDA()
# Fit model
lda_clf.fit(X_train,Y_train)

print('Class Priors (P(Y = k)) =', lda_clf.priors_)
print('Class Means μk\n   Down:', lda_clf.means_[0], '\n   Up:  ', lda_clf.means_[1])
print('Coeffecients =\n', lda_clf.scalings_)

# Scatter plot the data colored by market direction #
#####################################################
fig, ax = plt.subplots(figsize=(8,8))
# Plot the training lags color coded by market direction
ax.scatter(X_train[Y_train==1].Lag1, X_train[Y_train==1].Lag2, alpha=0.7, label='Up');
ax.scatter(X_train[Y_train==0].Lag1, X_train[Y_train==0].Lag2, alpha=0.7, label='Down');

# Calculate Bayes Decision Boundary #
#####################################
# Construct a meshgrid to calulate Bayes Boundary over
nx, ny = 200, 200
x_min, x_max = plt.xlim()
y_min, y_max = plt.ylim()
xx, yy = np.meshgrid(np.linspace(x_min, x_max, nx), np.linspace(y_min, y_max, ny))

# Use predict_proba to calculate Probability at each x1,x2 pair
Z = lda_clf.predict_proba(np.c_[xx.ravel(), yy.ravel()])
Z = Z[:, 1].reshape(xx.shape)
# The Bayes Boundary for k=2 classes is the contour where P(Y=k|X=x) = 0.5
cp = ax.contour(xx, yy, Z, [0.5], linewidths=1., colors='k');
plt.clabel(cp, inline=True, fmt='Bayes Decision Boundary',fontsize=8)

# Plot mean lag vector (lag1,lag2) for each class 'Up' and 'Down' #
###################################################################
ax.plot(lda_clf.means_[0][0], lda_clf.means_[0][1], 'o', color='red', markersize=10);
ax.plot(lda_clf.means_[1][0], lda_clf.means_[1][1], 'o', color='blue', markersize=10);

ax.set_xlabel('Lag1')
ax.set_ylabel('Lag2')
ax.legend(loc='best');
plt.savefig(PATH + 'bayes_boundaries.png', dpi=300)
plt.close()
lda_pred_class_coded = lda_clf.predict(test_df[predictors])
print(lda_pred_class_coded)

lda_pred_class = ['Up' if c == 1 else 'Down' for c in lda_pred_class_coded]
test_df['lda_pred_class'] = lda_pred_class
print(lda_pred_class[:10])
# Compute Test Confusion Matrix #
#################################
table = pd.crosstab(test_df.lda_pred_class, test_df.Direction)
print(table)
print(np.mean(test_df.lda_pred_class == test_df.Direction))
lda_pred_posterior = lda_clf.predict_proba(test_df[predictors])
print(lda_pred_posterior)

print(np.sum(lda_pred_posterior[:,0] >= 0.5))
print(np.sum(lda_pred_posterior[:,1] >= 0.5))
print(lda_pred_posterior[:20,0])
print(test_df.lda_pred_class[:20])
print(np.sum(lda_pred_posterior[:,0] >= 0.9))
print(np.max(lda_pred_posterior[:,0]))

# QUADRATIC DISCRIMINANT ANALYSIS
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis as QDA
# Create Classifier Instance
qda_clf = QDA()
# Fit model
qda_clf.fit(X_train,Y_train)
print('Class Priors (P(Y = k)) =', qda_clf.priors_)
print('Class Means μk\n   Down:', qda_clf.means_[0], '\n   Up:  ', lda_clf.means_[1])

qda_pred_class_coded = qda_clf.predict(test_df[predictors])
qda_pred_class = ['Up' if c == 1 else 'Down' for c in qda_pred_class_coded]
test_df['qda_pred_class'] = qda_pred_class
print('The model makes {0:.4f} correct predictions'.format(100*np.mean(test_df.qda_pred_class == test_df.Direction)))

# Compute Test Confusion Matrix #
#################################
table = pd.crosstab(test_df.qda_pred_class, test_df.Direction)
print(table)

# Scatter plot the data colored by market direction #
#####################################################
fig, ax = plt.subplots(figsize=(8,8))
# Plot the training lags color coded by market direction
ax.scatter(X_train[Y_train==1].Lag1, X_train[Y_train==1].Lag2, alpha=0.7, label='Up');
ax.scatter(X_train[Y_train==0].Lag1, X_train[Y_train==0].Lag2, alpha=0.7, label='Down');

# Calculate Bayes Decision Boundary #
#####################################
# Construct a meshgrid to calulate Bayes Boundary over
nx, ny = 200, 200
x_min, x_max = plt.xlim()
y_min, y_max = plt.ylim()
xx, yy = np.meshgrid(np.linspace(x_min, x_max, nx), np.linspace(y_min, y_max, ny))

# Use predict_proba to calculate Probability at each x1,x2 pair
Z = qda_clf.predict_proba(np.c_[xx.ravel(), yy.ravel()])
Z = Z[:, 1].reshape(xx.shape)
# The Bayes Boundary for k=2 classes is the contour where P(Y=k|X=x) = 0.5
cp = ax.contour(xx, yy, Z, [0.5], linewidths=1., colors='k');
plt.clabel(cp, inline=True, fmt='Bayes Decision Boundary',fontsize=8)

ax.set_xlabel('Lag1')
ax.set_ylabel('Lag2')
ax.legend(loc='best');
plt.savefig(PATH + 'qda.png', dpi=300)
plt.close()

# K NEAREST NEIGHBORS
from sklearn.neighbors import KNeighborsClassifier as KNNC
# Build a KNN classifier
knn_1 = KNNC(n_neighbors=1)
knn_1.fit(X_train, train_df.Direction)

knn1_pred = knn_1.predict(test_df[predictors])
print(knn1_pred)
print('The model makes {0:.4f}% correct predictions'.format(100*np.mean(knn1_pred == test_df.Direction)))

# Compute Test Confusion Matrix #
#################################
table = pd.crosstab(knn1_pred, test_df.Direction)
print(table)

# use 3 neighbors now
knn_3 = KNNC(n_neighbors=3)
knn_3.fit(X_train, train_df.Direction)
knn3_pred = knn_3.predict(test_df[predictors])
print('The model makes {0:.4f}% correct predictions'.format(100*np.mean(knn3_pred == test_df.Direction)))

# Compute Test Confusion Matrix #
#################################
table = pd.crosstab(knn3_pred, test_df.Direction)
print(table)

# CARAVAN APPLICATION
# Load the caravan insurance data for section 4.6.6
caravan_df = pd.read_csv('caravan.csv', index_col=0)
(caravan_df.head())
print(caravan_df.shape)
print(caravan_df.Purchase.describe())
print('The probability an individual purchased car insurance was,',
      1- caravan_df.Purchase.describe().freq / len(caravan_df.Purchase))

# Standardize the Variables #
#############################
X = scale(caravan_df.iloc[:,0:85], axis=0)

# check that X[:,1] is now standardized
print('mean =', np.mean(X[:,0]), 'variance = ', np.var(X[:,0]))
Y = caravan_df.Purchase.values

X_train = X[1000:]
X_test = X[:1000]
Y_train = Y[1000:]
Y_test = Y[:1000]
knn1 = KNNC(n_neighbors=1)
knn1.fit(X_train, Y_train)
knn1_pred = knn1.predict(X_test)
error_rate = np.mean(knn1_pred != Y_test)

print('The error rate for k={0:d} is {1:.3f} %'.format(1, 100*error_rate))
print('There are {} % custumors who bought insurance on the test set.'.format(np.mean(Y_test != 'No')))
table = pd.crosstab(knn1_pred, Y_test)
print(table)
print("The true positive rate on the test set: {}".format(table.values[1,1]/(table.values[1,1] + table.values[1,0])))

# Build a k=3 Neighbor Classifier #
###################################
knn3 = KNNC(n_neighbors=3)
knn3.fit(X_train, Y_train)
knn3_pred = knn3.predict(X_test)
error_rate = np.mean(knn3_pred != Y_test)
print('The error rate for k=3 is {} %'.format(100*error_rate))
table = pd.crosstab(knn3_pred, Y_test)
print("The true positive rate on the test for k=3 set: {}".format(table.values[1,1]/(table.values[1,1] + table.values[1,0])))

# Build a k=5 Neighbor Classifier #
###################################
knn5 = KNNC(n_neighbors=5)
knn5.fit(X_train, Y_train)
knn5_pred = knn5.predict(X_test)
error_rate = np.mean(knn5_pred != Y_test)
print('The error rate for k=5 is {} %'.format(100*error_rate))
table = pd.crosstab(knn5_pred, Y_test)
print("The true positive rate on the test for k=5 set: {}".format(table.values[1,1]/(table.values[1,1] + table.values[1,0])))

# Logistic Regression Approach
predictors = caravan_df.columns.tolist()[:-1]
#formula = 'ResCoded ~ ' + ' + '.join(predictors)
Y_train_coded = [0 if d == 'No' else 1 for d in Y_train]
X_train2 = sm.add_constant(X_train)
logit_fit = sm.Logit(Y_train_coded, X_train2).fit()
X_test2 = sm.add_constant(X_test, has_constant='add')
logit_probs = logit_fit.predict(X_test2)
logit_pred = pd.Series(['Yes' if p > 0.5 else 'No' for p in logit_probs])
table = pd.crosstab(logit_pred, Y_test)
print(table)

# move the threshold from 0.5 to 0.25
logit_pred = pd.Series(['Yes' if p > 0.25 else 'No' for p in logit_probs])
table = pd.crosstab(logit_pred, Y_test)
print(table)


# client.py v0.4
# Description:  A simple e2ee command line chat application. This is the client which will listen for incoming messages.
#               Features: RSA Encryption, Message Padding
# Changelog:    v0.1: Base Chat Listener/Sender
#               v0.2: Added RSA Key Generation & Exchange
#               v0.3: Added Encryption & Decryption
#               v0.4: Added Padding
#               v0.5: Added RSA Sign/Verify

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

from hashlib import sha512

import binascii
import socket, threading
import time

# Public/Private Key Generation
keys = RSA.generate(4096)
pubKey = keys.publickey()
pubStr = pubKey.exportKey("PEM")
pubStr = pubStr.decode('utf-8')

# User input for server's address and port
host_no = input("Enter server IP address: ")
port_no = int(input("Enter desired port number: "))

# Username
# if-else will check if whitespace are present in input, if present, replace whitespace with null
ADDR = (host_no, port_no)
name = input("Enter your name: ")
if " " in name:
    name = name.replace(" ", "")

# sender()
# Description:  1. Sends a initial message to Server telling that its connected
#               2. Constantly checks for input, if available, encrypt the message using encrypt(message) before sending out
def sender():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(ADDR)

    message = client_socket.recv(4096).decode('ascii')
    if message == 'NAME':
        client_socket.send(name.encode('ascii'))

    while True:
        message = '{}: {}'.format(name, input(''))
        signature = sign(message)
        message = encrypt(message)
        message = binascii.hexlify(message).decode('utf-8') + " " + signature
        client_socket.send(message.encode('ascii'))

# listener()
# Description:  Client will constantly listen to received messages and perform the following:
#               1. if message == 'NAME':    Check if a reply is received from the server, if yes, tells the server that the listener has been connected
#               2. if "entered" in message: Check if someone has entered the room
#                                           Yes:    Checks if its a listener, if no, performs key exchange
#                                           No:     Checks if its a system message, if no, decrypts the message before printing it
#               3. elif "BEING PUBLIC KEY": Checks if a key-exchange request is received, if yes, perform key-checks before storing the key in peer_key[]
def listener():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(ADDR)

    while True:
        try:
            message = client_socket.recv(4096).decode('ascii')
            if message == 'NAME':
                nameR = name + "'s Listener"
                client_socket.send(nameR.encode('ascii'))
            else:
                if "entered" in message:
                    if not name in message:
                        if not "Listener" in message:
                            print(message)
                            print("System: Initialising...")
                            message = key_exchange(message)
                            time.sleep(3)
                            client_socket.send(message.encode('ascii'))
                            print("System: Complete!")
                elif "BEGIN PUBLIC KEY" in message:
                    if not name in message:
                        print("System: Initialising...")
                        message = key_check(message)
                        if "YES" in message:
                            client_socket.send(message.encode('ascii'))
                        print("System: Complete!")
                else:
                    if not "Connection Success." in message:
                        signature = message.split()[1]
                        message = message.split()[0]
                        message = message.encode('utf-8')
                        message = binascii.unhexlify(message)
                        message = decrypt(message)
                        if "NO" in verify_signature(message, signature):
                            print("System: Message does not originate from original sender!")
                        print(message)
                    elif "left" in message:
                        print("System: " + message)
                    else:
                        print("System: " + message)
                        print("System: Please wait...")
        except Exception as e:
            # The following are for error handling
            #print(e)
            #print("Error. Bye.")
            #client_socket.close()
            #break
            pass

# Key Storage
peer_list = []
peer_key = []

# key_exchange()
# Description:  Performs Key Exchange. Checks if the name is present, if yes, sends a message back telling the target that the current client has its public key and will not require an exchange.
#               Will still send out personal public key.
# Args: message > System message that indicates who entered
def key_exchange(message):
    present = 0

    if not peer_list:
        message = '{} {} NO'.format(name, pubStr)
    else:
        for peer in peer_list:
            if peer in message:
                present = 1
                break
        if present == 1:
            message = '{} {} YES'.format(name, pubStr)
        else:
            message = '{} {} NO'.format(name, pubStr)
    return message

# key_check()
# Description:  Performs key storage. Checks if the target requires this client's public key, if yes, sends personal public key.
# Args: message > Received message that contains the target's name, public key and whether a key exchange is required
def key_check(message):
    sender = message.split()[0]
    key = message.split()[1] + " " + message.split()[2] + " " + message.split()[3] + "\n" + message.split()[4] + "\n" + message.split()[5] + "\n" + message.split()[6] + "\n" + message.split()[7] + "\n" + message.split()[8] + "\n" + message.split()[9] + "\n" + message.split()[10] + "\n" + message.split()[11] + "\n" + message.split()[12] + "\n" + message.split()[13] + "\n" + message.split()[14] + "\n" + message.split()[15] + "\n" + message.split()[16] + " "  + message.split()[17] + " "  + message.split()[18]
    status = message.split()[19]

    peer_list.append(sender)
    peer_key.append(key)

    if "NO" in status:
        return '{} {} YES'.format(name, pubStr)
    else:
        return "NO"

# encrypt()
# Description:  Pads the message using pad() before encrypting the message with personal private key.
# Args: message > Input string
def encrypt(message):
    peerKey = RSA.importKey(peer_key[0])
    encryptor = PKCS1_OAEP.new(peerKey)
    message = pad(message)
    return encryptor.encrypt(message.encode('utf-8'))

# decrypt()
# Description:  Decrypts the received message and unpad it before returning
# Args: message > Received message from target
def decrypt(message):
    decryptor = PKCS1_OAEP.new(keys)
    message = decryptor.decrypt(message).decode('utf-8')
    return unpad(message)

# pad()
# Description:  Pads the input with two strings, one at the front and the other at the end. These will be used for tampering checks.
# Args: message > Input string
def pad(message):
    return "=what=is=nice=" + message + "=apple=pie="

# unpad()
# Description:  Unpads the decrypted message and return the original message. If two predefined substrings are not present, informs the user that message has been tampered.
# Args: message > Decrypted message
def unpad(message):
    if "=what=is=nice=" in message:
        if "=apple=pie=" in message:
            message = message.replace("=what=is=nice=", "")
            message = message.replace("=apple=pie=", "")
            return message
        else:
            return "System: Message is tempered!\nSystem: Received message: " + message
    else:
        return "System: Message is tempered!\nSystem: Received message: " + message

# sign()
# Description:  Signs the input using client's private key which will be used for identity tracing when the target receives
# Args: message > Input string
def sign(message):
    hash = int.from_bytes(sha512(message.encode('utf-8')).digest(), byteorder='big')
    return hex(pow(hash, keys.d, keys.n))

# verify_signature()
# Description:      Verify the authencity of the received message, if it belongs to the target, returns "YES" to tell the system that this is a verified message
# Args: message     > Decrypted message
#       signature   > Received signature from target
def verify_signature(message, signature):
    peerKey = RSA.importKey(peer_key[0])
    hash = int.from_bytes(sha512(message.encode('utf-8')).digest(), byteorder='big')
    hashFromSignature = pow(int(signature, 0), peerKey.e, peerKey.n)
    if hash == hashFromSignature:
        return "YES"
    else:
        return "NO"

# Threading to allow separation of client's sender and receiver
send_thread = threading.Thread(target=sender)
send_thread.start()
receive_thread = threading.Thread(target=listener)
receive_thread.start()


# 프로그래머스_레벨 2_영어 끝말잇기
# 220814

from collections import defaultdict

def solution(n, words):
    word_dict = defaultdict(bool)
    prev = '?'
    for idx, word in enumerate(words):
        # 이미 이전에 나온 단어인지 확인
        if word_dict[word]: return [(idx % n) + 1, (idx // n) + 1]
        else: word_dict[word] = True

        # 이전 단어의 끝말잇기가 되는지 확인
        if prev == word[0] or prev == '?': prev = word[-1]
        else: return [(idx % n) + 1, (idx // n) + 1]

    return [0, 0]

프로그래머스/레벨 2_영어 끝말잇기.py

레벨 2_영어 끝말잇기.py


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 16 22:37:53 2020

@author: shreyasaxena
"""
import matplotlib.pyplot as plt
from sklearn.cross_decomposition import CCA
import numpy as np
import os

def parse_areanames(areanames_):
    areainds=[]; areanames=[];
    for i,area in enumerate(areanames_[0][0]):
        areainds.append(area[0][0])
        areanames.append(areanames_[0][0].dtype.descr[i][0])
    sortvec=np.argsort(np.abs(areainds))
    areanames=[areanames[i] for i in sortvec]
    areainds=[areainds[i] for i in sortvec]
    return areainds,areanames

def plot_components(A,C,areas,atlas,areanames_,outputfolder):
   # Make figures directory
    figdir=os.path.join(outputfolder,'Figures')
    if not os.path.exists(figdir):
        os.makedirs(figdir)

    areainds,areanames = parse_areanames(areanames_)

    print('plotting components',flush=True)
    # One figure per component
    if not os.path.exists(os.path.join(figdir,'AllComponents')):
        os.makedirs(os.path.join(figdir,'AllComponents'))

    for i,area in enumerate(areas):
        try:
            areadir=os.path.join(figdir,'AllComponents',areanames[areainds.index(area)])
            if not os.path.exists(areadir):
                os.makedirs(areadir)
            fig=plt.figure()
            ax1 = fig.add_subplot(2,2,1)
            ax1.imshow(atlas==area);
            ax1.set_title('Atlas '+areanames[areainds.index(area)])
            ax1.axis('off')

            ax2 = fig.add_subplot(2,2,2)
            ax2.imshow(A[:,:,i])
            ax2.set_title('A [%s]'%(i+1))
            ax2.axis('off')

            ax3 = fig.add_subplot(2,1,2)
            ax3.plot(C[i,:min(1000,C.shape[1])])
            ax3.set_title('C [%s]'%(i+1))
            fig.savefig(os.path.join(areadir,'Component_'+str(i+1)+'.png'))
            plt.close()
        except:
            pass

    # Spatial and Temporal Components: Summary
    atlascolor=np.zeros((atlas.shape[0],atlas.shape[1],4))
    A_color=np.zeros((A.shape[0],A.shape[1],4))
    cmap=plt.cm.get_cmap('jet')
    colors=cmap(np.arange(len(areainds))/len(areainds))
    for i,area_i in enumerate(areainds):
        if area_i not in areas:
            continue
        atlascolor[atlas==area_i,:]=colors[i,:]
        C_area=C[np.where(areas==area_i)[0],:]
        for j in np.arange(colors.shape[1]):
            A_color[:,:,j]=A_color[:,:,j]+colors[i,j]*A[:,:,np.where(areas==area_i)[0][0]]
    fig=plt.figure(figsize=(10,10))
    ax1=fig.add_subplot(2,2,1)
    ax1.imshow(atlascolor)
    ax1.set_title('Atlas Regions')
    ax1.axis('off')
    ax2=fig.add_subplot(2,2,3)
    ax2.imshow(A_color)
    ax2.set_title('Spatial Components (One per region)')
    ax2.axis('off')
    ax3=fig.add_subplot(1,2,2)
    axvar=0
    for i,area_i in enumerate(areainds):
        if area_i not in areas:
            continue
        C_area=C[np.where(areas==area_i)[0][0],:min(1000,C.shape[1])]
        ax3.plot(1.5*axvar+C_area/np.nanmax(np.abs(C_area)),color=colors[i,:])
        axvar+=1
    ax3.set_title('Temporal Components (One per region)')
    ax3.axis('off')
    fig.savefig(os.path.join(figdir,'SummaryComponents.png'))
    plt.close()

    return figdir

def plot_correlations(A,C,areas,atlas,areanames_,outputfolder):
    # Correlation plot
   # Make figures directory
    figdir=os.path.join(outputfolder,'Figures')
    if not os.path.exists(figdir):
        os.makedirs(figdir)

    areainds,areanames = parse_areanames(areanames_)

    # Preprocess C to remove nans
    keepinds=np.nonzero(np.sum(np.isfinite(C),axis=0))[0]
    C=C[:,keepinds]
    corrmat=np.zeros((len(areainds),len(areainds)))
    skipinds=[]
    for i,area_i in enumerate(areainds):
        for j,area_j in enumerate(areainds):
            if i==0 and area_j not in areas:
                skipinds.append(j)
            C_i=C[np.where(areas==area_i)[0],:].T
            C_j=C[np.where(areas==area_j)[0],:].T
            if i not in skipinds and j not in skipinds:
                cca=CCA(n_components=1)
                cca.fit(C_i,C_j)
                C_i_cca,C_j_cca=cca.transform(C_i,C_j)
                try:
                    C_i_cca=C_i_cca[:,0]
                except:
                    pass
                try:
                    C_j_cca=C_j_cca[:,0]
                except:
                    pass
                corrmat[i,j]=np.corrcoef(C_i_cca,C_j_cca)[0,1]
    corrmat=np.delete(corrmat,skipinds,axis=0);
    corrmat=np.delete(corrmat,skipinds,axis=1);
    corr_areanames=np.delete(areanames,skipinds)
    print('plotting correlations',flush=True)
    fig=plt.figure(figsize=(16,16))
    plt.imshow(corrmat,cmap=plt.cm.get_cmap('jet')); plt.colorbar(shrink=0.8)
    plt.get_cmap('jet')
    plt.xticks(ticks=np.arange(len(areainds)-len(skipinds)),labels=corr_areanames,rotation=90);
    plt.yticks(ticks=np.arange(len(areainds)-len(skipinds)),labels=corr_areanames);
    plt.title('CCA between all regions',fontsize=36)
    plt.xlabel('Region i',fontsize=30)
    plt.ylabel('Region j',fontsize=30)
    fig.savefig(os.path.join(figdir,'CorrelationPlot.png'))
    plt.close()

    return figdir


from flask import Flask, render_template, request, redirect, session
app = Flask(__name__)
app.secret_key = 'csdvdf'

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/process', methods=['POST'])
def process():
    name = request.form['name']
    age = request.form['age']
    print(name)
    session['ninja'] = {
        'name': name,
        'age': age
    }
    return redirect('/results')

@app.route('/results')
def results():
    return render_template('results.html')

if __name__ == "__main__":
    app.run(debug=True)


import argparse
from datetime import date, timedelta

from .constants import DATES_FORMAT

today = date.today()
month_ago = today - timedelta(days=30)

parser = argparse.ArgumentParser()
main_subparsers = parser.add_subparsers(dest='subparser_name')
login_parser = main_subparsers.add_parser(
    'login', help='Log in and save your credentials.')
login_parser.add_argument(
    '--remember', dest="remember_credentials",  action="store_true", help="Save credentials; enables automatically re-authenticating on expired session.")

# ACCOUNTS
accounts_parser = main_subparsers.add_parser(
    'accounts', help='List accounts')
accounts_parser.add_argument('account_id', nargs="?")
accounts_subparsers = accounts_parser.add_subparsers(
    dest='accounts_subparser_name')

# ACCOUNTS [id] transactions
transactions_parser = accounts_subparsers.add_parser(
    'transactions', help='List and filter transactions')
transactions_parser.add_argument(
    '--start', required=False, default=month_ago.strftime(DATES_FORMAT))
transactions_parser.add_argument(
    '--end', required=False, default=today.strftime(DATES_FORMAT))
transactions_parser.add_argument(
    '--type', choices=['in', 'out'], required=False)
transactions_parser.add_argument('--name', required=False)

# ACCOUNTS [id] balance
balance_parser = accounts_subparsers.add_parser(
    'balance', help="Show the balance on the specified account")

# ACCOUNtS [id] reservations
reservations_parser = accounts_subparsers.add_parser(
    'reservations', help="List reserved funds")

# CARDS
cards_parser = main_subparsers.add_parser('cards', help='List cards')
cards_parser.add_argument('card_id', nargs='?')
cards_subparsers = cards_parser.add_subparsers(dest="cards_subparser_name")

# CARDS [id] balance
cards_subparsers.add_parser(
    'balance', help="Show the balance on the specified card")

# CARDS [id] transactions
cards_subparsers.add_parser(
    'transactions', help="List and filter card transactions")

# export
parsed_args = parser.parse_args()


import matplotlib.pyplot as plt
import numpy as np

from pyha.common.util import is_float, is_complex
from pyha.cores.util import SQNR
from pyha.simulation.tracer import Tracer

figsize = (9.75, 5)

def plot_time_domain(simulations, name='Time domain'):
    simulations["MODEL"] = np.array(simulations["MODEL"])
    simulations["HARDWARE"] = np.array(simulations["HARDWARE"])
    if is_float(simulations["MODEL"][0]):
        fig, ax = plt.subplots(2, sharex="all", figsize=figsize, gridspec_kw={'height_ratios': [4, 2]})

        if name:
            fig.suptitle(name, fontsize=14, fontweight='bold')
        ax[0].plot(simulations["MODEL"], label='MODEL')
        ax[0].plot(simulations["HARDWARE"], label='HARDWARE')
        ax[0].set(title=f'SQNR={SQNR(simulations["MODEL"], simulations["HARDWARE"]):.2f} dB')
        ax[0].set_xlabel('Sample')
        ax[0].set_ylabel('Magnitude')
        ax[0].grid(True)
        ax[0].legend(loc='upper right')

        ax[1].plot(simulations["MODEL"] - simulations["HARDWARE"], label='Error')
        ax[1].grid(True)
        ax[1].legend(loc='upper right')
    elif is_complex(simulations["MODEL"][0]):
        fig, ax = plt.subplots(2, 2, sharex="all", sharey='row', figsize=figsize,
                               gridspec_kw={'height_ratios': [4, 2]})

        if name:
            fig.suptitle(name, fontsize=14, fontweight='bold')
        ax[0][0].plot(simulations["MODEL"].real, label='MODEL')
        ax[0][0].plot(simulations["HARDWARE"].real, label='HARDWARE')
        ax[0][0].set(title=f'REAL SQNR={SQNR(simulations["MODEL"].real, simulations["HARDWARE"].real):.2f} dB')
        ax[0][0].set_xlabel('Sample')
        ax[0][0].set_ylabel('Magnitude')
        ax[0][0].grid(True)
        ax[0][0].legend(loc='upper right')

        ax[1][0].plot(simulations["MODEL"].real - simulations["HARDWARE"].real, label='Error')
        ax[1][0].grid(True)
        ax[1][0].legend(loc='upper right')

        ax[0][1].plot(simulations["MODEL"].imag, label='MODEL')
        ax[0][1].plot(simulations["HARDWARE"].imag, label='HARDWARE')
        ax[0][1].set(title=f'IMAG SQNR={SQNR(simulations["MODEL"].imag, simulations["HARDWARE"].imag):.2f} dB')
        ax[0][1].set_xlabel('Sample')
        ax[0][1].set_ylabel('Magnitude')
        ax[0][1].grid(True)
        ax[0][1].legend(loc='upper right')

        ax[1][1].plot(simulations["MODEL"].imag - simulations["HARDWARE"].imag, label='Error')
        ax[1][1].grid(True)
        ax[1][1].legend(loc='upper right')

    plt.tight_layout(rect=[0, 0, 1, 0.95])
    plt.show()

def plot_frequency_domain(simulations, name='Frequency domain', window=plt.mlab.window_hanning, xlim=None, ylim=None):
    simulations["MODEL"] = np.array(simulations["MODEL"])
    simulations["HARDWARE"] = np.array(simulations["HARDWARE"])
    gain = 1.0
    fig, ax = plt.subplots(2, sharex="all", figsize=figsize, gridspec_kw={'height_ratios': [4, 2]})

    if name:
        fig.suptitle(name, fontsize=14, fontweight='bold')

    spec_model, freq, _ = ax[0].magnitude_spectrum(simulations["MODEL"] * gain,
                                                   window=window,
                                                   scale='dB', label='MODEL')
    spec_pyha, _, _ = ax[0].magnitude_spectrum(simulations["HARDWARE"] * gain,
                                               window=window,
                                               scale='dB',
                                               label='HARDWARE')

    ax[0].set(title=f'SQNR={SQNR(simulations["MODEL"], simulations["HARDWARE"]):.2f} dB')
    ax[0].grid(True)
    ax[0].legend(loc='upper right')

    ax[1].plot(freq, 20 * np.log10(spec_model) - 20 * np.log10(spec_pyha), label='Error')
    ax[1].grid(True)
    ax[1].legend(loc='upper right')

    plt.tight_layout(rect=[0, 0, 1, 0.95])
    if xlim:
        plt.xlim(xlim)

    if ylim:
        ax[0].set_ylim(ylim)
        ax[1].set_ylim(ylim)

    plt.show()

def plot_frequency_response(simulations, name='Frequency response', xlim=None, ylim=None):
    simulations["MODEL"] = np.array(simulations["MODEL"])
    simulations["HARDWARE"] = np.array(simulations["HARDWARE"])
    gain = len(simulations["MODEL"])
    window = plt.mlab.window_none
    if is_complex(simulations["MODEL"][0]):
        gain *= 0.707

    simulations["MODEL"] *= gain
    simulations["HARDWARE"] *= gain
    plot_frequency_domain(simulations, name, window, xlim, ylim)

def plot_imshow(simulations, rows, transpose=False, name=None):
    simulations["MODEL"] = np.array(simulations["MODEL"])
    simulations["HARDWARE"] = np.array(simulations["HARDWARE"])
    fig, ax = plt.subplots(1, 2, figsize=figsize, sharex='all', sharey='all')

    if name:
        fig.suptitle(name, fontsize=14, fontweight='bold')

    from skimage.exposure import exposure

    inp = np.reshape(simulations["MODEL"], (-1, rows))
    if transpose:
        inp = inp.T

    p2, p98 = np.percentile(inp, (2, 98))
    inp = exposure.rescale_intensity(inp, in_range=(p2, p98))

    ax[0].imshow(inp, interpolation='nearest', aspect='auto', origin='lower')
    ax[0].set(title=f'MODEL')
    ax[0].set_xlabel('Time')
    ax[0].set_ylabel('Magnitude')

    inp = np.reshape(simulations["MODEL"], (-1, rows))
    if transpose:
        inp = inp.T

    p2, p98 = np.percentile(inp, (2, 98))
    inp = exposure.rescale_intensity(inp, in_range=(p2, p98))

    ax[1].imshow(inp, interpolation='nearest', aspect='auto', origin='lower')
    ax[1].set(title=f'HARDWARE, SQNR={SQNR(simulations["MODEL"], simulations["HARDWARE"]):.2f} dB')
    ax[1].set_xlabel('Time')
    ax[1].set_ylabel('Magnitude')

    plt.tight_layout(rect=[0, 0, 1, 0.95])
    plt.show()

def plot_trace():
    traces = Tracer.get_sorted_traces()
    for i, (k, v) in enumerate(traces.items()):
        plot_time_domain(v, name=k)

def plot_trace_input_output(plotter=plot_time_domain):
    its = list(Tracer.get_sorted_traces().items())
    plotter(its[0][1], name=its[0][0])
    plotter(its[-1][1], name=its[-1][0])
    # return traces[0], traces[-1]


"""
Project name: fish_book
Description:
Create Time: 2020/7/31 13:35
Author: to2bage
Email: to2bage@hotmail.com
Version: 0.1
"""
from wtforms import Form, StringField, IntegerField
from wtforms.validators import DataRequired, Length, NumberRange

class SearchForm(Form):
    q = StringField(
        validators=[
            DataRequired(message="关键字是必填项目"),
            Length(min=1, max=30, message="关键字有长度的要求: [1, 30]")
        ]
    )
    page = IntegerField(
        validators=[
            NumberRange(min=1, max=99, message="页码的范围: [1, 99]")
        ], default=1
    )


from django.urls import path, include
from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'books', views.AllBooksView)
router.register(r'search', views.SearchBooksView)
router.register(r'date', views.FilteredByDate)

app_name = 'restapi'
urlpatterns = [
    path('', include(router.urls)),
    ]


# Python
from flask import Flask, request, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///posts.db'
db = SQLAlchemy(app)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    message = db.Column(db.String(500), nullable=False)
    time = db.Column(db.String(50), nullable=False)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        name = request.form.get('name')
        message = request.form.get('message')
        time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        new_post = Post(name=name, message=message, time=time)
        db.session.add(new_post)
        db.session.commit()

    search = request.args.get('search')
    order = request.args.get('order')

    query = Post.query

    if search:
        query = query.filter(Post.name.contains(search))

    if order == 'old':
        query = query.order_by(Post.time)
    else:
        query = query.order_by(Post.time.desc())

    posts = query.all()

    return render_template('index.html', posts=posts)

@app.route('/post/<int:post_id>')
def post_detail(post_id):
    post = Post.query.get_or_404(post_id)
    return render_template('post_detail.html', post=post)

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)


import sys
import re
import random
import os
from subprocess import Popen
import argparse
import res_selection
import readxvg

from molecule import molecule
#import cpc.dataflow
#from cpc.dataflow import FileValue
from cpc.lib.gromacs import cmds

# If initial_confs is None or zero length, use start/end etc to interpolate, otherwise use the structures in initial_confs
#
# Note: if initial_confs are given, they should include the start and end configs as well (the complete string)

def write_restraints(inp, initial_confs, start, end, start_xvg, end_xvg, tpr, top, includes, n, ndx_file, Nchains):
    cmdnames = cmds.GromacsCommands()
    # Get the atoms involved with the residues to use for dihedrals (might be more than one atom in the index
    # per residue, since it's probably generated by make_ndx)
    ndx_atoms = res_selection.read_ndx(ndx_file)
    # Map them to each affected residue so we just get the residue numbers back
    selection = res_selection.res_select(start, ndx_atoms)

    n = int(n)  # number of points in the string, including start and end point

    use_interpolation = False

    if initial_confs is None or len(initial_confs) == 0:
        use_interpolation = True
        # Read the starting and ending dihedrals for later interpolation
        startpts = readxvg.readxvg(start_xvg, selection)
        endpts = readxvg.readxvg(end_xvg, selection)
    else:
        # Have to generate the dihedrals ourselves from the given initial structures
        # Note: when we get an initial_confs[] array, we use it for all points and
        # the start/end input parameters are completely ignored
        # TODO: assert that len(initial_confs) == n otherwise?

        ramaprocs = {}

        # Run g_rama (in parallel) on each structure and output to a temporary .xvg
        FNULL = open(os.devnull, 'w') # dont generate spam from g_rama
        for i in range(n):
            # TODO: check for and use g_rama_mpi.. like everywhere else
            cmd = cmdnames.rama.split() + ['-f', initial_confs[i], '-s', tpr,
                                           '-o', '0%3d.xvg' % i]
            ramaprocs[i] = Popen(cmd, stdout=FNULL, stderr=FNULL)

        # Go through the output from the rama sub-processes and read the xvg outputs

        stringpts = {}  # Will have 4 levels: stringpoint, residue, chain, phi/psi value

        for i in range(n):
            # Start array indexed by residue
            xvg_i = os.path.join(inp.getOutputDir(), '0%3d.xvg' % i)
            # Make sure the corresponding g_rama task has ended
            ramaprocs[i].communicate()
            # Read back and parse like for the start/end_xvg above
            stringpts[i] = readxvg.readxvg(xvg_i, selection)

    # Rewrite the topology to include the res itp files instead of the original per-chain itps (if any)
    # There will be one topol_x.top per string point

    sys.stderr.write('%s' % includes)
    for k in range(n):
        with open(top) as in_topf:
            in_top = in_topf.read()
            for mol in range(Nchains):
                if len(includes) > 0:
                    includename = includes[mol].split('/')[-1]
                    in_top = re.sub(includename, 'res_%d_chain_%d.itp' % (k, mol), in_top)
            with open('topol_%d.top' % k,'w') as out_top:
                # sys.stderr.write('%s'%in_top)
                out_top.write(in_top)

    # Generate/copy and write-out the dihedrals for each point
    for k in range(n):
        for mol in range(Nchains):
            # TODO: use with statement for restraint_itp as well
            restraint_itp = open('res_%d_chain_%d.itp' % (k, mol), 'w')
            if Nchains > 1:
                with open(includes[mol]) as moltop_f:
                    moltop = moltop_f.read()
                    restraint_itp.write(moltop)
            # write the initial part of the topology file
            # Note: gromacs 4.6+ required
            restraint_itp.write("[ dihedral_restraints ]\n")
            restraint_itp.write("; ai   aj   ak   al  type phi  dphi  kfac\n")
            if len(includes) > 0:
                protein = molecule(includes[mol])
                # replace the chain names with the chain names
            else:
                with open('topol_%d.top' % k, 'w') as out_top:
                    protein = molecule(top)
                    with open(top,'r') as in_itp_f:
                        in_itp = in_itp_f.read().split('; Include Position restraint file')
                        out_top.write(in_itp[0])
                        out_top.write('#include "res_%d_chain_%d.itp"\n' % (k, mol))
                        out_top.write(in_itp[1])

            # Create a lookup-table for the protein topology that maps residue to dihedrally relevant
            # backbone atom indices for N, CA and C.

            dih_atoms = {}

            for a in protein:
                if (a.atomname == 'CA' or a.atomname == 'N' or a.atomname == 'C'):
                    try:
                        dih_atoms[a.resnr][a.atomname] = a.atomnr;
                    except KeyError:
                        dih_atoms[a.resnr] = { a.atomname: a.atomnr }

            # Use the lookup-table built above and get the dihedral specification atoms needed for each
            # residue in the selection. This is O(n) in residues, thanks to the dih_atoms table.

            for r in selection:
                # Get the atom numbers to use for the phi and psi dihedrals (4 atoms each)

                # phi is C on the previous residue, and N, CA, C on this
                phi = [ dih_atoms[r - 1]['C'], dih_atoms[r]['N'], dih_atoms[r]['CA'], dih_atoms[r]['C'] ]

                # psi is N, CA and C on this residue and N on the next
                psi = [ dih_atoms[r]['N'], dih_atoms[r]['CA'], dih_atoms[r]['C'], dih_atoms[r + 1]['N'] ]

                # Write phi, psi angles and the associated k factor into a row in the restraint file
                # Note: in the Gromacs 4.6+ format, the k-factor is here. Before, it was in the .mdp as
                # dihre_fc.
                # Also see reparametrize.py

                if use_interpolation:
                    # k is from 0 to n-1, so map it so we get a factor from 0 to 1
                    phi_val = startpts[r][mol][0] + k * (endpts[r][mol][0] - startpts[r][mol][0]) / (n - 1)
                    psi_val = startpts[r][mol][1] + k * (endpts[r][mol][1] - startpts[r][mol][1]) / (n - 1)
                else:
                    # Use the values extracted from the initial_confs[] structures above
                    phi_val = stringpts[k][r][mol][0]
                    psi_val = stringpts[k][r][mol][1]

                # Since we need different force constants in different stages, we need to put
                # a searchable placeholder in the file here and replace it later. KFAC is normally
                # a %8.4f number.
                restraint_itp.write("%5d%5d%5d%5d%5d %8.4f%5d  KFAC\n"
                                    %(phi[0], phi[1], phi[2], phi[3], 1, phi_val, 0))
                restraint_itp.write("%5d%5d%5d%5d%5d %8.4f%5d  KFAC\n"
                                    %(psi[0], psi[1], psi[2], psi[3], 1, psi_val, 0))

            restraint_itp.close()


import os
import json
from pathlib import Path
import shutil

# Define paths
#base_path = Path("..\data")
base_path = Path("racuni")

metadata_path = base_path.joinpath("key")
image_path = base_path.joinpath("img")
# define metadata list
metadata_list = []

# parse metadata
for file_name in metadata_path.glob("*.json"):
  with open(file_name, "r", encoding="utf8") as json_file:
    # load json file
    data = json.load(json_file)
    # create "text" column with json string
    text = json.dumps(data)
    # add to metadata list if image exists
    if image_path.joinpath(f"{file_name.stem}.jpg").is_file():
      metadata_list.append({"text":text,"file_name":f"{file_name.stem}.jpg"})
      # delete json file

# write jsonline file
with open(image_path.joinpath('metadata.jsonl'), 'w') as outfile:
    for entry in metadata_list:
        json.dump(entry, outfile)
        outfile.write('\n')

# remove old meta data
shutil.rmtree(metadata_path)


#!/usr/bin/env python3
'''read json and write markdown table'''

import json
import argparse
from sys import stdout, stderr

def parseOptions():
    '''Parse the commandline options'''
    parser = argparse.ArgumentParser(description='None :)')
    parser.add_argument('--verbose','-v', dest='verbose', action='count', default=0)
    parser.add_argument('--inputfile','--input', '-i', default=None)
    args = parser.parse_args()
    return args
args = parseOptions()

with open(args.inputfile,"r") as f:
    jsonstring = f.read()
metrics = [  "cores", "ram", "instances", "gigabytes", "floating-ips", "fixed-ips"]

data = json.loads(jsonstring)
allvos={}

# print(json.dumps(data, sort_keys=True, indent=4, separators=(',', ': ')))

# collect available VOs
for site in data.keys():
    for vo in data[site].keys():
        if vo not in ["mteam.data.kit.edu"]:
            allvos[vo]=True

# Dump the tables

for metric in metrics:

    stdout.write(F"| {metric} |")
    for vo in allvos:
        stdout.write(F" {vo.split('.')[0]} |")
    print("")
    for vo in allvos:
        stdout.write("|-------------------------")
    print("|---|")
    for site in data.keys():
        stdout.write(F"| {site}| ")
        for vo in allvos:
            if data[site].get(vo):
                stdout.write(F"    {data[site].get(vo)[metric]}|")
            else:
                stdout.write(F"    | ")
        print("")
    print ("\n\n")


import numpy as np
import matplotlib.pyplot as plt
import math as m

#Trapz rule is NOT L-stable! (While Backward Euler is L-Stable)
#Test equation: y'(t)=-2000*(y-cos(t)), y(0)=0

def Fun(t,x):
    return -2000*(x-m.cos(t))

tf=1.5
t0=0
ts=50
k=(tf-t0)/ts
t=np.linspace(t0,tf,ts+1)
y=np.zeros((ts+1)) #trapz
yE=np.zeros((ts+1)) #Backward Euler
y0=0
y[0]=y0
yE[0]=0

for i in range (0,ts):
    y[i+1]=(y[i]+1000*k*(-y[i]+m.cos(t[i])+m.cos(t[i+1])))/(1+k*1000)
    yE[i+1]=(y[i]+2000*k*m.cos(t[i+1]))/(1+k*2000)

plt.plot(t,y,marker='o',label='Trapezi')
plt.plot(t,yE,marker='d',label='Backward Euler')
plt.legend()
plt.show()


from zipfile import ZipFile
from os.path import join, isdir
import os
import shutil
import scipy.ndimage
import tifffile
import numpy as np

from_path = 'walmart_1/zips'
to_path = 'walmart_1/ims'
tmp_path = 'tmp'
for filename in os.listdir(from_path):
    print (filename)
    with ZipFile(join(from_path, filename), 'r') as zipObj:
        if (isdir(tmp_path)):
            shutil.rmtree(tmp_path)
        os.makedirs(tmp_path)
        # Extract all the contents of zip file in different directory
        zipObj.extractall(tmp_path)

        for f in os.listdir(tmp_path):
            if (f.endswith('_Analytic_clip.tif')):
                dn_f = f[:-9] + '_DN_udm_clip.tif'
                clouds_np = tifffile.imread(join(tmp_path, dn_f)) > 0
                clouds_np = scipy.ndimage.grey_opening(clouds_np, (15, 15))

                if (np.max(clouds_np) == False):
                    shutil.move(join(tmp_path, f), join(to_path, f))
        #sys.exit()


from collections import defaultdict

dd = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: 0)))
all_ranges = []

#0 = undefined, 1 = on, -1 = off

#with open("input.txt", "r") as f:
#with open("test.txt", "r") as f:
with open("storre.txt", "r") as f:
    for line in f.readlines():
        split = line.split(" ")
        cmd = split[0]
        split = split[1:][0]

        ranges = split.split(",")
        for i, x in enumerate(ranges):
            ranges[i] = x[2:].strip()
            ranges[i] = tuple([int(val) for val in ranges[i].split("..")])
        all_ranges.append((cmd, ranges))

for cmd, ranges in all_ranges:
    x_range, y_range, z_range = ranges
    for x in range(x_range[0], x_range[1] + 1):
        for y in range(y_range[0], y_range[1] + 1):
            for z in range(z_range[0], z_range[1] + 1):
                #print(x, y, z)

                if cmd == "on":
                    dd[x][y][z] = 1
                else:
                    dd[x][y][z] = -1
print("begnin")
res = 0
for x in dd.values():
    for y in x.values():
        for z in y.values():
            if z == 1:
                res += 1
#all_cubes = dd.values().values().values()
#res = len(list(filter(lambda x: x == 1, all_cubes)))
print("res:", res)


from djangae.test import TestCase
from django.contrib.auth.models import AnonymousUser
from django.http import Http404
from django.template import TemplateSyntaxError
from django.test import RequestFactory, override_settings
from django_webtest import WebTest

from tracker.checks import check_csp_is_not_report_only, check_session_csrf_enabled, check_csp_sources_not_unsafe
from tracker.site.models import Ticket, Project
from tracker.site.views import update_project_view, update_ticket_view, create_ticket_view, delete_ticket_view, \
    my_tickets_view, create_project_view
from tracker.site.factories import ProjectFactory, TicketFactory

class ProjectTest(TestCase):
    def setUp(self):
        self.project = ProjectFactory.create()
        self.user = self.project.created_by
        self.rf = RequestFactory()

    def test_projects_unauthenticated(self):
        r = self.client.get('/projects/')
        self.assertEquals(r.status_code, 200)

    def test_project_edit(self):
        # I'm unsure how to test with logged user using djangoae
        # Using request factory to bypass that.
        request = self.rf.get('/projects/%s/edit/' % self.project.id)
        request.user = self.user
        r = update_project_view(request, project_id=self.project.id)
        self.assertEqual(r.status_code, 200)
        r.render()
        self.assertIn(u'Edit', r.content.decode('utf8'))

    def test_project_create_ticket(self):
        # I'm unsure how to test with logged user using djangoae
        # Using request factory to bypass that.
        request = self.rf.get('/projects/%s/tickets/create' % self.project.id)
        request.user = self.user
        r = create_ticket_view(request, project_id=self.project.id)
        self.assertEqual(r.status_code, 200)
        r.render()
        self.assertIn(u'Submit', r.content.decode('utf8'))

    def test_project_create_get(self):
        # I'm unsure how to test with logged user using djangoae
        # Using request factory to bypass that.
        request = self.rf.get('/projects/create')
        request.user = self.user
        r = create_project_view(request)
        self.assertEqual(r.status_code, 200)
        r.render()
        self.assertIn(u'Submit', r.content.decode('utf8'))

    def test_project_create_post(self):
        # I'm unsure how to test with logged user using djangoae
        # Using request factory to bypass that.
        request = self.rf.post('/projects/create', data={'title': 'New project'})
        request.user = self.user
        r = create_project_view(request)
        self.assertEqual(r.status_code, 302)
        self.assertTrue(Project.objects.filter(title='New project'))

class TicketTest(TestCase):
    def setUp(self):
        self.ticket = TicketFactory.create()
        self.user = self.ticket.created_by
        self.project = self.ticket.project
        self.rf = RequestFactory()

    def test_my_tickets_not_authenticated(self):
        request = self.rf.get('/')
        request.user = AnonymousUser()
        r = my_tickets_view(request)
        self.assertEqual(r.status_code, 200)

    def test_my_tickets_authenticated(self):
        request = self.rf.get('/')
        request.user = self.user
        r = my_tickets_view(request)
        self.assertEqual(r.status_code, 200)

    def test_switch_ticket_ownership(self):
        project2 = ProjectFactory.create()
        self.assertNotEqual(project2.id, self.project.id)

        request = self.rf.get('/projects/%s/tickets/%s/edit' % (project2.id, self.ticket.id))
        # I'm unsure how to test with logged user using djangoae
        # Using request factory to bypass that.
        request.user = self.user
        self.assertRaises(Http404, update_ticket_view, request, project_id=project2.id, ticket_id=self.ticket.id)

    def test_ticket_edit(self):
        # I'm unsure how to test with logged user using djangoae
        # Using request factory to bypass that.
        request = self.rf.get('/projects/%s/tickets/%s/edit' % (self.project.id, self.ticket.id))
        request.user = self.user
        r = update_ticket_view(request, project_id=self.project.id, ticket_id=self.ticket.id)
        self.assertEqual(r.status_code, 200)
        r.render()
        self.assertIn(u'Submit', r.content.decode('utf8'))

    def test_ticket_delete(self):
        # I'm unsure how to test with logged user using djangoae
        # Using request factory to bypass that.
        request = self.rf.post('/projects/%s/tickets/%s/delete' % (self.project.id, self.ticket.id))
        request.user = self.user
        r = delete_ticket_view(request, project_id=self.project.id, ticket_id=self.ticket.id)
        self.assertEqual(r.status_code, 302)
        self.assertFalse(Ticket.objects.filter(id=self.ticket.id).exists())

class ProjectWebTest(WebTest):
    def setUp(self):
        self.project = ProjectFactory.create()
        self.user = self.project.created_by

    def test_project_details(self):
        projects_list = self.app.get('/projects/', user=self.user.username)
        self.assertIn(self.project.title, projects_list)

        # Now click on the title to access details
        project_details = projects_list.click(self.project.title)

        # Not ideal as using string which can change.
        self.assertIn('Create ticket', project_details)

class CheckTests(TestCase):
    @override_settings(MIDDLEWARE_CLASSES=[])
    def test_check_missing_session_middleware(self):
        self.assertEqual(check_session_csrf_enabled(), ['SESSION_CSRF_DISABLED'])

    @override_settings(CSP_REPORT_ONLY=True)
    def test_check_missing_csp_report_only_setting(self):
        self.assertEqual(check_csp_is_not_report_only(), ['CSP_REPORT_ONLY_ENABLED'])

    @override_settings(MIDDLEWARE_CLASSES=['session_csrf.CsrfMiddleware'])
    def test_check_middleware_csrf_is_present(self):
        self.assertEqual(check_session_csrf_enabled(), [])

    @override_settings(CSP_REPORT_ONLY=False)
    def test_check_csp_report_is_missing(self):
        self.assertEqual(check_csp_is_not_report_only(), [])

    @override_settings(CSP_DEFAULT_SRC=("'self'", "*.gstatic.com"))
    def test_check_csp_sources_not_unsafe(self):
        self.assertEqual(check_csp_sources_not_unsafe(), ['CSP_STYLE_SRC_UNSAFE'])


#!/usr/bin/env python
# coding=UTF-8
from __future__ import absolute_import, division, print_function, unicode_literals
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1' #显示信息等级
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import tensorflow as tf
print(tf.test.is_gpu_available())
from tensorflow import feature_column
from tensorflow.keras import layers
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score, precision_score, recall_score
import datetime

start_time = datetime.datetime.now()

CSV_FILE_PATH = 'binary_classification.csv'
#四个类

df = pd.read_csv(CSV_FILE_PATH)

#Object类型转换为离散数值（Label列）
df['Label'] = pd.Categorical(df['Label'])
df['Label'] = df['Label'].cat.codes
print(df['Label'].head(20))
#将int类型转换为float类型
columns_counts = df.shape[1]                                                #获取列数
for i in range(columns_counts):
  if(df.iloc[:,i].dtypes) != 'float64':
    df.iloc[:, i] = df.iloc[:,i].astype(float)

#将特征随时间变化用图像展示出来

# ts = df['Init_Win_bytes_forward']
# ts.plot(title='PortScan:Init_Win_bytes_forward')
# plt.xlabel('Time-Step')
# plt.ylim(0,80000)
# plt.xlim(0,1000)
# plt.show()

#选取11个特征和Label
features_considered = ['Label','Bwd_Packet_Length_Min','Subflow_Fwd_Bytes','Total_Length_of_Fwd_Packets','Fwd_Packet_Length_Mean','Bwd_Packet_Length_Std','Flow_Duration','Flow_IAT_Std','Init_Win_bytes_forward','Bwd_Packets/s',
                 'PSH_Flag_Count','Average_Packet_Size']
feature_last = ['Bwd_Packet_Length_Min','Subflow_Fwd_Bytes','Total_Length_of_Fwd_Packets','Fwd_Packet_Length_Mean','Bwd_Packet_Length_Std','Flow_Duration','Flow_IAT_Std','Init_Win_bytes_forward','Bwd_Packets/s',
                 'PSH_Flag_Count','Average_Packet_Size']
feature = df[features_considered]

print(len(feature))

#将数据集分为训练集、验证集、测试集
train, test = train_test_split(feature,test_size=0.2)
print("train_shape",train.shape)

print("test_shape",test.shape)

#标准化
def normalize_dataset(dataset, dataset_mean, dataset_std, insert_target):
    dataset = (dataset-dataset_mean)/dataset_std
    final_dataset = pd.DataFrame(dataset, columns=feature_last)
    final_dataset.insert(0, 'Label', insert_target)
    return final_dataset

train.reset_index(drop=True,inplace=True)
#重置索引，很关键！ drop=True,把原来的索引index列丢掉
train_target = train['Label']
print("Target_size",train_target.shape)
train_other = train[feature_last]
train_dataset = train_other.values
train_mean = train_dataset.mean(axis=0)
train_std = train_dataset.std(axis=0)
train = normalize_dataset(train_dataset, train_mean, train_std, train_target)

#对测试集进行标准化时使用训练集的均值和标准差
test.reset_index(drop=True,inplace=True)
test_target = test['Label']
test_other = test[feature_last]
test_dataset = test_other.values
test = normalize_dataset(test_dataset, train_mean, train_std, test_target)

train, val = train_test_split(train, test_size=0.2)
print(len(train), 'train examples')
print(len(val), 'validation examples')
print(len(test), 'test examples')

#使用tf.data.Dataset读取数据
def df_to_dataset(dataframe, shuffle=True, batch_size=32):
  dataframe = dataframe.copy()
  labels = dataframe.pop('Label')
  #如果赋值给变量，返回的是Series
  ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
  if shuffle:
    ds = ds.shuffle(buffer_size=len(dataframe))
  ds = ds.batch(batch_size)
  return ds

#选择要使用的
feature_use = []
for header in feature_last:
  feature_use.append(feature_column.numeric_column(header))
print(len(feature_use),len(feature_use[0]),feature_use[0])
print("featuer_use"+"="*20+"\n")

feature_layer = tf.keras.layers.DenseFeatures(feature_use,dtype='float64')

batch_size = 50                                                             #50-256

print("train_shape..........",train.shape)
train_ds = df_to_dataset(train, batch_size=batch_size)
# print(list(train_ds.as_numpy_iterator())[0])
val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size)
test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)
print("train_ds.take(1).....",train_ds.take(1))

#创建，编译和训练模型
model = tf.keras.Sequential([
  feature_layer,
  layers.Dense(256, activation='relu'),
  layers.Dense(128, activation='relu'),
layers.Dropout(0.2),
  layers.Dense(64, activation='relu'),
layers.Dropout(0.2),
  layers.Dense(32, activation='relu'),
  layers.Dense(4, activation='softmax')
])
model.compile(optimizer='Adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'],
              run_eagerly=True)

#其他指标、使用Tensorboard，

recall=tf.keras.metrics.Recall(),
FP=tf.keras.metrics.FalsePositives(),
TN=tf.keras.metrics.TrueNegatives()

log_dir = "graph/log_fit/13"
checkpoint_path = "traing_1/cp-{epoch:04d}.ckpt"

checkpoint_dir = os.path.dirname(checkpoint_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
                                                 verbose=1,
                                                 save_weights_only=True,
                                                 save_freq=200)

tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)

# model.save_weights(checkpoint_path.format(epoch=0))
history=model.fit(train_ds,
          validation_data=val_ds,
          epochs=25,callbacks=[tensorboard_callback,cp_callback]
          )

loss, accuracy = model.evaluate(test_ds)

classifer=["BENIGN","DDoS","Hulk","PortScan"]

plt.figure(figsize=(16,8))
plt.plot(history.history['loss'], label='train loss')
plt.plot(history.history['val_loss'], label='val loss')
plt.legend(loc='best')
plt.show()

for x, y in test_ds.take(3):  # 拿出来3个 batch_size
    print("model.predict(x).shape==================", model.predict(x).shape)
# 第一个256为batch_size,但也不一定，看看批量处理的x是多大。
    for i in range(5):
        result = model.predict(x)[i]  # 得到的是4个的概率
        print("pre_result:", np.argmax(result),"true_result",y[i])
        print("pre_result:", classifer[np.argmax(result)], "true_result", classifer[int(y[i])])

def result_csv(val_data_single):
    j=1;
    result_df=pd.DataFrame(columns=["x","y","pre"])
    for x, y in val_data_single.take(3):  # 拿出来3个 batch_size
        print("model.predict(x).shape==================", model.predict(x).shape)
        for i in range(50):
        # 第一个256为batch_size,但也不一定，看看批量处理的x是多大。
            result = model.predict(x)[0]#得到的是4个的概率
            print("result:", np.argmax(result))
            result=model.predict(x)[i]
            result=np.argmax(result)
            result_df.loc[j, :] = [j, y[i].numpy(),result]
            j+=1
    result_df.to_csv("result_DNN.csv",header=False,index=False)
# result_csv(test_ds)#暂时不需要

model.save_weights("dnn_model")
end_time = datetime.datetime.now()
print("spend_time:",(end_time-start_time).seconds)
#保存模型
begin_time = datetime.datetime.now()
# reconstructed_model = tf.keras.models.load_model('DNN_Model.h5')
# reconstructed_model.evaluate(test_ds)
final_moment = datetime.datetime.now()
print('保存的模型预测时间：', (final_moment-begin_time).seconds)
print("loss:",loss)
print("Accuracy:", accuracy)
print(model.summary())


import numpy as np
import pytest

from pandas import (
    CategoricalIndex,
    DatetimeIndex,
    Index,
    PeriodIndex,
    TimedeltaIndex,
    isna,
)
import pandas._testing as tm
from pandas.core.api import (
    Float64Index,
    NumericIndex,
)
from pandas.core.arrays import BooleanArray
from pandas.core.indexes.datetimelike import DatetimeIndexOpsMixin

@pytest.mark.parametrize(
    "func",
    [
        np.exp,
        np.exp2,
        np.expm1,
        np.log,
        np.log2,
        np.log10,
        np.log1p,
        np.sqrt,
        np.sin,
        np.cos,
        np.tan,
        np.arcsin,
        np.arccos,
        np.arctan,
        np.sinh,
        np.cosh,
        np.tanh,
        np.arcsinh,
        np.arccosh,
        np.arctanh,
        np.deg2rad,
        np.rad2deg,
    ],
    ids=lambda x: x.__name__,
)
def test_numpy_ufuncs_basic(index, func):
    # test ufuncs of numpy, see:
    # https://numpy.org/doc/stable/reference/ufuncs.html

    if isinstance(index, DatetimeIndexOpsMixin):
        with tm.external_error_raised((TypeError, AttributeError)):
            with np.errstate(all="ignore"):
                func(index)
    elif isinstance(index, NumericIndex) or (
        not isinstance(index.dtype, np.dtype) and index.dtype._is_numeric
    ):
        # coerces to float (e.g. np.sin)
        with np.errstate(all="ignore"):
            result = func(index)
            exp = Index(func(index.values), name=index.name)

        tm.assert_index_equal(result, exp)
        if type(index) is not Index:
            # i.e NumericIndex
            assert isinstance(result, Float64Index)
        else:
            # e.g. np.exp with Int64 -> Float64
            assert type(result) is Index
    else:
        # raise AttributeError or TypeError
        if len(index) == 0:
            pass
        else:
            with tm.external_error_raised((TypeError, AttributeError)):
                with np.errstate(all="ignore"):
                    func(index)

@pytest.mark.parametrize(
    "func", [np.isfinite, np.isinf, np.isnan, np.signbit], ids=lambda x: x.__name__
)
def test_numpy_ufuncs_other(index, func, request):
    # test ufuncs of numpy, see:
    # https://numpy.org/doc/stable/reference/ufuncs.html
    if isinstance(index, (DatetimeIndex, TimedeltaIndex)):

        if func in (np.isfinite, np.isinf, np.isnan):
            # numpy 1.18 changed isinf and isnan to not raise on dt64/td64
            result = func(index)
            assert isinstance(result, np.ndarray)
        else:
            with tm.external_error_raised(TypeError):
                func(index)

    elif isinstance(index, PeriodIndex):
        with tm.external_error_raised(TypeError):
            func(index)

    elif isinstance(index, NumericIndex) or (
        not isinstance(index.dtype, np.dtype) and index.dtype._is_numeric
    ):
        # Results in bool array
        result = func(index)
        if not isinstance(index.dtype, np.dtype):
            # e.g. Int64 we expect to get BooleanArray back
            assert isinstance(result, BooleanArray)
        else:
            assert isinstance(result, np.ndarray)
        assert not isinstance(result, Index)
    else:
        if len(index) == 0:
            pass
        else:
            with tm.external_error_raised(TypeError):
                func(index)

@pytest.mark.parametrize("func", [np.maximum, np.minimum])
def test_numpy_ufuncs_reductions(index, func, request):
    # TODO: overlap with tests.series.test_ufunc.test_reductions
    if len(index) == 0:
        return

    if repr(index.dtype) == "string[pyarrow]":
        mark = pytest.mark.xfail(reason="ArrowStringArray has no min/max")
        request.node.add_marker(mark)

    if isinstance(index, CategoricalIndex) and index.dtype.ordered is False:
        with pytest.raises(TypeError, match="is not ordered for"):
            func.reduce(index)
        return
    else:
        result = func.reduce(index)

    if func is np.maximum:
        expected = index.max(skipna=False)
    else:
        expected = index.min(skipna=False)
        # TODO: do we have cases both with and without NAs?

    assert type(result) is type(expected)
    if isna(result):
        assert isna(expected)
    else:
        assert result == expected


import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture as GMM
from scipy.stats import multivariate_normal

#loads data
data = np.genfromtxt('vowdata_nohead.dat', dtype='U16')
identifiers = data[:, 0]
data = data[:, 2:7].astype(np.int)  # pulls out 'steady state' values for the vowels

vowels = ['ae', 'ah', 'aw', 'eh', 'er', 'ei', 'ih', 'iy', 'oa', 'oo', 'uh', 'uw']

#distributes tarining and testing data
N_train = 70
N_test = 69
N_all = N_train + N_test

train_index = []
test_index = []

for vowel in vowels:
    index = np.flatnonzero(np.core.defchararray.find(identifiers, vowel) != -1)
    train_index.extend(index[:N_train])
    test_index.extend(index[N_train:])

train_set = data[train_index]
test_set = data[test_index]

#put data into dictionary and creates answersheats
data_dict = dict()

for i in range(12):
	data_dict[vowels[i]] = data[i*N_all:(i+1)*N_all, :]

correct_train = np.asarray([i for i in range(12) for _ in range(N_train)])
correct_test = np.asarray([i for i in range(12) for _ in range(N_test)])

def mean(m):
    mean = m.mean(axis=0)
    return mean

def cov(m, diagonal=True):
    c = np.dot((m - m.mean(axis=0)).T, (m - m.mean(axis=0))) / (len(m) - 1)
    if diagonal:
        c = np.diag(np.diag(c))
    return c

# makes predictions given pdfs
def predict(dist, x):
	vowel_probabilities = np.zeros((len(vowels), len(x)))

	for i in range(len(vowels)):
		vowel_probabilities[i] = dist[vowels[i]](x)
	return np.argmax(vowel_probabilities, axis=0)

def error_rate(N, m):
    e = np.sum(m) - np.trace(m)
    print("#feil:", e)
    return e / N*100

#prints confusion matrix and error rate
def confuse(pred, corr, label=''):
	conf = np.zeros((12, 12))
	for i, j in zip(pred, corr):
		conf[i, j] += 1
	print(label, 'confusion:\n', conf)

	print("%s error: %.2f%%" % (label, error_rate(pred.shape[0], conf)))

# GAUSS (=GMM1) full cov

#train
distributions = dict()
for v in vowels:
	distributions[v] = multivariate_normal(mean(data_dict[v]),cov(data_dict[v], diagonal=False)).pdf

#predict
predicted_vowel_indices_test = predict(distributions, test_set)
#print confusion
confuse(predicted_vowel_indices_test, correct_test, 'full covar')

# GAUSS (=GMM1) diag cov

distributions = dict()
for v in vowels:
	distributions[v] = multivariate_normal(mean(data_dict[v]),cov(data_dict[v], diagonal=True)).pdf

predicted_vowel_indices_test = predict(distributions, test_set)
confuse(predicted_vowel_indices_test, correct_test, 'diag covar')

# GMM2

distributions = dict()
for v in vowels:
	gmm = GMM(2, 'diag') # 2 mixtures, cov-type diagonal
	gmm.fit(data_dict[v])
	distributions[v] = gmm.score_samples

pred = predict(distributions, test_set)
confuse(pred, correct_test, 'GMM2')

# GMM3

distributions = dict()
for v in vowels:
	gmm = GMM(3, 'diag')  # 3 mixtures, cov-type diag
	gmm.fit(data_dict[v])
	distributions[v] = gmm.score_samples

pred = predict(distributions, train_set)
confuse(pred, correct_test, 'GMM3')