"""

Tests for Randomized Reconstruction Commands

"""
import unittest
import requests
import sys
import os
import importlib
from pathlib import Path
import json

# Add the client folder to sys.path
CLIENT_DIR = os.path.join(os.path.dirname(__file__), "..", "client")
if CLIENT_DIR not in sys.path:
    sys.path.append(CLIENT_DIR)

from fusion360gym_client import Fusion360GymClient

HOST_NAME = "127.0.0.1"
PORT_NUMBER = 8080

class TestFusion360GymRandomizedReconstruction(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.client = Fusion360GymClient(f"http://{HOST_NAME}:{PORT_NUMBER}")

        current_dir = Path(__file__).parent
        test_config_file = current_dir / "test_config.json"
        if not test_config_file.exists():
            print("Error: test_config.json file not found in the test directory")

        with open(test_config_file, encoding="utf8") as f:
            test_config = json.load(f)
        dataset_dir = Path(test_config["dataset_dir"])
        if not dataset_dir.exists():
            print("Error: dataset_dir does not exist")

        cls.data_dir = dataset_dir
        cls.void_data_dir = dataset_dir.parent / "void"
        cls.split_file = dataset_dir.parent / "train_test.json"
        cls.void_split_file = dataset_dir.parent / "void.json"
        cls.distributions_json = dataset_dir.parent / "d7_distributions.json"
        cls.distributions_training_only_json = dataset_dir.parent / "d7_training_distributions.json"

    def test_sample_design(self):
        # Sample the whole dataset
        r = self.client.sample_design(self.data_dir, filter=False)
        # Sample the training data
        r = self.client.sample_design(self.data_dir, filter=True, split_file=self.split_file)

    def test_sample_design_invalid_data_dir(self):
        # Sample from a non-existent directory
        r = self.client.sample_design(self.void_data_dir, filter=False)
        # Sample from a non-existent directory with the split file
        r = self.client.sample_design(self.void_data_dir, filter=True, split_file=self.split_file)
        # Sample from a non-existent string
        r = self.client.sample_design("random_data_dir", filter=False)

    def test_sample_design_invalid_split_file(self):
        # the split file is void
        r = self.client.sample_design(self.data_dir, filter=True, split_file=self.void_split_file)

    def test_get_distributions_from_dataset(self):
        import json
        # distributions of the whole dataset
        r = self.client.get_distributions_from_dataset(self.data_dir, filter=False)
        # with open('d7_distributions.json', 'w') as outfile:
        #     json.dump(r, outfile)
        # distributions of the training dataset
        r = self.client.get_distributions_from_dataset(self.data_dir, filter=True, split_file=self.split_file)
        # with open('d7_training_distributions.json', 'w') as outfile:
        #     json.dump(r, outfile)

    def test_get_distributions_from_json(self):
        # distributions of the whole dataset
        r = self.client.get_distributions_from_json(self.distributions_json)
        # distributions of the training dataset
        r = self.client.get_distributions_from_json(self.distributions_training_only_json)
        # invalid input file
        r = self.client.get_distributions_from_json("void")

    def test_distribution_sampling(self):
        # test invalid distributions
        distributions = {"invalid": "testing"}
        r = self.client.distribution_sampling(distributions)
        # sample all parameters
        distributions = self.client.get_distributions_from_json(self.distributions_training_only_json)
        r = self.client.distribution_sampling(distributions)
        # test invalid parameters
        r = self.client.distribution_sampling(distributions, ["invalid"])
        # sample a list of selected parameters
        r = self.client.distribution_sampling(distributions, ["num_faces", "num_bodies"])

    def test_sample_sketch(self):
        json_data, _ = self.client.sample_design(self.data_dir, filter=True, split_file=self.split_file)
        # test invlid sampling type
        r = self.client.sample_sketch(json_data, "invalid")
        # random sampling
        r = self.client.sample_sketch(json_data, sampling_type = "random")
        # deterministic sampling
        r = self.client.sample_sketch(json_data, sampling_type = "deterministic")
        # distributive sampling
        distributions = self.client.get_distributions_from_json(self.distributions_training_only_json)
        r = self.client.sample_sketch(json_data, sampling_type = "distributive", area_distribution=distributions["sketch_areas"])
        # test invalid area distribution
        r = self.client.sample_sketch(json_data, sampling_type = "distributive", area_distribution=["invalid"])

    def test_sample_profiles(self):
        json_data, _ = self.client.sample_design(self.data_dir, filter=True, split_file=self.split_file)
        sketch_data = self.client.sample_sketch(json_data, sampling_type = "random")
        # test invalid sketch data
        r = self.client.sample_profiles({"data":"invalid"}, max_number_profiles = 1, sampling_type = "random")
        # test invalid max number of profiles
        r = self.client.sample_profiles(sketch_data, max_number_profiles = -1, sampling_type = "random")
        # random sampling
        r = self.client.sample_profiles(sketch_data, max_number_profiles = 2, sampling_type = "random")
        # deterministic sampling
        r = self.client.sample_profiles(sketch_data, max_number_profiles = 2, sampling_type = "deterministic")
        # distributive sampling
        distributions = self.client.get_distributions_from_json(self.distributions_training_only_json)
        r = self.client.sample_sketch(json_data, sampling_type = "distributive", area_distribution=distributions["profile_areas"])
        # test invalid area distribution
        r = self.client.sample_sketch(json_data, sampling_type = "distributive", area_distribution=["invalid"])

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


#!/usr/bin/python3
"""Use reddit api to get info about subredit subscribers"""

def number_of_subscribers(subreddit):
    """Return number of subscribers in subreddit given as argument"""
    import requests

    url = 'https://www.reddit.com/r/{}/about.json'.format(subreddit)
    headers = {'user-agent': 'andy'}
    res = requests.get(url, headers=headers, allow_redirects=False)

    if res.status_code != 200:
        return (0)
    else:
        return (res.json()['data']['subscribers'])


#https://towardsdatascience.com/how-to-perform-lasso-and-ridge-regression-in-python-3b3b75541ad8
import numpy as np
import pandas as pd

#we only have three advertising mediums, and sales is our target variable.
DATAPATH = 'Advertising.csv'
data = pd.read_csv(DATAPATH)
print(data.head())
data.drop(['Unnamed: 0'], axis=1, inplace=True) #remove first column which have the record number

#Least square regression

from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LinearRegression

Xs = data.drop(['sales'], axis=1)
y = data['sales'].values.reshape(-1,1)

lin_reg = LinearRegression()

MSEs = cross_val_score(lin_reg, Xs, y, scoring='neg_mean_squared_error', cv=5)

mean_MSE = np.mean(MSEs)

print("Least square MSE  ",mean_MSE)

#Lasso regression
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import Lasso

lasso = Lasso()

parameters = {'alpha': [1e-15, 1e-10, 1e-8, 1e-4, 1e-3,1e-2, 1, 5, 10, 20]}

#GridSearchCV. This will allow us to automatically perform 5-fold cross-validation
# with a range of different regularization parameters in order to find the optimal value of alpha.

lasso_regressor = GridSearchCV(lasso, parameters, scoring='neg_mean_squared_error', cv = 5)

lasso_regressor.fit(Xs, y)

print("Lasso best alpth value ",lasso_regressor.best_params_)

print("Lasso MSE  score ",lasso_regressor.best_score_) #MSE


# This is mostly lifted from django-storages' sftp backend: Their license:
#
# SFTP storage backend for Django.
# Author: Brent Tubbs <brent.tubbs@gmail.com>
# License: MIT
#
# Modeled on the FTP storage by Rafal Jonca <jonca.rafal@gmail.com>
from __future__ import print_function
try:
    import ssh
except ImportError:
    import paramiko as ssh

import os
import posixpath
import warnings

from django.conf import settings
from django.core.files.base import File
try:
    from io import StringIO
except ImportError:
    # Python 2 fallbacks
    from cStringIO import StringIO

from localdevstorage.base import BaseStorage

class SftpStorage(BaseStorage):
    def __init__(self, location=None, base_url=None, user=None, host=None, root_path=None):
        warnings.warn(
            'The SFTP backend is unsupported and untested. '
            'Usage is not recommended!'
        )
        self._host = host or settings.LOCALDEVSTORAGE_SFTP_HOST
        self._root_path = root_path or settings.LOCALDEVSTORAGE_SFTP_ROOT_PATH

        # if present, settings.SFTP_STORAGE_PARAMS should be a dict with params
        # matching the keyword arguments to paramiko.SSHClient().connect().  So
        # you can put username/password there.  Or you can omit all that if
        # you're using keys.
        self._params = getattr(settings, 'SFTP_STORAGE_PARAMS', {})
        self._params['username'] = user or settings.LOCALDEVSTORAGE_SFTP_USER

        # for now it's all posix paths.  Maybe someday we'll support figuring
        # out if the remote host is windows.
        self._pathmod = posixpath
        super(SftpStorage, self).__init__(location, base_url)

    def _connect(self):
        self._ssh = ssh.SSHClient()

        # automatically add host keys from current user.
        self._ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))

        # and automatically add new host keys for hosts we haven't seen before.
        self._ssh.set_missing_host_key_policy(ssh.AutoAddPolicy())

        try:
            self._ssh.connect(self._host, **self._params)
        except ssh.AuthenticationException as e:
            raise
        except Exception as e:
            print(e)

        if not hasattr(self, '_sftp'):
            self._sftp = self._ssh.open_sftp()

    @property
    def sftp(self):
        """Lazy SFTP connection"""
        if not hasattr(self, '_sftp'):
            self._connect()
        return self._sftp

    def _get(self, name):
        try:
            return SFTPStorageFile(name, self, 'rb')
        except IOError:
            pass

    def _exists_upstream(self, name):
        try:
            f = SFTPStorageFile(name, self, 'rb')
            f.close()
            return True
        except Exception:
            return False

    def _read(self, name):
        remote_path = self._remote_path(name)
        return self.sftp.open(remote_path, 'rb')

    def _remote_path(self, name):
        return self._join(self._root_path, name)

    def _join(self, *args):
        # Use the path module for the remote host type to join a path together
        return self._pathmod.join(*args)

