"""
levin.py

Contains the Levin class, a general Levin integrator, as well as subclasses that implement specific integrals.

For details on the Levin method, see this writuep:
https://reference.wolfram.com/language/tutorial/NIntegrateIntegrationRules.html#32844337
"""
from typing import Tuple, Callable

import numpy as np
from scipy.special import spherical_jn

class Levin(object):
    """
    General Levin integration class

    To use:
    * Figure out amplitude function, kernel vector and differential matrix
    * Instantiate class
    * Set limits
    * Set amplitude
    * Set kernel
    * Set differential matrix
    * Call integrate

    The kernel and differential matrix will likely need to be constructed for each individual
    integral, but the limits and amplitude can probably be evaluated only a single time for a given
    class of integrals.

    The integrate method returns the integral and the error estimate (difference from previous refinement, most likely
    an overestimate).

    Note that no attempt is made to switch to a different method when the integrand is not oscillatory over
    the domain of the integral. This should be handled separately.
    """

    def __init__(self, starting_points: int = 20, refinements: int = 6,
                 abs_tol: float = 0, rel_tol: float = 1e-7) -> None:
        """Initialize the Levin integrator by precomputing grids"""
        # Store parameters
        self.starting_points = starting_points
        self.refinements = refinements
        self.abs_tol = abs_tol
        self.rel_tol = rel_tol

        # Construct the different grid sizes
        assert refinements > 0
        self.grid_sizes = [starting_points]
        for _ in range(refinements):
            self.grid_sizes.append(self.grid_sizes[-1] * 2)

        # Construct collocation angles for the largest grid
        numpoints = self.grid_sizes[-1]
        theta = np.pi * np.linspace(0.0, 1.0, numpoints + 1)  # We use one extra point at 0
        # Collocation points in x space
        self.colloc = -np.cos(theta)

        # Precompute the Chebyshev polynomials on the largest grid
        # These are (n, collocation) indexed
        self.chebyTs = np.array([self._chebyT(theta, n) for n in range(numpoints + 1)])
        self.dchebyTs = np.array([n * self._chebyU(theta, n - 1) for n in range(0, numpoints + 1)])

        # Set up placeholders
        self.a = None
        self.b = None
        self.kvals = None
        self.kernel_a = None
        self.kernel_b = None
        self.amplitude = None
        self.dm = None

    @staticmethod
    def _chebyT(theta: np.array, n: int) -> np.array:
        """
        Returns Chebyshev polynomials of the first kind of order n at value -theta.
        Vectorized over theta.
        """
        return (-1) ** (n % 2) * np.cos(n * theta)

    @staticmethod
    def _chebyU(theta: np.array, n: int) -> np.array:
        """
        Returns Chebyshev polynomials of the second kind of order n at value -theta.
        Vectorized over theta.
        """
        if n == -1:
            return np.zeros_like(theta)
        subtheta = theta[1:-1]
        n1 = n + 1
        factor = (-1) ** (n % 2)
        return np.concatenate(([factor * n1], factor * np.sin(n1 * subtheta) / np.sin(subtheta), [n1]))

    def set_limits(self, a: float, b: float) -> None:
        """
        Sets limits of integration and construct collocation grid in k-space.
        x space ranges from -1 to 1, while k-space ranges from a to b.
        """
        self.a = a
        self.b = b
        self.kvals = (b - a) / 2 * self.colloc + (b + a) / 2

    def set_amplitude(self, amplitude: Callable) -> None:
        """
        Set the amplitude function.
        Evaluates the amplitude on all collocation gridpoints.
        """
        assert self.a is not None
        self.amplitude = np.array([amplitude(k) for k in self.kvals])

    def set_kernel(self, kernel: Callable) -> None:
        """
        Set the integration kernel.
        Evaluates the kernel at the limits of integration.
        """
        assert self.a is not None
        self.kernel_a = kernel(self.kvals[0])
        self.kernel_b = kernel(self.kvals[-1])

    def set_differential_matrix(self, differential_matrix: Callable) -> None:
        """
        Set the differential matrix.
        Evaluates the differential matrix on all collocation gridpoints.
        """
        assert self.a is not None
        assert self.kernel_a is not None
        # This is indexed by collocation, weight1, weight2, where weight1 and weight2 are set
        # so that kernel' = dm[idx].kernel.
        self.dm = np.array([differential_matrix(k) for k in self.kvals])
        # Check that the matrix has the right dimensions
        shape = self.dm[0].shape
        assert len(self.kernel_a) == shape[0] == shape[1]

    def _slice(self, numpoints: int) -> slice:
        """
        Constructs the slice that will extract the appropriate gridpoints from everything.

        :param numpoints: Number of collocation points to use
        :return: A slice object
        """
        # Find the refinement number for the given number of points
        try:
            refinement = self.grid_sizes.index(numpoints)
        except ValueError:
            raise ValueError('Number of collocation points was not initialized')

        # Compute the stepsize and construct the slice
        stepsize = 2 ** (self.refinements - refinement)
        sl = np.s_[0::stepsize]
        assert len(self.colloc[sl]) == numpoints + 1

        return sl

    def _integrate(self, numpoints: int) -> float:
        """
        Integrates functions of the form
        int_a^b f(k) w(k) dk
        using the Levin-collocation method, using the given number of points.

        We use a kernel vector w_i(k), with w(k) = w_1(k).
        The differential matrix dm is such that dw/dk = dm.w for the vector w.

        The kernel vector only needs to be evaluated at the limits a and b.
        The differential matrix needs to be computed at each collocation point.

        :param numpoints: Number of collocation points to use
        :return: Value of the integral
        """
        # Make sure everything is ready to go!
        assert self.a is not None
        assert self.b is not None
        assert self.kvals is not None
        assert self.kernel_a is not None
        assert self.kernel_b is not None
        assert self.amplitude is not None
        assert self.dm is not None

        # Construct the slice operator to extract values on the appropriate collocation grid
        sl = self._slice(numpoints)
        numpoints += 1  # Add the extra point for 0

        # Extract everything on the appropriate collocation points
        kernel_a = self.kernel_a
        kernel_b = self.kernel_b
        amplitude = self.amplitude[sl]
        dm = self.dm[sl]
        chebyTs = self.chebyTs[:numpoints, sl]  # Take first numpoints ell values, then slice for collocation points
        derivs = 2 / (self.b - self.a) * self.dchebyTs[:numpoints, sl]

        # Construct the amplitude matrix (including zero weights for unused kernels)
        kernel_len = len(self.kernel_a)
        # This is indexed by kernel index, collocation point
        amplitudes = np.vstack([amplitude] + [np.zeros_like(amplitude)] * (kernel_len - 1))

        # The collocation method now solves the following equation at the collocation points:
        # sum_i^kernel_len A_{i,j}(x) (sum_k^num_points u_k(x) c_{i, k}) + sum_k^num_points c_{j, k} u_k'(x) = f_j(x)
        # A is the differential matrix
        # f_j is the amplitude for weight j
        # c_{i, k} are the unknown coefficients to solve for
        # We use u_k(x) = Chebyshev polynomials and evaluate this equation at the collocation points
        # Number of collocation points = Number of Chebyshev polynomials used

        # Now construct the matrix equations a_{ijkl} c_{ik} = f_{jl}  (l is the collocation index)
        # c_{ik} is unknown, and needs to be solved for
        # f_{jl} is the amplitude matrix constructed above
        # a_{ijkl} needs to be constructed, and has indices of weight1, weight2, Chebyshev order, collocation index
        a = np.zeros([kernel_len, kernel_len, numpoints, numpoints])
        # Loop over collocation points
        for l in range(numpoints):
            # These tensordots are constructed as a tensor product (no summation)
            a[:, :, :, l] = np.tensordot(dm[l], chebyTs[:, l], 0) + np.tensordot(np.eye(kernel_len), derivs[:, l], 0)

        # Solve the system, moving indices i and k to the right to contract with c_{ik}
        cij = np.linalg.tensorsolve(a, amplitudes, axes=(0, 2))

        # Construct the integral. The antiderivative is
        # F_i(x) = sum_k c_{ik} T_k(x)
        # which we evaluate at the limits
        resulta = np.dot(np.dot(cij, chebyTs[:, 0]), kernel_a)
        resultb = np.dot(np.dot(cij, chebyTs[:, -1]), kernel_b)
        result = float(resultb - resulta)

        return result

    def integrate(self) -> Tuple[float, float]:
        """
        Performs the Levin integration. Starts out by using the minimum number of points specified, then refines
        repeatedly until the desired tolerances are met.

        :return: Value of the integral, error estimate
        """
        base = self._integrate(self.starting_points)

        for gridsize in self.grid_sizes[1:]:
            # Compute the integral on the next grid
            result = self._integrate(gridsize)

            # Check to see if the result is within the appropriate tolerance
            tolerance = self.abs_tol + np.abs(result) * self.rel_tol
            err = abs(result - base)
            if err <= tolerance:
                return result, err

            # Make the result the next base, and try again
            base = result
        else:
            # If we got here, we didn't converge
            # print('Warning: Did not converge to the desired tolerance within desired number of refinements')
            return base, err

