#!/usr/bin/python3

import pathlib
import tensorflow as tf

def input_pipeline(dirname,
                   imagepath,
                   annotationpath,
                   is_training,
                   batch_size=32,
                   num_channels=3,
                   image_size=(224, 224),
                   standardize=True,
                   use_augmentation=True,
                   rotate=True,
                   flip=True,
                   crop=True,
                   padding=None,
                   num_parallel_calls=tf.data.experimental.AUTOTUNE,
                   use_caching=True,
                   resize=False):
    """Construct a data generator using tf.Dataset.

    Args:
        dirname: the directory containing the data
        imagepath: the path pattern for image files
        annotationpath: the path pattern for annotation files
        is_training: wether to use data augmentation and shuffling
        batch_size: the batch_size
        num_channels: the number of channels of the image
        image_size: (height, width) of images to output
        standardize: wether to standardize images
        use_augmentation: wether to use data augmentation
        rotate: wether to use rotation
        flip: wether to use flipping
        crop: wether to use cropping
        padding: the padding to use when cropping
        num_parallel_calls: the number of elements to process in parallel
        use_caching: wether to use caching after preprocessing or not. Can
        improve performance if RAM is big enough to store all the data

    Returns:
        tf.data.Dataset: Dataset with iterator that returns (image, annotation)
    """

    root_dir = pathlib.Path(dirname)

    # Create tf.data.Dataset containing the path strings
    # Important: We need to make sure that we only consider the images with
    # annotations available. We therefore loop over images/ txt files and look
    # if the associated file exist. Use sorting, just to be sure that data is
    # read in the same order.
    image_paths = tf.data.Dataset.from_tensor_slices(
        [str(path) for path in sorted(root_dir.glob(imagepath))
         if path.stem in [path2.stem for path2
                          in root_dir.glob(annotationpath)]]
    )
    annotation_paths = tf.data.Dataset.from_tensor_slices(
        [str(path) for path in sorted(root_dir.glob(annotationpath))
         if path.stem in [path2.stem for path2
                          in root_dir.glob(imagepath)]]
    )

    # Now create new datasets that load images and annotations one-the-fly
    images = image_paths.map(
        lambda x: load_image(x, resize=resize, num_channels=num_channels),
        num_parallel_calls=num_parallel_calls
    )
    if annotationpath.endswith('.txt'):
        annotations = annotation_paths.map(
            load_annotations,
            num_parallel_calls=num_parallel_calls
        )
    elif annotationpath.endswith('.png'):
        annotations = annotation_paths.map(
            lambda x: load_image(x, resize=resize, num_channels=1),
            num_parallel_calls=num_parallel_calls
        )
    else:
        raise NotImplementedError('Annotations need to be txt or png files')

    # Since the datasets are in the same order we can just zip them together
    # to get a dataset of (image, annotations) pairs.
    data = tf.data.Dataset.zip((images, annotations))

    data = data.map(
        lambda x, y: preprocessing(data=(x, y), standardize=standardize),
        num_parallel_calls=num_parallel_calls)

    if is_training:
        data = data.shuffle(100)

    if use_caching:
        data = data.cache()

    data = data.repeat()

    if use_augmentation:
        data = data.map(
            lambda x, y: augment(
                data=(x, y),
                size=image_size,
                num_channels=num_channels,
                rotate=rotate,
                flip=flip,
                crop=crop,
                padding=padding),
            num_parallel_calls=num_parallel_calls)
        data = data.batch(batch_size, drop_remainder=True)
    else:
        data = data.map(
            lambda x, y: extract_patches(
                data=(x, y),
                size=image_size,
                num_channels=num_channels),
            num_parallel_calls=num_parallel_calls
        )

    data = data.prefetch(tf.data.experimental.AUTOTUNE)

    return data

def serving_input_pipeline(imagepath,
                           num_channels=3,
                           image_size=(224, 224),
                           standardize=True,
                           num_parallel_calls=tf.data.experimental.AUTOTUNE):
    """Construct a data generator using tf.Dataset for prediction.

    Args:
        imagepath: the path pattern for image files
        num_channels: the number of channels of images
        image_size: (height, width) of images to output
        standardize: wether to standardize images
        num_parallel_calls: the number of elements to process in parallel

    Returns:
        tf.data.Dataset: Dataset with iterator that returns (image, annotation)
    """

    paths = tf.gfile.Glob(imagepath)
    image_paths = tf.data.Dataset.from_tensor_slices(paths)

    images = image_paths.map(
        lambda x: load_image(x, num_channels=num_channels),
        num_parallel_calls=num_parallel_calls
    )

    if standardize:
        images = images.map(
            lambda x: tf.image.per_image_standardization(x),
            num_parallel_calls=num_parallel_calls)

    images = images.map(
        lambda x: tf.reshape(
            tf.extract_image_patches(
                images=tf.expand_dims(x, 0),
                ksizes=(1,) + image_size + (1,),
                strides=(1,) + image_size + (1,),
                rates=[1, 1, 1, 1],
                padding='SAME'),
            shape=[-1, image_size[0], image_size[1], num_channels]),
        num_parallel_calls=num_parallel_calls)

    return images, paths

def load_image(path, resize=False, num_channels=3):
    """Load images.

    Args:
        path: the path of the image
        num_channels: the number of channels

    Returns:
        Tensor: with shape [height, width, num_channels]
    """
    image = tf.read_file(path)
    image = tf.image.decode_png(image, channels=num_channels)
    if resize:
        image = tf.image.resize_images(image, size=(1500, 2000))
    image.set_shape([None, None, num_channels])
    return tf.cast(image, tf.float32)

# TODO: Obsolet?
def load_annotations(path):
    """Load annotations.

    Args:
        path: the path of the txt file containing annotations

    Returns:
        Tensor:
    """
    annotations = tf.read_file(path)
    # Get rid of the last value, because it is an empty string
    annotations = tf.strings.split([annotations], '\n').values[:-1]
    # Extract columns by using blank space as delimiter
    x_position, y_position, _ = tf.io.decode_csv(
        records=annotations,
        record_defaults=[[], [], 0],
        field_delim=' ')
    # Transform to sparse Tensor, i.e. use x_position and y_position as
    # indices
    sparse_annotations = tf.SparseTensor(
        indices=tf.stack(
            [tf.cast(y_position, tf.int64), tf.cast(x_position, tf.int64)],
            axis=-1),
        values=tf.ones_like(y_position),
        dense_shape=[1600, 1200]
    )
    annotation_mask = tf.sparse.to_dense(
        sparse_annotations,
        validate_indices=False)

    return annotation_mask

def augment(data,
            size=(224, 224),
            num_channels=1,
            rotate=False,
            flip=False,
            crop=False,
            padding=None):
    """Applies rotating, flipping and cropping data augmentation.

    Args:
        data: the image and annotations
        size: (height, width) of image
        num_channels: the number of channels of images
        rotate: wether to use rotation
        flip: wether to use flipping
        crop: wether to use cropping
        padding: the padding to use when cropping

    Returns:
        (Tensor, Tensor): augmented image of shape (height, width,
        num_channels) and associated annotations of shape (height, width)
    """

    # Concat image and annotations so the same augmentation is applied
    image_annotations = tf.concat(data, axis=-1)

    if crop:
        if padding:
            image_annotations = tf.pad(
                image_annotations,
                ((padding, padding), (padding, padding), (0, 0)))
        image_annotations = tf.image.random_crop(
            image_annotations, size + (num_channels+1,))
    else:
        image_annotations = tf.extract_image_patches(
            images=tf.expand_dims(image_annotations, 0),
            ksizes=(1,) + size + (1,),
            strides=(1,) + size + (1,),
            rates=[1, 1, 1, 1],
            padding='SAME'
        )
        patches_shape = tf.shape(image_annotations)
        image_annotations = tf.reshape(
            image_annotations,
            (-1,) + size + (num_channels+1,)
        )
        image_annotations.set_shape((None, size[0], size[1], num_channels+1))

    if rotate:
        # Rotate 0, 90, 180 or 270 degrees randomly
        image_annotations = tf.image.rot90(
            image_annotations,
            tf.random_uniform(shape=[], minval=0, maxval=4, dtype=tf.int32)
        )

    if flip:
        image_annotations = tf.image.random_flip_left_right(image_annotations)

    image = image_annotations[..., :-1]
    annotations = image_annotations[..., -1:]
    return image, annotations

def preprocessing(data, standardize=False):
    """Apply preprocessing to image.

    Args:
        data: the image and annotations
        standardize: wether to standardize image

    Returns:
        (Tensor, Tensor): the preprocessed image, the annotations
    """
    # Unpack image and annotations form data
    image, annotations = data

    image /= 255.
    annotations /= 255.

    # Standardize to mean zero and unit variance
    if standardize:
        image = tf.image.per_image_standardization(image)

    return image, annotations

def extract_patches(data, size=(224, 224), num_channels=3):
    """Extract patches from image and annotations.

    Args:
        data: the image and annotations
        size: (height, width) of patches

    Returns:
        (Tensor, Tensor): image of shape (n_patches, height, width, n_channels)
        and annotations of shape (n_patches, height, width)
    """

    patches = tf.concat(data, axis=-1)
    patches = tf.extract_image_patches(
        images=tf.expand_dims(patches, 0),
        ksizes=(1,) + size + (1,),
        strides=(1,) + size + (1,),
        rates=[1, 1, 1, 1],
        padding='SAME'
    )

    patches = tf.reshape(patches, shape=[-1, size[0], size[1], num_channels+1])
    patches.set_shape((None, size[0], size[1], num_channels+1))
    image = patches[..., :-1]
    annotations = patches[..., -1:]
    return image, annotations


from corsheaders.defaults import default_headers
from .base import *
from sentry_sdk.integrations.celery import CeleryIntegration

SECRET_KEY = env('SECRET_KEY')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
ALLOWED_HOSTS = ['*']
CORS_ORIGIN_ALLOW_ALL = True
DJANGO_DEBUG = False
DJANGO_READ_DOT_ENV_FILE = False

CORS_ALLOW_HEADERS = list(default_headers) + [
    'content-disposition',
    'access-control-max-age'
]

# Email backend for Production
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

# Initialize Sentry
sentry_sdk.init(
    dsn=env.str('SENTRY_DSN'),
    integrations=[DjangoIntegration(), CeleryIntegration()],
    send_default_pii=True
)


import requests
import random_url
import sys
import json
import time
import pickle
import os
import datetime

def connect(url):
    r = requests.get(url)
    # print("Status Code:", r.status_code)

    if r.status_code != requests.codes.ok:
        print("Received a bad status code from the server -- aborting")
        print(r.text)
        # sys.exit()
    return r

def getPageResult(res):
    return json.loads(res.text)['results']

def getArrivalList(key, source):
    return [entry[key] for entry in source]

def getStops(predictions):
    stops = [(entry['sequence'], entry['stop_code_lbsl'])
             for entry in predictions]
    sorted(stops, key=lambda x: x[0])
    stops = [x[1] for x in stops]
    return stops

def getTime(l):
    return datetime.datetime.fromtimestamp(int(l / 1000))

def getPredictions(pre_res, tfl_res):
    predictions = getPageResult(pre_res)
    tfl_timetable = getPageResult(tfl_res)

    stops = getStops(predictions)

    historical = getArrivalList('cumulative_travel_time', predictions)
    print(historical)
    current = getArrivalList('curr_cumulative_travel_time', predictions)
    print(current)
    reference = getArrivalList('cumulative_travel_time', tfl_timetable)
    return (historical, current, reference, stops)

def connect_to_countdown(route, run, naptan_atco):
    url = ("http://countdown.api.tfl.gov.uk/interfaces/ura/instant_V1?"
           "LineName={}&DirectionID={}&StopCode2={}&"
           "ReturnList=StopID,LineName,DirectionID,VehicleID,TripID,"
           "EstimatedTime,ExpireTime")
    url = url.format(route, run, naptan_atco)
    # print(url)
    r = requests.get(url, auth=('LiveBus95085', 'rU9HUx4ZEm'))
    # print("Status Code:", r.status_code)

    if r.status_code != requests.codes.ok:
        print("Received a bad status code from the server -- aborting")
        print(r.text)
        # sys.exit()
    return r

