'''
This file contains a class that are mainly used to do a pre processing step of the
image to be analyzed. The idea of this preprocessing is to make the segmentation step
easier / simpler. It might not be neccesary to do the preprocessing, but as a first
idea, needs to be considered.

The implemented class contains a flag in the constructor that enables or disables the
preprocessing step, so in order to disable, we only change a True by a False on construction
and that's it.
'''

import copy
import os

import numpy as np
import cv2
from scipy import ndimage
from skimage.filters import threshold_otsu

class ImagePreprocessing(object):
    '''
    Class that will make some treatments to the provided image.
    It can be enabled or disabled. If disabled, the output image will
    be directly the input.
    '''
    def __init__(self, is_preprocessing_enabled):
        '''
        Constructor

        Args:
            is_preprocessing_enabled: Boolean flag. If it is True, the module will
                process the image when preprocess_image method is called.
        '''
        self.enabled = is_preprocessing_enabled

        # We load a reference MRI image for the histogram transfer
        dirpath = os.path.dirname(os.path.realpath(__file__))
        filepath = os.path.join(dirpath, 'reference_mri.png')
        self.reference_img = cv2.imread(filepath, cv2.IMREAD_UNCHANGED)
        if self.reference_img is None:
            raise IOError("Cannot open the reference image located at {fp}".format(fp=filepath))

    def is_module_enabled(self):
        return self.enabled

    def set_enable(self, val):
        self.enabled = val

    def preprocess_image(self, img, processes):
        '''
        Apply some Image processing to the input in order to generate an easy
        to segment image.

        Args:
            img: Input image to process
            processes: List of tuples that contains the desired processes that want
                to be applied to the input image. The first element of the tuple must
                be the name of the processes to be applied and the second one,
                the argument of such process. The supported processes are:
                    ('smoothing', size_of_window - odd integer)
                    ('remove_bits', amount_of_bits_to_remove - Integer between 0 and 7)
                    ('histogram_eq', 0)
                    ('transfer_histogram', 0)
                    ('median_filter', window_size)
                    ('edge_detector', 0)
                    ('thresholding', 0)
                    ('gaussian_smoothing', 0)
                    ('edge_reinforcement', edge_contribution)

        Returns:
            Processed image
        '''
        if self.enabled:
            final_img = np.array(img, dtype=np.uint8)
            if len(final_img.shape) == 2:
                final_img = final_img.reshape(final_img.shape + (1,))

            for proc in processes:
                if proc[0] == 'smoothing':
                    final_img = self.smooth_filtering(final_img, proc[1])

                elif proc[0] == 'gaussian_smoothing':
                    final_img = self.gaussian_filter(final_img)

                elif proc[0] == 'remove_bits':
                    final_img = self.remove_smaller_bits(final_img, proc[1])

                elif proc[0] == 'histogram_eq':
                    final_img = self.histeq(final_img)

                elif proc[0] == 'transfer_histogram':
                    for i in range(final_img.shape[2]):
                        final_img = self.transfer_one_band_histogram(self.reference_img, final_img, band=i)

                elif proc[0] == 'median_filter':
                    final_img = self.median_filtering(final_img, proc[1])

                elif proc[0] == 'edge_detector':
                    final_img = self.edge_detection(final_img)

                elif proc[0] == 'edge_reinforcement':
                    final_img = self.edge_reinforcement(final_img, proc[1])

                elif proc[0] == 'thresholding':
                    final_img = self.image_thresholding(final_img)

            # Final reshaping
            final_img = final_img.reshape(img.shape)
            return final_img
        else:
            return copy.deepcopy(img)

    def image_thresholding(self, img):
        '''
        Convert image into binary image. It uses the Otsu threshold to binarize

        Args:
            img: Input image to binarize

        Returns:
            Binarized image. Values below the Otsu threshold are set to zero,
            and higher than threshold are set to 255
        '''
        out = copy.deepcopy(img)
        threshold = threshold_otsu(out)
        out[out < threshold] = 0
        # out[out >= threshold] = 255
        return out

    def edge_reinforcement(self, image, edge_weight):
        '''
        Increase the edges intensity. This function will do the edge detection
        and then make the sum of the resulting edges and the original image.

        Args:
            image: Input image
            edge_weight: Float. Value that indicates how important should be the edge
                in contrast with the original image value.

        Returns:
            Image with the edges reinforced
        '''
        edges = self.edge_detection(image)
        th_edges = self.image_thresholding(edges)
        denoised_img = self.gaussian_filter(image)
        output_img = (edge_weight * np.array(th_edges, dtype=np.float)) + np.array(denoised_img, dtype=np.float)
        # output_img[output_img > 255] = 255
        # return np.array(output_img, dtype=np.uint8)
        factor = 255.0 / np.max(output_img)
        return np.array(output_img * factor, dtype=np.int16)

    def edge_detection(self, img):
        '''
        Generate an image that contains only edges

        Args:
            img: input image from which we want to detect edges

        Returns:
            Image with edges only
        '''
        g_x = np.array([[-1,0,1],[-2,0,2],[-1,0,1]], dtype=np.float)
        g_y = np.array([[1,2,1],[0,0,0],[-1,-2,-1]], dtype=np.float)

        f_x = np.array(self.apply_convolution(img, g_x), dtype=np.float)
        f_y = np.array(self.apply_convolution(img, g_y), dtype=np.float)
        sobel_filtered = np.sqrt(np.power(f_x, 2) + np.power(f_y, 2))
        max_val = np.max(sobel_filtered) if np.max(sobel_filtered) > 0 else 1
        return np.array(sobel_filtered * (255.0 / max_val), dtype=np.uint8)

    def median_filtering(self, image, kernel_size):
        '''
        Apply median filtering to an image

        Args:
            image: Input image to filter
            kernel_size: Size of the filter to be applied. It is going to
                be same size of rows and columns. This number must be odd

        Returns:
            Filtered image
        '''
        if kernel_size % 2 == 0:
            raise ValueError("The kernel size must be an odd number. Provided: {n}".format(n=kernel_size))
        return ndimage.median_filter(image, 3)

    def remove_smaller_bits(self, input_img, bits_to_remove):
        '''
        Truncate to zero the smaller bits of the image values. This is a
        basic noise reduction technique.

        Args:
            input_img: Noise image to filter
            bits_to_remove: Amount of bits to remove from each image value.
                If this value is zero, then this function has no effect.
                The maximum allowed value is 7.

        Returns:
            Filtered image of the same size as the input image
        '''
        if bits_to_remove < 0 or bits_to_remove > 7:
            raise ValueError("Amount of bits to remove too big. Choose an integer number between 1 and 7")
        if type(bits_to_remove) != int:
            raise TypeError("bits_to_remove should be an integer. Type given {}".format(type(bits_to_remove)))

        mask = 255 - (np.power(2, bits_to_remove) - 1)
        return np.bitwise_and(input_img, mask)

    def zero_padding(self, img, filter_size):
        '''
        Pad with zeros the sides of the image before doing a standard
        convolution algorithm.

        NOTE: For add-shift-multiply algorithm for convolution, zero-padding
        is not needed

        Args:
            img: Input image
            filter_size: List with the size of the filter (rows and columns)

        Returns:
            Augmented size input image zero padded on top, bottom,
            right and left sides
        '''
        starting_coord_x = int(filter_size[1] / 2)
        starting_coord_y = int(filter_size[0] / 2)
        if len(img.shape) == 2:
            img = img.reshape(img.shape + (1,))
        output = np.zeros([img.shape[0] + 2 * starting_coord_y, img.shape[1] + 2 * starting_coord_x, img.shape[2]])

        for i in range(img.shape[2]):
            output[starting_coord_y:img.shape[0]+starting_coord_y,starting_coord_x:img.shape[1]+starting_coord_x,i] = img[:,:,i]

        if output.shape[2] == 1:
            output = output.reshape([output.shape[0], output.shape[1]])
        return np.array(output, dtype=np.uint8)

    def smooth_filtering(self, input_img, kernel_size):
        '''
        Apply a low pass filter to the given image.

        Args:
            input_img: 2D array that represents the image to filter
            kernel_size: Integer that represents the amount of columns
                and rows that the kernel will have

        Returns:
            Filtered image
        '''
        if kernel_size % 2 == 0:
            raise ValueError("The kernel size must be an odd number. Provided: {n}".format(n=kernel_size))
        factor = 1.0 / (kernel_size * kernel_size)
        kernel_shape = np.array((kernel_size, kernel_size))
        kernel = np.ones(kernel_shape) * factor
        output_img = self.apply_convolution(input_img, kernel)
        return output_img

    def gaussian_filter(self, image):
        '''
        Apply a 3x3 Gaussian filter to the image.

        Args:
            image: Input image to be filtered

        Returns:
            Filtered image
        '''
        kernel = np.array([[1.0,2.0,1.0],[2.0,4.0,2.0],[1.0,2.0,1.0]]) / 16.0
        output_img = self.apply_convolution(image, kernel)
        return output_img

    def apply_convolution(self, image, kernel):
        '''
        Make the convolution of the image with the given kernel. This function
        is made for 2D signals, not for 1D signals.

        The algorithm implemented is called Add-shift-multiply. It does not reduce
        the image size once applied

        Args:
            image: Input image
            kernel: Input kernel (filter)

        Returns:
            Result of doing the convolution of image and the given kernel
        '''
        np_img = np.array(image, dtype=np.float)
        if len(np_img.shape) == 2:
            np_img = np_img.reshape(np_img.shape + (1,))
        np_h = np.array(kernel)

        img_rows = np_img.shape[0]
        img_cols = np_img.shape[1]
        bands = np_img.shape[2]

        h_rows = np_h.shape[0]
        h_cols = np_h.shape[1]
        A = np.zeros([img_rows + h_rows - 1, img_cols + h_cols - 1, bands])

        for m in range(h_rows):
            for n in range(h_cols):
                A[m:m+img_rows,n:n+img_cols,:] += (np_img * np_h[m,n])

        center_x = int(h_rows / 2.0)
        center_y = int(h_cols / 2.0)

        return np.array(A[center_x:center_x + img_rows, center_y:center_y + img_cols, :], dtype=np.int)

    def get_histogram(self, image_matrix):
        '''
        Compute histograms of an image's matrix

        Args:
            image_matrix: Matrix of the image from which we are going to extract
                the histograms.

        Returns:
            List of histograms. If the image is grayscale, this list has only one element,
            If the image is RGB, then the list contains 3 elements, one per band
        '''
        amount_of_levels = 256
        if len(image_matrix.shape) == 2:
            image_matrix = image_matrix.reshape(image_matrix.shape + (1,))
        histograms_bgr = []
        image_matrix = np.array(image_matrix, dtype=np.uint8)
        ## calcHist returns a list of lists, where each list is the histogram value, so in order to have only one
        # dimentional array, we need to concatenate the values
        ## Taken from https://answers.opencv.org/question/33909/calchist-on-bgr-in-python/
        for i in range(image_matrix.shape[2]):
            histograms_bgr.append(np.concatenate(cv2.calcHist([image_matrix],[i],None,[amount_of_levels],[0,amount_of_levels])))

        return histograms_bgr

    def compute_image_cumulative_distribution_funct(self, histogram, normalized=True):
        '''
        Get the CDF function given an histogram

        Args:
            histogram: List with the histogram values of the image of which we want to
                create the CDF

            normalized: Boolean. If true, the CDF returned list will contain float values
                contained in the interval [0.0, 1.0] (probabilities). If False, each value would
                be a integer within the interval [0, amount_of_pixels]

        Returns:
            List with the CDF values
        '''
        amount_of_elements = len(histogram)
        cdf = []
        acumulator = 0
        for i in range(amount_of_elements):
            acumulator += histogram[i]
            cdf.append(acumulator)

        if normalized:
            return np.array(cdf) / float(acumulator)
        else:
            return np.array(cdf)

    def get_image_cdf(self, hist_arrays):
        '''
        Get the CDF function of the given list of histograms (grayscale or RGB)
        '''
        cdf_array = []
        for hist in hist_arrays:
            cdf_array.append(self.compute_image_cumulative_distribution_funct(hist))

        return cdf_array

    def histeq(self, image_matrix):
        '''
        Equalize image's histogram (make it flat)

        Args:
            image_matrix: NumPy array like matrix with the image to correct

        Returns:
            NumPy array like matrix that corresponds to the image with the
                contrast corrected through histogram's equalization
        '''
        hist_float = self.get_histogram(image_matrix)
        image_cdf = self.get_image_cdf(hist_float)[0] * 255.0

        K = np.array(image_cdf[image_matrix], dtype=np.uint8)
        print("Original image size: {s}".format(s=image_matrix.shape))
        print("K shape: {}".format(K.shape))
        return K

    def transfer_histogram(self, ref_image_matrix, dis_image_matrix, hist_ref, hist_discolored, rows, cols):
        '''
        Take the histogram of a reference image and transfer it to another image.
        This function will work with only one band at time, so hist_ref and
        hist_discolored should be lists of numbers

        TODO: Make this function actually work with one array and not a list of lists.
        TODO: Analyze how to remove the images as arguments from this function
        Args:
            ref_image_matrix: NumPy Array like matrix with the information of the image
                taken as reference, from which we are going to extract the histogram.

            dis_image_matrix: NumPy Array like matrix with the information of the image
                that is going to receive the histogram from the reference image.

            hist_ref: Histogram of the reference image (it should be only one band of an
                RGB image)

            hist_discolored: Histogram of the image we want to change (it should be only one band of an
                RGB image)

            rows: Amount of rows from the image to be changed

            cols: Amount of columns from the image to be changed

        Returns:
            NumPy array like matrix of the modified image
        '''
        K = np.zeros([rows, cols])

        ref_image_matrix = np.array(ref_image_matrix)
        dis_image_matrix = np.array(dis_image_matrix)

        int_hist_discolored = []
        int_hist_ref = []
        for hist in hist_discolored:
            int_hist_discolored.append(np.array(hist, dtype=np.uint32))

        for hist in hist_ref:
            int_hist_ref.append(np.array(hist, dtype=np.uint32))

        ## m_d = Minimum intensity in the discolored image
        m_d = np.min(dis_image_matrix)
        ## M_d: Maximum intensity in the discolored image
        M_d = np.max(dis_image_matrix)
        ## m_d = Minimum intensity in the reference image
        m_r = np.min(ref_image_matrix)
        ## M_d: Maximum intensity in the reference image
        M_r = np.max(ref_image_matrix)

        P_d = self.get_image_cdf(int_hist_discolored)[0]
        P_r = self.get_image_cdf(int_hist_ref)[0]
        g_r = m_r

        for g_d in np.arange(m_d, M_d, 1):
            while g_r < M_r and P_d[g_d+1] < 1.0 and P_r[g_r+1] < P_d[g_d+1]:
                g_r = g_r + 1
            ## This function returns us a matrix where the first row is the row
            # and the second row is the column of an element in dis_image_matrix
            # that has the same value as g_d
            K[np.where(dis_image_matrix == g_d)] += g_r

        K = np.array(K, dtype=np.uint8)
        return K

    def transfer_one_band_histogram(self, img_ref, img_dis, band=0):
        '''
        Transfer a specific band histogram from one image to another one

        Args:
            img_ref: Image from which we are going to extract the histogram(s).
            img_dis: Image at which we are going to transfer the extracted histogram
            band: Band to transfer / to extract from the reference image. If the images
                are grayscale, then we don't use this parameter
        '''
        ## We compute both image histograms from the selected band
        dis_img_band = img_dis
        ref_img_band = img_ref

        if len(img_dis.shape) == 3:
            dis_img_band = img_dis[:, :, band]

        if len(img_ref.shape) == 3:
            ref_img_band = img_ref[:, :, band]

        hist_ref = self.get_histogram(ref_img_band)
        hist_dis = self.get_histogram(dis_img_band)

        ## We create a new image based on img_discolored, and that has the same
        # histogram as img_reference
        new_histogram = self.transfer_histogram(ref_img_band,
            dis_img_band,
            hist_ref,
            hist_dis,
            img_dis.shape[0],
            img_dis.shape[1])

        if len(img_dis.shape) == 3:
            img_dis[:, :, band] = new_histogram
            return img_dis
        else:
            return new_histogram