class LevinIntegrals(Levin):
    """
    Integration class for various spherical bessel integrals.

    Instantiate using the __init__ parameters of Levin.

    Before calling an integrate_X routine, set the limits and amplitude function using

    # Set the limits of integration
    LevinIntegrals.set_limits(a, b)
    # Set the amplitude function
    LevinIntegrals.set_amplitude(amplitude)
    """

    def integrate_I(self, ell: int, alpha: float) -> Tuple[float, float]:
        """
        Performs integrals of the form
        I = int_a^b f(k) j_l(alpha k) dk
        using the Levin-collocation method.

        The kernel vector is {j_ell(alpha*k), j_(ell+1)(alpha*k)}.
        The differential matrix is {{ell/k, -alpha}, {alpha, -(2+ell)/k}}.

        Note that the differential matrix becomes singular as k -> 0, so we can only treat positive limits.

        :param ell: Order of spherical bessel function to integrate
        :param alpha: Coefficient in the spherical bessel function
        :return: Value of the integral, error estimate
        """
        # Set the integration kernel
        def kernel(k):
            return np.array([spherical_jn(ell, alpha * k), spherical_jn(ell + 1, alpha * k)])
        self.set_kernel(kernel)

        # Set the differential matrix
        dm_diag = np.diag([ell, -(2 + ell)])
        dm_off = np.zeros((2, 2))
        dm_off[0, 1] = -alpha
        dm_off[1, 0] = alpha

        def dm(k):
            return dm_diag / k + dm_off
        self.set_differential_matrix(dm)

        # Perform the integration
        return self.integrate()

    def integrate_I2(self, ell: int, alpha: float) -> Tuple[float, float]:
        """
        Performs integrals of the form
        I = int_a^b f(k) j_l(alpha k) dk
        using the Levin-collocation method.

        This uses a different kernel to the integrate_I method (they are, however, equivalent for ell = 0).

        The kernel vector is {j_ell(alpha*k), ell/(alpha*k)*j_ell(alpha*k) - j_(ell+1)(alpha*k)}.
        The differential matrix is {{0, alpha}, {ell*(ell+1)/(alpha*k^2) - alpha, -2/k}}.

        Note that the differential matrix becomes singular as k -> 0, so we can only treat positive limits.

        :param ell: Order of spherical bessel function to integrate
        :param alpha: Coefficient in the spherical bessel function
        :return: Value of the integral, error estimate
        """

        # Set the integration kernel
        def kernel(k):
            return np.array([spherical_jn(ell, alpha * k), ell / (alpha * k) * spherical_jn(ell, alpha * k) - spherical_jn(ell + 1, alpha * k)])

        self.set_kernel(kernel)

        # Set the differential matrix
        dm = np.zeros((2, 2))
        dm[0, 1] = alpha

        def dm(k):
            result = dm.copy()
            result[1, 0] = ell * (ell + 1) / (alpha * k * k) - alpha
            result[1, 1] = - 2 / k
            return result

        self.set_differential_matrix(dm)

        # Perform the integration
        return self.integrate()

    def integrate_I3(self, alpha: float) -> Tuple[float, float]:
        """
        Performs integrals of the form
        I = int_a^b f(k) j_1(alpha k) dk
        using the Levin-collocation method. (Note: ell = 1)

        This uses the same approach as integrate_I, but using j_0 and j_1 instead of j_1 and j_2.

        The kernel vector is {j_1(alpha*k), j_0(alpha*k)}.
        The differential matrix is {{-2/k, alpha}, {-alpha, 0}}.

        Note that the differential matrix becomes singular as k -> 0, so we can only treat positive limits.

        :param alpha: Coefficient in the spherical bessel function
        :return: Value of the integral, error estimate
        """

        # Set the integration kernel
        def kernel(k):
            return np.array([spherical_jn(1, alpha * k),
                             spherical_jn(0, alpha * k)])

        self.set_kernel(kernel)

        # Set the differential matrix
        dm = np.zeros((2, 2))
        dm[0, 1] = alpha
        dm[1, 0] = -alpha

        def dm(k):
            result = dm.copy()
            result[0, 0] = - 2 / k
            return result

        self.set_differential_matrix(dm)

        # Perform the integration
        return self.integrate()

    def integrate_H(self, ell: int, alpha: float) -> Tuple[float, float]:
        """
        Performs integrals of the form
        I = int_a^b f(k) j_l(alpha k)^2 dk
        using the Levin-collocation method.

        The kernel vector is {j_ell(alpha*k)^2, j_ell(alpha*k) * j_(ell+1)(alpha*k), j_(ell+1)(alpha*k)^2}.
        The differential matrix is {{2*ell/k, -2*alpha, 0}, {alpha, -2/k, -alpha}, {0, 2*alpha, -2*(ell+2)/k}}.

        Note that the differential matrix becomes singular as k -> 0, so we can only treat positive limits.

        :param ell: Order of spherical bessel function to integrate
        :param alpha: Coefficient in the spherical bessel function
        :return: Value of the integral, error estimate
        """

        # Set the integration kernel
        def kernel(k):
            return np.array([spherical_jn(ell, alpha * k)**2,
                             spherical_jn(ell, alpha * k) * spherical_jn(ell + 1, alpha * k),
                             spherical_jn(ell + 1, alpha * k)**2])

        self.set_kernel(kernel)

        # Set the differential matrix
        dm_diag = np.diag([2*ell, -2, -2*(ell+2)])
        dm_off = np.zeros((3, 3))
        dm_off[0, 1] = -2*alpha
        dm_off[1, 0] = alpha
        dm_off[1, 2] = -alpha
        dm_off[2, 1] = 2*alpha

        def dm(k):
            return dm_diag / k + dm_off

        self.set_differential_matrix(dm)

        # Perform the integration
        return self.integrate()

    def integrate_K(self, ell: int, alpha: float, beta: float) -> Tuple[float, float]:
        """
        Performs integrals of the form
        I = int_a^b f(k) j_l(alpha k) j_l(beta k) dk
        using the Levin-collocation method.

        The kernel vector is {j_ell(alpha*k) * j_ell(beta*k),
                              j_{ell+1}(alpha*k) * j_ell(beta*k),
                              j_ell(alpha*k) * j_{ell+1}(beta*k),
                              j_{ell+1}(alpha*k) * j_{ell+1}(beta*k)}.
        The differential matrix is:
        (0 -alpha -beta 0)
        (alpha 0 0 -beta)   +   diag(2*ell/k, -2/k, -2/k, -2*(ell+2)/k)
        (beta 0 0 -alpha)
        (0 beta alpha 0)

        Note that the differential matrix becomes singular as k -> 0, so we can only treat positive limits.

        :param ell: Order of spherical bessel function to integrate
        :param alpha: Coefficient in the spherical bessel function
        :param beta: Coefficient in the spherical bessel function
        :return: Value of the integral, error estimate
        """

        # Set the integration kernel
        def kernel(k):
            return np.array([spherical_jn(ell, alpha * k) * spherical_jn(ell, beta * k),
                             spherical_jn(ell + 1, alpha * k) * spherical_jn(ell, beta * k),
                             spherical_jn(ell, alpha * k) * spherical_jn(ell + 1, beta * k),
                             spherical_jn(ell + 1, alpha * k) * spherical_jn(ell + 1, beta * k)])

        self.set_kernel(kernel)

        # Set the differential matrix
        dm_diag = np.diag([2*ell, -2, -2, -2*(2 + ell)])
        dm_off = np.zeros((4, 4))
        dm_off[0, 1] = -alpha
        dm_off[1, 0] = alpha
        dm_off[0, 2] = -beta
        dm_off[2, 0] = beta
        dm_off[1, 3] = -beta
        dm_off[2, 3] = -alpha
        dm_off[3, 1] = beta
        dm_off[3, 2] = alpha

        def dm(k):
            return dm_diag / k + dm_off

        self.set_differential_matrix(dm)

        # Perform the integration
        return self.integrate()


import os, sys
import pygame as pg
from random import choice, randrange

class Symbol:
    def __init__(self, x, y, speed):
        self.x, self.y = x, y
        self.speed = speed
        self.value = choice(green_katakana)
        self.interval = randrange(5, 30)

    def draw(self, color):
        # randomize the sybol
        frames = pg.time.get_ticks()
        if not frames % self.interval:
            self.value = choice(green_katakana if color == 'green' else lightgreen_katakana)

        # fall effect of the symbol
        self.y = self.y + self.speed if self.y < HEIGHT else -FONT_SIZE
        surface.blit(self.value, (self.x, self.y))

class SymbolColumn:
    def __init__(self, x, y):
        self.column_height = randrange(8, 24)
        self.speed = randrange(2, 5)
        # colum of symbol
        self.symbols = [Symbol(x, i, self.speed) for i in range(y, y - FONT_SIZE * self.column_height, - FONT_SIZE)]

    def draw(self):
        # different colors
        [symbol.draw('green') if i else symbol.draw('lightgreen') for i, symbol in enumerate(self.symbols)]

# old method for center screen
os.environ['SDL_VIDEO_CENTERED'] = '1'
RES = WIDTH, HEIGHT = 1280, 720
FONT_SIZE = 40
alpha_value = 0

# pygame setup ======================================
pg.init()
screen = pg.display.set_mode(RES)
clock = pg.time.Clock()
# blur effect
surface = pg.Surface(RES)
surface.set_alpha(alpha_value)

# katakana from hexadecimal values
katakana = [chr(int('0x30a0', 16) + i) for i in range(96)]
# load font
font = pg.font.Font('font/MS Mincho.ttf', FONT_SIZE, bold= True)
green_katakana = [font.render(char, True, (40, randrange(160, 256), 40)) for char in katakana]
# font color
lightgreen_katakana = [font.render(char, True, pg.Color('lightgreen')) for char in katakana]

# Instance of class
symbol_columns = [SymbolColumn(x, randrange(-HEIGHT, 0)) for x in range(0, WIDTH, FONT_SIZE)]

while True:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            pg.quit()
            sys.exit()

    # Draw ------------------------
    screen.blit(surface, (0, 0))
    surface.fill(pg.Color('black'))

    # many colums
    [symbol_column.draw() for symbol_column in symbol_columns]

    if not pg.time.get_ticks() % 20 and alpha_value < 170:
        alpha_value += 6
        surface.set_alpha(alpha_value)

    # pygame setup ------------------------
    pg.display.flip()
    clock.tick(60)
    pg.display.set_caption(f'FPS: {clock.get_fps() :.0f}')


#!/usr/bin/python3

from assets.headers import enumeration_header
from assets.shortcuts import Exit
from assets.prefixes import eagleshell_prefix, invalid_input_prefix
from assets.colors import *

class Enumeration:
    def __init__(self):
        try:
            enumeration_header()
            print('Scripts:')
            print('\n\t1): BR4NCH - Linux PE Enumeration Script')
            print('\n\tZ): Back')
            print('\tX): Exit\n')
            while True:
                enumeration_select = input(eagleshell_prefix).lower()
                if enumeration_select == '1':
                    print(YELLOW + '\n\tYou can download our PE Enum Script on our Github Page:' + RESET + BLUE + '\n\thttps://github.com/TRSTN4/BR4NCH\n' + RESET)
                elif enumeration_select == 'z':
                    from ..scripts import Scripts
                    Scripts()
                elif enumeration_select == 'x':
                    Exit()
                else:
                    print(invalid_input_prefix)
                    continue
        except KeyboardInterrupt:
            Exit()


from django.conf.urls.defaults import patterns, include
from django.conf import settings

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

from frontend import views, device_views, router_views, mobile, policy_views