class SFTPStorageFile(File):
    def __init__(self, name, storage, mode):
        self._name = name
        self._storage = storage
        self._mode = mode
        self._is_dirty = False
        self.file = StringIO()
        self._is_read = False

    @property
    def size(self):
        if not hasattr(self, '_size'):
            self._size = self._storage.size(self._name)
        return self._size

    def read(self, num_bytes=None):
        if not self._is_read:
            self.file = self._storage._read(self._name)
            self._is_read = True

        return self.file.read(num_bytes)

    def write(self, content):
        raise NotImplementedError

    def close(self):
        if self._is_dirty:
            self._storage._save(self._name, self.file.getvalue())
        self.file.close()


""" https://adventofcode.com/2020/day/17 """

from typing import List
from copy import deepcopy
from functools import lru_cache

def part1(data: List[str]) -> int:
    """ O(n) solution """

    size_x = len(data[0]) + 2 * CYCLES
    size_y = len(data) + 2 * CYCLES
    size_z = CYCLES * 2 + 1

    pocket = [[[False] * size_x for _ in range(size_y)] for _ in range(size_z)]

    for y in range(len(data)):
        for x in range(len(data[y])):
            pocket[CYCLES][CYCLES + y][CYCLES + x] = data[y][x] == "#"

    for _ in range(CYCLES):
        temp = deepcopy(pocket)
        for z, depth in enumerate(pocket):
            for y, row in enumerate(depth):
                for x, cube in enumerate(row):
                    position = (z, y, x)
                    adjacents = find_3d_adjacents(
                        position, len(pocket), len(pocket[0]))
                    active = sum([(pocket[i][j][k]) for i, j, k in adjacents])

                    if cube and active not in (2, 3):
                        temp[z][y][x] = False
                    elif not cube and active == 3:
                        temp[z][y][x] = True

        pocket = deepcopy(temp)

    return sum([x for z in pocket for y in z for x in y])

def part2(data: List[str]) -> int:
    """ O(?) solution """

    size_x = len(data[0]) + 2 * CYCLES
    size_y = len(data) + 2 * CYCLES
    size_z = CYCLES * 2 + 1
    size_w = CYCLES * 2 + 1

    pocket = [[[[False] * size_x for _ in range(size_y)]
               for _ in range(size_z)] for _ in range(size_w)]

    for y, _ in enumerate(data):
        for x, _ in enumerate(data[y]):
            pocket[CYCLES][CYCLES][CYCLES +
                                   y][CYCLES + x] = data[y][x] == "#"

    for _ in range(CYCLES):
        temp = deepcopy(pocket)
        for w, time in enumerate(pocket):
            for z, depth in enumerate(time):
                for y, row in enumerate(depth):
                    for x, cube in enumerate(row):
                        position = (w, z, y, x)
                        adjacents = find_4d_adjacents(position, len(
                            pocket), len(pocket[0]), len(pocket[0][0]))
                        active = sum([(pocket[i][j][k][l])
                                      for i, j, k, l in adjacents])

                        if cube and active not in (2, 3):
                            temp[w][z][y][x] = False
                        elif not cube and active == 3:
                            temp[w][z][y][x] = True

        pocket = deepcopy(temp)

    return sum([x for w in pocket for z in w for y in z for x in y])

@lru_cache(maxsize=None)
def find_3d_adjacents(pos, depth, width):
    z, y, x = pos

    adjacents = []
    for i in range(z - 1, z + 2):
        for j in range(y - 1, y + 2):
            for k in range(x - 1, x + 2):
                if (i, j, k) != pos and - 1 < i < depth and - 1 < j < width and - 1 < k < width:
                    adjacents.append((i, j, k))

    return adjacents

@lru_cache(maxsize=None)
def find_4d_adjacents(pos, time, depth, width):
    w, z, y, x = pos

    adjacents = []
    for i in range(w - 1, w + 2):
        for j in range(z - 1, z + 2):
            for k in range(y - 1, y + 2):
                for l in range(x - 1, x + 2):
                    if (i, j, k, l) != pos and - 1 < i < time and - 1 < j < depth and - 1 < k < width and - 1 < l < width:
                        adjacents.append((i, j, k, l))

    return adjacents

if __name__ == "__main__":
    TEST = [line.strip() for line in open("tests/d17.txt", "r")]
    PUZZLE = [line.strip() for line in open("puzzles/d17.txt", "r")]
    CYCLES = 6

    assert part1(TEST) == 112
    assert part2(TEST) == 848

    print(f"Part 1: {part1(PUZZLE)}")
    print(f"Part 2: {part2(PUZZLE)}")


"""Parsing url to check its SEO and availability"""
from datetime import date
from bs4 import BeautifulSoup

def get_page_data(response):
    """Check SEO functionality of url"""

    result = {'status_code': response.status_code}

    page = BeautifulSoup(response.text, 'html.parser')

    result['h1'] = page.h1.get_text() if page.h1 else ''

    result['title'] = page.title.get_text() if page.title else ''

    result['description'] = page.find(
        'meta', {'name': 'description'}
    ).get('content') if page.find('meta', {'name': 'description'}) else ''

    result['created_at'] = date.today()

    return result


import numpy as np
import dill
import math
import sys
sys.path.append('../')
sys.path.append('./')
from src.graph import Graph
from src.evolution_strategies import one_plus_lambda, tournament_selection
from src.population import Population
from src.arg_parser import parse_args
import cProfile
import pstats

def bool_and(x, y): return x and y
def bool_or(x, y): return x or y
def bool_nand(x, y): return not(x and y)
def bool_nor(x, y): return not(x or y)

Population.add_operation(arity=2, func=bool_and, string="AND")
Population.add_operation(arity=2, func=bool_or, string="OR")
Population.add_operation(arity=2, func=bool_nand, string="NAND")
Population.add_operation(arity=2, func=bool_nor, string="NOR")

def eleven_multiplexer(arr):
    if len(arr) != 11:
        print("AAAAAAAAAAAAAAAAAAAAAAA")
        raise
    d = arr[0:8]
    a = arr[8:11]
    index = (int(a[0]) * 4) + (int(a[1]) * 2) + (int(a[2]) * 1)
    if d[index] == "1":
        return True
    return False

def create_tests(n):
    tests = []

    for i in range(2**n):
        base_2_v = bin(i).replace("0b", "").zfill(n)
        cont = 0
        input_arr = []
        for c in base_2_v:
            inp = False
            if c == "1":
                cont += 1
                inp = True
            input_arr.append(inp)
        response = True if cont%2 == 0 else False
        tests.append((input_arr, [response]))
    return tests

def fitness_func(individual: Graph, gen: int, tests):
    fitness = 0
    for t in tests:
        inputs = t[0]
        expected_out = t[1]

        graph_out = individual.operate(inputs)

        for h, y in zip(graph_out, expected_out):
            if h == y:
                fitness += 1

    fitness = fitness/len(tests)
    return np.clip(fitness, -1*(10**10), 10**10)

def main():
    n = 5
    args = parse_args()
    Population.rng = np.random.default_rng(args["seed"])

    tests = create_tests(n)
    def fit_func(indv, gen): return fitness_func(indv, gen, tests)

    population = Population(
        population_size=args["pop_size"],
        n_in=n,
        n_out=1,
        n_middle=args["n_middle_nodes"]
    )

    def t_select(): return tournament_selection(
        population=population,
        generations=args["max_gens"],
        goal_fit=1,
        fitness_func=fit_func,
        minimize_fitness=False,
        fit_share=args["fit_share"],
        stagnation=args["stagnation"],
        stag_preservation=args["stag_preservation"],
        report=args["report"],
        mutate_active_only=args["mut_active_only"],
        mutation_rate=args["mut_rate"],
        elitism=args["elitism"],
        crossover_rate=args["crossover_rate"],
        tournament_size=args["tourney_size"],
        species_threshold=args["species_threshold"],
        n_threads=args["n_threads"],
        csv_file=args["csv"],
        fit_partition_size=args["fit_partition"]
    )

    def p_lambda(): return one_plus_lambda(
        population=population,
        generations=args["max_gens"],
        goal_fit=1,
        fitness_func=fit_func,
        minimize_fitness=False,
        fit_share=args["fit_share"],
        stagnation=args["stagnation"],
        stag_preservation=args["stag_preservation"],
        report=args["report"],
        n_champions=args["elitism"],
        mutate_active_only=args["mut_active_only"],
        mutation_rate=args["mut_rate"],
        species_threshold=args["species_threshold"],
        n_threads=args["n_threads"],
        csv_file=args["csv"],
        fit_partition_size=args["fit_partition"]
    )

    exec_func = t_select
    if args["selection_method"] == "lambda":
        exec_func = p_lambda

    # profile = cProfile.Profile()
    # profile.runcall(exec_func)
    # ps = pstats.Stats(profile)
    # ps.print_stats()
    # print()
    exec_func()

    if args["save_to"] is not None:
        dill.dump(population, open(args["save_to"], mode='wb'))

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
"""This module loads images from csv files and outputs numpy arrays"""
from __future__ import absolute_import, division, print_function

from copy import deepcopy

import numpy as np
import tensorflow as tf
from six import string_types

