import project.model as db_model
from operator import itemgetter
from scipy import signal as signal_processor
from scipy.signal import find_peaks
import numpy as np
import sys
import matplotlib.pyplot as plt

class Controller:
    internal_shots = 0
    internal_time = 0
    internal_temperature_original = 0
    internal_channels_pos = 0
    internal_psi_r = 0
    internal_psi = 0
    internal_q_database = 0
    internal_q_x_database = 0
    internal_surfaces_ro = 0
    internal_surfaces_psinorm = 0

    win_list_names = [
        'triang',  # minimum info save
        'blackmanharris',  # middle info save (maybe best practice)
        'flattop',  # maximum info save
        'boxcar', 'blackman', 'hamming', 'hann',
        'bartlett', 'parzen', 'bohman', 'nuttall', 'barthann'
    ]

    database = db_model.LoadDB()

    def load(self):
        """ -----------------------------------------
             version: 0.10
             desc: load matlab DB (model trigger)
         ----------------------------------------- """
        sawdata = self.database.load()
        self.shots = self.database.shots

        return sawdata

    def assign(self, database, discharge, source):
        """ -----------------------------------------
             version: 0.10
             desc: assign data from loaded DB (model trigger)
         ----------------------------------------- """

        self.database.assign(database, discharge, source)

        self.channels_pos = self.database.channels
        self.time = self.database.time
        self.temperature_original = self.database.temperature
        self.psi = self.database.psi
        self.psi_r = self.database.psi_r
        self.q_database = self.database.q_database
        self.q_x_database = self.database.q_x_database
        self.surfaces_ro = self.database.surfaces_ro
        self.surfaces_psinorm = self.database.surfaces_psinorm

        return 1

    @property
    def q_database(self):
        return self.internal_q_database

    @q_database.setter
    def q_database(self, value):
        self.internal_q_database = value

    @property
    def q_x_database(self):
        return self.internal_q_x_database

    @q_x_database.setter
    def q_x_database(self, value):
        self.internal_q_x_database = value

    @property
    def surfaces_ro(self):
        return self.internal_surfaces_ro

    @surfaces_ro.setter
    def surfaces_ro(self, value):
        self.internal_surfaces_ro = value

    @property
    def surfaces_psinorm(self):
        return self.internal_surfaces_psinorm

    @surfaces_psinorm.setter
    def surfaces_psinorm(self, value):
        self.internal_surfaces_psinorm = value

    @property
    def shots(self):
        return self.internal_shots

    @shots.setter
    def shots(self, value):
        self.internal_shots = value

    @property
    def psi_r(self):
        return self.internal_psi_r

    @psi_r.setter
    def psi_r(self, value):
        self.internal_psi_r = value

    @property
    def psi(self):
        return self.internal_psi

    @psi.setter
    def psi(self, value):
        self.internal_psi = value

    @property
    def time(self):
        return self.internal_time

    @time.setter
    def time(self, value):
        self.internal_time = value

    @property
    def temperature_original(self):
        return self.internal_temperature_original

    @temperature_original.setter
    def temperature_original(self, value):
        self.internal_temperature_original = value

    @property
    def channels_pos(self):
        return self.internal_channels_pos

    @channels_pos.setter
    def channels_pos(self, value):
        self.internal_channels_pos = value

class Profiling(Controller):

    def order_by_r_maj(self, temperature_list_to_order, chan_pos_order_buffer):
        """ -----------------------------------------
            version: 0.2
            desc: ordering temperature list by r_maj position
            ;:param temperature_list_to_order: 2d array of temperature
            :return ordered 2d array
        ----------------------------------------- """
        temperature_ordered_list = []

        for channel in sorted(chan_pos_order_buffer.items(), key=itemgetter(1)):
            # if channel[0] in range(1, len(temperature_list_to_order)):
            if channel[0] in temperature_list_to_order:
                temperature_ordered_list.append(
                    temperature_list_to_order[channel[0]]
                )

        return temperature_ordered_list

    @staticmethod
    def normalization(temperature):

        """ -----------------------------------------
            version: 0.2
            desc: math normalization on 1
            :param temperature: 2d list of num
            :return normalized 2d list of num
        ----------------------------------------- """

        output = []

        for num_list in temperature:
            normalized = num_list / (sum(num_list[0:10]) / 10)
            output.append(normalized)

        return output

    @staticmethod
    def outlier_filter(temperature, boundary):

        """ -----------------------------------------
            version: 0.2.0
            desc: remove extra values from list
            :param temperature: 1d list of num
            :param boundary: array 0=>min and 1=>max
            :return filtered 1d list of num
        ----------------------------------------- """

        filtered_list = []

        for num_list in temperature:
            filtered_num = []
            for num in num_list:

                if num < boundary[0]:
                    filtered_num.append(boundary[0])
                elif num > boundary[1]:
                    filtered_num.append(boundary[1])
                else:
                    filtered_num.append(num)

            filtered_list.append(filtered_num)

        return filtered_list

    @staticmethod
    def outlier_filter_std_deviation(temperature_list, boundary, offset):

        """ -----------------------------------------
            version: 0.2.1
            desc: remove extra values from list
            :param temperature_list: 1d list of num
            :param boundary: float val intensity of cutting edge on standard deviation
            :param offset: int val of which temperature val reset
            :return filtered 1d list of num
        ----------------------------------------- """

        temperature_list = np.transpose(temperature_list)

        filtered_list = []

        for i_list, temperature in enumerate(temperature_list):
            filtered_num = []

            mean, data_std = np.mean(temperature), np.std(temperature)
            cut_off = data_std * boundary
            lower, upper = mean - cut_off, mean + cut_off

            for i, t in enumerate(temperature):
                if t < lower:
                    filtered_num.append(temperature[i-offset])
                    # filtered_num.append(lower)
                elif t > upper:
                    filtered_num.append(temperature[i-offset])
                    # filtered_num.append(upper)
                else:
                    filtered_num.append(t)

            filtered_list.append(filtered_num)

        return np.transpose(filtered_list)

class PreProfiling:

    @staticmethod
    def median_filtered(signal, threshold=3):
        """
        signal: is numpy array-like
        returns: signal, numpy array
        """
        difference = np.abs(signal - np.median(signal))
        median_difference = np.median(difference)
        s = 0 if median_difference == 0 else difference / float(median_difference)
        mask = s > threshold
        signal[mask] = np.median(signal)
        return signal

    @staticmethod
    def filter(input_signal, window_width, window_name):
        window = signal_processor.get_window(window_name, window_width)
        output_signal = []

        for temperature in input_signal:
            output_signal.append(
                signal_processor.convolve(temperature, window, mode='valid') / sum(window)
            )

        return output_signal

    @staticmethod
    def dict_to_list(dict_array):
        return [value for key, value in dict_array.items()]

    @staticmethod
    def list_to_dict(list_array):
        return {i: k for i, k in enumerate(list_array)}