urlpatterns = patterns('',
    (r'^login/$', views.login_get),
    (r'^authenticate/$', views.login_post),
    (r'^dojango/', include('dojango.urls')),
    (r'^$', views.index),

    (r'^known_devices/$', device_views.get_known_devices),
    (r'^device/(?P<mac_address>.*)$', device_views.device),
    (r'^enable_device/$', device_views.enable_device),

    (r'^m$', mobile.index),

    (r'^arp_upload/$', router_views.arp_upload),
    (r'^arp_upload/(?P<filename>.*)$', router_views.arp_upload),
    (r'^iptables_download/$', router_views.iptables_download),

    (r'^policies/$', policy_views.get_policies),
    (r'^traffic_policy/(?P<traffic_policy_name>.*)$', policy_views.edit_traffic_policy),

    (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
)


import pandas as pd
import numpy as np
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import scale

letters = pd.read_csv('G:/Software/Machine learning/1/18. Support Vector Machine (SVM)/SVM/letter-recognition.csv')

letters.columns = ['letter', 'xbox', 'ybox', 'width', 'height', 'onpix', 'xbar',
       'ybar', 'x2bar', 'y2bar', 'xybar', 'x2ybar', 'xy2bar', 'xedge',
       'xedgey', 'yedge', 'yedgex']

order = list(np.sort(letters['letter'].unique()))
print(order)

letter_means = letters.groupby('letter').mean()
letter_means.head()

sns.countplot(x = 'letter' , data = letters)

round(letters.drop('letter', axis=1).mean(), 2)

plt.figure(figsize=(16, 8))
sns.barplot(x='letter', y='xbox',  data=letters, order=order)

plt.figure(figsize=(18, 10))
sns.heatmap(letter_means)

round(letters.drop('letter', axis=1).mean(), 2)

X = letters.drop("letter", axis = 1)
y = letters['letter']

X_scaled = scale(X)

X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size = 0.3, random_state = 101)

model_linear = SVC(kernel='linear')
model_linear.fit(X_train, y_train)
y_pred = model_linear.predict(X_test)

print("accuracy:", metrics.accuracy_score(y_true = y_test, y_pred = y_pred), "\n")

mat = metrics.confusion_matrix(y_true = y_test, y_pred = y_pred)
print(mat)

non_linear_model = SVC(kernel='rbf')
non_linear_model.fit(X_train, y_train)
y_pred = non_linear_model.predict(X_test)
print("accuracy:", metrics.accuracy_score(y_true=y_test, y_pred=y_pred), "\n")

print(metrics.confusion_matrix(y_true=y_test, y_pred=y_pred))

non_linear_model = SVC(kernel='poly')
non_linear_model.fit(X_train, y_train)
y_pred = non_linear_model.predict(X_test)
print("accuracy:", metrics.accuracy_score(y_true=y_test, y_pred=y_pred), "\n")

print(metrics.confusion_matrix(y_true=y_test, y_pred=y_pred))

folds = KFold(n_splits = 5, shuffle = True, random_state = 101)

hyper_params = [ {'gamma': [1e-2, 1e-3, 1e-4],'C': [1, 10, 100, 1000]}]

model = SVC(kernel="rbf")

model_cv = GridSearchCV(estimator = model, param_grid = hyper_params, scoring= 'accuracy', cv = folds,  verbose = 1,return_train_score=True)

model_cv.fit(X_train, y_train)

cv_results = pd.DataFrame(model_cv.cv_results_)
cv_results

cv_results['param_C'] = cv_results['param_C'].astype('int')

# # plotting
plt.figure(figsize=(16,6))

# subplot 1/3
plt.subplot(131)
gamma_01 = cv_results[cv_results['param_gamma']==0.01]

plt.plot(gamma_01["param_C"], gamma_01["mean_test_score"])
plt.plot(gamma_01["param_C"], gamma_01["mean_train_score"])
plt.xlabel('C')
plt.ylabel('Accuracy')
plt.title("Gamma=0.01")
plt.ylim([0.60, 1])
plt.legend(['test accuracy', 'train accuracy'], loc='upper left')
plt.xscale('log')

# subplot 2/3
plt.subplot(132)
gamma_001 = cv_results[cv_results['param_gamma']==0.001]

plt.plot(gamma_001["param_C"], gamma_001["mean_test_score"])
plt.plot(gamma_001["param_C"], gamma_001["mean_train_score"])
plt.xlabel('C')
plt.ylabel('Accuracy')
plt.title("Gamma=0.001")
plt.ylim([0.60, 1])
plt.legend(['test accuracy', 'train accuracy'], loc='upper left')
plt.xscale('log')

# subplot 3/3
plt.subplot(133)
gamma_0001 = cv_results[cv_results['param_gamma']==0.0001]

plt.plot(gamma_0001["param_C"], gamma_0001["mean_test_score"])
plt.plot(gamma_0001["param_C"], gamma_0001["mean_train_score"])
plt.xlabel('C')
plt.ylabel('Accuracy')
plt.title("Gamma=0.0001")
plt.ylim([0.60, 1])
plt.legend(['test accuracy', 'train accuracy'], loc='upper left')
plt.xscale('log')


from ...abs.client_abc import ClientABC

from ...utils.adapters import append_client_to_name
from ...utils.adapters import save_to_file

import uuid

from PIL import Image

from google.cloud import vision
from google.cloud.vision import types
from google.api_core.exceptions import PermissionDenied

from pprint import pprint as p

import io
import os

__all__ = ["GoogleVisionClient"]

def object_localization(objects):

    data = []
    for object_ in objects:
        obj_data = {
            object_.name : {'confidence' : object_.score}
        }
        for vertex in object_.bounding_poly.normalized_vertices:
            obj_data[object_.name].setdefault('vertices', []).append([vertex.x, vertex.y])
        data.append(obj_data)

    return data

parsers = {
    'object_localization' : object_localization
}

class GoogleVisionClient(ClientABC):

    def __init__(self,service_account):
        self.client = vision.ImageAnnotatorClient()\
                    .from_service_account_json(service_account)

    REPORTS = {'object_localization' : lambda client, image: client.object_localization(
        image=image).localized_object_annotations
        }

    def get_response(self, file_path, report_type):

        try:
            with io.open(file_path, 'rb') as image_file:
                content = image_file.read()
            image = vision.types.Image(content=content)
        except:
            try:
                image = vision.types.Image()
                image.source.image_uri = self.file_path
            except PermissionDenied:
                raise PermissionDenied("Ensure Vision API is enabled")

        objects = self.REPORTS[report_type](self.client,image)

        return parsers[report_type](objects)

    def read(self, shuttle, report_type, gcs_file_path=None):

        shuttle.client = self

        shuttle.name = append_client_to_name(shuttle=shuttle)

        if gcs_file_path: #in the cloud
            shuttle.data = self.get_response(file_path=gcs_file_path, report_type=report_type)
        else: #using image obj
            tmp_file = '{}/{}.jpg'.format(shuttle.staging_path, uuid.uuid4().hex)
            save_to_file(data=shuttle.data,file_path=tmp_file)
            shuttle.data = self.get_response(file_path=tmp_file, report_type=report_type)
            os.remove(tmp_file)

        return shuttle

    def write(self,shuttle):
        raise NotImplementedError('Cannot write to the Google VisionAPI')

    def delete(self,shuttle):
        raise NotImplementedError('Cannot delete on the Google VisionAPI')

    def edit(self,shuttle):
        raise NotImplementedError('Cannot edit the Google VisionAPI')

    def merge(self,shuttle):
        raise NotImplementedError('Cannot merge on the Google VisionAPI')


from __future__ import unicode_literals
from django.http import HttpResponse
from django.shortcuts import render
from django.views.generic import TemplateView
from django.contrib.auth.models import User
import urllib
from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf

# Create your views here.

def get_authorization_url(request):

        # URL to where we will redirect to
        redirect_url = urllib.quote_plus(settings.SITE_URL + reverse('register_google'))

        # create a unique state value for CSRF validation
        request.session['google_state'] = unicode(csrf(request)['csrf_token'])

        scope = urllib.quote_plus('https://www.googleapis.com/auth/userinfo.email') + '+' + \
                urllib.quote_plus('https://www.googleapis.com/auth/userinfo.profile')

        # redirect to google for approval
        url = 'https://accounts.google.com/o/oauth2/auth?' \
              + 'scope=' + scope \
              + '&state=' + request.session['google_state'] \
              + '&redirect_uri=' + redirect_url \
              + '&response_type=code' \
              + '&client_id=' + settings.GOOGLE_OAUTH2_CLIENT_ID \
              + '&access_type=offline' \
              + '&approval_prompt=auto'

        return url
def verify(request):
        # Google will direct with state and code in the URL
        # ?state=zNHRjuYO...&code=4/zK5F93g2we...

        # ensure we have a session state and the state value is the same as what google returned
        if 'google_state' not in request.session \
           or 'state' not in request.GET \
           or 'code' not in request.GET \
           or request.session['google_state'] != request.GET['state']:
            return False
        else:
            return True

def get_user_profile(request, userid):
    user = User.objects.get(id=userid)
    return render(request, 'ProfileView/profile.html', {"user":user})

def select_profile(request):
	get_authorization_url(request)
	HttpResponseRedirect(url)


import datetime
import io
import pathlib
import pickle
import re
import uuid

# import gym
import numpy as np
import tensorflow as tf
import tensorflow.compat.v1 as tf1
import tensorflow_probability as tfp
from tensorflow.keras.mixed_precision import experimental as prec
from tensorflow_probability import distributions as tfd

def count_episodes(directory):
    filenames = directory.glob("*.npz")
    lengths = [int(n.stem.rsplit("-", 1)[-1]) - 1 for n in filenames]
    episodes, steps = len(lengths), sum(lengths)
    return episodes, steps

def graph_summary(writer, fn, *args):
    step = tf.summary.experimental.get_step()

    def inner(*args):
        tf.summary.experimental.set_step(step)
        with writer.as_default():
            fn(*args)

    return tf.numpy_function(inner, args, [])

# def video_summary(name, video, step=None, fps=20):
#     #   name = name if isinstance(name, str) else name.decode('utf-8')
#     name = str(name)

#     if np.issubdtype(video.dtype, np.floating):
#         video = np.clip(255 * video, 0, 255).astype(np.uint8)
#     print("video.shape:", video.shape)
#     B, T, H, W, C = video.shape
#     try:
#         # frames = video.transpose((1, 2, 0, 3, 4)).reshape((T, H, B * W, C))
#         frames = video
#         summary = tf1.Summary()
#         image = tf1.Summary.Image(height=H, width=W, colorspace=C)
#         image.encoded_image_string = encode_gif(frames, fps)
#         summary.value.add(tag=name + "/gif", image=image)
#         tf.summary.experimental.write_raw_pb(summary.SerializeToString(), step)
#     except (IOError, OSError) as e:
#         print("GIF summaries require ffmpeg in $PATH.", e)
#         frames = video.transpose((0, 2, 1, 3, 4)).reshape((1, B * H, T * W, C))
#         tf.summary.image(name + "/grid", frames, step)