def getCountdowns(r):
    buses = []
    for line in r.iter_lines():
        if not line:
            continue
        line = json.loads(line.decode('utf-8-sig'))
        if line[0] != 1:
            continue
        line = line[1:]
        buses.append(line)
    return buses

def getNextVehicle(countdown_res):
    # next_vehicles = []
    # while next_vehicles == []:
        # print("Getting countdowns...")
        # print(countdown_res)
        # print(len(countdown_res.lines()))
    next_vehicles = getCountdowns(countdown_res)
    sorted(next_vehicles, key=lambda x: x[5])
    if not next_vehicles:
        return []
    nxt = next_vehicles[0]
    vehicle = {}
    vehicle['stop_code_lbsl'] = nxt[0]
    vehicle['route'] = nxt[1]
    vehicle['run'] = nxt[2]
    vehicle['vehicle_id'] = nxt[3]
    vehicle['trip_id'] = nxt[4]
    vehicle['arrival_time'] = nxt[5]
    return vehicle

def load_current_predictions():
    if os.path.isfile("evaluate_api.p"):
        return pickle.load(open("evaluate_api.p", "rb"))
    else:
        return {}

def updateRecord(record, pre_res, tfl_res, countdown_res,
                 params, next_vehicle, record_time):
    print("Getting predictions")
    historical, current, reference, stops = getPredictions(pre_res, tfl_res)
    record_key = (params['day'], params['hour'], params['route'],
                  params['run'], params['naptan_atco'])
    record[record_key] = {'historical': historical,
                          'current': current,
                          'reference': reference,
                          'pre_url': pre_url,
                          'tfl_url': tfl_url,
                          'next_vehicle': next_vehicle,
                          'stops': stops,
                          'record_time': record_time}
    return record

for i in range(100):
    record = load_current_predictions()
    next_vehicle = []
    try:
        while not next_vehicle:
            pre_url, tfl_url, params = random_url.getCurrentURLs()

            print("Connecting to TfL countdown")
            print(params)
            countdown_res = connect_to_countdown(params['route'],
                                                 params['run'],
                                                 params['naptan_atco'])
            next_vehicle = getNextVehicle(countdown_res)
            record_time = time.time()
            print('next_vehicle')
            print(next_vehicle)
            if countdown_res.status_code != requests.codes.ok:
                continue
            if not next_vehicle:
                continue

            if getTime(next_vehicle['arrival_time']) - datetime.datetime.now() > datetime.timedelta(minutes=5):
                continue
                print('next loop')

            print("Connecting to endpoints")
            print(pre_url)
            pre_res, tfl_res = connect(pre_url), connect(tfl_url)
            if pre_res.status_code != requests.codes.ok:
                continue
            if tfl_res.status_code != requests.codes.ok:
                continue

            print("Updating record")
            print(countdown_res.text)
            record = updateRecord(record, pre_res, tfl_res, countdown_res,
                                  params, next_vehicle, record_time)
            print(len(record))
            print("Saving to pickle")
            pickle.dump(record, open("evaluate_api.p", "wb"))
            print("Finish")
    except ValueError:
        print("Error,")


import scipy.io as io
from PIL import Image
from glob import glob
import os
from einops import rearrange
import numpy as np
import torch

class GTA_dataset():
    def __init__(self,
                path,
                split="train",
                img_size = (1914, 1052),
                mean=[0.5, 0.5, 0.5],
                std=[1, 1, 1],
                ignore_index=250):

        if not (split == "train" or split == "test" or split == "val"):
            assert("split only train/test/val")
        splits = io.loadmat(os.path.join(path, 'split.mat'))
        ids = None
        if (split == "train"):
            ids = splits["trainIds"][:,0]
        elif (split == "test"):
            ids = splits["testIds"][:,0]
        elif (split == "val"):
            ids = splits["valIds"][:,0]
        ids = [str(i).zfill(5)+".png" for i in ids]
        self.img_paths = [os.path.join(path, "images", item) for item in ids]
        self.lbl_paths = [os.path.join(path, "labels", item) for item in ids]
        self.img_size = img_size
        self.mean = mean
        self.std = std
        self.ignore_index = ignore_index
        self._init()
    def __len__(self):
        return len(self.lbl_paths)

    def __getitem__(self, index):
        img = Image.open(self.img_paths[index])
        lbl = Image.open(self.lbl_paths[index])
        img = img.resize(self.img_size, Image.BILINEAR)
        lbl = lbl.resize(self.img_size, Image.NEAREST)
        img = np.array(img, dtype=np.uint8)
        lbl = np.array(lbl, dtype=np.uint8)
        lbl = self.encode_segmap(lbl) # 将官方label的index变为我们关心的
        # 归一化
        img = img / 255.0
        img = img - self.mean
        img = img / self.std
        img = rearrange(img, "h w c -> c h w")
        # 转为tensor
        img = torch.from_numpy(img).float()
        lbl = torch.from_numpy(lbl).long()
        return img, lbl
    def _init(self):
        self.n_classes = 19
        self.valid_classes = [7, 8, 11, 12, 13, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 32, 33,]
        self.class_names = ["road","sidewalk","building","wall","fence","pole","traffic_light",
            "traffic_sign","vegetation","terrain","sky","person","rider","car","truck","bus","train",
            "motorcycle","bicycle",]
        self.class_map = dict(zip(self.valid_classes, range(self.n_classes)))
    def encode_segmap(self, mask):
        """将label官方index转为想要的

        Args:
            mask (_type_): _description_

        Returns:
            _type_: _description_
        """
        label_copy = self.ignore_index * np.ones_like(mask, dtype=np.uint8)
        for k, v in list(self.class_map.items()):
            label_copy[mask == k] = v
        return label_copy


"""
This module is used in order to display the data
in a complete and good-looking way
"""

import pandas as pd
from tabulate import tabulate

def display_table(data):
    """
    Get the weather information and display it in a nice way through a table
    :param data: weather information
    :return: table to be displayed to the user in which there are the
    weather, the temperature, the description, the icon of the requested city
    or its history
    """
    # create a list of dictionaries
    data = [data] if type(data) is dict else data
    # create a dataframe
    df = pd.DataFrame(data)
    if 'id' in df.columns:
        df.drop(['id'], axis=1, inplace=True)
    # use capital letters for the headers
    df.columns = df.columns.str.upper()
    # create the table using tabulate
    table = tabulate(df, headers='keys', showindex=False)
    print(table)


import pandas as pd

file = "C:\\Users\\DJew\\Documents\\Learning\\Python\\Data21Notes\\Advent1\\Numbers.xlsx"
df = pd.read_excel(file)  # reading file

# loop through to get first number
for ind, row1 in df.iterrows():
    currentNumber = int(row1[0])
    # loop through to add second number
    for ind, row2 in df.iterrows():
        tempNumber1 = int(row2[0])
        if currentNumber + tempNumber1 < 2020:
            # if less than 2020 then loop through to add third number
            for ind, row3 in df.iterrows():
                tempNumber2 = int(row3[0])
                if (currentNumber + tempNumber1 + tempNumber2) == 2020:
                    print(currentNumber*tempNumber1*tempNumber2)
                    print(currentNumber + tempNumber1 + tempNumber2)
                else:
                    continue
        else:
            continue


import pandas as pd

def subset_df(df, kv_dict:dict):
    ''' Subsets a dataframe based on an arbitrary number of column condition matches.
        Example:
            select_df(df, kv_dict={'Type':'pvf', 'year':2008})
        Usage Note:
            for now, equals ("==") is the only conditional supported. '''

    for key in kv_dict.keys():
        df = df[df[key]==kv_dict[key]]

    return df

def make_rafaj_custom_cmap():
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.colors import ListedColormap
    from Additional_Colormaps import make_hex_list, make_custom_cmap_from_hex_list, load_all_cmaps

    new_cmaps = load_all_cmaps()
    n_colors = [4, 4, 6]
    total_n = np.sum(np.array(n_colors))

    rgb_values = (np.array(new_cmaps['rafaj_AQ'].colors[0:2])[:,:3]*255).astype(int)
    test_hex_list = make_hex_list(rgb_values)
    colors1       = make_custom_cmap_from_hex_list(hex_list=test_hex_list, n_colors=n_colors[0], cmap_name='c1')
    colors1       = colors1(np.linspace(0, 1, n_colors[0]))

    rgb_values    = (np.array(new_cmaps['rafaj_AQ'].colors[2:5])[:,:3]*255).astype(int)
    test_hex_list = make_hex_list(rgb_values)
    colors2       = make_custom_cmap_from_hex_list(hex_list=test_hex_list, n_colors=n_colors[1], cmap_name='c2')
    colors2       = colors2(np.linspace(0, 1, n_colors[1]))

    rgb_values    = (np.array(new_cmaps['rafaj_AQ'].colors[5:])[:,:3]*255).astype(int)
    test_hex_list = make_hex_list(rgb_values)
    colors3       = make_custom_cmap_from_hex_list(hex_list=test_hex_list, n_colors=n_colors[2], cmap_name='c3')
    colors3       = colors3(np.linspace(0, 1, n_colors[2]))

    all_colors = np.vstack((colors1, colors2, colors3))
    newcmap = ListedColormap(all_colors)

    return newcmap


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 19 16:32:27 2021