import niftynet.utilities.util_csv as util_csv
from niftynet.io.image_type import ImageFactory
from niftynet.layer.base_layer import Layer, DataDependentLayer, RandomisedLayer
from niftynet.utilities.user_parameters_helper import make_input_tuple
from niftynet.utilities.util_common import print_progress_bar

# NP_TF_DTYPES = {'i': tf.int32, 'u': tf.int32, 'b': tf.int32, 'f': tf.float32}
from niftynet.utilities.niftynet_global_config import NiftyNetGlobalConfig

NP_TF_DTYPES = {'i': tf.float32,
                'u': tf.float32,
                'b': tf.float32,
                'f': tf.float32}

def infer_tf_dtypes(image_array):
    return NP_TF_DTYPES.get(image_array.dtype[0].kind, tf.float32)

class ImageReader(Layer):
    """
    For a concrete example:
    _input_sources define multiple modality mappings, e.g.,
    _input_sources {'image': ('T1', 'T2'),
                    'label': ('manual_map',)}
    means
    'image' consists of two components, formed by
    concatenating 'T1' and 'T2' input source images.
    'label' consists of one component, loading from 'manual_map'

    self._names: a tuple of the output names of this reader.
    ('image', 'labels')

    self._shapes: the shapes after combining input sources
    {'image': (192, 160, 192, 1, 2), 'label': (192, 160, 192, 1, 1)}

    self._dtypes: store the dictionary of tensorflow shapes
    {'image': tf.float32, 'label': tf.float32}

    self.output_list is a list of dictionaries, with each item:
    {'image': <niftynet.io.image_type.SpatialImage4D object>,
     'label': <niftynet.io.image_type.SpatialImage3D object>}
    """

    def __init__(self, names):
        # list of file names
        self._file_list = None
        self._input_sources = None
        self._shapes = None
        self._dtypes = None
        self._names = None
        self.names = names

        self._global_config = NiftyNetGlobalConfig()

        # list of image objects
        self.output_list = None
        self.current_id = -1

        self.preprocessors = []
        super(ImageReader, self).__init__(name='image_reader')

    def initialise_reader(self, data_param, task_param):
        """
        task_param specifies how to combine user input modalities
        e.g., for multimodal segmentation 'image' corresponds to multiple
        modality sections, 'label' corresponds to one modality section
        """
        if not self.names:
            tf.logging.fatal('Please specify data names, this should '
                             'be a subset of SUPPORTED_INPUT provided '
                             'in application file')
            raise ValueError
        self._names = [name for name in self.names
                       if vars(task_param).get(name, None)]

        self._input_sources = {name: vars(task_param).get(name)
                               for name in self.names}
        data_to_load = {}
        for name in self._names:
            for source in self._input_sources[name]:
                try:
                    data_to_load[source] = data_param[source]
                except KeyError:
                    tf.logging.fatal(
                        'reader name [%s] requires [%s], however it is not '
                        'specified as a section in the config, '
                        'current input section names: %s',
                        name, source, list(data_param))
                    raise ValueError

        default_data_folder = self._global_config.get_niftynet_home_folder()
        self._file_list = util_csv.load_and_merge_csv_files(data_to_load, default_data_folder)
        self.output_list = _filename_to_image_list(
            self._file_list, self._input_sources, data_param)
        for name in self.names:
            tf.logging.info(
                'image reader: loading [%s] from %s (%d)',
                name, self.input_sources[name], len(self.output_list))

    def prepare_preprocessors(self):
        for layer in self.preprocessors:
            if isinstance(layer, DataDependentLayer):
                layer.train(self.output_list)

    def add_preprocessing_layers(self, layers):
        assert self.output_list is not None, \
            'Please initialise the reader first, ' \
            'before adding preprocessors.'
        if isinstance(layers, Layer):
            self.preprocessors.append(layers)
        else:
            self.preprocessors.extend(layers)
        self.prepare_preprocessors()

    # pylint: disable=arguments-differ
    def layer_op(self, idx=None, shuffle=True):
        """
        this layer returns a dictionary
          keys: self.output_fields
          values: image volume array
        """
        if idx is None and shuffle:
            # training, with random list output
            idx = np.random.randint(len(self.output_list))

        if idx is None and not shuffle:
            # testing, with sequential output
            # accessing self.current_id, not suitable for multi-thread
            idx = self.current_id + 1
            self.current_id = idx

        try:
            idx = int(idx)
        except ValueError:
            idx = -1

        if idx < 0 or idx >= len(self.output_list):
            return -1, None, None

        image_dict = self.output_list[idx]
        image_data_dict = {field: image.get_data()
                           for (field, image) in image_dict.items()}
        interp_order_dict = {field: image.interp_order
                             for (field, image) in image_dict.items()}
        if self.preprocessors:
            preprocessors = [deepcopy(layer) for layer in self.preprocessors]
            # dictionary of masks is cached
            mask = None
            for layer in preprocessors:
                # import time; local_time = time.time()
                if layer is None:
                    continue
                if isinstance(layer, RandomisedLayer):
                    layer.randomise()
                    image_data_dict = layer(image_data_dict, interp_order_dict)
                else:
                    image_data_dict, mask = layer(image_data_dict, mask)
                # print('%s, %.3f sec'%(layer, -local_time + time.time()))
        return idx, image_data_dict, interp_order_dict

    @property
    def shapes(self):
        """
        image shapes before any preprocessing
        :return: tuple of integers as image shape
        """
        # to have fast access, the spatial dimensions are not accurate
        # 1) only read from the first image in list
        # 2) not considering effects of random augmentation layers
        # but time and modality dimensions should be correct
        if not self.output_list:
            tf.logging.fatal("please initialise the reader first")
            raise RuntimeError
        if not self._shapes:
            first_image = self.output_list[0]
            self._shapes = {field: first_image[field].shape
                            for field in self.names}
        return self._shapes

    @property
    def tf_dtypes(self):
        if not self.output_list:
            tf.logging.fatal("please initialise the reader first")
            raise RuntimeError
        if not self._dtypes:
            first_image = self.output_list[0]
            self._dtypes = {field: infer_tf_dtypes(first_image[field])
                            for field in self.names}
        return self._dtypes

    @property
    def input_sources(self):
        if not self._input_sources:
            tf.logging.fatal("please initialise the reader first")
            raise RuntimeError
        return self._input_sources

    @property
    def names(self):
        return self._names

    @names.setter
    def names(self, fields_tuple):
        # output_fields is a sequence of output names
        # each name might correspond to a list of multiple input sources
        # this should be specified in CUSTOM section in the config
        self._names = make_input_tuple(fields_tuple, string_types)

    def get_subject_id(self, image_index):
        return self._file_list.iloc[image_index, 0]

def _filename_to_image_list(file_list, mod_dict, data_param):
    """
    converting a list of filenames to a list of image objects
    useful properties (e.g. interp_order) are added to each object
    """
    volume_list = []
    for idx in range(len(file_list)):
        print_progress_bar(idx, len(file_list),
                           prefix='reading datasets headers',
                           decimals=1, length=10, fill='*')
        # combine fieldnames and volumes as a dictionary
        _dict = {field: _create_image(file_list, idx, modalities, data_param)
                 for (field, modalities) in mod_dict.items()}
        volume_list.append(_dict)
    return volume_list

def _create_image(file_list, idx, modalities, data_param):
    """
    data_param consists of description of each modality
    This function combines modalities according to the 'modalities'
    parameter and create <niftynet.io.input_type.SpatialImage*D>
    """
    try:
        file_path = tuple(file_list.loc[idx, mod] for mod in modalities)
        interp_order = tuple(data_param[mod].interp_order for mod in modalities)
        pixdim = tuple(data_param[mod].pixdim for mod in modalities)
        axcodes = tuple(data_param[mod].axcodes for mod in modalities)
    except KeyError:
        tf.logging.fatal(
            "Specified modality names %s "
            "not found in config: input sections %s",
            modalities, list(data_param))
        raise
    except AttributeError:
        tf.logging.fatal(
            'data params must contain: interp_order, pixdim, axcodes')
        raise

    image_properties = {'file_path': file_path,
                        'name': modalities,
                        'interp_order': interp_order,
                        'output_pixdim': pixdim,
                        'output_axcodes': axcodes}
    return ImageFactory.create_instance(**image_properties)


# coding=utf-8
from django.contrib.admin import ModelAdmin, site
from models import News

class NewsAdmin(ModelAdmin):
    list_display = ('id', 'match_type', 'game_start_time', 'end_score', 'middle_score', 'status', 'team1', 'score',
                    'team2',  'yapan','yapanSB', 'daxiaopan','daxiaopanSB', 'findex', 'create_time')
    ording = ('id',)
    list_per_page = 300
    list_filter = ('create_time',)
    search_fields = ['team1', 'team2', 'findex', 'score']

site.register(News, NewsAdmin)


import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.cm import get_cmap

data = pd.read_csv("./output_geo.csv")
df = pd.DataFrame(data)
fig, ax = plt.subplots()

# get a color map
cmap = get_cmap("tab20", 28)  # type: matplotlib.colors.ListedColormap
colors = cmap.colors  # type: list

ips = df['ip']
mean_rtt = df['mean_rtt']

ax.bar(ips, mean_rtt, color=colors)
ax.set_ylabel('Mean RTT in ms')
ax.set_title('Mean RTT for each hop between ips')

plt.xticks(rotation=15)
plt.show()


