#!/usr/bin/env python
# coding: utf-8

# ### Preliminary Code

#Importing the necessary packages
import pandas as pd
import numpy as np
import plotly
import plotly.express as px
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout, RepeatVector, TimeDistributed, Flatten
from sklearn.model_selection import GridSearchCV
from keras.wrappers.scikit_learn import KerasRegressor, KerasClassifier
import matplotlib.pyplot as pltport

#Reading in the Pfizer stock price data
stock_prices = pd.read_csv('C:/Users/chink/Downloads/PFE.csv')
stock_prices

# This dataset includes dates ranging from June 1, 1972 to October 1st, 2021. It has 5 different stock prices for each date: "Open", "High", "Low", "Close", and "Adj Close". I will choose to use the adjusted closing price as this quantity accounts for any corporate actions that affect the closing price of the stock, such as stock splits or rights offerings.

#Visualizing prices
fig = px.line(stock_prices, x='Date', y='Adj Close',)
fig.update_layout(
    title="Pfizer Stock Price",
    xaxis_title="Date",
    yaxis_title="Adjusted Closing Price ($)")
fig.show()

#Checking for null entries in the "Date" column
if np.sum(stock_prices['Date'].isnull()) == 0:
    print("There are no null entries in the Date column")
else:
    print("There are null entries in the Date column")

#Checking for null entries in the "Adj Close" column
if np.sum(stock_prices['Date'].isnull()) == 0:
    print("There are no null entries in the Adj Close column")
else:
    print("There are null entries in the Adj Close column")

# ### Splitting and scaling the data

# To split the data, I will select a training and a test set. The test set is of course stock prices from the beginning January 2020 to the end September 2021. For the training set, I will select a subset of the data during which time I assume that there are almost zero anomalies. While there are many ways to construct this dataset, I will choose the decade of the 2010s as the training data, as this constitutes a large chunk of time and immediately precedes the test data.

#Creating the training set
start_Jan_2010_ind = stock_prices[stock_prices['Date'].str.contains('2010-01')].index[0]
end_Dec_2019_ind = stock_prices[stock_prices['Date'].str.contains('2019-12')].index[-1]
training_data = stock_prices.loc[start_Jan_2010_ind:end_Dec_2019_ind][['Date','Adj Close']]

# Just a small note: due to weekends and holidays, the beginning date for Jan 2010 isn't just '2010-01-01' and likewise the end date of 2019 isn't just '2019-12-31'; for this reason, I need to collect the indices corresponding to the start and end dates
# for the period of time spanning the training set

#Viewing the training set
training_data

#Creating the test set in a similar fashion
start_Jan_2020_ind = stock_prices[stock_prices['Date'].str.contains('2020-01')].index[0]
end_Sep_2021_ind = stock_prices[stock_prices['Date'].str.contains('2021-09')].index[-1]
test_data = stock_prices.loc[start_Jan_2020_ind:end_Sep_2021_ind][['Date','Adj Close']]

#Viewing the test data
test_data

#Scaling the data
scale = MinMaxScaler()
scale.fit(training_data[['Adj Close']])
train = training_data.copy()
test = test_data.copy()
train['Adj Close'] = scale.transform(training_data[['Adj Close']])
test['Adj Close'] = scale.transform(test_data[['Adj Close']])

# ### Creating the time-series sequences

#Creating a function to construct the sequences
def sequences(df,t_step):
    input_seq = []
    output_val = []
    for i in range(len(df)-t_step):
        sequence = df.iloc[i:i+t_step]['Adj Close'].values
        input_seq.append(sequence)
        val = df.iloc[i+t_step]['Adj Close']
        output_val.append(val)
    #input_seq = np.array(input_seq)
    newshape = (len(input_seq),30,1)
    input_seq = np.reshape(input_seq,newshape)
    input_seq = np.array(input_seq)
    output_val = np.array(output_val)
    return input_seq,output_val

#Creating the train sequences, predicted train stock prices, test sequences, and predicted test sequences
time_step = 60
train_sequences, train_sp = sequences(train,time_step)
test_sequences, test_sp = sequences(test,time_step)

#Confirming the shapes of the datasets are correct
print("Training sequence data shape: ",train_sequences.shape)
print('Training stock price data shape: ',train_sp.shape)
print('Testing sequence data shape: ',test_sequences.shape)
print('Testing stock price data shape: ',test_sp.shape)

#Setting a seed for reproducibility
np.random.seed(2021)
tf.random.set_seed(2021)

#Defining the model
def create_model(dropout_rate=0.15):
    model = Sequential()
    model.add(LSTM(100,activation = 'tanh', input_shape=(train_sequences.shape[1],train_sequences.shape[2])))
    model.add(Dropout(dropout_rate))
    model.add(RepeatVector(train_sequences.shape[1]))
    model.add(LSTM(100, activation = 'tanh', return_sequences=True))
    model.add(Dropout(dropout_rate))
    model.add(TimeDistributed(Dense(train_sequences.shape[2])))
    model.compile(optimizer='adam', loss='mae')
    return model

#Creating the model
model = KerasRegressor(build_fn=create_model,verbose=0)

#Defining the grid-search parameters
dropout_rate = [0.15,0.2,0.25,0.3]
batch_size_list=[25,50,75,100]
epochs_list=[100,150,200,250]

#Define the parameter grid
param_grid = dict(dropout_rate=dropout_rate,batch_size=batch_size_list,epochs=epochs_list)

#Grid-searching and tuning the hyperparamters
grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_result = grid.fit(train_sequences,train_sequences)

#Outputting the results to a file
file = open('C:/Users/chink/Downloads/GridSearchOutput.txt','w')
print(grid_result.best_score_,grid_result.best_params_)
a = "Best score: "+str(grid_result.best_score_,)+"\n"+"Best_params: "+str(grid_result.best_params_)
file.write(a)
file.close()


'''
author:mxt
desc:无算法应用，纯属Python暴力破解
time：2019/08/16
'''
import numpy as np

class Solution(object):
    @classmethod
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        new_list = nums1 + nums2
        new_list.sort()
        return np.median(new_list)
        # print(np.median(new_list))
        # # print(new_list)
        # if len(new_list) == 1:
        #     return new_list[0]
        # a, b = divmod(len(new_list), 2)
        # # print(a,b)
        # if not b:
        #     return (new_list[a - 1] + new_list[a]) / 2.0
        # return new_list[a]

if __name__ == '__main__':
    num1 = [1, 4]
    num2 = [2, 3]
    print(Solution.findMedianSortedArrays(num1, num2))


#!/usr/bin/env python3

from collections import OrderedDict
import torch
from torch import nn
from kanachan.training.constants import (
    NUM_TYPES_OF_ACTIONS, MAX_NUM_ACTION_CANDIDATES,)
from kanachan.training.bert.encoder import Encoder

class ValueDecoder(nn.Module):
    def __init__(
            self, *, dimension: int, dim_feedforward: int, activation_function: str, dropout: float,
            num_layers: int, device: torch.device, dtype: torch.dtype) -> None:
        if num_layers <= 0:
            raise ValueError(num_layers)

        super(ValueDecoder, self).__init__()

        layers = OrderedDict()
        for i in range(num_layers - 1):
            layers[f'layer{i}'] = nn.Linear(
                dimension if i == 0 else dim_feedforward, dim_feedforward,
                device=device, dtype=dtype)
            if activation_function == 'relu':
                layers[f'activation{i}'] = nn.ReLU()
            elif activation_function == 'gelu':
                layers[f'activation{i}'] = nn.GELU()
            else:
                raise ValueError(activation_function)
            layers[f'dropout{i}'] = nn.Dropout(p=dropout)
        layers[f'layer{num_layers - 1}'] = nn.Linear(
            dimension if num_layers == 1 else dim_feedforward, 1, device=device, dtype=dtype)
        self.layers = nn.Sequential(layers)

    def forward(self, candidates: torch.Tensor, encode: torch.Tensor) -> torch.Tensor:
        assert candidates.dim() == 2
        assert encode.dim() == 3
        assert candidates.size(0) == encode.size(0)

        mask = (candidates == NUM_TYPES_OF_ACTIONS)

        encode = encode[:, -MAX_NUM_ACTION_CANDIDATES:]
        value: torch.Tensor = self.layers(encode)
        value = torch.squeeze(value, dim=2)
        value = value[mask]
        assert value.dim() == 1
        assert value.size(0) == candidates.size(0)

        # Set `V` of the terminal state to `0.0`.
        value = torch.where(candidates[:, 0] != NUM_TYPES_OF_ACTIONS, value, 0.0)

        return value