@author: pierre
"""

import glob
from astropy.io import fits
import numpy as np
import os
import scipy.signal
from sinfobj import sinfobj
from get_mag import get_coord_sinfoni, get_2MASS_mags
from scipy.signal import medfilt
import matplotlib.pyplot as plt
import numpy.ma as ma
rep_save = '/media/pierre/Disque_2/SNR/CALIBRATED_1/'

def get_obj_header(filename):
    hdu = fits.open(filename)
    obj = hdu[0].data
    header = hdu[0].header
    hdu.close()
    return np.nan_to_num(obj), header

def get_fov(filename):
    hdu = fits.open(filename)
    header = hdu[0].header
    pscale = header['CDELT2']*3600
    fov = pscale*np.shape(hdu[0].data)[1]
    hdu.close()
    return fov

def get_coord(filename):
    hdu = fits.open(filename)
    header = hdu[0].header
    RA = header['RA']
    dec = header['DEC']
    hdu.close()
    return RA, dec

def get_band(filename):
    hdu = fits.open(filename)
    header = hdu[0].header
    wl = header['CRVAL3']
    if wl < 1.3:
        band ='j'
    elif wl < 1.8:
        band='h'
    else:
        band='k'
    return band

def get_zmin_zmax(filter_interp):
    zmin = 0
    zmax = len(filter_interp)
    first_half = True
    done = False
    for x in range(len(filter_interp)):
        # print(x)
        y = filter_interp[x]
        if y == 0 and first_half:
            zmin = x
        elif first_half:
            first_half = False
        elif  y == 0 and (not done):
            zmax = x
            done = True
    return zmin, zmax

# for rep1 in glob.glob(rep_save+'/*'):
#     for rep2 in glob.glob(rep1+'/*'):
#         for rep3 in glob.glob(rep2+'/*'):
#             for file in glob.glob(rep3+'/calibrated.fits'):
#                 if 'NGC' in file:
#                     print(file)
#                     obj, header = get_obj_header(file)
#                     raobj, decobj = get_coord(file)
#                     fov = get_fov(file)
#                     band = get_band(file)
#                     mags_obj = np.array(get_2MASS_mags(raobj, decobj, fov=fov, band=band, verbose=False))
#                     mag_obj = np.mean(mags_obj[~np.isnan(mags_obj)])

#                     xmax, ymax = np.unravel_index(np.argmax(scipy.signal.medfilt(np.median(np.nan_to_num(obj),0),(5,5))), np.shape(obj[0]))

#                     limits = [np.max([0,xmax-28]), np.min([xmax+28, np.shape(obj[0])[0]]),np.max([0,ymax-28]), np.min([ymax+28, np.shape(obj[0])[1]])]

#                     if band == 'j':
#                         F_0 = 3.129e-13*1e4# *1e4 pour passer de W/cm2/um à W/m2/um
#                         bwidth = 0.162
#                         filter_name = '/home/pierre/Documents/2021/SINFONI_analysis/2MASS_filters/J.txt'
#                         filt = np.loadtxt(filter_name).T

#                     if band == 'h':
#                         F_0 = 3.129e-13*1e4# *1e4 pour passer de W/cm2/um à W/m2/um
#                         bwidth = 0.162
#                         filter_name = '/home/pierre/Documents/2021/SINFONI_analysis/2MASS_filters/J.txt'
#                         filt = np.loadtxt(filter_name).T

#                     if band =='k':
#                         F_0 = 4.283e-14*1e4# *1e4 pour passer de W/cm2/um à W/m2/um
#                         bwidth = 0.261
#                         filter_name = '/home/pierre/Documents/2021/SINFONI_analysis/2MASS_filters/K.txt'
#                         filt = np.loadtxt(filter_name).T

#                     wl = (np.arange(len(obj))-header['CRPIX3'])*header['CDELT3']+header['CRVAL3']

#                     filter_interp = np.interp(wl, filt[0], filt[1])

#                     zmin, zmax = get_zmin_zmax(filter_interp)

#                     obj_2MASSed = obj*filter_interp[:, np.newaxis, np.newaxis]
#                     tot_adu = np.sum(np.nan_to_num(obj_2MASSed[:,limits[0]:limits[1],limits[2]:limits[3]]))
#                     med_adu = np.median(np.nan_to_num(obj_2MASSed[zmin:zmax,limits[0]:limits[1],limits[2]:limits[3]]))*len(obj_2MASSed[zmin:zmax, limits[0]:limits[1], limits[2]:limits[3]].flatten())
#                     if abs(2.5*np.log10(tot_adu/bwidth/F_0)-2.5*np.log10(med_adu/bwidth/F_0))>1.2:
#                         print(band, fov, mag_obj, -2.5*np.log10(tot_adu/bwidth/F_0), -2.5*np.log10(med_adu/bwidth/F_0), '(', med_adu, ' and not ', tot_adu, ')')
#                     else:
#                         print('OK')

filenames = glob.glob('/media/pierre/Disque_2/SNR/CALIBRATED_1/*Circi*/*50/N_*/*.fits')

filenames = glob.glob('/media/pierre/Disque_2/SNR/CALIBRATED_1/*1808*/H*/N_*/*.fits')
filename = '/media/pierre/Disque_2/SNR/archive/076B0098A/reflex_end_products/2021-04-23T11:22:26/SINFO.2005-03-24T00:07:57.876_tpl/calibrated/calibrated.fits'
specs = []
for filename in filenames:
    hdu = fits.open(filename)
    obj = sinfobj(hdu)
    obj.plot_spec(-0.5,0.5,-0.5,0.5, newfig=False)
    spec = obj.get_spec(-0.5,0.5,-0.5,0.5)[1]
    im = obj.get_im(1.6,1.7,-1,1,-1,1)
    xmax, ymax = np.unravel_index(np.argmax(medfilt(im,(5,5))), np.shape(im))
    if xmax > 5:
        specs.append(ma.masked_invalid(spec))
        print(xmax, ymax)
        print(obj.header['OBJECT'])

plt.figure()
plt.plot(np.mean(specs, 0))


import sys

import pygame
from pygame import *
from pygame.mixer import Sound

import Config
from Config import *
from classes.menus.main_menu import main_menu

Config.current_menu = main_menu

def main():
    running = True

    while running:
        clock.tick(FPS)
        for p in main_menu.player_sprite:
            if Config.x > 0:
                Config.x = p.rect.x - WIN.get_width()/2
                if Config.x + Config.WIDTH < Config.map.get_width():
                    Config.x = p.rect.x - WIN.get_width() / 2
                else:
                    if p.rect.x + WIDTH/2 < Config.map.get_width():
                        Config.x = p.rect.x - WIN.get_width() / 2
                    Config.x = p.rect.x - (WIDTH - (Config.map.get_width() - p.rect.x))
            else:
                if p.rect.x - WIN.get_width()/2 > 0:
                    Config.x = p.rect.x - WIN.get_width()/2

            if p.rect.y - HEIGHT/2 > 0:
                if p.rect.y + Config.HEIGHT/2 < Config.map.get_height():
                    Config.y = p.rect.y - Config.HEIGHT/2
                elif p.rect.y + Config.HEIGHT / 2 > Config.map.get_height():
                    Config.y = Config.map.get_height() - HEIGHT
                else:
                    Config.y = 0

        Config.map.convert_alpha()
        WIN.blit(Config.map, (-1 * Config.x, -1 * Config.y))
        Config.current_menu.run()

        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                running = False

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()


class RandomizedSet:
    def __init__(self):
        self.s=set()
    def insert(self, val):
        if val in self.s:
            return False
        self.s.add(val)
        return True
    def remove(self,val):
        if val not in self.s:
            return False
        self.s.remove(val)
        return True
    def getRandom(self):
        from random import randint
        return list(self.s)[randint(0,len(self.s)-1)]

obj=RandomizedSet()
print(obj.s)
obj.insert(1)
obj.insert(2)
obj.insert(3)
obj.insert(4)
obj.insert(5)
obj.insert(6)
print(obj.s)
obj.remove(1)
print(obj.getRandom())


"""jemimu.py
Desc: hardware abstraction layer around accel and gyro sensor
Driver used: BNO055
Example:
    >> imu = JemIMU()
    >> imu.gyro['y'] # deg / sec
    >> 1.3
    >> imu.accel['y'] # g's
    >> 0.983
    >> imu.power_down() # if available, will put device to sleep to save power
    >> imu.pn # part number of driver
    >> "BNO055"