"""
Perform Outlier Rejection with MCMC
-----------------------------------
Figure 8.9

Bayesian outlier detection for the same data as shown in figure 8.8. The
top-left panel shows the data, with the fits from each model. The top-right
panel shows the 1-sigma and 2-sigma contours for the slope and intercept with
no outlier correction: the resulting fit (shown by the dotted line) is clearly
highly affected by the presence of outliers. The bottom-left panel shows the
marginalized 1-sigma and 2-sigma contours for a mixture model (eq. 8.67). The
bottom-right panel shows the marginalized 1-sigma and 2-sigma contours for a
model in which points are identified individually as "good" or "bad"
(eq. 8.68). The points which are identified by this method as bad with a
probability greater than 68% are circled in the first panel.
"""
# Author: Jake VanderPlas (adapted to PyMC3 by Brigitta Sipocz)
# License: BSD
#   The figure produced by this code is published in the textbook
#   "Statistics, Data Mining, and Machine Learning in Astronomy" (2013)
#   For more information, see http://astroML.github.com
#   To report a bug or issue, use the following forum:
#    https://groups.google.com/forum/#!forum/astroml-general
import numpy as np

import pymc3 as pm

from matplotlib import pyplot as plt
from theano import shared as tshared
import theano.tensor as tt

from astroML.datasets import fetch_hogg2010test
from astroML.plotting.mcmc import convert_to_stdev

# ----------------------------------------------------------------------
# This function adjusts matplotlib settings for a uniform feel in the textbook.
# Note that with usetex=True, fonts are rendered with LaTeX.  This may
# result in an error if LaTeX is not installed on your system.  In that case,
# you can set usetex to False.
if "setup_text_plots" not in globals():
    from astroML.plotting import setup_text_plots
setup_text_plots(fontsize=8, usetex=True)

np.random.seed(0)

# ------------------------------------------------------------
# Get data: this includes outliers. We need to convert them to Theano variables
data = fetch_hogg2010test()
xi = tshared(data['x'])
yi = tshared(data['y'])
dyi = tshared(data['sigma_y'])
size = len(data)

# ----------------------------------------------------------------------
# Define basic linear model

def model(xi, theta, intercept):
    slope = np.tan(theta)
    return slope * xi + intercept

# ----------------------------------------------------------------------
# First model: no outlier correction
with pm.Model():
    # set priors on model gradient and y-intercept
    inter = pm.Uniform('inter', -1000, 1000)
    theta = pm.Uniform('theta', -np.pi / 2, np.pi / 2)

    y = pm.Normal('y', mu=model(xi, theta, inter), sd=dyi, observed=yi)

    trace0 = pm.sample(draws=5000, tune=1000)

# ----------------------------------------------------------------------
# Second model: nuisance variables correcting for outliers
# This is the mixture model given in equation 17 in Hogg et al
def mixture_likelihood(yi, xi):
    """Equation 17 of Hogg 2010"""

    sigmab = tt.exp(log_sigmab)
    mu = model(xi, theta, inter)

    Vi = dyi ** 2
    Vb = sigmab ** 2

    root2pi = np.sqrt(2 * np.pi)

    L_in = (1. / root2pi / dyi * np.exp(-0.5 * (yi - mu) ** 2 / Vi))

    L_out = (1. / root2pi / np.sqrt(Vi + Vb)
             * np.exp(-0.5 * (yi - Yb) ** 2 / (Vi + Vb)))

    return tt.sum(tt.log((1 - Pb) * L_in + Pb * L_out))

with pm.Model():
    # uniform prior on Pb, the fraction of bad points
    Pb = pm.Uniform('Pb', 0, 1.0, testval=0.1)

    # uniform prior on Yb, the centroid of the outlier distribution
    Yb = pm.Uniform('Yb', -10000, 10000, testval=0)

    # uniform prior on log(sigmab), the spread of the outlier distribution
    log_sigmab = pm.Uniform('log_sigmab', -10, 10, testval=5)

    inter = pm.Uniform('inter', -200, 400)
    theta = pm.Uniform('theta', -np.pi / 2, np.pi / 2, testval=np.pi / 4)

    y_mixture = pm.DensityDist('mixturenormal', logp=mixture_likelihood,
                               observed={'yi': yi, 'xi': xi})

    trace1 = pm.sample(draws=5000, tune=1000)

# ----------------------------------------------------------------------
# Third model: marginalizes over the probability that each point is an outlier.
# define priors on beta = (slope, intercept)

def outlier_likelihood(yi, xi):
    """likelihood for full outlier posterior"""

    sigmab = tt.exp(log_sigmab)
    mu = model(xi, theta, inter)

    Vi = dyi ** 2
    Vb = sigmab ** 2

    logL_in = -0.5 * tt.sum(qi * (np.log(2 * np.pi * Vi)
                                  + (yi - mu) ** 2 / Vi))

    logL_out = -0.5 * tt.sum((1 - qi) * (np.log(2 * np.pi * (Vi + Vb))
                                         + (yi - Yb) ** 2 / (Vi + Vb)))

    return logL_out + logL_in

with pm.Model():
    # uniform prior on Pb, the fraction of bad points
    Pb = pm.Uniform('Pb', 0, 1.0, testval=0.1)

    # uniform prior on Yb, the centroid of the outlier distribution
    Yb = pm.Uniform('Yb', -10000, 10000, testval=0)

    # uniform prior on log(sigmab), the spread of the outlier distribution
    log_sigmab = pm.Uniform('log_sigmab', -10, 10, testval=5)

    inter = pm.Uniform('inter', -1000, 1000)
    theta = pm.Uniform('theta', -np.pi / 2, np.pi / 2)

    # qi is bernoulli distributed
    qi = pm.Bernoulli('qi', p=1 - Pb, shape=size)

    y_outlier = pm.DensityDist('outliernormal', logp=outlier_likelihood,
                               observed={'yi': yi, 'xi': xi})

    trace2 = pm.sample(draws=5000, tune=1000)

# ------------------------------------------------------------
# plot the data
fig = plt.figure(figsize=(5, 5))
fig.subplots_adjust(left=0.1, right=0.95, wspace=0.25,
                    bottom=0.1, top=0.95, hspace=0.2)

# first axes: plot the data
ax1 = fig.add_subplot(221)
ax1.errorbar(data['x'], data['y'], data['sigma_y'], fmt='.k', ecolor='gray', lw=1)
ax1.set_xlabel('$x$')
ax1.set_ylabel('$y$')

#------------------------------------------------------------
# Go through models; compute and plot likelihoods
linestyles = [':', '--', '-']
labels = ['no outlier correction\n(dotted fit)',
          'mixture model\n(dashed fit)',
          'outlier rejection\n(solid fit)']

x = np.linspace(0, 350, 10)

bins = [(np.linspace(140, 300, 51), np.linspace(0.6, 1.6, 51)),
        (np.linspace(-40, 120, 51), np.linspace(1.8, 2.8, 51)),
        (np.linspace(-40, 120, 51), np.linspace(1.8, 2.8, 51))]

for i, trace in enumerate([trace0, trace1, trace2]):
    H2D, bins1, bins2 = np.histogram2d(np.tan(trace['theta']),
                                       trace['inter'], bins=50)
    w = np.where(H2D == H2D.max())

    # choose the maximum posterior slope and intercept
    slope_best = bins1[w[0][0]]
    intercept_best = bins2[w[1][0]]

    # plot the best-fit line
    ax1.plot(x, intercept_best + slope_best * x, linestyles[i], c='k')

    # For the model which identifies bad points,
    # plot circles around points identified as outliers.
    if i == 2:
        Pi = trace['qi'].mean(0)
        outlier_x = data['x'][Pi < 0.32]
        outlier_y = data['y'][Pi < 0.32]
        ax1.scatter(outlier_x, outlier_y, lw=1, s=400, alpha=0.5,
                    facecolors='none', edgecolors='red')

    # plot the likelihood contours
    ax = plt.subplot(222 + i)

    H, xbins, ybins = np.histogram2d(trace['inter'],
                                     np.tan(trace['theta']), bins=bins[i])
    H[H == 0] = 1E-16
    Nsigma = convert_to_stdev(np.log(H))

    ax.contour(0.5 * (xbins[1:] + xbins[:-1]),
               0.5 * (ybins[1:] + ybins[:-1]),
               Nsigma.T, levels=[0.683, 0.955], colors='black')

    ax.set_xlabel('intercept')
    ax.set_ylabel('slope')
    ax.grid(color='gray')
    ax.xaxis.set_major_locator(plt.MultipleLocator(40))
    ax.yaxis.set_major_locator(plt.MultipleLocator(0.2))

    ax.text(0.96, 0.96, labels[i], ha='right', va='top',
            bbox=dict(fc='w', ec='none', alpha=0.5),
            transform=ax.transAxes)
    ax.set_xlim(bins[i][0][0], bins[i][0][-1])
    ax.set_ylim(bins[i][1][0], bins[i][1][-1])

ax1.set_xlim(0, 350)
ax1.set_ylim(100, 700)

plt.show()


import copy
import logging
from collections import OrderedDict
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, NamedTuple, Union

import yaml

import cekit
from cekit.cekit_types import _T, RawDescriptor
from cekit.config import Config
from cekit.descriptor import (
    Arg,
    Descriptor,
    Env,
    Label,
    Modules,
    Osbs,
    Packages,
    Port,
    Run,
    Volume,
)
from cekit.descriptor.resource import Resource, create_resource
from cekit.errors import CekitError
from cekit.tools import get_latest_image_version

if TYPE_CHECKING:
    from cekit.descriptor.modules import Install
    from cekit.descriptor.overrides import Overrides
    from cekit.generator.base import ModuleRegistry

logger = logging.getLogger("cekit")
config = Config()