def video_summary(name, video, step=None, fps=20):
    # print("name:", name)
    # name = name if isinstance(name, str) else name.decode("utf-8")
    name = str(name)
    if np.issubdtype(video.dtype, np.floating):
        video = np.clip(255 * video, 0, 255).astype(np.uint8)
    B, T, H, W, C = video.shape
    try:
        frames = video.transpose((1, 2, 0, 3, 4)).reshape((T, H, B * W, C))
        summary = tf1.Summary()
        image = tf1.Summary.Image(height=B * H, width=T * W, colorspace=C)
        image.encoded_image_string = encode_gif(frames, fps)
        summary.value.add(tag=name + "/gif", image=image)
        tf.summary.experimental.write_raw_pb(summary.SerializeToString(), step)
    except (IOError, OSError) as e:
        print("GIF summaries require ffmpeg in $PATH.", e)
        frames = video.transpose((0, 2, 1, 3, 4)).reshape((1, B * H, T * W, C))
        tf.summary.image(name + "/grid", frames, step)

def encode_gif(frames, fps):
    from subprocess import Popen, PIPE

    h, w, c = frames[0].shape
    pxfmt = {1: "gray", 3: "rgb24"}[c]
    cmd = " ".join(
        [
            f"ffmpeg -y -f rawvideo -vcodec rawvideo",
            f"-r {fps:.02f} -s {w}x{h} -pix_fmt {pxfmt} -i - -filter_complex",
            f"[0:v]split[x][z];[z]palettegen[y];[x]fifo[x];[x][y]paletteuse",
            f"-r {fps:.02f} -f gif -",
        ]
    )
    proc = Popen(cmd.split(" "), stdin=PIPE, stdout=PIPE, stderr=PIPE)
    for image in frames:
        proc.stdin.write(image.tostring())
    out, err = proc.communicate()
    if proc.returncode:
        raise IOError("\n".join([" ".join(cmd), err.decode("utf8")]))
    del proc
    return out

class TanhBijector(tfp.bijectors.Bijector):
    def __init__(self, validate_args=False, name="tanh"):
        super().__init__(
            forward_min_event_ndims=0, validate_args=validate_args, name=name
        )

    def _forward(self, x):
        return tf.nn.tanh(x)

    def _inverse(self, y):
        dtype = y.dtype
        y = tf.cast(y, tf.float32)
        y = tf.where(
            tf.less_equal(tf.abs(y), 1.0),
            tf.clip_by_value(y, -0.99999997, 0.99999997),
            y,
        )
        y = tf.atanh(y)
        y = tf.cast(y, dtype)
        return y

    def _forward_log_det_jacobian(self, x):
        log2 = tf.math.log(tf.constant(2.0, dtype=x.dtype))
        return 2.0 * (log2 - x - tf.nn.softplus(-2.0 * x))

class SampleDist:
    def __init__(self, dist, samples=100):
        self._dist = dist
        self._samples = samples

    @property
    def name(self):
        return "SampleDist"

    def __getattr__(self, name):
        return getattr(self._dist, name)

    def mean(self):
        samples = self._dist.sample(self._samples)
        return tf.reduce_mean(samples, 0)

    def mode(self):
        sample = self._dist.sample(self._samples)
        logprob = self._dist.log_prob(sample)
        return tf.gather(sample, tf.argmax(logprob))[0]

    def entropy(self):
        sample = self._dist.sample(self._samples)
        logprob = self.log_prob(sample)
        return -tf.reduce_mean(logprob, 0)

class OneHotDist:
    def __init__(self, logits=None, probs=None):
        self._dist = tfd.Categorical(logits=logits, probs=probs)
        self._num_classes = self.mean().shape[-1]
        self._dtype = prec.global_policy().compute_dtype

    @property
    def name(self):
        return "OneHotDist"

    def __getattr__(self, name):
        return getattr(self._dist, name)

    def prob(self, events):
        indices = tf.argmax(events, axis=-1)
        return self._dist.prob(indices)

    def log_prob(self, events):
        indices = tf.argmax(events, axis=-1)
        return self._dist.log_prob(indices)

    def mean(self):
        return self._dist.probs_parameter()

    def mode(self):
        return self._one_hot(self._dist.mode())

    def sample(self, amount=None):
        amount = [amount] if amount else []
        indices = self._dist.sample(*amount)
        sample = self._one_hot(indices)
        probs = self._dist.probs_parameter()
        sample += tf.cast(probs - tf.stop_gradient(probs), self._dtype)
        return sample

    def _one_hot(self, indices):
        return tf.one_hot(indices, self._num_classes, dtype=self._dtype)


import socket
from cryptography.fernet import Fernet

user   = "Alice"
server = "Bob"
key_TGS = b"BgIFUaxnefMzR1FI_Sv-meLxCV4e5RI6zp-5Y_RlR6s="

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
port = 22222
server_socket.bind(("127.0.0.1", port))
server_socket.listen(5)

while True:
    # Step 5
    c, addr = server_socket.accept()
    (enc_1, enc_2) = c.recv(1024).decode().split()
    print(f"Connection request received from Client: {user}, Address: {addr}")
    # Step 6
    fernet_1 = Fernet(key_TGS)
    (user_tmp, key_session) = fernet_1.decrypt(enc_2.encode()).split()
    fernet_2 = Fernet(key_session)
    nonce = fernet_2.decrypt(enc_1.encode()).decode()
    nonce_new = str(int(nonce) - 1)
    enc = fernet_2.encrypt(nonce_new.encode())
    c.send(enc)
    print(f"Nonce: {nonce} received from Client: {user_tmp}")
    print(f"Session Key: {key_session} received from Client: {user_tmp}")
    print(f"Sending new Nonce: {nonce_new} to Client: {user_tmp}...")
    c.close()
    break


import datetime
import math

def prodList(myList) :
    result = 1
    for x in myList:
         result = result * x
    return result

getal = 1
a = 1
max = 100000
t = datetime.datetime.now()
result = []
E = []
rad = []

for getal in range (1, max+1):
	a = getal
	b = 2
	while a%2==0:
	  a = a/2
	  rad.append(2)
	for b in range(3, int(math.sqrt(getal))+1,2):
	  while a%b == 0:
	  	a = a/b
	  	rad.append(b)
	if a > 2:
		rad.append(int(a))
	#print (set(rad))
	E.append([getal, prodList(rad), prodList(set(rad))])
	rad = []
#E.sort(key=lambda x: x[0])
E.sort(key=lambda x: x[2])

#print (E)
print (E[10000-1])
runtime  = datetime.datetime.now() - t
print (runtime)


class Edge(object):
    def __init__(self, u, v, c):
        self.source = u
        self.sink = v
        self.capacity = c
        self.flow = 0

    def __str__(self):
        return 'From ' + str(self.source) + ' to ' + str(self.sink)

class FlowNetwork(object):
    def __init__(self):
        self.adj = {}

    def getVertices(self):
        return self.adj.keys()

    def addVertex(self, vertex):
        self.adj[vertex] = []

    def getEdges(self, v):
        return self.adj[v]

    def addEdge(self, u, v, c):
        if u not in self.adj:
            self.addVertex(u)
        if v not in self.adj:
            self.addVertex(v)

        # Because the input file contains edges it is needed to create two links
        edge = Edge(u, v, c)
        self.adj[u].append(edge)
        edge_ = Edge(v, u, c)
        self.adj[v].append(edge_)

# Shortest path from a source node to a destination one algorithm using BFS method where the residual is taken into acount
def flowBFS(graph, source, destination):
    queue = [source] # Used as a FIFO queue
    seen = (source,) # Tuple of already visited nodes
    path = {} # Dictionary wich saves the path for each node
    path[source] = [] # Initialize the path for the source node as nothing
    while queue:
        current = queue.pop(0)
        if current == destination:
            return path[destination]
        for edge in graph.getEdges(current):
            residual = edge.capacity - edge.flow
            if residual > 0 and edge.sink not in seen:
                seen += (edge.sink,)
                path[edge.sink] = path[edge.source] + [edge]
                queue.append(edge.sink)

# Edmonds Karp algorithm to find the max flow between a source and destination node
def edmondsKarp(graph, source, destination):
    path = flowBFS(graph, source, destination)
    while path:
        residuals = [edge.capacity - edge.flow for edge in path]
        flow = min(residuals)
        for edge in path:
            edge.flow += flow
        path = flowBFS(graph, source, destination)
    return sum(edge.flow for edge in graph.getEdges(source))

if __name__ == '__main__':
    import sys
    import time as t
    import matplotlib.pyplot as plt
    import copy

    Network = FlowNetwork()

    # Reads the text file and creates the network graph with capacities for each link = 1.
    f = open(str(sys.argv[1]),"r")
    for line in f:
        word = line.split()
        Network.addEdge(word[0], word[1], 1)

    f.closed

    # Creates a vector list with the minimum number of edges that separates one node from another from all vertices to all vertices
    total_counts = 0
    connectivity_list = []
    for source in Network.getVertices():
        for destination in Network.getVertices():
            if source == destination:
                continue
            connectivity_list.append(edmondsKarp(copy.deepcopy(Network), source, destination))
            total_counts += 1 # number of runs of Edonds Karp algorithm

    # Process the list so it cn be plotted as a complementary cumulative distribution of the minimum number of edges that separates one node from another
    _max = max(connectivity_list) # maximum number of edges to be disconected
    min_connect = [0] * (_max + 2)
    for x in connectivity_list:
        min_connect[x] += 1

    for x in range(_max - 1, 0, -1):
        min_connect[x] += min_connect[x+1]

    for x in range(len(min_connect)):
        min_connect[x] = min_connect[x] / total_counts

    plt.plot(list(range(1, _max + 2)), min_connect[1:])
    plt.title('Complementary cumulative distribution of the minimum number of edges that separates one node from another')
    plt.ylabel('Pairs of nodes')
    plt.xlabel('k edges')
    plt.show()


import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import argrelextrema
from pandas import ExcelWriter
import os
import openpyxl

choice = input("Would you like to just do computations on one file (1) or combine multiple .csv files into an .xlsx file (2): ")