"""

from drivers.bno055 import BNO055

class JemIMU(BNO055):
    def __init__(self, **kwargs):
        super(JemIMU, self).__init__(**kwargs)

    @property
    def mag(self):
        """Return mag struct that can reference x, y and z values
        Ex: >> imu = JemIMU()
            >> imu.mag['x']
            >> 0.1
        """
        try:
            mag_data = self.read_magnetometer()
            # get struct so user can access: mag['x']   mag['y']   mag['z']
            return {'x':mag_data[0], 'y':mag_data[1], 'z':mag_data[2]}
        except Exception as e:
            print("mag failed - from {0} device - {1}".format(self.pn, e))

    @property
    def gyro(self):
        """Return gyro struct that can reference x, y and z values
        Ex: >> imu = JemIMU()
            >> imu.gyro['x']
            >> 0.42
        """
        try:
            d = self.read_gyroscope()
            # get struct so user can access: gyro['x']   gyro['y']   gyro['z']
            return {'x':d[0], 'y':d[1], 'z':d[2]}
        except Exception as e:
            print("gyro failed - from {0} device - {1}".format(self.pn, e))

    @property
    def accel(self):
        """Return accel struct that can reference x, y and z values
        Ex: >> imu = JemIMU()
            >> imu.accel['x']
            >> 1.23
        """
        try:
            d = self.read_accelerometer()
            return {'x':d[0], 'y':d[1], 'z':d[2]}
        except Exception as e:
            print("accel failed - from {0} device - {1}".format(self.pn, e))

    @property
    def orientation(self):
        """Return roll, pitch, yaw (heading) in degrees
        Ex: >> imu = JemIMU()
            >> imu.orientation['roll']
            >> 34.5
        """
        try:
            d = self.read_euler()
            return {'yaw':d[0], 'roll':d[1], 'pitch':d[2]}
        except Exception as e:
            print("orientation failed - from {0} device - {1}".format(self.pn, e))

if __name__ == "__main__":
    import time
    imu = JemIMU()
    # move your hand up / down over the range sensor to see distance change
    for i in range(10): # run for 10 seconds
        print("orientation: %s" % imu.orientation)
        time.sleep(1)


import re
import subprocess
import sys

from PySide2.QtCore import QObject, Signal
from PySide2.QtWidgets import QApplication, QMainWindow, QMessageBox, QListWidgetItem, QMenu, QAction
from netifaces import ifaddresses, interfaces, AF_INET

from ui import Ui_MainWindow

class MySignals(QObject):
    signal = Signal(object)

class QMain(QMainWindow):

    def __init__(self):
        super(QMain, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        # 过滤掉未获取到IP地址的适配器
        self.ip_address_list = sorted([a for a in self.get_all_ip_address() if a[:3] != '169'])
        self.ui.listenaddress.addItems(self.ip_address_list)
        self.ui.connectaddress.addItems(self.ip_address_list)
        self.update_network_list = MySignals()
        # 信号连接槽，需要更新端口转发地址时发送信号触发函数调用
        self.update_network_list.signal.connect(self.get_all_network)  # noqa
        self.get_all_network()
        self.check_service_status()

    @staticmethod
    def get_all_ip_address():
        """
        获取本机所有的IP地址

        :return: IP地址列表
        """
        return [ifaddresses(a)[AF_INET][0]['addr'] for a in interfaces() if (AF_INET in ifaddresses(a))]

    def start(self):
        """
        运行程序

        :return: None
        """
        network = self.ui.network.currentText()
        listen_address = self.ui.listenaddress.currentText()
        listen_port = self.ui.listenport.text()
        connect_address = self.ui.connectaddress.currentText()
        connect_port = self.ui.connectport.text()
        if self.check_ip_port(listen_address, listen_port, connect_address, connect_port):
            command = 'netsh interface portproxy add %s listenaddress=%s listenport=%s connectaddress=%s connectport=%s'  # noqa
            command = command % (network, listen_address, listen_port, connect_address, connect_port)
            self.run_and_check_result(command)
            # 执行命令结束发出信号更新network_list
            self.update_network_list.signal.emit(True)  # noqa

    def check_ip_port(self, listen_address, listen_port, connect_address, connect_port):
        """
        检测IP地址和端口是否合法

        :param listen_address: 监听地址
        :param listen_port: 监听端口
        :param connect_address: 连接地址
        :param connect_port: 连接端口
        :return: bool
        """
        if not (listen_address and listen_port and connect_address and connect_port):
            text = ''
            if not listen_address:
                text += '监听地址，'
            if not listen_port:
                text += '监听端口，'
            if not connect_address:
                text += '连接地址，'
            if not connect_port:
                text += '连接端口，'
            QMessageBox.warning(self, '提示', f'{text[:-1]}不能为空！', QMessageBox.Ok, QMessageBox.Ok)
            return False
        rule_ipaddress = re.compile(r'^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$')
        rule_port = re.compile(
            r'^[1-9]$|(^[1-9][0-9]$)|(^[1-9][0-9][0-9]$)|(^[1-9][0-9][0-9][0-9]$)|(^[1-6][0-9][0-9][0-9][0-9]$)')
        if rule_ipaddress.match(listen_address) and rule_ipaddress.match(connect_address) and \
                rule_port.match(listen_port) and rule_port.match(connect_port):
            if 1 <= int(listen_port) <= 65535 and 1 <= int(connect_port) <= 65535:
                return True
            else:
                if not (1 <= int(listen_port) <= 65535):
                    QMessageBox.warning(self, '提示', '监听端口不合法！', QMessageBox.Ok, QMessageBox.Ok)
                    return False
                if not (1 <= int(connect_port) <= 65535):
                    QMessageBox.warning(self, '提示', '连接端口不合法！', QMessageBox.Ok, QMessageBox.Ok)
                    return False
        else:
            text = ''
            if not rule_ipaddress.match(listen_address):
                text += '监听地址，'
            if not rule_ipaddress.match(connect_address):
                text += '连接地址，'
            if not rule_port.match(listen_port):
                text += '监听端口，'
            if not rule_port.match(connect_port):
                text += '连接端口，'
            QMessageBox.warning(self, '提示', f'{text[:-1]}不合法！', QMessageBox.Ok, QMessageBox.Ok)
            return False

    def run_and_check_result(self, command):
        """
        运行程序并且检测返回结果

        :param command: 需要运行的命令
        :return: None
        """
        stdout_data, stderr_data = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                                    stdin=subprocess.PIPE,  # GUI程序中记得设置标准输入
                                                    shell=True).communicate()
        stdout_data = stdout_data.decode('gbk')
        stderr_data = stderr_data.decode('gbk')
        if stdout_data == '请求的操作需要提升(作为管理员运行)。\n\r\n':
            QMessageBox.warning(self, '提示', '请使用管理员权限运行程序！', QMessageBox.Ok, QMessageBox.Ok)
        elif stdout_data == '\r\n' and stderr_data == '':
            QMessageBox.information(self, '提示', 'OK!', QMessageBox.Ok, QMessageBox.Ok)
        else:
            QMessageBox.information(self, '提示', f'{stdout_data}\r\n{stderr_data}', QMessageBox.Ok, QMessageBox.Ok)

    def edit_item(self, item: QListWidgetItem):
        """
        编辑IP和端口

        :param item: 选中的item
        :return: None
        """
        src, des = item.text().split(' -> ')
        src_ip, src_port = src.split(':')
        des_ip, des_port = des.split(':')
        self.ui.listenaddress.setCurrentText(src_ip)
        self.ui.listenport.setText(src_port)
        self.ui.connectaddress.setCurrentText(des_ip)
        self.ui.connectport.setText(des_port)

    def get_all_network(self):
        """
        获取所有的网络适配器中包含的地址

        :return: None
        """
        # 先清空之前的值，再更新
        self.ui.network_list.clear()
        parent = r'(\S+?)\s+?(\d+?) \s+?(\S+?)\s+?(\d+?)\s+?'
        get_ip_port = re.compile(parent, re.VERBOSE)
        command = 'netsh interface portproxy show all'  # noqa
        stdout_data, stderr_data = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                                                    stdin=subprocess.PIPE,
                                                    shell=True).communicate()
        stdout_data, stderr_data = stdout_data.decode('gbk'), stderr_data.decode('gbk')
        result = re.findall(get_ip_port, stdout_data)
        for a in result:
            self.ui.network_list.addItem(f'{a[0]}:{a[1]} -> {a[2]}:{a[3]}')

    def my_listwidget_context(self, position):  # noqa
        """
        右键菜单

        :param position: 选中的条目索引
        :return: None
        """
        # 只有在选中item时才会出现菜单
        if self.ui.network_list.itemAt(position):
            menu = QMenu()
            del_act = QAction("删除", self)
            del_act.triggered.connect(self.del_network)  # noqa
            menu.addAction(del_act)
            menu.exec_(self.ui.network_list.mapToGlobal(position))

    def del_network(self):
        """
        删除数据

        :return: None
        """
        ip, port = self.ui.network_list.currentItem().text().split(' -> ')[0].split(':')
        command = f'netsh interface portproxy delete {self.ui.network.currentText()} listenaddress={ip} listenport={port}'  # noqa
        self.run_and_check_result(command)
        # 执行命令结束发出信号更新network_list
        self.update_network_list.signal.emit(True)  # noqa

    def check_service_status(self):
        """
        检查端口转发所需服务状态

        :return: None
        """
        command = 'sc query iphlpsvc'  # noqa
        stdout_data, stderr_data = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                                                    stderr=subprocess.PIPE, shell=True).communicate()
        stdout_data, stderr_data = stdout_data.decode('gbk'), stderr_data.decode('gbk')
        print(stdout_data, stderr_data)
        if stdout_data:
            service_status = re.compile(r'STATE\s+?:\s+?(\d)').search(stdout_data).group(1)
            if service_status == '4':
                self.setWindowTitle(f'{self.windowTitle()}  服务状态：运行')
                return
            if service_status == '1':
                self.setWindowTitle(f'{self.windowTitle()}  服务状态：停止')
                return
            else:
                self.setWindowTitle(f'{self.windowTitle()}  服务状态：未知')
                return
        else:
            self.setWindowTitle(f'{self.windowTitle()}  服务状态：未知')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    s = QMain()
    s.show()
    sys.exit(app.exec_())


def intensity_energy(Sx1, Sx2, Sx3, F, Fadj): # starting for gsi file

    import numpy as np

    # check for input dimensionality
    if (Sx1.shape[0]>Sx1.shape[1]) or (Sx2.shape[0]>Sx2.shape[1]) or (Sx3.shape[0]>Sx3.shape[1]):
        print('Please ensure the channel dimension is first, followed by sample dimension.')
        return

    Ix = Sx1*Sx2 # x-component
    Iy = Sx1*Sx3 # y-component

    active_intensity = np.sqrt( np.real(Ix)**2 + np.real(Iy)**2 )
    reactive_intensity = np.sqrt( np.imag(Ix)**2 + np.imag(Iy)**2 )

    if len(Fadj): # if we need to adjust for phase drift per freq
        # this is a rough adjustment Aaron suggested for his instruments
        I = np.argmin(np.abs(F - Fadj))
        active_intensity[(I+1):,:] = reactive_intensity[(I+1):,:]

    energy_density = 0.5*( (np.abs(Sx1)**2 ) + np.abs(Sx2)**2 + np.abs(Sx3)**2 ) # pressure autospectrum + velocity autospectrum

    active_ItoE = active_intensity/energy_density
    reactive_ItoE = reactive_intensity/energy_density

    return active_ItoE, reactive_ItoE, active_intensity, reactive_intensity


# -*- coding: utf-8 -*-

from time import time
import numpy as np

import cv2
from sklearn.decomposition import PCA
import matplotlib
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.metrics import mean_squared_error, accuracy_score, f1_score, confusion_matrix, classification_report
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
import os

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
import tensorflow as tf

# taken from gridsearch exercise
def SearchReport(model):

    def GetBestModelCTOR(model, best_params):
        def GetParams(best_params):
            ret_str=""
            for key in sorted(best_params):
                value = best_params[key]
                temp_str = "'" if str(type(value))=="<class 'str'>" else ""
                if len(ret_str)>0:
                    ret_str += ','
                ret_str += f'{key}={temp_str}{value}{temp_str}'
            return ret_str
        try:
            param_str = GetParams(best_params)
            return type(model).__name__ + '(' + param_str + ')'
        except:
            return "N/A(1)"

    print("\nBest model set found on train set:")
    print()
    print(f"\tbest parameters={model.best_params_}")
    print(f"\tbest '{model.scoring}' score={model.best_score_}")
    print(f"\tbest index={model.best_index_}")
    print()
    print(f"Best estimator CTOR:")
    print(f"\t{model.best_estimator_}")
    print()
    try:
        print(f"Grid scores ('{model.scoring}') on development set:")
        means = model.cv_results_['mean_test_score']
        stds  = model.cv_results_['std_test_score']
        i=0
        for mean, std, params in zip(means, stds, model.cv_results_['params']):
            print("\t[%2d]: %0.3f (+/-%0.03f) for %r" % (i, mean, std * 2, params))
            i += 1
    except:
        print("WARNING: the random search do not provide means/stds")

    global currmode
    currmode = "xray"
    assert "f1_micro"==str(model.scoring), f"come on, we need to fix the scoring to be able to compare model-fits! Your scoreing={str(model.scoring)}...remember to add scoring='f1_micro' to the search"
    return f"best: dat={currmode}, score={model.best_score_:0.5f}, model={GetBestModelCTOR(model.estimator,model.best_params_)}", model.best_estimator_

def ClassificationReport(model, X_test, y_test, target_names=None):
    assert X_test.shape[0]==y_test.shape[0]
    print("\nDetailed classification report:")
    print("\tThe model is trained on the full development set.")
    print("\tThe scores are computed on the full evaluation set.")
    print()
    y_true, y_pred = y_test, model.predict(X_test)
    print(classification_report(y_true, y_pred, target_names))
    print()

def FullReport(model, X_test, y_test, t):
    print(f"SEARCH TIME: {t:0.2f} sec")
    beststr, bestmodel = SearchReport(model)
    ClassificationReport(model, X_test, y_test)
    print(f"CTOR for best model: {bestmodel}\n")
    print(f"{beststr}\n")
    return beststr, bestmodel

#%% Load Data and format data

np.random.seed(42)

labels = ['NORMAL', 'PNEUMONIA']
img_size = 150
def load_data(data_dir):
    X = []
    y = []
    for label in labels:
        path = os.path.join(data_dir, label)
        class_num = labels.index(label)
        for img in os.listdir(path):
            try:
                img_arr = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
                resized_arr = cv2.resize(img_arr, (img_size, img_size)) # Reshaping images to preferred size
                X.append(resized_arr) # use X.append(resized_arr.flatten()) for enything else that the CNN
                y.append(class_num)
            except Exception as e:
                print(e)

    return np.array(X), np.array(y)

#%% PCA
def pca(n_components, X):
    # with max wished for n_componets
    pca = PCA(n_components=n_components,svd_solver='randomized',whiten=True)
    pca.fit(X)

    pca.components_.reshape((n_components, img_size, img_size))

    X_new = pca.fit_transform(X)
    recovered = pca.inverse_transform(X_new)

    image = recovered[0].reshape(img_size, img_size)

    plt.figure()
    plt.imshow(image, cmap = matplotlib.cm.binary, interpolation="nearest")

    # max n_components
    pca = PCA(svd_solver='randomized',whiten=True)
    pca.fit(X)

    pca.components_.reshape((245, img_size, img_size)) # remember to change 245 if max n_components change

    X_new = pca.fit_transform(X)
    recovered = pca.inverse_transform(X_new)

    image = recovered[0].reshape(img_size, img_size)

    plt.figure()
    plt.imshow(image, cmap = matplotlib.cm.binary, interpolation="nearest")

    plt.figure()
    plt.plot(np.cumsum(pca.explained_variance_)/np.sum(pca.explained_variance_))
    plt.title('Explained variance - procentdel')
    plt.xlabel('Dimension nummer')

#%% ML models
def train_decision_tree(X, y):
    clf = DecisionTreeClassifier()
    clf.fit(X,y)
    return clf

def train_random_forrest(X, y): #best parameters={'criterion': 'gini', 'n_estimators': 167}

    clf = RandomForestClassifier(n_jobs=-1)

    tuning_parameters = {
        'n_estimators': list(range(100, 200, 1)),
        'criterion': ('gini', 'entropy'),
    }

    CV = 5
    VERBOSE = 0
    grid_tuned = GridSearchCV(clf,
                          tuning_parameters,
                          cv=CV,
                          scoring='f1',
                          verbose=VERBOSE,
                          iid=True)
    grid_tuned.fit(X, y)

    return grid_tuned

def train_cnn(X, y):
    X = tf.expand_dims(X, axis=-1)
    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=(150, 150, 1)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(32, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors
    model.add(Dense(64))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1))
    model.add(Activation('sigmoid'))

    model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

    model.fit(x=X, y=y)
    return model

def train_knn(X, y):
    clf = KNeighborsClassifier()
    tuning_parameters = {
        'n_neighbors': list(range(1, 10, 1)),
        'weights': ('uniform', 'distance'),
        'algorithm': ('ball_tree', 'kd_tree', 'brute')
    }

    CV = 5
    VERBOSE = 0
    grid_tuned = GridSearchCV(clf,
                          tuning_parameters,
                          cv=CV,
                          scoring='f1',
                          verbose=VERBOSE,
                          n_jobs=12,
                          iid=True)
    grid_tuned.fit(X, y)

    return grid_tuned

def train_SVC(X, y):
    clf = SVC()

    tuning_parameters = {
        'C': np.linspace(0.01, 2, num=50),
        'kernel': ('linear', 'poly', 'rbf', 'sigmoid'),
        'degree': list(range(2, 10, 1))
    }

    CV = 5
    VERBOSE = 0
    grid_tuned = GridSearchCV(clf,
                          tuning_parameters,
                          cv=CV,
                          scoring='f1_micro',
                          verbose=VERBOSE,
                          n_jobs=8,
                          iid=True)
    grid_tuned.fit(X, y)

    return grid_tuned

    # clf.fit(X, y)
    # return clf

#%% main
if __name__ == "__main__":
    X_train, y_train = load_data('chest_xray/chest_xray/train')
    X_test, y_test = load_data('chest_xray/chest_xray/test')
    X_val, y_val = load_data('chest_xray/chest_xray/val')

#%%
    shuffle_index = np.random.permutation(5216)
    X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]

#%% Plots example image
    #cv2.imshow("image", X_train[0].reshape(img_size,img_size))

#%%
    #pca(64, X_train)

#%%
    start = time()
    model = train_cnn(X_train, y_train)
    t = time() - start
    X_test = tf.expand_dims(X_test, axis=-1)
    y_pred = model.predict(X_test)
    y_pred = np.rint(y_pred) # CNN gives out a procentage for how confident it is that it detects pheumonia this rounds that of to 1 or 0.
    # MSE = mean_squared_error(y_pred, y_test)
    # print(f'RMSE = {MSE**(1/2)}')
    print(f'F1-score: {f1_score(y_test, y_pred)}')
    print(f'accuracy: {accuracy_score(y_test, y_pred)}')
    print(confusion_matrix(y_test, y_pred))
    #b0, m0 = FullReport(model, X_test, y_test, t) # can and should be used if a grid- or random-seartch is done in the training function.


"""These two are used via decorators to validate the user is allowed to call the endpoint."""

from functools import wraps
from flask import abort, request
from datetime import datetime

from apps.users.models import UsersAccessTokens, UsersAccessMapping, Users
from settings.config import CONFIG

def invalid_token(user_id, access_token):
    """Check that user and user's token is valid."""
    token = UsersAccessTokens.query.filter_by(UserID=user_id).first()
    if token is None:
        return True
    if token.AccessToken != access_token:
        return True
    if token.ExpirationDate <= datetime.now():
        return True
    return False