class FindCollapseDuration:

    def collapse_duration(self, temperature_list_reverse, temperature_list, std_low_limit, inv_radius_channel, dynamic_outlier_limitation, median_filter_window_size):

        """ -----------------------------------------
            version: 0.3
            desc: search time points of Collapse duration
            :param temperature_list: 2d list of num
            :param time_list: 1d list of num
            :param std_low_limit: float val of min deviation which indicate start index
            :return list with int val of indexes in time_list
        ----------------------------------------- """

        collapse_start_time = self.collapse_start(temperature_list, median_filter_window_size, inv_radius_channel)
        collapse_end_time = self.collapse_end(temperature_list, inv_radius_channel, collapse_start_time, median_filter_window_size)

        # return (collapse_start_time, collapse_end_time)
        return (collapse_start_time, collapse_end_time)

    @staticmethod
    def gaussian(x, mu, sig):
        return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))

    # @staticmethod
    def collapse_end(self, temperature_list, r_inv_index, start, median_filter_window_size):
        """ -----------------------------------------
            version: 0.7
            desc: search time point at which end
            :param temperature_list: 2d list of num
            :return int val of index in time_list
        ----------------------------------------- """

        # fig, ax = plt.subplots()
        # fig.set_size_inches(15, 7)
        #
        # fig1, ax1 = plt.subplots()
        # fig1.set_size_inches(15, 7)

        temperature_list = temperature_list[r_inv_index:r_inv_index+10, median_filter_window_size[0]:-median_filter_window_size[0]]
        correlators = []
        height = []
        step_backward = 20
        smooth_window = 151
        smooth_window_offset = round((smooth_window - 1) / 2)
        for prototype_index, prototype in enumerate(temperature_list):

            window = signal_processor.get_window('triang', smooth_window)
            prototype = signal_processor.convolve(prototype, window, mode='valid')

            # ax.plot(prototype[(step_backward+smooth_window_offset):])

            ######################################### Financial momentum correlator
            correlator = []
            for t_i, t in enumerate(prototype):
                if t_i > step_backward:
                    # # Correlator based on all points in window
                    # k = []
                    # for i in range(step_backward):
                    #     k.append(t / prototype[t_i - i])
                    ##########################################

                    # # Correlator based only on endpoints
                    correlator.append(t / prototype[t_i - step_backward])

            correlator = correlator / np.mean(correlator[:500])
            correlator = np.abs(correlator - 1) + 1

            # ax1.plot(np.abs(correlator-1))

            correlator = correlator.tolist()
            correlators.append(correlator)
            ########################################## std correlator
            # correlator = []
            # for t_i, t in enumerate(prototype):
            #     if t_i > step_backward:
            #         correlator.append(np.std(prototype[t_i - step_backward:t_i]))
            #
            # correlator = correlator / np.mean(correlator[:500])
            # correlator = correlator.tolist()
            # correlators.append(correlator)
            ##########################################

            height.append(max(correlator) - 1)

        work_index = height.index(max(height))
        height = max(height)
        correlator = correlators[work_index]
        mu = correlator.index(max(correlator))
        level = (height / 4) + 1

        sigma_right = 0
        for c_i, c in enumerate(correlator[::-1]):
            if c > level:
                sigma_right = len(correlator) - c_i
                break

        sigma_left = 0
        for c_i, c in enumerate(correlator):
            if c > level:
                sigma_left = mu - c_i
                break

        # # Gaus, don't know if I need this
        # sigma = sigma_left + sigma_right
        # mu = np.round(((mu - sigma_left) + (mu + sigma_right)) / 2).astype(int)
        #
        # sigma = sigma / 4
        # x_values = np.linspace(0, len(correlator), len(correlator))
        # gaus = (height * self.gaussian(x_values, mu, sigma)) + 1
        #
        # deviation = 0.0145 * height
        # end = 0
        # for g_i, g in enumerate(gaus[::-1]):
        #     if (g - 1) > deviation:
        #         end = len(correlator) - g_i + step_backward + smooth_window_offset  # !!!!!!!!!!!!!!!!11
        #         break
        ##########################################

        ########################################## DEBUG ploting
        # fig, ax = plt.subplots()
        # fig.set_size_inches(15, 7)
        # prototype = temperature_list[work_index]
        # prototype = prototype / np.mean(prototype[:500])
        # ax.plot(correlator)
        # ax.plot(prototype[(step_backward+smooth_window_offset):])
        ##########################################

        end = sigma_right + step_backward + smooth_window_offset
        return end

    # @staticmethod
    def collapse_start(self, temperature_list, median_filter_window_size, r_inv_index=60):
        """ -----------------------------------------
            version: 0.7
            desc: search time point at which start Precursor Phase
            :param temperature_list: 2d list of num
            :return int val of index in time_list
        ----------------------------------------- """

        fig, ax = plt.subplots(2, 2)
        fig.set_size_inches(15, 7)

        temperature_list = temperature_list[:r_inv_index-3, median_filter_window_size[0]:-median_filter_window_size[0]]
        correlators = []
        height = []
        prominence = []
        step_backward = 21
        smooth_window = 51
        medfit_width = 51
        smooth_window_offset = round(smooth_window / 2)
        step_backward_offset = round(step_backward / 2)
        for prototype_index, prototype in enumerate(temperature_list):

            prototype = signal_processor.medfilt(prototype, medfit_width)
            window = signal_processor.get_window('triang', smooth_window)
            prototype = signal_processor.convolve(prototype, window, mode='valid')

            ax[0, 0].plot(prototype[(step_backward+smooth_window_offset):])

            """ Financial momentum correlator """
            correlator = []
            for t_i, t in enumerate(prototype):
                if t_i > step_backward:
                    """ Correlator based on all points in window """
                    # k = []
                    # for i in range(step_backward):
                    #     k.append(t / prototype[t_i - i])
                    # correlator.append(np.mean(k))
                    ##########################################

                    """ Correlator based only on endpoints """
                    correlator.append(prototype[t_i - step_backward] / t)

            correlator = correlator / np.mean(correlator[:500])
            correlator = np.abs(correlator - 1) + 1

            ax[0, 1].plot(correlator)

            correlator = correlator.tolist()
            correlators.append(correlator)

            """ Std correlator """
            # correlator = []
            # for t_i, t in enumerate(prototype):
            #     if t_i > step_backward:
            #         correlator.append(np.std(prototype[t_i - step_backward:t_i]))
            #
            # correlator = correlator / np.mean(correlator[:500])
            # correlator = correlator.tolist()
            # correlators.append(correlator)
            ##########################################

            """ Determine height of current correlator """
            height_val = max(correlator) - 1
            height.append(height_val)

            """ Determine prominence of current correlator """
            peaks, _ = find_peaks(correlator, prominence=(height_val / 1.5))
            correlator = np.asarray(correlator)
            prominence.append(np.mean(correlator[peaks]))

        """ Determine work_index by max value of max prominence in whole set of correlators
            Which one is better??? """
        work_index = prominence.index(max(prominence))
        """ Determine work_index by max height in whole set of correlators """
        # work_index = height.index(max(height))

        height = max(height)
        correlator = correlators[work_index]
        mu = correlator.index(max(correlator))

        level_height = (height / 5) + 1
        peaks, _ = find_peaks(correlator[:500])
        mean_peak_height = np.mean(np.asarray(correlator)[peaks])

        level_std = ((mean_peak_height - 1) * 10) + np.mean(correlator[:500])
        level = level_height if level_std > level_height else level_std

        sigma_right = 0
        for c_i, c in enumerate(correlator[::-1]):
            if c > level:
                sigma_right = len(correlator) - c_i
                break

        sigma_left = 0
        for c_i, c in enumerate(correlator):
            if c > level:
                sigma_left = c_i
                break

        """ Gaus, don't know if I need this """
        # sigma = sigma_left + sigma_right
        # mu = np.round(((mu - sigma_left) + (mu + sigma_right)) / 2).astype(int)
        #
        # sigma = sigma / 4
        # x_values = np.linspace(0, len(correlator), len(correlator))
        # gaus = (height * self.gaussian(x_values, mu, sigma)) + 1
        #
        # deviation = 0.0145 * height
        # end = 0
        # for g_i, g in enumerate(gaus[::-1]):
        #     if (g - 1) > deviation:
        #         end = len(correlator) - g_i + step_backward + smooth_window_offset  # !!!!!!!!!!!!!!!!11
        #         break
        ##########################################

        """ DEBUG ploting etc. """
        # # print(sigma_left)
        # prototype = temperature_list[work_index]
        # prototype = prototype / np.mean(prototype[:500])
        #
        # window = signal_processor.get_window('triang', smooth_window)
        # prototype_smooth = signal_processor.convolve(temperature_list[work_index], window, mode='valid')
        # prototype_smooth = prototype_smooth / np.mean(prototype_smooth[:500])
        #
        # ax[1, 0].plot(prototype_smooth)
        # ax[1, 1].plot(prototype[(step_backward+smooth_window_offset):])
        # ax[1, 1].plot([level for x in correlator])
        # ax[1, 1].plot(correlator)
        #
        # peaks, _ = find_peaks(correlator, prominence=(height / 1.5))
        # correlator = np.asarray(correlator)
        # plt.plot(correlator)
        # plt.plot(peaks, correlator[peaks], "x")
        ##########################################

        start = sigma_left + step_backward + smooth_window_offset - step_backward_offset
        return start

class FindInvRadius:

    @staticmethod
    def trend_indicator(plane_list):

        """ -----------------------------------------
            version: 0.2
            desc: define if list of nums (T(r_maj)) increase or decrease
            :param plane_list: 1d list of num
            :return indicator => 1: increase, -1: decrease, 0: flat/undefined
        ----------------------------------------- """

        compare_num = plane_list[0]
        increase = []
        decrease = []
        stat_weight = 1 / len(plane_list)

        for num in plane_list:

            difference = num - compare_num
            compare_num = num

            if difference > 0:
                increase.append(difference)
            elif difference < 0:
                decrease.append(difference)

        indicator_increase = sum(map(abs, increase)) * (len(increase) * stat_weight) + 1
        indicator_decrease = sum(map(abs, decrease)) * (len(decrease) * stat_weight) + 1

        if indicator_increase > indicator_decrease:
            indicator = 1
        elif indicator_decrease > indicator_increase:
            indicator = -1
        else:
            indicator = 0

        return indicator

    def inv_radius(self, temperature_list, window_width, std_low_limit, channel_offset):

        """ -----------------------------------------
            version: 0.2
            desc: define if list of nums increase or decrease
            :param temperature_list: 2d array of nums normalised on 1
            :param std_low_limit: float val to skip flat regions
            :param window_width: int val of len by which make plane indicating
            :return main_candidate_index: value of the most probable index
                    of channel with inversion radius
        ----------------------------------------- """

        temperature_list = np.transpose(temperature_list)
        mean = np.mean(temperature_list[0])
        area = int((len(temperature_list[0]) - (len(temperature_list[0]) % window_width)))
        candidate_list = []
        stat_weight = {}

        for timeline, t_list in enumerate(temperature_list):
            if timeline == 0:
                continue

            # flat_outlier = sum(abs(t_list - mean)) / len(t_list)
            flat_outlier = np.std(t_list)

            # print(flat_outlier, ' ', std_low_limit)
            if flat_outlier > std_low_limit:
                candidates = []
                plane_area_direction_prev = 1
                for i in range(window_width, area, window_width):
                    if i < channel_offset:
                        continue

                    analysis_area = t_list[i-1:i + window_width]

                    """ Analysis only upward trends """
                    plane_area_direction = self.trend_indicator(analysis_area)
                    if plane_area_direction != -1 and plane_area_direction_prev == 1:

                        """ Analysis only analysis_area which have intersection with mean value"""
                        upper_area = 0
                        under_area = 0
                        for t_i, t_analysis in enumerate(analysis_area):
                            upper_area = 1 if t_analysis > mean else upper_area
                            under_area = 1 if t_analysis < mean else under_area

                        """ Candidates => (range of points, temperature at each point) """
                        if upper_area == 1 and under_area == 1:
                            candidates.append((range(i, i + window_width), analysis_area))
                            stat_weight_to_update = (stat_weight[i] + 1) if i in stat_weight else 0
                            stat_weight.update({i: stat_weight_to_update})

                    plane_area_direction_prev = plane_area_direction

                    """ Candidate_list => (timeline with candidates, candidates) """
                    candidate_list.append((timeline, candidates))

        if len(stat_weight) == 0:
            # print('Error: std_low_limit is too big')
            return 0

        search_area_max = max(stat_weight.items(), key=itemgetter(1))
        search_area = search_area_max[0]

        # candidate_info = 0
        # if search_area_max[1] < 1000:
        #     return candidate_info

        temperature_list = np.transpose(temperature_list)
        main_candidate_index = self.sum_deviation(temperature_list[search_area:(search_area + window_width)])
        main_candidate_index = search_area + main_candidate_index

        return main_candidate_index

    def inv_radius_intersection(self, temperature_list, window_width, std_low_limit, r_maj):

        """ -----------------------------------------
            version: 0.2.1
            desc: define if list of nums increase or decrease
            :param temperature_list: 2d array of nums normalised on 1
            :param std_low_limit: float val to skip flat regions
            :param window_width: int val of len by which make plane indicating
            :return main_candidate_index: value of the most probable index
                    of channel with inversion radius
        ----------------------------------------- """

        temperature_list = np.transpose(temperature_list)
        mean = sum(temperature_list[0]) / len(temperature_list[0])  # normalised on 1
        area = int((len(temperature_list[0]) - (len(temperature_list[0]) % window_width)))
        stat_weight = {}
        candidates = []

        for timeline, t_list in enumerate(temperature_list):
            flat_outlier = sum(abs(t_list - mean)) / len(t_list)

            if flat_outlier > std_low_limit:
                plane_area_direction_prev = 1
                for i in range(window_width, area, window_width):

                    analysis_area = t_list[i-1:i + window_width]

                    """ Analysis only upward trends """
                    plane_area_direction = self.trend_indicator(analysis_area)
                    if plane_area_direction != -1 and plane_area_direction_prev == 1:

                        """ Analysis only analysis_area which have intersection with mean value"""
                        upper_area = 0
                        under_area = 0
                        intersection_indexes = ()
                        for tia, t_analysis in enumerate(analysis_area):
                            upper_area = 1 if t_analysis > mean else upper_area
                            if under_area == 1 and upper_area == 1:
                                intersection_indexes = (i + tia - 2, i + tia - 1)
                                break
                            under_area = 1 if t_analysis < mean else under_area

                        """ Candidates => (range of points, temperature at each of point) """
                        if upper_area == 1 and under_area == 1 and len(intersection_indexes) == 2:

                            intersection = self.intersection_pos(t_list, intersection_indexes, r_maj, mean)
                            if intersection > 0:
                                candidates.append((intersection_indexes[0], intersection))

                                stat_weight_to_update = (stat_weight[intersection_indexes[0]] + 1) if intersection_indexes[0] in stat_weight else 1
                                stat_weight.update({intersection_indexes[0]: stat_weight_to_update})

                    plane_area_direction_prev = plane_area_direction

        sorted_candidates = {}
        # print(len(candidates))
        for c in candidates:
            inter_list = sorted_candidates[c[0]] if c[0] in sorted_candidates else []
            inter_list.append(c[1])
            sorted_candidates.update({c[0]: inter_list})

        if len(stat_weight) == 0:
            sys.exit('Error: std_low_limit is too big')

        search_area_max = max(stat_weight.items(), key=itemgetter(1))
        search_area = search_area_max[0]

        intersection = np.mean(sorted_candidates[search_area])

        candidate_info = (0, 0)
        if search_area_max[1] < 500:
            return candidate_info

        candidate_info = ('{:.4f}'.format(intersection), str(search_area) + "-" + str(search_area + 1))

        return candidate_info

    @staticmethod
    def intersection_pos(t_list, intersection_indexes, r_maj, mean):

        """ -----------------------------------------
            version: 0.2
            desc: calculate deviation from mean val and give index of channel
            :param t_list:
            :param intersection_indexes:
            :param r_maj:
            :param mean:
            :return intersection float val
        ----------------------------------------- """

        cathete_under = mean - t_list[intersection_indexes[0]]
        cathete_above = t_list[intersection_indexes[1]] - mean

        cathete_side = cathete_under + cathete_above

        if cathete_side > 0:
            cathete_down = r_maj[intersection_indexes[1]] - r_maj[intersection_indexes[0]]

            hypotenuse = np.sqrt(np.power(cathete_side, 2) + np.power(cathete_down, 2))

            aspect_ratio = hypotenuse / cathete_side
            hypotenuse_under = aspect_ratio * cathete_under

            cathete_mean = np.sqrt(np.power(hypotenuse_under, 2) - np.power(cathete_under, 2))

            intersection = r_maj[intersection_indexes[0]] + cathete_mean
        else:
            intersection = 0

        return intersection

    @staticmethod
    def sum_deviation(search_area):

        """ -----------------------------------------
            version: 0.3
            desc: calculate deviation from mean val and give index of channel
            :param search_area: 2d array of nums normalised on 1 where can be channel with inv radius
            :return index of channel with minimum deviation from mean that means
                    that it is index of inversion radius
        ----------------------------------------- """

        deviation = []
        for t_list in search_area:
            deviation.append(np.std(t_list))

        return deviation.index(min(deviation))