if __name__ == '__main__':
    dirpath = os.path.dirname(os.path.realpath(__file__))
    # filepath = os.path.join(dirpath, 'cameraman.tif')
    filepath = os.path.join(dirpath, 'lena.png')
    img = cv2.imread(filepath)
    preproc = ImagePreprocessing(True)

    preprocessing = [
        ('edge_detector', 0),
        ('thresholding', 0),
        ('transfer_histogram', 0),
        ('smoothing', 7),
        ('median_filter', 3),
        ('remove_bits', 6),
        ('histogram_eq', 0),
    ]

    for proc in preprocessing:
        out = np.array(preproc.preprocess_image(img, [proc]), dtype=np.uint8)
        cv2.imshow('Original', img)
        cv2.imshow(proc[0], out)
        cv2.waitKey()
        cv2.destroyAllWindows()


# How to send an SMS in Python using Twillo

from twilio.rest import Client
import keys

client = Client(keys.account_sid, keys.auth_token)

message = client.messages.create(
    body = "are you ok?",
    from_= '+13609970543',
    to=keys.my_number
)

print(message.body)


"""
Implement a simple Convolutional Neural Network in TensorFlow with two convolutional layers,
followed by two fully-connected layers at the end
"""

# imports
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# ___Step 1___: Load MNIST data
from tensorflow.examples.tutorials.mnist import input_data

# helper function for the MNIST data loading
# modes:    train (which loads the training and validation images and their corresponding labels)
#           test (which loads the test images and their corresponding labels)
def load_data(mode='train'):
    """
    Function to (download and) load the MNIST data
    :param mode: train or test
    :return: images and the corresponding labels
    """
    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

    if mode == 'train':
        x_train, y_train, x_valid, y_valid = mnist.train.images, mnist.train.labels, \
                                             mnist.validation.images, mnist.validation.labels
        x_train, _ = reformat(x_train, y_train)
        x_valid, _ = reformat(x_valid, y_valid)
        return x_train, y_train, x_valid, y_valid
    elif mode == 'test':
        x_test, y_test = mnist.test.images, mnist.test.labels
        x_test, _ = reformat(x_test, y_test)
    return x_test, y_test

def reformat(x, y):
    """
    Reformats the data to the format acceptable for convolutional layers
    :param x: input array
    :param y: corresponding labels
    :return: reshaped input and labels
    """
    img_size, num_ch, num_class = int(np.sqrt(x.shape[-1])), 1, len(np.unique(np.argmax(y, 1)))
    dataset = x.reshape((-1, img_size, img_size, num_ch)).astype(np.float32)
    labels = (np.arange(num_class) == y[:, None]).astype(np.float32)
    return dataset, labels

def randomize(x, y):
    """ Randomizes the order of data samples and their corresponding labels"""
    permutation = np.random.permutation(y.shape[0])
    shuffled_x = x[permutation, :, :, :]
    shuffled_y = y[permutation]
    return shuffled_x, shuffled_y

def get_next_batch(x, y, start, end):
    x_batch = x[start:end]
    y_batch = y[start:end]
    return x_batch, y_batch

# load data
x_train, y_train, x_valid, y_valid = load_data(mode='train')

print("Size of MNIST:")
print("- Train images:\t\t{}".format(len(x_train)))
print("- Train labels:\t\t{}".format(len(y_train)))
print("- validation images:\t{}".format(len(x_valid)))
print("- validation labels:\t{}".format(len(y_valid)))

print("Shape of MNIST:")
print('- x_train:\t{}'.format(x_train.shape))
print('- y_train:\t{}'.format(y_train.shape))
print('- x_train:\t{}'.format(x_valid.shape))
print('- y_valid:\t{}'.format(y_valid.shape))

# ___Step 2___: Hyper-parameters

# batch size: the number of training examples in one forward/backward pass.
# iteration: one forward pass and one backward pass of one batch of images the training examples.
# epoch: one forward pass and one backward pass of all the training examples. epoch(1)=55000/batch size(100)=550(iteration)
epochs = 10             # Total number of training epochs
batch_size = 100        # Training batch size
display_freq = 100      # Frequency of displaying the training results
learning_rate = 0.001   # The optimization initial learning rate
n_classes = 10          # Number of classes, one class per digit
n_channels = 1

# data dimenstion
img_h = img_w = 28             # MNIST images are 28x28
img_size_flat = img_h * img_w  # 28x28=784, the total number of pixels

# path to the folder that we want to save the logs for Tensorboard
logs_path = "./graphs"

# ___Step 2.1___: Network configuration

# 1st Convolutional Layer
filter_size1 = 5    # Convolution filters are 5 x 5 pixels.
num_filters1 = 16   # There are 16 of these filters.
stride1 = 1         # The stride of the sliding window

# 2nd Convolutional Layer
filter_size2 = 5    # Convolution filters are 5 x 5 pixels.
num_filters2 = 32   # There are 32 of these filters.
stride2 = 1         # The stride of the sliding window

# Fully-connected layer.
h1 = 128            # Number of neurons in fully-connected layer.

# ___Step 3___: Variables

def weight_variable(shape):
    """
    Create a weight variable with appropriate initialization
    :param name: weight name
    :param shape: weight shape
    :return: initialized weight variable
    """
    initer = tf.truncated_normal_initializer(stddev=0.01)
    return tf.get_variable('W', dtype=tf.float32, shape=shape, initializer=initer)

def bias_variable(shape):
    """
    Create a bias variable with appropriate initialization
    :param name: bias variable name
    :param shape: bias variable shape
    :return: initialized bias variable
    """
    initial = tf.constant(0., shape=shape, dtype=tf.float32)
    return tf.get_variable('b', dtype=tf.float32, initializer=initial)

# Helper-function for creating a new Convolutional Layer
def conv_layer(x, filter_size, num_filters, stride, name):
    """
    Create a 2D convolution layer
    :param x: input from previous layer
    :param filter_size: size of each filter
    :param num_filters: number of filters (or output feature maps)
    :param stride: filter stride
    :param name: layer name
    :return: The output array
    """
    with tf.variable_scope(name):
        num_in_channel = x.get_shape().as_list()[-1]
        shape = [filter_size, filter_size, num_in_channel, num_filters]

        W = weight_variable(shape=shape)
        b = bias_variable(shape=[num_filters])

        # To visualize the parameters, we will use tf.summary class to write the summaries of parameters.
        tf.summary.histogram('W', W)
        tf.summary.histogram('b', b)

        layer = tf.nn.conv2d(x, W, strides=[1, stride, stride, 1], padding="SAME")
        layer += b

        return tf.nn.relu(layer)

# Helper-function for creating a new Max-pooling Layer
def max_pool(x, ksize, stride, name):
    """
    Create a max pooling layer
    :param x: input to max-pooling layer
    :param ksize: size of the max-pooling filter
    :param stride: stride of the max-pooling filter
    :param name: layer name
    :return: The output array
    """
    return tf.nn.max_pool(x, ksize=[1, ksize, ksize, 1], strides=[1, stride, stride, 1], padding="SAME", name=name)