def user_is_admin(user_id):
    """Check if the user is admin or not."""
    user = Users.query.filter_by(UserID=user_id).first()
    user_map = UsersAccessMapping.query.filter_by(UserID=user_id).first()
    if user is None:
        return False
    if user_map is None:
        return False
    if user_map.UsersAccessLevelID == CONFIG.ADMIN_LEVEL:
        return True
    return False

def user_is_registered_or_more(user_id):
    """Check that user is registered, moderator, or admin."""
    user = Users.query.filter_by(UserID=user_id).first()
    user_map = UsersAccessMapping.query.filter_by(UserID=user_id).first()
    if user is None:
        return False
    if user_map is None:
        return False
    if user_map.UsersAccessLevelID >= CONFIG.REGISTERED_LEVEL:
        return True
    return False

def admin_only(f):
    """When a route has this @admin_only decorator, that endpoint can only be accessed with a valid
    user_id and access_token provided in the request. Anything else will be a 401 Unauthorized."""
    @wraps(f)
    def check_user_level(*args, **kwargs):
        user_id = request.headers.get("User", "")
        access_token = request.headers.get("Authorization", "")

        if user_id and access_token:
            # Check that user is admin
            if user_is_admin(user_id) is False:
                abort(401)
            # And make sure the access token the user provided is still valid for that user
            if invalid_token(user_id, access_token):
                abort(401)
        else:
            abort(401)
        return f(*args, **kwargs)  # pragma: no cover
    return check_user_level

def registered_only(f):
    """When a route decorated with @registered_only is accessed, the user must be at least a valid
    Registered User level, or higher. Anything else will be a 401 Unauthorized."""
    @wraps(f)
    def check_user_level(*args, **kwargs):
        user_id = request.headers.get("User", "")
        access_token = request.headers.get("Authorization", "")

        if user_id and access_token:
            # Check that user is at least registered level. If less than that, respond with 401
            if user_is_registered_or_more(user_id) is False:
                abort(401)
            # And make sure the access token the user provided is still valid for that user
            if invalid_token(user_id, access_token):
                abort(401)
        else:
            abort(401)
        return f(*args, **kwargs)  # pragma: no cover
    return check_user_level

def user_id_or_guest(user_id):
    """Validate the input and return the userID, or the guest userID (= 1)"""
    try:
        valid_id = int(user_id)
    except (ValueError, TypeError):
        valid_id = 1
    if valid_id <= 0:
        valid_id = 1

    return valid_id

def validate_user(headers):
    """Validate the user and return the results."""
    user_id = headers.get("User", "")
    token = headers.get("Authorization", "")
    registered = False

    if user_id:
        valid_user_id = user_id_or_guest(user_id)
        registered = valid_user_id > 1
    else:
        valid_user_id = 1

    is_token_invalid = invalid_token(user_id, token)

    return valid_user_id, registered, is_token_invalid


# -*- coding: utf-8 -*-
# @date：2023/5/18 15:56
# @Author：LiuYiJie
# @file： copy_file
import os
import shutil

class CopyFile:

    def __init__(self, src_path: str = None, dest_path: str = None, exclude_file: list = None):
        self._src_path = src_path
        self._dest_path = dest_path

    # 复制整个文件
    def copy_dir(self):
        shutil.copytree(self._src_path, self._dest_path)

    # 复制单个文件
    def copy_oneFile(self):
        if not os.path.exists(os.path.dirname(self._dest_path)):
            os.makedirs(os.path.dirname(self._dest_path))
        shutil.copyfile(self._src_path, self._dest_path)

    # 复制文件
    def copy_file(self, src, dest):
        # 判断是否是文件夹
        if os.path.isdir(src):
            file_list = os.listdir(src)  # 拿到源文件夹里的所有文件
            # 遍历列表
            for file in file_list:
                # 得到全路径
                src_path = os.path.join(src, file)
                # 如果是文件夹 --> 在目标文件夹下新建文件夹然后复制
                target_path = os.path.join(dest, file)
                if not os.path.exists(os.path.dirname(target_path)):
                    os.makedirs(os.path.dirname(target_path))

                if os.path.isdir(src_path):
                    # 拿到文件夹的名然后在目标文件夹下新建
                    self.copy_file(src_path, target_path)

                else:
                    # 不是文件夹 --> 正常复制
                    dest_path = os.path.join(dest, file)
                    if os.path.exists(dest_path):
                        continue
                    with open(src_path, 'rb') as rstream:
                        contain = rstream.read()

                        print(f'正在复制{src_path}')
                        with open(dest_path, 'wb') as wstream:
                            wstream.write(contain)

if __name__ == '__main__':
    exclude_file = []
    c = CopyFile(src_path=r'E:\任务数据\学科clc\F239 审计.csv', dest_path=r'G:\任务数据\EITest\test.csv', exclude_file=exclude_file)
    # src_path = r'E:\任务数据\EI'
    # dest_path = r'G:\任务数据\EITest'
    # shutil.copytree(src_path, dest_path)
    c.copy_oneFile()
    # copy_file(src_path, dest_path)


cryptMode = input("[Ш]ифр|[Д]ешифр: ").upper()
if cryptMode not in ['Ш','Д']:
 print("Қате: Ш немесе Д Әріпін қолданыңыз!"); raise SystemExit

startMessage = input("АшыҚ мӘтін: ").upper()
try:rotKey = int(input("Қадамды еҢгізіҢіз: "))
except ValueError: print("Қате: тек сандар енгізілуі керек!"); raise SystemExit

def encryptDecrypt(mode, message, key, final = ""):
	for symbol in message:
		if mode == 'Ш':
			final += chr((ord(symbol) + key - 16)%32 + ord('А'))
		else:
			final += chr((ord(symbol) - key - 16)%32 + ord('А'))
	return final

print("Шифр мӘтін:",encryptDecrypt(cryptMode, startMessage, rotKey))


#assignment3
def fact(num:int):      #factorial
    c=1
    fac=1
    while c<num+1:
        fac*=c
        c+=1
    return fac

def FACT_SERIES(a:int,terms:int):       #FACT_SERIES function
    c=2
    ser='1'
    while c<terms+1:
        ser+=', '+str(a**c/fact(c-1))
        c+=1
    print("series is:",ser)
    ser='+'.join(ser.split(","))
    print("sum is:",eval(ser))

def NEW_STR(inp:str):       #NEW_STR function e.g Subhash Bose -> S Bose
    l=inp.split()
    out=''
    for i in range(len(l)-1):
        out+=l[i][0]+'.'
    out+=l[-1]
    print(out)

def main():
    while True:
        choice=input("Enter F/f for FACT_SERIES or N/n for NEW_STR: ")      #user choice

        if choice in "Ff":
            #FACT_SERIES
            p=int(input("Enter parameter a: "))
            t=int(input("Enter no. of terms: "))
            FACT_SERIES(p,t)

        elif choice in "Nn":
            #NEW_STR
            str1=input("Enter string: ")
            NEW_STR(str1)

        else:
            print("Invalid input. Try again")
            continue

        yn=input("Do you want to continue?(y/n): ")
        if yn in "Nn":
            break

if __name__=="__main__":
    main()


import json
import tempfile
from pathlib import Path

from poif.tests import write_image_in_file
from poif.utils import hash_object, hash_string
from poif.versioning.directory import VersionedDirectory

temp_dir = Path(tempfile.mkdtemp())
img_folder = temp_dir / "image"
img_folder.mkdir(exist_ok=True)

img1_path = img_folder / "01.jpg"
img2_path = img_folder / "02.jpg"

write_image_in_file(img1_path)
write_image_in_file(img2_path)

img1_hash = hash_object(img1_path)
img2_hash = hash_object(img2_path)

dir_hash = hash_string(img1_hash + img2_hash)

def test_writing():
    directory = VersionedDirectory(base_dir=temp_dir, data_dir=img_folder)
    vdir_file = directory.write_vdir_to_folder(temp_dir)

    with open(vdir_file, "r") as f:
        vdir_contents = json.load(f)

    assert vdir_contents["data_folder"] == "image"
    assert vdir_contents["tag"] == dir_hash

    mapping_contents = directory.get_parsed()

    assert mapping_contents[img1_hash] == "image/01.jpg"
    assert mapping_contents[img2_hash] == "image/02.jpg"


"Module for importing questions from a tsv file."

import csv
import questions

class ImporterError(Exception):
    def __init__(self, emsg):
        self.emsg = emsg
    def __str__(self):
        return repr(self.emsg)

class Importer(object):
    def __init__(self, f, st):
        self.f = f
        self.st = st
        self.ql = []
        self.errors = []
        self.curOrd = None

    def txtImport(self):
        """Run an import. Returns a string to display to the user containing a
        list of errors in the import."""

        with open(self.f, 'rb') as csvfile:
            try:
                dialect = csv.Sniffer().sniff(csvfile.read(1024))
            except Exception as e:
                if "Could not determine delimiter" in e:
                    return "Could not determine the delimiter used in this " \
                           "file. Please use tab, comma, or semicolon."
                else:
                    raise e
            if dialect.delimiter not in ('\t', ',', ';'):
                return "Invalid delimiter detected. Please use tab, comma, " \
                       "or semicolon."
            csvfile.seek(0)
            r = csv.reader(csvfile, dialect)
            for row in r:
                self.mkQuestion(row)

        return self.errListFormat()

    def mkQuestion(self, row):
        try:
            question, a, b, c, d, e, ca = row
        except ValueError:
            self.errors.append((row[0], "Wrong number of columns for this row."))
            return
        except Exception as e:
            self.errors.append((row[0], e))

        # munge a little
        ca = ca.lower()
        ansList = [i.strip() for i in [a,b,c,d,e] if i]

        try:
            self.ql.append(questions.Question(
                question, ansList, ca, self.st, self.getOrd()))
        except questions.DuplicateError:
            self.errors.append((question, "This question is a duplicate."))
        except questions.QuestionFormatError as e:
            self.errors.append((question, e))

    def getOrd(self):
        if not self.curOrd:
            self.curOrd = questions.findNextOrd(self.st)
        else:
            self.curOrd += 1
        return self.curOrd

    def errListFormat(self):
        """Provide user with a list of problems that occurred during import."""
        errString = ""
        num = 1
        for i in self.errors:
            errString += "\n\n#%i.\nQuestion: %s\nError: %s" % (num, i[0], i[1])
            num += 1
        return errString.strip()