_image_schema = yaml.safe_load(
    """
map:
  name: {type: str, required: True}
  version: {type: text, required: True}
  schema_version: {type: int}
  release: {type: text}
  from: {type: str}
  follow_tag: {type: str}
  description: {type: text}
  args:  {type: any}
  labels: {type: any}
  envs:  {type: any}
  ports: {type: any}
  run: {type: any}
  artifacts: {type: any}
  modules: {type: any}
  packages: {type: any}
  osbs: {type: any}
  volumes: {type: any}
  help:
    map:
      add: {type: bool}
      template: {type: text}"""
)

class ImageOverrides(NamedTuple):
    artifacts: Dict[str, "Resource"]
    modules: Dict[str, "Install"]

def get_image_schema():
    return copy.deepcopy(_image_schema)

class Image(Descriptor):
    def __init__(self, descriptor: RawDescriptor, artifact_dir: str):
        self._artifact_dir: str = artifact_dir
        self.path: str = artifact_dir
        self.schema = _image_schema.copy()
        super(Image, self).__init__(descriptor)
        self.skip_merging = ["description", "version", "name", "release"]
        self._prepare()

    def _prepare(self):
        # TODO: Separating raw image descriptor from a higher level Image class would change this
        # confusing code into a connector/factory.
        self._descriptor["labels"] = [
            Label(x) for x in self._descriptor.get("labels", [])
        ]
        self._descriptor["envs"] = [Env(x) for x in self._descriptor.get("envs", [])]
        self._descriptor["ports"] = [Port(x) for x in self._descriptor.get("ports", [])]
        if "run" in self._descriptor:
            self._descriptor["run"] = Run(self._descriptor["run"])
        self._descriptor["artifacts"] = [
            create_resource(a, directory=self._artifact_dir)
            for a in self._descriptor.get("artifacts", [])
        ]
        self._descriptor["modules"] = Modules(
            self._descriptor.get("modules", {}), self.path
        )
        self._descriptor["packages"] = Packages(
            self._descriptor.get("packages", {}), self.path
        )
        self._descriptor["osbs"] = Osbs(self._descriptor.get("osbs", {}), self.path)
        self._descriptor["volumes"] = [
            Volume(x) for x in self._descriptor.get("volumes", [])
        ]

        # make sure image declarations override any module definitions
        # TODO: Make into a NamedTuple to make types easier to reason about.
        self._image_overrides = ImageOverrides(
            artifacts=Image._to_dict(self.artifacts),
            modules=Image._to_dict(self.modules.install),
        )
        self._all_artifacts: Dict[str, Resource] = Image._to_dict(self.artifacts)

    def process_defaults(self):
        """Prepares default values before rendering"""
        if not self.run:
            self.run = Run({})

        # do we want to force a user?
        if "user" not in self.run:
            self.run._descriptor["user"] = cekit.DEFAULT_USER

        # Default package manager is yum
        if not self.packages.manager:
            self.packages._descriptor["manager"] = "yum"

        # Default directory for supplementary files that should be copied to dist-git directory
        if not self.osbs.extra_dir:
            self.osbs._descriptor["extra_dir"] = "osbs_extra"

        # Placing this here rather than in init as apply_image_overrides runs after that. This means
        # follow_tag is applied *after* overrides.
        if self.follow:
            if not config.get("common", "redhat"):
                raise CekitError(
                    "follow_tag annotation only supported with redhat flag"
                )
            self.base = get_latest_image_version(self.follow)

    @property
    def name(self) -> str:
        return self.get("name")

    @name.setter
    def name(self, value: str):
        self._descriptor["name"] = value

    @property
    def version(self) -> Any:
        # TODO: Convert to string up front to simplify
        return self.get("version")

    @version.setter
    def version(self, value: Any):
        self._descriptor["version"] = value

    # TODO: release is undocumented.
    @property
    def release(self) -> str:
        return self.get("release")

    @release.setter
    def release(self, value: str):
        self._descriptor["release"] = value

    @property
    def base(self) -> str:
        return self.get("from")

    @base.setter
    def base(self, value: str):
        self._descriptor["from"] = value

    @property
    def follow(self) -> str:
        return self.get("follow_tag")

    @follow.setter
    def follow(self, value: str):
        self._descriptor["follow_tag"] = value

    @property
    def description(self) -> str:
        return self.get("description")

    @description.setter
    def description(self, value: str) -> None:
        self._descriptor["description"] = value

    @property
    def labels(self) -> List[Label]:
        return self.get("labels", [])

    @property
    def envs(self) -> List[Env]:
        return self.get("envs", [])

    @property
    def args(self) -> List[Arg]:
        return self.get("args", [])

    @property
    def ports(self) -> List[Port]:
        return self.get("ports", [])

    @property
    def run(self) -> Run:
        return self.get("run")

    @run.setter
    def run(self, value: Run):
        self._descriptor["run"] = value

    @property
    def all_artifacts(self) -> Iterable[Resource]:
        return self._all_artifacts.values()

    @property
    def artifacts(self) -> List[Resource]:
        return self.get("artifacts", [])

    @property
    def modules(self) -> Modules:
        return self.get("modules", Modules({}, self._artifact_dir))

    @property
    def packages(self) -> Packages:
        return self.get("packages", Packages({}, self.path))

    @property
    def osbs(self) -> Osbs:
        return self.get("osbs")

    @osbs.setter
    def osbs(self, value: Osbs):
        self._descriptor["osbs"] = value

    @property
    def volumes(self) -> List[Volume]:
        return self.get("volumes", [])

    @property
    def help(self) -> dict:
        return self.get("help", {})

    def apply_image_overrides(self, overrides: List["Overrides"]):
        """
        Applies overrides to the image descriptor.
        """
        if not overrides:
            return
        for override in overrides:
            if override.name:
                self.name = override.name
            if override.version:
                self.version = override.version
            if override.base:
                self.base = override.base
            if override.description:
                self.description = override.description

            labels = Image._to_dict(self.labels)
            for label in override.labels:
                name = label.name
                if name in labels:
                    labels[name] = label.merge(labels[name])
                else:
                    labels[name] = label
            self._descriptor["labels"] = list(labels.values())

            envs = Image._to_dict(self.envs)
            for env in override.envs:
                name = env.name
                if name in envs:
                    envs[name] = env.merge(envs[name])
                else:
                    envs[name] = env
            self._descriptor["envs"] = list(envs.values())

            ports = Image._to_dict(self.ports)
            for port in override.ports:
                name = port.value
                if name in ports:
                    ports[name] = port.merge(ports[name])
                else:
                    ports[name] = port
            self._descriptor["ports"] = list(ports.values())

            module_repositories = Image._to_dict(self.modules.repositories)
            for repository in override.modules.repositories:
                name = repository.name
                if name in module_repositories:
                    module_repositories[name] = repository.merge(
                        module_repositories[name]
                    )
                else:
                    module_repositories[name] = repository
            self.modules._descriptor["repositories"] = list(
                module_repositories.values()
            )

            self.packages._descriptor = override.packages.merge(self.packages)

            # In case content sets are provided as null values
            # Remove the key entirely.
            # TODO: This should be handled probably at general level, for every key
            for flag in ["content_sets", "content_sets_file"]:
                if flag in override.packages and override.packages[flag] is None:
                    self.packages._descriptor.pop("content_sets", None)
                    self.packages._descriptor.pop("content_sets_file", None)

            # Merge override osbs items into self.
            self.osbs = self.osbs.merge(override.osbs)

            # Using 'or []' to avoid having to set default value in packages.py for _descriptor["remove"]
            for package in override.packages.remove or []:
                if package not in self.packages.remove:
                    self.packages.remove.append(package)

            for package in override.packages.install or []:
                if package not in self.packages.install:
                    self.packages.install.append(package)

            for package in override.packages.reinstall or []:
                if package not in self.packages.reinstall:
                    self.packages.reinstall.append(package)

            artifact_overrides = self._image_overrides.artifacts
            image_artifacts = Image._to_dict(self.artifacts)
            for i, artifact in enumerate(override.artifacts):
                name = artifact.name
                # override.artifact contains override values WITH defaults.
                # override.original_descriptor contains override value WITHOUT defaults.
                # artifact_overrides contains original dictionary
                #
                # Iterating over dest / target / ...
                #   If we have _not_ supplied a target (check original_descriptor),
                #      then check artifact_overrides,
                #         otherwise use default from override.artifact
                override_without_defaults = override.original_descriptor.get(
                    "artifacts"
                )[i]
                for key in ["dest", "target", "description"]:
                    if override_without_defaults.get(key):
                        logger.debug(
                            "Key ({}) found in override as {}".format(
                                key, override_without_defaults.get(key)
                            )
                        )
                        artifact[key] = override_without_defaults.get(key)
                    elif artifact_overrides.get(name) and artifact_overrides.get(
                        name
                    ).get(key):
                        new_value = artifact_overrides.get(name).get(key)
                        logger.debug(
                            "Key ({}) found in original artifact as {}".format(
                                key, new_value
                            )
                        )
                        artifact[key] = new_value

                # collect override so we can apply it to modules
                artifact_overrides[name] = artifact
                # add it to the list of everything
                self._all_artifacts[name] = artifact
                # Apply override to image descriptor
                image_artifacts[name] = artifact
                # Sort the output as it makes it easier to view and test.
                logger.debug(
                    "Final (with override) artifact is {}".format(
                        sorted(artifact.items())
                    )
                )
            self._descriptor["artifacts"] = list(image_artifacts.values())

            module_overrides = self._image_overrides.modules
            image_modules = Image._to_dict(self.modules.install)
            for module in override.modules.install:
                name = module.name
                # collect override so we can apply it to modules.
                # this allows us to override module versions without affecting ordering.
                module_overrides[name] = module
                # Apply override to image descriptor
                # If the module does not exists in the original descriptor, add it there
                image_modules[name] = module
            self.modules._descriptor["install"] = list(image_modules.values())

            if override.run is not None:
                if self.run:
                    self.run = override.run.merge(self.run)
                else:
                    self.run = override.run

    def apply_module_overrides(self, module_registry: "ModuleRegistry"):
        """
        Applies overrides to included modules.  This includes:
            Artifact definitions
            Module dependency version overrides
        Also incorporates module contributed global configuration into the image:
            Run specification
            Package repository definitions
            Required artifacts
        """
        install_list: Dict[str, "Install"] = OrderedDict()

        # index by name for easier access
        self._package_repositories = Image._to_dict(self.packages.repositories)

        # collect final 'run' value from modules
        self._module_run = Run({})

        # process the modules and integrate relevant bits into ourself
        self.process_install_list(
            self, self.modules.install, install_list, module_registry
        )

        # update ourself based on module declarations
        # final order of modules to be installed
        self.modules._descriptor["install"] = list(install_list.values())
        # all package repositories required for installing packages
        self.packages._descriptor["repositories"] = list(
            self._package_repositories.values()
        )

        # final 'run' value
        if self.run:
            self.run = self.run.merge(self._module_run)
        else:
            self.run = self._module_run

    def process_install_list(
        self,
        source: Union["Image"],
        to_install_list: List["Install"],
        install_list: Dict[str, "Install"],
        module_registry: "ModuleRegistry",
    ) -> None:
        # TODO: Return value is passed as parameter in `install_list`
        module_overrides = self._image_overrides.modules
        artifact_overrides = self._image_overrides.artifacts
        for to_install in to_install_list:
            logger.debug(
                "Preparing module '{}' required by '{}'.".format(
                    to_install.name, source.name
                )
            )
            override = module_overrides.get(to_install.name, None)
            if override:
                if override.version != to_install.version:
                    logger.debug(
                        "Module '{}:{}' being overridden with '{}:{}'.".format(
                            to_install.name,
                            to_install.version,
                            override.name,
                            override.version,
                        )
                    )
                # apply module override
                to_install = override

            existing = install_list.get(to_install.name, None)
            # see if we've already processed this
            if existing:
                # check for a version conflict
                if existing.version != to_install.version:
                    logger.warning(
                        "Module version inconsistency for {}: {} requested, but {} will be used.".format(
                            to_install.name, to_install.version, existing.version
                        )
                    )
                continue

            module = module_registry.get_module(to_install.name, to_install.version)
            if not module:
                raise CekitError(
                    "Could not locate module %s version %s. Please verify that it is included in one of the "
                    "specified module repositories."
                    % (to_install.name, to_install.version)
                )

            # collect artifacts and apply overrides
            module_artifacts = Image._to_dict(module.artifacts)
            for artifact in module.artifacts:
                name = artifact.name
                if name in artifact_overrides:
                    override = artifact_overrides[name]
                    self._all_artifacts[name] = override
                    module_artifacts[name] = override
                else:
                    self._all_artifacts[name] = artifact
            module._descriptor["artifacts"] = list(module_artifacts.values())

            # collect package repositories
            for repo in module.packages.repositories:
                name = repo.name
                if name not in self._package_repositories:
                    self._package_repositories[name] = repo

            # collect package manager
            if not self.packages.manager and module.packages.manager:
                logger.debug(
                    f"Applying module package manager of {module.packages.manager} to image"
                )
                self.packages._descriptor["manager"] = module.packages.manager

            # incorporate run specification contributed by module
            if module.run:
                # we're looping in order of install, so we want the current module to override whatever we have
                self._module_run = module.run.merge(self._module_run)

            # prevent circular dependencies. we'll move it to the end after processing
            install_list[to_install.name] = to_install

            # process this modules dependencies
            self.process_install_list(
                module, module.modules.install, install_list, module_registry
            )

            # move this module to the end of the list.
            install_list.pop(to_install.name)
            install_list[to_install.name] = to_install

    # helper to simplify merging lists of objects
    @classmethod
    def _to_dict(cls, named_items: Iterable[_T], key="name") -> Dict[str, _T]:
        # TODO: `key` argument is never used?
        # TODO: This assumes that `name` is always a string, but in fact it isn't for Port
        dictionary = OrderedDict()
        for item in named_items:
            dictionary[item[key]] = item
        return dictionary


