"""
The Trajectory class that takes the raw trajectory data and automatically processes the data to derive relevant action
measures.

Written by X.M. Wang.

Wang, X.M., & Welsh, T.N. (2023). TAT-HUM: Trajectory Analysis Toolkit for Human Movements in Python.

"""

from .coord import Coord

import numpy as np
from scipy import interpolate
from scipy.signal import butter, filtfilt
from scipy.spatial.transform import Rotation
from skspatial.objects import Plane, Points, Vector
from pytransform3d.rotations import matrix_from_axis_angle
import matplotlib.pyplot as plt

class Trajectory:
    """
    Automatically processes trajectory data.
    """
    x = Coord()
    y = Coord()
    z = Coord()
    time = Coord()

    def __init__(self,
                 x, y, z, time=None,
                 transform_end_points=None,  # end points used for spatial transformation
                 principal_dir='xz',  # 2D plane that specifies the principal direction of the reach
                 primary_dir='z',  # the primary movement direction
                 ground_dir='y',  # the ground's normal direction
                 vel_threshold=50.,
                 time_cutoff=0.2,  # used for finding the start and end positions
                 n_fit=100, fs=250, fc=10, spline_order=3,
                 unit='mm',
                 missing_data_filler=0.,
                 movement_selection_method='length',
                 movement_selection_sign=None,
                 movement_selection_dir=None,
    ):
        """
        :param n_fit: number of fitted time stamps for the B-spline fit.
        :param time: the time stamps, if not supplied will calculate using sampling frequency.
        :param fs: sampling frequency.
        :param fc: cutoff frequency for the low-pass Butterworth filter.
        :param unit: position measurement unit.
        :param x: x coordinate
        :param y: y coordinate
        :param z: z coordinate
        :param time: the corresponding time stamps
        :param transform_end_points: A minimum of three 3D points that specifies the plane on which the movement
        occurred. If provided, the best-fitting plane for these points will be computed and used to transform the
        trajectory so that the transformed movement would take place on a horizontal surface. This could be derived
        using the same Trajectory class.
        :param principal_dir: The principal directions of the movement.
        :param vel_threshold: The velocity threshold to determine movement initiation and termination.
        :param time_cutoff: The amount of time before/after the movement initiation/termination to consider when
        computing the trajectory's end positions. Instead of using the position at a particular time, the end position
        is the average of all positions within this time cutoff range.
        :param mt_threshold: threshold for determining whether the trial contains valid movement. MT below this
        threshold would be considered invalid
        :param n_fit: number of fitted trajectory points when using bspline
        :param fs: sampling frequency
        :param fc: cutoff frequency (for the Butterworth filter)
        :param spline_order: the order of the b-spline fit, default to 3
        :param unit: position measure's unit
        :param missing_data_filler: the filler value for missing data, default to be 0.
        :param movement_selection_method: the method to select the movement segment in case extraneous movements are
        detected. Can be chosen from ('length', 'sign', ). 'length' simply select the movement segment with the most
        number of points, whereas 'sign' selects the movement segment based on movement direction. 'length' is more
        effective for small extraneous movements whereas 'sign' is more effective for movement reversals during the data
        collection period. See movement_selection_sign for more.
        :param movement_selection_sign: can be chosen from ('positive', 'negative'), only applies to directional
        movement. The sign is determined by the difference between the end and start position.
        :param movement_selection_dir: the axis ('x', 'y', 'z') along which the movement selection should be performed
        """
        self.unit = unit
        self.fs = fs
        self.fc = fc
        self.missing_data_filler = missing_data_filler
        self.spline_order = spline_order

        self.x_original, self.y_original, self.z_original = x.copy(), y.copy(), z.copy()  # keep a separate copy of the original data
        self.x, self.y, self.z = x, y, z
        self.n_frames = self.validate_size()
        self.principal_dir = principal_dir
        self.secondary_dir = None
        self.primary_dir = primary_dir
        self.ground_plane = None
        self.ground_dir = ground_dir

        self.movement_selection_method = movement_selection_method
        self.movement_selection_sign = movement_selection_sign
        if self.movement_selection_method == 'sign':
            if self.movement_selection_sign is None:
                raise ValueError('movement_selection_method is set to "sign" but movement_selection_sign was not specified!')
            if movement_selection_dir is None:
                self.movement_selection_dir = self.primary_dir
            else:
                if movement_selection_dir == 'x':
                    self.movement_selection_dir = 0
                elif movement_selection_dir == 'y':
                    self._primary_dir = 1
                elif movement_selection_dir == 'z':
                    self._primary_dir = 2
                else:
                    raise ValueError('Invalid movement_selection_dir! Please use the following: x, y, or z')

        self.contain_movement = True  # whether there was actual movement

        # set the time stamps. If time stamps are not supplied, generate evenly spaced time stamps based on sampling
        # frequency and number of frames.
        if time is not None:
            self.time_original = time
            self.time = time
            if len(self.time) != self.n_frames:
                raise ValueError('The size of the input time stamps is not the same as the size of the coordinates!')
        else:
            self.time = np.linspace(0, self.n_frames * 1 / self.fs, num=self.n_frames, endpoint=False)
            self.time_original = self.time.copy()

        # eliminate missing data; need to do it before the transformation
        self.contain_missing, self.n_missing, self.ind_missing = self.missing_data()

        # transform the data if necessary
        if transform_end_points is not None:
            self.x, self.y, self.z = self.transform_data(self.x, self.y, self.z, transform_end_points)
            self.x_original, self.y_original, self.z_original = self.transform_data(
                self.x_original, self.y_original, self.z_original, transform_end_points)

        # smooth position
        self.x_smooth = self.low_butter_scipy(self.x)
        self.y_smooth = self.low_butter_scipy(self.y)
        self.z_smooth = self.low_butter_scipy(self.z)

        # # parameterize and fit the trajectory
        self.n_frames_fit = n_fit

        # 3d distance to the origin
        self.pos_3d = np.sqrt(self.x_smooth ** 2 + self.y_smooth ** 2 + self.z_smooth ** 2)
        self.vel_3d = self.cent_diff(self.time, self.pos_3d)

        # compute velocity
        self.x_vel = self.cent_diff(self.time, self.x_smooth)
        self.y_vel = self.cent_diff(self.time, self.y_smooth)
        self.z_vel = self.cent_diff(self.time, self.z_smooth)

        # smooth velocity
        self.x_vel_smooth = self.low_butter_scipy(self.x_vel)
        self.y_vel_smooth = self.low_butter_scipy(self.y_vel)
        self.z_vel_smooth = self.low_butter_scipy(self.z_vel)

        # identify movement initiation and termination
        self.start_time, self.end_time, self.movement_ind = self.find_time(vel_threshold)
        if np.isnan(self.start_time) | np.isnan(self.end_time):
            self.contain_movement = False
        elif len(self.movement_ind) <= self.spline_order:  # when few data points are detected
            self.contain_movement = False

        if self.contain_movement:
            self.rt = self.start_time
            self.mt = self.end_time - self.start_time

            self.start_pos, self.end_pos = self.find_start_and_end_pos(time_cutoff)

            # normalize the start and end positions so that the reach starts at the origin
            self.start_pos_norm = self.start_pos - self.start_pos
            self.end_pos_norm = self.end_pos - self.start_pos

            self.movement_time = self.time[self.movement_ind]
            self.x_movement = self.x[self.movement_ind]
            self.y_movement = self.y[self.movement_ind]
            self.z_movement = self.z[self.movement_ind]
            self.x_movement_fit, self.movement_time_fit = self.b_spline_fit_1d(
                self.movement_time, self.x_movement, self.n_frames_fit, full_output=True)
            self.y_movement_fit = self.b_spline_fit_1d(self.movement_time, self.y_movement, self.n_frames_fit)
            self.z_movement_fit = self.b_spline_fit_1d(self.movement_time, self.z_movement, self.n_frames_fit)

            self.x_vel_movement = self.x_vel[self.movement_ind]
            self.y_vel_movement = self.y_vel[self.movement_ind]
            self.z_vel_movement = self.z_vel[self.movement_ind]
            self.x_vel_movement_fit = self.b_spline_fit_1d(self.movement_time, self.x_vel_movement, self.n_frames_fit)
            self.y_vel_movement_fit = self.b_spline_fit_1d(self.movement_time, self.y_vel_movement, self.n_frames_fit)
            self.z_vel_movement_fit = self.b_spline_fit_1d(self.movement_time, self.z_vel_movement, self.n_frames_fit)
        else:
            # in case the trajectory does not satisfy the movement initiation/termination criteria, in cases such as
            # when the participant number moved during the data collection period
            self.rt = np.nan
            self.mt = np.nan

            self.start_pos, self.end_pos = np.empty(3) * np.nan, np.empty(3) * np.nan,
            self.start_pos_norm, self.end_pos_norm = self.start_pos, self.end_pos

            self.movement_time = np.nan
            self.x_fit_trimmed = np.nan
            self.y_fit_trimmed = np.nan
            self.z_fit_trimmed = np.nan

            self.x_movement_fit, self.movement_time_fit = np.nan, np.nan
            self.y_movement_fit = np.nan
            self.z_movement_fit = np.nan

    def find_time(self, vel_threshold, ax=''):
        """
        :param vel_threshold: the velocity threshold, need to be in the same unit as the velocity
        :param ax: the axis used to determine movement initiation and termination. Default is the principal directions
        specified in the constructor. Other values are 'x', 'y', 'z', or 'xyz'
        :return:

        Find the movement initiation and termination time based on the velocity threshold and the velocity axis.
        """
        # determine the velocity axis to use.
        vel_all = np.concatenate([
            np.expand_dims(self.x_vel_smooth, 1),
            np.expand_dims(self.y_vel_smooth, 1),
            np.expand_dims(self.z_vel_smooth, 1),
        ], axis=1)

        if ax == '':  # default is the principal axes
            vel_principal = vel_all[:, self.principal_dir]

            # get the resultant velocity
            vel_eval = np.sqrt(vel_principal[:, 0] ** 2 + vel_principal[:, 1] ** 2)
        elif ax == 'x':
            vel_eval = np.abs(vel_all[:, 0])
        elif ax == 'y':
            vel_eval = np.abs(vel_all[:, 1])
        elif ax == 'z':
            vel_eval = np.abs(vel_all[:, 2])
        elif ax == 'xyz':
            vel_eval = np.sqrt(vel_all[:, 0] ** 2 + vel_all[:, 1] ** 2 + vel_all[:, 2] ** 2)
        else:
            raise ValueError('Unidentified axis! Enter either "" (an empty str), "x", "y", "z", or "xyz"')

        # find movement start and end times
        vel_threshold_ind = np.where(vel_eval >= vel_threshold)[0]

        if len(vel_threshold_ind) == 0:
            # in case there's no movement detected
            return np.nan, np.nan, np.nan

        vel_ind = self.consecutive(vel_threshold_ind)

        # in case there are multiple crossings at the threshold velocity
        if len(vel_ind) > 1:
            if self.movement_selection_method == 'length':
                # only use the portion of movement with the largest number of samples
                vel_len = [len(vel) for vel in vel_ind]
                max_vel = np.where(vel_len == np.max(vel_len))[0][0]
                vel_threshold_ind = vel_ind[max_vel]

            elif self.movement_selection_method == 'sign':
                displacement_all = np.concatenate([
                    np.expand_dims(self.x_smooth, 1),
                    np.expand_dims(self.y_smooth, 1),
                    np.expand_dims(self.z_smooth, 1),
                ], axis=1)

                displacement_eval = displacement_all[:, self.movement_selection_dir]

                movement_dist = []
                for vel in vel_ind:
                    movement_dist.append(displacement_eval[vel[-1]] - displacement_eval[vel[0]])
                movement_dist = np.array(movement_dist)

                if self.movement_selection_sign == 'positive':
                    segment_id = np.where(movement_dist > 0)[0]
                else:
                    segment_id = np.where(movement_dist < 0)[0]

                if len(segment_id) == 1:
                    vel_threshold_ind = vel_ind[segment_id[0]]
                elif len(segment_id) > 1:
                    # get the segment with the most data
                    vel_len = [len(vel_ind[seg_id]) for seg_id in segment_id]
                    max_vel = np.where(vel_len == np.max(vel_len))[0][0]
                    vel_threshold_ind = vel_ind[segment_id[max_vel]]
                else:
                    print('no valid movement detected!')
                    return np.nan, np.nan, np.nan

        move_start_ind = vel_threshold_ind[0] - 1 if vel_threshold_ind[0] > 0 else 0
        move_end_ind = vel_threshold_ind[-1] + 1 if vel_threshold_ind[-1] < self.n_frames - 1 else self.n_frames - 1

        time_start = self.time[move_start_ind]
        time_end = self.time[move_end_ind]

        return time_start, time_end, vel_threshold_ind

    def compute_transformation(self, screen_corners, full_output=False):
        """
        :param screen_corners: the corners of the surface on which the movement was performed
        :param full_output: whether to return full output, which includes the objects for the plane and corners
        :return:
        """
        # center the corners
        screen_center = np.mean(screen_corners, axis=0)
        screen_corners = screen_corners - screen_center

        # find the surface normal
        screen_plane = Plane.best_fit(screen_corners)
        screen_norm = Vector(screen_plane.cartesian()[:3])
        if screen_norm[self.ground_dir] < 0:
            screen_norm = screen_norm * -1

        # project the current screen normal to the ground plane
        screen_norm_ground = self.ground_plane.project_vector(screen_norm)

        # find the angle between the projected norm and the primary direction - this is to align the screen's primary
        # direction with the primary direction in the Cartesian coordinate
        primary_norm = np.zeros(3)
        primary_norm[self.primary_dir] = 1
        angle = screen_norm_ground.angle_between(primary_norm)
        angle = np.pi - angle if angle > np.pi / 2 else angle

        # construct the rotation matrix and rotate the screen normal
        ground_norm = np.zeros(3)
        ground_norm[self.ground_dir] = 1
        rotmat = matrix_from_axis_angle(np.hstack((ground_norm, (angle,))))
        rotation_to_align = Rotation.from_matrix(rotmat)
        screen_norm_rot = Vector(rotation_to_align.apply(screen_norm))

        # after the screen is aligned with the primary axis, we can rotate it around the secondary axis to make the
        # screen surface horizontal
        angle = -screen_norm_rot.angle_between(ground_norm)

        # axis is around the secondary direction
        secondary_norm = np.zeros(3)
        secondary_norm[self.secondary_dir] = 1
        rotmat = matrix_from_axis_angle(np.hstack((secondary_norm, (angle,))))
        rotation_to_ground = Rotation.from_matrix(rotmat)

        # the complete transformation - need to rotate to align first, then rotate to ground
        rotation = rotation_to_ground * rotation_to_align

        screen_corners_rot = Points(rotation.apply(screen_corners)) + screen_center
        screen_plane_rot = Plane.best_fit(screen_corners_rot)

        if full_output:
            return rotation, screen_center, {
                'screen_plane': screen_plane,
                'screen_corners_rot': screen_corners_rot,
                'screen_plane_rot': screen_plane_rot,
            }
        else:
            return rotation, screen_center

    def transform_data(self, x, y, z, screen_corners):
        """
        Spatially transform the trajectory so that the trajectory is on a flat, horizontal plane.
        :param x: x coordinate
        :param y: y coordinate
        :param z: z coordinate
        :param screen_corners: the corners of the screen
        :return:
        """
        rotation, screen_center = self.compute_transformation(screen_corners)
        coord = np.concatenate([np.expand_dims(x, axis=1),
                                np.expand_dims(y, axis=1),
                                np.expand_dims(z, axis=1)], axis=1)
        coord -= screen_center
        coord_rot = rotation.apply(coord)
        return coord_rot[:, 0], coord_rot[:, 1], coord_rot[:, 2]

    def find_start_and_end_pos(self, time_cutoff):
        """

        :param time_cutoff: The amount of time before/after the movement initiation/termination to consider when
        computing the trajectory's end positions. Instead of using the position at a particular time, the end position
        is the average of all positions within this time cutoff range.
        :return: mean_start, mean_end: the start and end positions
        """

        ind_start = (self.time < self.start_time) & (self.time > self.start_time - time_cutoff)
        if np.any(ind_start):
            start_x = self.x[ind_start]
            start_y = self.y[ind_start]
            start_z = self.z[ind_start]
            mean_start = np.mean(np.array([start_x, start_y, start_z]), axis=1)
        else:
            mean_start = np.empty((3,)) * np.nan

        ind_end = (self.time > self.end_time) & (self.time < self.end_time + time_cutoff)
        if np.any(ind_end) > 0:
            end_x = self.x[ind_end]
            end_y = self.y[ind_end]
            end_z = self.z[ind_end]
            mean_end = np.mean(np.array([end_x, end_y, end_z]), axis=1)
        else:
            mean_end = np.empty((3,)) * np.nan

        return mean_start, mean_end

    def validate_size(self):
        """ Validate input coordinate size. """
        n_x, n_y, n_z = len(self.x), len(self.y), len(self.z)
        if not (n_x == n_y == n_z):
            raise ValueError("The input x, y, and z have to be of the same size! \n"
                             f"Instead, len(x)={len(self.x)}, len(y)={len(self.y)}, len(z)={len(self.z)}")
        return n_x

    @staticmethod
    def consecutive(data, step_size=1):
        """ splits the missing data indices into chunks"""
        return np.split(data, np.where(np.diff(data) != step_size)[0] + 1)

    def missing_data(self):
        """
        Find if there is any outliers in the original movement trajectory. The outliers are detected by comparing each
        consecutive points' difference with a certain proportion of the overall range of motion.

        threshold: the threshold for the difference of x, y, and z, before and after the missing data block. If the
        difference is small, then we will use linear interpolation to fill in the gap. By default, the threshold for
        each axis is 1 mm/s.
        """
        # contain_anomolies = False
        missing_ind = np.where(self.x == self.missing_data_filler)[0]
        not_missing_ind = np.where(self.x != self.missing_data_filler)[0]
        if len(missing_ind) > 0:

            f_interp = interpolate.interp1d(self.time[not_missing_ind], self.x[not_missing_ind], bounds_error=False,
                                            fill_value=(np.NaN, np.NaN))
            self.x = f_interp(self.time)

            f_interp = interpolate.interp1d(self.time[not_missing_ind], self.y[not_missing_ind], bounds_error=False,
                                            fill_value=(np.NaN, np.NaN))
            self.y = f_interp(self.time)

            f_interp = interpolate.interp1d(self.time[not_missing_ind], self.z[not_missing_ind], bounds_error=False,
                                            fill_value=(np.NaN, np.NaN))
            self.z = f_interp(self.time)

            ind_delete = np.where(np.isnan(self.x))[0]
            self.x = np.delete(self.x, ind_delete)
            self.y = np.delete(self.y, ind_delete)
            self.z = np.delete(self.z, ind_delete)
            self.time = np.delete(self.time, ind_delete)
            self.n_frames = len(self.x)

            return True, len(missing_ind), missing_ind
        else:
            return False, 0, []

    def low_butter_scipy(self, signal, order=2):
        """
        Direct usage of the low-pass Butterworth Filter using library from SciPy.
        :param signal: 1D data to be filtered
        :param order: butterworth order
        :return: filtered signal
        """
        Wn = self.fc / (self.fs / 2)
        poly = butter(order, Wn, btype='lowpass', output='ba')  # returns numerator [0] and denominator [1] polynomials
        return filtfilt(poly[0], poly[1], signal.copy())

    @staticmethod
    def cent_diff(time, signal):
        """ Central difference method to find derivatives. """
        n_frames = len(time)
        der = np.zeros(n_frames, dtype=float)

        der[0] = (signal[1] - signal[0]) / (time[1] - time[0])
        der[-1] = (signal[-1] - signal[-2]) / (time[-1] - time[-2])

        for i_frame in np.arange(1, n_frames - 1):
            der[i_frame] = (signal[i_frame + 1] - signal[i_frame - 1]) / (
                    time[i_frame + 1] - time[i_frame - 1])

        return der

    @staticmethod
    def b_spline_fit_1d(time_vec, coord, n_fit, smooth=0., full_output=False):
        tck = interpolate.splrep(time_vec, coord,
                                 s=smooth,  # smoothing factor
                                 k=3,  # degree of the spline fit. Scipy recommends using cubic splines.
                                 )
        time_fit = np.linspace(np.min(time_vec), np.max(time_vec), n_fit)
        spline = interpolate.BSpline(tck[0], tck[1], tck[2])
        if full_output:
            return spline(time_fit), time_fit
        else:
            return spline(time_fit)

    def debug_plots(self, fig=None, axs=None):
        """ Create a debug plot that shows displacement, velocity, acceleration, and XY trajectory"""
        if axs is None:
            fig, axs = plt.subplots(2, 1)
            # plt.tight_layout()

        axs[0].plot(self.time_original, self.x_original, label='x', linestyle=':')
        axs[0].plot(self.time_original, self.y_original, label='y', linestyle=':')
        axs[0].plot(self.time_original, self.z_original, label='z', linestyle=':')
        axs[0].scatter(self.time_original[self.ind_missing], self.x_original[self.ind_missing], color='k')

        axs[0].plot(self.time, self.x_smooth, label='x', c='r')
        axs[0].plot(self.time, self.y_smooth, label='y', c='g')
        axs[0].plot(self.time, self.z_smooth, label='z', c='b')

        for principal_dir in self.principal_dir:
            axs[0].plot(self.time, np.ones((len(self.time), 1)) * self.start_pos[principal_dir],
                        c='c', linestyle=':', linewidth=3)
            axs[0].plot(self.time, np.ones((len(self.time), 1)) * self.end_pos[principal_dir],
                        c='m', linestyle=':', linewidth=3)

        axs[0].plot([self.start_time, self.start_time],
                    [np.min([self.x_smooth, self.y_smooth, self.z_smooth]),
                     np.max([self.x_smooth, self.y_smooth, self.z_smooth])], label='start', c='c')
        axs[0].plot([self.end_time, self.end_time],
                    [np.min([self.x_smooth, self.y_smooth, self.z_smooth]),
                     np.max([self.x_smooth, self.y_smooth, self.z_smooth])], label='end', c='m')
        axs[0].set_xlabel('Time (seconds)')
        axs[0].set_ylabel('Displacement')
        # axs[0].set_title(f'{self.n_missing} missing data')
        # axs[0].legend()

        axs[1].plot(self.time, self.x_vel_smooth, label='x', c='r')
        axs[1].plot(self.time, self.y_vel_smooth, label='y', c='g')
        axs[1].plot(self.time, self.z_vel_smooth, label='z', c='b')
        axs[1].plot([self.start_time, self.start_time],
                    [np.min([self.x_vel_smooth, self.y_vel_smooth, self.z_vel_smooth]),
                     np.max([self.x_vel_smooth, self.y_vel_smooth, self.z_vel_smooth])], label='start', c='c')
        axs[1].plot([self.end_time, self.end_time],
                    [np.min([self.x_vel_smooth, self.y_vel_smooth, self.z_vel_smooth]),
                     np.max([self.x_vel_smooth, self.y_vel_smooth, self.z_vel_smooth])], label='end', c='m')

        axs[1].set_xlabel('Time (seconds)')
        axs[1].set_ylabel('Velocity')
        # axs[1].set_title('Velocity')
        # axs[1].legend()

        plt.subplots_adjust(top=0.90, hspace=0.38, left=0.12, bottom=0.12)
        return fig, axs

    def demo_plots(self, fig=None, axs=None):
        if axs is None:
            fig, axs = plt.subplots(1, 1)
            # plt.tight_layout()

        axs.plot(self.time, self.x_smooth, label='x', linewidth=3, c='c')
        axs.plot(self.time, self.y_smooth, label='y', linewidth=3, c='m')
        axs.plot(self.time, self.z_smooth, label='z', linewidth=3, c='y')

        # axs.plot(self.time_original, self.x_original, label='x', linewidth=3, linestyle=':', c='k')
        # axs.plot(self.time_original, self.y_original, label='y', linewidth=3, linestyle=':', c='k')
        # axs.plot(self.time_original, self.z_original, label='z', linewidth=3, linestyle=':', c='k')
        # axs.scatter(self.time_original[self.ind_missing], self.x_original[self.ind_missing], color='k')

        axs.plot([self.start_time, self.start_time],
                 [np.min([self.x_smooth, self.y_smooth, self.z_smooth]),
                  np.max([self.x_smooth, self.y_smooth, self.z_smooth])],
                 label='Movement Start', color='g', linewidth=4, linestyle=':')
        axs.plot([self.end_time, self.end_time],
                 [np.min([self.x_smooth, self.y_smooth, self.z_smooth]),
                  np.max([self.x_smooth, self.y_smooth, self.z_smooth])],
                 label='Movement End', color='r', linewidth=4, linestyle=':')
        axs.set_xlabel('Time (s)', fontdict={'fontsize': 16})
        axs.set_ylabel('Displacement (mm)', fontdict={'fontsize': 16})
        axs.set_xticklabels(axs.get_xticklabels(), fontsize=12)
        axs.set_yticklabels(axs.get_yticklabels(), fontsize=12)
        # axs[0].set_title(f'Displacement, {self.n_missing} missing data')
        axs.legend()

        return fig, axs

    def debug_traj_3d(self, ax=None, color='k'):
        """ Create a debug plot that shows 3d trajectories"""
        if ax is None:
            plt.figure()
            ax = plt.axes(projection='3d')
        else:
            if ax.name != '3d':
                raise ValueError('The input MPL ax has to be a 3D axis! You can simply create an axis with the '
                                 'projection keyword: \n'
                                 'ax = plt.axes(projection=\'3d\')')

        # # ax.plot3D(self.x_smooth, self.y_smooth, self.z_smooth)
        # ax.scatter(self.x_smooth, self.y_smooth, self.z_smooth, c='k')
        # ax.scatter(self.x_smooth[0], self.y_smooth[0], self.z_smooth[0], c='r')  # beginning
        # ax.scatter(self.x_smooth[-1], self.y_smooth[-1], self.z_smooth[-1], c='g')  # end

        ax.plot3D(self.x, self.y, self.z, c=color)
        ax.scatter(self.x[0], self.y[0], self.z[0], c='r')  # beginning
        ax.scatter(self.x[-1], self.y[-1], self.z[-1], c='g')  # end

        ax.set_xlabel('x')
        ax.set_ylabel('y')
        ax.set_zlabel('z')

        return ax

    def debug_traj_2d(self, x_axis, y_axis, var='', ax=None, center=True, full_output=False):
        """
        :param x_axis: the trajectory axis to be plotted on the x-axis of the 2d plot
        :param y_axis: the trajectory axis to be plotted on the y-axis of the 2d plot
        :param var: the variable to be plotted
        :param ax: matplotlib 2d axis object
        :param center: whether to center the data
        :param full_output: if True, will also return plot x and y coordinates
        :return: matplotlib 2d axis object
        """

        def check_axis(axis_name, _var):
            axis_name = axis_name.lower()

            if _var != '':
                _var = f'_{_var}'

            if (axis_name == 'x') | (axis_name == 'y') | (axis_name == 'z'):
                pos = getattr(self, f'{axis_name}{_var}')
            elif axis_name == 'xy':
                pos = np.sqrt((getattr(self, f'x{_var}') ** 2 +
                               getattr(self, f'y{_var}') ** 2))
            elif axis_name == 'xz':
                pos = np.sqrt((getattr(self, f'x{_var}') ** 2 +
                               getattr(self, f'z{_var}') ** 2))
            elif axis_name == 'yz':
                pos = np.sqrt((getattr(self, f'y{_var}') ** 2 +
                               getattr(self, f'z{_var}') ** 2))
            else:
                raise ValueError("Unrecognized trajectory axis name! Only support 1D or 2D axes!")
            return pos - pos[0] if center else pos

        plot_x = check_axis(x_axis, var)
        plot_y = check_axis(y_axis, var)
        line = ax.plot(plot_x, plot_y, alpha=.5)
        ax.scatter(plot_x[0], plot_y[0], c='r')
        ax.scatter(plot_x[-1], plot_y[-1], c='g')

        if full_output:
            return ax, line, plot_x, plot_y
        else:
            return ax, line

    @property
    def principal_dir(self):
        return self._principal_dir

    @principal_dir.setter
    def principal_dir(self, value):
        if value == 'xy':
            self._principal_dir = [0, 1]
        elif value == 'xz':
            self._principal_dir = [0, 2]
        elif value == 'yz':
            self._principal_dir = [1, 2]
        else:
            raise ValueError('Invalid principal directions! Please use the following: '
                             'xy, xz, or yz')

    @property
    def primary_dir(self):
        return self._primary_dir

    @primary_dir.setter
    def primary_dir(self, value):
        if value == 'x':
            self._primary_dir = 0
        elif value == 'y':
            self._primary_dir = 1
        elif value == 'z':
            self._primary_dir = 2
        else:
            raise ValueError('Invalid primary directions! Please use the following: '
                             'x, y, or z')

        self.secondary_dir = list(set(self.principal_dir) - {self.primary_dir})[0]

    @property
    def ground_dir(self):
        return self._ground_dir

    @ground_dir.setter
    def ground_dir(self, value):
        if value == 'x':
            self._ground_dir = 0
        elif value == 'y':
            self._ground_dir = 1
        elif value == 'z':
            self._ground_dir = 2
        else:
            raise ValueError('Invalid principal directions! Please use the following: '
                             'x, y, or z')

        ground_points = np.random.random((3, 3))
        ground_points[:, self._ground_dir] = 0
        self.ground_plane = Plane.best_fit(ground_points)