try:
    numerator = int(input("Enter the numerator: "))
    denominator = int(input("Enter the denominator: "))
    fraction = numerator / denominator
except ValueError:
    print("Numerator and denominator must be valid numbers!")
except ZeroDivisionError:
    print("Cannot divide by zero!")
print("Finished.")

# A value error will occur when using decimals
# A ZeroDivisionError occurs when attempting to divide by zero
# By requiring a strict range of inputs, errors such as the zerodivisionerror can be avoided.


import matplotlib.pyplot as plt
import numpy as np
from stl import mesh
import math
import rayCast
import lidarNoise
from mpl_toolkits import mplot3d
from matplotlib import pyplot

def point_cloud(O_B, horizontal_resolution, vertical_resolution, h_range, v_range, sat_mesh, sat_pos, v_rel, omega):
    """

    :param O_B:
    :param h_res:
    :param v_res:
    :param h_range:
    :param v_range:
    :return:
    """
    theta_r = np.deg2rad(np.linspace(-h_range/2, h_range/2, horizontal_resolution)) # horizontal FoV
    phi_r = np.deg2rad(np.linspace(-v_range/2,v_range/2, vertical_resolution)) # vertical FoV

    Theta, Phi = np.meshgrid(theta_r, phi_r)

    # to have rays coming out from the z-axis
    # theta rotates wrt x axis, with theta = 0 on the z-axis
    # phi rotates wrt the y' axis (after theta rotation), with phi = 0 on the y-z plane
    # xr = np.cos(Phi)*np.sin(Theta)
    # yr = -np.sin(Phi)
    # zr = np.cos(Theta)*np.cos(Phi)

    rays_polar = np.array([Theta.ravel(), Phi.ravel()]).T
    theta = rays_polar[:,[0]]
    phi = rays_polar[:,[1]]
    rays = np.hstack([(np.cos(phi)*np.sin(theta)), np.sin(phi), np.cos(theta)*np.cos(phi)])

    locations = rayCast.cast(O_B, sat_mesh, rays)  # Returns an array of points (X, Y, Z), irrelevant ones are labeled Nan

    #figure = pyplot.figure()
    #axes = figure.add_subplot(projection='3d')

    #axes.add_collection3d(mplot3d.art3d.Poly3DCollection(sat_mesh.vectors, alpha=0.3))

    # Locations in a target centered frame
    xp = np.array(locations[:,0])
    yp = np.array(locations[:,1])
    zp = np.array(locations[:,2])

    # Filter out NaN values
    Xp = []
    Yp = []
    Zp = []
    for idx, x in enumerate(xp):
        Xp.append(xp[idx]) if ~np.isnan(xp[idx]) else Xp
        Yp.append(yp[idx]) if ~np.isnan(yp[idx]) else Yp
        Zp.append(zp[idx]) if ~np.isnan(zp[idx]) else Zp
    Xp = np.array(Xp)
    Yp = np.array(Yp)
    Zp = np.array(Zp)
    # Transform to Xs, Ys, Zs distances from LiDAR frame
    Xs = Xp - O_B[0]
    Ys = Yp - O_B[1]
    Zs = Zp - O_B[2]
    useful_rel_locations = np.vstack([Xs,Ys,Zs]).T

    v_los_v = np.zeros(np.shape(useful_rel_locations)) # initialize line of sight velocity (a vector)
    v_los_s = np.zeros(len(useful_rel_locations)) # line of sight speed (array of scalars)
    for i, p in enumerate(useful_rel_locations):
        r = p - sat_pos # debris relative position
        u_los = -(p)/np.linalg.norm(p)
        v_los_s[i] = np.dot(np.cross(omega, r), u_los) + np.dot(v_rel, u_los)
        v_los_v[i] = u_los * v_los_s[i]

    # add noise to lidar scan results
    Xn, Yn, Zn, Vn = lidarNoise.add_noise(Xs,Ys,Zs,v_los_s)
    v_los_vn = v_los_v/v_los_s[:,np.newaxis]*Vn[:,np.newaxis]
    # Transform to target coordinate frame (z is pointing in the direction of target,

    #axes.scatter3D(O_B[0],O_B[1],O_B[2], marker = '+', color = 'black', zorder=20)
    #axes.scatter3D(Xs,Ys,Zs, color = 'red', zorder=20)
    #axes.quiver(Xn, Yn, Zn, v_los_vn[:,0], v_los_vn[:,1], v_los_vn[:,2], length = 0.4, normalize=False)
    #scale = sat_mesh.points.flatten()
    #axes.set_xlim3d(left=-5, right=5)
    #axes.set_ylim3d(bottom=-5, top=5)
    #axes.set_zlim3d(bottom=-2, top=8)
    # axes.auto_scale_xyz(scale, scale, scale)
    #axes.set_xlabel('x')
    #axes.set_ylabel('y')
    #axes.set_zlabel('z')
    # pyplot.show()

    return Xn, Yn, Zn, Vn


# source: http://www.paulvangent.com/2016/04/01/emotion-recognition-with-python-opencv-and-a-face-dataset/
import glob
import shutil
import os

emotions = ["neutral", "anger", "contempt", "disgust", "fear", "happy", "sadness", "surprise"]  # Define emotion order

participants = glob.glob(
    "../ck+/Emotion_labels/Emotion/*/*/*")  # Returns a list of all folders with participant numbers

IMAGE_PATH = '../ck+/extended-cohn-kanade-images/cohn-kanade-images/{}/{}/*'
if not os.path.exists('../sorted_set'):
    os.mkdir('../sorted_set')

for x in participants:
    file = open(x)
    emotionIndex = int(float(file.readline()))
    filePath = x.split('\\')
    folder = filePath[-3]
    folder2 = filePath[-2]

    imagePath = IMAGE_PATH.format(folder, folder2)

    images = glob.glob(imagePath)

    target_path = '../sorted_set/neutral/'
    if not os.path.exists(target_path):
        os.mkdir(target_path)

    shutil.copy(images[0], target_path)

    currentEmotion = emotions[emotionIndex]
    target_path2 = '../sorted_set/{}/'.format(currentEmotion)
    if not os.path.exists(target_path2):
        os.mkdir(target_path2)

    [shutil.copy(i, target_path2) for i in images[-3:]]
    file.close()

resultPath = '../sorted_set/{}/*'
for emotion in emotions:
    emotionPath = resultPath.format(emotion)

    print('{} nums: {}'.format(emotion.ljust(8), len(glob.glob(emotionPath))))


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import os
import subprocess
import sys
from distutils.spawn import find_executable

import mozunit
import pytest

from mozlint import cli

here = os.path.abspath(os.path.dirname(__file__))

@pytest.fixture
def parser():
    return cli.MozlintParser()

@pytest.fixture
def run(parser, lintdir, files):
    def inner(args=None):
        args = args or []
        args.extend(files)
        lintargs = vars(parser.parse_args(args))
        lintargs["root"] = here
        lintargs["config_paths"] = [os.path.join(here, "linters")]
        return cli.run(**lintargs)

    return inner

def test_cli_with_ascii_encoding(run, monkeypatch, capfd):
    cmd = [sys.executable, "runcli.py", "-l=string", "-f=stylish", "files/foobar.js"]
    env = os.environ.copy()
    env["PYTHONPATH"] = os.pathsep.join(sys.path)
    env["PYTHONIOENCODING"] = "ascii"
    proc = subprocess.Popen(
        cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        cwd=here,
        env=env,
        universal_newlines=True,
    )
    out = proc.communicate()[0]
    assert "Traceback" not in out

def test_cli_run_with_fix(run, capfd):
    ret = run(["-f", "json", "--fix", "--linter", "external"])
    out, err = capfd.readouterr()
    assert ret == 0
    assert out.endswith("{}\n")

@pytest.mark.skipif(not find_executable("echo"), reason="No `echo` executable found.")
def test_cli_run_with_edit(run, parser, capfd):
    os.environ["EDITOR"] = "echo"

    ret = run(["-f", "compact", "--edit", "--linter", "external"])
    out, err = capfd.readouterr()
    out = out.splitlines()
    assert ret == 1
    assert out[0].endswith("foobar.js")  # from the `echo` editor
    assert "foobar.js: line 1, col 1, Error" in out[1]
    assert "foobar.js: line 2, col 1, Error" in out[2]
    assert "2 problems" in out[-1]
    assert len(out) == 5

    del os.environ["EDITOR"]
    with pytest.raises(SystemExit):
        parser.parse_args(["--edit"])

def test_cli_run_with_setup(run, capfd):
    # implicitly call setup
    ret = run(["-l", "setup", "-l", "setupfailed", "-l", "setupraised"])
    out, err = capfd.readouterr()
    assert "setup passed" in out
    assert "setup failed" in out
    assert "setup raised" in out
    assert ret == 1

    # explicitly call setup
    ret = run(["-l", "setup", "-l", "setupfailed", "-l", "setupraised", "--setup"])
    out, err = capfd.readouterr()
    assert "setup passed" in out
    assert "setup failed" in out
    assert "setup raised" in out
    assert ret == 1

def test_cli_for_exclude_list(run, monkeypatch, capfd):
    ret = run(["-l", "excludes", "--check-exclude-list"])
    out, err = capfd.readouterr()

    assert "**/foobar.js" in out
    assert (
        "The following list of paths are now green and can be removed from the exclude list:"
        in out
    )

    ret = run(["-l", "excludes_empty", "--check-exclude-list"])
    out, err = capfd.readouterr()

    assert "No path in the exclude list is green." in out
    assert ret == 1

def test_cli_run_with_wrong_linters(run, capfd):

    run(["-l", "external", "-l", "foobar"])
    out, err = capfd.readouterr()

    # Check if it identifes foobar as invalid linter
    assert "A failure occurred in the foobar linter." in out

    # Check for exception message
    assert "Invalid linters given, run again using valid linters or no linters" in out

if __name__ == "__main__":
    mozunit.main()


"""Write a Python program for department library which has N books, write functions for
following:
a) Delete the duplicate entries
b) Display books in ascending order based on cost of books
c) Count number of books with cost more than 500.
d) Copy books in a new list which has cost less than 500.
"""

print(__doc__)

class Book:
    def __init__(self, name, cost):
        self.name = name
        self.cost = cost

book_list = []

def add_book(name, cost):
    book = Book(name, cost)
    book_list.append(book)

add_book("DSA", 500)
add_book("CG", 400)
add_book("DELD", 300)
add_book("OOP", 700)
add_book("DM", 590)
add_book("DSA", 500)
add_book("DELD", 300)
add_book("OOP", 700)

for book in book_list:
    print(book.name, book.cost)

def delete_duplicate(book_list):
    does_copy_exists = False
    unique_book_list = []
    for book in book_list:
        for u_book in unique_book_list:
            if u_book.name == book.name and u_book.cost == book.cost:
                does_copy_exists = True
        if not does_copy_exists:
            unique_book_list.append(book)
    return unique_book_list

book_list = delete_duplicate(book_list)

print("\na.")
for book in book_list:
    print(book.name, book.cost)

def arrange_books(book_list):
    for j in range(len(book_list) - 1):
        min_value_index = j
        for i in range(j, len(book_list)):
            if book_list[min_value_index].cost > book_list[i].cost:
                min_value_index = i
        book_list[j], book_list[min_value_index] = (
            book_list[min_value_index],
            book_list[j],
        )

arrange_books(book_list)
print("\nb.")
for book in book_list:
    print(book.name, book.cost)

def count_book_filter(cost=500):
    cnt = 0
    for book in book_list:
        if book.cost >= cost:
            cnt += 1  # cnt = cnt+1
    return cnt

print("\nc.", count_book_filter())

def seperate_book_filter(cost=500):
    less_cost_book = []
    for book in book_list:
        if book.cost < cost:
            less_cost_book.append(book)
    return less_cost_book

print("\nd.")
for book in seperate_book_filter():
    print(book.name, book.cost)


"""
Classes used by Damage page.
"""

from tkinter import (StringVar, IntVar, OptionMenu, Button, ttk,
                     Checkbutton, VERTICAL, N, W)