if choice == '2':
    csv_files = [] # Initialize an empty list

    while True: # Continue prompting the user until they choose to stop
        csv_file = input("Enter the full path of a .csv file (or 'quit' to finish): ")

        if csv_file.lower() == 'quit':
            break

        # Checks to see if file exists
        if not os.path.isfile(csv_file):
            print("The file does not exist. Please check the path and try again.")
        else:
            # Append entered file to the list
            csv_files.append(csv_file)

    # Prompts user to enter the output file name with .xlsx
    outputfileName = input("What would you like the output file to be named (with .xlsx): ")
    # Create a Pandas Excel writer using XlsxWriter as the engine
    with ExcelWriter(outputfileName) as writer:
        # Iterate through all the .csv files and add each one to a separate worksheet
        for csv_file in csv_files:
            df = pd.read_csv(csv_file)
            # Use the .csv file name (without extension) as the name of the worksheet
            df.to_excel(writer, sheet_name=os.path.splitext(os.path.basename(csv_file))[0], index=False)
        writer.save()

        # Input which worksheet to work with
    looper = 1
    while looper == 1:
        selectSheet = input("Enter which worksheet you would like to work with (for list, enter 'GiveList'): ")
        if selectSheet == 'GiveList':
            #Lists all the worksheets inside .xlsx file
            xls = pd.ExcelFile(outputfileName)
            sheet_list = xls.sheet_names
            print(sheet_list)
        else:
            # Reads the new Excel file skipping the first 17 lines inside the respective worksheet
            df = pd.read_excel(outputfileName, header=None, skiprows = 17, sheet_name = selectSheet)
            looper = 0

elif choice == '1':
    filename = input("Please input filename with respective path and type: ")
    #filename = r"C:\Users\Jakey\Desktop\Summer_2023_Research\Python\780-AuNS-3_0.5-S1.1" + '.xlsx'
    #filename = r"C:\Users\movaq\OneDrive\Spring 2023\Gold Nano-star\data\python_data" + '.xlsx'

    # If the filetype is .xlsx which includes multiple worksheets
    if filename.endswith('.xlsx'):
        # Input which worksheet to work with
        looper = 1
        while looper == 1:
            selectSheet = input("Enter which worksheet you would like to work with (for list, enter 'GiveList'): ")
            if selectSheet == 'GiveList':
                #Lists all the worksheets inside .xlsx file
                xls = pd.ExcelFile(filename)
                sheet_list = xls.sheet_names
                print(sheet_list)
            else:
                # Reads the new Excel file skipping the first 17 lines inside the respective worksheet
                df = pd.read_excel(filename, header=None, skiprows = 17, sheet_name = selectSheet)
                looper = 0

    # If the filetype is .csv which only has 1 worksheet
    elif filename.endswith('.csv'):
        # Reads the new .csv file skipping the first 17 lines
        df = pd.read_csv(filename, header=None, skiprows = 17)
    else:
        raise ValueError('Invalid file type. Please use .xlsx or .csv file')

else:
    raise ValueError('Invalid choice')

# Create a sample dataframe with header names
header_names = input("Enter the header names separated by commas: ").split(',')

df.columns = header_names

# display the dataframeg
print(df)

# Get the header name of the first column
x_col = df.columns[0]

# Filter the data between 450 and 1600
df = df[(df[x_col] >= 450) & (df[x_col] <= 1600)]

# Plot all the spectra with the first column as the x-axis
for i in range(1, df.shape[1]):
    # Fit a polynomial to the data
    z = np.polyfit(df[x_col], df.iloc[:, i], 30)
    p = np.poly1d(z)

    # Subtract the minimum value of the polynomial fit from the data to get the baseline-corrected data
    baseline_corrected_data = df.iloc[:, i] - p(df[x_col])
    min_value = np.min(baseline_corrected_data)
    baseline_corrected_data += abs(min_value)

    # Bring all the negative values on the curve to position one
    if np.min(baseline_corrected_data) < 0:
        negative_values = baseline_corrected_data[baseline_corrected_data < 0]
        baseline_corrected_data[baseline_corrected_data < 0] = 1
        baseline_corrected_data[0:len(negative_values)] = negative_values

    # Plot the baseline-corrected data
    plt.plot(df[x_col], baseline_corrected_data, label=df.columns[i])

    # Find the indices of the local maxima of the data
    maxima_indices = argrelextrema(baseline_corrected_data.values, np.greater)

    # Sort the indices based on the value of the data at the indices
    maxima_indices = maxima_indices[0][np.argsort(-baseline_corrected_data.values[maxima_indices])]

    # Mark the top three highest peaks with markers on the plot
    #for j in range(min(3, len(maxima_indices))):
     #   plt.plot(df[x_col].values[maxima_indices[j]], baseline_corrected_data.values[maxima_indices[j]], 'ro')

# Add a straight line
plt.axvspan(1186, 1226, color='blue', alpha=0.3)
plt.axvspan(1250, 1290, color='black', alpha=0.3)
plt.axvspan(1447, 1487, color='yellow', alpha=0.3)
plt.axvspan(1495, 1535, color='red', alpha=0.3)

plt.text(1206 -50, 18000, '[1206] \nC-H \nrocking of \ncyclohexene ring', ha='right')
plt.text(1270 + 10, 15000, '[1270] \nC-H \nrocking of \nphenyl ring', ha='left')
plt.text(1467 -10, 5000, '[1467] \nC=C \nbending of \nphenyl', ha='right')

plt.text(1515 + 50, 4500, '[1515] \nC-H \nstretching \nof phenyl', ha='left')

# add a title and labels to the axes
#plt.title('SERS measurement of silica coated, IR780 encapsulated GNS')
plt.xlabel('Wavenumber (cm$^{-1}$)', fontsize=12)
plt.ylabel('Raman Intensity (counts)', fontsize=12)

# Set the minimum value of the y-axis to be lower than the minimum value of the data
plt.ylim(bottom=min(df.iloc[:, 1:].min().min(), 0))

# Add a legend
plt.legend(loc='upper left')

# display the plot
plt.show()

# Plot all the spectra with the first column as the x-axis
fig, ax = plt.subplots()
fig.set_size_inches(6, 4)
x = df[x_col].values
y_offset = 1

for i in range(1, df.shape[1]):
    # Fit a polynomial to the data
    z = np.polyfit(x, df.iloc[:, i], 3)
    p = np.poly1d(z)

    # Subtract the polynomial fit from the data to get the baseline-corrected data
    baseline_corrected_data = df.iloc[:, i] - p(x) + y_offset
    min_value = np.min(baseline_corrected_data)
    baseline_corrected_data += abs(min_value)

    # Plot the baseline-corrected data with an offset in the y-axis
    ax.plot(x, baseline_corrected_data, label=df.columns[i])

    # Find the indices of the local maxima of the data
    maxima_indices = argrelextrema(baseline_corrected_data.values, np.greater)

    # Sort the indices based on the value of the data at the indices
    maxima_indices = maxima_indices[0][np.argsort(-baseline_corrected_data.values[maxima_indices])]

    # Mark the top three highest peaks with markers on the plot
    for j in range(min(4, len(maxima_indices))):
        ax.plot(x[maxima_indices[j]], baseline_corrected_data.values[maxima_indices[j]], 'ro')

    # Increment the y offset for the next plot
    y_offset += 25000

# Add labels to the axes
#ax.set_title('Baseline-corrected spectra', fontsize=14, loc="center")
ax.set_xlabel('Wavenumber (cm$^{-1}$)', fontsize=12)
ax.set_ylabel('Raman intensity', fontsize=12)

# Display the legend
ax.legend(loc = 'upper right')

# Display the plot
plt.show()

# Create empty lists to store the highest peak, second highest peak, and third highest peak of each spectrum and its corresponding sample name
highest_peaks = []
second_highest_peaks = []
third_highest_peaks = []

sample_names = []

highest_wavenumbers = []
second_highest_wavenumbers = []
third_highest_wavenumbers = []

# Loop through each spectrum in the DataFrame
for i in range(1, df.shape[1]):
    # Fit a polynomial to the data
    z = np.polyfit(df[x_col], df.iloc[:, i], 3)
    p = np.poly1d(z)

    # Subtract the minimum value of the polynomial fit from the data to get the baseline-corrected data
    baseline_corrected_data = df.iloc[:, i] - p(df[x_col])
    min_value = np.min(baseline_corrected_data)
    baseline_corrected_data += abs(min_value)

    # Find the indices of the local maxima of the data
    maxima_indices = argrelextrema(baseline_corrected_data.values, np.greater)

    # Sort the indices based on the value of the data at the indices
    sorted_maxima_indices = maxima_indices[0][np.argsort(-baseline_corrected_data.values[maxima_indices])]

    # Add the highest peak, second highest peak, third highest peak value and sample name to the corresponding lists
    highest_peaks.append(baseline_corrected_data.values[sorted_maxima_indices[0]])
    second_highest_peaks.append(baseline_corrected_data.values[sorted_maxima_indices[1]])
    third_highest_peaks.append(baseline_corrected_data.values[sorted_maxima_indices[2]])

    highest_wavenumbers.append(df[x_col].values[sorted_maxima_indices[0]])
    second_highest_wavenumbers.append(df[x_col].values[sorted_maxima_indices[1]])
    third_highest_wavenumbers.append(df[x_col].values[sorted_maxima_indices[2]])

    sample_names.append(df.columns[i])

# Compute the mean and standard deviation of the highest peaks
mean_highest_peak = np.mean(highest_peaks)
std_highest_peak = np.std(highest_peaks)

mean_second_highest_peak = np.mean(second_highest_peaks)
std_second_highest_peak = np.std(second_highest_peaks)

mean_third_highest_peak = np.mean(third_highest_peaks)
std_third_highest_peak = np.std(third_highest_peaks)

# Compute the RSD of the highest peaks
rsd_highest_peak = (std_highest_peak / mean_highest_peak) * 100
rsd_second_highest_peak = (std_second_highest_peak / mean_second_highest_peak) * 100
rsd_third_highest_peak = (std_third_highest_peak / mean_third_highest_peak) * 100

# Create labels for the mean and standard deviation
mean_label_highest = f"Mean: {mean_highest_peak:.2f}\n+/- {std_highest_peak:.2f}\nRSD: {rsd_highest_peak:.2f}%"
mean_label_second_highest = f"Mean: {mean_second_highest_peak:.2f}\n+/- {std_second_highest_peak:.2f}\nRSD: {rsd_second_highest_peak:.2f}%"
mean_label_third_highest = f"Mean: {mean_third_highest_peak:.2f}\n+/- {std_third_highest_peak:.2f}\nRSD: {rsd_third_highest_peak:.2f}%"