#!/usr/bin/python3
# -*- coding: utf-8 -*-

from flask import Flask, render_template, session, request, redirect, flash,send_from_directory,send_file
import os
import pickle
import math
import pandas as pd
import numpy as np
from werkzeug.utils import secure_filename

model=pickle.load(open("model_clean_xgboost.sav", "rb"))
UPLOAD_FOLDER = '/home/bdiouf/Bureau/Mastere Spécialisé Big data/Formation MS big data 2020 Télécom Paris/Projet Bearing POint/Livrables école/Période 2/Déploiement sur le web/stockage_csv_web'

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.secret_key = b'012(\xffb\xb4\xd6_\xbe\x16\x10\xb9\x91\x1e\xf1'  #os.urandom(16,seed=2)

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/result', methods=['GET','POST'])
def results():
    if request.method=="POST":
        req=request.form
        missing=[]
        for k,v in req.items():
            if v=="":
                missing.append(k)
        if 'GR' in missing:
            GR=np.nan
        else:
            GR=float(request.form["GR"])
        if 'CAL' in missing:
            CAL=np.nan
        else:
            CAL=float(request.form["CAL"])
        if 'RESD' in missing:
            RESD=np.nan
        else:
            RESD=math.log(float(request.form["RESD"]))
        if 'RESM' in missing:
            RESM=np.nan
        else:
            RESM=math.log(float(request.form["RESM"]))
        if 'PHIN' in missing:
            PHIN=np.nan
        else:
            PHIN=float(request.form["PHIN"])

        df = pd.DataFrame(data=[[GR, PHIN, RESD, RESM,CAL]],columns=["GR","PHIN","RESD","RESM","CAL"])
        col = ["GR","PHIN","RESD","RESM","CAL"]
        X_test = df[col]
        pred=model.predict(X_test)
        proba=model.predict_proba(X_test)
        if pred[0]==0 :
            flash("Avec une probablité de  {} la lithologie est du non argile".format(proba[0,0]))
            return render_template('index.html')
        else:
            flash("Avec une probablité de  {} la lithologie est de l'argile".format(proba[0,1]))
            return render_template('index.html')
    return redirect('index.html')