from magus_kalkulator.sebzes import return_penalty
from magus_kalkulator.random_body import pick_sub_parts
from magus_kalkulator.validate import validate_integer, FieldValidationError
from magus_kalkulator.interface_elements import (CharacterValueField,
                                                 organize_rows_to_left,
                                                 ChooseCharacterFrame,
                                                 on_all_children)

from magus_kalkulator import magus_constants as mgc

DAMAGE_PAGE_COLUMN = 0

DAMAGE_BUTTON_TEXT = 'Start'
SELECT_CHARACTER = 'Megtamadott'
SELECT_WEAPON = 'Tamado fegyver'
DAMAGE_TEXT = 'Sebzes'
TULUTES_TEXT = 'Tulutes'
ATUTES_TEXT = 'Atutes'
HIT_LABEL = 'Talalat helye'
FROM_BACK_LABEL = 'Hatulrol'
ANYWHERE = 'Barhol'
MAIN_PART_LABEL = 'Fo testresz'
SUB_PART_LABEL = 'Al testresz'

MSG_TAB = 4

# Types of attacking weapons. Used when calculating the damage
WEAPON_TYPES = [mgc.THRUST, mgc.SLASH, mgc.BLUDGEON, mgc.BITE, mgc.CLAW]

ATUTES_VALUES = [0, 1, 2, 3, 4, 5]

EP_LOSS_KEY = 'ep_loss'
FP_LOSS_KEY = 'fp_loss'
HIT_KEY = 'hit_target'
PENALTY_KEY = 'penalty'

KEY_TEXT_DICT = {
    EP_LOSS_KEY: 'EP veszteseg',
    FP_LOSS_KEY: 'FP veszteseg',
    HIT_KEY: 'Talalati hely',
    PENALTY_KEY: 'Hatrany'
}

def remove_duplicates(a_list):
    """
    Removes all duplicates from a list, making sure
    each elem is unique.
    """
    for elem in a_list:
        while a_list.count(elem) > 1:
            a_list.remove(elem)

    return a_list

def get_unique_body_parts(body_parts_list):
    """
    Used in removing duplicates from a body parts
    list.
    """
    [main_part, sub_parts_list] = body_parts_list
    unique_sub_parts_list = remove_duplicates(sub_parts_list)
    return [main_part, unique_sub_parts_list]

UNIQUE_HEAD_LIST = get_unique_body_parts(mgc.HEAD_LIST)
UNIQUE_TORSO_LIST = get_unique_body_parts(mgc.TORSO_LIST)
UNIQUE_TORSO_LIST_BEHIND = mgc.TORSO_LIST_BEHIND
UNIQUE_RARM_LIST = get_unique_body_parts(mgc.RARM_LIST)
UNIQUE_LARM_LIST = get_unique_body_parts(mgc.LARM_LIST)
UNIQUE_RLEG_LIST = get_unique_body_parts(mgc.RLEG_LIST)
UNIQUE_LLEG_LIST = get_unique_body_parts(mgc.LLEG_LIST)

BODY_LISTS_DICT = {
    mgc.HEAD: UNIQUE_HEAD_LIST,
    mgc.TORSO: UNIQUE_TORSO_LIST,
    mgc.RARM: UNIQUE_RARM_LIST,
    mgc.LARM: UNIQUE_LARM_LIST,
    mgc.RLEG: UNIQUE_RLEG_LIST,
    mgc.LLEG: UNIQUE_LLEG_LIST
}

BODY_LISTS_DICT_BEHIND = {
    mgc.HEAD: UNIQUE_HEAD_LIST,
    mgc.TORSO: UNIQUE_TORSO_LIST_BEHIND,
    mgc.RARM: UNIQUE_RARM_LIST,
    mgc.LARM: UNIQUE_LARM_LIST,
    mgc.RLEG: UNIQUE_RLEG_LIST,
    mgc.LLEG: UNIQUE_LLEG_LIST
}

def format_list_msg(list_value):
    """
    Formats a key/value pair where the value
    is a list.

    Each list element is placed on a new line, they are
    all indented by a specified tab.
    """
    separator = '\n'
    for _i in range(0, MSG_TAB):
        separator += ' '

    return '{}{}'.format(separator, separator.join(list_value))

def format_damage_msg(penalty_dict):
    """
    Formats message returned on
    penalty calculation.
    """
    msg = ''

    for key, value in sorted(penalty_dict.items()):

        # Replace actual key with key text.
        key = KEY_TEXT_DICT[key]

        if isinstance(value, list):
            value = format_list_msg(value)

        msg += '{}: {}\n'.format(key, value)

    return msg.strip()

class SebzesPage(ttk.Frame):
    """
    Main tab for calculating damage and penalties.
    """
    def __init__(self, master_tabs, characters, messages, width):
        """
        Initializes damage tab.
        """
        ttk.Frame.__init__(self, master_tabs, width=width)
        CharacterPanel(self, characters, messages,
                       width=width, orient=VERTICAL).grid()

class CharacterPanel(ttk.PanedWindow):
    """
    Main panel of damage page.
    """
    def __init__(self, page, characters, messages, **kwargs):
        """
        Initialise main panel.
        """
        ttk.PanedWindow.__init__(self, page, **kwargs)
        self.messages = messages
        self.characters = characters

        sebzes_button = Button(self, text=DAMAGE_BUTTON_TEXT)
        sebzes_button.bind('<Button-1>', self.write_results)

        self.choose_frame = ChooseCharacterFrame(self, characters)
        self.weapon_frame = WeaponTypeFrame(self)
        self.damage_frame = DamageFrame(self)
        self.piercing_frame = PiercingFrame(self, ATUTES_VALUES)
        self.body_parts_frame = ChooseBodyPartFrame(self)

        organize_rows_to_left([self.choose_frame, self.weapon_frame,
                               self.damage_frame, self.piercing_frame,
                               self.body_parts_frame, sebzes_button], 0)

    def reset_panel(self):
        """
        Resets all child widgets of the panel.
        """
        on_all_children('reset_frame', self)

    def write_results(self, _event):
        """
        Gets result based on input fields/values and writes
        result to message panel.
        """
        success, attacked = self.choose_frame.get_selected()

        if not success:
            self.messages.write_message(attacked)
            return

        character = self.characters.get_character(attacked)

        success, damage = self.damage_frame.get_damage()

        if not success:
            self.messages.write_message(damage)
            return

        attacking_weapon = self.weapon_frame.get_weapon()
        body_parts_list = self.body_parts_frame.get_targeted()
        is_critical = self.damage_frame.is_critical()
        armour_piercing = self.piercing_frame.get_piercing()
        is_zero_zero = self.damage_frame.is_zero_zero()

        result = return_penalty(character['sfe'], damage, body_parts_list,
                                character['max_ep'], attacking_weapon,
                                tulutes=is_critical, atutes=armour_piercing,
                                is_zero_zero=is_zero_zero)

        msg = format_damage_msg(result)
        self.messages.write_message(msg)
        self.reset_panel()

class WeaponTypeFrame(ttk.LabelFrame):
    """
    Frame for weapon-type selection drop-down.
    """
    def __init__(self, character_panel):
        """
        Initialises weapon-type frame.
        """
        ttk.LabelFrame.__init__(self, character_panel, text=SELECT_WEAPON)
        self.selected_weapon = StringVar()
        self.selected_weapon.set(WEAPON_TYPES[0])
        self.weapon_menu = OptionMenu(self, self.selected_weapon,
                                      *WEAPON_TYPES)
        self.weapon_menu.grid()

    def get_weapon(self):
        """
        Returns selected weapon.
        """
        return self.selected_weapon.get()

    def reset_frame(self):
        """
        Resets all child widgets of the frame.
        """
        self.selected_weapon.set(WEAPON_TYPES[0])

class DamageFrame(ttk.LabelFrame):
    """
    Frame comprising damage entry field.
    """
    def __init__(self, character_panel):
        """
        Initialises frame.
        """
        ttk.LabelFrame.__init__(self, character_panel, text=DAMAGE_TEXT)
        self.damage = CharacterValueField(self, validate_integer)

        self.critical_state = IntVar()
        self.critical_state.set(0)
        self.tulutes = Checkbutton(self, text=TULUTES_TEXT,
                                   variable=self.critical_state)

        self.zero_zero_state = IntVar()
        self.zero_zero_state.set(0)
        self.zero_zero = Checkbutton(self, text='00',
                                     variable=self.zero_zero_state)

        self.damage.grid(row=0, column=0)
        self.tulutes.grid(row=0, column=1)
        self.zero_zero.grid(row=0, column=2)

    def reset_frame(self):
        """
        Resets all child widgets of the frame.
        """
        self.damage.reset_fld()
        self.critical_state.set(0)
        self.zero_zero_state.set(0)

    def get_damage(self):
        """
        Tries to return value of entry field. Returns
        an error message if the value of the field
        is invalid.
        """
        try:
            damage = self.damage.get_validated()
            return True, damage

        except FieldValidationError as error:
            return False, error.message

    def is_critical(self):
        """
        Checks whether the critical tick-box is checked.
        """
        return self.critical_state.get()

    def is_zero_zero(self):
        """
        Checks whether the 00 tickbox is checked.
        """
        return self.zero_zero_state.get()

class PiercingFrame(ttk.LabelFrame):
    """
    Frame comprising the armour-piercing value drop-down.
    """
    def __init__(self, character_panel, piercing_values):
        """
        Initialises frame.
        """
        ttk.LabelFrame.__init__(self, character_panel, text=ATUTES_TEXT)
        self.piercing = IntVar()
        self.piercing_values = piercing_values
        self.piercing.set(self.piercing_values[0])
        self.piercing_menu = OptionMenu(self, self.piercing, *piercing_values)
        self.piercing_menu.grid()

    def get_piercing(self):
        """
        Retrieves value of AP drop-down.
        """
        return self.piercing.get()

    def reset_frame(self):
        """
        Resets the piercing value to 0.
        """
        self.piercing.set(self.piercing_values[0])

class ChooseBodyPartFrame(ttk.LabelFrame):
    """
    Master frame for body selection drop-downs.
    """
    def __init__(self, character_panel):
        """
        Initialises frame.
        """
        ttk.LabelFrame.__init__(self, character_panel, text=HIT_LABEL)

        self.main_body_frame = ChooseMainBodyPartFrame(self)
        self.behind_state = IntVar()
        self.behind_state.set(0)
        self.from_behind_box = Checkbutton(self, text=FROM_BACK_LABEL,
                                           variable=self.behind_state,
                                           command=self.set_state)

        self.from_behind_box.grid(row=0, column=0, sticky=(N, W))

        self.main_body_frame.grid(row=1, column=0)
        self.sub_body_frame = ChooseSubBodyPartFrame(self,
                                                     self.main_body_frame)
        self.sub_body_frame.grid(row=1, column=1)

    def get_parts(self):
        """
        Retrieves the selected main and sub-body parts, if any.
        """
        main_part = self.main_body_frame.main_body_part.get()

        if main_part == ANYWHERE:
            return None, None

        sub_part = self.sub_body_frame.selected_sub_part

        if not sub_part:
            return main_part, None

        return main_part, sub_part

    def set_state(self, *_args):
        """
        Set the state based on tick-box being selected or not.
        Also, reset main body part drop-down as any selected value
        can become invalid once the attack comes from behind not from
        the front or vice versa.
        """
        self.main_body_frame.reset_frame()

    def is_from_behind(self):
        """
        Gets the state of the from-behind tick-box.
        """
        return self.behind_state.get()

    def get_targeted(self):
        """
        Either returns the selected body parts - if any -
        or selects a random set of body parts.

        Also takes into account whether the attack happens
        from behind.
        """
        is_from_behind = self.is_from_behind()
        main_part, sub_part = self.get_parts()

        return pick_sub_parts(from_behind=is_from_behind,
                              main_part=main_part,
                              sub_part=sub_part)

    def reset_frame(self):
        """
        Resets the child widgets of the element and
        also sets the from behind checkbox to False.
        """
        self.behind_state.set(0)
        on_all_children('reset_frame', self)