# Create a bar chart of the highest peak of each spectrum after baseline correction
fig, ax = plt.subplots(figsize=(10, 5))
x = np.arange(len(sample_names))

ax.bar(x, highest_peaks, width=0.8, label='Highest Peak', tick_label=sample_names)
#ax.errorbar(x, highest_peaks, yerr=std_highest_peak, fmt='none', ecolor='black', capsize=5)
ax.text(3,-5000, mean_label_highest, ha='right')

ax.bar(x + 20, second_highest_peaks, width=0.8, label='Second Highest Peak', tick_label=sample_names)
#ax.errorbar(x + 20, second_highest_peaks, yerr=std_second_highest_peak, fmt='none', ecolor='black', capsize=5)
ax.text(23,-5000, mean_label_second_highest, ha='right')

ax.bar(x + 10, third_highest_peaks, width=0.8, label='Third Highest Peak', tick_label=sample_names)
#ax.errorbar(x + 10, third_highest_peaks, yerr=std_third_highest_peak, fmt='none', ecolor='black', capsize=5)
ax.text(13,-5000, mean_label_third_highest, ha='right')

width = 10
xticks = np.tile(x, 3) + np.repeat([0, width, 2*width], len(sample_names))
ax.set_xticks(xticks)
ax.set_xticklabels(np.tile(sample_names, 3), rotation=90)
ax.tick_params(axis='x', pad=10, which='minor')
ax.set_ylabel('Raman Intensity', fontsize=12)
ax.set_xlabel('Samples', fontsize=12)

ax2 = ax.twiny()
ax2.set_xticks([4, 15, 26, 30])
ax2.set_xticklabels([round(highest_wavenumbers[0],0), round(second_highest_wavenumbers[0],0), round(third_highest_wavenumbers[0],0), ""])
ax2.set_xlabel('Wavenumber (cm$^{-1}$)', fontsize=12)

fig.tight_layout()
plt.show()

# ##########################################################
# # Inside these comments is the combining files code
# # If you just want the skip 17 lines and select the worksheet code, comment this out and uncomment all above

# # Function to handle different files
# def process_file(filename, selectSheet=None):
#     if filename.endswith('.xlsx'):
#         df = pd.read_excel(filename, header=None, skiprows = 17, sheet_name = selectSheet)
#     elif filename.endswith('.csv'):
#         df = pd.read_csv(filename, header=None, skiprows = 17)
#     else:
#         raise ValueError('Invalid file type. Please use .xlsx or .csv file')
#     return df

# # Function to combine files
# def combine_files(filenames):
#     combined_data = None
#     for filename in filenames:
#         filename = filename.strip()  # Remove any leading/trailing spaces
#         if filename.endswith('.xlsx'):
#             selectSheet = input(f"Enter which worksheet you would like to work with for file {filename}: ")
#             df = process_file(filename, selectSheet)
#         else:
#             df = process_file(filename)

#         if combined_data is None:
#             combined_data = df
#         else:
#             combined_data = pd.concat([combined_data, df], axis=1)

#     # Write the combined data to a new Excel file
#     combined_filename = "combined.xlsx"
#     write_to_excel(combined_data, combined_filename)
#     print(f"All files combined into {combined_filename}. Now proceeding with the data analysis.")

#     return combined_filename

# def write_to_excel(df, filename):
#     writer = ExcelWriter(filename)
#     df.to_excel(writer, 'Sheet1', index=False)
#     writer.save()

# choice = input("Do you want to (1) process a single file or (2) combine multiple files? ")

# if choice == '1':
#     filename = input("Please input the full file path and filename: ")
#     if filename.endswith('.xlsx'):
#         selectSheet = input("Enter which worksheet you would like to work with: ")
#         df = process_file(filename, selectSheet)
#     else:
#         df = process_file(filename)
# elif choice == '2':
#     filenames = input("Please input the full file paths and filenames, separated by commas: ").split(',')
#     filename = combine_files(filenames)
#     df = process_file(filename)
# else:
#     raise ValueError('Invalid choice. Please enter 1 or 2.')

# # Read the file (either the single file or the combined file)
# df = pd.read_excel(filename, header=None, skiprows=17)

# ##################################################################################


"""Dict helpers, mostly used in config routines."""

from typing import Any, Dict, List, Optional

def nested_combine(*dicts: Dict[str, Any]) -> Dict[str, Any]:
    """Combine an iterable of dictionaries.

    Each dictionary is combined into a result dictionary. For
    each key in the first dictionary, it will be overwritten
    by any same-named key in any later dictionaries in the
    iterable. If the element at that key is a dictionary, rather
    than just overwriting we use the same function to combine
    those dictionaries.

    Args:
        *dicts: An iterable of dictionaries to be combined.

    Returns:
        `dict`: A combined dictionary from the input dictionaries.

    A simple example:
    >>> nested_combine({"a": {"b": "c"}}, {"a": {"d": "e"}})
    {'a': {'b': 'c', 'd': 'e'}}

    Keys overwrite left to right:
    >>> nested_combine({"a": {"b": "c"}}, {"a": {"b": "e"}})
    {'a': {'b': 'e'}}
    """
    r: Dict[str, Any] = {}
    for d in dicts:
        for k in d:
            if k in r and isinstance(r[k], dict):
                if isinstance(d[k], dict):
                    r[k] = nested_combine(r[k], d[k])
                else:  # pragma: no cover
                    raise ValueError(
                        "Key {!r} is a dict in one config but not another! PANIC: "
                        "{!r}".format(k, d[k])
                    )
            else:
                r[k] = d[k]
    return r

def dict_diff(
    left: Dict[str, Any], right: Dict[str, Any], ignore: Optional[List[str]] = None
) -> Dict[str, Any]:
    """Work out the difference between two dictionaries.

    Returns a dictionary which represents elements in the `left`
    dictionary which aren't in the `right` or are different to
    those in the `right`. If the element is a dictionary, we
    recursively look for differences in those dictionaries,
    likewise only returning the differing elements.

    NOTE: If an element is in the `right` but not in the `left`
    at all (i.e. an element has been *removed*) then it will
    not show up in the comparison.

    Args:
        left (:obj:`dict`): The object containing the *new* elements
            which will be compared against the other.
        right (:obj:`dict`): The object to compare against.
        ignore (:obj:`list` of `str`, optional): Keys to ignore.

    Returns:
        `dict`: A dictionary representing the difference.

    Basic functionality shown, especially returning the left as:
    >>> dict_diff({"a": "b", "c": "d"}, {"a": "b", "c": "e"})
    {'c': 'd'}

    Ignoring works on a key basis:
    >>> dict_diff({"a": "b"}, {"a": "c"})
    {'a': 'b'}
    >>> dict_diff({"a": "b"}, {"a": "c"}, ["a"])
    {}
    """
    buff: Dict[str, Any] = {}
    for k in left:
        if ignore and k in ignore:
            continue
        # Is the key there at all?
        if k not in right:
            buff[k] = left[k]
        # Is the content the same?
        elif left[k] == right[k]:
            continue
        # If it's not the same but both are dicts, then compare
        elif isinstance(left[k], dict) and isinstance(right[k], dict):
            diff = dict_diff(left[k], right[k], ignore=ignore)
            # Only include the difference if non-null.
            if diff:
                buff[k] = diff
        # It's just different
        else:
            buff[k] = left[k]
    return buff


import sys
import os
import requests
import aiohttp
import aiofiles
import asyncio
import time

if len(sys.argv[1:])!=1:
    print("Usage: python3 web_sync.py <file_name>")
    sys.exit(1)

async def get_file_content(file_path):
    f = await aiofiles.open(file_path, "r", encoding="utf-8")
    return await f.read()