class MachineLearning:

    @staticmethod
    def ml_load(filename):
        """ -----------------------------------------
             version: 0.3
             desc: load data from matlab with previously prepared data
             :param filename: string val
             :return nd array
         ----------------------------------------- """
        db = db_model.Model()
        mat = db.load(filename)

        data = {
            'ece_data': mat['ece_data'][0, 0]['signal'],
            'discharge': mat['ece_data'][0, 0]['discharge']
        }

        return data

    @staticmethod
    def ml_find_inv_radius(data_train, data_test):
        from sklearn.neural_network import MLPClassifier
        from sklearn.neighbors import KNeighborsClassifier
        from sklearn.svm import SVC
        from sklearn.gaussian_process import GaussianProcessClassifier
        from sklearn.gaussian_process.kernels import RBF
        from sklearn.tree import DecisionTreeClassifier
        from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
        from sklearn.naive_bayes import GaussianNB
        from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis

        data_test = np.array(data_test)[1000:1900, :60]

        print('data_train len:', len(data_train))

        X_train = data_train[:, :-1]
        y_train = data_train[:, -1]

        # KNeighborsClassifier(3),
        # SVC(kernel="linear", C=0.025),
        # SVC(gamma=2, C=1),
        # GaussianProcessClassifier(1.0 * RBF(1.0)),
        # DecisionTreeClassifier(max_depth=5),
        # RandomForestClassifier(max_depth=5, n_estimators=10, max_features=1),
        # MLPClassifier(alpha=1),
        # AdaBoostClassifier(),
        # GaussianNB(),
        # QuadraticDiscriminantAnalysis()
        model = DecisionTreeClassifier().fit(X_train, y_train)

        print('Accuracy of Linear SVC classifier on training set: {:.2f}'
         .format(model.score(X_train, y_train)))

        return model.predict(data_test)

    @staticmethod
    def ml_find_collapse_duration(data_train, data_test):
        from sklearn.tree import DecisionTreeClassifier

        data_test = np.array(data_test)[15:45, 1000:1901]

        print('data_train len:', len(data_train))
        # print(data_train.shape)
        # exit()

        X_train = data_train[:, :-1]
        y_train = data_train[:, -1]
        # print(y_train[0])
        # exit()

        model = DecisionTreeClassifier().fit(X_train, y_train)

        print('Accuracy of Linear SVC classifier on training set: {:.2f}'
              .format(model.score(X_train, y_train)))

        # exit()
        return model.predict(data_test)


#!/srv/homeassistant/bin/python3
import os
import importlib
import re

from util.entity_map import entity_map
from util import logger
import appdaemon.plugins.hass.hassapi as hass
import event_factory
import event_dispatcher
import timer_manager
import scheduler
import api_handle

class AutomationHub(hass.Hass):
    def initialize(self):
        api_handle.instance = self

        self.event_list = self.args["event_list"]
        self.subscribe_events()
        self.subscribe_states()
        if not hasattr(self, "event_handler_map"):
            self.event_handler_map = {}
        self._load_handlers()
        scheduler.schedule_daily_tasks()
        scheduler.schedule_polling_tasks()
        self._notify_started()

    def _load_handlers(self):
        cwd = os.path.dirname(os.path.realpath(__file__))
        handler_path = os.path.join(cwd, "event_handlers")
        ls_output = os.listdir(handler_path)
        module_files = [pyfile.replace('.py', '') for pyfile in ls_output if re.match(r'^.+\.py$', pyfile) and '__init__.py' not in pyfile]

        event_dispatcher.clear_callbacks()

        for module_name in module_files:
            if module_name in self.event_handler_map:
                module = importlib.reload(self.event_handler_map[module_name])
            else:
                module = importlib.import_module(".".join(["event_handlers", module_name]))
            module.register_callbacks()
            self.event_handler_map[module_name] = module

    def _notify_started(self):
        event = event_factory.create_automation_hub_started_event()
        event_dispatcher.dispatch(event)

    def subscribe_events(self):
        self.listen_event(self.on_event, event="MQTT_MESSAGE", namespace="mqtt")
        for event in self.event_list:
            self.listen_event(self.on_event, event=event, namespace="hass")
        self.event_list.append("MQTT_MESSAGE")

    def on_event(self, event_name, data, kwargs):
        logger.debug("Received New Event - name = {} data = {} kwargs = {}".format(event_name, data, kwargs))

        if event_name in self.event_list:

            adevent = event_factory.create_from_event(event_name, data, kwargs)
            if adevent:
                event_dispatcher.dispatch(adevent)
        else:
            logger.error(f"Received untracked event: {event_name}")

    def subscribe_states(self):
        for entity_id in entity_map.keys():
            self.listen_state(self.on_state_changed, entity_id=entity_id, attribute="all", namespace="hass")

    def on_state_changed(self, entity, attribute, old, new, kwargs):

        if entity in entity_map:
            logger.debug("Received New State Change - entity = {} attribute = {} old = {} new = {} kwargs = {}".format(entity, attribute, old, new, kwargs))
            logger.debug("Received state change for subscribed entity (name = {}, type = {}".format(entity_map[entity]['name'], entity_map[entity]['type']))

            friendly_name = entity_map[entity]["name"]
            entity_type = entity_map[entity]["type"]
            old_state = old.get("state") if old else None
            new_state = new.get("state") if new else None
            attributes = new.get("attributes")

            adevents = event_factory.create_from_state_change(friendly_name, entity_type, entity, attributes, old_state, new_state, kwargs)
            for adevent in adevents:
                event_dispatcher.dispatch(adevent)
        else:
            logger.error(f"Received untracked state change from entity: {entity}")

    def timer_callback(self, kwargs):
        partial = kwargs.get("partial")
        name = kwargs.get("title")
        timer_manager.remove_timer(name)
        if partial:
            partial()

    def scheduler_callback(self, kwargs):
        title = kwargs.get("title")
        partial = kwargs.get("partial")
        if partial:
            partial()


class HasDuplicate:
    @staticmethod
    def has_duplicate(nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        item_set = set()
        for n in nums:
            if n in item_set:
                return True
            else:
                item_set.add(n)
        return False


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('api', '0001_initial'),
    ]

    operations = [
        migrations.RenameField(
            model_name='snippet',
            old_name='titlle',
            new_name='tittle',
        ),
    ]


# Write a method that takes an array of numbers. If a pair of numbers
# in the array sums to zero, return the positions of those two numbers.
# If no pair of numbers sums to zero, return `None`.
#
# Difficulty: medium.
import unittest

def two_sum(nums):
    index1 = 0
    while index1 <= len(nums)-1:
        index2 = index1 + 1
        while index2 <= len(nums)-1:
            if nums[index1] + nums[index2] == 0:
                return [index1, index2]
            index2 += 1
        index1 += 1
    return None

# These are tests to check that your code is working. After writing
# your solution, they should all print true.

class TwoSum(unittest.TestCase):

    def test_has_sum(self):
        self.assertEqual(two_sum([1, 3, 5, -3]), [1, 3])

    def test_is_none(self):
        self.assertIsNone(two_sum([1, 3, 5]))

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


class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

class Tree:
    def __init__(self):
        self.root = None

    def insert(self, data):
        self.root = self.__insert(self.root, data)

    def __insert(self, node, data):
        if node is None:
            return Node(data)
        if data < node.data:
            node.left = self.__insert(node.left, data)
        elif data > node.data:
            node.right = self.__insert(node.right, data)
        return node

    def remove(self, data):
        self.root = self.__remove(self.root, data)

    def __remove(self, node, data):
        if node is None:
            raise ValueError("Data not in the list!")
        if data < node.data:
            node.left = self.__remove(node.left, data)
        elif data > node.data:
            node.right = self.__remove(node.right, data)
        else:
            if node.left is not None and node.right is not None:
                temp = self.minNode(node.right)
                node.data = temp.data
                node.right = self.__remove(node.right, temp.data)
            elif node.left is None:
                node = node.right
            elif node.right is None:
                node = node.left
        return node

    def minNode(self, node):
        if node is None:
            raise ValueError("List is empty!")
        while node.left:
            node = node.left
        return node

    def inOrder(self, temp):
        if not temp:
            return
        self.inOrder(temp.left)
        print(temp.data, end=" ")
        self.inOrder(temp.right)

    def levelOrder(self):
        queue = [self.root]
        while queue:
            temp = queue.pop(0)
            print(temp.data, end=" ")
            if temp.left is not None:
                queue.append(temp.left)
            if temp.right is not None:
                queue.append(temp.right)

tree = Tree()
tree.insert(10)
tree.insert(11)
tree.insert(7)
tree.insert(9)
tree.insert(6)
tree.insert(8)

tree.remove(9)
tree.levelOrder()
# print(tree.minNode(tree.root))
# tree.inOrder(tree.root)