class ChooseMainBodyPartFrame(ttk.LabelFrame):
    """
    Main body-part drop-down frame.
    """
    def __init__(self, body_frame):
        """
        Initialises frame.
        """
        ttk.LabelFrame.__init__(self, body_frame, text=MAIN_PART_LABEL)
        self.main_body_part = StringVar()
        self.main_body_part.set(ANYWHERE)
        self.main_body_parts = OptionMenu(self,
                                          self.main_body_part,
                                          *[ANYWHERE, mgc.HEAD, mgc.TORSO,
                                            mgc.RARM, mgc.LARM, mgc.RLEG,
                                            mgc.LLEG])
        self.main_body_parts.grid()

    def reset_frame(self):
        """
        Sets the main body part selection drop-down to
        anywhere, triggering the same change in the sub drop-down too.
        """
        self.main_body_part.set(ANYWHERE)

class ChooseSubBodyPartFrame(ttk.LabelFrame):
    """
    Sub body-part frame.
    """
    def __init__(self, body_frame, main_body_frame):
        """
        Initialise sub body part frame.
        """
        ttk.LabelFrame.__init__(self, body_frame, text=SUB_PART_LABEL)
        self.body_frame = body_frame
        self.selected_sub_parts = None
        self.selected_sub_part = None
        self.main_body_frame = main_body_frame
        self.main_body_part = main_body_frame.main_body_part
        self.main_body_part.trace('w', self._follow_main_bodypart)
        self.sub_body_part = StringVar()
        self.sub_body_part.set(ANYWHERE)
        self.sub_body_part.trace('w', self._follow_sub_part)
        self.sub_body_parts = OptionMenu(self,
                                         self.sub_body_part,
                                         *[ANYWHERE])
        self.sub_body_parts.grid()

    def _follow_sub_part(self, *_args):
        """
        Traces the sub body part selected. Since the
        damage calculation expects the sub body part to
        be a list of two, this function selects the
        corresponding pair based on the selected sub part.

        E.g. if Breastbone is selected, the pair will be
        [Chest, Breastbone].
        """
        selected_sub_part = self.sub_body_part.get()

        if selected_sub_part and selected_sub_part != ANYWHERE:
            self.selected_sub_part = [x for x in self.selected_sub_parts
                                      if selected_sub_part in x][0]
        else:
            self.selected_sub_part = None

    def _follow_main_bodypart(self, *_args):
        """
        Sub body parts dropdown follows changes in
        the main body part dropwdown.
        """
        # Get currently selected value of main dropdown.
        selected_main_body_part = self.main_body_part.get()

        # See if from behind box is ticked
        is_from_behind = self.body_frame.is_from_behind()

        if is_from_behind:
            body_list_map = BODY_LISTS_DICT_BEHIND
        else:
            body_list_map = BODY_LISTS_DICT

        # Calculate options for sub part dropdown if a main part is selected.
        if selected_main_body_part != ANYWHERE:
            [_main_part, sub_parts] = body_list_map[selected_main_body_part]

            # Sub parts are a list of lists with two elements
            # E.g. [['Mellkas', 'sziv'],..]. Save choices to state
            self.selected_sub_parts = sub_parts

            # Only use the second element of sub body part for options
            choices = [ANYWHERE] + [x[1] for x in sub_parts]

        # If no main body part is selected, sub parts can only be ANYWHERE.
        else:
            self.selected_sub_parts = None
            choices = [ANYWHERE]

        # Update drop-down menu with choices.
        self._update(choices)

    def _update(self, list_of_choices):
        """
        Update dropdown with supported choices.
        """
        menu = self.sub_body_parts.children['menu']
        menu.delete(0, 'end')

        for value in list_of_choices:
            menu.add_command(label=value,
                             command=lambda v=value: self.sub_body_part.set(v))

        # Set dropdown to first element in list. (ANYWHERE)
        self.sub_body_part.set(list_of_choices[0])


def bubble_sort(lista):
    '''função que implementa o algoritmo de ordenação bubble sort '''

    while True:
        trocou = False
        for i in range(len(lista)-1):
            if lista[i+1] < lista[i]:
                lista[i+1], lista[i] = lista[i], lista[i+1]
                trocou=True
        if not trocou:
            break

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

from data.emp10mil import empresas10
from data.emp25mil import empresas25
from data.emp50mil import empresas50
from data.emp100mil import empresas100
from time import time
import tracemalloc

#10mil
ini=time()
tracemalloc.start()

nomes_ord = bubble_sort(empresas10)

mem_atual, mem_pico = tracemalloc.get_traced_memory()

fim=time()

#print(nomes_ord)
print("10 mil")
print(f"Tempo: {fim-ini}")
print(f'pico de memoria: {mem_pico / 1024 / 1024}mb')

tracemalloc.stop()

#25mil
ini=time()
tracemalloc.start()

nomes_ord = bubble_sort(empresas25)

mem_atual, mem_pico = tracemalloc.get_traced_memory()

fim=time()

#print(nomes_ord)
print("25 mil")
print(f"Tempo: {fim-ini}")
print(f'pico de memoria: {mem_pico / 1024 / 1024}mb')

tracemalloc.stop()

#50mil
ini=time()
tracemalloc.start()

nomes_ord = bubble_sort(empresas50)

mem_atual, mem_pico = tracemalloc.get_traced_memory()

fim=time()

#print(nomes_ord)
print("50 mil")
print(f"Tempo: {fim-ini}")
print(f'pico de memoria: {mem_pico / 1024 / 1024}mb')

tracemalloc.stop()

#100mil
ini=time()
tracemalloc.start()

nomes_ord = bubble_sort(empresas100)

mem_atual, mem_pico = tracemalloc.get_traced_memory()

fim=time()

#print(nomes_ord)
print("100 mil")
print(f"Tempo: {fim-ini}")
print(f'pico de memoria: {mem_pico / 1024 / 1024}mb')

tracemalloc.stop()


#!/usr/bin/python
import boto3
import argparse
import yaml
import pprint

pp = pprint

# client = boto3.client('cloudformation', region_name='us-east-1')
# response = client.create_stack(
#     StackName='create-s3-bucket',
#     TemplateURL='https://s3.amazonaws.com/my-jpendyala-bucket/create-s3-bucket.yml',
# )
# print (response)

def cp_cf_template(stack_name, bucket_name):

    s3 = boto3.resource('s3', region_name = 'us-east-1')
    s3.meta.client.upload_file('/var/lib/jenkins/workspace/create-update-stack-job/AWSTesting/CloudFormation/' + stack_name + '.yml', bucket_name, stack_name + '.yml')

def mystack_create(stack_name, bucket_name):

    response = cf_client.create_stack(
        StackName=stack_name,
        TemplateURL='https://s3.amazonaws.com/' + bucket_name + '/' + stack_name + '.yml',
        OnFailure='ROLLBACK'
    )
    print (response)

def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument('--stack_name')
    parser.add_argument('--bucket_name')
    #parser.add_argument('--url')
    args = parser.parse_args()
    return args

def main(args):
    cp_cftemplate = cp_cf_template(args.stack_name, args.bucket_name)
    crt_stack = mystack_create(args.stack_name, args.bucket_name)

if __name__== "__main__":
    PARSED_ARGS = parse_arguments()
    #region_name = PARSED_ARGS.region_name
    cf_client = boto3.client('cloudformation', region_name='us-east-1')
    #s3_client = boto3.client('s3', region_name='us-east-1')
    main(PARSED_ARGS)

# python createupdatestack.py --region_name 'us-east-1' --stack_name create-s3-bucket --url 'https://s3.amazonaws.com/my-jpendyala-bucket/create-s3-bucket.yml'

#
# import yaml
# with open('config.yaml', 'r') as f:
#     doc = yaml.load(f)


import unittest
import uuid
import os
import time

from studio.pubsub_queue import PubsubQueue
from studio.sqs_queue import SQSQueue
from studio.local_queue import LocalQueue, get_local_queue_lock

from studio.util import has_aws_credentials
from studio import logs

class DummyContextManager(object):
    def __init__(self):
        pass

    def __enter__(self):
        return self

    def __exit__(self, *args):
        pass

class QueueTest(object):
    def get_queue(self):
        pass

    def test_simple(self):
        with self.get_lock():
            q = self.get_queue()
            q.clean()
            data = str(uuid.uuid4())

            q.enqueue(data)
            recv_data = q.dequeue(timeout=self.get_timeout())

            self.assertEquals(data, recv_data)
            self.assertTrue(q.dequeue() is None)

    def test_clean(self):
        with self.get_lock():
            q = self.get_queue()
            q.clean()
            data = str(uuid.uuid4())

            q.enqueue(data)
            q.clean(timeout=self.get_timeout())

            self.assertTrue(q.dequeue(timeout=self.get_timeout()) is None)

    def get_lock(self):
        return DummyContextManager()

    def get_timeout(self):
        return 0

class LocalQueueTest(QueueTest, unittest.TestCase):
    def get_queue(self):
        return LocalQueue()

    def get_lock(self):
        return get_local_queue_lock()

class DistributedQueueTest(QueueTest):

    def test_unacknowledged(self):
        q = self.get_queue()
        q.clean()
        data1 = str(uuid.uuid4())
        data2 = str(uuid.uuid4())

        q.enqueue(data1)
        q.enqueue(data2)

        recv1 = q.dequeue(timeout=self.get_timeout())
        time.sleep(15)
        recv2 = q.dequeue(timeout=self.get_timeout())

        self.assertTrue(data1 == recv1 or data2 == recv1)
        self.assertTrue(data1 == recv2 or data2 == recv2)
        self.assertFalse(recv1 == recv2)

        self.assertTrue(q.dequeue() is None)

    def test_two_receivers(self):
        logger = logs.getLogger('test_two_receivers')
        logger.setLevel(10)
        q1 = self.get_queue()
        q1.clean()

        q2 = self.get_queue(q1.get_name())

        data1 = str(uuid.uuid4())
        data2 = str(uuid.uuid4())

        logger.debug('data1 = ' + data1)
        logger.debug('data2 = ' + data2)

        q1.enqueue(data1)

        self.assertEquals(data1, q2.dequeue(timeout=self.get_timeout()))

        q1.enqueue(data1)
        q1.enqueue(data2)

        recv1 = q1.dequeue(timeout=self.get_timeout())
        recv2 = q2.dequeue(timeout=self.get_timeout())

        logger.debug('recv1 = ' + recv1)
        logger.debug('recv2 = ' + recv2)

        self.assertTrue(data1 == recv1 or data2 == recv1)
        self.assertTrue(data1 == recv2 or data2 == recv2)
        self.assertFalse(recv1 == recv2)

        self.assertTrue(q1.dequeue() is None)
        self.assertTrue(q2.dequeue() is None)

    def test_hold(self):
        q = self.get_queue()
        q.clean()

        data = str(uuid.uuid4())
        q.enqueue(data)

        msg, ack_id = q.dequeue(acknowledge=False, timeout=60)
        q.hold(ack_id, 1.5)

        self.assertTrue(q.dequeue(timeout=10) is None)

        msg = q.dequeue(timeout=self.get_timeout())
        self.assertEquals(data, msg)

    def get_timeout(self):
        return 120

@unittest.skipIf(
    'GOOGLE_APPLICATION_CREDENTIALS' not in
    os.environ.keys(),
    'GOOGLE_APPLICATION_CREDENTIALS environment ' +
    'variable not set, won'' be able to use google ' +
    'PubSub')
class PubSubQueueTest(DistributedQueueTest, unittest.TestCase):
    _multiprocess_shared_ = True

    def get_queue(self, name=None):
        name = 'pubsub_queue_test' + str(uuid.uuid4()) if not name else name
        print(name)
        return PubsubQueue(name)

@unittest.skipIf(
    not has_aws_credentials(),
    "AWS credentials is not present, cannot use SQSQueue")
class SQSQueueTest(DistributedQueueTest, unittest.TestCase):
    _multiprocess_shared_ = True

    def get_queue(self, name=None):
        return SQSQueue(
            'sqs_queue_test_' + str(uuid.uuid4()) if not name else name)

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