@app.route("/upload",methods=["GET","POST"])
def upload():
    if request.method=="POST":
        target=app.config['UPLOAD_FOLDER']
        print(target)

        file= request.files['file']
        print(file)
        filename = secure_filename(file.filename)
        destination=os.path.join(app.config['UPLOAD_FOLDER'],"test.csv")
        print(destination)
        file.save(destination)
        return render_template("complete.html")
    return render_template("upload.html")

@app.route("/return_files")
def download():
    data=pd.read_csv(os.path.join(app.config['UPLOAD_FOLDER'],"test.csv"),sep=" ")
    data=data.replace(r'^\s*$', np.nan, regex=True)
    for i in [-9999,-9999.0,-999,-999.0] :
        data=data.replace(i,np.nan,regex=True)
    for i in ['RESD','RESM']:
        for j in range(len(data)):
            if data.loc[j,str(i)]==np.nan and data.loc[j,str(i)] > 0:
                data.loc[j,str(i)]=math.log(data.loc[j,str(i)])
            else:
                data.loc[j,str(i)]=np.nan
    x_test=data[["GR","PHIN","RESD","RESM","CAL"]]
    pred=model.predict(x_test)
    proba=model.predict_proba(x_test)
    proba_sable=pd.DataFrame(proba[:,0],columns=['probablité sable'])
    proba_argile=pd.DataFrame(proba[:,1],columns=['probablité argile'])
    litho_predite=pd.DataFrame(pred,columns=['lithologie prédite'])
    #dict_={"0":"Sable","1":"Argile"}
    #for i in [0,1]:
    #    litho_predite.replace(i,dict_[str(i)])
    result_test=pd.concat([x_test,proba_sable,proba_argile,litho_predite],axis=1)
    result_test.to_csv(os.path.join(app.config['UPLOAD_FOLDER'],"result_test.csv"))
    return send_file('stockage_csv_web/result_test.csv',as_attachment=True) #send_from_directory(directory='stockage_csv_web', filename='result_test.csv"', as_attachment=True)

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