import cv2

import numpy as np

from scipy import signal

import math

import matplotlib.pyplot as plt

if __name__ == "__main__":

    gauss_blur_filter = [[0 for x in range(3)] for y in range(3)]

    gauss_blur_filter[0][0] = 1/16
    gauss_blur_filter[0][1] = 1/8
    gauss_blur_filter[0][2] = 1/16
    gauss_blur_filter[1][0] = 1/8
    gauss_blur_filter[1][1] = 1/4
    gauss_blur_filter[1][2] = 1/8
    gauss_blur_filter[2][0] = 1/16
    gauss_blur_filter[2][1] = 1/8
    gauss_blur_filter[2][2] = 1/16

    image = cv2.imread('point.jpg',0)

    kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype = np.float)

    replicate = cv2.copyMakeBorder(image,20,20,20,20,cv2.BORDER_REPLICATE)

    resultant_image = cv2.blur(replicate,(5,5))

    cv2.imwrite('gauss-blue.jpg',resultant_image)

    resultant_image_1 = signal.convolve2d(image,kernel,'same')

    rows,columns = resultant_image_1.shape

    for i in range(rows):
        for j in range(columns):

            resultant_image_1[i][j] = abs(resultant_image_1[i][j])

    cv2.imwrite('mask-application.jpg',resultant_image_1)

    print(resultant_image_1.max())

    for i in range(rows):
        for j in range(columns):

            if resultant_image_1[i][j] >= 2024:

                print(i,j)

            else:

                resultant_image_1[i][j] = 0

    cv2.imwrite('point-detection.jpg',resultant_image_1)

    image_segment = cv2.imread('segment.jpg',0)

    rows,columns = image_segment.shape

    '''x = np.zeros(255)

    y = np.arange(0,255,1)
    for i in range(rows):
        for j in range(columns):
            if image_segment[i][j] != 0:
                x[image_segment[i][j]] += 1

    hist, bins = np.histogram(x, bins=y)
    width = 1.0 * (bins[1] - bins[0])
    center = (bins[:-1] + bins[1:]) / 2
    plt.bar(center, hist, align='center', width=width)

    #plt.plot(y,x)
    #plt.bar(np.arange(len(y)),y)
    plt.show()'''

    for i in range(rows):
        for j in range(columns):

            if image_segment[i][j] > 208 or image_segment[i][j] < 200 :
                image_segment[i][j] = 0

    cv2.imwrite('segemented.jpg',image_segment)


import numpy as np
import torch
import os
import yaml
import tqdm
from addict import Dict
from collections import defaultdict
from matplotlib import pyplot as plt
import matplotlib.patches as patches
import pickle
import random
import pytorch_ssim

from skimage.measure import compare_ssim as ssim
from train import build_loaders
from scene_generation.data import imagenet_deprocess_batch
from scene_generation.metrics import jaccard
from scene_generation.model import Model
from scene_generation.args import get_args

#perceptual error
from PerceptualSimilarity import models
#from PerceptualSimilarity.util import util

GPU = 0
PRECOMPUTED = False     # use precomputed samples (saved in the checkpoint) for evaluation
EVAL_ALL = True         # evaluate on all bounding boxes (batch size=1)
USE_GT = True           # use ground truth bounding boxes for evaluation
USE_FEATS = False #True
IGNORE_SMALL = False
SPLIT = '../sg2im/datasets/vg/test.h5'

BATCH_SIZE = 1
PRINT_EVERY = 50
SAVE_EVERY = 500

#EXPERIMENT = 'jitter_L_0.05_FixBoxes'
#EXPERIMENT = 'clean_infeats_64'
EXPERIMENT = "aGCN_SPADE"
ckpt = "checkpoint"
#EXPERIMENT = 'baseline_64_noise_250k'
CHECKPOINT = './output/Nov12_14-43-14_atnavab21/{}_with_model.pt'.format(ckpt)
#config_file = 'experiments/default/logs/{}/args.yaml'.format(EXPERIMENT)
results_file = 'test_results_{}.pickle'

def main():
    if not os.path.isfile(CHECKPOINT):
        print('ERROR: Checkpoint file "%s" not found' % CHECKPOINT)
        return

    # Read config file of the model
    args = get_args()
    print(args)
    torch.manual_seed(1)
    random.seed(1)
    np.random.seed(1)

    # reset some arguments
    args.add_jitter_bbox = None
    args.add_jitter_layout = None
    args.add_jitter_feats = None
    args.batch_size = BATCH_SIZE
    args.test_h5 = SPLIT
    device = torch.device("cuda:0") #torch.cuda.set_device(GPU)

    # Load the model, with a bit of care in case there are no GPUs
    map_location = 'cpu' if device == torch.device('cpu') else None
    checkpoint = torch.load(CHECKPOINT, map_location=map_location)

    if not PRECOMPUTED:
        # initialize model and load checkpoint
        kwargs = checkpoint['model_kwargs']

        model = Model(**kwargs)
        model.load_state_dict(checkpoint['model_state'])
        model.eval()
        model.to(device)

        # create data loaders
        _, train_loader, val_loader, test_loader = build_loaders(args, evaluating=True)

        # testing model
        print('Batch size: ', BATCH_SIZE)
        print('Evaluating on {} set'.format(SPLIT))
        eval_model(args, model, test_loader, device, use_gt=USE_GT, use_feats=USE_FEATS, filter_box=IGNORE_SMALL)
        # losses, samples, avg_iou = results
    else:
        # sample images and scores already computed while training (only one batch)
        samples = checkpoint['val_samples'][-1]    # get last iteration
        original_img = samples['gt_img'].cpu().numpy()
        predicted_img = samples['gt_box_pred_mask'].cpu().numpy()

    return