from osv import fields,osv
import mx.DateTime
import tools.sql
from tools.translate import _

class kdvn_report_contract_to_client(osv.osv):
    _name='kdvn.report.contract.to.client'
    _description='KDVN Report Contract To Client'
    _auto=False

    _columns={
                "contract_no":fields.char("Contract No.",size=25),
                "project_name":fields.char("Project Name",size=20),
                "description":fields.char("Payment No.",size=255),
                "contract_currency":fields.many2one('project.currency',"Contract Cur."),
                'payment_id':fields.many2one("kdvn.payment.from.client",'Payment'),
                "contract_id":fields.integer('Contract ID'),
                "quotation_info":fields.char("Payment No.",size=255),

                "direct_amount":fields.float("Contract Amount"),
                "vat":fields.float("Contract VAT"),
                "total_amount":fields.float("Contract Total"),

                "payment_number":fields.char("Payment No.",size=20),
                "claim_date":fields.date("Claim Date"),
                "claim_amount":fields.float("Claim Amount"),
                "received_date":fields.date("Received Date"),
                "received_amount":fields.float('Received Amount'),
                "red_invoice_ok":fields.boolean('VAT OK?'),
                "payment_term_line_id":fields.many2one('kdvn.payment.term.line','Payment Term Line'),

                "completion_date":fields.date('Completion Date'),
                "contract_sent":fields.boolean("Contract Sent?"),
                "contract_received":fields.boolean("Contract Received?"),

                "progress_sent":fields.boolean("Progress Sent?"),
                "progress_received":fields.boolean("Progress Received?"),

                "electrical":fields.float("Electrical"),
                "mechanical":fields.float("Mechanical"),
                "discount":fields.float("Discount")
              }
    def init(self,cr):
        tools.sql.drop_view_if_exists(cr,'kdvn_report_contract_to_client')
        cr.execute("create or replace view kdvn_report_contract_to_client as\
                        Select\
                            (id::text || coalesce(payment_id,0)::text)::integer as id,\
                            id as contract_id,\
                            contract_no,\
                            project_name,\
                            description,\
                            \
                            quotation_info,\
                            \
                            coalesce(contract_amount_e,0.0) + coalesce(contract_amount_m,0) as direct_amount,\
                            coalesce(contract_vat,0) as vat,\
                            coalesce(contract_total,0.0) as total_amount,\
                    \
                            number as payment_number,\
                            claim_date,\
                            claim_amount,\
                            received_date,\
                            received_amount,\
                            red_invoice_ok,\
                            payment_term_line_id,\
                            \
                            completion_date,\
                            \
                            coalesce(attached_contract_sent,False) as contract_sent,\
                            coalesce(attached_contract_received,False) as contract_received,\
                            \
                            coalesce(attached_progress_sent,False) as progress_sent,\
                            coalesce(attached_progress_received,False) as progress_received,\
                            \
                            electrical,\
                            mechanical,\
                            discount,\
                            coalesce(payment_id,0) as payment_id,\
                            pc_id as contract_currency\
                        from\
                            kdvn_contract_client kcc\
                        left join\
                                (Select id as pc_id,contract_id as pc_contract_id from project_currency where default_curr=True limit 1) pcc on kcc.id=pcc.pc_contract_id\
                        left join\
                            (Select\
                                contract_id,\
                                sum(name || to_char(date_order,': dd-Mon-yyyy;'||E'\n')) as quotation_info,\
                                sum(coalesce(q_amount_total_e,0)) as electrical,\
                                sum(coalesce(q_amount_total_m,0)) as mechanical,\
                                sum(coalesce(approved_amount,0)-coalesce(q_amount_total_e,0)-coalesce(q_amount_total_m,0)) as discount\
                            from\
                                sale_order\
                            group by\
                                contract_id) vwquotation on id=contract_id\
                        left join    \
                            (Select \
                                kpfc.id as payment_id,\
                                contract_id,\
                                number,\
                                kpfc.date as claim_date,\
                                coalesce(amount_e,0)+coalesce(amount_m,0)+coalesce(adv_payment,0)+coalesce(retention,0)+coalesce(others,0)+coalesce(kdvn_amount_tax,0) as claim_amount,\
                                max(kr.date) as received_date,\
                                sum(coalesce(tax_amount,0) + coalesce(kr.amount,0)) as received_amount,\
                                payment_term_line_id,\
                                case when coalesce(vwred.payment_id,0)=0 then False else True end as red_invoice_ok\
                            from \
                                kdvn_payment_from_client kpfc\
                            left join\
                                kdvn_received kr on kpfc.id=kr.payment_id\
                            left join\
                                (Select Distinct payment_id from payment_from_client_kdvn_red_invoice_rel where red_invoice_id>0) vwred on kpfc.id=vwred.payment_id\
                            where state not in ('draft','cancel')\
                            group by\
                                contract_id,\
                                number,\
                                kpfc.id,\
                                claim_date,\
                                claim_amount,\
                                payment_term_line_id,\
                                red_invoice_ok) vwpayment on id=vwpayment.contract_id")
kdvn_report_contract_to_client()

class kdvn_contract_client(osv.osv):
    _name = 'kdvn.contract.client'
    _inherit = 'kdvn.contract.client'
    _description="KDVN Contract Client"

    _columns={
              'contract_client_report_id':fields.one2many('kdvn.report.contract.to.client','id','Contract Client Report')
              }
kdvn_contract_client()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# File : core.classifiers.RCNLPTextClassifier.py
# Description : Echo State Network for text classification.
# Auteur : Nils Schaetti <nils.schaetti@unine.ch>
# Date : 01.02.2017 17:59:05
# Lieu : Nyon, Suisse
#
# This file is part of the Reservoir Computing NLP Project.
# The Reservoir Computing Memory Project is a set of free software:
# you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Foobar is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
#

import argparse
from core.tools.RCNLPLogging import RCNLPLogging
import core.clustering.functions as cf
import numpy as np
import os
from scipy.stats import ttest_1samp
import pickle
from core.converters.RCNLPPosConverter import RCNLPPosConverter
from core.converters.RCNLPTagConverter import RCNLPTagConverter
from core.converters.RCNLPFuncWordConverter import RCNLPFuncWordConverter
from core.converters.RCNLPWordVectorConverter import RCNLPWordVectorConverter

#########################################################################
#
# Experience settings
#
#########################################################################

# Exp. info
ex_name = "Author clustering Experience"
ex_instance = "Author clustering One Reservoir"

# Reservoir Properties
rc_leak_rate = 0.5  # Leak rate
rc_input_scaling = 0.5  # Input scaling
rc_size = 500  # Reservoir size
rc_spectral_radius = 0.99  # Spectral radius
rc_w_sparsity = 0.1
rc_input_sparsity = 0.2

####################################################
# Main function
####################################################

if __name__ == "__main__":

    # Argument parser
    parser = argparse.ArgumentParser(description="RCNLP - Author clustering with Part-Of-Speech to Echo State Network")

    # Argument
    parser.add_argument("--texts", type=str, help="Text directory.")
    parser.add_argument("--startup", type=int, help="Number of start-up states to remove.", default=20)
    parser.add_argument("--out-components", type=int, help="Number of principal component to reduce reservoir states.", default=-1)
    parser.add_argument("--in-components", type=int, help="Number of principal component to reduce inputs.", default=-1)
    parser.add_argument("--homogene", action='store_true', help="Keep the same number of states for each authors.",
                        default=False)
    parser.add_argument("--pca-images", action='store_true', help="Generate image of principal components.",
                        default=False)
    parser.add_argument("--converter", type=str, help="The text converter to use (fw, pos, tag, wv).")
    parser.add_argument("--lang", type=str, help="Language model", default='en')
    parser.add_argument("--show-states", type=int, help="Number of states to show", default=500)
    parser.add_argument("--samples", type=int, help="Samples to estimate performances", default=20)
    parser.add_argument("--nreservoir", type=int, help="Number of reservoir to generate.", default=20)
    parser.add_argument("--pca-model", type=str, help="PCA model to load", default='')
    parser.add_argument("--output", type=str, help="Where to save the reservoir.", default="reservoir.p")
    args = parser.parse_args()

    # Logging
    logging = RCNLPLogging(exp_name=ex_name, exp_inst=ex_instance,
                           exp_value=RCNLPLogging.generate_experience_name(locals()))
    logging.save_globals()
    logging.save_variables(locals())

    # PCA model
    pca_model = None
    if args.pca_model != "":
        pca_model = pickle.load(open(args.pca_model, 'r'))
    # end if

    # Results
    state_results = np.array([])
    doc_results = np.array([])

    # >> 1. Convert the text to symbolic or continuous representations
    if args.converter == "pos":
        converter = RCNLPPosConverter(resize=args.in_components, pca_model=pca_model)
    elif args.converter == "tag":
        converter = RCNLPTagConverter(resize=args.in_components, pca_model=pca_model)
    elif args.converter == "fw":
        converter = RCNLPFuncWordConverter(resize=args.in_components, pca_model=pca_model)
    else:
        converter = RCNLPWordVectorConverter(resize=args.in_components, pca_model=pca_model)
        # end if

    # Whathever
    max_score = 0.0

    # Iterate over reservoirs
    for r in range(args.nreservoir):
        # Create a reservoir
        flow = cf.create_reservoir(converter.get_n_inputs(), rc_size, rc_input_scaling, rc_leak_rate, rc_spectral_radius,
                                   rc_input_sparsity, rc_w_sparsity)

        # Iterate
        for i in np.arange(0, args.samples):
            authors_id = np.random.choice(49, 2, replace=False) + 1
            texts1 = os.path.join(args.texts, str(authors_id[0]))
            texts2 = os.path.join(args.texts, str(authors_id[1]))
            print("Round %d with author %s and %s" % (i, texts1, texts2))
            state_score, doc_score = cf.clustering_states(args=args, texts1=texts1, texts2=texts2, ex_name=ex_name,
                                                          ex_instance=ex_instance, input_scaling=rc_input_scaling,
                                                          input_sparsity=rc_input_sparsity, leak_rate=rc_leak_rate,
                                                          logging=logging, size=rc_size, spectral_radius=rc_spectral_radius,
                                                          w_sparsity=rc_w_sparsity, save_graph=True if i == 0 else False,
                                                          pca_model=pca_model, flow=flow)

            # Log results
            #logging.save_results("V state score " + str(i), state_score, display=True)
            #logging.save_results("V doc score " + str(i), doc_score, display=True)

            # Save results
            state_results = np.append(state_results, state_score)
            doc_results = np.append(doc_results, doc_score)
        # end for

        # Log overall state results
        print("#############################################################################")
        logging.save_results("Overall state score", np.average(state_results), display=True)
        logging.save_results("Overall state score std", np.std(state_results), display=True)
        logging.save_results("State score T-test", ttest_1samp(state_results, 0).pvalue * 100.0, display=True)

        # Log overall doc results
        logging.save_results("Overall doc score", np.average(doc_results), display=True)
        logging.save_results("Overall doc score std", np.std(doc_results), display=True)
        logging.save_results("Doc score T-test", ttest_1samp(doc_results, 0).pvalue * 100.0, display=True)

        # Save reservoir
        if np.average(doc_results) > max_score:
            pickle.dump(flow, open(args.output, 'w'))
        # end if
    # end for

    # Open logging dir
    logging.open_dir()