2 - Déploiement sur le web avec Flask/geomodeling.py


# section 1
import random

n = int(input("how many times do you want to roll the dice?: "))
accum = 0

for i in range(n):
    accum += random.randint(1,6)
print("the sum is: ", accum)

# section 2

arr = []
while 1:
    n = input("how many times do you want to roll the dice?: ")
    if (not n.isdigit()):
        break
    arr.append(int(n))
arr.sort(reverse=True)
print("the top 5 values are: ", arr[:5])

# section 3
all_prime_numbers = [2,3]
n = int(input("type in a number to check if its prime: "))
for i in range(2,n+1):
    has_mod = 0
    for j in all_prime_numbers:
        if (i % j == 0):
            has_mod = 1
    if (has_mod != 1):
        all_prime_numbers.append(i)
        has_mod = 0

if  (n in all_prime_numbers):
    print("The number is a prime")
else:
    print("The number is not a prime")

# section 4
arr = []
for i in range(5):
    n = input("type in a city name: ")
    arr.append(n)
print("Tye cities you typed are:")
for i in arr:
    print(i)


from llm import LLMModels
from langchain.agents import Tool
from langchain.tools import DuckDuckGoSearchRun
from langchain.output_parsers import PydanticOutputParser
from langchain.output_parsers import OutputFixingParser
from langchain.prompts import PromptTemplate

from langchain.agents import AgentExecutor
from langchain.schema import SystemMessage
from langchain.agents import OpenAIFunctionsAgent

from .output_parsers import SimilarToolsList
from .prompts import similar_tools_prompt

class SimilarToolsAgent:
    def __init__(self, summary) -> None:
        self.summary = summary
        search = DuckDuckGoSearchRun()
        self.tools = [
            Tool(
                name="search",
                func=search.run,
                description="Useful for when you need to answer questions about current events. You should ask targeted questions",
            ),
        ]
        self.llm = LLMModels.get_chat_model()

    def get_similar_tools(self):
        system_message = SystemMessage(
            content="You are a seasoned online market researcher skilled at efficiently and effectively identifying competitive products through thorough online searches"
        )
        prompt = OpenAIFunctionsAgent.create_prompt(system_message=system_message)
        search_agent = OpenAIFunctionsAgent(
            llm=self.llm, tools=self.tools, prompt=prompt
        )
        agent_executor = AgentExecutor(
            agent=search_agent, tools=self.tools, verbose=True
        )
        parser = PydanticOutputParser(pydantic_object=SimilarToolsList)
        pp = PromptTemplate(
            template=similar_tools_prompt,
            input_variables=["description"],
            partial_variables={"format_instructions": parser.get_format_instructions()},
        )
        gg = agent_executor.run(pp.format_prompt(description=self.summary))
        try:
            similartools = parser.parse(gg)
        except:
            fixing_parser = OutputFixingParser.from_llm(parser=parser, llm=self.llm)
            similartools = fixing_parser.parse(gg)

        return similartools


from rest_framework import serializers

from .models import Student, Officer, Person
from api.auth.serializers import UserSerializer
class PersonSerializer(UserSerializer):

    class Meta:
        model = Person
        fields = ['user_id','first_name', 'last_name', 'phone']
        read_only_fields= ['user_id']
        abstract = True
class StudentSerializer(PersonSerializer):
    class Meta:
        model = Student
        fields = ['user_id','studentID', 'first_name', 'last_name', 'phone','major', 'pages_remaning']
        read_only_fields = ['studentID', 'first_name','last_name','major', 'pages_remaining']
class OfficerSerializer(PersonSerializer):
    class Meta:
        model = Officer
        fields = ['user_id','officerID', 'first_name', 'last_name', 'phone','position']
        read_only_fields = ['officerID', 'position']


import argparse
import difflib
import pathlib
import sys

from ssort._exceptions import ResolutionError
from ssort._ssort import ssort

def _find_files(patterns):
    if not patterns:
        patterns = ["."]

    paths_set = set()
    paths_list = []
    for pattern in patterns:
        path = pathlib.Path(pattern)
        if path.suffix == ".py":
            subpaths = [path]
        else:
            subpaths = list(path.glob("**/*.py"))

        for subpath in sorted(subpaths):
            if subpath not in paths_set:
                paths_set.add(subpath)
                paths_list.append(subpath)

    return paths_list

def main():
    parser = argparse.ArgumentParser(
        description="Sort python statements into dependency order",
    )

    parser.add_argument(
        "--diff",
        dest="show_diff",
        action="store_true",
        help="Prints a diff of all changes ssort would make to a file.",
    )
    parser.add_argument(
        "--check",
        dest="check",
        action="store_true",
        help="Check the file for unsorted statements.  Returns 0 if nothing "
        "needs to be changed.  Otherwise returns 1.",
    )
    parser.add_argument(
        "files", nargs="*", help="One or more python files to sort"
    )

    args = parser.parse_args()

    unsorted = 0
    unsortable = 0
    unchanged = 0

    paths = _find_files(args.files)
    for path in paths:
        original = path.read_text()

        try:
            updated = ssort(original, filename=str(path))

        except ResolutionError as e:
            for req in e.unresolved:
                sys.stderr.write(
                    f"ERROR: unresolved dependency {req.name!r} "
                    + f"in {str(path)!r}: "
                    + f"line {req.lineno}, column {req.col_offset}\n"
                )
            unsortable += 1
            continue

        except SyntaxError as e:
            sys.stderr.write(
                f"ERROR: syntax error in {str(path)!r}: "
                + f"line {e.lineno}, column {e.offset}\n"
            )
            unsortable += 1
            continue

        except Exception as e:
            raise Exception(f"ERROR while sorting {path}\n") from e

        if original != updated:
            unsorted += 1
            if args.check:
                sys.stderr.write(
                    f"ERROR: {str(path)!r} is incorrectly sorted\n"
                )
            else:
                sys.stderr.write(f"Sorting {str(path)!r}\n")
                path.write_text(updated)
        else:
            unchanged += 1

        if args.show_diff:
            sys.stderr.writelines(
                difflib.unified_diff(
                    original.splitlines(keepends=True),
                    updated.splitlines(keepends=True),
                    fromfile=f"{path}:before",
                    tofile=f"{path}:after",
                )
            )

    if args.check:

        def _fmt_count(count):
            return f"{count} file" if count == 1 else f"{count} files"

        summary = []
        if unsorted:
            summary.append(f"{_fmt_count(unsorted)} would be resorted")
        if unchanged:
            summary.append(f"{_fmt_count(unchanged)} would be left unchanged")
        if unsortable:
            summary.append(f"{_fmt_count(unsortable)} would not be sortable")

        sys.stderr.write(", ".join(summary) + "\n")

        if unsorted or unsortable:
            sys.exit(1)

    else:

        def _fmt_count_were(count):
            if count == 1:
                return f"{count} file was"
            else:
                return f"{count} files were"

        summary = []
        if unsorted:
            summary.append(f"{_fmt_count_were(unsorted)} resorted")
        if unchanged:
            summary.append(f"{_fmt_count_were(unchanged)} left unchanged")
        if unsortable:
            summary.append(f"{_fmt_count_were(unsortable)} not sortable")

        sys.stderr.write(", ".join(summary) + "\n")

        if unsortable:
            sys.exit(1)


# coding: utf-8

import pandas as pd
from timeUtils import clock, elapsed, getTimeSuffix, getDateTime, addDays, printDateTime, getFirstLastDay
from pandasUtils import castDateTime, castInt64, cutDataFrameByDate, convertToDate, isSeries, isDataFrame, getColData
from geoUtils import getDist
import geohash

#############################################################################################################################
# Overnight Stays
#############################################################################################################################
def checkStartingLocation(startGeo, prevGeo, gc, debug=False):
    if not all([startGeo, prevGeo]):
        return False

    if startGeo != prevGeo:
        comPrevGeo  = gc.getClusterCoM(prevGeo)
        comStartGeo = gc.getClusterCoM(startGeo)
        dist        = getDist(comPrevGeo, comStartGeo)
        if dist > 500:
            return False

    return True