# Helper-function for flattening a layer
def flatten_layer(layer):
    """
    Flattens the output of the convolutional layer to be fed into fully-connected layer
    :param layer: input array
    :return: flattened array
    """
    with tf.variable_scope('Flatten_layer'):
        layer_shape = layer.get_shape()
        num_features = layer_shape[1:4].num_elements()
        layer_flat = tf.reshape(layer, [-1, num_features])
    return layer_flat

# Helper-function for creating a new fully-connected Layer
def fc_layer(x, num_units, name, use_relu=True):
    """
    Create a fully-connected layer
    :param x: input from previous layer
    :param num_units: number of hidden units in the fully-connected layer
    :param name: layer name
    :param use_relu: boolean to add ReLU non-linearity (or not)
    :return: The output array
    """
    with tf.variable_scope(name):
        in_dim = x.get_shape()[1]

        W = weight_variable(shape=[in_dim, num_units])
        b = bias_variable(shape=[num_units])

        tf.summary.histogram('W', W)
        tf.summary.histogram('b', b)

        layer = tf.matmul(x, W)
        layer += b

        if use_relu:
            layer = tf.nn.relu(layer)
        return layer

# ___Step 4___: Create the newwork graph

# Placeholders for the inputs (x) and corresponding labels (y)
with tf.name_scope('Input'):
    x = tf.placeholder(tf.float32, shape=[None, img_h, img_w, n_channels], name='X')
    y = tf.placeholder(tf.float32, shape=[None, n_classes], name='Y')

# Create the network layers
conv1 = conv_layer(x, filter_size1, num_filters1, stride1, name='conv1')
pool1 = max_pool(conv1, ksize=2, stride=2, name='pool1')

conv2 = conv_layer(pool1, filter_size2, num_filters2, stride2, name='conv2')
pool2 = max_pool(conv2, ksize=2, stride=2, name='pool2')

layer_flat = flatten_layer(pool2)
fc1 = fc_layer(layer_flat, h1, 'FC1', use_relu=True)

# ___Step 5___: Create the model structure

output_logits = fc_layer(fc1, n_classes, 'OUT', use_relu=False)

# ___Step 6___: Define the loss function, optimizer, accuracy, and predicted class
with tf.variable_scope('Train'):
    with tf.variable_scope('Loss'):
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=output_logits), name='loss')
        tf.summary.scalar('loss', loss)
    with tf.variable_scope('Optimizer'):
        optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate, name='Adam-op').minimize(loss)
    with tf.variable_scope('Accuracy'):
        correct_prediction = tf.equal(tf.argmax(output_logits, 1), tf.argmax(y, 1), name='correct_pred')
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name='accuracy')
        tf.summary.scalar('accuracy', accuracy)
    with tf.variable_scope('Prediction'):
        # Network predictions
        cls_prediction = tf.argmax(output_logits, axis=1, name='predictions')

 # ___Step 7___: Initialize all variables

# Creating the op for initializing all variables
init = tf.global_variables_initializer()

# Finally, to merge all the summeries
merged = tf.summary.merge_all()

# ___Step 8___: Training

# Create an interactive session (to keep the session in the other cells)
sess = tf.InteractiveSession()

# Initialize all variables
sess.run(init)

# To write all the summaries on the disk
train_writer = tf.summary.FileWriter(logs_path, sess.graph)

# Number of training iterations in each epoch
num_tr_iter = int(len(y_train) / batch_size)

global_step = 0 # for visualize

# Loop for epoch
import datetime as time

for epoch in range(epochs):
    print('Training epoch: {}'.format(epoch + 1))

    # Randomly shuffle the training data at the beginning of each epoch
    x_train, y_train = randomize(x_train, y_train)

    time_start = time.datetime.now()

    # Loop for iteration
    for iteration in range(num_tr_iter):
        global_step += 1    # for visualize

        # get batch data
        start = iteration * batch_size
        end = (iteration + 1) * batch_size
        x_batch, y_batch = get_next_batch(x_train, y_train, start, end)

        # Run optimization op (backprop)
        feed_dict_batch = {x: x_batch, y: y_batch}
        sess.run(optimizer, feed_dict=feed_dict_batch)

        if iteration % display_freq == 0:
            # Calculate and display the batch loss and accuracy
            loss_batch, acc_batch, summary_tr = sess.run([loss, accuracy, merged],
                                                         feed_dict=feed_dict_batch)
            train_writer.add_summary(summary_tr, global_step)

            print("iter {0:3d}:\t Loss={1:.2f},\tTraining Accuracy={2:.01%}".
                  format(iteration, loss_batch, acc_batch))

    # Run validation after every epoch
    feed_dict_valid = {x: x_valid, y: y_valid}
    loss_valid, acc_valid = sess.run([loss, accuracy], feed_dict=feed_dict_valid)

    # report result
    time_end = time.datetime.now()

    print('---------------------------------------------------------')
    print("Epoch: {0}, validation loss: {1:.2f}, validation accuracy: {2:.01%}, time cost: {3:.2f} ms".
          format(epoch + 1, loss_valid, acc_valid, (time_end - time_start).total_seconds() * 1000))
    print('---------------------------------------------------------')

# ___Step 9___:Test the network after training

# Accuracy
x_test, y_test = load_data(mode='test')
feed_dict_test = {x: x_test, y: y_test}

time_start = time.datetime.now()

loss_test, acc_test = sess.run([loss, accuracy], feed_dict=feed_dict_test)

time_end = time.datetime.now()

print('---------------------------------------------------------')
print("Test loss: {0:.2f}, test accuracy: {1:.01%}, time cost: {2:.2f} ms".
    format(loss_test, acc_test, (time_end - time_start).total_seconds() * 1000))
print('---------------------------------------------------------')

# ___Step 10___: plot result

def plot_images(images, cls_true, cls_pred=None, title=None):
    """
    Create figure with 3x3 sub-plots.
    :param images: array of images to be plotted, (9, img_h*img_w)
    :param cls_true: corresponding true labels (9,)
    :param cls_pred: corresponding true labels (9,)
    """
    fig, axes = plt.subplots(3, 3, figsize=(9, 9))
    fig.subplots_adjust(hspace=0.3, wspace=0.3)

    for i, ax in enumerate(axes.flat):
        # Plot image.
        ax.imshow(np.squeeze(images[i]), cmap='binary')

        # Show true and predicted classes.
        if cls_pred is None:
            ax_title = "True: {0}".format(cls_true[i])
        else:
            ax_title = "True: {0}, Pred: {1}".format(cls_true[i], cls_pred[i])

        ax.set_title(ax_title)

        # Remove ticks from the plot.
        ax.set_xticks([])
        ax.set_yticks([])

    if title:
        plt.suptitle(title, size=20)

    plt.show(block=False)

def plot_example_errors(images, cls_true, cls_pred, title=None):
    """
    Function for plotting examples of images that have been mis-classified
    :param images: array of all images, (#imgs, img_h*img_w)
    :param cls_true: corresponding true labels, (#imgs,)
    :param cls_pred: corresponding predicted labels, (#imgs,)
    """
    # Negate the boolean array.
    incorrect = np.logical_not(np.equal(cls_pred, cls_true))

    # Get the images from the test-set that have been
    # incorrectly classified.
    incorrect_images = images[incorrect]

    # Get the true and predicted classes for those images.
    cls_pred = cls_pred[incorrect]
    cls_true = cls_true[incorrect]

    # Plot the first 9 images.
    plot_images(images=incorrect_images[0:9], cls_true=cls_true[0:9], cls_pred=cls_pred[0:9], title=title)

# Plot some of the correct and misclassified examples
cls_pred = sess.run(cls_prediction, feed_dict=feed_dict_test)

cls_true = np.argmax(y_test, axis=1)

plot_images(x_test, cls_true, cls_pred, title='Correct Examples')
plot_example_errors(x_test, cls_true, cls_pred, title='Misclassified Examples')

plt.show()

# ___Step 11___: finish all
sess.close()


#encoding=utf-8

from fangcloud.transport import YfyTransport
from fangcloud.url_builder import UrlBuilder

class UserRequests(YfyTransport):

    def __init__(self, client):
        self.client = client
        super(UserRequests, self).__init__(self.client.access_token, self.client.refresh_token, self.client.call_back)

    def get_self_info(self):
        url = UrlBuilder.get_self_info()
        return self.get(url)

    def get_user_info(self, user_id):
        url = UrlBuilder.get_user_info(user_id)
        return self.get(url)

    def get_user_profile_pic_file(self, user_id, profile_pic_key, file_path):
        url = UrlBuilder.get_user_pic(user_id)
        query = {
            "profile_pic_key": profile_pic_key
        }
        self.get_file(url, file_path, params=query)

    def update_user_info(self, name):
        assert isinstance(name, str)
        url = UrlBuilder.update_user_info()
        pay_load = {
            "name": name
        }
        return self.post(url, request_json_arg=pay_load)

    def get_user_space(self):
        url = UrlBuilder.get_space_usage()
        return self.get(url)

    def search_user(self, query_words, page_id):
        """
        本企业内的用户搜索

        :param query_words: 搜索关键字
        :param page_id: 页码
        :return: 用户列表
        """
        assert isinstance(query_words, str)
        assert isinstance(page_id, int)
        url = UrlBuilder.search_user()
        query = {
            "query_words": query_words,
            "page_id": page_id
        }
        return self.get(url, params=query)


class Solution:
    def eventualSafeNodes(self, graph: List[List[int]]) -> List[int]:
        result = []
        visited = [-1] * len(graph)

        def explore(i):
            visited[i] = 0
            for node in graph[i]:
                if visited[node] == 0 or (visited[node] == -1 and explore(node)):
                    return True
            visited[i] = 1
            result.append(i)
            return False

        for i in range(len(graph)):
            if visited[i] == -1:
                explore(i)
        return sorted(result)


'''
Created on Sept 9, 2021

Name:  Ben Lamb
Program:  modify_benlamb
Description: A search-and-replace script for the command line
@author: blamb
'''
import sys

#read in command-line args
fileSpec = sys.argv[1]
searchText = sys.argv[2]
replaceText = sys.argv[3]

#open script with target text
inFile = open(fileSpec, 'r')
script_contents = inFile.read()
inFile.close()

#search for and replace target text
fill = script_contents.replace(searchText, replaceText)
print("Update complete! Saving file...")

#write update to file
outPointer = open(fileSpec,'w')
outPointer.write(fill)
outPointer.close()


from functools import wraps
from typing import TYPE_CHECKING, Any

from aiohttp import ContentTypeError, ClientConnectorError
from fastapi import Request, Response, HTTPException, status, Depends

from gateway.server.core.request import fetch
from gateway.server.utils.body import unzip_body_object
from gateway.server.utils.form import unzip_form_params
from gateway.server.utils.query import unzip_query_params
from gateway.server.utils.request import create_request_data
from gateway.server.utils.headers import (
    generate_headers_for_microservice, inheritance_service_headers,
)
from gateway.server.utils.router import import_from_module_string

if TYPE_CHECKING:
    from gateway.server.core.database.models import Scope