class ValueModel(nn.Module):
    def __init__(self, encoder: Encoder, decoder: ValueDecoder) -> None:
        super(ValueModel, self).__init__()
        self.encoder = encoder
        self.decoder = decoder

    def forward(
            self, sparse: torch.Tensor, numeric: torch.Tensor, progression: torch.Tensor,
            candidates: torch.Tensor) -> torch.Tensor:
        encode = self.encoder(sparse, numeric, progression, candidates)
        prediction = self.decoder(candidates, encode)
        return prediction


import os
import logging
import yaml
import json

logger = logging.getLogger('taskn.utils')
__multi__ = 'thread'

if __multi__ == 'thread':
    logger.debug('using "threadpool" for the worker queue.')
    import threadpool

    def worker_pool(jobs, func, *args):
        p = threadpool.ThreadPool(len(jobs))
        for item in jobs:
            p.putRequest(threadpool.WorkRequest(func, args=[item] + [ i for i in args]))
        p.wait()

elif __multi__ == 'gevent':
    logger.debug('using "gevent" pools for the worker queue.')
    from  gevent.pool import Pool

    def worker_pool(jobs, func, *args):
        p = Pool(len(jobs))
        for item in jobs:
            p.spawn(func, item, *args)
        p.join()

def mkdir_if_needed(name, base):
    dir = os.path.join(base, name)
    if not os.path.exists(dir):
        os.makedirs(dir)

    return dir

def symlink(name, target):
    if not os.path.islink(name):
        try:
            os.symlink(target, name)
        except AttributeError:
            from win32file import CreateSymbolicLink
            CreateSymbolicLink(name, target)
        except ImportError:
            logger.critical('platform does not contain support for symlinks. Windows users need to pywin32.')
            exit(1)

def init_logging(logfile, debug=False):
    if debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        if logfile is None:
            logging.basicConfig(level=logging.CRITICAL)
        else:
            logging.basicConfig(level=logging.WARNING, filename=logfile)

def expand_tree(path, input_extension):
    file_list = []

    for root, subFolders, files in os.walk(path):
        for file in files:
            f = os.path.join(root, file)

            if os.path.islink(f):
                continue
            elif f.endswith(input_extension):
                file_list.append(f)

    return file_list

def create_notes_dir(dir, strict):
    if not os.path.exists(dir):
        if not strict:
            logger.info("{0} notes directory doesn't exist. creating now.".format(dir))
            os.makedirs(dir)
        else:
            logger.critical('notes directory, "{0}" does not exist.'
                            'Create or restart without strict mode.'.format(dir))
            exit(1)

def dump_yaml(data):
    return yaml.safe_dump_all(data, default_flow_style=False, indent=3,
                         line_break=True) + '...'

def dump_json(data):
    return json.dumps(data, indent=3)


"""
https://stepik.org/lesson/236918/step/3?unit=209305
Метки можно комбинировать использую логический операторы

pytest -s -v -m "not smoke" test_fixture8.py - запустятся все кроме smoke

pytest -s -v -m "smoke or regression" test_fixture8.py - запустятся и smoke и regression

pytest -s -v -m "smoke and win10" test_fixture81.py - запустятся только промаркированные двумя метками
"""
import pytest
from selenium import webdriver

link = "http://selenium1py.pythonanywhere.com/"

@pytest.fixture
def browser():
    print("\nЗапускаем бразуер..")
    browser = webdriver.Chrome()
    yield browser
    print("\nЗакрываем браузер..")
    browser.quit()

class TestMainPage1:

    @pytest.mark.smoke
    def test_guest_should_see_login_link(self, browser):
        # не передаём как параметр фикстуру prepare_data, но она все равно выполняется
        browser.get(link)
        browser.find_element_by_css_selector("#login_link")

    @pytest.mark.smoke
    @pytest.mark.win10
    def test_guest_should_see_basket_link_on_the_main_page(self, browser):
        browser.get(link)
        browser.find_element_by_css_selector(".basket-mini .btn-group > a")


s = input("Enter:")
l = len(s)
integ = []
integ2 = []
i = 0

while i < l:
    s_int = ''
    a = s[i]
    while '0' <= a <= '9':
        s_int += a
        i += 1
        if i < l:
            a = s[i]
        else:
            break
    i += 1
    if s_int != '':
        integ.append(int(s_int))
print("Only numbers:",integ)

largest_number = max(integ)
print("Max=",largest_number)

for i in range(len(integ)):
    if integ[i] != largest_number:
        integ2.append(integ[i]**i)
print("The numbers are raised to the power of them index:",integ2)

for d in '1234567890':
    s=s.replace(d, '')
s.strip(' ')
while s.find('  ') != -1:
    s = s.replace('  ', ' ')
print("Characters only:",s)
def big(s):
 r=""
 z=0
 spl=str(s).split()
 for i in spl:
    for i in spl[z].split():
        a=''.join(spl[z])
        if len(a)==1:
                r=r+a[0].upper()+' '
        else:
                r=r+a[0].upper()+a[1:-1]+a[-1].upper()+' '
        z=z+1
 return r
print("Each word begins and ends with a capital letter:",big(s))


import os
import pickle
import numpy as np
import configparser
from tab_shap import SHAPAnalysis
import argparse

def read_config_file(file_path):
    """Parse a config file and return a configparser.ConfigParser object."""

    # Check if the file exists
    if not os.path.isfile(file_path):
        raise FileNotFoundError(f"{file_path} does not exist")

    # Instantiate a ConfigParser object and read the config file
    config = configparser.ConfigParser()
    config.read(file_path)

    return config

def load_data(file_path):
    """Load a data file and return its content."""

    # Check if the file exists
    if not os.path.isfile(file_path):
        raise FileNotFoundError(f"{file_path} does not exist")

    # Load the file content
    data = np.load(file_path)

    return data

def main(config_path):
    """Main function to load model, test data, compute and plot SHAP values."""

    # Read and parse the config file
    config = read_config_file(config_path)

    # Extract values from the config file
    # The .get() method provides a way to specify a default value in case the key is not present
    model_filename = config.get("DEFAULT", "model_filename", fallback=None)
    test_data_preprocess = config.get("DEFAULT", "test_data_preprocess", fallback=None)
    save_dir_for_plots = config.get("DEFAULT", "save_dir_for_plots", fallback=None)
    local_plt_indices_list = [int(x) for x in config.get("DEFAULT", "local_plt_indices_list", fallback="").split(",")]
    top_n_dependence_plots = int(config.get("DEFAULT", "top_n_dependence_plots", fallback=0))
    top_n_dependence_interactions = int(config.get("DEFAULT", "top_n_dependence_interactions", fallback=0))
    feature_names = config.get("DEFAULT", "feature_names", fallback=0).split(",")

    # Load the trained model
    model = pickle.load(open(model_filename, 'rb'))

    # Load the test data
    test_data = load_data(test_data_preprocess)

    # check if the dimension match between the feature names and the data
    if len(feature_names) != np.squeeze(test_data).shape[-1]:
        feature_names = None

    # Initialize SHAPAnalysis with the trained model and compute SHAP values
    shap_analysis_svm = SHAPAnalysis(model, save_dir_for_plots, feature_names=feature_names)
    shap_analysis_svm.compute(test_data)

    # Generate and save plots

    shap_analysis_svm.global_summary_plot()
    shap_analysis_svm.local_plot(local_plt_indices_list)
    shap_analysis_svm.shap_dependence_plot(top_n_dependence_plots, no_of_interactions=top_n_dependence_interactions)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Process config file path.')
    parser.add_argument('config_path', type=str, help='Path to the configuration file.')
    args = parser.parse_args()
    main(args.config_path)


from setuptools import setup, find_packages
from subprocess import check_output
from pathlib import Path
import os
from importlib.util import module_from_spec, spec_from_file_location

NAME="AISTool"
CWD = Path(__file__).parent
requirements_file = CWD / "requirements.txt"
readme_file = CWD / "README.md"
# Get requirements
with requirements_file.open(encoding="utf-8") as f:
    REQUIREMENTS = f.read().splitlines()

# Get the long description from the README file
with readme_file.open(encoding="utf-8") as f:
    long_description = f.read()

CLASSIFIERS = """
Development Status :: 3 - Alpha
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
""".strip().splitlines()

def get_version_and_cmdclass(pkg_path):
    spec = spec_from_file_location("version", os.path.join(pkg_path, "_version.py"))
    module = module_from_spec(spec)
    spec.loader.exec_module(module)
    return module.__version__, module.get_cmdclass(pkg_path)

version, cmdclass = get_version_and_cmdclass(r".")

setup(
    name=f"{NAME}",
    version=version,
    cmdclass=cmdclass,
    description="Generate ssh config file from Ansible inventory",
    long_description=long_description,
    long_description_content_type="text/markdown",
    author="Jani Mikkonen",
    author_email="jani.mikkonen@gmail.com",
    url="https://github.com/rasjani/AISTool",
    license="MIT",
    classifiers=CLASSIFIERS,
    packages=[NAME],
    entry_points={
        'console_scripts': [
            f'{NAME}=AISTool.main:main'
        ],
    },
    install_requires=REQUIREMENTS,
    python_requires=">=3.7"
)