async def get_content(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def write_content(content,file):
    if os.name == "posix":
        tmp_dir = f"/tmp/web_{file}"
    else:
        tmp_dir = f"./Tp6/tmp/web_{file}"

    if not os.path.exists(tmp_dir.split('/')[0]):
        os.makedirs(tmp_dir)
    elif not os.path.exists('/'.join(tmp_dir.split('/')[1:])):
        os.makedirs('/'.join(tmp_dir.split('/')[1:]))
    elif not os.path.exists(tmp_dir):
        os.makedirs(tmp_dir)

    os.chdir(tmp_dir)

    f= await aiofiles.open(file+".html","w", encoding="utf-8")
    await f.write(content)
    await f.close()

    os.chdir("../../..")

if __name__ == "__main__":
    startTime= time.time()
    file_path = sys.argv[1]
    sites= asyncio.run(get_file_content(file_path))
    for site in sites.split("\n"):
        file_name = site.split(".")[1]
        print(file_name)
        asyncio.run(write_content(asyncio.run(get_content(site)),file_name))
    print(f"Done! In {time.time()-startTime} seconds")


import torch
from torch import nn
from torch.nn import init

# JK
def init_weights(net, init_type='normal', init_gain=0.02):
    """Initialize network weights.

    Parameters:
        net (network)   -- network to be initialized
        init_type (str) -- the name of an initialization method: normal | xavier | kaiming | orthogonal
        init_gain (float)    -- scaling factor for normal, xavier and orthogonal.

    We use 'normal' in the original pix2pix and CycleGAN paper. But xavier and kaiming might
    work better for some applications. Feel free to try yourself.
    """

    def init_func(m):  # define the initialization function
        classname = m.__class__.__name__
        if hasattr(m, 'weight') and (classname.find('Conv') != -1 or classname.find('Linear') != -1):
            if init_type == 'normal':
                init.normal_(m.weight.data, 0.0, init_gain)
            elif init_type == 'xavier':
                init.xavier_normal_(m.weight.data, gain=init_gain)
            elif init_type == 'kaiming_uniform':
                init.kaiming_uniform(m.weight.data, a=0, mode='fan_in')
                init.kaiming_uniform(m.bias.data, a=0, mode='fan_in')
            elif init_type == 'orthogonal':
                init.orthogonal_(m.weight.data, gain=init_gain)
                init.orthogonal_(m.bias.data, gain=init_gain)
            else:
                raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
            if hasattr(m, 'bias') and m.bias is not None:
                init.constant_(m.bias.data, 0.0)
        elif classname.find(
                'BatchNorm2d') != -1:  # BatchNorm Layer's weight is not a matrix; only normal distribution applies.
            init.normal_(m.weight.data, 1.0, init_gain)
            init.constant_(m.bias.data, 0.0)

    print('initialize network with %s' % init_type)
    net.apply(init_func)

class ScoreModel(nn.Module):
    def __init__(self, clamp=False, masked_feat_id=None):
        super(ScoreModel, self).__init__()
        self.clamp = clamp
        self.masked_feat_id = masked_feat_id

    def compute_score(self, x):
        raise NotImplementedError

    def forward(self, x):
        if self.masked_feat_id is not None:
            x = x.index_fill(-1, torch.tensor(self.masked_feat_id, dtype=torch.long, device=x.device), 0.0)
        score = self.compute_score(x)
        if self.clamp:
            score = torch.clamp(score, -10, 10)
        return score

class LinearModel(ScoreModel):

    #One layer simple linear model

    def __init__(self, input_dim=2, **kwargs):
        super(LinearModel, self).__init__(**kwargs)
        self.input_dim = input_dim
        self.w = nn.Linear(input_dim, 1, bias=True)

    def compute_score(self, x):
        h = self.w(x)
        return h

"""   original
class MLP(ScoreModel):
    def __init__(self, input_dim: int, hidden_layer: int, dropout: float = 0.0, **kwargs):
        super(MLP, self).__init__(**kwargs)
        self.input_size = input_dim
        fcs = []
        last_size = self.input_size
        for _ in range(hidden_layer):
            size = last_size // 2
            linear = nn.Linear(last_size, size)
            linear.bias.data.fill_(0.0)
            fcs.append(linear)
            last_size = size
            fcs.append(nn.ReLU())
            if dropout > 0.0:
                fcs.append(nn.Dropout(dropout))
        self.fc = nn.Sequential(*fcs)
        linear = nn.Linear(last_size, 1)
        linear.bias.data.fill_(0.0)
        self.final_layer = linear

    def compute_score(self, x):
        out = self.fc(x)
        out = self.final_layer(out)
        return out
"""

# Batch Norm version
class MLP(ScoreModel):
    def __init__(self, input_dim: int, hidden_layer: int, dropout: float = 0.0, **kwargs):
        super(MLP, self).__init__(**kwargs)
        self.input_size = input_dim
        fcs = []
        last_size = self.input_size
        for _ in range(hidden_layer):
            size = last_size // 2
            linear = nn.Linear(last_size, size)
            bn = nn.BatchNorm1d(20)  #JK

            #bn = nn.LayerNorm(size)  #JK
            linear.bias.data.fill_(0.0)
            fcs.append(linear)
            use_bn = False #JK
            if use_bn:    #JK
                fcs.append(bn) #JK
            last_size = size
            fcs.append(nn.ReLU())
            if dropout > 0.0:
                fcs.append(nn.Dropout(dropout))
        self.fc = nn.Sequential(*fcs)
        linear = nn.Linear(last_size, 1)
        linear.bias.data.fill_(0.0)
        self.final_layer = linear

    def compute_score(self, x):

        out = self.fc(x)
        out = self.final_layer(out)
        return out

# MLP for predicting an embedding of the group composition.
# Differs from the main MLP in that each item does not get its own score
# Items are aggregated to a group composition embedding to help predict accurate
class MLPGroupEmbedding(nn.Module):
    def __init__(self, input_dim: int, hidden_layer: int, dropout: float = 0.0, clamp = False):
        super(MLPGroupEmbedding, self).__init__()
        self.input_size = input_dim
        self.clamp = clamp
        fcs = []
        input_size = self.input_size
        for _ in range(hidden_layer):
            #size = last_size // 2
            #linear = nn.Linear(last_size, size)
            linear = nn.Linear(input_size, input_size)
            linear.bias.data.fill_(0.0)
            fcs.append(linear)
            bn = nn.BatchNorm1d(20)    # JK 1005
            #last_size = size
            fcs.append( bn )           # JK 1005
            fcs.append(nn.ReLU())
            if dropout > 0.0:
                fcs.append(nn.Dropout(dropout))
        self.fc = nn.Sequential(*fcs)
        linear = nn.Linear(input_size, input_size)
        linear.bias.data.fill_(0.0)
        self.final_layer = linear

    def forward(self, x):
        out = self.fc(x)
        out = self.final_layer(out)
        if self.clamp:
            out = torch.clamp(out, -10, 10)
        return out

# JK
class SiameseMLP(nn.Module):
    def __init__(self, ScoreModel, GroupCompModel):
        super(SiameseMLP, self).__init__()
        self.gcm = GroupCompModel
        self.sm  = ScoreModel

    def forward(self,x,gid):

        out_sm  = self.sm(x)
        out_gcm = self.gcm(gid)

        return out_sm, out_gcm

# This version concatenates item scores with group id vector, and
# aggregates to size-N^2 score embedding for the QP
class MLPQuadScore(nn.Module):
    def __init__(self, ScoreModel, list_len):
        super(MLPQuadScore, self).__init__()
        self.sm  = ScoreModel
        self.fc1 = nn.Linear(2*list_len,list_len**2)
        self.fc2 = nn.Linear(list_len**2,list_len**2)
        self.fc1.bias.data.fill_(0.0)
        self.fc2.bias.data.fill_(0.0)
        self.bn  = nn.BatchNorm1d(400)

    def forward(self,x,gid):

        out_sm  = self.sm(x)

        #out = torch.cat( (out_sm.squeeze(-1),gid),1 )
        out = torch.cat( (out_sm.view(gid.shape),gid),1 )
        out = self.fc1(out)
        out = self.bn(out)
        out = self.fc2(out)

        return out

def convert_vars_to_gpu(varlist):
    return [var.cuda() for var in varlist]

# for Zehlike baseline 11/8

class NNModel(nn.Module):
    """
    Neural network model
    """

    def __init__(self,
                 hidden_layer=64,
                 D=2,
                 dropout=0.0,
                 init_weight1=None,
                 init_weight2=None,
                 pooling=False,
                 clamp=False):
        self.input_dim = D
        super(NNModel, self).__init__()
        self.fc = nn.Linear(D, hidden_layer, bias=True)
        self.fc_drop = nn.Dropout(p=dropout)
        # self.activation = nn.ReLU()
        self.activation = nn.ReLU()
        if pooling == "concat_avg":
            self.fc2 = nn.Linear(2 * hidden_layer, hidden_layer, bias=True)
            self.fc3 = nn.Linear(hidden_layer, 1, bias=True)
        elif pooling is not False:
            self.fc2 = nn.Linear(hidden_layer, hidden_layer, bias=True)
            self.fc3 = nn.Linear(hidden_layer, 1, bias=True)
        else:
            self.fc2 = nn.Linear(hidden_layer, 1, bias=True)
        self.softmax = nn.Softmax(dim=1)
        if init_weight1 is not None:
            self.fc.weight = torch.nn.Parameter(init_weight1)
        if init_weight2 is not None:
            self.fc2.weight = torch.nn.Parameter(init_weight2)
        self.pooling_layer = pooling
        self.clamp = clamp

    def forward(self, x):
        h = self.activation(self.fc(x))
        h = self.fc_drop(h)
        if self.pooling_layer:
            if self.pooling_layer == "average":
                h1 = h - torch.mean(h, dim=0, keepdim=True)
            elif self.pooling_layer == "max":
                h1 = h - torch.max(h, dim=0, keepdim=True)
            elif self.pooling_layer == "concat_avg":
                h1 = torch.cat(
                    (h, torch.mean(h, dim=0, keepdim=True).repeat(
                        x.size()[0], 1)),
                    dim=1)
        else:
            h1 = h
        h2 = self.fc2(h1)
        if self.pooling_layer:
            h3 = self.fc3(self.activation(h2))
            return h3 if not self.clamp else torch.clamp(h3, -10, 10)

        else:
            return h2 if not self.clamp else torch.clamp(h2, -10, 10)


import sys
import collections

def bfs():

    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]

    queue.append((0, 0, 0))
    is_visited[0][0][0] = 1

    while len(queue) != 0:

        cur = queue.popleft()
        (is_broken, i, j) = cur

        if (i, j) == (n - 1, m - 1):
            return is_visited[is_broken][i][j]

        for (next_i, next_j) in [(i + _dir[0], j + _dir[1]) for _dir in directions]:

            if next_i < 0 or next_i > (n - 1) or next_j < 0 or next_j > (m - 1) :

                continue

            if is_visited[is_broken][next_i][next_j] != 0:

                continue

            if maze[next_i][next_j] == 0 and is_visited[is_broken][next_i][next_j] == 0:

                is_visited[is_broken][next_i][next_j] = is_visited[is_broken][i][j] + 1
                queue.append((is_broken, next_i, next_j))
                continue

            if maze[next_i][next_j] == 1 and  is_broken == 0:

                is_visited[1][next_i][next_j] = is_visited[is_broken][i][j] + 1
                queue.append((1, next_i, next_j))
                continue

    return -1

n, m = map(int, input().split())
maze = [(list(map(int, list(input())))) for _ in range(n)]
is_visited = [[[0] * m for __ in range(n)] for _ in range(2)]
queue = collections.deque()
print(bfs())

백준/Gold/2206.벽 부수고 이동하기/벽 부수고 이동하기.py

벽 부수고 이동하기.py


import tkinter as tk
import customtkinter as ctk

from PIL.Image import open as OpenImage

from settings import StyleElements as style
from settings import Paths as paths

from CTkMessagebox import CTkMessagebox