# end if


import torch
from torch import nn
import torch.optim as optim

from utils import evaluation

def training(batch_size, n_epoch, lr, model_dir, train, valid, model, device):
    # Keep the loss and accuracy at every iteration for plotting
    train_loss_list = []
    valid_loss_list = []
    train_acc_list = []
    valid_acc_list = []

    # print model status
    total = sum(p.numel() for p in model.parameters())
    trainable = sum(p.numel() for p in model.parameters() if p.requires_grad)
    print('\nstart training, parameter total:{}, trainable:{}\n'.format(total, trainable))

    # model params
    criterion = nn.BCELoss() #binary cross entropy loss
    t_batch_num = len(train)
    v_batch_num = len(valid)
    optimizer = optim.Adam(model.parameters(), lr=lr)
    #optimizer = torch.optim.SGD(model.parameters(), lr, momentum=0.9, weight_decay=1e-4)
    #optimizer = optim.Adadelta(model.parameters(), lr=lr) #lr=1

    # training loop
    model.train()
    train_total_loss, train_total_acc, best_acc, best_loss = 0, 0, 0, 10000
    for epoch in range(n_epoch):
        # training
        train_total_loss, train_total_acc = 0, 0
        for i, (inputs, labels) in enumerate(train):
            inputs = inputs.to(device, dtype=torch.long) # device is "cuda" inputs to torch.cuda.LongTensor
            labels = labels.to(device, dtype=torch.float) # device is "cuda" labels to torch.cuda.FloatTensor
            optimizer.zero_grad() # duo to loss.backward(), gradient will accumulate，so we need to zero it every batch
            outputs = model(inputs)
            outputs = outputs.squeeze() # squeeze (batch_size,1) to (batch_size)
            loss = criterion(outputs, labels) # calculate training loss
            loss.backward() # compute gradient from loss
            optimizer.step() # update model parameters

            correct = evaluation(outputs, labels)
            train_total_acc += (correct / batch_size)
            train_total_loss += loss.item()
            print('[ Epoch{}: {}/{} ] '.format(epoch+1, i+1, t_batch_num), end='\r')
        print('\nTrain | Loss:{:.5f} Acc: {:.3f}'.format(train_total_loss/t_batch_num, train_total_acc/t_batch_num*100))

        # validation
        model.eval() # set model to eval mode，fix model parameters
        with torch.no_grad():
            valid_total_loss, valid_total_acc = 0, 0
            for i, (inputs, labels) in enumerate(valid):
                inputs = inputs.to(device, dtype=torch.long)
                labels = labels.to(device, dtype=torch.float)
                outputs = model(inputs)
                outputs = outputs.squeeze()
                loss = criterion(outputs, labels)
                correct = evaluation(outputs, labels)
                valid_total_acc += (correct / batch_size)
                valid_total_loss += loss.item()

            print("Valid | Loss:{:.5f} Acc: {:.3f} ".format(valid_total_loss/v_batch_num, valid_total_acc/v_batch_num*100))
            if valid_total_acc > best_acc or valid_total_loss < best_loss:
                best_acc = valid_total_acc
                best_loss = valid_total_loss
                torch.save(model, "{}/ckpt_{}.model".format(model_dir,valid_total_acc/v_batch_num*100))
                print('saving model with acc {:.3f}'.format(valid_total_acc/v_batch_num*100))
        print('-----------------------------------------------')
        model.train() # set model to train mode，let model parameters updatable

        # store acc and loss result
        train_loss_list.append(train_total_loss/t_batch_num)
        valid_loss_list.append(valid_total_loss/v_batch_num)
        train_acc_list.append(train_total_acc/t_batch_num*100)
        valid_acc_list.append(valid_total_acc/v_batch_num*100)

    # plotting result
    import matplotlib.pyplot as plt

    # Loss curve
    plt.plot(train_loss_list)
    plt.plot(valid_loss_list)
    plt.title('Loss')
    plt.legend(['train', 'valid'])
    plt.savefig('loss.png')
    plt.show()

    # Accuracy curve
    plt.plot(train_acc_list)
    plt.plot(valid_acc_list)
    plt.title('Accuracy')
    plt.legend(['train', 'valid'])
    plt.savefig('acc.png')
    plt.show()


import pymongo

conn = pymongo.MongoClient('localhost',27017)

db = conn.stu

myset = db.class0

# -------------索引操作---------------------------

# index_name = myset.create_index('name')

# index_name = myset.create_index([('age',-1)],name='Age')
# print(index_name)

# 创建其他类型索引
# index_name = myset.create_index([('name',1),('age',1)],sparse=True)

# 删除索引
# myset.drop_index('name_1')

# myset.drop_indexes()    # 删除所有索引

# list_indexes = myset.list_indexes() #查看索引

# for x in list_indexes:
#     print(x)

# ---------------------------聚合操作-------------------------------------

# l = [
#     {'$group':{'_id':'$gender','num':{'$sum':1}}}
# ]
# cursor = myset.aggregate(l)
# for i in cursor:
#     print(i)

conn.close()


import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
import random
tf.set_random_seed(777)  # for reproducibility

# Check out https://www.tensorflow.org/get_started/mnist/beginners for
# more information about the mnist dataset
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
batch_xs, batch_ys = mnist.train.next_batch(100)

nb_classes = 10
learning_rate = 0.001
keep_prob = tf.placeholder(tf.float32)

# MNIST data image of shape 28 * 28 = 784
X = tf.placeholder(tf.float32, [None, 784])
# 0 - 9 digits recognition = 10 classes
Y = tf.placeholder(tf.float32, [None, nb_classes])

W1 = tf.get_variable('W1', shape=[784, 512],
                    initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.Variable(tf.random_normal([512]))
L1 = tf.nn.relu(tf.matmul(X, W1) + b1)
L1 = tf.nn.dropout(L1, keep_prob=keep_prob)

W2 = tf.get_variable('W2', shape=[512, 512],
                    initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.Variable(tf.random_normal([512]))
L2 = tf.nn.relu(tf.matmul(L1, W2) + b2)
L2 = tf.nn.dropout(L2, keep_prob=keep_prob)

W3 = tf.get_variable('W3', shape=[512, 512],
                    initializer=tf.contrib.layers.xavier_initializer())
b3 = tf.Variable(tf.random_normal([512]))
L3 = tf.nn.relu(tf.matmul(L2, W3) + b3)
L3 = tf.nn.dropout(L3, keep_prob=keep_prob)

W4 = tf.get_variable('W4', shape=[512, 512],
                    initializer=tf.contrib.layers.xavier_initializer())
b4 = tf.Variable(tf.random_normal([512]))
L4 = tf.nn.relu(tf.matmul(L3, W4) + b4)
L4 = tf.nn.dropout(L4, keep_prob=keep_prob)

W5 = tf.get_variable('W5', shape=[512, nb_classes],
                    initializer=tf.contrib.layers.xavier_initializer())
b5 = tf.Variable(tf.random_normal([nb_classes]))
hypothesis = tf.matmul(L4, W5) + b5

# Cross entropy cost/loss function
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

# Test model
is_correct = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
# Calculate accuracy
accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))

# parameters
training_epochs = 15
batch_size = 100

with tf.Session() as sess:
    # Initialize TensorFlow variables
    sess.run(tf.global_variables_initializer())

    # Training cycle
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(mnist.train.num_examples / batch_size)

        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            c, _ = sess.run([cost, optimizer], feed_dict={X: batch_xs, Y: batch_ys, keep_prob: 0.7})
            avg_cost += c / total_batch

        print('Epoch: ', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))

    print ("Accuracy: ", accuracy.eval(session=sess,
            feed_dict={X: mnist.test.images, Y: mnist.test.labels, keep_prob: 1}))

    # Get one and predict
    # r = random.randint(0, mnist.test.num_examples - 1)
    # print("Label:", sess.run(tf.argmax(mnist.test.labels[r:r+1], 1)))
    # print("Prediction:", sess.run(tf.argmax(hypothesis, 1),
    #                         feed_dict={X: mnist.test.images[r:r+1]}))

    # plt.imshow(mnist.test.images[r:r+1].
    #             reshape(28, 28), cmap='Greys', interpolation='nearest')
    # plt.show()


import sys
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)

severities = sys.argv[1:]

result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
for severity in severities:
    channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key=severity)

channel.basic_consume(queue=queue_name,
                        auto_5ack=True,
                        uu7ib=callback)

print(' [*] Waiting for messages. To exit press CTRL+C')

channel.start_consuming()


#! /usr/bin/env python

import pygame, sys, time, string
from pygame.locals import *
from companyState import *

pygame.init()
blue = 0, 0, 255
background = 0,0,0
font = pygame.font.Font(None, 36)

def header(screen, companyState):

	screen.fill(background)

	width = screen.get_width()
	height = screen.get_height()

	# Draw header line
	point1 = 0, 30
	point2 = screen.get_width(), 30
	pygame.draw.line(screen, blue, point1, point2)

	# Draw company name in header text
	text = font.render(companyState.companyName, 1, blue)
	screen.blit(text, (2, 5))

	# Draw day in header text
	text = font.render(str(companyState.day), 1, blue)
	screen.blit(text, (width-30, 5))

	return screen

def main():

	company = CompanyState("Tinder")

	screen = pygame.display.set_mode((640, 400))
	running = True
	screen.fill((0, 0, 0))

	while running:
        # events for txtbx
		events = pygame.event.get()
        # process other events
		for event in events:
			# close it x button si pressed
			if event.type == QUIT: return

		screen = header(screen, company)
		pygame.display.flip()

		company.tickTime()
		time.sleep(2)

if __name__ == '__main__':
	main()


# This is the MIT license: http://www.opensource.org/licenses/mit-license.php
#
# Copyright (c) 2005-2012 the SQLAlchemy authors and contributors <see AUTHORS file>.
# SQLAlchemy is a trademark of Michael Bayer.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
# to whom the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or
# substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
# FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

from __future__ import absolute_import
from __future__ import unicode_literals
import jaydebeapi
import os
import logging
from .base import DrillDialect, DrillCompiler_sadrill