def getOvernightStays(trips, gc, debug=False):
    if 'Start' not in trips.columns:
        return None

    from pandas import Series
    overnightStays = {}
    trips = trips.sort_values(by="Start", ascending=True, inplace=False)
    trips['start']    = convertToDate(castDateTime(trips['Start']))
    trips['end']      = convertToDate(castDateTime(trips['End']))
    trips['startGeo'] = trips["geo0"]
    trips['endGeo']   = trips["geo1"]

    from collections import Counter
    overnightStays = Counter()

    prevGeo = None
    prevEnd = None
    for tripno, trip in trips.iterrows():
        startGeo = trip['startGeo']
        endGeo   = trip['endGeo']
        overnightStays[startGeo] += 0
        overnightStays[endGeo] += 0

        if debug:
            print("\nTripNo: {0} -----> {1} , {2}, {3}, {4}".format(tripno, startGeo, endGeo, trip['start'], trip['end']))

        if not checkStartingLocation(startGeo, prevGeo, gc, debug):
            prevGeo = endGeo
            prevEnd = trip['end']
            if debug:
                print("  Last Geo and Start Geo are too far apart or one is not recognized. Will not use this data.")
            continue

        dTime = trip['start'] - prevEnd
        days  = dTime.days
        if days >= 1:
            overnightStays[startGeo] += 1
        if debug:
            print("  Overnight Stays at {0} is {1} w/ Days = {2}".format(startGeo, dTime, days))

        prevGeo = endGeo
        prevEnd = trip['end']

    retval = {"Global": len(overnightStays)}
    for geo,cnts in overnightStays.most_common():
        retval[geo] = cnts

    return retval

#############################################################################################################################
# Dwell Time
#############################################################################################################################
def getDwellTimes(trips, gc, debug=False):
    if 'Start' not in trips.columns:
        return None

    from pandas import Series
    dwellTimes = {}
    trips = trips.sort_values(by="Start", ascending=True, inplace=False)
    trips['start']    = castDateTime(trips['Start'])
    trips['end']      = castDateTime(trips['End'])
    trips['startGeo'] = trips["geo0"]
    trips['endGeo']   = trips["geo1"]

    dwellData = []

    prevGeo = None
    prevEnd = None
    for tripno, trip in trips.iterrows():
        startGeo = trip['startGeo']
        endGeo   = trip['endGeo']

        if debug:
            print("\nTripNo: {0} -----> {1} , {2}, {3}, {4}".format(tripno, startGeo, endGeo, trip['start'], trip['end']))

        if not checkStartingLocation(startGeo, prevGeo, gc, debug):
            prevGeo = endGeo
            prevEnd = trip['end']
            if debug:
                print("  Last Geo and Start Geo are too far apart or one is not recognized. Will not use this data.")
            continue

        dTime = trip['start'] - prevEnd
        hours = dTime.seconds/3600
        if hours < 24:
            if dwellTimes.get(startGeo) is None:
                dwellTimes[startGeo] = []
            dwellTimes[startGeo].append(hours)
            dwellData.append(hours)

            if debug:
                print("  Dwell Time at {0} is {1} w/ Hours = {2}".format(startGeo, dTime, hours))

        prevGeo = endGeo
        prevEnd = trip['end']

    retval = {"Global": Series(dwellData).mean()}
    sigval = {}
    for geo in dwellTimes.keys():
        if len(dwellTimes[geo]) >= 1:
            dts = Series(dwellTimes[geo])
            dwellTimes[geo] = [dts.size, dts.mean(), dts.std()]
            retval[geo]     = dwellTimes[geo][1]
        else:
            dwellTimes[geo] = [None, None, None]
            retval[geo]     = None

    return retval

#############################################################################################################################
# Get Daily Visits
#############################################################################################################################
def getDailyVisits(trips, debug=False):
    if 'Start' not in trips.columns:
        return None

    dvData = {}
    from pandas import to_datetime
    trips['Date'] = to_datetime(trips['Start']).dt.date
    for tripno, trip in trips.iterrows():
        startGeo = trip['geo0']
        endGeo   = trip['geo1']
        if dvData.get(startGeo) is None:
            dvData[startGeo] = set()
        if dvData.get(endGeo) is None:
            dvData[endGeo] = set()

        sData = trip['Date']
        dvData[startGeo].add(sData)
        dvData[endGeo].add(sData)

    dvData = {k: len(v) for k,v in dvData.items()}
    return dvData

#############################################################################################################################
# Get Common Location
#############################################################################################################################
def getCommonLocation(trips, debug=False):
    startGeo = trips["geo0"]
    endGeo   = trips["geo1"]
    from pandas import concat
    try:
        visits = concat([startGeo, endGeo], axis=0).reset_index(drop=True).value_counts()
        visits = dict(visits)
    except:
        visits = None
        raise ValueError("Could not create ordered list of geos for last place/first place")

    retval = visits
    return retval

#############################################################################################################################
# Guess Home
#############################################################################################################################
def getHome(dailyVisits, overnightStays, dwellTimes, commonLocation, debug=False, verydebug=False):
    if debug:
        print("Deriving Home From Daily Visits, Overnight Stays, Dwell Times, and Common Location")

    if all([dailyVisits, overnightStays, dwellTimes]):
        ## Possible clusters come from overnight stays
        possibleDTCls = [k for k,v in dwellTimes.items() if v > 0]
        if debug:
            print("There are {0} possible home clusters".format(len(dwellTimes)))
            if verydebug:
                print("  CLs: {0}".format(possibleDTCls))

        ## Require at least two overnight stays for home
        possibleDTCls = [k for k,v in dwellTimes.items() if v >= 2]
        if debug:
            print("There are {0} possible home clusters with at least two hours of dwell time".format(len(possibleDTCls)))
            if verydebug:
                print("  CLs: {0}".format(possibleDTCls))

        ## Require at least ten daily visits for home
        possibleDVCls = [k for k,v in dailyVisits.items() if v >= 10]
        if debug:
            print("There are {0} possible home clusters with at least ten daily visits".format(len(possibleDVCls)))
            if verydebug:
                print("  CLs: {0}".format(possibleDVCls))

        ## Rank remaining cluster dwell times
        dts = {}
        for cl,dt in overnightStays.items():
            if cl in possibleDTCls and cl in possibleDVCls and dt > 0:
                dts[cl] = dt

        from pandas import Series
        dts = Series(dts)
        dts.sort_values(ascending=False, inplace=True)
        if debug:
            print("There are {0} possible home clusters with overnight stays".format(dts.count()))
            if verydebug:
                print("  CLs: {0}".format(possibleDVCls))

        if verydebug:
            print("  Ranked List:")
            print("{0}".format(dts))

        possibleHomes  = dts.count()
        try:
            homeCl     = dts.index[0]
        except:
            homeCl     = None

        try:
            nextCl     = dts.index[1]
            homeRatio  = round(dts[homeCl]/dts[nextCl],1)
        except:
            homeRatio  = None

        if debug:
            print("Selecting {0} as the home cluster with significance {1}, {2} overnight stays, {3} daily visits, and {4} dwell time hours.".format(homeCl, homeRatio, overnightStays[homeCl], dailyVisits[homeCl], round(dwellTimes[homeCl],1)))
        retval = {"GeoID": homeCl, "Vtx": None, "Ratio": homeRatio, "Days": dailyVisits[homeCl], "Possible": possibleHomes}

    else:
        from pandas import Series
        dts = Series(commonLocation)
        dts.sort_values(ascending=False, inplace=True)

        try:
            homeCl     = dts.index[0]
        except:
            homeCl     = None

        try:
            nextCl     = dts.index[1]
            homeRatio  = round(dts[homeCl]/dts[nextCl],1)
        except:
            homeRatio  = None

        if debug:
            print("Selecting {0} as the home cluster with the most common location.".format(homeCl))
        retval = {"GeoID": homeCl, "Vtx": None, "Ratio": homeRatio, "Days": None, "Possible": 1}

    return retval


import pandas as pd
import numpy as np

train_data = pd.read_csv('kc_house_train_data.csv')
test_data = pd.read_csv('kc_house_test_data.csv') #dataframe

input_feature = train_data['sqft_living']
sqft_living_lst = [i for i in train_data['sqft_living']] # seriers converts into lst
sqft_living_array = np.array(sqft_living_lst) #lst converts into array

output = train_data['price']
price_lst = [i for i in train_data['price']]
price_array = np.array(price_lst)
#print(price_array)

def simple_linear_regression(input_feature,output):
    numerator = (input_feature * output).mean(axis =0) - (input_feature.mean(axis =0))*(output.mean(axis=0)) #axis = 0  work on the row
    denominator =(input_feature**2).mean(axis=0) - (input_feature.mean(axis=0))*(input_feature.mean(axis=0))
    slope = numerator/ denominator
    intercept = output.mean(axis= 0) - slope *(input_feature.mean(axis=0))
    return slope, intercept
slope_train,intercept_train = simple_linear_regression(sqft_living_array, price_array)

def get_regression_predictions(input_feature,slope, intercept):
    predicted_output = intercept + input_feature * slope
    return predicted_output

'''Quiz Question: Using your Slope and Intercept from (4), What is the predicted price for a house with 2650 sqft?'''
print(get_regression_predictions(2650,slope_train,intercept_train))
'''What is the RSS for the simple linear regression using squarefeet to predict prices on TRAINING data'''
def get_residual_sum_of_squares(input_feature, output, intercept,slope):
    RSS =(((intercept + input_feature * slope)- output)**2).sum(axis=0)
    return RSS

print(get_residual_sum_of_squares(sqft_living_array,price_array,intercept_train,slope_train))

'''Quiz Question: According to this function and the slope and intercept from
(4) What is the RSS for the simple linear regression using squarefeet to predict prices on TRAINING data?'''

def inverse_regression_predictions(output, intercept, slope):
    estimated_input = (output - intercept) / slope
    return(estimated_input)

'''According to this function and the regression slope and intercept from (3) what is the estimated square-feet for a house costing $800,000?'''

#print(inverse_regression_predictions(800000,intercept_train,slope_train))

'''Which model (square feet or bedrooms) has lowest RSS on TEST data? Think about why this might be the case.'''
sqft_living_array_test = np.array([ i for i in test_data['sqft_living']])
bedrooms_array_test = np.array([i for i in test_data['bedrooms']])
price_array_test = np.array([i for i in test_data['price']])

rss_sqft =get_residual_sum_of_squares(sqft_living_array_test,price_array_test,intercept_train,slope_train)
#print('rss_sqft:', rss_sqft)

bed_rss = get_residual_sum_of_squares(bedrooms_array_test,price_array_test,intercept_train,slope_train)
print('bed_rss:',bed_rss)

print (rss_sqft - bed_rss)

'''my_file = open('my_file.csv','w')
my_file.write(str(bed_rss))
my_file.close()'''


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 13 11:00:27 2018