def to_microservice(
        request_method,
        func,
        scope_model: "Scope"
):
    response_model = Any
    dependencies = []
    if scope_model.response_model:
        response_model = import_from_module_string(scope_model.response_model) or Any
    if scope_model.dependencies:
        for dependency in scope_model.dependencies:
            dep = import_from_module_string(dependency)
            if dep:
                dependencies.append(Depends(dep))

    register_endpoint = request_method(
        path=scope_model.path,
        response_model=response_model,
        dependencies=dependencies,
        tags=[f"Microservice: {scope_model.microservice.name if scope_model.microservice else 'Without microservice'}"]
    )

    @register_endpoint
    @wraps(func)
    async def wrapper(request: Request, response: Response, **kwargs):
        scope = request.scope
        scope_method = scope["method"].lower()
        content_type = str(request.headers.get('Content-Type'))
        request_form = (
            await request.form() if 'x-www-form-urlencoded' in content_type else None
        )

        prepare_microservice_path = f"{scope_model.microservice.base_url}{scope_model.path}"
        if scope_model.microservice_path:
            prepare_microservice_path = f"{scope_model.microservice.base_url}{scope_model.microservice_path}"

        microservice_url = prepare_microservice_path.format(**scope["path_params"])
        request_body = await unzip_body_object(
            necessary_params=scope_model.body_params,
            all_params=kwargs,
        )
        request_query = await unzip_query_params(
            necessary_params=scope_model.query_params, all_params=kwargs
        )
        request_form = await unzip_form_params(
            necessary_params=scope_model.form_params,
            request_form=request_form,
            all_params=kwargs,
        )

        request_headers = generate_headers_for_microservice(
            headers=request.headers,
        )

        request_data = create_request_data(
            form=request_form,
            body=request_body,
        )
        try:
            (
                resp_data,
                status_code_from_service,
                microservice_headers,
            ) = await fetch(
                url=microservice_url,
                method=scope_method,
                data=request_data,
                query_params=request_query,
                headers=request_headers,
            )

        except ClientConnectorError:
            raise HTTPException(
                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
                detail="Service is unavailable.",
            )
        except ContentTypeError:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Service error.",
            )

        if scope_model.override_headers:
            service_headers = inheritance_service_headers(
                gateway_headers=response.headers,
                service_headers=microservice_headers,
            )
            for key, value in service_headers.items():
                response.headers.append(key, value)
        response.status_code = status_code_from_service

        return resp_data

    return wrapper


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