class DrillDialect_jdbc(DrillDialect):
    jdbc_db_name = "drill"
    jdbc_driver_name = "org.apache.drill.jdbc.Driver"

    statement_compiler = DrillCompiler_sadrill
    logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)

    def __init__(self, *args, **kwargs):
        super(DrillDialect_jdbc, self).__init__(*args, **kwargs)
        self.jdbc_driver_path = os.environ.get('DRILL_JDBC_DRIVER_PATH')
        self.jdbc_jar_name = os.environ.get('DRILL_JDBC_JAR_NAME')

        if self.jdbc_driver_path is None:
            raise Exception('To connect to Drill via JDBC, you must set the DRILL_JDBC_DRIVER path to the location of the Drill JDBC driver.')

        if self.jdbc_jar_name is None:
            raise Exception(
                'To connect to Drill via JDBC, you must set the DRILL_JDBC_JAR_NAME environment variable.')

    def initialize(self, connection):
        super(DrillDialect_jdbc, self).initialize(connection)

    """
    Open a connection to a database using a JDBC driver and return
        a Connection instance.
        jclassname: Full qualified Java class name of the JDBC driver.
        url: Database url as required by the JDBC driver.
        driver_args: Dictionary or sequence of arguments to be passed to
               the Java DriverManager.getConnection method. Usually
               sequence of username and password for the db. Alternatively
               a dictionary of connection arguments (where `user` and
               `password` would probably be included). See
               http://docs.oracle.com/javase/7/docs/api/java/sql/DriverManager.html
               for more details
        jars: Jar filename or sequence of filenames for the JDBC driver
        libs: Dll/so filenames or sequence of dlls/sos used as shared
              library by the JDBC driver
        """
    def create_connect_args(self, url):
        if url is not None:
            params = super(DrillDialect, self).create_connect_args(url)[1]
            driver = self.jdbc_driver_path + self.jdbc_jar_name

            cargs = (self.jdbc_driver_name,
                     self._create_jdbc_url(url),
                     [params['username'], params['password']],
                     driver)
            cparams = {p: params[p] for p in params if p not in ['host', 'username', 'password', 'port']}

            logging.info("Cargs:" + str(cargs))
            logging.info("Cparams" + str(cparams))

            return (cargs, cparams)

    def _create_jdbc_url(self, url):
        return "jdbc:drill:drillbit=%s:%s" % (
            url.host,
            url.port or 31010
        )

    @classmethod
    def dbapi(cls):
        return jaydebeapi

dialect = DrillDialect_jdbc


#!/usr/local/bin/python3.4
import kombu
from _socket import timeout
import os
import traceback
import sys
import pprint

from adhoc import TaxiLantern

def light_up_lantern(body, message):
    lantern = TaxiLantern(26)
    lantern.on()

try:
    connection = kombu.Connection(os.getenv('RABBIT_URL'))
    channel = connection.channel()
    queue = kombu.Queue('taxiLamp', durable=False, auto_delete=False)

    consumer = kombu.Consumer(channel, queues=queue, callbacks=[light_up_lantern])
    consumer.consume()

    try:
        connection.drain_events(timeout=1)
    except timeout as e:
        pass
    except connection.connection_errors + connection.channel_errors:
        connection.close()
        print("Host down, connecting to the next one.")
        connection.ensure_connection()
        channel = connection.channel()
        consumer = kombu.Consumer(channel, queues=queue, callbacks=[light_up_lantern])
        consumer.consume()

except Exception as e:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print("*** print_tb:")
    traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
    print("*** print_exception:")
    traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2, file=sys.stdout)
    pprint.pprint("Error = " + str(e))


import requests
import json
from urllib.request import urlopen
from bs4 import BeautifulSoup

# Función genérica que escribe un archivo a partir de un texto
# Puede utilizarse para escribir un archivo HTML copia local
# de la página que vamos a leer
def escribirArchivo(texto, archivo):
    f = open(archivo, "w")
    f.write(texto)
    f.close()

def devolverSoup(url):
  resp = requests.get(url)
  # resp = urlopen(url).read().decode('utf-8')

  if resp.status_code == 200:
    # print(resp.encoding)
    # resp.encoding = 'utf-8'
    # print(resp.encoding)
    contenido = resp.content

    print(contenido)
    soup = BeautifulSoup(contenido, 'html.parser')
    return soup

# Función genérica que crea un archivo JSON de nombre "nombre" y
# con los datos "datos"
def crearJSON(nombre, datos):
  result = {}
  result[nombre] = datos

  with open(nombre + ".json", "w") as write_file:
    json.dump(result, write_file, indent=2)

# Función específica a la página y la información que queremos
# extraer
def extraerProductos(soup):
  productos = soup.find_all('tr')
  result = []

  for producto in productos:
    objProducto = {}

    # Recuperamos el nombre del producto y el primer precio en COP
    nombre = producto.find('td', class_='product-name')
    precio = producto.find('td', class_='price')

    # Para no tratar el encabezado
    if None in (nombre, precio):
      continue

    objProducto['nombre'] = nombre.text.strip()
    precioAux = precio.text.strip().replace('$', '').replace(',', '.')
    objProducto['precio'] = float(precioAux)

    result.append(objProducto)

  return result

# Dada la URL, creamos un objeto soup que contiene la página
# Luego extraemos la información que necesitamos
# Finalemente creamos un archivo JSON con los datos extraidos
if __name__ == "__main__":

  url = "https://preciosmundi.com/colombia/precios-supermercado"

  soup = devolverSoup(url)
  productos = extraerProductos(soup)

  crearJSON("productos", productos)


import sys
from math import sqrt

def list_of_pcdfile(filename):
    pointcloud = []
    with open(filename, 'r') as f:
        for line in f:
            row = line.split()
            if row[0] not in ['VERSION', 'FIELDS', 'SIZE', 'TYPE', 'COUNT', 'WIDTH', 'HEIGHT', 'VIEWPOINT', 'POINTS', 'DATA']:
                p = [float(x) for x in row[:3]]
                pointcloud.append(p)
    return pointcloud

def squared_euclidean_distance(p,q):
    return sum((xp - xq) * (xp - xq) for xp,xq in zip(p,q))

def compute_diameter(pointcloud):
    squared_diameter = max(squared_euclidean_distance(p,q) for i,p in enumerate(pointcloud) for q in pointcloud[i+1:])
    return sqrt(squared_diameter)

def print_usage():
    print('SYNOPSIS')
    print()
    print('{} pcdfile'.format(sys.argv[0]))
    print('      Calculate the diameter of the pointcloud in <pcdfile>,')
    print('      i.e. the largest distance between two points in the cloud.')
    sys.exit(1)

def main():
    if len(sys.argv) == 2:
        print(compute_diameter(list_of_pcdfile(sys.argv[1])))
    else:
        print_usage()

if __name__=='__main__':
    main()


import unittest
import threading

from SingletonSetting import SingletonSetting

class TestSingleton(unittest.TestCase):
    singletonList = {}

    def test_threads_problem(self):

        threads = []
        for iterator in range(10):
            try:
                for i in range(10):
                    thread = threading.Thread(target=TestSingleton.make_setting_setting, name='th' + format(i),
                                              args=())
                    threads.append(thread)
                    thread.start()
            except:
                print("Error")

        for x in threads:
            x.join()

        print('\n\nsingleton list: ' + str(self.singletonList))
        print('singleton list length: ' + str(len(self.singletonList)))

    @classmethod
    def make_setting_setting(cls):
        obj = SingletonSetting()
        cls.singletonList[id(obj)] = obj
        return

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


s = input()
x = [int(i) for i in s.split()]
for i in range(len(x)):
    mini=x[i]
    index=i
    for j in range(i+1,len(x)):
        if (x[j]<mini):
            mini=x[j]
            index=j
    x[i],x[index]=x[index],x[i]
q=[]
for i in range(len(x) - 1):
    b=x[i]-x[i+1]
    q.append(b)
n=0
for j in range(len(q)-1):
    if (q[j]==q[j+1]):
        n=n+1
if (n==len(q)-1):
    print("possible")
else:
    print("impossible")


"""
Exercice 2
On désire réaliser un programme qui permet de simuler le fonctionnement d’une calculatrice.
L’utilisateur saisit en entrée 2 nombres et choisit un nombre compris entre 1 et 4 pour l’opération
1: addition
2: soustraction
3: multiplication
4: division
Donner une deuxième version de l’algorithme pour laquelle il faudra gérer une possible erreur de
l’utilisateur pour indiquer l’opération.
----------
L'utilisateur saisi deux nombres (a et b)
Puis il saisi un nombre associé à une opération (1: addition ; 2: soustraction ; 3: multiplication ; 4: division)
L'utilisateur peut faire une erreur dans ce cas de figure dans la sélection d'opération
Le programme réalise et affiche l'opération
----------
début
Lire(a)
a = entier
Lire(b)
b = entier

Verif_num = Faux
Verif_ope = Faux

Tant que Verif_num est Faux Et Verif_ope est Faux:
    num_oper = Lire("Saisisez un nombre associé à une opération (1: addition ; 2: soustraction ; 3: multiplication ; 4: division) : ")

    Lire(num_oper)
    Essayez:
        num_oper = entier(num_oper)
    Exceptiion Pas Entier:
        Afficher("Ce que vous avez saisi n'est pas un nombre.")
        Verif_num = Faux
        continuer
    else:
        num_oper = entier(num_oper)
        Verif_num = Vrai

si num_oper == 1:
    afficher(a, "+", b, "=", a + b)
    Verif_ope = Vrai
sinon si num_oper == 2:
    afficher(a, "-", b, "=", a - b)
    Verif_ope = Vrai
sinon si num_oper == 3:
    afficher(a, "*", b, "=", a * b)
    Verif_ope = Vrai
sinon si num_oper == 4:
    afficher(a, "/", b, "=", a / b)
    Verif_ope = Vrai
sinon:
    afficher("Je n'ai pas compris votre demande, veuillez réitérer s'il vous plais.")
    Verif_num = Faux
    continuer
fin
"""
a = input("Saisisez un premier nombre : ") # Affectation du premier nombre
a = int(a)
b = input("Saisisez un second nombre : ") # Affectation du second nombre
b = int(b)

Verif_num = False # booléen permettant de vérifier si le nombre donné en est bien un, il est faux par défaut
Verif_ope = False # booléen permettant de vérifier si le nombre fait bien partie de l'ensemble 1, 2, 3, 4, il est faux par défaut

while Verif_num is False and Verif_ope is False:
    num_oper = input("Saisisez un nombre associé à une opération (1: addition ; 2: soustraction ; 3: multiplication ; 4: division) : ")
    # Affectation du nombre permettant de selectionner l'opération ciblée

    try: # test permettant de vérifier si le nombre n'est pas une chaîne de caractère
        num_oper = int(num_oper)
    except ValueError:
        print()
        print("Ce que vous avez saisi n'est pas un nombre.")
        Verif_num = False
        continue
    else:
        num_oper = int(num_oper)
        Verif_num = True

    if num_oper == 1: # condition permettant d'affecter l'opération ciblée (si le bon nombre est choisi) aux deux nombres
        print(a, "+", b, "=", a + b)
        Verif_ope = True
    elif num_oper == 2:
        print(a, "-", b, "=", a - b)
        Verif_ope = True
    elif num_oper == 3:
        print(a, "*", b, "=", a * b)
        Verif_ope = True
    elif num_oper == 4:
        print(a, "/", b, "=", a / b)
        Verif_ope = True
    else:
        print()
        print("Je n'ai pas compris votre demande, veuillez réitérer s'il vous plais.")
        Verif_num = False
        continue