def eval_model(args, model, loader, device, use_gt=False, use_feats=False, filter_box=False):
    all_losses = defaultdict(list)
    all_boxes = defaultdict(list)
    total_iou = []
    total_boxes = 0
    num_batches = 0
    num_samples = 0
    mae_per_image = []
    mae_roi_per_image = []
    roi_only_iou = []
    ssim_per_image = []
    ssim_rois = []
    rois = 0
    margin = 2

    ## Initializing the perceptual loss model
    lpips_model = models.PerceptualLoss(model='net-lin',net='alex',use_gpu=True)
    perceptual_error_image = []
    perceptual_error_roi = []
    # ---------------------------------------

    with torch.no_grad():
        for batch in tqdm.tqdm(loader):
            num_batches += 1
            # if num_batches > 10:
            #     break
            batch = [tensor.to(device) for tensor in batch]
            masks = None
            if len(batch) == 6:
                imgs, objs, boxes, triples, obj_to_img, triple_to_img = batch
            elif len(batch) == 7:
                imgs, objs, boxes, masks, triples, obj_to_img, triple_to_img = batch
            elif len(batch) == 12:
                imgs, objs, boxes, triples, obj_to_img, triple_to_img, \
                objs_r, boxes_r, triples_r, obj_to_img_r, triple_to_img_r, imgs_in = batch
            elif len(batch) == 13:
                imgs, objs, boxes, triples, obj_to_img, triple_to_img, attributes, \
                objs_r, boxes_r, triples_r, obj_to_img_r, triple_to_img_r, imgs_in = batch
            else:
                assert False
            predicates = triples[:, 1]

            # #EVAL_ALL = True
            if EVAL_ALL:
                imgs, imgs_in, objs, boxes, triples, obj_to_img, \
                dropbox_indices, dropfeats_indices = process_batch(
                    imgs, imgs_in, objs, boxes, triples, obj_to_img, triple_to_img, device,
                    use_feats=use_feats, filter_box=filter_box)
            else:
                dropbox_indices = None
                dropfeats_indices = None
            #
            # if use_gt: # gt boxes
            #     model_out = model(objs, triples, obj_to_img, boxes_gt=boxes, masks_gt=masks, src_image=imgs_in,
            #                       drop_box_idx=None, drop_feat_idx=dropfeats_indices, mode='eval')
            # else:
            #     model_out = model(objs, triples, obj_to_img, boxes_gt=boxes, src_image=imgs_in,
            #                       drop_box_idx=dropbox_indices, drop_feats_idx=dropfeats_indices, mode='eval')

            masks_gt = None
            gt_train = False

            attributes = torch.zeros_like(attributes)

            all_features = None
            # Run the model with predicted masks
            model_out = model(imgs, objs, triples, obj_to_img, boxes_gt=boxes, masks_gt=masks_gt, attributes=attributes,
                              gt_train=gt_train, test_mode=False, use_gt_box=True, features=all_features
                              , drop_box_idx=dropbox_indices, drop_feat_idx= dropfeats_indices, src_image= imgs_in)
            #imgs_pred, boxes_pred, masks_pred, _, layout, _ = model_out

            # OUTPUT
            imgs_pred, boxes_pred, masks_pred, predicate_scores, layout, _ = model_out
            # --------------------------------------------------------------------------------------------------------------
            #imgs_pred *= 3
            #print(imgs_pred.min(), imgs_pred.max())

            # Save all box predictions
            all_boxes['boxes_gt'].append(boxes)
            all_boxes['objs'].append(objs)
            all_boxes['boxes_pred'].append(boxes_pred)
            all_boxes['drop_targets'].append(dropbox_indices)

            # IoU over all
            total_iou.append(jaccard(boxes_pred, boxes).cpu().numpy()) #.detach()
            total_boxes += boxes_pred.size(0)

            # IoU over targets only
            pred_dropbox = boxes_pred[dropbox_indices.squeeze() == 0, :]
            gt_dropbox = boxes[dropbox_indices.squeeze() == 0, :]
            roi_only_iou.append(jaccard(pred_dropbox, gt_dropbox).detach().cpu().numpy())
            rois += pred_dropbox.size(0)
            # assert(pred_dropbox.size(0) == imgs.size(0))

            num_samples += imgs.shape[0]
            imgs = imagenet_deprocess_batch(imgs).float()
            imgs_pred = imagenet_deprocess_batch(imgs_pred).float()

            # Uncomment to plot images (for debugging purposes)
            #visualize_imgs_boxes(imgs, imgs_pred, boxes, boxes)

            # MAE per image
            mae_per_image.append(torch.mean(
                torch.abs(imgs - imgs_pred).view(imgs.shape[0], -1), 1).cpu().numpy())

            for s in range(imgs.shape[0]):
                # get coordinates of target
                left, right, top, bottom = bbox_coordinates_with_margin(boxes[s, :], margin, imgs)
                # calculate errors only in RoI one by one - good, i wanted to check this too since the errors were suspicious pheww
                mae_roi_per_image.append(torch.mean(
                    torch.abs(imgs[s, :, top:bottom, left:right] - imgs_pred[s, :, top:bottom, left:right])).cpu().item())

                ssim_per_image.append(
                    pytorch_ssim.ssim(imgs[s:s+1, :, :, :] / 255.0,
                                      imgs_pred[s:s+1, :, :, :] / 255.0, window_size=3).cpu().item())
                ssim_rois.append(
                    pytorch_ssim.ssim(imgs[s:s+1, :, top:bottom, left:right] / 255.0,
                                      imgs_pred[s:s+1, :, top:bottom, left:right] / 255.0, window_size=3).cpu().item())

                imgs_pred_norm = imgs_pred[s:s+1, :, :, :] / 127.5 - 1 # = util.im2tensor(imgs_pred[s:s+1, :, :, :].detach().cpu().numpy())
                imgs_gt_norm = imgs[s:s+1, :, :, :] / 127.5 - 1  # util.im2tensor(imgs[s:s+1, :, :, :].detach().cpu().numpy())

                #perceptual_error_roi.append(lpips_model.forward(imgs_pred_norm[:,:, top:bottom, left:right],
                #                                                  imgs_gt_norm[:,:, top:bottom, left:right]))

                #print(imgs_pred_norm.shape)
                perceptual_error_image.append(
                    lpips_model.forward(imgs_pred_norm, imgs_gt_norm).detach().cpu().numpy())

            if num_batches % PRINT_EVERY == 0:
                calculate_scores(mae_per_image, mae_roi_per_image, total_iou, roi_only_iou, ssim_per_image, ssim_rois,
                                 perceptual_error_image, perceptual_error_roi)

            if num_batches % SAVE_EVERY == 0:
                save_results(mae_per_image, mae_roi_per_image, total_iou, roi_only_iou, ssim_per_image, ssim_rois,
                 perceptual_error_image, perceptual_error_roi, all_boxes, num_batches)

    # mean_losses = {k: np.mean(v) for k, v in all_losses.items()}

    save_results(mae_per_image, mae_roi_per_image, total_iou, roi_only_iou, ssim_per_image, ssim_rois,
                 perceptual_error_image, perceptual_error_roi, all_boxes, 'final')

    # masks_to_store = masks
    # if masks_to_store is not None:
    #     masks_to_store = masks_to_store.data.cpu().clone()

    # masks_pred_to_store = masks_pred
    # if masks_pred_to_store is not None:
    #     masks_pred_to_store = masks_pred_to_store.data.cpu().clone()

    # batch_data = {
    #     'objs': objs.detach().cpu().clone(),
    #     'boxes_gt': boxes.detach().cpu().clone(),
    #     'masks_gt': masks_to_store,
    #     'triples': triples.detach().cpu().clone(),
    #     'obj_to_img': obj_to_img.detach().cpu().clone(),
    #     'triple_to_img': triple_to_img.detach().cpu().clone(),
    #     'boxes_pred': boxes_pred.detach().cpu().clone(),
    #     'masks_pred': masks_pred_to_store
    # }
    # out = [mean_losses, samples, batch_data, avg_iou]
    # out = [mean_losses, mean_L1, avg_iou]

    return  # mae_per_image, mae_roi_per_image, total_iou, roi_only_iou

def calculate_scores(mae_per_image, mae_roi_per_image, total_iou, roi_only_iou, ssim_per_image, ssim_rois,
                     perceptual_image, perceptual_roi):

    mae_all = np.mean(np.hstack(mae_per_image), dtype=np.float64)
    mae_std = np.std(np.hstack(mae_per_image), dtype=np.float64)
    mae_roi = np.mean(mae_roi_per_image, dtype=np.float64)
    mae_roi_std = np.std(mae_roi_per_image, dtype=np.float64)
    iou_all = np.mean(np.hstack(total_iou), dtype=np.float64)
    iou_std = np.std(np.hstack(total_iou), dtype=np.float64)
    iou_roi = np.mean(np.hstack(roi_only_iou), dtype=np.float64)
    iou_roi_std = np.std(np.hstack(roi_only_iou), dtype=np.float64)
    ssim_all = np.mean(ssim_per_image, dtype=np.float64)
    ssim_std = np.std(ssim_per_image, dtype=np.float64)
    ssim_roi = np.mean(ssim_rois, dtype=np.float64)
    ssim_roi_std = np.std(ssim_rois, dtype=np.float64)
    # percept error -----------
    percept_all = np.mean(perceptual_image, dtype=np.float64)
    #print(perceptual_image, percept_all)
    percept_all_std = np.std(perceptual_image, dtype=np.float64)
    percept_roi = np.mean(perceptual_roi, dtype=np.float64)
    percept_roi_std = np.std(perceptual_roi, dtype=np.float64)
    # ------------------------

    print()
    print('MAE: Mean {:.6f}, Std {:.6f}'.format(mae_all, mae_std))
    print('MAE-RoI: Mean {:.6f}, Std {:.6f}: '.format(mae_roi, mae_roi_std))
    print('IoU: Mean {:.6f}, Std {:.6f}'.format(iou_all, iou_std))
    print('IoU-RoI: Mean {:.6f}, Std {:.6f}'.format(iou_roi, iou_roi_std))
    print('SSIM: Mean {:.6f}, Std {:.6f}'.format(ssim_all, ssim_std))
    print('SSIM-RoI: Mean {:.6f}, Std {:.6f}'.format(ssim_roi, ssim_roi_std))
    print('LPIPS: Mean {:.6f}, Std {:.6f}'.format(percept_all, percept_all_std))
    print('LPIPS-RoI: Mean {:.6f}, Std {:.6f}'.format(percept_roi, percept_roi_std))
    return