def elements_in_str(user_str):
    """
    :param user_str: Входная строка пользователя
    :return: Генерирует каждое слово (i) из строки пользователя (user_str)
    """
    for i in user_str.split():
        yield i

if __name__ == '__main__':
    user_str = "i am generating words from text"
    element = elements_in_str(user_str)
    for i in element:
        print(i)


from socket import socket
from threading import Thread
from router import *
import time

class Server:
    def __init__(self):
        self.router = Router(Constant.map_file)

    def start(self):
        with socket() as welcoming_socket:
            welcoming_socket.bind(('', 8000))
            welcoming_socket.listen()
            print("waiting for someone to connect...")
            while True:
                client_socket, address = welcoming_socket.accept()
                Thread(target=self.client_handler, args=(client_socket,)).start()

    def client_handler(self, sock: socket):
        sock.send(Constant.map_file.encode('ascii'))
        try:
            while True:
                data, _ = sock.recvfrom(2048)
                data = data.decode("ascii")
                print(data)
                first_vertice, second_vertice = data.split()
                roads = self.router.find_shortest_path(int(first_vertice), int(second_vertice))
                strings = [str(road) for road in roads]
                sock.send(" ".join(strings).encode("ascii"))
                time.sleep(1)
        except Exception:
            pass

s = Server()
s.start()