@author: sage
"""
from sklearn.model_selection import train_test_split
from DataLoaders.DataPoint import DataPoint
from sklearn.model_selection import KFold
import numpy as np
import os

class DataLoader():
    '''Abstract DataLoader Class'''

    def __init__(self,
                 init_location,
                 label_location,
                 in_memory=True,
                 memory_loc=None,
                 compress=False,
                 preloaded=False,
                 ):

        '''
        init_location - Location of the raw data files.
        label_location - Location of the label file/folder.
        in_memory - Flag to determine if the data should be loaded into memory
                    or if it should be saved to disk.
        memory_loc - If saved to disk, location to save to.
        compress - Flag to determine if the data should be saved in a
                   compressed form.
        preloaded - Flag to indicate if data has already been saved in temp mem spot
        '''

        self.init_location = os.path.abspath(init_location)
        self.label_location = os.path.abspath(label_location)

        self.in_memory = in_memory
        self.memory_loc = memory_loc
        self.compress = compress
        self.preloaded = preloaded

        self.data_points = []

        self.kf_train_splits = []
        self.kf_test_splits = []

    def load_labels(self):
        pass

    def load_data(self):
        pass

    def load_new(self):
        pass

    def load_unseen(self):
        self.load_new()

        return self.data_points

    def create_data_point(self, name, label, slc=None):

        if type(label) == list:

            dp = DataPoint(
                name = name,
                label = label[0],
                extra = label[1:],
                in_memory = self.in_memory,
                memory_loc = self.memory_loc,
                compress = self.compress,
                slc = slc )

        else:

            dp = DataPoint(
                    name = name,
                    label = label,
                    in_memory = self.in_memory,
                    memory_loc = self.memory_loc,
                    compress = self.compress,
                    slc = slc )

        return dp

    def get_unique_patients(self):

        patients = sorted(list(set([dp.get_patient() for dp in self.data_points])))
        return np.array(patients)

    def get_data_points_by_patient(self, patients):

        relevant = []

        for dp in self.data_points:
            if dp.get_patient() in patients:
                relevant.append(dp)

        return relevant

    def load_all(self):

        self.load_labels()
        self.load_data()

    def get_all(self):
        '''Return just one set, for just train'''

        self.load_all()

        return self.data_points

    def get_train_test_split(self, test_size, seed):

        self.load_all()
        patients = self.get_unique_patients()

        train_patients, test_patients = train_test_split(patients,
                                                         test_size=test_size,
                                                         random_state=seed)

        train = self.get_data_points_by_patient(train_patients)
        test = self.get_data_points_by_patient(test_patients)

        return train, test

    def get_train_test_val_split(self, test_size, val_size, seed):

        self.load_all()
        patients = self.get_unique_patients()

        train_patients, test_patients = train_test_split(patients,
                                                         test_size=test_size,
                                                         random_state=seed)
        train_patients, val_patients = train_test_split(train_patients,
                                                        test_size=val_size,
                                                        random_state=seed)

        train = self.get_data_points_by_patient(train_patients)
        test = self.get_data_points_by_patient(test_patients)
        val = self.get_data_points_by_patient(val_patients)

        return train, test, val

    def setup_kfold_splits(self, n_splits, seed):
        '''Preforms a kfold val_split by patient, and stores the splits.'''

        self.load_all()
        patients = self.get_unique_patients()

        kf = KFold(n_splits=n_splits, random_state=seed)

        for train_patients, test_patients in kf.split(patients):
            self.kf_train_splits.append(patients[train_patients])
            self.kf_test_splits.append(patients[test_patients])

    def get_k_split(self, ind):

        train_patients = self.kf_train_splits[ind]
        test_patients = self.kf_test_splits[ind]

        train = self.get_data_points_by_patient(train_patients)
        test = self.get_data_points_by_patient(test_patients)

        return train, test


import random

from selenium import webdriver
from selenium.webdriver.common.by import By

month = "07"
day = "2"
proguide_url = "https://proguide.co.kr/best-starbucks-tumbler/"
keyword = "텀블러"
keyword_en = "best-tumbler"
detail_2_contents_order = [0,1,2,3]
itemList = [
    ["텀스 뉴메가 진공 스텐텀블러 3종",
     "https://link.coupang.com/a/2JUDm"],
    ["스타벅스 스트랩 텀블러 473ml",
     ""],
    ["",
     ""],
    ["",
     ""],
    ["",
     ""],
    ["",
     ""],
    ["",
     ""],
]
# none: 1
itemOrdering = [3, 0, 2, 4,  5, 6]

driver = webdriver.Chrome()
driver.get(proguide_url)

title = driver.find_element(By.CLASS_NAME, "entry-title").text
entry_content_list = [x.text for x in driver.find_elements(By.XPATH, "//div/div/p") if x != ""][:4]
detail_1_item_award = [x.text for x in driver.find_elements(By.CLASS_NAME, "ptp-table-award")]
detail_1_item_title = [x.text for x in driver.find_elements(By.CLASS_NAME, "ptp-table-title")]
detail_1_item_feature_list = [[y.get_attribute('outerHTML') for y in x.find_elements(By.TAG_NAME, "li")] for x in
                              driver.find_elements(By.CLASS_NAME, "ptp-table-features-list")]

detail_2_subtitle = [x.text for x in driver.find_elements(By.CLASS_NAME, "heading-list")]
detail_2_contents = [[y.get_attribute('outerHTML') for y in x.find_elements(By.TAG_NAME, "li")] for x in
                     driver.find_elements(By.CLASS_NAME, "arrow-pink")]

detail_3_title = driver.find_element(By.ID, "q2").text
detail_3_intro = [
    [y.get_attribute('outerHTML') for y in x.find_element(By.TAG_NAME, 'ul').find_elements(By.TAG_NAME, 'li')] for x in
    driver.find_elements(By.CLASS_NAME, "product-introduction")]
detail_3_cons = [x.find_element(By.TAG_NAME, 'li').text for x in driver.find_elements(By.CLASS_NAME, "con-box")]
detail_3_table = [x.find_element(By.TAG_NAME, 'table').get_attribute('outerHTML') for x in
                  driver.find_elements(By.CLASS_NAME, "product-spec-table")]

detail_0_ul_hey = ""
for i in itemOrdering:
    detail_0_ul_hey += "
" + itemList[i][0] + "
\n"

detail_1_raw = f"""

DETAIL_1_AWARD

DETAIL_1_ITEM_NAME

DETAIL_1_FEATURE_1

DETAIL_1_FEATURE_2

DETAIL_1_FEATURE_3

              최저가보기

"""
detail_1_hey = ""
for i in itemOrdering:
    lastFeature = ""
    if len(detail_1_item_feature_list[i]) > 2:
        lastFeature = detail_1_item_feature_list[i][2]

    detail_1_hey += detail_1_raw.replace("DETAIL_1_AWARD", detail_1_item_award[i]) \
        .replace("DETAIL_1_FEATURE_1", detail_1_item_feature_list[i][0]) \
        .replace("DETAIL_1_FEATURE_2", lastFeature) \
        .replace("DETAIL_1_FEATURE_3", detail_1_item_feature_list[i][1]).replace("DETAIL_1_ITEM_NAME", itemList[i][0]) \
        .replace("DETAIL_1_IMG_NAME", keyword_en + "_" + str(i)).replace("DETAIL_1_URL", itemList[i][1])
    detail_1_hey += "\n"

detail_2_h3_raw = """
INDEX_HEY. SUBTITLE_HEY
\n"""
detail_2_hey = ""
detail_2_content_idx = 0
for i in range(len(detail_2_subtitle)):
    detail_2_hey += detail_2_h3_raw.replace("INDEX_HEY", str(i + 1)).replace("SUBTITLE_HEY", detail_2_subtitle[i][3:])
    if i in detail_2_contents_order:
        now_detail_2_contents = detail_2_contents[detail_2_content_idx]
        random.shuffle(now_detail_2_contents)
        detail_2_hey += '
' + "\n".join(
            now_detail_2_contents) + "
"
        detail_2_content_idx += 1
    else:
        detail_2_hey += "
HEY
\n"

detail_3_raw = f"""

                INDEX. DETAIL_3_ITEM_TITLE

💡 DETAIL_3_ITEM_AWARD

최저가 보기

            DETAIL_3_INTRO

장점

DETAIL_3_FEATURE_1

DETAIL_3_FEATURE_2

DETAIL_3_FEATURE_3

단점

DETAIL_3_CON