class DataView(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent, bg=style.CLR_BACKGROUND)

        self.controller = controller

        if self.controller.options['n_users'] == 1:
            self.populate_UI_1user()
        else:
            self.populate_UI_2users()
        return

    def back(self):
        self.controller.stop_measurement_thread()
        self.controller.back()
        return

    def end(self):
        self.controller.stop_measurement()
        return

    def recalibrate(self):
        print('recalibrate')
        self.controller.update_calibration_factor()
        return

    def populate_navigation_bar(self):
        # ------------------
        #   IMAGES USED
        # ------------------
        IC_BACK = ctk.CTkImage(OpenImage(paths.PATH_IC_BACK), size=(40,40))
        IC_CALIBRATE = ctk.CTkImage(OpenImage(paths.PATH_IC_CALIBRATE), size=(64,51))
        IC_END = ctk.CTkImage(OpenImage(paths.PATH_IC_END), size=(40,51))

        # ------------------
        #   NAVIGATION BAR
        # ------------------
        btn_back = ctk.CTkButton(master=self,
                                 width=40,
                                 height=51,
                                 text="",
                                 bg_color=style.CLR_BACKGROUND,
                                 fg_color=style.CLR_BACKGROUND,
                                 command=self.back,
                                 image=IC_BACK)
        btn_back.place(x=16, y=4)

        btn_recalibrate = ctk.CTkButton(master=self,
                                 width=64,
                                 height=51,
                                 text="",
                                 bg_color=style.CLR_BACKGROUND,
                                 fg_color=style.CLR_BACKGROUND,
                                 command=self.recalibrate,
                                 image=IC_CALIBRATE)
        btn_recalibrate.place(x=646, y=4)

        btn_end = ctk.CTkButton(master=self,
                                 width=40,
                                 height=51,
                                 text="",
                                 bg_color=style.CLR_BACKGROUND,
                                 fg_color=style.CLR_BACKGROUND,
                                 command=self.end,
                                 image=IC_END)
        btn_end.place(x=726, y=4)
        return

    def populate_UI_1user(self):
        # Navigation bar
        self.populate_navigation_bar()

        # Frame Top Left
        tl_frame = tk.Frame(self, width=368, height=130, bg= style.CLR_PRIMARY,
                            highlightthickness=1, highlightcolor=style.CLR_ONBACKGROUND)
        tl_frame.place(anchor='nw', x=24, y=64)

        time_txt = tk.Label(tl_frame, text="TIME [s]", font= style.FNT_CAPTION,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height = 16)
        time_txt.place(anchor='ne', x=364, y=0, height=16)

        self.time_var = tk.DoubleVar()
        time_data = tk.Label(tl_frame, textvariable=self.time_var, font= style.FNT_DATA,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height=106)
        time_data.place(anchor='ne', x=364, y=20, height=106)

        # Frame Top Right
        tr_frame = tk.Frame(self, width=368, height=130, bg= style.CLR_PRIMARY,
                            highlightthickness=1, highlightcolor=style.CLR_ONBACKGROUND)
        tr_frame.place(anchor='nw', x=384+24, y=0+64)

        pf_txt = tk.Label(tr_frame, text="PEAK FORCE [kg]", font= style.FNT_CAPTION,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height = 16)
        pf_txt.place(anchor='ne', x=364, y=0, height=16)

        self.pf_var = tk.DoubleVar()
        pf_data = tk.Label(tr_frame, textvariable=self.pf_var, font= style.FNT_DATA,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height=106)
        pf_data.place(anchor='ne', x=364, y=20, height=106)

        # Frame Mid Right
        mr_frame = tk.Frame(self, width=368, height=130, bg= style.CLR_PRIMARY,
                            highlightthickness=1, highlightcolor= style.CLR_ONBACKGROUND)
        mr_frame.place(anchor='nw', x=384+24, y=138+64)

        watt_txt = tk.Label(mr_frame, text="POWER [W]", font= style.FNT_CAPTION,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height = 16)
        watt_txt.place(anchor='ne', x=364, y=0, height=16)

        self.power_var = tk.DoubleVar()
        watt_data = tk.Label(mr_frame, textvariable=self.power_var, font= style.FNT_DATA,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height=106)
        watt_data.place(anchor='ne', x=364, y=20, height=106)

        # Frame Mid Left
        ml_frame = tk.Frame(self, width=368, height=130, bg= style.CLR_PRIMARY,
                            highlightthickness=1, highlightcolor= style.CLR_ONBACKGROUND)
        ml_frame.place(anchor='nw', x=0+24, y=138+64)

        mf_txt = tk.Label(ml_frame, text="MEAN FORCE [kg]", font= style.FNT_CAPTION,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height = 16)
        mf_txt.place(anchor='ne', x=364, y=0, height=16)

        self.mf_var = tk.DoubleVar()
        mf_data = tk.Label(ml_frame, textvariable=self.mf_var, font= style.FNT_DATA,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height=106)
        mf_data.place(anchor='ne', x=364, y=20, height=106)

        # Frame Bottom
        b_frame = tk.Frame(self, width=750, height= 138, bg=style.CLR_SECONDARY,
                                highlightthickness=1, highlightcolor= style.CLR_ONBACKGROUND)
        b_frame.place(anchor='nw', x=0+24 , y=276+64)

        mf_txt = tk.Label(b_frame, text="FORCE [kg]", font= style.FNT_CAPTION,
                            bg= style.CLR_PRIMARY, fg= style.CLR_ONBACKGROUND, height = 16)
        mf_txt.place(anchor='ne', x=746, y=0, height=16)
        return

    def populate_UI_2users(self):
        # Navigation bar
        self.populate_navigation_bar()

        # Frame Top Left
        clr_tl = style.CLR_GREY75
        tl_frame = tk.Frame(self, width=368, height=130, bg=clr_tl,
                            highlightthickness=0, highlightcolor=style.CLR_BLACK)
        tl_frame.place(anchor='nw', x=24, y=64)

        time_txt = tk.Label(tl_frame, text="TIME [s]", font= style.FNT_CAPTION,
                            bg=clr_tl, fg= style.CLR_ONBACKGROUND, height = 16)
        time_txt.place(anchor='nw', x=4, y=0, height=16)

        self.time_var = tk.DoubleVar()
        time_data = tk.Label(tl_frame, textvariable=self.time_var, font= style.FNT_DATA,
                            bg=clr_tl, fg= style.CLR_ONBACKGROUND, height=106)
        time_data.place(anchor='nw', x=4, y=20, height=106)

        # Frame Top Right
        clr_tr = style.CLR_GREY75
        tr_frame = tk.Frame(self, width=368, height=130, bg=clr_tr,
                            highlightthickness=0, highlightcolor=style.CLR_BLACK)
        tr_frame.place(anchor='nw', x=384+24, y=0+64)

        velocity_txt = tk.Label(tr_frame, text="VELOCITY [m/s]", font= style.FNT_CAPTION,
                            bg=clr_tr, fg= style.CLR_ONBACKGROUND, height = 16)
        velocity_txt.place(anchor='ne', x=364, y=0, height=16)

        self.velocity_var = tk.DoubleVar()
        velocity_data = tk.Label(tr_frame, textvariable=self.velocity_var, font= style.FNT_DATA,
                            bg=clr_tr, fg= style.CLR_ONBACKGROUND, height=106)
        velocity_data.place(anchor='ne', x=364, y=20, height=106)

        # Frame Mid Right
        clr_user2 = style.CLR_PRIMARY
        mr_frame = tk.Frame(self, width=368, height=130, bg=clr_user2,
                            highlightthickness=1, highlightcolor= style.CLR_ONBACKGROUND)
        mr_frame.place(anchor='nw', x=384+24, y=138+64)

        force2_txt = tk.Label(mr_frame, text="FORCE 2 [kg]", font= style.FNT_CAPTION,
                            bg=clr_user2, fg= style.CLR_ONBACKGROUND, height = 16)
        force2_txt.place(anchor='ne', x=364, y=0, height=16)

        self.force2_var = tk.DoubleVar()
        force2_data = tk.Label(mr_frame, textvariable=self.force2_var, font= style.FNT_DATA,
                            bg=clr_user2, fg= style.CLR_ONBACKGROUND, height=106)
        force2_data.place(anchor='ne', x=364, y=20, height=106)

        # Frame Mid Left
        clr_user1 = style.CLR_SECONDARY
        ml_frame = tk.Frame(self, width=368, height=130, bg=clr_user1,
                            highlightthickness=1, highlightcolor= style.CLR_ONBACKGROUND)
        ml_frame.place(anchor='nw', x=0+24, y=138+64)

        force1_txt = tk.Label(ml_frame, text="FORCE 1 [kg]", font= style.FNT_CAPTION,
                            bg=clr_user1, fg= style.CLR_ONBACKGROUND, height = 16)
        force1_txt.place(anchor='nw', x=4, y=0, height=16)

        self.force1_var = tk.DoubleVar()
        force1_data = tk.Label(ml_frame, textvariable=self.force1_var, font= style.FNT_DATA,
                            bg=clr_user1, fg= style.CLR_ONBACKGROUND, height=106)
        force1_data.place(anchor='nw', x=4, y=20, height=106)

        # Frame Bottom Left
        bl_frame = tk.Frame(self, width=368, height=138, bg=clr_user1,
                            highlightthickness=1, highlightcolor=style.CLR_ONBACKGROUND)
        bl_frame.place(anchor='nw', x=0+24, y=276+64)

        pf1_txt = tk.Label(bl_frame, text="PEAKFORCE 1 [kg]", font= style.FNT_CAPTION,
                            bg=clr_user1, fg= style.CLR_ONBACKGROUND, height = 16)
        pf1_txt.place(anchor='nw', x=4, y=0, height=16)

        self.pf1_var = tk.DoubleVar()
        pf1_data = tk.Label(bl_frame, textvariable=self.pf1_var, font= style.FNT_DATA,
                            bg=clr_user1, fg= style.CLR_ONBACKGROUND, height=106)
        pf1_data.place(anchor='nw', x=4, y=20, height=106)

        # Frame Bottom Right
        br_frame = tk.Frame(self, width=368, height=138, bg=clr_user2,
                            highlightthickness=1, highlightcolor= style.CLR_ONBACKGROUND)
        br_frame.place(anchor='nw', x=384+24, y=276+64)

        pf2_txt = tk.Label(br_frame, text="PEAKFORCE 2 [kg]", font= style.FNT_CAPTION,
                            bg=clr_user2, fg= style.CLR_ONBACKGROUND, height = 16)
        pf2_txt.place(anchor='ne', x=364, y=0, height=16)

        self.pf2_var = tk.DoubleVar()
        pf2_data = tk.Label(br_frame, textvariable=self.pf2_var, font= style.FNT_DATA,
                            bg=clr_user2, fg= style.CLR_ONBACKGROUND, height=106)
        pf2_data.place(anchor='ne', x=364, y=20, height=106)
        return

    def display_time(self, time):
        self.time_var.set(round(time,1))

    def display_data_1p(self, data):
        self.force = data[0]
        self.power_var.set(round(data[1], 0))
        self.mf_var.set(round(data[2], 0))
        self.pf_var.set(round(data[3], 0))

    def display_data_2p(self, data):
        self.force1_var.set(round(data[0], 0))
        self.force2_var.set(round(data[1], 0))
        self.velocity_var.set(round(data[2], 2))
        self.pf1_var.set(round(data[3], 0))
        self.pf2_var.set(round(data[4], 0))

    def display_msg(self):
        # Display messagebox
        ctk.set_appearance_mode('light')
        CTkMessagebox(title="Data is being processed",
                          message="Your data is being processed, and can be found in the user profiles once its done",
                          icon='check', option_1='OK')

    def display_errormsg(self):
        # Display messagebox
        ctk.set_appearance_mode('light')
        CTkMessagebox(title="Error",
                          message="No data from peripherals was found, check that the sensors are connected properly and that the peripherals are running",
                          icon='check', option_1='OK')