"""
一个长度为n-1的递增排序数组中的所有数字都是唯一的，并且每个数字都在范围0～n-1之内。
在范围0～n-1内的n个数字中有且只有一个数字不在该数组中，请找出这个数字。

示例 1:
输入: [0,1,3]
输出: 2

示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8

限制：
1 <= 数组长度 <= 10000

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""

from typing import List
import sure

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        i = 0

        for i in range(0, len(nums)):
            if nums[i] != i:
                return i
            i += 1

        return i

    def missingNumberBinary(self, nums: List[int]) -> int:
        l = 0
        r = len(nums) - 1

        while l <= r:
            m = (l + r) // 2
            if m != nums[m]:
                r = m - 1
            else:  # m == nums[m]
                l = m + 1

        return l

solution = Solution()
solution.missingNumberBinary([0, 1]).should.equal(2)
solution.missingNumberBinary([0]).should.equal(1)
solution.missingNumberBinary([0, 1, 3]).should.equal(2)
solution.missingNumberBinary([0, 1, 2, 3, 4, 5, 6, 7, 9]).should.equal(8)
solution.missingNumberBinary([1, 2, 3]).should.equal(0)


#!/usr/bin/env python3

from models import (User, List, Task, Category)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from rich.console import Console
from rich.table import Table as TB
import inquirer

class Menu:

    all = []
    currentIndex = 0

    def __init__(self, menu_dict):

        self.menu_dict = menu_dict
        self.questions = [
            inquirer.List("functions", message="Select an option", choices = self.menu_dict.keys())
        ]

        Menu.all.append(self)

    def loop(self):
        Menu.currentIndex = Menu.all.index(self)
        print(f"\n{33*'='}")
        answers = inquirer.prompt(self.questions)
        print(f"{33*'='}\n")
        self.menu_dict.get(answers['functions'])()

class app:

    def __init__(self):

        self.selected_user = None
        self.selected_list = None
        self.selected_task = None
        self.selected_category = None

    def create_menus(self):

        self.main_menu = Menu({
            self.make_user.__name__: self.make_user,
            self.fetch_user.__name__: self.fetch_user,
            self.delete_user.__name__: self.delete_user,
            self.exit.__name__: self.exit})

        self.user_menu = Menu(
            {self.select_list.__name__: self.select_list,
             self.make_list.__name__: self.make_list,
             self.delete_list.__name__:self.delete_list,
             self.make_category.__name__:self.make_category,
             self.back.__name__: self.back})

        self.list_menu = Menu({
            self.select_task.__name__: self.select_task,
            self.make_task.__name__: self.make_task,
            self.delete_task.__name__: self.delete_task,
            self.show_by_category.__name__: self.show_by_category,
            self.back.__name__: self.back})

        self.task_menu = Menu({
            self.change_status.__name__: self.change_status,
            self.change_task_description.__name__: self.change_task_description,
            self.back.__name__: self.back})

    def save_to_db(self, save_object):
        session.add(save_object)
        session.commit()

    def delete_from_db(self, delete_obj):
        session.delete(delete_obj)
        session.commit()

    def run_app(self):

        self.main_menu.loop()

    def back(self):

        return_functions = {
            1: self.main_loop,
            2: self.user_loop,
            3: self.list_loop,
            4: self.task_loop
            }

        return_functions.get(Menu.currentIndex)()

    def print_console(self, table):

        console = Console()
        print('\n')
        console.print(table)

    def exit(self):

        return 1

    def main_loop(self):

        self.main_menu.loop()

    def user_loop(self):

        self.print_console(self.selected_user.__repr__())
        self.user_menu.loop()

    def list_loop(self):

        self.print_console(self.selected_list.__repr__())
        self.list_menu.loop()

    def task_loop(self):

        self.print_console(self.selected_task.__repr__())
        self.task_menu.loop()

    def fetch_user(self):

        f_name = input("Enter first name: ")
        l_name = input("Enter last name: ")
        self.selected_user = session.query(User).filter(User.first_name == f_name and User.last_name == l_name).first()

        if (self.selected_user):

            self.user_loop()

        else:

            print("User not found.")
            self.main_menu.loop()

    def select_list(self):

        self.print_console(self.selected_user.__repr__())
        list_name = input("Select List: ")
        self.selected_list = session.query(List).filter(List.name == list_name).first()

        if self.selected_list:

            self.list_loop()

        else:

            print("List not found")
            self.user_menu.loop()

    def select_task(self):

        self.print_console(self.selected_list.__repr__())

        task_description = input("Select Task: ")
        self.selected_task = session.query(Task).filter(Task.description == task_description).first()

        if self.selected_task:

            self.task_loop()

        else:

            print("Task not found")
            self.list_loop()

    def make_user(self):

        f_name = input("Enter first name: ")
        l_name = input("Enter last name: ")

        new_user = User(first_name = f_name, last_name = l_name)
        self.save_to_db(new_user)
        self.selected_user = new_user

        if self.selected_user:
            self.user_loop()

    def make_list(self):

        list_name = input("Enter List name: ")
        new_list = List(name = list_name, user_id = self.selected_user.id)

        if new_list:

            self.save_to_db(new_list)
            self.selected_list = new_list
            self.list_loop()

    def make_category(self):

        new_title = input("Enter input: ")

        if new_title:

            new_cat = Category(title=new_title)
            self.save_to_db(new_cat)

        else:

            print("Category can't be empty!")

        self.user_loop()

    def make_task(self):

        task_description = input("Enter task: ")

        if task_description:

            new_task = Task(description = task_description, list_id = self.selected_list.id)
            categories = session.query(Category).all()

            cat_list = [inquirer.Checkbox("Categories", message="Select Category", choices = [cat.title for cat in categories])]
            answers = inquirer.prompt(cat_list)
            self.selected_category = answers["Categories"]
            new_task.categories = session.query(Category).filter(Category.title.in_(answers["Categories"])).all()
            self.save_to_db(new_task)

        else:

            print("Task description must be non-empty string!")

        self.list_loop()

    def delete_user(self):

        f_name = input("Enter user name to be deleted: ")
        user_id = int(input("Enter user id to be deleted: "))

        if f_name and user_id and type(user_id) == int:

            delete_user = session.query(User).filter(User.id == user_id and User.first_name == f_name).first()
            self.delete_from_db(delete_user)

        else:

            print("Invalid name or id.")

        self.main_loop()

    def delete_list(self):

        self.print_console(self.selected_user.__repr__())
        list_name = input("Enter list to be deleted: ")
        list_id = int(input("Enter list id: "))
        delete_list = session.query(List).filter(List.name == list_name and List.id == list_id).first()
        self.delete_from_db(delete_list)
        self.user_loop()

    def delete_task(self):

        self.print_console(self.selected_list.__repr__())

        task_id = int(input("Enter task id to be deleted: "))

        if task_id:
            delete_task = session.query(Task).filter(Task.id == task_id).first()
            self.delete_from_db(delete_task)

        else:
            print("Invalid task description!")

        self.list_loop()

    def change_status(self):

        change_options = [inquirer.List("choices", message="Select incomplete or complete", choices=["Incomplete", "Complete"])]
        answer = inquirer.prompt(change_options)
        fetch_task = session.query(Task).filter(Task.id == self.selected_task.id).first()
        fetch_task.complete = 0 if answer["choices"] == "Incomplete" else 1
        session.commit()
        self.task_loop()

    def change_task_description(self):

        self.print_console(self.selected_task.__repr__())
        new_description = input("Enter new description: ")
        fetch_task = session.query(Task).filter(Task.id == self.selected_task.id).first()
        fetch_task.description = new_description
        session.commit()
        self.selected_task = session.query(Task).filter(Task.id == self.selected_task.id).first()
        self.task_loop()

    def show_by_category(self):

        choices = [inquirer.List("choices", message="Select a Category", choices=[cat.title for cat in session.query(Category).all()])]
        answer = inquirer.prompt(choices)
        tasks = session.query(Task).filter(Task.list_id == self.selected_list.id and Task.categories.in_(answer["choices"]))
        task_table = TB(title = "Task by Category")
        task_table.add_column("id")
        task_table.add_column("Category")
        task_table.add_column("Task")

        for task in tasks:
            task_table.add_row(f"{task.id}", answer["choices"], task.description)

        self.print_console(task_table)
        self.list_loop()

if __name__ == '__main__':

    engine = create_engine('sqlite:///todo.db')
    Session = sessionmaker(bind=engine)
    session = Session()

    my_app = app()
    my_app.create_menus()
    my_app.run_app()


from urls import routes
from views import NotFound
from datetime import date

def date_today(request):
    request['date'] = date.today()

fronts = [date_today]

class Application:
    def __init__(self, routes, fronts):
        self.routes = routes
        self.fronts = fronts

    def __call__(self, environ, answer):
        path = environ['PATH_INFO']
        print(environ['PATH_INFO'])
        if not path.endswith('/'):
            path = f'{path}/'
        if path in routes:
            view = self.routes[path]
        else:
            view = NotFound()
        request = {}
        for front in self.fronts:
            front(request)
        head, body = view(request)
        answer(head, [('Content-Type', 'text/html')])
        return [body.encode('utf-8')]


import pathlib
import matplotlib.pyplot as plt
import numpy as np
import PIL
import os
import keras
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from keras.models import Sequential
from tensorflow import keras
from keras.utils import get_file
dataset_dir=pathlib.Path("dataset/Priora_data/")

sound_count = len(list(dataset_dir.glob("*/*.wav")))
print(f"Всего файлов: {sound_count}")
batch_size=32
train_ds = tf.keras.utils.audio_dataset_from_directory(
    dataset_dir,
	validation_split = 0.3,
	subset = "training",
	seed = 123,
	batch_size = batch_size
)

validation_ds = tf.keras.utils.audio_dataset_from_directory(
    dataset_dir,
	validation_split = 0.3,
	subset = "validation",
	seed = 123,
	batch_size = batch_size
)
class_names = train_ds.class_names
print(f"Class names: {class_names}")
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
validation_ds = validation_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)

input_shape1=(32,44100,2)
model = keras.models.Sequential()

# Добавьте слои для обработки аудиоданных
# Например, можно использовать сверточные и рекуррентные слои
model.add(keras.layers.Conv2D(16, (1, 100), activation='relu', input_shape=input_shape1))
model.add(keras.layers.MaxPooling2D((4, 4)))
model.add(keras.layers.Conv2D(64, (1, 100), activation='relu'))
model.add(keras.layers.MaxPooling2D((2, 2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(64,input_shape=(input_shape1,) ,activation='relu'))

# Добавьте выходной слой для классификации (зависит от задачи)
# Например, для задачи классификации звуковых классов
num_classes = 10
model.add(keras.layers.Dense(num_classes, activation='softmax'))

model.compile(
	optimizer='adam',
	loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
	metrics=['accuracy'])
model.summary()


import math
import numpy as np
import PIL.Image
import torch
from dextr.data_pipeline import affine

def _choose_item(items, rng):
    """
    Randomly choose an item from the array items

    :param items: items as a NumPy array of shape `(N, ...)`
    :param rng: RNG used for choosing item
    :return: an item from `items`
    """
    if len(items) == 1:
        return items[0]
    else:
        i = rng.randint(0, len(items))
        return items[i]

def _select_extreme(mask, extreme_range, rng):
    """
    Randomly select a pixel in the mask that has a non-zero value and return its co-ordinates,
    with an offset added.

    :param mask: mask as a NumPy array of shape `(H, W)`
    :param extreme_range: range to randomly search
    :return: `(y, x)` co-ordinates of the chosen pixel, with offset applied
    """
    m_y, m_x = np.where(mask)
    m_yx = np.stack([m_y, m_x], axis=1)

    top_filter = m_y <= (m_y.min() + extreme_range)
    bottom_filter = m_y >= (m_y.max() - extreme_range)
    left_filter = m_x <= (m_x.min() + extreme_range)
    right_filter = m_x >= (m_x.max() - extreme_range)
    top_extreme = _choose_item(m_yx[top_filter], rng)
    bottom_extreme = _choose_item(m_yx[bottom_filter], rng)
    left_extreme = _choose_item(m_yx[left_filter], rng)
    right_extreme = _choose_item(m_yx[right_filter], rng)

    return np.stack([top_extreme, bottom_extreme, left_extreme, right_extreme], axis=0)

def _gaussian_kernels(size, sigma, centres):
    """
    Compute gaussian kernels in PyTorch

    :param size: size of the kernel 'image'
    :param sigma: Gaussian sigma
    :param centres: the location of the centres of the blobs as a `(N,)` Torch tensor
    :param torch_device: Torch device to use

    :return: NumPy array tensor of shape `(N, size,)`
    """
    x = np.arange(size, dtype=float)
    return np.exp(-0.5 * (x - centres[..., None]) ** 2 / sigma ** 2)

class DextrTrainingTransform (object):
    def __init__(self, target_size_yx, padding, extreme_range, noise_std=1.0, blob_sigma=10.0,
                 hflip=True, rot_range=math.radians(20.0), fix_box_to_extreme=True, rng=None):
        self.target_size_yx = target_size_yx
        self.hflip = hflip
        self.rot_range = rot_range
        self.padding = padding
        self.extreme_range = extreme_range
        self.noise_std = noise_std
        self.blob_sigma = blob_sigma
        self.target_size_xy = np.array(target_size_yx[::-1]).astype(float)
        self.target_size_nopad_xy = self.target_size_xy - self.padding * 2
        self.fix_box_to_extreme = fix_box_to_extreme
        self.__rng = rng

    @property
    def rng(self):
        if self.__rng is None:
            self.__rng = np.random.RandomState()
        return self.__rng

    def __call__(self, sample):
        mask_pil = sample['target_mask']
        mask = np.array(mask_pil)
        outline_yx = sample['target_mask_outline'] + 0.5
        image_size = mask.shape[:2]

        rng = self.rng

        # Horizontal flip
        flip_flags = (rng.binomial(1, 0.5, size=(1, 3)) * np.array([1, 0, 0])) != 0
        flip_xf = affine.flip_xyd_matrices(flip_flags, image_size)

        # Rotation
        theta = rng.uniform(-self.rot_range, self.rot_range)
        rot_xf = affine.rotation_matrices([theta])

        # Apply flip and rotation to hull points
        rot_flip_xf = affine.cat_nx2x3(rot_xf, flip_xf)
        outline_rotflip_xy = affine.transform_points(rot_flip_xf[0], outline_yx[:, ::-1])
        outline_rotflip_xy_min = np.floor(outline_rotflip_xy.min(axis=0)).astype(int)
        outline_rotflip_xy_max = np.ceil(outline_rotflip_xy.max(axis=0)).astype(int)
        outline_rotflip_xy_size = outline_rotflip_xy_max - outline_rotflip_xy_min

        if self.fix_box_to_extreme:
            # Scale to target size
            scale = self.target_size_xy / outline_rotflip_xy_size.astype(float)
            scale_xf = affine.scale_matrices(scale[None, :])

            # Compose transformation from:
            # flip, rotate, top-left corner, scale
            extreme_xf = affine.cat_nx2x3(
                scale_xf,
                affine.translation_matrices(-outline_rotflip_xy_min[None, :]),
                rot_xf, flip_xf)
            extreme_xf_pil = affine.inv_nx2x3(extreme_xf)

            # Transform mask
            mask_extreme_pil = mask_pil.transform(
                self.target_size_yx[::-1], PIL.Image.AFFINE, tuple(extreme_xf_pil.flatten().tolist()),
                resample=PIL.Image.NEAREST)
            mask_extreme = np.array(mask_extreme_pil) > 127

            # Select extreme points
            extreme_points = _select_extreme(mask_extreme, self.extreme_range, rng)
            extreme_points = extreme_points + rng.normal(size=extreme_points.shape) * self.noise_std

            # Compute the bounding box given the points
            points_lower_yx = extreme_points.min(axis=0)
            points_upper_yx = extreme_points.max(axis=0)
            points_size_yx = points_upper_yx - points_lower_yx

            # Scale points so that their bounds fit the target size minus padding
            points_frac_yx = (extreme_points - points_lower_yx) / np.maximum(points_size_yx, 1.0)
            final_points_yx = points_frac_yx * self.target_size_nopad_xy[::-1] + self.padding

            # Final DEXTR transform:
            # - existing extreme points transform
            # - move top left corner of extreme points to [0,0]
            # - scale bounds of extreme points to the target size minus padding
            # - padding (translation)
            points_scale_xy = self.target_size_nopad_xy / np.maximum(points_size_yx, 1.0)[::-1]
            dextr_xf = affine.cat_nx2x3(
                affine.translation_matrices(np.array([[self.padding, self.padding]])),
                affine.scale_matrices(points_scale_xy[None, ...]),
                affine.translation_matrices(-points_lower_yx[::-1][None, ...]),
                extreme_xf,
            )
            dextr_xf_pil = affine.inv_nx2x3(dextr_xf)

            # Create blobs
            gauss_y = _gaussian_kernels(self.target_size_yx[0], self.blob_sigma, final_points_yx[:, 0])
            gauss_x = _gaussian_kernels(self.target_size_yx[1], self.blob_sigma, final_points_yx[:, 1])
            heatmap = (gauss_y[:, :, None] * gauss_x[:, None, :]).max(axis=0)

            input_dextr_pil = sample['input'].transform(
                self.target_size_yx[::-1], PIL.Image.AFFINE, tuple(dextr_xf_pil.flatten().tolist()),
                resample=PIL.Image.BILINEAR)
            mask_dextr_pil = mask_pil.transform(
                self.target_size_yx[::-1], PIL.Image.AFFINE, tuple(dextr_xf_pil.flatten().tolist()),
                resample=PIL.Image.BILINEAR)

            return dict(input=input_dextr_pil, target_mask=mask_dextr_pil, heatmap=heatmap)
        else:
            # Scale to target size, accounting for padding
            scale = self.target_size_nopad_xy / outline_rotflip_xy_size.astype(float)
            scale_xf = affine.scale_matrices(scale[None, :])

            # Compose transformation from:
            # flip, rotate, top-left corner, scale, pad
            dextr_xf = affine.cat_nx2x3(
                affine.translation_matrices(np.array([[self.padding, self.padding]])),
                scale_xf,
                affine.translation_matrices(-outline_rotflip_xy_min[None, :]),
                rot_xf, flip_xf)
            dextr_xf_pil = affine.inv_nx2x3(dextr_xf)

            # Transform mask
            mask_dextr_pil = mask_pil.transform(
                self.target_size_yx[::-1], PIL.Image.AFFINE, tuple(dextr_xf_pil.flatten().tolist()),
                resample=PIL.Image.BILINEAR)
            mask_extreme = np.array(mask_dextr_pil) > 127

            # Select extreme points, within
            extreme_points = _select_extreme(mask_extreme, self.extreme_range, rng)
            extreme_points = extreme_points + rng.normal(size=extreme_points.shape) * self.noise_std

            # Create blobs
            gauss_y = _gaussian_kernels(self.target_size_yx[0], self.blob_sigma, extreme_points[:, 0])
            gauss_x = _gaussian_kernels(self.target_size_yx[1], self.blob_sigma, extreme_points[:, 1])
            heatmap = (gauss_y[:, :, None] * gauss_x[:, None, :]).max(axis=0)

            input_dextr_pil = sample['input'].transform(
                self.target_size_yx[::-1], PIL.Image.AFFINE, tuple(dextr_xf_pil.flatten().tolist()),
                resample=PIL.Image.BILINEAR)

            return dict(input=input_dextr_pil, target_mask=mask_dextr_pil, heatmap=heatmap)

class DextrFindExtremesTransform (object):
    def __init__(self, target_size_yx, extreme_range, rng=None):
        self.target_size_yx = target_size_yx
        self.extreme_range = extreme_range
        self.__rng = rng

    @property
    def rng(self):
        if self.__rng is None:
            self.__rng = np.random.RandomState()
        return self.__rng

    def __call__(self, sample):
        outline_yx = sample['target_mask_outline'] + 0.5

        rng = self.rng

        # Apply flip and rotation to hull points
        outline_yx_min = np.floor(outline_yx.min(axis=0))
        outline_yx_max = np.ceil(outline_yx.max(axis=0))

        # Transform mask
        mask_extreme_pil = sample['target_mask'].transform(
            self.target_size_yx[::-1], method=PIL.Image.EXTENT,
            data=(outline_yx_min[1], outline_yx_min[0], outline_yx_max[1], outline_yx_max[0]),
            resample=PIL.Image.NEAREST
        )
        mask_extreme = np.array(mask_extreme_pil) > 127

        # Select extreme points
        extreme_points_in_tgt = _select_extreme(mask_extreme, self.extreme_range, rng)
        extreme_points_frac = extreme_points_in_tgt / np.array(self.target_size_yx)

        extreme_points = outline_yx_min + extreme_points_frac * (outline_yx_max - outline_yx_min)

        return dict(input=sample['input'], target_mask=sample['target_mask'],
                    target_mask_outline=sample['target_mask_outline'], extreme_points=extreme_points)

def crop_with_heatmap(input_image, target_mask, target_size_yx, padding, extreme_points, blob_sigma):
    """
    Crop the input image (and optionally target mask) to a region surrounding the extreme points
    and create a corresponding heat map with gaussian blobs centred on the extreme points.

    :param input_image: input image as a `PIL.Image`
    :param target_mask: [optional] target mask as a `PIL.Image`
    :param target_size_yx: target crop size
    :param padding: padding in target crop space that lies between the extreme points and the closest
        edge of the target crop
    :param extreme_points: extreme points as a `(4, [y, x])` NumPy array
    :param blob_sigma: Gaussian blob sigma size
    :return: `(cropped_input, cropped_mask, heatmap, crop_yx)` where:
        cropped_input is the crop taken from the input image, scaled to `target_size_yx`, as a PIL.Image
        cropped_mask is the crop taken from the target mask image, scaled to `target_size_yx` as a PIL.Image,
            or None if target_mask is None
        heatmap is the heat map as a 2D NumPy array
        crop_yx the crop region taken from the input and mask images as a `[[lower_y, lower_x], [upper_y, upper_x]]`
            NumPy array
    """
    target_size_nopad_yx = np.array(target_size_yx) - padding * 2
    rel_padding_yx = padding / target_size_nopad_yx

    # Compute the bounding box given the points
    points_lower_yx = extreme_points.min(axis=0)
    points_upper_yx = extreme_points.max(axis=0)
    points_size_yx = points_upper_yx - points_lower_yx
    crop_lower_yx = points_lower_yx - points_size_yx * rel_padding_yx
    crop_upper_yx = points_upper_yx + points_size_yx * rel_padding_yx
    crop_size_yx = crop_upper_yx - crop_lower_yx

    # Scale points so that their bounds fit the target size minus padding
    points_frac_yx = (extreme_points - crop_lower_yx) / np.maximum(crop_size_yx, 1.0)
    points_tgt_yx = points_frac_yx * np.array(target_size_yx)

    # Create blobs
    gauss_y = _gaussian_kernels(target_size_yx[0], blob_sigma, points_tgt_yx[:, 0])
    gauss_x = _gaussian_kernels(target_size_yx[1], blob_sigma, points_tgt_yx[:, 1])
    heatmap = (gauss_y[:, :, None] * gauss_x[:, None, :]).sum(axis=0)

    input_dextr_pil = input_image.transform(
        target_size_yx[::-1], method=PIL.Image.EXTENT,
        data=(int(crop_lower_yx[1]), int(crop_lower_yx[0]), int(crop_upper_yx[1]), int(crop_upper_yx[0])),
        resample=PIL.Image.BILINEAR)

    crop_yx = np.stack([crop_lower_yx, crop_upper_yx], axis=0)

    if target_mask is not None:
        mask_dextr_pil = target_mask.transform(
            target_size_yx[::-1], method=PIL.Image.EXTENT,
            data=(crop_lower_yx[1], crop_lower_yx[0], crop_upper_yx[1], crop_upper_yx[0]),
            resample=PIL.Image.BILINEAR)
    else:
        mask_dextr_pil = None

    return input_dextr_pil, mask_dextr_pil, heatmap, crop_yx

class DextrCropWithHeatmapTransform (object):
    def __init__(self, target_size_yx, padding, blob_sigma=10.0, keep_original_mask=False):
        self.padding = padding
        self.blob_sigma = blob_sigma
        self.keep_original_mask = keep_original_mask
        self.target_size_yx = target_size_yx
        self.target_size_nopad_yx = np.array(target_size_yx) - self.padding * 2
        self._rel_padding_yx = padding / self.target_size_nopad_yx

    def __call__(self, sample):
        input_dextr_pil, mask_dextr_pil, heatmap, crop_yx = crop_with_heatmap(
            sample['input'], sample.get('target_mask'), self.target_size_yx, self.padding,
            sample['extreme_points'], self.blob_sigma
        )

        out_sample = dict(input=input_dextr_pil, heatmap=heatmap, crop_yx=crop_yx)

        if 'target_mask' in sample:
            out_sample['target_mask'] = mask_dextr_pil
        return out_sample

class DextrToTensor (object):
    def __call__(self, sample):
        input_pil = sample['input']
        heatmap = sample['heatmap']

        input_rgb = np.array(input_pil).astype(np.float32) / 255.0
        input_rgbh = np.append(input_rgb, heatmap[:, :, None], axis=2)

        out_sample = dict(
            input=torch.tensor(input_rgbh.transpose(2, 0, 1), dtype=torch.float)
        )

        if 'target_mask' in sample:
            mask = sample['target_mask']
            mask = np.array(mask).astype(np.float32) / 255.0
            out_sample['target_mask'] = torch.tensor(mask[None, :, :], dtype=torch.float)

        if 'crop_yx' in sample:
            out_sample['crop_yx'] = torch.tensor(sample['crop_yx'], dtype=torch.float)

        return out_sample

class DextrNormalize (object):
    """
    We need per-channel mean and standard devidation.
    Channels are R, G, B, H where H is the heat map channel.

    For RGB, use the ImageNet mean and std-dev specified in torchvision:
    mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]

    For X, computed from Pascal VOC 2012:
    mean=0.008, std=0.066

    So:
    >>> DextrNormalize(mean=[0.485, 0.456, 0.406, 0.008],
    ...                std=[0.229, 0.224, 0.225, 0.066])

    Or simply:
    >>> DextrNormalize()
    to use the above default values.
    """
    def __init__(self, mean=None, std=None):
        if mean is None:
            mean = [0.485, 0.456, 0.406, 0.008]
        if std is None:
            std = [0.229, 0.224, 0.225, 0.066]
        if len(mean) != 4:
            raise ValueError('mean should have 4 channels, not {}'.format(len(mean)))
        if len(std) != 4:
            raise ValueError('stdev should have 4 channels, not {}'.format(len(std)))
        mean = np.array(mean)
        std = np.array(std)
        self.mean = torch.tensor(mean[:, None, None], dtype=torch.float)
        self.std = torch.tensor(std[:, None, None], dtype=torch.float)

    def __call__(self, sample):
        out_sample = sample.copy()
        device = sample['input'].device
        out_sample['input'] = (sample['input'] - self.mean.to(device)) / self.std.to(device)
        return out_sample

def paste_mask_into_image(image_size, mask_arr, target_crop):
    """

    :param image_size: output image size as a `(H, W)` tuple
    :param mask_arr: predicted mask as a `(target_h, target_w)` NumPy array
    :param target_crop: image space box that mask should be pasted (with scaling) into
    :return: PIL.Image of type 'L' (uint8, single channel) of size `image_size[::-1]`
    """
    mask_size_yx = np.array(mask_arr.shape[:2])

    crop_lower_yx = target_crop[0]
    crop_upper_yx = target_crop[1]
    crop_size_yx = crop_upper_yx - crop_lower_yx

    crop_lower_px_yx = np.floor(crop_lower_yx).astype(int)
    crop_upper_px_yx = np.ceil(crop_upper_yx).astype(int)

    crop_lower_px_yx = np.maximum(crop_lower_px_yx, 0)
    crop_upper_px_yx = np.minimum(crop_upper_px_yx, np.array(image_size))

    src_mask_crop_lower_yx = mask_size_yx * (crop_lower_px_yx - crop_lower_yx) / crop_size_yx
    src_mask_crop_upper_yx = mask_size_yx * (crop_upper_px_yx - crop_lower_yx) / crop_size_yx

    output_size = crop_upper_px_yx - crop_lower_px_yx

    if (output_size > 0).all():
        if issubclass(mask_arr.dtype.type, np.floating):
            mask_arr = (mask_arr * 255.0).astype(np.uint8)

        mask_pil = PIL.Image.fromarray(mask_arr)

        crop_pil = mask_pil.transform(
            tuple(output_size)[::-1], method=PIL.Image.EXTENT,
            data=(src_mask_crop_lower_yx[1], src_mask_crop_lower_yx[0],
                  src_mask_crop_upper_yx[1], src_mask_crop_upper_yx[0]),
            resample=PIL.Image.BILINEAR)

        out_pil = PIL.Image.new('L', image_size[::-1], 0)
        out_pil.paste(crop_pil, (crop_lower_px_yx[1], crop_lower_px_yx[0]))

        return out_pil
    else:
        return PIL.Image.new('L', image_size[::-1], 0)


import uuid
from random import choice
from typing import List

import numpy as np

from mMath.data.cluster.gng.graph.Edge import Edge
from mMath.data.cluster.gng.graph.Node import Node

class Graph:
    ''''''

    def __init__(self
                 , nodes: List[Node] = None
                 , edges: List[Edge] = None):
        ''''''
        self.__nodes = nodes if nodes is not None else []
        self.__edges = edges if edges is not None else []

    def addNode(self, node: Node) -> None:
        ''''''
        nodeId = self.__getNewNodeUniqueId()
        node.updateId(nodeId)
        self.__nodes.append(node)

    def __getNewNodeUniqueId(self) -> uuid.UUID:
        return uuid.uuid1()

    def addEdge(self, edge: Edge) -> None:
        if edge.getNode1().getId() == edge.getNode2().getId():
            raise Exception("edge has same nodes on both sides")

        if not self.edgeExists(edge.getNode1(), edge.getNode2()):
            self.__edges.append(edge)

    def edgeExists(self, node1, node2) -> bool:
        if self.getEdgeBetweenTwoNodes(node1, node2) is None:
            return False
        else:
            return True

    def removeEdge(self, edge: Edge) -> None:
        ''''''
        edgeCounter = 0
        for loopingEdge in self.__edges:
            if edge.getNode1().getId() == loopingEdge.getNode1().getId() and edge.getNode2().getId() == loopingEdge.getNode2().getId():
                del self.__edges[edgeCounter]
            elif edge.getNode2().getId() == loopingEdge.getNode1().getId() and edge.getNode1().getId() == loopingEdge.getNode2().getId():
                del self.__edges[edgeCounter]
            edgeCounter += 1

    def removeEdgeBetweenTwoNodes(self, node1: Node, node2: Node):
        edge: Edge = self.getEdgeBetweenTwoNodes(node1, node2)
        self.removeEdge(edge)

    def removeNode(self, node: Node) -> None:
        ''''''
        # first remove edges from that node
        self.removeEdgeByNode(node)

        nodeCounter = 0
        for loopingNode in self.__nodes:
            if node.getId() == loopingNode.getId():
                del self.__nodes[nodeCounter]
            nodeCounter += 1

    def removeEdgeByNode(self, node: Node) -> None:
        ''''''
        edgeCounter = 0
        for loopingEdge in self.__edges:
            if loopingEdge.getNode1().getId() == node.getId() or loopingEdge.getNode2().getId() == node.getId():
                del self.__edges[edgeCounter]
            edgeCounter += 1

    def getNeighbouringNodes(self, node: Node) -> List[Node]:
        ''''''
        neighborNodes = []
        for edge in self.__edges:
            if node.getId() == edge.getNode1().getId():  # if given node's id matches one side of the edge's node
                if not self.isNodeInNodes(edge.getNode2(), neighborNodes):  # to make sure it is unique
                    neighborNodes.append(edge.getNode2())  # put the other side's node in neigbouring nodes list
            elif node.getId() == edge.getNode2().getId():  # if given node's id matches one side of the edge's node
                if not self.isNodeInNodes(edge.getNode1(), neighborNodes):  # to make sure it is unique
                    neighborNodes.append(edge.getNode1())  # put the other side's node in neigbouring nodes list
        if (len(neighborNodes) > 0):
            return neighborNodes
        return None

    def isNodeInNodes(self, node: Node, givenNodes: List[Node]) -> bool:
        ''''''
        for givenNode in givenNodes:
            if (givenNode.getId() == node.getId()):
                return True
        return False

    def getNodeEdges(self, node: Node) -> List[Edge]:
        foundEdges = []
        for edge in self.__edges:
            if edge.hasNode(node):
                foundEdges.append(edge)
        if len(foundEdges) == 0:
            return None
        else:
            return foundEdges

    def getEdgeBetweenTwoNodes(self, node1: Node, node2: Node) -> Edge:
        ''''''
        for edge in self.__edges:
            if edge.getNode1().getId() == node1.getId() and edge.getNode2().getId() == node2.getId():
                return edge
            elif edge.getNode1().getId() == node2.getId() and edge.getNode2().getId() == node1.getId():
                return edge
        return None

    def getEdges(self) -> List[Edge]:
        return self.__edges

    def getNodes(self) -> List[Node]:
        return self.__nodes

    def getNodeByIndex(self, index) -> Node:
        ''''''
        return self.__nodes[index]

    def getNodeById(self, id: int) -> Node:
        if self.__nodes is not None:
            for node in self.__nodes:
                if node.getId() == id:
                    return node
        return None

    def getRandomNode(self):
        ''''''
        return choice(self.__nodes)

    def getNodeWithLargestError(self) -> Node:
        ''''''
        return self.getNodeWithLargestErrorAmongGivenNodes(self.__nodes)

    def getNeighbouringNodeWithLargestError(self, node: Node) -> Node:
        ''''''
        neihbours = self.getNeighbouringNodes(node)
        return self.getNodeWithLargestErrorAmongGivenNodes(neihbours)

    def getNodeWithLargestErrorAmongGivenNodes(self, givenNodes: List[Node]) -> Node:
        ''''''
        nodeWithLargestError: Node = None
        if givenNodes is not None:
            for node in givenNodes:
                if nodeWithLargestError is None or node.getError() > nodeWithLargestError.getError():
                    nodeWithLargestError = node
        return nodeWithLargestError

    def removeEdgelessNodes(self) -> None:
        ''''''
        for node in self.getNodes():
            edges = self.getNodeEdges(node)
            if edges is None:
                self.removeNode(node)

    def getEdgelessNodes(self):
        ''''''
        edglessNodes: List[Node] = None
        allNodeIds = [node.getId() for node in self.__nodes]
        for node in self.__nodes:
            for edge in self.__edges:
                if edge.getNode1().getId() == node.getId() or edge.getNode2().getId() == node.getId():
                    if not node.getId() in allNodeIds:
                        edglessNodes.append(node)
        return edglessNodes

    def getNodesNum(self) -> int:
        ''''''
        if self.__nodes is not None:
            return len(self.__nodes)
        else:
            return 0

    def getEdgesNum(self):
        ''''''
        if self.__edges is not None:
            return len(self.__edges)
        else:
            return 0

    def getNpNodesComponentsByIndex(self, componentIndex: int):
        ''''''
        colData = []
        for node in self.getNodes():
            colData.append(node.getRefVec().getComponentByIndex(componentIndex))
        npCol = np.asarray(colData)
        return npCol

    def printNodes(self):
        print("Nodes reference vectors are as follows:")
        for node in self.__nodes:
            print(node.getRefVec().getNpRows())

    def report(self):
        self.printNodes()
        print("Number of clusters/nodes: " + str(self.getNodesNum()))
        print("Number of edges: " + str(self.getEdgesNum()))


# coding=utf-8
"""Tests for the Impact Function Centric Wizard."""

import unittest
import sys
import os
import shutil

# Import qgis in order to set SIP API.
# pylint: disable=unused-import
import qgis
from qgis.core import QgsProject
# pylint: enable=unused-import
from qgis.PyQt import QtCore

# noinspection PyPackageRequirements
# Add PARENT directory to path to make test aware of other modules
pardir = os.path.abspath(
    os.path.join(os.path.dirname(__file__), '../../..///'))
sys.path.append(pardir)

from safe.common.utilities import temp_dir
from safe.test.utilities import (
    load_test_vector_layer,
    clone_raster_layer,
    clone_shp_layer,
    get_qgis_app,
    get_dock,
    standard_data_path)

from safe.definitions.constants import INASAFE_TEST
from safe.definitions.hazard import hazard_all, hazard_volcano
from safe.definitions.exposure import exposure_all, exposure_structure
from safe.definitions import (
    layer_purpose_hazard,
    layer_purpose_exposure,
    layer_geometry_polygon
)
from safe.definitions.utilities import get_allowed_geometries

# AG: get_qgis_app() should be called before importing modules from
# safe.gui.tools.wizard
QGIS_APP, CANVAS, IFACE, PARENT = get_qgis_app(qsetting=INASAFE_TEST)

from safe.gui.tools.wizard.wizard_dialog import WizardDialog

__copyright__ = "Copyright 2016, The InaSAFE Project"
__license__ = "GPL version 3"
__email__ = "info@inasafe.org"
__revision__ = '1a0dd4852cc92d080bf32eb73bc0487259083a8c'

# noinspection PyTypeChecker
class TestImpactFunctionCentricWizard(unittest.TestCase):
    """Test the Impact Function Centric Wizard."""

    @classmethod
    def setUpClass(cls):
        cls.dock = get_dock()
        # cls.dock = None

    def setUp(self):
        pass

    def tearDown(self):
        """Run after each test."""
        # Remove the mess that we made on each test
        shutil.rmtree(temp_dir(sub_dir='test'))

    def check_current_step(self, expected_step):
        """Helper function to check the current step is expected_step

        :param expected_step: The expected current step.
        :type expected_step: WizardStep instance
        """
        current_step = expected_step.parent.get_current_step()
        message = 'Should be step %s but it got %s' % (
            expected_step.__class__.__name__, current_step.__class__.__name__)
        self.assertEqual(expected_step, current_step, message)

    # noinspection PyUnresolvedReferences
    @staticmethod
    def select_from_list_widget(option, list_widget):
        """Helper function to select option from list_widget

        :param option: Option to be chosen
        :type option: str

        :param list_widget: List widget that wants to be checked.
        :type list_widget: QListWidget
        """
        available_options = []
        for i in range(list_widget.count()):
            if list_widget.item(i).text() == option:
                list_widget.setCurrentRow(i)
                return
            else:
                available_options.append(list_widget.item(i).text())
        message = (
            'There is no %s in the list widget. The available options are %s'
            % (option, available_options))

        raise Exception(message)

    def test_analysis_wizard(self):
        """Test Analysis Wizard."""
        dialog = WizardDialog(iface=IFACE)
        dialog.dock = self.dock
        dialog.set_function_centric_mode()
        QgsProject.instance().removeAllMapLayers()
        number_of_column = len(hazard_all)

        volcano_layer = load_test_vector_layer(
            'hazard',
            'volcano_krb.shp',
            clone=True)

        structure_layer = load_test_vector_layer(
            'exposure',
            'buildings.gpkg',
            clone=True)

        test_layers = [volcano_layer, structure_layer]

        QgsProject.instance().addMapLayers(test_layers)
        # Need to set the layers manually to map canvas. See:
        # https://gist.github.com/ismailsunni/dd2c30a38cef0147bd0dc8d6ba1aeac6
        qgs_map_canvas_layers = test_layers
        CANVAS.setLayers(qgs_map_canvas_layers)

        count = len(dialog.iface.mapCanvas().layers())
        self.assertEqual(count, len(test_layers))

        # step_fc_functions1: test function matrix dimensions
        col_count = dialog.step_fc_functions1.tblFunctions1.columnCount()
        self.assertEqual(col_count, number_of_column)
        row_count = dialog.step_fc_functions1.tblFunctions1.rowCount()
        self.assertEqual(row_count, len(exposure_all))

        # Select Volcano vs Structure
        volcano_index = hazard_all.index(hazard_volcano)
        structure_index = exposure_all.index(exposure_structure)

        dialog.step_fc_functions1.tblFunctions1.setCurrentCell(
            structure_index, volcano_index)

        selected_hazard = dialog.step_fc_functions1.selected_value(
            layer_purpose_hazard['key'])
        selected_exposure = dialog.step_fc_functions1.selected_value(
            layer_purpose_exposure['key'])
        self.assertEqual(selected_hazard, hazard_volcano)
        self.assertEqual(selected_exposure, exposure_structure)

        # step_fc_functions1: press next
        dialog.pbnNext.click()

        # step_fc_functions2
        # Check in the correct step
        self.check_current_step(dialog.step_fc_functions2)
        hazard_polygon_index = get_allowed_geometries(
            layer_purpose_hazard['key']).index(layer_geometry_polygon)
        exposure_polygon_index = get_allowed_geometries(
            layer_purpose_exposure['key']).index(layer_geometry_polygon)
        dialog.step_fc_functions2.tblFunctions2.setCurrentCell(
            exposure_polygon_index, hazard_polygon_index)

        selected_hazard_geometry = dialog.step_fc_functions2.selected_value(
            layer_purpose_hazard['key'])
        selected_exposure_geometry = dialog.step_fc_functions2.selected_value(
            layer_purpose_exposure['key'])
        self.assertEqual(selected_hazard_geometry, layer_geometry_polygon)
        self.assertEqual(selected_exposure_geometry, layer_geometry_polygon)

        # step_fc_functions2: press next
        dialog.pbnNext.click()

        # Check in the correct step
        self.check_current_step(dialog.step_fc_hazlayer_origin)

        # step hazard origin: press next
        dialog.pbnNext.click()

        # Check in the correct step
        self.check_current_step(dialog.step_fc_hazlayer_from_canvas)

        # Check the number of layer in the list
        self.assertEqual(
            dialog.step_fc_hazlayer_from_canvas.lstCanvasHazLayers.count(), 1)

        # step hazard from canvas: press next
        dialog.pbnNext.click()

        # Check in the correct step
        self.check_current_step(dialog.step_fc_explayer_origin)

        # step exposure origin: press next
        dialog.pbnNext.click()

        # Check in the correct step
        self.check_current_step(dialog.step_fc_explayer_from_canvas)

        # Check the number of layer in the list
        self.assertEqual(
            dialog.step_fc_explayer_from_canvas.lstCanvasExpLayers.count(), 1)

        # step exposure from canvas: press next
        dialog.pbnNext.click()

        # Check in the correct step
        self.check_current_step(dialog.step_fc_agglayer_origin)

        # Check no aggregation
        dialog.step_fc_agglayer_origin.rbAggLayerNoAggregation.setChecked(True)

        # step aggregation origin: press next
        dialog.pbnNext.click()

        # Check in the correct step
        self.check_current_step(dialog.step_fc_summary)

        # step extent: press next
        dialog.pbnNext.click()

        # Check in the correct step
        self.check_current_step(dialog.step_fc_analysis)

if __name__ == '__main__':
    suite = unittest.makeSuite(TestImpactFunctionCentricWizard)
    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)


import atpy
from numpy import *
import subprocess

def deg_to_degmins(x):	    #converts angle degrees form in to dd:mm:ss.ss
	x=float(x)
	deg=abs(x)
	degr=deg-int(deg)
	mins=(degr)*60.00
	secs=(mins-int(mins))*60.0
	if mins!=0:
		if -1e-5<=(secs-60)<1e-5:
			mins=mins+1
			secs=0.0
	if x>=0:
		return '+%02d%02d%02d' %(int(deg),int(mins),int(secs))
	if x<0:
		return '-%02d%02d%02d' %(int(deg),int(mins),int(secs))

def deg_to_hour(x):    #converts angle in degrees in to hh:mm:ss.ss, must input as a string
	x=float(x)
	deg=abs(x)
	hr=deg/15.0
	mins=(hr-int(hr))*60.0
	secs=(mins-int(mins))*60.0
	if mins!=0:
		if -1e-5<=(secs-60)<1e-5:
			mins=mins+1
			secs=0.0
	if x>=0:
		return '%02d%02d%02d' %(int(hr),int(mins),int(secs))
	if x<0:
		return '-%02d:%02d:%08.5f' %(int(hr),int(mins),secs)

def hour_to_deg(time):      #converts hh:mm:ss.ss in to degrees, must input as a string
	negtest=time[0]
	time=time.split(':')
	degr=float(time[0])*15.0
	mins=float(time[1])*(15.0/60.0)
	secs=float(time[2])*(15.0/(3600.0))
	if negtest=='-':
		deg=degr-mins-secs
	if negtest!='-':
		deg=degr+mins+secs
	return deg

def dec_to_deg(time):    #converts dd:mm:ss.ss in to degrees, must input as a string
	negtest=time[0]
	time=time.split(':')
	degr=float(time[0])
	mins=float(time[1])*(1.0/60.0)
	secs=float(time[2])*(1.0/(3600.0))
	if negtest=='-':
		deg=degr-mins-secs
	if negtest!='-':
		deg=degr+mins+secs
	return deg

class source_info:
	def __init__(self):
		self.name = None
		self.ra = None
		self.dec = None
		self.rerr = None
		self.derr = None
		self.SI = None
		self.intercept = None
		self.SI_err = None
		self.intercept_err = None
		self.num_match = None
		self.retained_match = None
		self.type_match = None
		self.low_resid = None
		self.f180 = None
		self.f180_ext = None
		self.num_cats = None

ras = []
rerrs = []
decs = []
derrs = []
fluxs = []
ferrs = []
majors = []
minors = []
PAs = []
fields = []
flags = []

vlssr_data = open('FullVLSSCatalog.text').read().split('\n')

def fill_full(hh,mm,ss,dd,dm,ds,ori,flux,major,minor,PA,flag,field,X,Y):
	ra = hour_to_deg('%s:%s:%s' %(hh,mm,ss))
	dec = dec_to_deg('%s:%s:%s' %(dd,dm,ds))
	ras.append(ra)
	decs.append(dec)
	fluxs.append(float(flux))

	if '<' in major:
		major = major[1:]
	if '<' in minor:
		minor = minor[1:]

	majors.append(float(major))
	minors.append(float(minor))
	PAs.append(float(PA))
	fields.append(field)
	flags.append(flag)

for line in vlssr_data:
	if 'RA' in line:
		pass
	elif '#' in line:
		pass
	elif 'NVSS' in line:
		pass
	elif 'deg' in line:
		pass
	else:
		info = line.split()
		if len(info) == 14:
			hh,mm,ss,dd,dm,ds,ori,flux,major,minor,PA,field,X,Y = info
			fill_full(hh,mm,ss,dd,dm,ds,ori,flux,major,minor,PA,'',field,X,Y)
		elif len(info) == 15:
			hh,mm,ss,dd,dm,ds,ori,flux,major,minor,PA,flag,field,X,Y = info
			fill_full(hh,mm,ss,dd,dm,ds,ori,flux,major,minor,PA,flag,field,X,Y)
		else:
			rerrs.append(float(info[0])*(15.0/3600.0))
			derrs.append(float(info[1])*(1.0/3600.0))
			ferrs.append(float(info[3]))

tdata = atpy.Table(masked=True)

names = ['J%s%s' %(deg_to_hour(ras[i]),deg_to_degmins(decs[i])) for i in xrange(len(ras))]

tdata.add_column('Name', array(names),description='Name based on J2000 position',dtype=str)
tdata.add_column('RA_J2000',array(ras),description='J2000 Right ascension of source',unit='deg',dtype=float)
tdata.add_column('RA_err',array(rerrs),description='Error on Right ascension of source',unit='deg',dtype=float)
tdata.add_column('DEC_J2000',array(decs),description='J2000 Declination of source',unit='deg',dtype=float)
tdata.add_column('DEC_err',array(derrs),description='Error on Declination of source',unit='deg',dtype=float)
tdata.add_column('Flux',array(fluxs),description='Flux density',unit='Jy',dtype=float)
tdata.add_column('Flux_err',array(ferrs),description='Error on flux density',unit='Jy',dtype=float)
tdata.add_column('major',array(majors),description='Major axes of  gaussian fit',unit='arcsec',dtype=float)
tdata.add_column('minor',array(minors),description='Minor axes of  gaussian fit',unit='arcsec',dtype=float)
tdata.add_column('PA',array(PAs),description='Position angle of gaussian fit',unit='deg',dtype=float)
tdata.add_column('Flags',array(flags),description='If extended, vlssr includes a flag',unit='deg',dtype=str)
tdata.add_column('Field',array(fields),description='The image field ID',unit='deg',dtype=str)

tdata.write("vlssr_names.vot",votype='ascii',overwrite=True)
subprocess.call('stilts tcopy ifmt=votable ofmt=fits in=sumss_names.vot out=sumss_names.fits',shell=True)


__author__ = 'Netšajev'

def find_sums(weights, min_sum, max_sum):
    """
    Assume you have a set of weights w1...wn and you
    would like to find a subset of them that gets as
    close as possible to a certain total weight. For
    n weights, there are 2 ^ n possible subsets, and
    there is no known algorithm that would solve this
    problem efficiently.

    Write a function findSums(weights,minSum,maxSum) that takes three arguments:
    :weights - a list of weights
    :minSum - a minimum total weight
    :maxSum - a maximum total weight
    The function should return a list of all subsets of the weights for which the sum falls
    into the allowed range.
    E.g. a call
    > findSums([1,2,4,8],10,13)
    should return
    [[2,8],[1,2,8],[4,8],[1,4,8]]
    (or a permutation thereof)
    """
    return list(filter(lambda x: min_sum <= sum(x) <= max_sum, [[item for item, flag in zip(weights, binum) if flag == '1'] for binum in [bin(item)[3:] for item in range(2 ** len(weights), 2 ** len(weights+[0]))]]))

weights = [1, 2, 4, 8]
print("Weights:", weights, "\nVariations:", find_sums(weights,10,13))