def save_results(mae_per_image, mae_roi_per_image, total_iou, roi_only_iou, ssim_per_image, ssim_rois,
                 perceptual_per_image, perceptual_rois, all_boxes, iter):

    results = dict()
    results['mae_per_image'] = mae_per_image
    results['mae_rois'] = mae_roi_per_image
    results['iou_per_image'] = total_iou
    results['iou_rois'] = roi_only_iou
    results['ssim_per_image'] = ssim_per_image
    results['ssim_rois'] = ssim_rois
    results['perceptual_per_image'] = perceptual_per_image
    results['perceptual_rois'] = perceptual_rois
    results['data'] = all_boxes

    with open(results_file.format(iter), 'wb') as p:
        pickle.dump(results, p)

def process_batch(imgs, imgs_in, objs, boxes, triples, obj_to_img, triples_to_img, device,
                  use_feats=True, filter_box=False):
    num_imgs = imgs.shape[0]
    imgs_stack = []
    imgs_in_stack = []
    boxes_stack = []
    objs_stack = []
    triples_stack = []
    obj_to_img_new = []
    candidates_stack = []
    previous_idx = 0

    for i in range(num_imgs):
        start_idx_for_img = (obj_to_img == i).nonzero()[0]
        last_idx_for_img = (obj_to_img == i).nonzero()[-1]
        boxes_i = boxes[start_idx_for_img: last_idx_for_img + 1, :]     # this includes the 'image' box!
        objs_i = objs[start_idx_for_img: last_idx_for_img + 1]

        start_idx_for_img = (triples_to_img == i).nonzero()[0]
        last_idx_for_img = (triples_to_img == i).nonzero()[-1]
        triples_i = triples[start_idx_for_img:last_idx_for_img + 1]

        num_boxes = boxes_i.shape[0]  # number of boxes in current image minus the 'image' box

        if filter_box:
            min_dim = 0.05  # about 3 pixels
            keep = [b for b in range(boxes_i.shape[0] - 1) if
                    boxes_i[b, 2] - boxes_i[b, 0] > min_dim and boxes_i[b, 3] - boxes_i[b, 1] > min_dim]
            print('Ignoring {} out of {} boxes'.format(boxes_i.shape[0] - len(keep), boxes_i.shape[0]))
            times_to_rep = len(keep)
            img_indices = torch.LongTensor(keep)
        else:
            times_to_rep = num_boxes - 1
            img_indices = torch.arange(0, times_to_rep)

        # boxes that will be dropped for each sample (always shift the index by one to get the next box)
        drop_indices = img_indices * (num_boxes + 1)

        # replicate things for current image
        imgs_stack.append(imgs[i, :, :, :].repeat(times_to_rep, 1, 1, 1))
        imgs_in_stack.append(imgs_in[i, :, :, :].repeat(times_to_rep, 1, 1, 1))
        objs_stack.append(objs_i.repeat(times_to_rep))     # replicate object ids #boxes times
        boxes_stack.append(boxes_i.repeat(times_to_rep, 1))   # replicate boxes #boxes times
        obj_to_img_new.append(img_indices.unsqueeze(1).repeat(1, num_boxes).view(-1) + previous_idx)
        previous_idx = obj_to_img_new[-1].max() + 1

        triplet_offsets = (num_boxes * img_indices.unsqueeze(1).repeat(1, triples_i.size(0)).view(-1)).cuda()
        triples_i = triples_i.repeat(times_to_rep, 1)
        triples_i[:, 0] = triples_i[:, 0] + triplet_offsets     # offset for replicated subjects
        triples_i[:, 2] = triples_i[:, 2] + triplet_offsets     # offset for replicated objects
        triples_stack.append(triples_i)

        # create index to drop for each sample
        candidates = torch.ones(boxes_stack[-1].shape[0], device=device)
        candidates[drop_indices] = 0     # set to zero the boxes that should be dropped
        candidates_stack.append(candidates)

    imgs = torch.cat(imgs_stack)
    imgs_in = torch.cat(imgs_in_stack)
    boxes = torch.cat(boxes_stack)
    objs = torch.cat(objs_stack)
    triples = torch.cat(triples_stack)
    obj_to_img_new = torch.cat(obj_to_img_new)
    candidates = torch.cat(candidates_stack).unsqueeze(1)

    if use_feats:
        feature_candidates = torch.ones((candidates.shape[0], 1), device=device)
    else:
        feature_candidates = candidates

    return imgs, imgs_in, objs, boxes, triples, obj_to_img_new, candidates, feature_candidates

def bbox_coordinates_with_margin(bbox, margin, img):
    # extract bounding box with a margin
    left = max(0, bbox[0] * img.shape[3] - margin)
    top = max(0, bbox[1] * img.shape[2] - margin)
    right = min(img.shape[3], bbox[2] * img.shape[3] + margin)
    bottom = min(img.shape[2], bbox[3] * img.shape[2] + margin)

    return int(left), int(right), int(top), int(bottom)

def visualize_imgs_boxes(imgs, imgs_pred, boxes, boxes_pred):

    nrows = imgs.size(0)
    imgs = imgs.detach().cpu().numpy()
    imgs_pred = imgs_pred.detach().cpu().numpy()
    boxes = boxes.detach().cpu().numpy()
    boxes_pred = boxes_pred.detach().cpu().numpy()
    plt.figure()

    for i in range(0, nrows):
        # i = j//2
        ax1 = plt.subplot(2, nrows, i+1)
        img = np.transpose(imgs[i, :, :, :], (1, 2, 0)) / 255.
        plt.imshow(img)

        left, right, top, bottom = bbox_coordinates_with_margin(boxes[i, :], 0, imgs[i:i+1, :, :, :])
        bbox_gt = patches.Rectangle((left, top),
                                    width=right-left,
                                    height=bottom-top,
                                    linewidth=1, edgecolor='r', facecolor='none')
        # Add the patch to the Axes
        ax1.add_patch(bbox_gt)
        plt.axis('off')

        ax2 = plt.subplot(2, nrows, i+nrows+1)
        pred = np.transpose(imgs_pred[i, :, :, :], (1, 2, 0)) / 255.
        plt.imshow(pred)

        left, right, top, bottom = bbox_coordinates_with_margin(boxes_pred[i, :], 0, imgs[i:i+1, :, :, :])
        bbox_pr = patches.Rectangle((left, top),
                                    width=right-left,
                                    height=bottom-top,
                                    linewidth=1, edgecolor='r', facecolor='none')
        # ax2.add_patch(bbox_gt)
        ax2.add_patch(bbox_pr)
        plt.axis('off')

    plt.show()

    return

if __name__ == '__main__':
    main()


import pygame

from configs import ColorConfig

class Button(object):

    def __init__(self, x_coordinate: int, y_coordinate: int, button_width: int,
                 button_height: int, text_font: str, text_size: str,
                 button_name: str, onclick_function=None):
        self.x = x_coordinate
        self.y = y_coordinate
        self.width = button_width
        self.height = button_height
        self.function_by_click = onclick_function
        self.buttonSurface = pygame.Surface((self.width, self.height))
        self.buttonRect = pygame.Rect(self.x, self.y, self.width, self.height)
        self.buttonSurf = pygame.font.SysFont(
            text_font, int(text_size)).render(button_name, True, (20, 20, 20))

    def process(self, game_window: pygame.display, parameter: str):
        self.buttonSurface.fill(ColorConfig.WHITE)
        if self.buttonRect.collidepoint(pygame.mouse.get_pos()):
            self.buttonSurface.fill(ColorConfig.GREY)
            if pygame.mouse.get_pressed(num_buttons=3)[0]:
                self.buttonSurface.fill(ColorConfig.GREEN)
                self.function_by_click(parameter)
                return True
        self.buttonSurface.blit(self.buttonSurf, [
            self.buttonRect.width / 2 - self.buttonSurf.get_rect().width / 2,
            self.buttonRect.height / 2 - self.buttonSurf.get_rect().height / 2
        ])
        game_window.blit(self.buttonSurface, self.buttonRect)


from django.urls import path
from . import views

app_name = "Employees"

urlpatterns = [
    path('profile', views.profile, name="profile"),
    path('edit_profile', views.editprofile, name="edit_profile"),
    path('check_employee', views.checkemployee, name="check_employee"),
    path('employee_position', views.employeeposition, name="employee_position"),
    path('modify_permissions', views.modifypermissions, name="modify_permissions"),
    path('access_requests', views.access_request, name="access_request"),
    path('access_requests_list', views.access_request_list, name="access_request_list"),
    ]