import cv2 as cv
import numpy as np
from random import randint
import math as math
from population import *
from path import *
from point import *

global esc
esc = 27

class mainWindow:
    def __init__(self):
        self.heightmap = cv.imread('terrain.png')
        self.tmp_map = self.heightmap.copy()
        self.height, self.width = self.tmp_map.shape[:2]
        self.window_name = 'PAPAJ'
        self.mWindow = cv.namedWindow(self.window_name, cv.WINDOW_GUI_NORMAL)
        self.maphandle = cv.imshow(self.window_name, self.tmp_map)
        self.key = 155
        esc = 27
    def drawPath(self, path):
        cv.line(self.tmp_map, path.start_point.getPoint(), path.getPoint(0), (255, 0, 0), 1)
        for i in range(1, path.length):
            cv.line(self.tmp_map, path.getPoint(i-1), path.getPoint(i), (0, 255, 0), 1)
        cv.line(self.tmp_map, path.end_point.getPoint(), path.getPoint(path.length-1), (255, 0, 0), 1)
    def drawPop(self, _population):
        for i in range(0, len(_population.paths)):
            self.drawPath(_population.paths[i])


class Page():
    def __init__(self, page_num, total_count, url_prefix, per_page=10, max_page=8):
        self.url_prefix = url_prefix
        # 每一页显示多少条数据
        # 每一页数据数
        self.per_page = per_page
        # 总页码展示数
        total_page, m = divmod(total_count, self.per_page)
        if m:
            total_page += 1
            self.total_page = total_page
        # 从url中取参数
        try:
            self.page_num = int(page_num)
            # 当输入页数大于最后一页 默认返回最后一页
            if self.page_num > total_page:
                self.page_num = total_page
        except Exception as e:
            # 当输入不正经数字 默认返回第一页
            page_num = 1
            self.page_num = page_num
        # 定义两个变量保存数据从哪到哪
        self.data_start = (self.page_num - 1) * per_page  # 没有传就用默认的展示10个
        self.data_end = self.page_num * per_page  # 没有传就用默认的展示10个
        # 页面上共展示多少页码
        self.max_page = max_page
        if total_page < max_page:
            max_page = total_page
        half_max_page = max_page // 2
        # 页面上展示的页码从哪里开始
        page_start = self.page_num - half_max_page
        # 页面展示的页码到哪里结束
        page_end = self.page_num + half_max_page
        if page_start <= 1:
            page_start = 1
            page_end = max_page
        if page_end >= total_page:
            page_end = total_page
            page_start = total_page - max_page + 1
        self.page_start = page_start
        self.page_end = page_end

    @property
    def start(self):
        return self.data_start

    @property
    def end(self):
        return self.data_end

    def page_html(self):
        # 自己并接分业务的HTML代码
        html_list = []
        # 加上首页
        html_list.append('
首页
'.format(self.url_prefix))
        # 加上上一页
        if self.page_num <= 1:
            html_list.append('
«
')
        else:
            html_list.append('
«
'.format(
                self.url_prefix, self.page_num - 1))
        for i in range(self.page_start, self.page_end+1):
            # 如果是当前页就加一个active样式类
            if i == self.page_num:
                tmp = '
{1}
'.format(self.url_prefix, i)
            else:
                tmp = '
{1}
'.format(self.url_prefix, i)
            html_list.append(tmp)
        # 加上下一页
        if self.page_num >= self.total_page:
            html_list.append('
»
')
        else:
            html_list.append(
                '
»
'.format(self.url_prefix,
                                                                                self.page_num + 1))
        # 加最尾页
        html_list.append('
尾页
'.format(self.url_prefix, self.total_page))
        page_html = ''.join(html_list)
        return page_html


def merge_sort(numbers):
    """ 오름차순 병합 정렬을 실행합니다. """
    n = len(numbers)

    if n <= 1:
        return

    mid = n // 2
    left_group = numbers[:mid]
    right_group = numbers[mid:]

    merge_sort(left_group)
    merge_sort(right_group)

    left = 0
    right = 0
    now = 0

    while left < len(left_group) and right < len(right_group):
        if left_group[left] < right_group[right]:
            numbers[now] = left_group[left]
            left += 1
            now += 1
        else:
            numbers[now] = right_group[right]
            right += 1
            now += 1

    while left < len(left_group):
        numbers[now] = left_group[left]
        left += 1
        now += 1

    while right < len(right_group):
        numbers[now] = right_group[right]
        right += 1
        now += 1

if __name__ == '__main__':
    numbers = [6, 5, 6, 4, 3, 2, 1]

    merge_sort(numbers)

    print(numbers)


from flask import Flask, render_template, redirect
import pymongo
import scrape_weather

app = Flask(__name__)

conn = "mongodb://localhost:27017"
client = pymongo.MongoClient(conn)
db = client.weather
col = db.data

# weather_data = scrape_weather.scrape()
# from pprint import pprint
# pprint(weather_data['alabama'])
# col.remove()
# col.insert(weather_data)

@app.route("/")
def home():

    data = list(col.find())
    print ("squid")
    print (data)
    return render_template("index.html", weather=data)

@app.route("/scrape")
def scrape():

    weather_data = scrape_weather.scrape()
    col.insert(weather_data)
    print("start")
    print (list(col.find()))
    print("finish")
    return redirect("/")

@app.route("/hightemp")
def highmap():
    return render_template("hightemp.html", weather=data)

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


#%%
import os
from copy import deepcopy
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from tqdm import tqdm, trange
from arguments import get_args
from augmentations import get_aug
from models import get_model, get_backbone
from tools import AverageMeter
from datasets import get_dataset
from optimizers import get_optimizer, LR_Scheduler
from sklearn.manifold import TSNE
import plotly.express as px
import io
from PIL import Image
import imageio
import numpy as np
import cv2
import random

#%%
args=get_args(inputs=["--config_file=configs/simsiam_stream51.yaml", "--data_dir=../stream_data", "--log_dir=../alignment_logs", "--ckpt_dir=.cache/jitter0", "--preload_dataset", "--bbox_crop", "--eval_from=alignment_models/stream51-cifar_time_jittering_deterministic0.pth"])

# %%
torch.manual_seed(0)
random.seed(0)
np.random.seed(0)
args.eval.num_epochs = 10

args.dataset_kwargs['ordering'] = 'instance'
train_loader = torch.utils.data.DataLoader(
    dataset=get_dataset(
        transform=get_aug(train=True, train_classifier=False, **args.aug_kwargs),
        train=True,
        **args.dataset_kwargs
    ),
    batch_size=args.eval.batch_size,
    shuffle=True,
    **args.dataloader_kwargs
    )

test_loader = torch.utils.data.DataLoader(
    dataset=get_dataset(
        transform=get_aug(train=False, train_classifier=False, **args.aug_kwargs),
        train=False,
        **args.dataset_kwargs
    ),
    batch_size=args.eval.batch_size,
    shuffle=True,
    **args.dataloader_kwargs
    )
# %%
if args.eval_from is not None:
    print("Loading model from", args.eval_from)
    model = get_backbone(args.model.backbone)
    save_dict = torch.load(args.eval_from, map_location='cpu')
    msg = model.load_state_dict({k[9:]:v for k, v in save_dict['state_dict'].items() if k.startswith('backbone.')}, strict=True)
    print(msg)

    model.to(args.device)
else:
    print("Specify an eval_from")

# %%
with torch.no_grad():
    all_train_features = []
    train_outputs = {}
    for x in tqdm(train_loader):
        images = x[0]
        labels = x[-1]

        feature = model(images.to(args.device, non_blocking=True))
        for i_label in range(len(labels)):
            l = labels[i_label].item()
            f = feature[i_label].detach().cpu()
            if l not in train_outputs:
                train_outputs[l] = []
            train_outputs[l].append(f)
            all_train_features.append(f)

    all_train_features = torch.stack(all_train_features)
    for l in train_outputs:
        train_outputs[l] = (torch.stack(train_outputs[l]) - all_train_features.mean()) / all_train_features.std()
    all_train_features = (all_train_features - all_train_features.mean()) / all_train_features.std()

# %%
with torch.no_grad():
    all_test_features = []
    test_outputs = {}
    for x in tqdm(test_loader):
        images = x[0]
        labels = x[-1]

        feature = model(images.to(args.device, non_blocking=True))
        for i_label in range(len(labels)):
            l = labels[i_label].item()
            f = feature[i_label].detach().cpu()
            if l not in test_outputs:
                test_outputs[l] = []
            test_outputs[l].append(f)
            all_test_features.append(f)

    all_test_features = torch.stack(all_test_features)
    for l in test_outputs:
        test_outputs[l] = (torch.stack(test_outputs[l]) - all_test_features.mean()) / all_test_features.std()
    all_test_features = (all_test_features - all_test_features.mean()) / all_test_features.std()
# %%

def align_loss(x, y, device, alpha=2, batch_size=512):
    align_loss = 0.
    for i in range(0, len(x), batch_size):
        x_batch = x[i:i+batch_size].to(device)
        y_batch = y[i:i+batch_size].to(device)
        align_loss += (x_batch - y_batch).norm(p=2, dim=1).pow(alpha).mean().item()
    return align_loss

def uniform_loss(x, device, t=2, batch_size=512):
    uniform_loss = 0.
    n = 0
    for i in range(0, len(x), batch_size):
        x_batch = x[i:i+batch_size].to(device)
        uniform_loss = (n / (n + 1.)) * uniform_loss + (1 / (n + 1.)) * torch.pdist(x_batch, p=2).pow(2).mul(-t).exp().mean().log().item()
        n += 1.
        print(uniform_loss)
    return uniform_loss
# %%

with torch.no_grad():
    train_uniform_metric = uniform_loss(all_train_features, args.device)
    test_uniform_metric = uniform_loss(all_test_features, args.device)
train_uniform_metric
test_uniform_metric
# %%


import numpy as np
import matplotlib.pyplot as plt

class Regression:
    '''Implement of multi dimensional linear regression.'''
    def __init__(self, learning_rate):
        self.learning_rate = learning_rate

    # Compute hypothesis value.
    def _predict(self, independence_set, constant, weights):
        return np.dot(independence_set, weights) + constant

    # Compute sum square error.
    def _sse(self, predict_value, observe_var):
        return ((predict_value - observe_var) ** 2).sum()

    # Train regression model with observe data.
    def learning(self, observe_var, *independence_var):
        # Declare tracking variables and define constant value.
        weights_list = list()
        constant_list = list()
        sse_list = list()
        predict_list = list()
        cost_factor1 = 2 * self.learning_rate
        constant = 0

        independence_set = np.stack([*independence_var], 1)  # Compress dimensions data into single variable.
        weights = np.zeros(independence_set.shape[1])  # Define start value of weight.
        weights_list.append(weights)  # Add first weights set to weight tracking variable
        constant_list.append(constant)  # Add first constant to constant tracking variable.
        predict_value = self._predict(independence_set, constant, weights)  # Compute first predict value.
        sse = self._sse(predict_value, observe_var)  # Compute first sum square error.
        predict_list.append(predict_value)  # Add first predict value to predict tracking variable.
        sse_list.append(sse)  # Add first sse value to sse tracking variable.

        while True:
            cost_factor2 = (predict_value - observe_var) * cost_factor1  # Compute cost value factor.
            weights -= np.dot(cost_factor2, independence_set)  # Adjust weight value of each dimension.
            constant -= cost_factor2.sum()  # Adjust weight value.
            weights_list.append(weights)  # Add each weight set to weight tracking variable.
            constant_list.append(constant)  # Add each constant to constant tracking variable.
            predict_value = self._predict(independence_set, constant, weights)  # Compute predict value.
            sse = self._sse(predict_value, observe_var)  # Compute sse value.
            predict_list.append(predict_value)  # Add predict value to predict tracking variable.

            # If new sum square error greater and equal to previous sum square error add current sum square error into
            # sum square error tracking variable and get out of loop.
            if not (sse < sse_list[-1]):
                sse_list.append(sse)
                break
            # Otherwise add current sum square error and continue loop.
            sse_list.append(sse)

        return {'weights_list': weights_list, 'constant_list': constant_list,
                'predict_list': predict_list, 'sse_list': sse_list}

# This function used to plot sum square error graph.
def sse_graph(sse):
    plt.figure()  # Create figure for plotting.
    plt.gca(yscale='log')  # Define y axis to logarithmic scale.
    plt.title('Sum Square Error')  # Define title of figure.
    plt.plot(sse)  # Plot sse value.
    plt.show()  # Display graph.

independent_var1 = np.random.uniform(5, 10, 50)  # Random first examples data set uniformly.
independent_var2 = np.random.uniform(5, 10, 50)  # Random second examples data set uniformly.

observe_var = 3 * independent_var1 + 2 * independent_var2 + 10 + np.random.randn(50) * 3  # Observed data set.
regress = Regression(0.0001)  # Instantiate regression object.
# Compute regression environment values.
regress_vals = regress.learning(observe_var, independent_var1, independent_var2)
sse_graph(regress_vals['sse_list']) # Plot sum square error graph.


import sys
import os
import json
import make_arch as march

def main():
	# path 0: memcached cache hit
	nodeList = []

	node_0 = march.make_serv_path_node(servName = "nginx", servDomain = "", codePath = 0, startStage = 0, endStage = -1,
		nodeId = 0, needSync = False, syncNodeId = None, childs = [1])
	nodeList.append(node_0)

	node_1 = march.make_serv_path_node(servName = "memcached", servDomain = "", codePath = -1, startStage = 0, endStage = -1,
		nodeId = 1, needSync = False, syncNodeId = None, childs = [2])
	nodeList.append(node_1)

	node_2 = march.make_serv_path_node(servName = "nginx", servDomain = "", codePath = 1, startStage = 0, endStage = -1,
		nodeId = 2, needSync = False, syncNodeId = None, childs = [3])
	nodeList.append(node_2)

	node_3 = march.make_serv_path_node(servName = "client", servDomain = "", codePath = -1, startStage = 0, endStage = -1,
		nodeId = 3, needSync = False, syncNodeId = None, childs = [])
	nodeList.append(node_3)

	path_memc_hit = march.make_serv_path(pathId = 0, entry = 0, prob = 0.5, nodes = nodeList)

	# path 1: memcached miss & mongodb hit
	nodeList = [node_0, node_1, node_2]
	# php_fcgi_req
	node_3 = march.make_serv_path_node(servName = "php", servDomain = "", codePath = 0, startStage = 0, endStage = 0,
		nodeId = 3, needSync = True, syncNodeId = 5, childs = [4])
	nodeList.append(node_3)

	node_4 = march.make_serv_path_node(servName = "php_io", servDomain = "", codePath = 0, startStage = 0, endStage = -1,
		nodeId = 4, needSync = False, syncNodeId = None, childs = [5])
	nodeList.append(node_4)

	# php_fopen
	node_5 = march.make_serv_path_node(servName = "php", servDomain = "", codePath = 0, startStage = 0, endStage = 1,
		nodeId = 5, needSync = True, syncNodeId = 7, childs = [6])
	nodeList.append(node_5)

	node_6 = march.make_serv_path_node(servName = "php_io", servDomain = "", codePath = 1, startStage = 0, endStage = -1,
		nodeId = 6, needSync = False, syncNodeId = None, childs = [7])
	nodeList.append(node_6)

	# php_fput
	node_7 = march.make_serv_path_node(servName = "php", servDomain = "", codePath = 0, startStage = 1, endStage = 2,
		nodeId = 7, needSync = True, syncNodeId = 9, childs = [8])
	nodeList.append(node_7)

	node_8 = march.make_serv_path_node(servName = "mongodb", servDomain = "", codePath = 0, startStage = 0, endStage = -1,
		nodeId = 8, needSync = False, syncNodeId = None, childs = [9])
	nodeList.append(node_8)

	# php_find_done
	node_9 = march.make_serv_path_node(servName = "php", servDomain = "", codePath = 0, startStage = 2, endStage = 3,
		nodeId = 9, needSync = True, syncNodeId = 11, childs = [10])
	nodeList.append(node_9)

	node_10 = march.make_serv_path_node(servName = "mongodb", servDomain = "", codePath = 0, startStage = 0, endStage = -1,
		nodeId = 10, needSync = False, syncNodeId = None, childs = [11])
	nodeList.append(node_10)

	# php_get_bytes
	node_11 = march.make_serv_path_node(servName = "php", servDomain = "", codePath = 0, startStage = 3, endStage = 4,
		nodeId = 11, needSync = True, syncNodeId = 13, childs = [12])
	nodeList.append(node_11)

	node_12 = march.make_serv_path_node(servName = "memcached", servDomain = "", codePath = 1, startStage = 0, endStage = -1,
		nodeId = 12, needSync = False, syncNodeId = None, childs = [13])
	nodeList.append(node_12)

	# php_mmc_store
	node_13 = march.make_serv_path_node(servName = "php", servDomain = "", codePath = 0, startStage = 4, endStage = -1,
		nodeId = 13, needSync = False, syncNodeId = None, childs = [14])
	nodeList.append(node_13)

	node_14 = march.make_serv_path_node(servName = "nginx", servDomain = "", codePath = 2, startStage = 0, endStage = -1,
		nodeId = 14, needSync = False, syncNodeId = None, childs = [15])
	nodeList.append(node_14)

	node_15 = march.make_serv_path_node(servName = "client", servDomain = "", codePath = -1, startStage = 0, endStage = -1,
		nodeId = 15, needSync = False, syncNodeId = None, childs = [])
	nodeList.append(node_15)

	path_memc_miss_mongo_hit = march.make_serv_path(pathId = 1, entry = 0, prob = 0.25, nodes = nodeList)

	# path 2: memcached miss & mongodb miss
	nodeList = []

	# first access to mongo
	node_8 = march.make_serv_path_node(servName = "mongodb", servDomain = "", codePath = 1, startStage = 0, endStage = 1,
		nodeId = 8, needSync = True, syncNodeId = 19, childs = [18])

	node_18 = march.make_serv_path_node(servName = "mongo_io", servDomain = "", codePath = 0, startStage = 0, endStage = -1,
		nodeId = 18, needSync = False, syncNodeId = None, childs = [19])

	node_19 = march.make_serv_path_node(servName = "mongodb", servDomain = "", codePath = 1, startStage = 1, endStage = -1,
		nodeId = 19, needSync = False, syncNodeId = None, childs = [9])

	# second access to mongo, should also access mongo_io, here just for testing internal chunking
	node_10 = march.make_serv_path_node(servName = "mongodb", servDomain = "", codePath = 1, startStage = 0, endStage = -1,
		nodeId = 10, needSync = False, syncNodeId = None, childs = [11])

	nodeList = [node_0, node_1, node_2, node_3, node_4, node_5, node_6, node_7, node_8, node_9, node_10, node_11, node_12,
		node_13, node_14, node_15, node_18, node_19]

	path_memc_miss_mongo_miss = march.make_serv_path(pathId = 2, entry = 0, prob = 0.25, nodes = nodeList)

	paths = [path_memc_hit, path_memc_miss_mongo_hit, path_memc_miss_mongo_miss]

	with open("./json/path.json", "w+") as f:
		json.dump(paths, f, indent=2)

if __name__ == "__main__":
	main()


'''
Si definiscono divisori propri di un numero tutti i suoi divisori tranne l'uno e il numero stesso.
Scrivere una funzione modi(ls,k) che, presa una lista ls di interi  ed un intero
non negativo k:
    1) cancella  dalla lista ls gli interi che non hanno esattamente k divisori propri
    2) restituisce una seconda lista che contiene i soli numeri primi di ls.
NOTA: un numero maggiore di 1 e' primo se ha 0 divisori propri.

ad esempio per ls = [121, 4, 37, 441, 7, 16]
modi(ls,3) restituisce la lista con i numeri primi [37,7] mentre al termine della funzione si avra' che la lista ls=[16]

Per altri  esempi vedere il file grade.txt

ATTENZIONE: NON USATE LETTERE ACCENTATE.
ATTENZIONE: Se il grader non termina entro 30 secondi il punteggio dell'esercizio e' zero.
'''

def modi(ls,k):
    la=[]
    primi=[]
    for numero in ls:
        conteggio=calcola(numero)
        if conteggio==k: #se iil conteggio è uguale a k appende il numero ad la
            la.append(numero)
        elif conteggio==0:#se il conteggio è uguale a 0 appende il numero a primi
            primi.append(numero)
    ls=modifica(ls,la)
    return primi

def calcola(numero):
    '''ritorna il numero dei divisori'''
    lista=[]
    n=2
    while n<int(numero/2)+1 and n<=numero//n: #per tutti gli n da 2 fino al numero/2 se n<=numero/n
        if numero%n==0 : #se n è un divisore appende alla lista sia n sia numero/n
            lista.append(n)
            lista.append(numero//n)
        n+=1
    return len(lista) #ritorna il numero degli elementi della lista ossia il numero dei divisori

def modifica(l1,l2):
    '''modifica l'originale l1'''
    i=0
    while i<len(l1):
        if l1[i] not in l2:
            l1.remove(l1[i]) #elimina tutti gli elementi di l1 che non sono in l2
        else:
            i+=1
    return l1 #ritorna la nuova l1 che viene sostituita all'originale


# Wyświetlanie posortowanej listy wprowadzonej przez użytkownika

scores = []
score = input("Podaj wynik (pusty wynik oznacza koniec rejestrowania wyników): ")

while score:
    scores.append(int(score))
    score = input("Podaj wynik (pusty wynik oznacza koniec rejestrowania wyników): ")

scores.sort()

print("\nWyniki:", end=' ')
for i in range(len(scores)):
    print(scores[i], end=' ')

scores.sort(reverse=True)

print("\nWyniki odwrotnie:", end=' ')
for i in range(len(scores)):
    print(scores[i], end=' ')