from django.db import models, migrations
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('aaa', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Ticket',
            fields=[
                ('ticket', models.CharField(max_length=255, unique=True, serialize=False, verbose_name='ticket', primary_key=True)),
                ('expires', models.DateTimeField(verbose_name='expires')),
                ('consumed', models.DateTimeField(null=True, verbose_name='consumed')),
                ('user', models.ForeignKey(verbose_name='user', to=settings.AUTH_USER_MODEL)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
    ]


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

from utils import *
from modules import *
import time
import math
import random
import numpy as np

class CMF(nn.Module):
    def __init__(self, h_dim, num_ents, num_rels, num_class, class_weight,
                dropout=0.2, seq_len=5, maxpool=1, use_edge_node=0, use_gru=1,
                attn='', weight_loss=False, n_label=20, emb_dim=300,device=torch.device('cpu'),
                multiclass=False, emb_mod='lstm',node_layer=1,text_dim=64):
        super().__init__()
        self.h_dim = h_dim
        self.num_ents = num_ents
        self.num_rels = num_rels
        self.num_class = num_class
        self.seq_len = seq_len
        self.dropout = nn.Dropout(dropout)
        # initialize rel and ent embedding
        self.rel_embeds = nn.Parameter(torch.Tensor(num_rels, h_dim))
        self.ent_embeds = nn.Parameter(torch.Tensor(num_ents, h_dim))
        self.class_weight = class_weight
        self.weight_loss = weight_loss
        self.device = device
        self.n_label = num_class
        self.doc_embeds = None
        self.multiclass = multiclass
        self.text_dict = None
        self.count_dict = None
        self.sent_embs_dict = None
        self.graph_dict = None
        self.time_of_locs = None # available time for each location, a list of list
        self.aggregator= multilevel_learning(h_dim, emb_dim, dropout, num_ents, num_rels, seq_len, maxpool, attn, self.n_label, self.device, self.multiclass, emb_mod,node_layer,text_dim)
        if use_gru:
            self.encoder = nn.GRU(2*h_dim, h_dim, batch_first=True, num_layers=1, bidirectional=False)
        else:
            self.encoder = nn.RNN(2*h_dim, h_dim, batch_first=True, num_layers=1, bidirectional=False)
        self.out_layer = nn.Sequential(nn.Linear(1*h_dim, h_dim),nn.ReLU(),nn.Linear(h_dim, num_class)) # nn.Dropout(dropout) after relu
        self.temp_nn = nn.Linear(3*h_dim, h_dim)
        self.threshold = 0.5
        if self.multiclass:
            if self.weight_loss:
                self.criterion = nn.CrossEntropyLoss(weight=1-self.class_weight)
            else:
                self.criterion = nn.CrossEntropyLoss()
            self.out_func = nn.Softmax(dim=-1)
        else:
            self.criterion = F.binary_cross_entropy
            self.out_func = torch.sigmoid
        self.init_weights()

    def init_weights(self):
        for p in self.parameters():
            if p.data.ndimension() >= 2:
                nn.init.xavier_uniform_(p.data, gain=nn.init.calculate_gain('relu'))
            else:
                stdv = 1. / math.sqrt(p.size(0))
                p.data.uniform_(-stdv, stdv)

    def forward(self, time_set, loc_set, y):
        pred, idx, _ = self.get_pred_embeds(time_set, loc_set, self.graph_dict)
        y_true = y[idx]
        if self.multiclass:
            loss = self.criterion(pred, y_true)
            pred = F.softmax(pred,-1)
        else:
            pred = F.sigmoid(pred)
            if self.weight_loss:
                loss = self.criterion(pred, y_true,reduction='none') # should be 1 0 vector TODO
                weight = y_true/(2*self.class_weight) + (1-y_true)/(2*(1-self.class_weight))
                loss = torch.mean(loss * weight)
            else:
                # loss = F.cross_entropy(opred, torch.argmax(y_true, dim=1), reduction='sum')
                loss = self.criterion(pred, y_true)
        return loss, pred, y_true, idx

    def get_pred_embeds(self, time_set, loc_set, graph_dict):
        sorted_t, idx = time_set.sort(0, descending=True)  #TODO
        embed_seq_tensor, len_non_zero = self.aggregator(sorted_t, loc_set[idx], self.ent_embeds,
                                    self.rel_embeds,
                                    graph_dict,
                                    self.text_dict,
                                    self.count_dict,
                                    self.doc_embeds,
                                    self.time_of_locs)
        packed_input = torch.nn.utils.rnn.pack_padded_sequence(embed_seq_tensor,
                                                            len_non_zero,
                                                            batch_first=True,
                                                            enforce_sorted=False)
        _, feature = self.encoder(packed_input)
        feature = feature.squeeze(0)
        feature = torch.cat((feature, torch.zeros(len(time_set) - len(feature), feature.size(-1)).to(self.device)), dim=0)
        pred = self.out_layer(feature)
        return pred, idx, feature

    def get_pred_embeds_w_temporal(self, time_set, loc_set, graph_dict):
        sorted_t, idx = time_set.sort(0, descending=True)  #TODO
        embed_seq_tensor, len_non_zero = self.aggregator(sorted_t, loc_set[idx], self.ent_embeds,
                                    self.rel_embeds,
                                    graph_dict,
                                    self.text_dict,
                                    self.count_dict,
                                    self.doc_embeds,
                                    self.time_of_locs)
        packed_input = torch.nn.utils.rnn.pack_padded_sequence(embed_seq_tensor,
                                                            len_non_zero,
                                                            batch_first=True,
                                                            enforce_sorted=False)
        _, feature = self.encoder(packed_input)
        feature = feature.squeeze(0)
        feature = torch.cat((feature, torch.zeros(len(time_set) - len(feature), feature.size(-1)).to(self.device)), dim=0)
        pred = self.out_layer(feature)
        return pred, idx, feature, embed_seq_tensor, len_non_zero

    def evaluate(self, pred, y): # y is a binary vector
        if self.multiclass:
            _, y_pred_tags = torch.max(pred, dim = -1)
            nonzero_y_idx = y.unsqueeze(-1).cpu().tolist()
            nonzero_pred_idx = y_pred_tags.unsqueeze(-1).cpu().tolist()
        else:
            sorted_pred, sorted_pred_idx = pred.sort(1, descending=True)
            sorted_pred = torch.where(sorted_pred > self.threshold, sorted_pred, torch.zeros(sorted_pred.size()).to(self.device))
            nonzero_pred_len = torch.count_nonzero(sorted_pred, 1)
            sorted_pred_idx = sorted_pred_idx.cpu().tolist()
            nonzero_pred_len = nonzero_pred_len.cpu().tolist()
            nonzero_pred_idx = []
            for i in range(len(sorted_pred_idx)):
                nonzero_pred_idx.append(sorted_pred_idx[i][:nonzero_pred_len[i]])
            sorted_y, sorted_y_idx = y.sort(1, descending=True)
            nonzero_y_len = torch.count_nonzero(sorted_y, 1)
            sorted_y_idx = sorted_y_idx.cpu().tolist()
            nonzero_y_len = nonzero_y_len.cpu().tolist()
            nonzero_y_idx = []
            for i in range(len(sorted_y_idx)):
                nonzero_y_idx.append(sorted_y_idx[i][:nonzero_y_len[i]])
        return nonzero_y_idx, nonzero_pred_idx

    def explain(self, time_set, loc_set, y, label_idx):
        with torch.no_grad():
            pred, idx, feature, embed_seq_tensor, len_non_zero = self.get_pred_embeds_w_temporal(time_set, loc_set, self.graph_dict)
        embed_seq_tensor = torch.cat((embed_seq_tensor, torch.zeros(len(time_set) - len(embed_seq_tensor), self.seq_len, embed_seq_tensor.size(-1)).to(self.device)), dim=0)
        ref_embeds = torch.cat((feature.unsqueeze(1).repeat(1,self.seq_len,1),embed_seq_tensor),dim=-1)
        ref_embeds = self.temp_nn(ref_embeds)
        sorted_t, idx = time_set.sort(0, descending=True)
        embed_seq_tensor, len_non_zero, g_list, edge_scores_list, saved_doc_scores = self.aggregator.explain(
                                                        sorted_t, loc_set[idx],
                                                        self.ent_embeds,
                                                        self.rel_embeds,
                                                        self.graph_dict,
                                                        self.text_dict,
                                                        self.count_dict,
                                                        self.doc_embeds,
                                                        self.time_of_locs,
                                                        ref_embeds, label_idx)

        with torch.no_grad(): # using explanatory graphs
            packed_input = torch.nn.utils.rnn.pack_padded_sequence(embed_seq_tensor,
                                                               len_non_zero,
                                                               batch_first=True,
                                                               enforce_sorted=False)
            _, x_feature = self.encoder(packed_input)
            x_feature = x_feature.squeeze(0)
            x_feature = torch.cat((x_feature, torch.zeros(len(time_set) - len(x_feature), x_feature.size(-1)).to(self.device)), dim=0)
            x_pred = self.out_layer(x_feature)

        r = {}
        r['len_non_zero'] = len_non_zero
        r['g_list'] = g_list
        r['edge_scores_list'] = edge_scores_list
        r['saved_doc_scores'] = saved_doc_scores
        r['time_set'] = time_set[idx]
        r['loc_set'] = loc_set[idx]
        r['y'] = y[idx]
        if self.multiclass:
            _, pred_label = torch.max(pred, dim = -1)
            _, x_pred_label = torch.max(x_pred, dim = -1)
            loss = - mutual_information(pred_label, x_pred_label)
            # loss = - mutual_infomation_loss(pred_label, x_pred_label)

            r['label'] = 'multiclass'
            r['pred'] = pred
            r['pred_label'] = pred_label
            r['x_pred'] = x_pred
            r['x_pred_label'] = x_pred_label
            return loss, r
        else:
            pred = F.sigmoid(pred)
            x_pred = F.sigmoid(x_pred)
            pred_label = (pred > 0.5).float() * 1
            x_pred_label = (x_pred > 0.5).float() * 1
            x = pred_label[:,label_idx]
            y1 = x_pred_label[:,label_idx]
            loss = - mutual_information(x, y1) # + doc_entropy + evt_entropy
            # loss = - mutual_infomation_loss(x, y1)

            r['label'] = 'multilabel' + str(label_idx)
            r['pred'] = pred[:,label_idx]
            r['pred_label'] = pred_label[:,label_idx]
            r['x_pred'] = x_pred[:,label_idx]
            r['x_pred_label'] = x_pred_label[:,label_idx]
            return loss, r


import pandas as pd
from datetime import datetime, timedelta

df = pd.read_csv("temp_all_cities.csv")

last_date = datetime.strptime(df["Date"][0], '%m/%d/%Y')

for index, row in df.iterrows():
    current_date = datetime.strptime(row["Date"], '%m/%d/%Y')
    if (last_date != current_date):
        #print (current_date)
        if (not (last_date - timedelta(1) == current_date)):
            print ("MISSING DATE")
            print ("last_date")
            print ("new_date")
        else:
            last_date = current_date


from PyQt5 import QtWidgets
from QtDesign.py.AddProviderInfo import Ui_AddProviderInfo

class AddProviderInfoForm(QtWidgets.QMainWindow, Ui_AddProviderInfo):
    def __init__(self, db, user):
        QtWidgets.QMainWindow.__init__(self)
        self.setupUi(self)
        self.db = db
        self.user = user
        self.btn_save.clicked.connect(self.on_save)

    def on_save(self):
        self.db.insert_provider_info(
            self.user.id,
            self.edit_3.text(),
            int(self.edit_1.text()),
            self.edit_2.text()
        )


# -*- coding: utf-8 -*-
import scrapy
from politics.text_agent import TextAgent
from politics.items import StoryItem
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
import pandas as pd
import os

agent = TextAgent('2020Elections.txt', 'Fox')

class FoxSpider(CrawlSpider):
    name = 'fox'
    allowed_domains = ['www.foxnews.com']
    start_urls = ['https://www.foxnews.com/']
    rules = (Rule(LinkExtractor(allow=(), restrict_css=('h2.title a', 'h5.title a', 'a.item-label-href', 'p a',)),callback="parse_story_item", follow=True),)

    def parse_story_item(self, response):
        similar = False
        if response.css('body::attr(class)').get().split(' ').pop() != 'homepage':
            title = response.css('h1.headline::text').get() #
            body = response.css('div.article-body p::text').getall() #
            story = StoryItem()
            if title and body:
                story['title'] = title
                story['body'] = body
                story_dict = {
                    'title': [title],
                    'body': [body]
                }
                x = pd.DataFrame(story_dict)
                if agent.should_append(x):
                    similar = True
                    yield story
        if similar:
            links = response.css('a::attr(href)').getall()
            for a in links:
                yield scrapy.Request(a, callback=self.parse_story_item)


#
# This assumes fit_m87.py has been run and that no significant
# changes have been made.
#
# It is run as
#    %run -i fit_m87_tied.py
#

print(dep.get_shells())

dep.tie_par('xsmekal.kt', 17, 18)
dep.tie_par('xsmekal.abundanc', 17, 18)

print(dep.get_shells()[0:5])

dep.fit()

tied = dep.get_fit_results()
print(len(tied))

print(tied['xsmekal.kT'][16:])
print(tied['xsmekal.Abundanc'][16:])

dep.fit_plot('xsmekal.kt', units='pc')
rmid = (onion['rlo_phys'] + onion['rhi_phys']) / 2
plt.scatter(rmid.to(u.pc), onion['xsmekal.kT'], c='k')
plt.savefig('m87_temperature_tied_comparison.png')

dep.untie_par('xsmekal.kt', 18)
dep.untie_par('xsmekal.abundanc', 18)
print(dep.get_shells()[0:4])


import numpy as np
import matplotlib.pyplot as plt

def make_epsilon_greedy_policy(Q, epsilon, nA):
    def policy_fn(observation):
        idx_max = np.argmax(Q[observation])
        probabilities = np.ones(nA) * (epsilon / nA)
        probabilities[idx_max] += 1.0 - epsilon
        return probabilities

    return policy_fn

def make_uniform_policy(nA):
    def policy_fn():
        probabilities = np.ones(nA) * (1.0 / nA)
        return probabilities

    return policy_fn

def plot_CI(results, label, n_steps):
    """ plot confidence intervals """
    results_mean = np.mean(results, axis=0)
    results_sde = 1.95 * np.std(results, axis=0) / np.sqrt(results.shape[0])
    plt.grid()
    plt.plot(
        np.linspace(0.0, n_steps, num=results.shape[1]), results_mean, label=label,
    )

    plt.fill_between(
        np.linspace(0.0, n_steps, num=results.shape[1]),
        results_mean + results_sde,
        results_mean - results_sde,
        alpha=0.3,
    )


d = {
    0:"Beginner",
    1:"Junior Developer",
    2:"Middle Developer",
    3:"Senior Developer",
    4:"Hacker",
    5:"Jeff Dean",
}

for _ in range(int(input())):
    l = list(map(int,input().split()))
    n = sum(l)
    print(d[n])


import Chemins
from Utils.UTILS_Traduction import _
import wx
import six
from Ctrl import CTRL_Bouton_image
import FonctionsPerso
import GestionDB
import wx.lib.mixins.listctrl  as  listmix
import datetime
if 'phoenix' in wx.PlatformInfo:
    from wx.adv import DatePickerCtrl, DP_DROPDOWN
else :
    from wx import DatePickerCtrl, DP_DROPDOWN
import calendar

class SelectionPeriode(wx.Dialog):
    """ On récupère les infos de cette boîte avec GetDates() ou avec GetPersonnesPresentes() """
    def __init__(self, parent, id=-1, title=_(u"Sélection d'une période"), nomFichier=""):
        wx.Dialog.__init__(self, parent, id, title, size=(350, 400))

        # Label
        self.label = wx.StaticText(self, -1, _(u"Veuillez sélectionner ou saisir une période :"))

        # listCtrl vacances
        self.staticbox_vacances = wx.StaticBox(self, -1, _(u"Périodes de vacances"))
        self.ctrl_vacances = ListCtrl_vacances(self)
        self.ctrl_vacances.SetMinSize((20, 20))

        # Mois et Année
        self.staticbox_moisAnnee = wx.StaticBox(self, -1, _(u"Mois et année"))
        self.label_mois = wx.StaticText(self, -1, "Mois :", size=(50, -1), style=wx.ALIGN_RIGHT)
        self.listeMois = [u"", _(u"Janvier"), _(u"Février"), _(u"Mars"), _(u"Avril"), _(u"Mai"), _(u"Juin"), _(u"Juillet"), _(u"Août"), _(u"Septembre"), _(u"Octobre"), _(u"Novembre"), _(u"Décembre")]
        self.ctrl_mois = wx.Choice(self, -1, choices = self.listeMois) #AdvancedComboBox( self, "", size=(100, -1), choices = self.listeMois)
        self.label_annee = wx.StaticText(self, -1, _(u"Année :"), style=wx.ALIGN_RIGHT)

        self.listeAnnees = ["",]
        for annee in range(2000, 2050) :
            self.listeAnnees.append(str(annee))
        self.ctrl_annee = wx.Choice(self, -1, choices = self.listeAnnees) #AdvancedComboBox( self, "", size=(70, -1), choices = self.listeAnnees) #TextCtrlAnnee(self, "", size=(50, -1) )

        # Dates
        self.staticbox_dates = wx.StaticBox(self, -1, _(u"Dates"))
        self.label_date_debut = wx.StaticText(self, -1, "Du :", size=(50, -1), style=wx.ALIGN_RIGHT)
        self.ctrl_date_debut = DatePickerCtrl(self, -1, style=DP_DROPDOWN)
        self.label_date_fin = wx.StaticText(self, -1, "Au :", style=wx.ALIGN_RIGHT)
        self.ctrl_date_fin = DatePickerCtrl(self, -1, style=DP_DROPDOWN)

        # Boutons
        self.bouton_ok = CTRL_Bouton_image.CTRL(self, texte=_(u"Ok"), cheminImage=Chemins.GetStaticPath("Images/32x32/Valider.png"))
        self.bouton_annuler = CTRL_Bouton_image.CTRL(self, id=wx.ID_CANCEL, texte=_(u"Annuler"), cheminImage=Chemins.GetStaticPath("Images/32x32/Annuler.png"))
        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.OnBoutonOk, self.bouton_ok)
        self.Bind(wx.EVT_CHOICE, self.On_maj_mois, self.ctrl_mois)
        self.Bind(wx.EVT_CHOICE, self.On_maj_annee, self.ctrl_annee)

    def __set_properties(self):
        self.bouton_ok.SetSize(self.bouton_ok.GetBestSize())
        self.bouton_annuler.SetSize(self.bouton_annuler.GetBestSize())

    def __do_layout(self):
        grid_sizer_base = wx.FlexGridSizer(rows=5, cols=1, vgap=10, hgap=10)
        grid_sizer_base.Add(self.label, 0, wx.ALL, 10)

        # Vacances
        sizerStaticBox_vacances = wx.StaticBoxSizer(self.staticbox_vacances, wx.HORIZONTAL)
        sizerStaticBox_vacances.Add(self.ctrl_vacances, 1, wx.EXPAND|wx.ALL, 5)
        grid_sizer_base.Add(sizerStaticBox_vacances, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 10)
        # Mois et Année
        sizerStaticBox_moisAnnee = wx.StaticBoxSizer(self.staticbox_moisAnnee, wx.HORIZONTAL)
        sizerStaticBox_moisAnnee.Add(self.label_mois, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        sizerStaticBox_moisAnnee.Add(self.ctrl_mois, 0, wx.EXPAND|wx.ALL, 5)
        sizerStaticBox_moisAnnee.Add(self.label_annee, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        sizerStaticBox_moisAnnee.Add(self.ctrl_annee, 0, wx.EXPAND|wx.ALL, 5)
        grid_sizer_base.Add(sizerStaticBox_moisAnnee, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 10)
        # Dates
        sizerStaticBox_dates = wx.StaticBoxSizer(self.staticbox_dates, wx.HORIZONTAL)
        sizerStaticBox_dates.Add(self.label_date_debut, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        sizerStaticBox_dates.Add(self.ctrl_date_debut, 0, wx.EXPAND|wx.ALL, 5)
        sizerStaticBox_dates.Add(self.label_date_fin, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        sizerStaticBox_dates.Add(self.ctrl_date_fin, 0, wx.EXPAND|wx.ALL, 5)
        grid_sizer_base.Add(sizerStaticBox_dates, 0, wx.EXPAND|wx.LEFT|wx.RIGHT, 10)

        # Boutons
        grid_sizer_boutons = wx.FlexGridSizer(rows=1, cols=3, vgap=10, hgap=10)
        grid_sizer_boutons.Add((20, 20), 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_ok, 0, 0, 0)
        grid_sizer_boutons.Add(self.bouton_annuler, 0, 0, 0)
        grid_sizer_boutons.AddGrowableCol(0)
        grid_sizer_base.Add(grid_sizer_boutons, 1, wx.ALL|wx.EXPAND, 10)

        self.SetSizer(grid_sizer_base)
        grid_sizer_base.AddGrowableCol(0)
        grid_sizer_base.AddGrowableRow(1)
        self.Layout()
        self.CenterOnScreen()

    def GetDates(self):
        """ Renvoie les dates des deux datepickers au format datetime """
        date_debut = self.GetDatePickerValue(self.ctrl_date_debut)
        date_fin = self.GetDatePickerValue(self.ctrl_date_fin)
        return (date_debut, date_fin)

    def SetDates(self, date_debut=None, date_fin=None):
        """ Ecrit les dates de début et fin dans les deux datepickers """
        if date_debut != None : self.SetDatePicker(self.ctrl_date_debut, date_debut)
        if date_fin != None : self.SetDatePicker(self.ctrl_date_fin, date_fin)

    def SetDatePicker(self, controle, date) :
        """ Met une date au format datetime dans un datePicker donné """
        annee = int(date.year)
        mois = int(date.month)-1
        jour = int(date.day)
        date = wx.DateTime()
        date.Set(jour, mois, annee)
        controle.SetValue(date)

    def GetDatePickerValue(self, controle):
        """ Renvoie la date au format datetime d'un datePicker """
        date_tmp = controle.GetValue()
        return datetime.date(date_tmp.GetYear(), date_tmp.GetMonth()+1, date_tmp.GetDay())

    def OnBoutonOk(self, event):
        """ Validation des données saisies """
        self.EndModal(wx.ID_OK)

    def ctrl_mois_EvtComboBox(self, event):
        self.On_maj_mois()

    def On_maj_mois(self, event):
        """ Quand un item est sélectionné dans le combobox mois """
        index = self.ctrl_mois.GetSelection()
        if index > 0 :
            mois = index
            # Si pas d'année saisie, sélectionne l'année en cours
            indexAnnee = self.ctrl_annee.GetSelection()
            if indexAnnee < 2 :
                annee = datetime.datetime.now().year
                self.ctrl_annee.SetStringSelection(str(annee))
            else:
                annee = int(self.listeAnnees[self.ctrl_annee.GetSelection()])
            # Si mois et année valide, on saisi les dates dans les datepickers
            date_debut = datetime.date(annee, mois, 1)
            date_fin = datetime.date(annee, mois, calendar.monthrange(annee, mois)[1])
            self.SetDates(date_debut, date_fin)

    def ctrl_annee_EvtComboBox(self, event):
        self.On_maj_annee()

    def On_maj_annee(self, event):
        """ Quand un item est sélectionné dans le combobox annee """
        index = self.ctrl_annee.GetSelection()
        if index != -1 :
            annee = int(self.listeAnnees[index])
            # Si un mois a déjà été saisi, on saisie les dates extrêmes du mois sélectionné dans les datespickers
            if self.ctrl_mois.GetSelection() != -1 :
                mois = self.ctrl_mois.GetSelection() + 1
                date_debut = datetime.date(annee, mois, 1)
                date_fin = datetime.date(annee,mois, calendar.monthrange(annee, mois)[1])
                self.SetDates(date_debut, date_fin)
            else:
                # Sinon, on saisie les dates extrêmes de l'année dans les datepickers
                date_debut = datetime.date(annee, 1, 1)
                date_fin = datetime.date(annee, 12, 31)
                self.SetDates(date_debut, date_fin)

    def GetPersonnesPresentes(self):
        """ Permet de récupérer la liste des personnes présentes sur la période sélectionnée """
        date_debut, date_fin = self.GetDates()
        # Récupération des presences des personnes
        DB = GestionDB.DB()
        req = """SELECT IDpersonne FROM presences WHERE date>='%s' AND date<='%s' GROUP BY IDpersonne""" % (date_debut, date_fin)
        DB.ExecuterReq(req)
        listeDonnees = DB.ResultatReq()
        DB.Close()
        listePersonnes = []
        if len(listeDonnees) != 0 :
            # Formatage de la liste
            for donnees in listeDonnees :
                listePersonnes.append(donnees[0])
        return listePersonnes

##class AdvancedComboBox(wx.ComboBox) :
##    """ Crée un comboBox avec auto-complete limité à la liste donnée """
##    def __init__(self, parent, value, choices=[], style=0, **par):
##        wx.ComboBox.__init__(self, parent, wx.ID_ANY, value, style=style|wx.CB_DROPDOWN, choices=choices, **par)
##        self.parent = parent
##        self.choices = choices
##        self.Bind(wx.EVT_TEXT, self.EvtText)
##        self.Bind(wx.EVT_CHAR, self.EvtChar)
##        self.Bind(wx.EVT_COMBOBOX, self.EvtCombobox)
##        self.Bind(wx.EVT_KILL_FOCUS, self.EvtKillFocus)
##        self.ignoreEvtText = False
##
##    def EvtCombobox(self, event):
##        self.ignoreEvtText = True
##        event.Skip()
##
##    def EvtChar(self, event):
##        if event.GetKeyCode() == 8 and self.GetValue() != u"" :
##            self.ignoreEvtText = True
##        event.Skip()
##
##    def EvtText(self, event):
##        if self.ignoreEvtText :
##            self.ignoreEvtText = False
##            return
##        currentText = event.GetString()
##        found = False
##        index = 0
##        for choice in self.choices :
##            if choice.startswith(currentText):
##                self.SetValue(choice)
##                self.SetInsertionPoint(len(currentText))
##                self.SetMark(len(currentText), len(choice))
##                found = True
##                break
##            index += 1
##        if not found and currentText!= "" :
##            ancienTexte = currentText[:-1]
##            if len(ancienTexte) == 0 :
##                self.SetValue("")
##            else :
##                for choice in self.choices :
##                    if choice.startswith(ancienTexte):
##                        self.SetValue(choice)
##                        self.SetInsertionPoint(len(ancienTexte))
##                        self.SetMark(len(ancienTexte), len(choice))
##                        break
##        event.Skip()
##
##    def EvtKillFocus(self, event):
##        # Si la valeur n'est pas correcte dans le champ, remet la valeur précédente
##        if self.GetValue() not in self.choices and self.GetValue() != u"" :
##            self.Undo()
##        # Fait la sélection dans la liste
##        if self.GetValue() in self.choices :
##            self.SetStringSelection(self.GetValue())
##        # Met à jour les contrôles mois et annee
##        self.parent.On_maj_mois()
##        self.parent.On_maj_annee()
##        event.Skip()

class ListCtrl_vacances(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin):
    def __init__(self, parent):
        wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES|wx.LC_NO_HEADER)
        self.parent = parent

        #adding some attributes (colourful background for each item rows)
        self.attr1 = wx.ListItemAttr()
        self.attr1.SetBackgroundColour("#EEF4FB") # Vert = #F0FBED

        # Remplissage du ListCtrl
        self.Remplissage()

        #events
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)

    def Remplissage(self):

        # Récupération des données dans la base de données
        self.Importation()

        # Création des colonnes
        self.nbreColonnes = 2
        self.InsertColumn(0, _(u"Nom"))
        self.SetColumnWidth(0, 100)
        self.InsertColumn(1, _(u"Dates"))
        self.SetColumnWidth(1, 100)

        #These two should probably be passed to init more cleanly
        #setting the numbers of items = number of elements in the dictionary
        self.itemDataMap = self.donnees
        self.itemIndexMap = list(self.donnees.keys())
        self.SetItemCount(self.nbreLignes)

        #mixins
        listmix.ListCtrlAutoWidthMixin.__init__(self)
        listmix.ColumnSorterMixin.__init__(self, self.nbreColonnes)

        #sort by genre (column 1), A->Z ascending order (1)
        self.SortListItems(1, 0)

    def DateEngFr(self, textDate):
        text = str(textDate[8:10]) + "/" + str(textDate[5:7]) + "/" + str(textDate[:4])
        return text

    def Importation(self):
        # Récupération des données
        DB = GestionDB.DB()
        req = """SELECT IDperiode, nom, annee, date_debut, date_fin
        FROM periodes_vacances ORDER BY date_debut DESC; """
        DB.ExecuterReq(req)
        listeVacances = DB.ResultatReq()
        DB.Close()
        self.nbreLignes = len(listeVacances)
        # Création du dictionnaire de données
        self.donnees = {}
        index = 0
        for IDperiode, nom, annee, date_debut, date_fin in listeVacances :
            self.donnees[index] = [nom + " " + annee, date_debut + "_" + date_fin]
            index += 1

    def MAJListeCtrl(self):
        self.ClearAll()
        self.Remplissage()
        self.resizeLastColumn(0)
        listmix.ColumnSorterMixin.__init__(self, self.nbreColonnes)

    def getColumnText(self, index, col):
        item = self.GetItem(index, col)
        return item.GetText()

    #---------------------------------------------------
    # These methods are callbacks for implementing the
    # "virtualness" of the list...

    def OnGetItemText(self, item, col):
        """ Affichage des valeurs dans chaque case du ListCtrl """
        index=self.itemIndexMap[item]
        valeur = six.text_type(self.itemDataMap[index][col])
        # Formatage de la colonne dates
        if col == 1 :
            date_debut, date_fin = valeur.split("_")
            valeur = "Du " + self.DateEngFr(date_debut) + " au " + self.DateEngFr(date_fin)
        return valeur

    def OnGetItemImage(self, item):
        """ Affichage des images en début de ligne """
        return -1

    def OnGetItemAttr(self, item):
        """ Application d'une couleur de fond pour une ligne sur deux """
        # Création d'une ligne de couleur 1 ligne sur 2
        if item % 2 == 1:
            return self.attr1
        else:
            return None

    #-----------------------------------------------------------
    # Matt C, 2006/02/22
    # Here's a better SortItems() method --
    # the ColumnSorterMixin.__ColumnSorter() method already handles the ascending/descending,
    # and it knows to sort on another column if the chosen columns have the same value.

    def SortItems(self,sorter=FonctionsPerso.cmp):
        items = list(self.itemDataMap.keys())
        items = FonctionsPerso.SortItems(items, sorter)
        self.itemIndexMap = items
        # redraw the list
        self.Refresh()

    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
    def GetListCtrl(self):
        return self

    def OnItemActivated(self, event):
        pass

    def OnItemSelected(self, event):
        """ Item selectionné """
        index = self.GetFirstSelected()
        valeur = six.text_type(self.itemDataMap[index][1])
        date_debut, date_fin = valeur.split("_")
        date_debut = datetime.date(year=int(date_debut[:4]), month=int(date_debut[5:7]), day=int(date_debut[8:10]))
        date_fin = datetime.date(year=int(date_fin[:4]), month=int(date_fin[5:7]), day=int(date_fin[8:10]))
        # Efface les contenus des contrôles mois et annee
        self.parent.ctrl_mois.SetStringSelection("")
        self.parent.ctrl_annee.SetStringSelection("")
        # Set les dates dans les datepickers
        self.parent.SetDates(date_debut, date_fin)

if __name__ == "__main__":
    app = wx.App(0)
    #wx.InitAllImageHandlers()
    frm = SelectionPeriode(None)
    frm.ShowModal()
    app.MainLoop()


import sys

class Menu:
    def __init__(self):
        #self.user = user
        self.choices = {
            "1": "patient",
            "2": "vaccination",
            "3": "qr scan",
            "4": "todo",
            "5": self.exit
        }

    def printMenu(self):
          print(("""================================
           MENU
               ================================
               1 - TODO
               2 - TODO
               3 - TODO
               4 - TODO
               5 - Exit program
               ================================"""),end = " ")

    def runCode(self):
        while True:
            self.printMenu()
            choice = input("Enter a number to choose an option: " )
            make = self.choices.get(choice)
            if make:
                    make()
            else:
                print("{0} is not a valid choice".format(choice))

    def exit(self):
        print("Exiting")
        sys.exit()

if __name__ == "__main__":
    menu = Menu()
    menu.printMenu()
    menu.runCode()
    menu.exit()


import os
import webbrowser

from fpdf import FPDF

class PdfReport:
    """ create a pdf report contain data about flatmates, bill, period"""
    def __init__(self, file):
        self.file = file

    def generate(self, flatmate1, flatmate2, bill):
        pdf = FPDF(orientation="P",
                   unit='pt',
                   format='A4')

        pdf.add_page()

        # add an image
        pdf.image("house.png", w=30, h=30)
        flatmate1_pays = str(round(flatmate1.pays(bill, flatmate2),2))
        flatmate2_pays = str(round(flatmate2.pays(bill, flatmate1),2))
        # add some text
        pdf.set_font(family='Times', size=24, style='B')
        pdf.cell(w=0, h=80, txt="Flatemates Bill", border=0, align='C', ln=1)
        pdf.set_font(family='Times', size=14, style='B')
        pdf.cell(w=100, h=40, txt='Period:', border=0)
        pdf.cell(w=150, h=40, txt=bill.period, border=0,ln=1)

        # insert name and bill
        pdf.set_font(family='Times', size=12, style='B')
        pdf.cell(w=100, h=25, txt=flatmate1.name, border=0)
        pdf.cell(w=150, h=25, txt= flatmate1_pays, border=0, ln=1)

        pdf.cell(w=100, h=25, txt=flatmate2.name, border=0)
        pdf.cell(w=150, h=25, txt=flatmate2_pays, border=0)
        pdf.output(self.file)
        webbrowser.open('file://' + os.path.realpath(self.file))
        #pdf.cell(w=100, h=40, txt=flatmate1.name, border=1)
        #pdf.cell(w=150, h=40, txt=bill.period, border=1)
        #pdf.output("bill.pdf")
        #pass


# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def minDiffInBST(self, root: TreeNode) -> int:
        q, nVal = [root],[]
        while len(q) >0:
            t = q.pop(0)
            nVal.append(t.val)
            if t.left: q.append(t.left)
            if t.right: q.append(t.right)
        nVal.sort()
        min = 100000000000
        for i in range(len(nVal) - 1):
            if abs(nVal[i] - nVal[i+1]) < min:
                min = abs(nVal[i] - nVal[i+1])
        return min

Leetcode/Leetcode-Minimum Distance Between BST Nodes.py


# coding: utf-8

import sys
import numpy as np
import matplotlib.pyplot as plt

sys.path.append("..")
from OpenPyHeat_2020.OpenPyHeat_Reader import allrun,allclean

## 1-
if True :
    # allclean('Example/triCouche0D')
    Ysol,Xt = allrun('Example/triCouche0D')

    Tsol = np.array([(Ysol[:,0]+Ysol[:,1])/2,
                    Ysol[:,2],
                    (Ysol[:,3]+Ysol[:,4])/2])

    plt.figure(1)
    [plt.plot(Xt,T) for T in Tsol]
    plt.legend(["Inox","Water","Verre"])
    plt.grid()
    plt.show()

## 1.1-
if True :
    # allclean('Example/triCouche0D_air')
    Ysol,Xt = allrun('Example/triCouche0D_air')

    Tsol = np.array([(Ysol[:,0]+Ysol[:,1])/2,
                    Ysol[:,2],
                    (Ysol[:,3]+Ysol[:,4])/2])

    plt.figure(2)
    [plt.plot(Xt,T) for T in Tsol]
    plt.legend(["Inox","Air","Verre"])
    plt.grid()
    plt.show()

## 2-
if True :
    # allclean('Example/monocouche_source_constante')
    Xsol,Xt = allrun('Example/monocouche_source_constante')
    x = np.linspace(0,1,len(Xsol[0]))

    Xana = np.loadtxt('Example/monocouche_source_constante/analytic_sol/analytic_solution')
    plt.figure(3)
    plt.plot(x,Xsol[-1],color='b',marker='s',
                                    markerfacecolor='orange',
                                    markeredgecolor='b',
                                    label="OpenPyHeat")
    plt.plot(Xana[:,0],Xana[:,1],'r',alpha=0.8,label="Analytic solution")
    plt.grid(True)
    plt.legend()
    plt.xlabel(r'$\bar X$')
    plt.ylabel('Temperature [K]')
    plt.show()

## 3-E
if True :
    #Xsol,Xt = allclean('Example/tri_couche')
    Xsol,Xt = allrun('Example/tri_couche')

    Xana = np.loadtxt('Example/tri_couche/analytic_sol/analytic_solution')
    plt.figure(4)
    plt.plot(Xsol[-1],color='b',marker='s',
                                    markerfacecolor='orange',
                                    markeredgecolor='b',
                                    label="OpenPyHeat")
    plt.plot(Xana,'r',alpha=0.8,label="Analytic solution")
    plt.grid(True)
    plt.legend()
    plt.xlabel(r'$\bar X$')
    plt.ylabel('Temperature [K]')
    plt.show()

## 4-
if True :
    # allclean('Example/tri_couche_steady')
    Xsol = allrun('Example/tri_couche_steady')
    xsol = np.linspace(0,1,len(Xsol))
    Xana = np.loadtxt('Example/tri_couche/analytic_sol/analytic_solution')
    xana = np.linspace(0,1,len(Xana))

    plt.figure(5)
    plt.plot(xsol,Xsol,color='b',marker='s',
                                    markerfacecolor='orange',
                                    markeredgecolor='b',
                                    label="OpenPyHeat")
    plt.plot(xana,Xana,'r',alpha=0.8,label="Analytic solution")
    plt.grid(True)
    plt.legend()
    plt.xlabel(r'$\bar X$')
    plt.ylabel('Temperature [K]')
    plt.show()

## 5-
if True :
    # allclean('Example/cylindric_1')
    Xsol = allrun('Example/cylindric_1')
    xsol = np.linspace(0,1,len(Xsol))
    Xana = np.loadtxt('Example/cylindric_1/analytic_sol/analytic_solution')
    xana = np.linspace(0,1,len(Xana))

    plt.figure(6)
    plt.plot(xsol,Xsol,color='b',marker='s',
                                    markerfacecolor='orange',
                                    markeredgecolor='b',
                                    label="OpenPyHeat")
    plt.plot(xana,Xana,'r',alpha=0.8,label="Analytic solution")
    plt.grid(True)
    plt.legend()
    plt.xlabel(r'$\bar X$')
    plt.ylabel('Temperature [K]')
    plt.show()

## 6-
if True :
    # allclean('Example/cylindric_2')
    Xsol = allrun('Example/cylindric_2')
    xsol = np.linspace(0,1,len(Xsol))
    Xana = np.loadtxt('Example/cylindric_2/analytic_sol/analytic_solution')
    xana = np.linspace(0,1,len(Xana))

    plt.figure(7)
    plt.plot(xsol,Xsol,color='b',marker='s',
                                    markerfacecolor='orange',
                                    markeredgecolor='b',
                                    label="OpenPyHeat")
    plt.plot(xana,Xana,'r',alpha=0.8,label="Analytic solution")
    plt.grid(True)
    plt.legend()
    plt.xlabel(r'$\bar X$')
    plt.ylabel('Temperature [K]')
    plt.show()

## 7-
if True :
    # allclean('Example/cylindric_3')
    Xsol = allrun('Example/cylindric_3')
    xsol = np.linspace(0,1,len(Xsol))
    Xana = np.loadtxt('Example/cylindric_3/analytic_sol/analytic_solution')
    xana = np.linspace(0,1,len(Xana))

    plt.figure(8)
    plt.plot(xsol,Xsol,color='b',marker='s',
                                    markerfacecolor='orange',
                                    markeredgecolor='b',
                                    label="OpenPyHeat")
    plt.plot(xana,Xana,'r',alpha=0.8,label="Analytic solution")
    plt.grid(True)
    plt.legend()
    plt.xlabel(r'$\bar X$')
    plt.ylabel('Temperature [K]')
    plt.show()

## 8-
if True :
    # allclean('Example/monocouche_transient')
    Xsol,Xt = allrun('Example/monocouche_transient')
    xsol = np.linspace(0,1,len(Xsol))
    Xopf = np.loadtxt('Example//monocouche_transient/analytic_sol/openfoam_solution')

    plt.figure(9)
    line1 = plt.plot(Xt,Xsol,color='b')
    line2 = plt.plot(Xopf[:,0],Xopf[:,1:],'r',alpha=0.8)
    plt.grid(True)
    plt.xlabel('t')
    plt.ylabel('Temperature [K]')
    plt.legend([line1[0],line2[0]],['OpenPyHeat',"Openfoam simu"])
    plt.show()

## 9-
if True :
    # allclean('Example/paraffinExchanger')
    Xsol,Xt = allrun('Example/paraffinExchanger')

    DATA = np.loadtxt('Example/paraffinExchanger/analytic_sol/ComsolResults.txt')
    t = DATA[:,0]
    fwComsol = DATA[:,1]
    fcComsol = DATA[:,2]
    TpcmComsol = DATA[:,3]
    TwaterComsol = DATA[:,4]

    plt.figure(10)
    line1 = plt.plot(Xt,Xsol[:,1:],color='r')
    line2 = plt.plot(Xt,Xsol[:,0],color='b')
    line3 = plt.plot(t,TpcmComsol,color='orange')
    line4 = plt.plot(t,TwaterComsol,color='c')
    plt.grid(True)
    plt.xlabel('t')
    plt.ylabel('Temperature [K]')
    plt.legend([line1[0],line2[0],line3[0],line4[0]],['paraffin',"water",'pcm COMSOL','water COMSOL'])
    plt.show()

## 10-
if True :
    allrun("Example/echangeur_air_eau")


import serial
import time
from numpy import *
from tkinter import *
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import random

current_pose = [0,0,0]
prev_x,prev_y,prev_w1,prev_w2 = 0,0,0,0

lmotor_max = 1500
rmotor_max = 0

lmotor_min = 750
rmotor_min = 750
rotate = 1

def __init__():
    ser = serial.Serial('/dev/ttyS0',baudrate=9600,timeout=0.05)
    return ser

def get_position(x,y,c1,c2,current_pose,rotate,t):
    d1 = float(c1) * 8.125
    d2 = float(c2) * 8.125
    print(t)
    d_dist = d1
    if rotate == 1 or rotate == -1:
        #d_theta = 360*c2*32.5*t/(2*pi*62.5)
        d_theta = c1*45*32.5/(62.5*2)
        dx = 0
        dy = 0

    else:
        d_theta = 0
        dx = d_dist*cos(radians(current_pose[2]))*2
        dy = d_dist*sin(radians(current_pose[2]))*2

    #print(d1,dx,dy,d_theta,rotate)
    return current_pose[0] + dx,current_pose[1] + dy,current_pose[2] + d_theta*rotate*1

def motor_control(ser,set_theta, current_pose,end_point):
        if set_theta - current_pose[2]  > 8:
            #lmotor + and rmotor -
            print("Now turning left")
            ser.write(b"0")
            rotate = 1

        elif set_theta - current_pose[2] < -8:
            #lmotor - and rmotor +
            print("Now turning right")
            ser.write(b"1")
            rotate = -1

        elif abs(current_pose[0] - end_point[0]) > 5 or abs(current_pose[1] - end_point[1]) > 5:
            #lmotor + and rmotor +
            print("Now forward")
            ser.write(b"2")
            rotate = 0

        else:
            #lmotor + and rmotor +
            print("Stop")
            ser.write(b"3")
            rotate = 0
        return rotate

def main(ser,prev_x,prev_y,prev_w1,prev_w2,end_point):
    while True:
        start_time = time.time()
        ser_bytes = ser.readline().decode("utf-8").rstrip()
        data = ser_bytes.split("\r")
        print(data)
        if len(data[0]) > 6 and data[0].find('s') == -1:
            #print(data[0])
            try:
                curr_x,curr_y,curr_w1,curr_w2 = [float(i) for i in data[0].split("|")]
            except ValueError:
                curr_x,curr_y,curr_w1,curr_w2 = prev_x,prev_y,prev_w1,prev_w2

            global current_pose
            global rotate
            current_pose = list(get_position(curr_x-prev_x, curr_y - prev_y,curr_w1-prev_w1,curr_w2-prev_w2,current_pose,rotate,time.time() - start_time))

            if current_pose[2] > 360:
                current_pose[2] = 0;
            #print(current_pose)

            prev_x,prev_y,prev_w1,prev_w2 = curr_x,curr_y,curr_w1,curr_w2

            set_theta = degrees(arctan2((end_point[1]-current_pose[1]),(end_point[0]-current_pose[0])))

            if (end_point[1]-current_pose[1] < 0):
                set_theta = set_theta  + 360
            print(set_theta)
            rotate = motor_control(ser,set_theta,current_pose,end_point)
            time.sleep(0.05)
            return [round(i,2) for i in current_pose],curr_w1,curr_w2
            break


import os

import gobject
import gtk
import pango

try:
    import gtksourceview
    use_sourceview = True
except:
    use_sourceview = False

if use_sourceview:
    language_manager = gtksourceview.SourceLanguagesManager()

from application import application
from editor import Editor
from shell_view import ShellView
from window_builder import WindowBuilder

class LibraryEditor(Editor):
    DISCARD_FORMAT = 'Discard unsaved changes to library "%s"?'
    DISCARD_FORMAT_BEFORE_QUIT = 'Save the changes to library "%s" before quitting?'

    def __init__(self, notebook):
        Editor.__init__(self, notebook)

        self.__filename = None
        self.__modified = False
        self.__file = None

        if use_sourceview:
            self.buf = gtksourceview.SourceBuffer()
            self.buf.set_highlight(True)
            language = language_manager.get_language_from_mime_type("text/x-python")
            if language != None:
                self.buf.set_language(language)
            self.view = gtksourceview.SourceView(self.buf)
            self.view.set_insert_spaces_instead_of_tabs(True)
            self.view.set_tabs_width(4)
        else:
            self.buf = gtk.TextBuffer()
            self.view = gtk.TextView(self.buf)

        self.view.modify_font(pango.FontDescription("monospace"))

        self.buf.connect_after('insert-text', lambda *args: self.__set_modified(True))
        self.buf.connect_after('delete-range', lambda *args: self.__set_modified(True))

        self.widget = gtk.ScrolledWindow()
        self.widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

        self.widget.add(self.view)

        self.widget.show_all()

    #######################################################
    # Overrides
    #######################################################

    def _get_display_name(self):
        if self.__filename == None:
            return "Unsaved Library %d" % self._unsaved_index
        else:
            return os.path.basename(self.__filename)

    def _get_filename(self):
        return self.__filename

    def _get_file(self):
        return self.__file

    def _get_modified(self):
        return self.__modified

    def _get_extension(self):
        return "py"

    def _save(self, filename):
        start = self.buf.get_start_iter()
        end = self.buf.get_end_iter()
        contents = self.buf.get_slice(start, end)

        f = open(filename, "w")
        f.write(contents)
        f.close()

        self.__set_filename_and_modified(filename, False)
        self.notebook.reset_module_by_filename(self.__filename)

    #######################################################
    # Utility
    #######################################################

    def __update_file(self):
        if self.__filename:
            new_file = self.notebook.file_for_absolute_path(self.__filename)
        else:
            new_file = None

        if new_file == self.__file:
            return

        if self.__file:
            self.__file.active = False
            self.__file.modified = False

        self.__file = new_file

        if self.__file:
            self.__file.active = True
            self.__file.modified = self.__modified

        self._update_file()

    def __set_filename(self, filename):
        if filename == self.__filename:
            return

        self.__filename = filename
        self._update_filename()
        self.notebook.refresh()
        self.__update_file()

    def __set_modified(self, modified):
        if modified == self.__modified :
            return

        self.__modified = modified
        if self.__file:
            self.__file.modified = modified
        self._update_modified()

    def __set_filename_and_modified(self, filename, modified):
        self.freeze_notify()
        self.__set_modified(modified)
        self.__set_filename(filename)
        self.thaw_notify()

    #######################################################
    # Public API
    #######################################################

    def load(self, filename):
        if os.path.exists(filename):
            f = open(filename, "r")
            contents = f.read()
            f.close()

            if use_sourceview:
                self.buf.begin_not_undoable_action()
            pos = self.buf.get_start_iter()
            self.buf.insert(pos, contents)
            if use_sourceview:
                self.buf.end_not_undoable_action()

        self.__set_filename_and_modified(filename, False)

    def close(self):
        Editor.close(self)
        if self.__file:
            self.__file.active = False
            self.__file.modified = False

    def undo(self):
        if use_sourceview:
            self.view.emit('undo')

    def redo(self):
        if use_sourceview:
            self.view.emit('redo')


#!/bin/python3

"""
Data Sanitize Python script
Author: Dusan Pilipovic Dusan.Pilipovic@dynatrace.com
v1.0 10-19-2020
v2.0 10-23-2020 - Changed script so that each FQDN that was found is replaced with unique host- parameter
v3.0 10-26-2020 - Modified script to update REGEXES with FQDN amd IP matches so we only replace once
v4.0 12-06-2021 - Added , errors='ignore' to lines 72 and 136 - so that script doesn't fail if it comes across non-UTF8 encoded characters
"""

import os, os.path, shutil, re, fnmatch
from datetime import datetime
import zipfile
import json

# Define paths
base = datetime.now().strftime("%m-%d-%Y-%H-%M-%S")
src = '/data/sanitize/dirty'
copydest = '/data/sanitize/clean/' + base

# Define Regexes - most important part, it's a list of compiled regular expressions with the text we want to replace it with
# They include email addresses, IP's, FQDN Hostnames and an AWS internal hostnames,  external AWS hostnames and Load Balancer names are covered by FQDN
# its much faster if you compile your regexes before you
# actually use them in a loop

REGEXES = [(re.compile(r"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|'(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*')@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])"), '*** EMAIL REPLACED ***'),
           (re.compile(r"ip(-[0-9]{1,3}){4}"), '*** AWS INT. HOSTNAME REPLACED ***')]

# ip_regex and hn_regex are used to find matches on IP addresses and Hostnames; Then those matches are added to REGEXES list before replacement
# regexes defined in REGEXES variable above just do complete replacement with the same text, ip_regex and hn_regex matches will be replaced with unique values
# as in host A becomes host-1 and host B becomes host-2;
# This was listed as a requirement by Support, as to make support logs easier to debug and that they can figure out which host talks to which.
# Note that both ip_regex and hn_regex are using non-capturing groups (:?) in order to return full matches and not capturing group matches
#
ip_regex = re.compile(r"(?:25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(?:25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])")

hn_regex = re.compile(r"[a-zA-Z0-9\-\.]+\.(?:com|org|net|mil|edu|COM|ORG|NET|MIL|EDU)")

def unpack_zipfiles(src):
    # Look for any zip files in the src dir via fnmatch and os.walk, unpack and remove zip
    print("Unpacking zip files at dirty directory, if any...")
    filePattern = '*.zip'
    for path, dirs, files in os.walk(os.path.abspath(src)):
      for filename in fnmatch.filter(files, filePattern):
        filepath = os.path.join(path, filename)
        zip_ref = zipfile.ZipFile(filepath)
        zip_ref.extractall(src)
        zip_ref.close()
        os.remove(filepath)

def ig_f(dir, files):
    # Get list of files in source to ignore when creating new directory structure
    return [f for f in files if os.path.isfile(os.path.join(dir, f))]

def copy_dir_tree(src, copydest):
    # Create a directory tree without files at destination
    print("Creating new directory structure at clean dir...")
    shutil.copytree(src, copydest, ignore=ig_f)

def find_matches(src, ip_regex, hn_regex, base, REGEXES):
    # Get a list of matches on ip_regex and hn_regex, create unique match dictionaries and then add them to REGEXES for replacement
    # Define dictionaries and counters
    ip_repl_d = {}
    ip_counter = 0
    hn_repl_d = {}
    hn_counter = 0
    srcfiles = [os.path.join(dp, f) for dp, dn, filenames in os.walk(src) for f in filenames]
    print("Searching for IP address and Hostname patterns in files and adding them to dictionary. This might take a while ...")
    for file in srcfiles:
      with open(file, 'r', errors='ignore') as f:
        for line in f:

          # Search for ip_regex matches and add unique match values to ip_repl_d dictionary
          if re.findall(ip_regex, line):
            ip_results = re.findall(ip_regex, line)
            ip_key = ip_results[0]
            if ip_key not in ip_repl_d:
              ip_counter = ip_counter + 1
              ip_val = ('ipaddr-' + str(ip_counter))
              ip_repl_d[ip_key] = ip_val

          # Search for hn_regex matches and add unique match values to hn_repl_d dictionary
          elif re.findall(hn_regex, line):
            hn_results = re.findall(hn_regex, line)
            hn_key = hn_results[0]
            if hn_key not in hn_repl_d:
              hn_counter = hn_counter + 1
              hn_val = ('host-' + str(hn_counter))
              hn_repl_d[hn_key] = hn_val

    # Let's capture replacement dictionaries of IPs and Hostnames for our own validation
    # It's a bit more readable in json format
    matches = '/data/sanitize/matches/match-' + base + '.json'
    print('Replacement dictionary of IP/Hostname matches is saved here: {}'.format(matches))
    ip_json = json.dumps(ip_repl_d)
    hn_json = json.dumps(hn_repl_d)
    m_file = open(matches,"w")
    m_file.write( '# IP replacement dictionary: ')
    m_file.write('\n')
    m_file.write( ip_json )
    m_file.write('\n')
    m_file.write( '# Hostname replacement dictionary: ')
    m_file.write('\n')
    m_file.write( hn_json )
    m_file.close()

    # Now append these matches to REGEXES list
    print("Adding IP and Hostname matches to REGEXES list for replacement...")
    for key, value in ip_repl_d.items():
      search = (re.compile(key))
      replace = value
      REGEXES.append((search, replace))

    for key, value in hn_repl_d.items():
      search = (re.compile(key))
      replace = value
      REGEXES.append((search, replace))

    #print(REGEXES)
    return REGEXES

def sanitize_files(src, copydest, REGEXES):
    # First obtain a list of files in src dir, then substitute any REGEXES it finds in all files!
    myfiles = [os.path.join(dp, f) for dp, dn, filenames in os.walk(src) for f in filenames]

    print("Now doing a replacement of all matches. This might take a while ...")
    for f in myfiles:
        input_file = f
        output_file = f.replace(src, copydest, 1)
        print('Original file: {}'.format(input_file))
        print('Cleaned file: {}'.format(output_file))

        with open(input_file, "r", errors='ignore') as fi, open(output_file, "w") as fo:
            for line in fi:
                for search, replace in REGEXES:
                    line = search.sub(replace, line)
                fo.write(line)
        # both the input and output files are closed automatically
        # after the with statement closes

def create_result_archive(base, copydest):
    output_filename = 'support-archive-' + base
    shutil.make_archive(output_filename, 'zip', copydest)
    print('Created Archive of cleaned files : {}.zip'.format(output_filename))

def main():
    unpack_zipfiles(src)
    copy_dir_tree(src, copydest)
    find_matches(src, ip_regex, hn_regex, base, REGEXES)
    sanitize_files(src, copydest, REGEXES)
    create_result_archive(base, copydest)

if __name__ == "__main__":
    main()


import pygame

pygame.init()

fenetre = pygame.display.set_mode((750, 750))

floor = pygame.image.load("floor.png")
wall = pygame.image.load("wall.png")
fenetre.blit(floor, (0,0))
fenetre.blit(wall, (10,10))
#Rafraîchissement de l'écran
pygame.display.flip()

#BOUCLE INFINIE
continuer = 1
while continuer:
	continuer = int(input())


def mostfrquent(arr):
    dict={}

    for x in arr:
        if x in dict:
            dict[x]+=1
        else:
            dict[x]=1

    mx=0
    ele=0

    for x in dict:
        if dict[x]>mx:
            mx=dict[x]
            ele=x

    print(ele)