제품
                상세표

              DETAIL_3_TABLE

            """
detail_3_hey = ""
index_hey = 0
for i in itemOrdering:
    detail_3_intro_shuffled = detail_3_intro[i].copy()
    random.shuffle(detail_3_intro_shuffled)
    index_hey += 1

    lastFeature = ""
    if len(detail_1_item_feature_list[i]) > 2:
        lastFeature = detail_1_item_feature_list[i][2]

    detail_3_hey += detail_3_raw.replace("DETAIL_3_URL", itemList[i][1]) \
        .replace("DETAIL_3_ITEM_AWARD", detail_1_item_award[i]) \
        .replace("DETAIL_3_IMG_NAME", keyword_en + "_" + str(i)) \
        .replace("DETAIL_3_ITEM_TITLE", itemList[i][0]) \
        .replace("INDEX", str(index_hey)) \
        .replace("DETAIL_3_INTRO", "\n".join(detail_3_intro_shuffled)) \
        .replace("DETAIL_3_FEATURE_1", detail_1_item_feature_list[i][0]) \
        .replace("DETAIL_3_FEATURE_2", lastFeature) \
        .replace("DETAIL_3_FEATURE_3", detail_1_item_feature_list[i][1]) \
        .replace("DETAIL_3_CON", detail_3_cons[i]) \
        .replace("DETAIL_3_TABLE", detail_3_table[i])

f = open("output_html/rank-guide-detail-raw.html", "r")
lines = f.readlines()
replaced_lines = [x.replace("TITLE_HEY", title).replace("KEYWORD_HEY", keyword)
                      .replace("DETAIL_0_UL_HEY", detail_0_ul_hey)
                      .replace("KEYWORD_EN_HEY", keyword_en)
                      .replace("DETAIL_1_HEY", detail_1_hey)
                      .replace("DETAIL_2_HEY", detail_2_hey)
                      .replace("DETAIL_3_HEY", detail_3_hey)
                      .replace("MONTH_HEY", month)
                      .replace("DAY_HEY", day)
                  for x in lines]

f.close()

new_f = open("rank-guide-detail-" + keyword + ".html", "w")
new_f.writelines(replaced_lines)
new_f.close()


from tkinter import *

window = Tk()
window.title('check button')

window.geometry('500x500')

def click():
	out = 'Result : ' + format(chk.get())
	label1.configure(text = out)

chk = BooleanVar();

tick = Checkbutton(window, text = 'accept privacy policy', font = ('Arial', 15), command = click, variable = chk)
tick.grid(row = 0, column = 0)

label1 = Label(window, font = ('Arial', 15))
label1.grid(row = 2, column = 0)

window.mainloop()


import torch
import torch.nn as nn
import torch.utils.model_zoo as model_zoo
import torchvision
from .mixstyle import MixStyle
from torch.nn import functional as F

class Convolution(nn.Module):

    def __init__(self, c_in, c_out):
        super().__init__()
        self.conv = nn.Conv2d(c_in, c_out, 3, stride=1, padding=1)
        self.relu = nn.ReLU(True)

    def forward(self, x):
        return self.relu(self.conv(x))

class CNN_Digits(nn.Module):

    def __init__(self, c_hidden=64, ms_layers=[], ms_p=0.5, ms_a=0.1):
        super().__init__()
        self.conv1 = Convolution(3, c_hidden)
        self.conv2 = Convolution(c_hidden, c_hidden)
        self.conv3 = Convolution(c_hidden, c_hidden)
        self.conv4 = Convolution(c_hidden, c_hidden)
        self.mixstyle = None
        if ms_layers:
            self.mixstyle = MixStyle(p=ms_p, alpha=ms_a)
            for layer_name in ms_layers:
                assert layer_name in ['layer1', 'layer2', 'layer3']
            print(f'Insert MixStyle after {ms_layers}')
        self.ms_layers = ms_layers

        self.fdim = 2**2 * c_hidden

    def _check_input(self, x):
        H, W = x.shape[2:]
        assert H == 32 and W == 32, \
            'Input to network must be 32x32, ' \
            'but got {}x{}'.format(H, W)

    def forward(self, x):
        self._check_input(x)
        x = self.conv1(x)
        x = F.max_pool2d(x, 2)
        if 'layer1' in self.ms_layers:
            x = self.mixstyle(x)
        x = self.conv2(x)
        x = F.max_pool2d(x, 2)
        if 'layer2' in self.ms_layers:
            x = self.mixstyle(x)
        x = self.conv3(x)
        x = F.max_pool2d(x, 2)
        if 'layer3' in self.ms_layers:
            x = self.mixstyle(x)
        x = self.conv4(x)
        x = F.max_pool2d(x, 2)
        return x.view(x.size(0), -1)


import argparse

parser = argparse.ArgumentParser()
parser.add_argument("file", help="display number of chars, words and lines of given file", type=argparse.FileType("r"))
parser.add_argument("-l", help="returns only number of lines of given file", dest='print_lines', action="store_true", default=False)
parser.add_argument("-w", help="returns only number of words of given file", dest='print_words', action="store_true", default=False)
parser.add_argument("-c", help="returns only number of chars of given file", dest='print_chars', action="store_true", default=False)
args = parser.parse_args()

def count_lines(file):
    counter = 0
    file.seek(0)
    for line in file:
        counter += 1
    return counter

def count_chars(file):
    counter = 0
    file.seek(0)
    for line in file:
        counter += len(line)
    return counter

def count_words(file):
    counter = 0
    file.seek(0)
    for line in file:
        in_the_middle_of_word = False
        for letter in line:
            if letter == ' ' and in_the_middle_of_word is True:
                counter += 1
                in_the_middle_of_word = False
            elif not letter.isspace():
                in_the_middle_of_word = True
        if in_the_middle_of_word is True:
            counter += 1
    return counter

def handler(arguments):
    if arguments.print_lines is False and arguments.print_words is False and arguments.print_chars is False:
        arguments.print_lines = True
        arguments.print_words = True
        arguments.print_chars = True
    if arguments.print_chars is True:
        print("Number of characters: %s" % str(count_chars(arguments.file)))
    if arguments.print_lines is True:
        print("Number of lines: %s" % str(count_lines(arguments.file)))
    if arguments.print_words is True:
        print("Number of words: %s" % str(count_words(arguments.file)))
    print(arguments.file.name)

handler(args)


from django.core.cache import cache

from apps.blog.models import Blog
from config.settings import CACHE_ENABLED

def blog_caching(pk):
    if CACHE_ENABLED:
        key = f'mailing_settings_list_{pk}'
        blog_cache = cache.get(key)
        if blog_cache is None:
            blog_cache = Blog.objects.filter(pk=pk)
            cache.set(key, blog_cache)
    else:
        blog_cache = Blog.objects.filter(pk=pk)
    return blog_cache


from logging import Logger

import ideavirtualdesktopcontroller
from ideavirtualdesktopcontroller.app.app_protocols import VirtualDesktopNotifiableDBProtocol
from ideavirtualdesktopcontroller.app.clients.events_client.events_client import VirtualDesktopEvent, VirtualDesktopEventType

class VirtualDesktopNotifiableDB(VirtualDesktopNotifiableDBProtocol):
    def __init__(self, context: ideavirtualdesktopcontroller.AppContext, table_name: str, logger: Logger):
        self.context = context
        self._logger = logger
        self._table_name = table_name
        self.sqs_client = self.context.aws().sqs()

    def trigger_delete_event(self, hash_key: str, range_key: str, deleted_entry: dict):
        self.context.events_client.publish_event(
            event=VirtualDesktopEvent(
                event_group_id=f'{hash_key}-{range_key}',
                event_type=VirtualDesktopEventType.DB_ENTRY_DELETED_EVENT,
                detail={
                    'hash_key': hash_key,
                    'range_key': range_key,
                    'deleted_value': deleted_entry,
                    'table_name': self._table_name
                }
            )
        )

    def trigger_create_event(self, hash_key: str, range_key: str, new_entry: dict):
        self.context.events_client.publish_event(
            event=VirtualDesktopEvent(
                event_group_id=f'{hash_key}-{range_key}',
                event_type=VirtualDesktopEventType.DB_ENTRY_CREATED_EVENT,
                detail={
                    'hash_key': hash_key,
                    'range_key': range_key,
                    'new_value': new_entry,
                    'table_name': self._table_name
                }
            )
        )

    def trigger_update_event(self, hash_key: str, range_key: str, old_entry: dict, new_entry: dict):
        self.context.events_client.publish_event(
            event=VirtualDesktopEvent(
                event_group_id=f'{hash_key}-{range_key}',
                event_type=VirtualDesktopEventType.DB_ENTRY_UPDATED_EVENT,
                detail={
                    'hash_key': hash_key,
                    'range_key': range_key,
                    'old_value': old_entry,
                    'new_value': new_entry,
                    'table_name': self._table_name
                }
            )
        )


import pygame
from pygame.sprite import Sprite

class Ship(Sprite):

    def __init__(self, ai_settings, screen):
        """初始化飞船并设置初始位置"""
        super().__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        # 加载飞船图像并获取其外形矩形
        self.image = pygame.image.load('images/ship.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # 将每一艘新的飞船都放在屏幕底部中央
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        # attribute center save float
        self.center = float(self.rect.centerx)

        # moving sign
        self.moving_right = False
        self.moving_left = False

    def update(self):
        """根据moving sign来调整飞船的坐标"""
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.ship_speed_factor

        # pass value of self.center to self.centerx
        self.rect.centerx = self.center

    def blitme(self):
        """在指定位置绘制飞船"""
        self.screen.blit(self.image, self.rect)

    def center_ship(self):
        """put ship at the center of screen"""
        self.center = self.screen_rect.centerx


switches = ["buitenlamp_spots", "buitenlamp_vlonder", "christmas_tree_relay", "exhaust_light", "hal_lamp", "led_strip", "side_lights"]
lights = ["achterkamer", "rotsverlichting", "voorkamer"]
covers = ["cover.shutter_back", "cover.shutter_front", "cover.shutter_kitchen"]

# First, check time to determine button behavior

current_time = datetime.datetime.now()

if current_time.hour >= 5 and current_time.hour <= 15:
    # It's morning, so open all shutters
    for cover in covers:
        state = hass.states.get(cover).state
        if state == 'closed':
            service_data = {'entity_id': cover}
            hass.services.call('cover', 'open_cover', service_data)

else:
    # It's evening, so close all covers, turn off lights & turn off the tv
    # check states of 2 door sensors and attic window sensor

    kitchen_sensor = hass.states.get('binary_sensor.kitchen_door').state
    living_door_sensor = hass.states.get('binary_sensor.living_door').state
    attic_sensor = hass.states.get('binary_sensor.attic_window').state

    if kitchen_sensor == 'on' or living_door_sensor == 'on' or attic_sensor == 'on':
        open_doors = ""
        if kitchen_sensor == 'on':
            open_doors += 'Keukendeur, '
        if living_door_sensor == 'on':
            open_doors +=  'Achterkamer deur, '
        if attic_sensor == 'on':
            open_doors += 'Zolderraam '
        message = f'{open_doors} staan nog open!'
        service_data = {'message': message, 'title': 'Er staat nog iets open!'}
        hass.services.call('notify', 'mobile_app_sm_g973f', service_data)
        hass.services.call('notify', 'mobile_app_sm_g981b', service_data)

    if kitchen_sensor != 'on' and living_door_sensor != 'on':
        service_data = {'message': 'Alles is dicht, welterusten!', 'title': 'Welterusten'}
        hass.services.call('notify', 'mobile_app_sm_g973f', service_data)
        hass.services.call('notify', 'mobile_app_sm_g981b', service_data)
        for cover in covers:
            state = hass.states.get(cover).state
            if state == 'open':
                service_data = {'entity_id': cover}
                hass.services.call('cover', 'close_cover', service_data)

        for switch in switches:
            entity_id = 'switch.' + switch
            service_data = {'entity_id': entity_id}
            hass.services.call('switch','turn_off', service_data)

        for light in lights:
            entity_id = 'light.' + light
            service_data = {'entity_id': entity_id}
            hass.services.call('light','turn_off', service_data)

        tv_state = hass.states.get('media_player.lg_tv')
        if tv_state != 'off':
            service_data = {'entity_id': 'media_player.lg_tv'}
            hass.services.call('media_player', 'turn_off', service_data)


#!/usr/bin/env python3

from os.path import basename, splitext
from sys import argv

from matplotlib import pyplot as plt

import numpy as np

from misc import COLORS

name = splitext(basename(argv[0]))[0]

data = np.loadtxt('{}.data'.format(name))
dts = np.sort(np.unique(data[:, 0]))
ts = np.sort(np.unique(data[:, 1]))

mass = 0.0005485799  # g/mol
omega = 0.13092033091438  # 1/ps
init_p = -5e-3  # g nm/ps mol
init_q = 50.  # nm

exact_ps = np.cos(omega * ts) * init_p - mass * omega * np.sin(omega * ts) * init_q  # g nm/ps mol
exact_qs = np.sin(omega * ts) * init_p / (mass * omega) + np.cos(omega * ts) * init_q  # nm

plt.plot(exact_qs, exact_ps, linestyle='dashed', linewidth=2, color='black')

for i, dt in enumerate(dts):
    d = data[data[:, 0] == dt]
    ps = d[:, 2]
    qs = d[:, 3]

    plt.plot(qs, ps, color=COLORS[i], label='$\Delta t^\star = \SI{' + str(dt) + '}{\pico\second}$')

fig = plt.gcf()
fig.set_size_inches(10, 5)

plt.title(r'Phase space of harmonic oscillator trajectories')
plt.xlabel(r'$q / \si{\nano\meter}$')
plt.ylabel(r'$p / \si{\gram\nano\meter\per\pico\second\per\mole}$')

plt.legend()

plt.savefig('{}.pdf'.format(name), bbox_inches='tight')


import pytest
from django.contrib.admin.sites import AdminSite
from django.test import TestCase
from django.utils.safestring import mark_safe

from rard.research.admin import SymbolAdmin
from rard.research.models import Symbol

pytestmark = pytest.mark.django_db

class TestSymbolAdmin(TestCase):
    # Test creation of new user via the admin interface
    def setUp(self):
        site = AdminSite()
        self.admin_view = SymbolAdmin(Symbol, site)

    def test_name_display(self):
        symbol = Symbol.objects.create(code="0020")
        self.assertEqual(
            self.admin_view.name_display(symbol), symbol.get_display_name()
        )

    def test_symbol_display(self):
        symbol = Symbol.objects.create(code="0020")
        expected = mark_safe(
            '&#x{};'.format(symbol.code)
        )
        self.assertEqual(self.admin_view.symbol_display(symbol), expected)


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt; plt.rcdefaults()

def graph(objects,performance,x_label,y_label):
    y_pos = np.arange(len(objects))
    plt.barh(y_pos, performance, align='center', alpha=0.5)
    plt.yticks(y_pos, objects)
    plt.xlabel(x_label)
    plt.title(y_label)
    plt.show()

df = pd.read_csv('USB-IDS-1-TEST.csv', usecols=[" Label"])
print(df.iloc[:,0].value_counts())
a = (df.iloc[:,0].value_counts())

key=a.keys()
values=a.values
attack=0
benign=0

for i in range(0,len(values)):
    if str(key[i])=="BENIGN":
        benign+=values[i]
    else:
        attack+=values[i]

key = [benign,attack]

labels=["Benign %"+str(round(benign/(benign+attack),2)*100),
        "Attack %"+str(round(attack/(benign+attack),2)*100)]
graph(labels,key,"Numbers","Attack and Benign Percentage")


from numpy import *
import matplotlib.pyplot as plt
import csv

def loadDataSet():
    datArr = loadtxt(open("E:/resource/project/test/second_first_hungarian.csv", "rb"), delimiter=',', skiprows=0)
    # 利用map()函数，将列表中每一行的数据值映射为float型
    # datArr = [map(float, line) for line in stringArr]
    # 将float型数据值的列表转化为矩阵返回
    return mat(datArr)

# pca特征维度压缩函数
# @dataMat 数据集矩阵
# @topNfeat 需要保留的特征维度，即要压缩成的维度数，默认4096
def pca(dataMat, topNfeat=4096):
    # 求数据矩阵每一列的均值
    meanVals = mean(dataMat, axis=0)
    # 数据矩阵每一列特征减去该列的特征均值
    meanRemoved = dataMat - meanVals
    # 计算协方差矩阵，除数n-1是为了得到协方差的无偏估计
    # cov(X,0) = cov(X) 除数是n-1(n为样本个数)
    # cov(X,1) 除数是n
    covMat = cov(meanRemoved, rowvar=0)
    # 计算协方差矩阵的特征值及对应的特征向量
    # 均保存在相应的矩阵中
    eigVals, eigVects = linalg.eig(mat(covMat))
    # sort():对特征值矩阵排序(由小到大)
    # argsort():对特征值矩阵进行由小到大排序，返回对应排序后的索引
    eigValInd = argsort(eigVals)
    # 从排序后的矩阵最后一个开始自下而上选取最大的N个特征值，返回其对应的索引
    eigValInd = eigValInd[:-(topNfeat + 1):-1]
    # 将特征值最大的N个特征值对应索引的特征向量提取出来，组成压缩矩阵
    redEigVects = eigVects[:, eigValInd]
    # 将去除均值后的数据矩阵*压缩矩阵，转换到新的空间，使维度降低为N
    lowDDataMat = meanRemoved * redEigVects
    # 利用降维后的矩阵反构出原数据矩阵(用作测试，可跟未压缩的原矩阵比对)
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    # 返回压缩后的数据矩阵即该矩阵反构出原始数据矩阵
    # return lowDDataMat,reconMat
    return lowDDataMat, reconMat

def main():
    lowDDataMat, reconMat = pca(loadDataSet(), 2)
    with open('E:\\resource\\project\\test\\lowDDataMat.csv', 'w',
              newline='') as file_csv:
        write_csv = csv.writer(file_csv)
        write_csv.writerows(lowDDataMat.tolist())
    with open('E:\\resource\\project\\test\\reconMat.csv', 'w',
              newline='') as file_csv:
        write_csv = csv.writer(file_csv)
        write_csv.writerows(reconMat.tolist())
    plt.scatter(lowDDataMat[:, 0].tolist(), lowDDataMat[:, 1].tolist(), s=10)

    plt.show()

if __name__ == "__main__":
    main()


from mmseg.datasets import DATASETS
from mmseg.datasets import PascalVOCDataset as _PascalVOCDataset

@DATASETS.register_module(force=True)
class PascalVOCDataset(_PascalVOCDataset):

    CLASSES = (
        'background',
        'aeroplane',
               'bicycle',
               'bird',
               'boat',
               'bottle',
               'bus',
               'car',
               'cat',
               'chair',
               'cow',
               'table',
               'dog',
               'horse',
               'motorbike',
               'person',
               'plant',
               'sheep',
               'sofa',
               'train',
               'monitor')
    def __init__(self,**kwargs):
        super(PascalVOCDataset, self).__init__(reduce_zero_label=False,**kwargs)
    # CLASSES = ('background',
    #            'airplane or aeroplane (informally plane), is a fixed-wing aircraft that is propelled forward by thrust from a jet engine, propeller, or rocket engine',
    #            'bicycle, also called a pedal cycle, bike or cycle, is a human-powered or motor-powered assisted, pedal-driven, single-track vehicle, having two wheels attached to a frame, one behind the other',
    #            'bird, is a group of warm-blooded vertebrates constituting the class Aves (), characterised by feathers, toothless beaked jaws, the laying of hard-shelled eggs, a high metabolic rate, a four-chambered heart, and a strong yet lightweight skeleton',
    #            'boat, is a watercraft of a large range of types and sizes, but generally smaller than a ship, which is distinguished by its larger size, shape, cargo or passenger capacity, or its ability to carry boats',
    #
    #            'bottle, is a narrow-necked container made of an impermeable material (such as glass, plastic or aluminium) in various shapes and sizes that stores and transports liquids',
    #            'bus (contracted from omnibus, with variants multibus, motorbus, autobus, etc.), is a road vehicle that carries significantly more passengers than an average car or van',
    #            'car (or automobile), is a wheeled motor vehicle that is used for transportation',
    #            'cat (Felis catus), is a domestic species of small carnivorous mammal',
    #            'chair, is a type of seat, typically designed for one person and consisting of one or more legs, a flat seat and a back-rest',
    #            'cow (Cattle), is large, domesticated, cloven-hooved, herbivores',
    #            'table, is an item of furniture with a raised flat top and is supported most commonly by 1 or 4 legs (although some can have more), used as a surface for working at, eating from or on which to place things',
    #            'dog (Canis familiaris or Canis lupus familiaris), is a domesticated descendant of the wolf',
    #            'horse (Equus ferus caballus), is a domesticated, one-toed, hoofed mammal',
    #            'motorcycle, often called a motorbike, bike, cycle, or (if three-wheeled) trike, is a two- or three-wheeled motor vehicle',
    #            'person (PL: people or persons), is a being that has certain capacities or attributes such as reason, morality, consciousness or self-consciousness, and being a part of a culturally established form of social relations such as kinship, ownership of property, or legal responsibility',
    #            'plants, are predominantly photosynthetic eukaryotes of the kingdom Plantae',
    #            'sheep or domestic sheep (Ovis aries), are domesticated, ruminant mammals typically kept as livestock',
    #            'couch, also known as a sofa, settee, or chesterfield, is a cushioned item of furniture for seating multiple people (although it is not uncommon for a single person to use a couch)',
    #            'train (from Old French trahiner, from Latin trahere, \"to pull, to draw\"), is a series of connected vehicles that run along a railway track and transport people or freight In rail transport.',
    #            'monitor, is an output device that displays information in pictorial or textual form')

    # CLASSES = ('background',
    #            'airplane or aeroplane (informally plane)',
    #            'bicycle, also called a pedal cycle, bike or cycle',
    #            'bird',
    #            'boat, is a watercraft (ship)',
    #
    #            'bottle',
    #            'bus',
    #            'car',
    #            'cat',
    #            'chair',
    #            'cow',
    #            'table',
    #            'dog',
    #            'horse',
    #            'motorbike, also called motorcycle',
    #            'person',
    #            'plant',
    #            'sheep',
    #            'sofa',
    #            'train',
    #            'monitor')


# Python program to read an excel file

# import openpyxl module

import openpyxl
from openpyxl import Workbook

# Create new new blank workbook
workbook = Workbook()
# data
sheet = workbook.active
c1 = sheet.cell(row=1, column=1)

# write values
c1.value = "Hello"
# Save changes
workbook.save(filename="contacts.xlsx")


from PyQt5 import QtWidgets
from ui_filePathSelector import Ui_filePathSelector

class FilePathSelector(QtWidgets.QWidget,Ui_filePathSelector):

    def __init__(self, parent:QtWidgets.QWidget=None) -> None:
        """Widget allowing path selection by writing the path or by openning a windows to select it. Both are view are conected.

        Args:
            parent (:class:`QtWidgets.QWidget`, optional): Parent widget. Defaults to None.
        """
        super(FilePathSelector,self).__init__(parent)
        self.setupUi(self)

        self.path = ""
        self.pushButton.clicked.connect(self.browse)
        self.textEdit.textChanged.connect(self.f)

    def browse(self) -> None:
        """Open :class:`QtWidgets.QfileDialog` to let the user choose a path.
        """
        file = QtWidgets.QFileDialog.getOpenFileName(self,"Choose a file","~/")
        if file[0] != '':
            self.textEdit.setPlainText(file[0])

    def f(self) -> None:
        """Called on :class:`testEdit` text change.
        """
        self.path = self.textEdit.toPlainText()