import os
import sys
import torch
import torch.nn as nn
import numpy as np
from PIL import Image
from itertools import chain
from random import shuffle
from torchvision import transforms
from torch.utils.data import Dataset, DataLoader

sys.path.append("..")
from Shared import utils

class Vocabulary(object):
    '''
        Wrapper for our vocabulary.
        Inspired by https://github.com/yunjey/pytorch-tutorial
    '''
    def __init__(self, word_vec_path):
        self.word_vect_dict = np.load(word_vec_path).item()
        self.all_words = list(self.word_vect_dict.keys())
        self._add_special_tokens()
        self.word_vectors = [self.word_vect_dict[word] for word in self.all_words]
        self.index_to_word = {i:v for i, v in enumerate(self.all_words)}
        self.word_to_index = {v:i for i, v in enumerate(self.all_words)}

    def __call__(self, word):
        return self.word_to_index[word]

    def __len__(self):
        return len(self.all_words)

    def _add_special_tokens(self):
        tokens = ['<pad>', '<start>', '<end>']
        token_vec = np.zeros(len(self.word_vect_dict['g']))
        for token in tokens:
            self.all_words.append(token)
            self.word_vect_dict[token] = token_vec

    def get_word_vectors(self):
        return nn.Parameter(
            torch.from_numpy(np.array(self.word_vectors, dtype=np.float32)),
            requires_grad=False
        )
    def get_word_from_index(self, index):
        return self.index_to_word[index]

class TranscriptionDataset(Dataset):
    def __init__(
        self, image_dir, annotation_path,
        data_path, word_vec_path, mean_path,
        split='train', debug=True
    ):
        self.cur_split_images = np.load(data_path).item()[split]
        if debug:
            self.images = [os.path.join(image_dir, '1_' + f) for f in self.cur_split_images[-2:]]
            self.images += [os.path.join(image_dir, '0_' + f) for f in self.cur_split_images[:2]]
        else:
            self.images = [os.path.join(image_dir, '1_' + f) for f in self.cur_split_images[:500]]
            self.images += [os.path.join(image_dir, '0_' + f) for f in self.cur_split_images[-500:]]

        shuffle(self.images)

        self.annotations = np.load(annotation_path).item()
        self.vocab = Vocabulary(word_vec_path)
        self.mean_path = mean_path

    def __len__(self):
        return len(self.images)

    def __getitem__(self, idx):
        image = Image.open(self.images[idx])
        y, aux_label = self._get_target_sequence(self.images[idx])
        transform = transforms.Compose([
            transforms.Resize((256, 256)),
            transforms.ToTensor(),
        ])
        return transform(image), y, aux_label

    def _get_target_sequence(self, path):
        name = path[path.rfind('/')+1 : ]
        name = name[:name.rfind('_')]
        annotations = self.annotations[name]
        label = int(name[:name.rfind('_')])

        caption = []
        caption.append(self.vocab('<start>'))
        caption += [self.vocab(i) for i in annotations]
        caption.append(self.vocab('<end>'))
        return torch.Tensor(caption), label

    def get_word_vectors(self):
        return self.vocab.get_word_vectors()

    def get_output_size(self):
        return len(self.vocab)

    def get_word(self, index):
        return self.vocab.get_word_from_index(index)

    def get_index(self, word):
        return self.vocab(word)

def collate_fn(data):
    '''
        Function for creating a batch where each datapoint
        is of a different length.
        Based fully on https://github.com/yunjey/pytorch-tutorial

        Returns:
            images: torch tensor (N, 3, 512, 512)
            targets: torch tensor (N, padded_length)
            auxilary_labels
    '''
    data.sort(key=lambda x: len(x[1]), reverse=True)
    images, captions, aux_labels = zip(*data)
    images = torch.stack(images, 0)
    lengths = [len(caption) for caption in captions]
    targets = torch.from_numpy(np.full((len(captions), max(lengths)), 622))
    for i, caption in enumerate(captions):
        end = lengths[i]
        targets[i, :end] = caption[:end]

    return images, targets, lengths, torch.Tensor(aux_labels)


import copy
import hashlib
import sys

class Node:
    def __init__(self, tiles = [] , parent = None ):
        self.tiles = copy.deepcopy(tiles)
        self.parent = parent
        self.hash = hashlib.sha256(str(tiles).encode()).digest()
        self.n = len(tiles)

    def isGoal(self):
        return self.tiles == goal.tiles

    def findBlank(self): #find the blank in a node's tiles
        tiles = self.tiles
        for i in range(self.n):
            for j in range(self.n):
                if tiles[i][j] == '_':
                    return i, j

    def genChildren(self):
        tiles = self.tiles
        x, y = self.findBlank()
        newTiles = []
        if x + 1 < self.n: #moving blank down / moving a tile up
            new = copy.deepcopy(tiles)
            new[x][y] = new[x+1][y]
            new[x+1][y] = '_'
            newTiles.append(new)
        if x - 1 > -1: #moving blank up / moving a tile down
            new = copy.deepcopy(tiles)
            new[x][y] = new[x-1][y]
            new[x-1][y] = '_'
            newTiles.append(new)
        if y + 1 < self.n:  # moving blank right / moving a tile left
            new = copy.deepcopy(tiles)
            new[x][y]=new[x][y+1]
            new[x][y+1]='_'
            newTiles.append(new)
        if y - 1 > -1: # moving blank left / moving a tile right
            new = copy.deepcopy(tiles)
            new[x][y] = new[x][y - 1]
            new[x][y-1] = '_'
            newTiles.append(new)
        ret = []
        for i in newTiles: #create children nodes
            child = Node(tiles=i, parent=self)
            ret.append(child)
        return ret

def dfs(start , goal):
    lst = []
    lst.append(start)
    vst = set()
    while lst:
        u = lst.pop()
        if u.isGoal():
            return u
        if u.hash not in vst:
            vst.add(u.hash)
            for w in u.genChildren():
                if w.hash not in vst:
                    lst.append(w)
    return None

def getInput(fileName):
    with open(fileName, "r") as f:
        data = f.read().strip().splitlines()
    n = int(data[0])
    tiles = []
    startTiles = [data[i + 1].strip().split() for i in range(n)]
    start = Node(startTiles)
    goalTiles = [data[i + 1 + n].strip().split() for i in range(n)]
    goal = Node(goalTiles)
    return start, goal

def output(fileName, path):
    res = ""
    n = len(path[0])
    for i in path:
        for row in i:
            for x in row:
                res += str(x).rjust(5)
            res += "\n"
        res += "=" * 20
        res += "\n"
    open(fileName, "w").write(res)

if __name__ == '__main__':
    inFile, outFile = sys.argv[1], sys.argv[2]
    start, goal = getInput(inFile)

    res = dfs(start, goal)

    if res is None:
        print("No solution.")
        sys.exit()

    path = [res.tiles]
    while True:
        res = res.parent
        path.append(res.tiles)
        if res.parent is None:
            break

    output(outFile, path[::-1])
    print("SUCCESS !")
    print("Number of steps:", len(path))


from tensorflow import keras
import numpy as np
import cv2 as cv
import os
import json

'''
Workflows(OOP):
    1. Load model
    2. Load image
    3. Preprocess image
    4. Predict
'''

#change to current file path
os.chdir(os.path.dirname(__file__))

#-----------------Constants-----------------
# Path to model
MODEL_PATH = '../model/plant_classifier.h5'
# Path to labels
LABEL_PATH = '../model/labels.json'
#-----------------Constants-----------------

#-----------------Class-----------------
class PlantClassifier:
    '''
    PlantClassifier class
    '''
    def __init__(self, model_path=MODEL_PATH, label_path=LABEL_PATH):
        '''
        Constructor
        '''
        self.model = keras.models.load_model(model_path)
        self.labels = json.load(open(label_path))

    def preprocess(self, img_data):#it should be work
        '''
        Preprocess image
        '''
        # Read image
        img = cv.imdecode(np.frombuffer(img_data.read(), np.uint8), cv.IMREAD_COLOR)
        # Resize image
        img = cv.resize(img, (224, 224))
        # Reshape image
        img = img.reshape(1, 224, 224, 3)
        # Normalize image
        img = img / 255.0
        return img

    def predict(self, img_data):
        '''
        Predict image
        '''
        # Preprocess image
        img = self.preprocess(img_data)
        # Predict
        prediction = self.model.predict(img)
        # Get label
        label = self.labels[str(np.argmax(prediction))]
        return label


import socket

# Create a socket object
s = socket.socket()

# Get local machine name
host = socket.gethostname()

port = 9999

# Connect to the server on local computer
s.connect((host, port))

# Receive no more than 1024 bytes
msg = s.recv(1024)

s.close()
print(msg.decode('ascii'))


""" Operations and utility functions used in the pipeline class

The functions described in this module define a single operation which will be
executed by the pipeline object. All public functions must adhere to the same
signature so the pipeline can dynamically execute them one by one.

@author: Max Weise
created: 23.07.2022
"""

from pipetex import exceptions
from pipetex.enums import SeverityLevels, ConfigDictKeys

import datetime
import os
import re
import shutil
import subprocess
from typing import Any, Optional, Tuple

# === Type Def ===
Monad = Tuple[bool, Optional[exceptions.InternalException]]

# === Preparation of file / working dir ===
def copy_latex_file(file_name: str, config_dict: dict[str, Any]) -> Monad:
    """Create a working copy of the specified latex file.

    To avoid losing data or corrupting the latex file a copy is created. The
    copy can be identified by a prefix added in this function. The new file
    name is written in the config dict. It is the responsibility of the
    dict owner to update the name of the working file accordingly.

    Args:
        file_name: The name of the file to be compiled. Does not contain any
            file extension.
        config_dict: Dictionary containing further settings to run the engine.

    Returns:
        Monad: Tuple which contains a boolean to indicate success of the
            function. If its true, the second value will be None. If its
            false, the second value will contain an InternalException object
            containing further information.

    Raises:
        InternalException: Indicates an internal error and is used to
            comunicate exceptions and how to handle them back to the calling
            interface.
            [Please see class definition]
        Raised Levels: CRITICAL
    """

    if f"{file_name}.tex" not in os.listdir():
        ex = exceptions.InternalException(
            f"The file {file_name}.tex is not in the directory.",
            SeverityLevels.CRITICAL
        )

        return False, ex

    file_prefix: str = config_dict[ConfigDictKeys.FILE_PREFIX.value]
    new_name: str = f"{file_prefix}_{file_name}"
    shutil.copy(f'{file_name}.tex', f'{new_name}.tex')

    config_dict[ConfigDictKeys.NEW_NAME.value] = new_name

    return True, None

def remove_draft_option(file_name: str, config_dict: dict[str, Any]) -> Monad:
    """Removes the draft option from a tex file.

    Each tex file contains a class definition, where additional options can
    be specified, including the draft option (for more info, see the project
    specification or the latex documentation). This function finds this option
    and removes it, leaving a compilable tex file.

    Args:
        file_name: The name of the file to be compiled. Does not contain any
            file extension.
        config_dict: Dictionary containing further settings to run the engine.

    Returns:
        Monad: Tuple which contains a boolean to indicate success of the
            function. If its true, the second value will be None. If its
            false, the second value will contain an InternalException object
            containing further information.

    Raises:
        InternalException: Indicates an internal error and is used to comunicate
            exceptions and how to handle them back to the calling interface.
            [Please see class definition]
        Raised Levels: CRITICAL, LOW
    """

    if f"{file_name}.tex" not in os.listdir():
        ex = exceptions.InternalException(
            f"The file {file_name}.tex is not found in the current "
            "working directory",
            SeverityLevels.CRITICAL
        )

        return False, ex

    with open(f"{file_name}.tex", "r", encoding="utf-8") as read_file:
        lines_of_file: list[str] = [line for line in read_file]

    class_line = lines_of_file[0]

    options_list = re.findall(r"\[(.+?)\]", class_line)[0].split(",")
    doc_class = re.findall(r"\{(.+?)\}", class_line)

    try:
        options_list.pop(options_list.index(" draft"))
    except ValueError:
        ex = exceptions.InternalException(
            "Draft option is not in the class definition",
            SeverityLevels.LOW
        )

        return False, ex

    options_string = "[" + ",".join(options_list) + "]"
    doc_class = "{" + doc_class[0] + "}"

    lines_of_file[0] = f"\\documentclass{options_string}{doc_class}\n"

    with open(f"{file_name}.tex", "w", encoding="utf-8") as write_file:
        write_file.writelines(lines_of_file)

    return True, None

# === Compilation / Creation of aux files / Generating LaTeX artifacts ===
def compile_latex_file(file_name: str, config_dict: dict[str, Any]) -> Monad:
    """Compiles the file with to create a PDF file.

    Compiles a file by using a latex engine on the filename given to the
    function.

    Args:
        file_name: The name of the file to be compiled. Does not contain any
            file extension.
        config_dict: Dictionary containing further settings to run the engine.

    Returns:
        Monad: Tuple which contains a boolean to indicate success of the
            function. If its true, the second value will be None. If its
            false, the second value will contain an InternalException object
            containing further information.

    Raises:
        InternalException: Indicates an internal error and is used to comunicate
            exceptions and how to handle them back to the calling interface.
            [Please see class definition]
        Raised Levels: CRITICAL
    """

    if f"{file_name}.tex" not in os.listdir():
        ex = exceptions.InternalException(
            f"The file {file_name}.tex is not found in the current "
            "working directory",
            SeverityLevels.CRITICAL
        )

        return False, ex

    argument_list: list[str] = ["pdflatex", "-quiet", f"{file_name}.tex"]
    if config_dict[ConfigDictKeys.VERBOSE.value]:
        argument_list.pop(argument_list.index("-quiet"))

    subprocess.call(argument_list)

    return True, None

def _is_bibfile_present() -> bool:
    """Searches bibliography file recursively in the current working dir.

    Returns:
        bool: True, if the bibliography file is present somewhere in the
            working dir or its subdirs."""
    file_types: list[str] = []
    for _, _, files in os.walk(os.getcwd()):
        for f in files:
            if "." in f:
                parts = f.split(".")
                file_types.append(parts[-1])

    return "bib" in file_types

def create_bibliograpyh(file_name: str, config_dict: dict[str, Any]) -> Any:
    """Creates a bibliography file.

    Runs a script to create a bibliography based on the entries in the main tex
    file. This does not hinder the creation of the PDF file.  There must be a
    .bfc file present for the script to run properly. The .bfc file is created
    when a tex file containing bibliography entries is compiled.

    Args:
        file_name: The name of the file to be compiled. Does not contain any
            file extension.
        config_dict: Dictionary containing further settings to run the engine.

    Returns:
        Monad: Tuple which contains a boolean to indicate success of the
            function. If its true, the second value will be None. If its
            false, the second value will contain an InternalException object
            containing further information.

    Raises:
        InternalException: Indicates an internal error and is used to comunicate
            exceptions and how to handle them back to the calling interface.
            [Please see class definition]
        Raised Levels: HIGH
    """
    if f"{file_name}.bcf" not in os.listdir():
        ex = exceptions.InternalException(
            f"The file {file_name}.bcf has not been created. "
            "Bibliography can not be created.",
            SeverityLevels.HIGH
        )

        return False, ex

    if not _is_bibfile_present():
        ex = exceptions.InternalException(
            "There is no bibliography file in the current project. "
            "Cant create bibliography.",
            SeverityLevels.HIGH
        )

        return False, ex

    argument_list: list[str] = ["biber", "-q", f"{file_name}"]

    if config_dict[ConfigDictKeys.VERBOSE.value]:
        argument_list.pop(argument_list.index("-q"))

    subprocess.call(argument_list)

    return True, None

def create_glossary(file_name: str, config_dict: dict[str, Any]) -> Any:
    """Creates a glossary file.

    Runs a script to create a glossary based on the entries in the main tex
    file. This does not hinder the creation of the PDF file.  There must be a
    .glo and .ist file present for the script to run properly. Thees files are
    created when a tex file containing glossary entries is compiled.

    Args:
        file_name: The name of the file to be compiled. Does not contain any
            file extension.
        config_dict: Dictionary containing further settings to run the engine.

    Returns:
        Monad: Tuple which contains a boolean to indicate success of the
            function. If its true, the second value will be None. If its
            false, the second value will contain an InternalException object
            containing further information.

    Raises:
        InternalException: Indicates an internal error and is used to comunicate
            exceptions and how to handle them back to the calling interface.
            [Please see class definition]
        Raised Levels: HIGH
    """
    if f"{file_name}.glo" not in os.listdir():
        ex = exceptions.InternalException(
            f"The file {file_name}.glo has not been created. "
            "Glossary can not be created.",
            SeverityLevels.HIGH
        )

        return False, ex

    if f"{file_name}.ist" not in os.listdir():
        ex = exceptions.InternalException(
            f"The file {file_name}.ist has not been created. "
            "Glossary can not be created.",
            SeverityLevels.HIGH
        )

        return False, ex

    if f"{file_name}.aux" not in os.listdir():
        ex = exceptions.InternalException(
            f"The file {file_name}.aux has not been created. "
            "Glossary can not be created.",
            SeverityLevels.HIGH
        )

        return False, ex

    argument_list: list[str] = ["makeglossaries", "-q", f"{file_name}"]

    if config_dict[ConfigDictKeys.VERBOSE.value]:
        argument_list.pop(argument_list.index("-q"))

    subprocess.call(argument_list)

    return True, None

# === tear down / clean up processes ===
def _move_pdf_file(file_name, new_file_name: Optional[str] = None) -> Monad:
    """Moves pdf file to seperate folder.

    To avoid that the created pdf file is deleted by the clean up process, this
    function creates a dedicated folder and moves the pdf file there.

    Args:
        file_name: The name of the file to be compiled. Does not contain any
            file extension.

    Returns:
        Monad: Tuple which contains a boolean to indicate success of the
            function. If its true, the second value will be None. If its
            false, the second value will contain an InternalException object
            containing further information.

    Raises:
        InternalException: Indicates an internal error and is used to comunicate
            exceptions and how to handle them back to the calling interface.
            [Please see class definition]
        Raised Levels: HIGH
    """
    _exeption = None
    _successvalue = True

    if not new_file_name:
        cur_date = datetime.datetime.now()
        formatted_date = cur_date.strftime("%Y_%m_%d_%H_%M")
        new_file_name = f"{formatted_date}_{file_name}"

    # Create Folder
    try:
        os.makedirs("DEPLOY")
    except FileExistsError:
        _exeption = exceptions.InternalException(
            "Folder already exists. Proceed as intended.",
            SeverityLevels.LOW
        )

        _successvalue = False

    try:
        shutil.move(f"{file_name}.pdf", "./DEPLOY")
        old_name = os.path.join(".", "DEPLOY", f"{file_name}.pdf")
        new_name = os.path.join(".", "DEPLOY", f"{new_file_name}.pdf")
        os.rename(old_name, new_name)
    except FileNotFoundError:
        _exeption = exceptions.InternalException(
            "The pdf document could not be found. Perhaps it was not created?",
            SeverityLevels.CRITICAL
        )

        _successvalue = False

    return _successvalue, _exeption

def clean_working_dir(file_name: str, config_dict: dict[str, Any],
                      new_file_name: Optional[str] = None) -> Monad:
    """Cleans the working directory from any generated files.

    Removes unwanted / redundant auxiliary files. Moves the created PDF
    document to a specified folder.

    Args:
        file_name: The name of the file to be compiled. Does not contain any
            file extension.
        config_dict: Dictionary containing further settings to run the engine.

    Returns:
        Monad: Tuple which contains a boolean to indicate success of the
            function. If its true, the second value will be None. If its
            false, the second value will contain an InternalException object
            containing further information.

    """
    _success: bool = True
    _exception: Optional[exceptions.InternalException] = None

    _success, _exception = _move_pdf_file(file_name, new_file_name)

    if _exception and _exception.severity_level >= 20:
        return False, _exception

    for file in os.listdir():
        if config_dict[ConfigDictKeys.FILE_PREFIX.value] in file:
            os.remove(file)

    return _success, _exception


from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkcalendar import Calendar, DateEntry
import numpy as np
import mysql.connector

class Alert():
    def __init__(self, master,mydb):
        def update(rows):
            self.trv.delete(*self.trv.get_children())
            for i in rows:
                self.trv.insert('','end', values=i)

        def vhc_update(rows):
            self.vhctrv.delete(*self.vhctrv.get_children())
            for i in rows:
                self.vhctrv.insert('','end', values=i)
        def driver_alert():
            self.mycursor = mydb.cursor()
            query = "SElECT Driver_ID, Firstname, Phone, PCO_Exp FROM driver Where PCO_Exp <CURDATE() or PCO_Exp<CURDATE()+30"
            self.mycursor.execute(query)
            rows = self.mycursor.fetchall()
            if len(list(rows))>0:
                rows = list(rows[0])
                rows.insert(2,'PCO')
                tablerow=[tuple(list(rows))]
            else:
                tablerow = [tuple(list(rows))]
            query2 = "SElECT Driver_ID, Firstname, Phone, DL_Exp FROM driver Where DL_Exp <CURDATE() or DL_Exp<CURDATE()+30"
            self.mycursor.execute(query2)
            rows2 = self.mycursor.fetchall()
            if len(list(rows2))>0:
                rows2 = list(rows2[0])
                rows2.insert(3,'DL')
                tablerow2=[tuple(list(rows2))]
                tb = tablerow + tablerow2
                update(tb)
            else:
                tablerow2= [tuple(list(rows2))]
                tb = tablerow + tablerow2
                update(tb)
        def Vehicle_alert():
            self.mycursor = mydb.cursor()
            query = "SElECT Reg_No, DriverID, PCO_Exp FROM vehicle Where PCO_Exp <CURDATE() or PCO_Exp<CURDATE()+30"
            self.mycursor.execute(query)
            rows = self.mycursor.fetchall()
            if len(list(rows))>0:
                rows = list(rows[0])

                rows.insert(2,'PCO')
                tablerow=[tuple(list(rows))]
            else:
                tablerow = [tuple(list(rows))]

            query2 = "SElECT Reg_No, DriverID, MOT_Exp FROM vehicle Where MOT_Exp <CURDATE() or MOT_Exp<CURDATE()+30"
            self.mycursor.execute(query2)
            rows2 = self.mycursor.fetchall()
            if len(list(rows2))>0:
                tablerow2=[]
                for i in list(rows2):
                    rows2 = list(i)
                    rows2.insert(2,'MOT')
                    tablerow2.append(tuple(rows2))
                tb = tablerow + tablerow2
                vhc_update(tb)
            else:
                tablerow2= [tuple(list(rows2))]
                tb = tablerow + tablerow2
                vhc_update(tb)
        def rfr():
            driver_alert()
            Vehicle_alert()

        self.mainFrame = Frame(master, width=950, background = 'grey')
        self.mainFrame.pack(fill=Y, expand=True)
        self.topFrame = Frame(self.mainFrame,width = 950, height=375, background="grey")
        self.topFrame.pack(fill=X, expand=True, side=TOP)
        self.bottomFrame = Frame(self.mainFrame,width = 950, height=375, background="grey")
        self.bottomFrame.pack(fill=X, expand=True, side=TOP)
        self.drvFrm = Frame(self.topFrame, height=40, bg='grey')
        self.drvFrm.pack(side=TOP,fill=X)
        self.drvLabel= Label(self.drvFrm, text= 'Driver', font = ('arial 14 bold'),fg='white',bg='grey')
        self.drvLabel.place(x=50, y=5)
        self.drvtableFrame = Frame(self.topFrame,width = 950, height=335, background="white")
        self.drvtableFrame.pack(fill=X, expand=True, side=TOP)

        self.vhcFrm = Frame(self.bottomFrame, height=40, bg='grey')
        self.vhcFrm.pack(side=TOP,fill=X)
        self.vhcLabel= Label(self.vhcFrm, text= 'Vehicle', font = ('arial 14 bold'),fg='white', bg='grey')
        self.vhcLabel.place(x=50, y=5)
        self.vhctableFrame = Frame(self.bottomFrame,width = 950, height=335, background="white")
        self.vhctableFrame.pack(fill=X, expand=True, side=TOP)

        # Scrollbar
        trv_scroll = Scrollbar(self.drvtableFrame)
        trv_scroll.grid(row=0, column=1, sticky="nsew", rowspan=2)

        self.trv = ttk.Treeview(self.drvtableFrame, columns = (1,2,3,4,5), show='headings', height=12, yscrollcommand = trv_scroll.set)
        self.trv.grid(column=0, row=0,sticky=W+N+S+E)
        self.trv.column(1, width=80, anchor="center")
        self.trv.heading(1, text='DriverID')
        self.trv.column(2, width=100, anchor="center")
        self.trv.heading(2, text='Name')
        self.trv.column(3, width=150, anchor="center")
        self.trv.heading(3, text='Tel')
        self.trv.column(4, width=160, anchor="center")
        self.trv.heading(4, text='Document')
        self.trv.column(5, width=160, anchor="center")
        self.trv.heading(5, text='Date')

        rfr_btn = Button(self.drvFrm, text= 'Refresh',width=6,command=rfr)
        rfr_btn.place(x=550)

        vhctrv_scroll = Scrollbar(self.vhctableFrame)
        vhctrv_scroll.grid(row=0, column=1, sticky="nsew", rowspan=2)

        self.vhctrv = ttk.Treeview(self.vhctableFrame, columns = (1,2,3,4), show='headings', height=12, yscrollcommand = trv_scroll.set)
        self.vhctrv.grid(column=0, row=0,sticky=W+N+S+E)
        self.vhctrv.column(1, width=80, anchor="center")
        self.vhctrv.heading(1, text='Reg No')
        self.vhctrv.column(2, width=100, anchor="center")
        self.vhctrv.heading(2, text='DriverID')
        self.vhctrv.column(3, width=150, anchor="center")
        self.vhctrv.heading(3, text='Documents')
        self.vhctrv.column(4, width=160, anchor="center")
        self.vhctrv.heading(4, text='Date')
        rfr()


from pprint import pprint
import re
import urllib.parse
from tools import *

user_args = {
    "input" : {
        "sql"       : "test.sql",
        "url"       : "http://111.22.333.44/~user",
        "public"    : "home/%username%/domains/%domain%/public_html",
    },
    "output" : {
        "sql"       : "test_replaced.sql",
        "url"       : "http://example.com",
        "public"    : "home/%username%/domains/%domain%/public_html",
    },
}

file_path = user_args["input"]["sql"]

file = open(file_path, "r", encoding="utf-8")
lines = file.readlines()
content = "".join(lines)

input_url  = user_args["input"]["url"]
input_dict = {
    "serialized" : {
        "url" : input_url,
    },
    "normal" : {
        "url" : input_url,
    },
}
input_dict["normal"]["dbl_escaped_fs"]  = input_url.replace("/", r"\\/")
input_dict["normal"]["encoded"]         = urllib.parse.quote(input_url, safe="")
input_dict["normal"]["encoded_tilde"]   = urllib.parse.quote(input_url, safe="").replace("~", "%7E")
input_dict["normal"]["dbl_encoded"]     = urllib.parse.quote(urllib.parse.quote(input_url, safe=""), safe="")
input_dict["normal"]["url_wo_schema"]   = re.sub("^https?://", "", input_url)
input_dict["normal"]["domain"]          = urllib.parse.urlparse(input_url).netloc
input_dict["serialized"]["domain"]      = urllib.parse.urlparse(input_url).netloc
input_dict["normal"]["path"]            = user_args["input"]["public"]

output_url = user_args["output"]["url"]
output_dict = {
    "serialized" : {
        "url" : output_url,
    },
    "normal" : {
        "url" : output_url,
    },
}
output_dict["normal"]["dbl_escaped_fs"] = output_url.replace("/", r"\\/")
output_dict["normal"]["encoded"]        = urllib.parse.quote(output_url, safe="")
output_dict["normal"]["encoded_tilde"]  = urllib.parse.quote(output_url, safe="").replace("~", "%7E")
output_dict["normal"]["dbl_encoded"]    = urllib.parse.quote(urllib.parse.quote(output_url, safe=""), safe="")
output_dict["normal"]["url_wo_schema"]  = re.sub("https?://", "", output_url)
output_dict["normal"]["domain"]         = urllib.parse.urlparse(output_url).netloc
output_dict["serialized"]["domain"]     = urllib.parse.urlparse(output_url).netloc
output_dict["normal"]["path"]           = user_args["output"]["public"]

content = re.sub("content ?: ?\\\\\"(.*?)\\\\\"", r"content: \'\1\'", content)

content = replace_serialized(content, input_dict["serialized"]["url"], output_dict["serialized"]["url"])
content = replace_serialized(content, input_dict["serialized"]["domain"], output_dict["serialized"]["domain"])

content = content.replace(input_dict["normal"]["url"], output_dict["normal"]["url"])
content = content.replace(input_dict["normal"]["dbl_escaped_fs"], output_dict["normal"]["dbl_escaped_fs"])
content = content.replace(input_dict["normal"]["encoded"], output_dict["normal"]["encoded"])
content = content.replace(input_dict["normal"]["encoded_tilde"], output_dict["normal"]["encoded_tilde"])
content = content.replace(input_dict["normal"]["dbl_encoded"], output_dict["normal"]["dbl_encoded"])
content = content.replace(input_dict["normal"]["url_wo_schema"], output_dict["normal"]["url_wo_schema"])
content = content.replace(input_dict["normal"]["domain"], output_dict["normal"]["domain"])
if output_dict["normal"]["path"] != input_dict["normal"]["path"]:
    content = content.replace(input_dict["normal"]["path"], output_dict["normal"]["path"])

output_file = open(user_args["output"]["sql"], "w", encoding="utf-8")
output_file.write(content)
output_file.close()

print("Done")
input()


from ray.rllib.agents.pg.pg import PGTrainer,DEFAULT_CONFIG
'''
The configuration dictionary passed to tune/PGTrainer has lot of parameters that can changed to customize your policy,
the config also has a key named 'model' which describes the neural network to be created
when it is passed as argument. The 'model' key also uses a dict to describe the network

In this assignment what you have to do is modify/create 'model' dictionary such that the network has
the following specs (activation function is 'relu'). (Refer https://docs.ray.io/en/latest/rllib-models.html#default-model-config-settings
to get an idea of possible modifications.)

Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
observations (InputLayer)       [(None, 4)]          0
__________________________________________________________________________________________________
fc_1 (Dense)                    (None, 128)          640         observations[0][0]
__________________________________________________________________________________________________
fc_2 (Dense)                    (None, 256)          33024       fc_1[0][0]
__________________________________________________________________________________________________
fc_3 (Dense)                    (None, 512)          131584      fc_2[0][0]
__________________________________________________________________________________________________
fc_4 (Dense)                    (None, 64)           32832       fc_3[0][0]
__________________________________________________________________________________________________
fc_out (Dense)                  (None, 2)            130         fc_4[0][0]
__________________________________________________________________________________________________
value_out (Dense)               (None, 1)            65          fc_4[0][0]
==================================================================================================

Note: value_out is used for value based algorithms. As it cannot be removed through config dict,
in cases where we don't use the value_out, we make it share the same layers with the policy so that
a separate network that calculates value (which is not required) is not created.
'''
config = DEFAULT_CONFIG
config['env'] = 'CartPole-v0'
config['framework'] = 'tf2' # using tensorflow to conveniently view model

# modify config

trainer = PGTrainer(config) # only for seeing the model specs
print(trainer.get_policy().model.base_model.summary())

# Initialize ray and train the policy using tune.


#!/usr/bin/env python3

import torch, glob, os
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

import numpy as np
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

data_pos = 'Imdb/train/pos/*.txt'
data_neg = 'Imdb/train/neg/*.txt'

base = os.environ['DATA_ROOT']
data_pos = os.path.join(base, data_pos)
data_neg = os.path.join(base, data_neg)

# settings
max_files = 1000
max_features = 5000

# hyper-parameters
lr = 0.01
batch_size = 100
epochs = 10

class ImdbDataset(Dataset):
  """Used to fetch individual vectorized examples"""

  def __init__(self):
    """Constructor"""

    self.vectorize()

  def load_data(self):
    """Rotten tomatoes"""

    labels = []
    sentences = []

    for file in glob.glob(data_pos)[:max_files]:
      labels.append(1)
      sentences.append(open(file).read().rstrip())
    for file in glob.glob(data_neg)[:max_files]:
      labels.append(0)
      sentences.append(open(file).read())

    return sentences, labels

  def vectorize(self):
    """Vectorize IMDB sentences"""

    sentences, labels = self.load_data()

    x_train, x_dev, y_train, y_dev = \
      train_test_split(
      sentences,
      labels,
      test_size=0.1,
      random_state=0)

    vectorizer = TfidfVectorizer(
      stop_words='english',
      max_features=max_features,
      ngram_range=(1, 1))

    x_train = vectorizer.fit_transform(x_train)
    x_dev = vectorizer.transform(x_dev)

    self.x_train = torch.tensor(x_train.toarray()).float()
    self.y_train = torch.tensor(y_train).float()
    self.x_dev = torch.tensor(x_dev.toarray()).float()
    self.y_dev = torch.tensor(y_dev).float()

  def get_dev(self):
    """Return the development set"""

    return self.x_dev, self.y_dev

  def __len__(self):
    """Should return the size of the datataset"""

    return len(self.x_train)

  def __getitem__(self, index):
    """Primary entry point for PyTorch datasets"""

    return self.x_train[index], self.y_train[index]

class Perceptron(nn.Module):
  """A Perceptron is one Linear layer"""

  def __init__(self, input_dim):
      """Args: input_dim (int): size of the input features"""

      super(Perceptron, self).__init__()
      self.fc1 = nn.Linear(input_dim, 1)

  def forward(self, x):
    """x.shape should be (batch, input_dim)"""

    return torch.sigmoid(self.fc1(x))

def train():
  """Training loop"""

  perceptron = Perceptron(input_dim=max_features)
  optimizer = optim.Adam(params=perceptron.parameters(), lr=lr)
  bce_loss = nn.BCELoss()

  dataset = ImdbDataset()
  # alternatively can use TensorDataset(x_train, y_train)
  # and then pass it to DataLoader(...) to make batches

  x_dev, y_dev = dataset.get_dev()
  batch_generator = DataLoader(dataset=dataset, batch_size=batch_size)

  for epoch in range(epochs):

    for x_train, y_train in batch_generator:

      optimizer.zero_grad()
      y_hat = perceptron(x_train).squeeze()
      loss = bce_loss(y_hat, y_train)
      loss.backward()
      optimizer.step()

    predictions = perceptron(x_dev).squeeze()
    predictions = predictions > 0.5
    acc = accuracy_score(y_dev, predictions.tolist())

    print('ep: {}, loss: {}, acc: {}'.format(epoch+1, loss.item(), acc))

if __name__ == "__main__":

  train()


from functools import reduce
import sys

FILE_PATH= "./sample_dataset/5355.txt"

def is_numeric_string(value):
    if value.isdigit():
        return True

    if value.count('.') == 1:
        parts = value.split('.')
        if all(part.isdigit() for part in parts):
            return True

    return False

def convert_operator(acc, list_item_value):
    if list_item_value == "@":
        return acc * 3
    elif list_item_value == "%":
        return acc + 5
    elif list_item_value == "#":
        return acc - 7
    else:
        return acc + list_item_value

def solution():
    # 테스트 데이터 입력
    # sys.stdin = open(FILE_PATH, 'r')

    T = int(input())

    for i in range(T):
        # input 데이터 전처리
        preprocesssed_input_data = [
            float(input_arr_value)
                if is_numeric_string(input_arr_value)
                else input_arr_value
            for input_arr_value in input().split()
        ]

        # print("preprocesssed_input_data",preprocesssed_input_data)
        result = reduce(convert_operator, preprocesssed_input_data, 0)
        print(f"{result:.2f}")

if __name__ == '__main__':
    solution()


from django.conf.urls import url

from . import views

app_name='pages'

urlpatterns=[
    url(r'^nova_planta/$', views.nova_planta, name='nova_planta'),
    url(r'^qrcode/$', views.qrcode, name='qrcode'),
    url(r'^minhas_plantas/$', views.minhas_plantas, name='minhas_plantas'),
    url(r'^banco_de_dados/$', views.banco_de_dados),
    url(r'^apagar/$', views.apagar),
    url(r'^deletar/$', views.deletar),
    url(r'^dados_planta/$', views.dados_planta),
    url(r'^informacoes/$', views.informacoes),
]


"""def fib(n):
    if n==1:
        return 0
    elif n==2:
        return 1
    else:
        return fib(n-1)+fib(n-2)"""
# too big time complexity of the algorithm O(n^2)

def fib(n):
    const=1
    r=0  # result
    for i in range(1,n):
        r=const+r
        const=r-const
    return r
# time complexity O(n)

n=100 # nr of elements
A = [] # the list
for i in range(1,n+1):
    A.append(fib(i))

print (A)


import sys

input=sys.stdin.readline

def wordReverse(str):
  w=''
  for i in range(len(str)-1,-1,-1):
    w+=str[i]
  return w

T=int(input())
#print("T=",T)
for _ in range(T):
  str=input().split()
  arr=list(map(wordReverse,str))
  #result =" ".join(arr)
  print(" ".join(arr))


from array import array
import os

with open("outputs") as f:
    content = f.readlines()
os.remove("outputs")

output_file = open('outputs.zip', 'wb')
float_array = array('d', content)

float_array.tofile(output_file)
output_file.close()


#!/usr/bin/python3
import random

import numpy as np
import pandas as pd

from numpy.random import beta
from typing import List
from typing import Dict #class

from pandas.core.frame import DataFrame #class
from pandas.core.series import Series #class

from aggregation.aAggregation import AAgregation #class
from aggregation.operators.rouletteWheelSelector import RouletteWheelSelector #class

from history.aHistory import AHistory #class
from abc import ABC, abstractmethod

from userBehaviourDescription.userBehaviourDescription import UserBehaviourDescription #class

class AggrRandomKfromN(AAgregation):
    DEBUG:bool = False

    ARG_MAIN_METHOD:str = "mainMethod"
    ARG_MAX_REC_SIZE:str = "maxRecSize"

    def __init__(self, history:AHistory, argumentsDict:Dict[str,object]):
        if not isinstance(history, AHistory):
            raise ValueError("Argument history isn't type AHistory.")
        if type(argumentsDict) is not dict:
            raise ValueError("Argument argumentsDict isn't type dict.")
        np.random.seed(42)
        self._history = history
        self.lastUsersRecommender = {}
        self.mainMethod =  argumentsDict[self.ARG_MAIN_METHOD]
        self.maxRecSize =  argumentsDict[self.ARG_MAX_REC_SIZE]

    def update(self, ratingsUpdateDF:DataFrame, argumentsDict:Dict[str,object]):
        pass

    # methodsResultDict:{String:pd.Series(rating:float[], itemID:int[])},
    # modelDF:pd.DataFrame[methodID:String, r:int, n:int, alpha0:int, beta0:int], numberOfItems:int
    def run(self, methodsResultDict:dict, modelDF:DataFrame, userID:int, numberOfItems, argumentsDict:Dict[str,object]={}):
        if type(methodsResultDict) is not dict:
            raise ValueError("Argument methodsResultDict isn't type dict.")
        if type(modelDF) is not DataFrame:
            raise ValueError("Argument modelDF isn't type DataFrame.")
        if type(numberOfItems) is not int:
            raise ValueError("Argument numberOfItems isn't type int.")
        if type(argumentsDict) is not dict:
            raise ValueError("Argument argumentsDict isn't type dict.")

        result:List[tuple] = self.runWithResponsibility(methodsResultDict, modelDF, numberOfItems)

        return list(map(lambda itemWithResponsibilityI: itemWithResponsibilityI[0], result))

    # methodsResultDict:{String:Series(rating:float[], itemID:int[])},
    # modelDF:DataFrame<(methodID:str, votes:int)>, numberOfItems:int
    def runWithResponsibility(self, methodsResultDict:dict, modelDF:DataFrame, userID:int, numberOfItems:int, argumentsDict:Dict[str,object]={}):
        #print("userID: " + str(userID))

        #print(methodsResultDict)

        if type(methodsResultDict) is not dict:
            raise ValueError("Argument methodsResultDict isn't type dict.")
        if type(numberOfItems) is not int:
            raise ValueError("Argument numberOfItems isn't type int.")
        if numberOfItems < 0:
            raise ValueError("Argument numberOfItems can't contain negative value.")
        if type(argumentsDict) is not dict:
            raise ValueError("Argument argumentsDict isn't type dict.")

        methodsResultDictI:dict = methodsResultDict
        methodsParamsDFI:DataFrame = modelDF

        recommenderID = self.mainMethod
        print(methodsResultDictI)
        results = methodsResultDictI[recommenderID] #pd.Series
        results.sort_values(ascending=False,inplace=True)

        if self.lastUsersRecommender.get(userID) is None or len(results) < numberOfItems:
            if self.DEBUG:
                print("Main vetev")
            #repeated recommendation, use different recommender
            resList = list(results.iteritems())[:numberOfItems]

        else:
            if self.DEBUG:
                print("Else vetev")
            results = results.iloc[0:self.maxRecSize]
            randResults = results.sample(numberOfItems)
            resList = list(randResults.iteritems())

        if self.DEBUG:
            print(recommenderID)

        self.lastUsersRecommender[userID] = 1

        return [(itemIdI[0], recommenderID) for itemIdI in resList]


def six_digits(n):
    cm = n//100000
    dm = n % 100000 // 10000
    m = n % 10000 // 1000
    c = n % 1000 // 100
    d = n % 100 // 10
    u = n % 10
    print(cm)
    print(dm)
    print(m)
    print(c)
    print(d)
    print(u)
    return cm+dm+m+c+d+u

print(six_digits(293721))

def five_digits(n):
    dm = n//10000
    m = n % 10000 // 1000
    c = n % 1000 // 100
    d = n % 100 // 10
    u = n % 10
    print(dm)
    print(m)
    print(c)
    print(d)
    print(u)
    return m+c+d+u+dm

# print(five_digits(29372))

def four_digits(n):
    m = n // 1000
    c = n % 1000 // 100
    d = n % 100 // 10
    u = n % 10
    print(m)
    print(c)
    print(d)
    print(u)
    return m+c+d+u

# print(four_digits(9874))

def three_digits(n):
    c = n//100
    m = n % 100 // 10
    x = n % 10
    print(c)
    print(m)
    print(x)
    return c+m+x

# print(three_digits(234))

def two_digits(n):
    m = n//10
    x = n % 10
    return m + x

# print(two_digits(28))

def suma(n):
    sum = 0
    for i in str(n)[::-1]:
        sum += int(i)
    return sum

def sum_digits(n):
    s = 0
    while n:
        s += n % 10
        n //= 10
    return s

print(suma(5432342))

Introduccion/ej suma digitos de un numero.py


from AdvancedPython.DataStructures.Trees.Node import Node

def breadthFirstSearch(root, count=0):
    if not count:
        print(root.val, end=' ')
    if root:
        if root.left:
            print(root.left.val, end=" ")
        if root.right:
            print(root.right.val, end=" ")
        breadthFirstSearch(root.left, count+1)
        breadthFirstSearch(root.right, count+1)

if __name__ == '__main__':
    root = Node(20)
    root.left = Node(8)
    root.right = Node(22)
    root.left.left = Node(4)
    root.left.right = Node(12)
    root.left.right.left = Node(10)
    root.left.right.right = Node(14)
    breadthFirstSearch(root)


from setuptools import setup
from crontab import __version__, __pkgname__
import os

# remove MANIFEST. distutils doesn't properly update it when the
# contents of directories change.
if os.path.exists('MANIFEST'): os.remove('MANIFEST')

# Grab description for Pypi
with open('README') as fhl:
    description = fhl.read()

setup(
    name             = __pkgname__,
    version          = __version__,
    description      = 'Python Crontab API',
    long_description = description,
    author           = 'Martin Owens',
    url              = 'https://launchpad.net/python-crontab',
    author_email     = 'doctormo@gmail.com',
    test_suite       = 'tests',
    platforms        = 'linux',
    license          = 'GPLv3',
    py_modules       = [ 'crontab', 'cronlog' ],
    provides         = [ 'crontab', 'cronlog' ],
    install_requires = [ 'python-dateutil' ],
    extras_require   = { 'cron-schedule': ['croniter'] },
    classifiers      = [
      'Development Status :: 5 - Production/Stable',
      'Development Status :: 6 - Mature',
      'Intended Audience :: Developers',
      'Intended Audience :: Information Technology',
      'Intended Audience :: System Administrators',
      'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
      'Operating System :: POSIX',
      'Operating System :: POSIX :: Linux',
      'Operating System :: POSIX :: SunOS/Solaris',
      'Programming Language :: Python',
      'Programming Language :: Python :: 2.6',
      'Programming Language :: Python :: 2.7',
      'Programming Language :: Python :: 3.3',
    ]
 )


import os
import re

findReg = ["^URL: (.+)","^Revision: (.+)"]
findKey = ["URL","Revision"]

def svnInfo():
    cmd = 'svn info'
    return os.popen(cmd).read()

def logChangeFile(logTxt):
    retInfo = {}
    strList = logTxt.split('\n')
    for line in strList:
        for i in xrange(0,len(findReg)):
            segre = re.compile(findReg[i])
            imglist = re.findall(segre,line)
            if len(imglist) >0 :
                retInfo[findKey[i]] = imglist[0]
                break
    return retInfo
def getSvnInfo():
    changeFile = svnInfo()
    return logChangeFile(changeFile)

# changeFile = svnInfo()
# print(logChangeFile(changeFile))
# raw_input()


# -*- coding: utf-8 -*-
#---------------------------Импорт модулей и внешних форм-------------------------#

from PyQt4 import QtCore, QtGui
import pickle
import os

class vertices_class():
	def out_frame_func(int_lng, prj_path, mesh_name_txt, vertices_visible):
		vertices_obj = None

		#----------------Если файл vertices.pkl существует, получаем данные из него для вывода в форму---------------#

		if vertices_visible == True:
			vertices_path_file = prj_path + '/' + mesh_name_txt + '/' + 'vertices.pkl'
			if os.path.exists(vertices_path_file):

				input = open(vertices_path_file, 'rb')
				vertices_obj = pickle.load(input)
				input.close()

		#---------------Формируем внешний вид формы для файла vertices.pkl на основе данных файла initial.pkl-------------#

		main_lbl = QtGui.QLabel()
		if int_lng == 'Russian':
			main_lbl.setText("Список координат вершин")
		elif int_lng == 'English':
			main_lbl.setText("List of coordinates of vertices")

		initial_path_file = prj_path + '/' + mesh_name_txt + '/' + 'initial.pkl'
		if os.path.exists(initial_path_file):

			input = open(initial_path_file, 'rb')
			obj = pickle.load(input)
			input.close()

			prs_grid = QtGui.QGridLayout()
			i = 1
			k = 0

			i_list = []
			vert_list_main = []
			while i <= obj['nov']:
				nov_str = QtGui.QHBoxLayout()
				n = 1
				p = 0
				vert_list = []
				while n <= 3:

					v_edit = QtGui.QLineEdit()
					if n == 1:
						if int_lng == 'Russian':
							v_edit.setToolTip("Укажите координату x1 вершины номер " + str(k))
						elif int_lng == 'English':
							v_edit.setToolTip("Specify the x1 coordinate of the vertex number " + str(k))
					elif n == 2:
						if int_lng == 'Russian':
							v_edit.setToolTip("Укажите координату x2 вершины номер " + str(k))
						elif int_lng == 'English':
							v_edit.setToolTip("Specify the x2 coordinate of the vertex number " + str(k))
					elif n == 3:
						if int_lng == 'Russian':
							v_edit.setToolTip("Укажите координату x3 вершины номер " + str(k))
						elif int_lng == 'English':
							v_edit.setToolTip("Specify the x3 coordinate of the vertex number " + str(k))
					v_edit.setFixedSize(35, 21)
					if vertices_obj != None:
						v_edit.setText(vertices_obj[k]['vertex_' + str(k)][p])
					validator = QtGui.QRegExpValidator(QtCore.QRegExp("\-?\\d*\\.\\d+"))
					v_edit.setValidator(validator)
					vert_list.append(v_edit)

					nov_str.insertWidget(n, v_edit)

					n = n + 1
					p = p + 1

				i_list.append(i)
				vert_list_main.append(vert_list)

				a_lbl = QtGui.QLabel("(")
				d_lbl = QtGui.QLabel(")")

				vert_lbl = QtGui.QLabel()

				if int_lng == 'Russian':
					vert_lbl.setText("// вершина номер " + str(k))
				elif int_lng == 'English':
					vert_lbl.setText("// vertex number " + str(k))

				prs_grid.addWidget(a_lbl, i, 0)
				prs_grid.addLayout(nov_str, i, 1)
				prs_grid.addWidget(d_lbl, i, 2)
				prs_grid.addWidget(vert_lbl, i, 3)

				i = i + 1
				k = k + 1

			prs_frame = QtGui.QFrame()
			prs_frame.setLayout(prs_grid)

        	# -------------------------Кнопка сохранения --------------------------#

			vertices_btnSave = QtGui.QPushButton()
			vertices_btnSave.setFixedSize(80, 25)
			buttons_hbox = QtGui.QHBoxLayout()
			buttons_hbox.addWidget(vertices_btnSave)
			if int_lng == 'Russian':
				vertices_btnSave.setText("Записать")
			elif int_lng == 'English':
				vertices_btnSave.setText("Write")

        	# -----------------------Групповой элемент формы-----------------------#

			vertices_grid = QtGui.QGridLayout()
			vertices_grid.addWidget(main_lbl, 0, 0, alignment=QtCore.Qt.AlignCenter)
			vertices_grid.addWidget(prs_frame, 1, 0, alignment=QtCore.Qt.AlignCenter)
			vertices_grid.addLayout(buttons_hbox, 2, 0, alignment=QtCore.Qt.AlignCenter)
			vertices_grid.setRowStretch(3, 6)
			vertices_group = QtGui.QGroupBox()
			vertices_group.setLayout(vertices_grid)

			return vertices_group, vertices_btnSave, obj, vert_list, i_list, vert_list_main


#!/usr/bin/env python3
#  Author:
#  Rudiger Birkner (Networked Systems Group ETH Zurich)

LOG = False

def update_supersets(updates, xrs):
    sdx_msgs = {"type": "update",
                "changes": []}

    for update in updates:
        if 'announce' in update:
            prefix = update['announce']['prefix']

            basic_set = get_all_participants_advertising(prefix, xrs.participants)

            if not is_subset_of_superset(basic_set, xrs.supersets):
                diffs = [len(basic_set.difference(set(superset))) for superset in xrs.supersets]
                unions = [len(basic_set.union(set(superset))) for superset in xrs.supersets]
                sorted_diff = sorted(diffs)

                new_members = None
                superset_index = None
                add_superset = True

                for i in range(0, len(sorted_diff)):
                    index = diffs.index(sorted_diff[i])
                    if unions[index] <= xrs.max_superset_size:
                        new_members = list(basic_set.difference(set(xrs.supersets[i])))
                        xrs.supersets[i].extend(new_members)
                        add_superset = False
                        superset_index = index
                        break

                if add_superset:
                    xrs.supersets.append(list(basic_set))
                    superset_index = len(xrs.supersets) - 1
                    for participant in xrs.supersets[-1]:
                        sdx_msgs["changes"].append({"participant_id": participant,
                                                   "superset": superset_index,
                                                   "position": xrs.supersets[superset_index].index(participant)})
                else:
                    for participant in new_members:
                        sdx_msgs["changes"].append({"participant_id": participant,
                                                   "superset": superset_index,
                                                   "position": xrs.supersets[superset_index].index(participant)})

                if len(xrs.supersets) > xrs.superset_threshold:
                    recompute_all_supersets(xrs)

                    sdx_msgs = {"type": "new",
                                "changes": []}

                    for superset in xrs.supersets:
                        for participant in superset:
                            sdx_msgs["changes"].append({"participant_id": participant,
                                                       "superset": superset_index,
                                                       "position": xrs.supersets[superset_index].index(participant)})

        elif 'withdraw' in update:
            continue

    return sdx_msgs

def recompute_all_supersets(xrs):
    peer_sets = get_all_participant_sets(xrs)
    peer_sets.sort(key=len, reverse=True)

    for i in range(0, len(peer_sets)):
        for j in reversed(range(i+1, len(peer_sets))):
            if peer_sets[i].issuperset(peer_sets[j]):
                peer_sets.remove(peer_sets[j])

    supersets = []

    for tmp_set in peer_sets:
        peer_sets.remove(tmp_set)
        superset = tmp_set

        intersects = [len(superset.intersection(s)) for s in peer_sets]

        for i in range(0, len(intersects)):
            index = intersects.index(max(intersects))
            if len(superset) == xrs.max_size or intersects[index] == -1:
                break
            if len(superset.union(peer_sets[index])) <= xrs.max_size:
                superset = superset.union(peer_sets[index])
                intersects[index] = -1
        for i in reversed(range(0, len(intersects))):
            if intersects[i] == -1:
                peer_sets.remove(peer_sets[i])
        supersets.append(list(superset))

    if len(superset) > xrs.superset_threshold:
        xrs.superset_threshold = xrs.superset_threshold * 2

    xrs.supersets = supersets

def is_subset_of_superset(subset, supersets):
    for superset in supersets:
        if set(superset).issuperset(subset):
            return True
    return False

def get_all_participants_advertising(prefix, participants):
    participant_set = set()

    for participant_name in participants:
        route = participants[participant_name].get_routes('input', prefix)
        if route:
            participant_set.add(participant_name)

    return participant_set


from PIL import Image
import os
import numpy as np
import sys
import Augmentor

"""
This file converts a dataset of images into different size and labels
used for preprocessing a Conditional WGAN Dataset
"""

# Defined variables with paths
out_path = "out/"
in_path = "train/"
labels = ["_small", "_big"]
img_format = ".png"  # might need to be changed depending on the dataset

# This method converts every image from a folder
# into a 64x64 Binary Image and assigns a label
# given the percentage of road in it.
# @param in_path The path to the images
# @param out_path The path to the output folder
# @param labaels The labels for the images
# @param pct The percentage that decides the labels
def convert_data(in_path, out_path, labels, pct=35):
    counter = 1
    print("Converting...")
    for im_path in os.listdir(in_path):
        if img_format not in im_path: continue
        # os.rename(in_path+im_path, str(counter)+".jpg")  # if renaming is needed
        img = Image.open(in_path+im_path)
        np.set_printoptions(threshold=sys.maxsize)
        img = np.array(img.resize((64, 64), Image.BILINEAR))
        count = np.count_nonzero(img)
        pct_count = (count/float(img.shape[0]*img.shape[1])) * 100.0  # Get percentage of road
        img = Image.fromarray(np.uint8(np.where(np.array(img) > 0, 1, 0)*255))
        if pct_count > pct: img.save(out_path + str(counter) + labels[1] + ".jpg")
        else: img.save(out_path + str(counter) + labels[0] + ".jpg")
        counter += 1
    print("Finished!")

# This method augments the data
# by rotating and zooming
# @param path The path to the images
def augment_data(path):
    print("Augmenting...")
    augmentor = Augmentor.Pipeline(path)
    augmentor.rotate90(1)
    augmentor.process()
    augmentor.rotate270(1)
    augmentor.process()
    print("Finished!")

# 1st) Augment_data
# augment_data(in_path[:-1])  # Remove last \
# 2nd) Convert data
# Do only after moving output folder to main folder after augmentation
convert_data(in_path, out_path, labels)


"""
Incremental Feature Dependency Discovery
iFDD implementation based on ICML 2011 paper
"""
from copy import deepcopy
import numpy as np

from rlpy.tools import printClass, PriorityQueueWithNovelty
from rlpy.tools import powerset, combinations, add_new_features
from rlpy.tools import plt
from .representation import Representation
import warnings
from collections import defaultdict

__copyright__ = "Copyright 2013, RLPy http://acl.mit.edu/RLPy"
__credits__ = [
    "Alborz Geramifard",
    "Robert H. Klein",
    "Christoph Dann",
    "William Dabney",
    "Jonathan P. How",
]
__license__ = "BSD 3-Clause"
__author__ = "Alborz Geramifard"

class iFDD_feature:
    """
    This object represents a feature used for linear function approximation.
    The feature can be an initial feature or made using
    the conjunction of existing features.
    :params potential: iFDD_Potential to be used, or a single integer passed
        to generate initial feature.

    TODO: refactor these docs.
    members:
        index: is the location of the feature in the feature vector
        f_set: set of features that their conjunction creates this feature.
        p1, p2: parents of the current feature.
                Notice that multiple combinations of parents may lead to
                the same feature. For example given 3 basic features of X, Y, and Z.
                P1=XY and P2=XZ and P1=X and P2=XZ both lead to the new features XYZ.
                Both these parameters are used for visualizations only.
    """

    def __init__(self, potential):
        if isinstance(potential, iFDD_potential):
            self.index = potential.index
            self.f_set = deepcopy(potential.f_set)
            self.p1 = potential.p1
            self.p2 = potential.p2
        else:
            # This is the case where a single integer is passed to generate an
            # initial feature
            index = potential
            self.index = index
            self.f_set = frozenset([index])
            self.p1 = -1
            self.p2 = -1

    def __deepcopy__(self, memo):
        new_f = iFDD_feature(self.index)
        new_f.p1 = self.p1
        new_f.p2 = self.p2
        new_f.f_set = deepcopy(self.f_set)
        return new_f

    def show(self):
        printClass(self)

class iFDD_potential(object):
    """
    This object represents a potential feature that can be promoted
    to a permanent feature.
    The structure of this object is very similar to iFDD feature object,
    except it has a relevance parameter that measures the importance
    of creating a new feature out of this potential feature.
    :param f_set: Set of features it corresponds to [Immutable].
    :param parant1: Parent 1 feature index.
    :param parant2: Parent 2 feature index.
    """

    def __init__(self, f_set, parent1, parent2):
        self.f_set = deepcopy(f_set)
        self.p1 = parent1
        self.p2 = parent2
        # If this feature has been discovered set this to its index else -1
        self.index = -1
        self.cumtderr = 0
        self.cumabstderr = 0
        self.count = 1  # Number of times this feature was visited

    def __deepcopy__(self, memo):
        new_p = iFDD_potential(self.f_set, self.p1, self.p2)
        new_p.cumtderr = self.cumtderr
        new_p.cumabstderr = self.cumabstderr
        return new_p

    def show(self):
        printClass(self)

class iFDD(Representation):
    """ The incremental Feature Dependency Discovery Representation based on
    [Geramifard et al. 2011 ICML paper]. This representation starts with a set of given
    binary features and adds new features as the conjunction of existing features.
    Given n features iFDD can expand the set of features up to 2^n-1 features
    (i.e. conjunction of each subset of n features can be considered as a new feature.
    """

    IS_DYNAMIC = True

    def __init__(
        self,
        domain,
        discovery_threshold,
        initial_representation,
        sparsify=True,
        discretization=20,
        debug=0,
        useCache=False,
        max_batch_discovery=1,
        batch_threshold=0,
        iFDDPlus=True,
        seed=1,
        use_chirstoph_ordered_features=True,
    ):
        """
        :param domain: The problem :py:class:`~rlpy.domains.domain.Domain` to learn.
        :param discovery_threshold: Psi in the paper.
        :param initial_representation: A Representation that provides the initial
            set of features for iFDD.
        :param sparsify: A boolean specifying the use of the trick mentioned in the
            paper so that features are getting sparser with more feature discoveries
            (i.e. use greedy algorithm for feature activation).
        :param discretization: Number of bins used for each continuous dimension.
        :param debug: Print more stuff.
        :param useCache: Use cache for phi(s) or not.
        :param batch_threshold: Minimum value of feature relevance for
            the batch setting.
        :param max_batch_discovery: Number of features to be expanded in the batch
            setting.
        :param iFDDPlus: ICML 11 iFDD would add sum of abs(TD-errors) while the iFDD
            plus uses the abs(sum(TD-Error))/sqrt(potential feature presence count).
        :param use_chirstoph_ordered_features: As Christoph mentioned adding new
            features may affect the phi for all states.
            This idea was to make sure both conditions for generating active
            features generate the same result.
        """
        super().__init__(
            domain, initial_representation.features_num, discretization, seed
        )
        # dictionary mapping initial feature sets to iFDD_feature
        self.iFDD_features = {}
        # dictionary mapping initial feature sets to iFDD_potential
        self.iFDD_potentials = {}
        # dictionary mapping each feature index (ID) to its feature object
        self.featureIndex2feature = {}
        # dictionary mapping  initial active feature set phi_0(s) to its corresponding
        # active features at phi(s). Based on Tuna's Trick to speed up iFDD
        self.cache = {}
        self.discovery_threshold = discovery_threshold
        self.sparsify = sparsify
        self.set_bins_per_dim(domain, discretization)
        self.debug = debug
        self.useCache = useCache
        self.max_batch_discovery = max_batch_discovery
        self.batch_threshold = batch_threshold
        # This is a priority queue based on the size of the features (Largest ->
        # Smallest). For same size features, it is also sorted based on the newest
        # -> oldest. Each element is the pointer to feature object.
        self.sortediFDDFeatures = PriorityQueueWithNovelty()
        self.initial_representation = initial_representation
        self.iFDDPlus = iFDDPlus
        self.addInitialFeatures()
        self.use_chirstoph_ordered_features = use_chirstoph_ordered_features
        # Helper parameter to get a sense of appropriate threshold on the
        # relevance for discovery
        self.maxRelevance = -np.inf

    def phi_non_terminal(self, s):
        """ Based on Tuna's Master Thesis 2012 """
        F_s = np.zeros(self.features_num, "bool")
        F_s_0 = self.initial_representation.phi_non_terminal(s)
        activeIndices = np.where(F_s_0 != 0)[0]
        if self.useCache:
            finalActiveIndices = self.cache.get(frozenset(activeIndices))
            if finalActiveIndices is None:
                # run regular and update the cache
                finalActiveIndices = self.findFinalActiveFeatures(activeIndices)
        else:
            finalActiveIndices = self.findFinalActiveFeatures(activeIndices)
        F_s[finalActiveIndices] = 1
        return F_s

    def findFinalActiveFeatures(self, intialActiveFeatures):
        """
        Given the active indices of phi_0(s) find the final active indices of phi(s)
        based on discovered features
        """
        finalActiveFeatures = []
        k = len(intialActiveFeatures)
        initialSet = set(intialActiveFeatures)

        if 2 ** k <= self.features_num:
            # k can be big which can cause this part to be very slow
            # if k is large then find active features by enumerating on the
            # discovered features.
            if self.use_chirstoph_ordered_features:
                for i in range(k, 0, -1):
                    if len(initialSet) == 0:
                        break
                    # generate list of all combinations with i elements
                    cand_i = [
                        (c, self.iFDD_features[frozenset(c)].index)
                        for c in combinations(initialSet, i)
                        if frozenset(c) in self.iFDD_features
                    ]
                    # sort (recent features (big ids) first)
                    cand_i.sort(key=lambda x: x[1], reverse=True)
                    for candidate, ind in cand_i:
                        # No more initial features to be mapped to extended ones
                        if len(initialSet) == 0:
                            break

                        # This was missing from ICML 2011 paper algorithm.
                        # Example: [0,1,20], [0,20] is discovered, but if [0]
                        # is checked before [1] it will be added even though it
                        # is already covered by [0,20]
                        if initialSet.issuperset(set(candidate)):
                            feature = self.iFDD_features.get(frozenset(candidate))
                            if feature is not None:
                                finalActiveFeatures.append(feature.index)
                                if self.sparsify:
                                    # print "Sets:", initialSet, feature.f_set
                                    initialSet = initialSet - feature.f_set
                                    # print "Remaining Set:", initialSet
            else:
                for candidate in powerset(initialSet, ascending=0):
                    # No more initial features to be mapped to extended ones
                    if len(initialSet) == 0:
                        break

                    # This was missing from ICML 2011 paper algorithm. Example:
                    # [0,1,20], [0,20] is discovered, but if [0] is checked
                    # before [1] it will be added even though it is already
                    # covered by [0,20]
                    if initialSet.issuperset(set(candidate)):
                        feature = self.iFDD_features.get(frozenset(candidate))
                        if feature is not None:
                            finalActiveFeatures.append(feature.index)
                            if self.sparsify:
                                initialSet = initialSet - feature.f_set
        else:
            # Loop on all features sorted on their size and then novelty and
            # activate features
            for feature in self.sortediFDDFeatures.toList():
                # No more initial features to be mapped to extended ones
                if len(initialSet) == 0:
                    break

                if initialSet.issuperset(set(feature.f_set)):
                    finalActiveFeatures.append(feature.index)
                    if self.sparsify:
                        initialSet = initialSet - feature.f_set

        if self.useCache:
            self.cache[frozenset(intialActiveFeatures)] = finalActiveFeatures
        return finalActiveFeatures

    def post_discover(self, s, terminal, a, td_error, phi_s):
        """
        returns the number of added features
        """
        # Indices of non-zero elements of vector phi_s
        activeFeatures = phi_s.nonzero()[0]
        discovered = 0
        for g_index, h_index in combinations(activeFeatures, 2):
            discovered += self.inspectPair(g_index, h_index, td_error)
        return discovered

    def inspectPair(self, g_index, h_index, td_error):
        """
        Inspect feature f = g union h where g_index and h_index are the indices of
        features g and h.
        If the relevance is > Threshold, add it to the list of features.
        Returns True if a new feature is added.
        """
        g = self.featureIndex2feature[g_index].f_set
        h = self.featureIndex2feature[h_index].f_set
        f = g.union(h)
        feature = self.iFDD_features.get(f)
        if not self.iFDDPlus:
            td_error = abs(td_error)

        if feature is not None:
            # Already exists
            return False

        # Look it up in potentials
        potential = self.iFDD_potentials.get(f)
        if potential is None:
            # Generate a new potential and put it in the dictionary
            potential = iFDD_potential(f, g_index, h_index)
            self.iFDD_potentials[f] = potential

        potential.cumtderr += td_error
        potential.cumabstderr += abs(td_error)
        potential.count += 1
        # Check for discovery

        if self.random_state.rand() < self.iFDDPlus:
            relevance = abs(potential.cumtderr) / np.sqrt(potential.count)
        else:
            relevance = potential.cumabstderr

        if relevance >= self.discovery_threshold:
            self.maxRelevance = -np.inf
            self.addFeature(potential)
            return True
        else:
            self.updateMaxRelevance(relevance)
            return False

    def show(self):
        self.showFeatures()
        self.showPotentials()
        self.showCache()

    def updateWeight(self, p1_index, p2_index):
        """
        Add a new weight corresponding to the new added feature for all actions.
        The new weight is set to zero if sparsify = False, and equal to the
        sum of weights corresponding to the parents if sparsify = True
        """
        if self.sparsify:
            new_elem = self.weight[:, p1_index] + self.weight[:, p2_index]
        else:
            new_elem = None
        self.weight = add_new_features(self.weight, new_elem)
        # We dont want to reuse the hased phi because phi function is changed!
        self.hashed_s = None

    def addInitialFeatures(self):
        for i in range(self.initial_representation.features_num):
            feature = iFDD_feature(i)
            # shout(self,self.iFDD_features[frozenset([i])].index)
            self.iFDD_features[frozenset([i])] = feature
            self.featureIndex2feature[feature.index] = feature
            # priority is 1/number of initial features corresponding to the
            # feature
            priority = 1
            self.sortediFDDFeatures.push(priority, feature)

    def addFeature(self, potential):
        # Add it to the list of features
        # Features_num is always one more than the max index (0-based)
        potential.index = self.features_num
        self.features_num += 1
        feature = iFDD_feature(potential)
        self.iFDD_features[potential.f_set] = feature
        # Expand the size of the weight_vec
        self.updateWeight(feature.p1, feature.p2)
        # Update the index to feature dictionary
        self.featureIndex2feature[feature.index] = feature
        # Update the sorted list of features
        # priority is 1/number of initial features corresponding to the feature
        priority = 1 / len(potential.f_set)
        self.sortediFDDFeatures.push(priority, feature)

        # If you use cache, you should invalidate entries that their initial
        # set contains the set corresponding to the new feature
        if self.useCache:
            for initialActiveFeatures in list(self.cache.keys()):
                if initialActiveFeatures.issuperset(feature.f_set):
                    if self.sparsify:
                        self.cache.pop(initialActiveFeatures)
                    else:
                        # If sparsification is not used, simply add the new
                        # feature id to all cached values that have feature set
                        # which is a super set of the features corresponding to
                        # the new discovered feature
                        self.cache[initialActiveFeatures].append(feature.index)
        if self.debug:
            self.show()

    def batch_discover(self, td_errors, phi, states):
        """
        Discovers features using iFDD in batch setting.
        self.batch_threshold is the minimum relevance value for the feature
        to be expanded.
        :param td_errors: p-by-1 (How much error observed for each sample)
        :param phi: n-by-p features corresponding to all samples
            (each column corresponds to one sample).
        """
        maxDiscovery = self.max_batch_discovery
        n = self.features_num  # number of features
        p = len(td_errors)  # Number of samples
        counts = np.zeros((n, n))
        relevances = np.zeros((n, n))
        for i in range(p):
            phiphiT = np.outer(phi[i, :], phi[i, :])
            if self.iFDDPlus:
                relevances += phiphiT * td_errors[i]
            else:
                relevances += phiphiT * abs(td_errors[i])
            counts += phiphiT
        # Remove Diagonal and upper part of the relevances as they are useless
        relevances = np.triu(relevances, 1)
        non_zero_index = np.nonzero(relevances)
        if self.iFDDPlus:
            # Calculate relevances based on theoretical results of ICML 2013
            # potential submission
            relevances[non_zero_index] = np.divide(
                np.abs(relevances[non_zero_index]), np.sqrt(counts[non_zero_index])
            )
        else:
            # Based on Geramifard11_ICML Paper
            relevances[non_zero_index] = relevances[non_zero_index]

        # Find indexes to non-zero excited pairs
        # F1 and F2 are the parents of the potentials
        (F1, F2) = relevances.nonzero()
        relevances = relevances[F1, F2]
        if len(relevances) == 0:
            # No feature to add
            self.logger.debug("iFDD Batch: Max Relevance = 0")
            return False

        if self.debug:
            e_vec = relevances.flatten()
            e_vec = e_vec[e_vec != 0]
            e_vec = np.sort(e_vec)
            plt.ioff()
            plt.plot(e_vec, linewidth=3)
            plt.show()

        # Sort based on relevances
        # We want high to low hence the reverse: [::-1]
        sortedIndices = np.argsort(relevances)[::-1]
        max_relevance = relevances[sortedIndices[0]]
        # Add top <maxDiscovery> features
        self.logger.debug("iFDD Batch: Max Relevance = {0:g}".format(max_relevance))
        added_feature = False
        new_features = 0
        for j in range(len(relevances)):
            if new_features >= maxDiscovery:
                break
            max_index = sortedIndices[j]
            f1 = F1[max_index]
            f2 = F2[max_index]
            relevance = relevances[max_index]
            if relevance > self.batch_threshold:
                # print "Inspecting",
                # f1,f2,'=>',self.getStrFeatureSet(f1),self.getStrFeatureSet(f2)
                if self.inspectPair(f1, f2, np.inf):
                    self.logger.debug(
                        "New Feature %d: %s, Relevance = %0.3f"
                        % (
                            self.features_num - 1,
                            self.getStrFeatureSet(self.features_num - 1),
                            relevances[max_index],
                        )
                    )
                    new_features += 1
                    added_feature = True
            else:
                # Because the list is sorted, there is no use to look at the
                # others
                break
        # A signal to see if the representation has been expanded or not
        return added_feature

    def showFeatures(self):
        print("Features:")
        print("-" * 30)
        print(" index\t| f_set\t| p1\t| p2\t | Weights (per action)")
        print("-" * 30)
        for feature in reversed(self.sortediFDDFeatures.toList()):
            print(
                " %d\t| %s\t| %s\t| %s\t| Omitted"
                % (
                    feature.index,
                    self.getStrFeatureSet(feature.index),
                    feature.p1,
                    feature.p2,
                )
            )

    def showPotentials(self):
        print("Potentials:")
        print("-" * 30)
        print(" index\t| f_set\t| relevance\t| count\t| p1\t| p2")
        print("-" * 30)
        for _, potential in self.iFDD_potentials.items():
            print(
                " %d\t| %s\t| %0.2f\t| %d\t| %s\t| %s"
                % (
                    potential.index,
                    str(np.sort(list(potential.f_set))),
                    potential.relevance,
                    potential.count,
                    potential.p1,
                    potential.p2,
                )
            )

    def showCache(self):
        if self.useCache:
            print("Cache:")
            if len(self.cache) == 0:
                print("EMPTY!")
                return
            print("-" * 30)
            print(" initial\t| Final")
            print("-" * 30)
            for initial, active in self.cache.items():
                print(" %s\t| %s" % (str(list(initial)), active))

    def updateMaxRelevance(self, newRelevance):
        # Update a global max relevance and outputs it if it is updated
        if self.maxRelevance < newRelevance:
            self.maxRelevance = newRelevance
            if self.debug:
                self.logger.debug(
                    "iFDD Batch: Max Relevance = {0:g}".format(newRelevance)
                )

    def getFeature(self, f_id):
        # returns a feature given a feature id
        if f_id in list(self.featureIndex2feature.keys()):
            return self.featureIndex2feature[f_id]
        else:
            print("F_id %d is not valid" % f_id)
            return None

    def getStrFeatureSet(self, f_id):
        # returns a string that corresponds to the set of features specified by
        # the given feature_id
        if f_id in list(self.featureIndex2feature.keys()):
            return str(sorted(list(self.featureIndex2feature[f_id].f_set)))
        else:
            print("F_id %d is not valid" % f_id)
            return None

    def feature_type(self):
        return bool

    def __deepcopy__(self, memo):
        ifdd = iFDD(
            self.domain,
            self.discovery_threshold,
            self.initial_representation,
            self.sparsify,
            self.discretization,
            self.debug,
            self.useCache,
            self.max_batch_discovery,
            self.batch_threshold,
            self.iFDDPlus,
        )
        for s, f in list(self.iFDD_features.items()):
            new_f = deepcopy(f)
            new_s = deepcopy(s)
            ifdd.iFDD_features[new_s] = new_f
            ifdd.featureIndex2feature[new_f.index] = new_f
        for s, p in list(self.iFDD_potentials.items()):
            new_s = deepcopy(s)
            new_p = deepcopy(p)
            ifdd.iFDD_potentials[new_s] = deepcopy(new_p)
        ifdd.cache = deepcopy(self.cache)
        ifdd.sortediFDDFeatures = deepcopy(self.sortediFDDFeatures)
        ifdd.features_num = self.features_num
        ifdd.weight = deepcopy(self.weight)
        return ifdd

class iFDDK_potential(iFDD_potential):
    def __init__(self, f_set, parent1, parent2):
        """
        :param f_set: Set of features it corresponds to [Immutable].
        :param parant1: Parent 1 feature index.
        :param parant2: Parent 2 feature index.
        """
        self.f_set = deepcopy(f_set)
        # If this feature has been discovered set this to its index else -1
        self.index = -1
        self.p1 = parent1
        self.p2 = parent2
        try:
            self.hp_dtype = np.dtype("float128")
        except TypeError:
            self.hp_dtype = np.dtype("float64")
        self.a = np.array(0.0, dtype=self.hp_dtype)  # tE[phi |\delta|] estimate
        self.b = np.array(0.0, dtype=self.hp_dtype)  # tE[phi \delta] estimate
        self.e = np.array(0.0, dtype=self.hp_dtype)  # eligibility trace
        self.n_crho = 0  # rho episode index of last update
        self.last_stats = {}

    def relevance(self, kappa=None, plus=None):
        if plus is None:
            assert kappa is not None
            plus = self.random_state.rand() >= kappa

        if plus:
            return np.abs(self.b) / np.sqrt(self.c)
        else:
            return self.a / np.sqrt(self.c)

    def update_statistics(self, rho, td_error, lambda_, discount_factor, phi, n_rho):
        # phi = phi_s[self.p1] * phi_s[self.p2]
        if n_rho > self.n_crho:
            self.e = 0
        self.e = rho * (lambda_ * discount_factor * self.e + phi)

        self.a += np.abs(td_error) * self.e
        self.b += td_error * self.e
        self.c += phi ** 2

        self.n_crho = n_rho

    def update_lazy_statistics(
        self, rho, td_error, lambda_, discount_factor, phi, y_a, y_b, t_rho, w, t, n_rho
    ):
        # phi = phi_s[self.p1] * phi_s[self.p2]
        if lambda_ > 0:
            # catch up on old updates
            gl = np.power(
                np.array(discount_factor * lambda_, dtype=self.hp_dtype),
                t_rho[n_rho] - self.l,
            )
            sa, sb = self.a.copy(), self.b.copy()
            self.a += self.e * (y_a[self.n_crho] - self.x_a) * np.exp(-self.nu) * gl
            self.b += self.e * (y_b[self.n_crho] - self.x_b) * np.exp(-self.nu) * gl
            if not np.isfinite(self.a):
                self.a = sa
                warnings.warn("Overflow in potential relevance estimate")
            if not np.isfinite(self.b):
                self.b = sb
                warnings.warn("Overflow in potential relevance estimate")
            if n_rho > self.n_crho:
                self.e = 0
                # TODO clean up y_a and y_b
            else:
                self.e *= (
                    gl
                    * (lambda_ * discount_factor) ** (t - 1 - t_rho[n_rho])
                    * np.exp(w - self.nu)
                )

        # updates based on current transition
        # np.seterr(under="warn")
        self.e = rho * (lambda_ * discount_factor * self.e + phi)

        self.a += np.abs(td_error) * self.e
        self.b += td_error * self.e
        # np.seterr(under="raise")
        self.c += phi ** 2
        # save current values for next catch-up update
        self.last_stats["t"] = t
        self.last_stats["y_a"] = y_a[n_rho].copy()
        self.last_stats["y_b"] = y_b[n_rho].copy()
        self.last_stats["w"] = w
        self.n_crho = n_rho

    def __deepcopy__(self, memo):
        new_p = iFDD_potential(self.f_set, self.p1, self.p2)
        for i in ["a", "b", "c", "n_crho", "e", "last_stats"]:
            new_p.__dict__[i] = deepcopy(self.__dict__[i])
        return new_p

def _set_comp_lt(a, b):
    if len(a) < len(b):
        return -1
    elif len(a) > len(b):
        return 1
    l1 = list(a)
    l2 = list(b)
    l1.sort()
    l2.sort()
    for i in range(len(l1)):
        if l1[i] < l2[i]:
            return -1
        if l1[i] > l2[i]:
            return +1
    return 0

class iFDDK(iFDD):
    """iFDD(kappa) algorithm with support for elibility traces
    The iFDD(kappa) algorithm is a stochastic mixture of iFDD and iFDD+
    to retain the best properties of both algorithms.
    """

    def __init__(
        self,
        domain,
        discovery_threshold,
        initial_representation,
        sparsify=True,
        discretization=20,
        debug=0,
        useCache=0,
        kappa=1e-5,
        lambda_=0.0,
        lazy=False,
    ):
        try:
            self.hp_dtype = np.dtype("float128")
        except TypeError:
            self.hp_dtype = np.dtype("float64")
        self.y_a = defaultdict(lambda: np.array(0.0, dtype=self.hp_dtype))
        self.y_b = defaultdict(lambda: np.array(0.0, dtype=self.hp_dtype))
        self.lambda_ = lambda_
        self.kappa = kappa
        self.discount_factor = domain.discount_factor
        self.lazy = lazy  # lazy updating?
        self.w = 0  # log(rho) trace
        self.n_rho = 0  # index for rho episodes
        self.t = 0
        self.t_rho = defaultdict(int)
        super().__init__(
            domain,
            discovery_threshold,
            initial_representation,
            sparsify=sparsify,
            discretization=discretization,
            debug=debug,
            useCache=useCache,
        )

    def episode_terminated(self):
        self.n_rho += 1
        self.w = 0
        self.t_rho[self.n_rho] = self.t

    def showPotentials(self):
        print("Potentials:")
        print("-" * 30)
        print(" index\t| f_set\t| relevance\t| count\t| p1\t| p2")
        print("-" * 30)

        k = sorted(iter(self.iFDD_potentials.keys()), cmp=_set_comp_lt)
        for f_set in k:
            potential = self.iFDD_potentials[f_set]
            print(
                " %d\t| %s\t| %g\t| %d\t| %s\t| %s"
                % (
                    potential.index,
                    str(np.sort(list(potential.f_set))),
                    potential.relevance(plus=True),
                    potential.c,
                    potential.p1,
                    potential.p2,
                )
            )

    def post_discover(self, s, terminal, a, td_error, phi_s, rho=1):
        """
        returns the number of added features
        """
        self.t += 1
        discovered = 0
        plus = self.random_state.rand() >= self.kappa
        # if self.t == 22:
        #    import ipdb; ipdb.set_trace()
        activeFeatures = phi_s.nonzero()[
            0
        ]  # Indices of non-zero elements of vector phi_s
        # print "Active Features:", activeFeatures, phi_s
        if not self.lazy:
            dd = defaultdict(float)
            for g_index, h_index in combinations(activeFeatures, 2):
                # create potential if necessary
                dd[self.get_potential(g_index, h_index).f_set] = (
                    phi_s[g_index] * phi_s[h_index]
                )

            for f, potential in list(self.iFDD_potentials.items()):
                potential.update_statistics(
                    rho, td_error, self.lambda_, self.discount_factor, dd[f], self.n_rho
                )
                # print plus, potential.relevance(plus=plus)
                if potential.relevance(plus=plus) >= self.discovery_threshold:
                    self.addFeature(potential)
                    del self.iFDD_potentials[f]
                    discovered += 1

            return discovered

        for g_index, h_index in combinations(activeFeatures, 2):
            discovered += self.inspectPair(g_index, h_index, td_error, phi_s, rho, plus)

        if rho > 0:
            self.w += np.log(rho)
        else:
            # cut e-traces
            self.n_rho += 1
            self.w = 0
            self.t_rho[self.n_rho] = self.t

        if self.lambda_ > 0:
            self.y_a[self.n_rho] += (
                np.exp(self.w)
                * (self.discount_factor * self.lambda_)
                ** (self.t - self.t_rho[self.n_rho])
                * np.abs(td_error)
            )
            self.y_b[self.n_rho] += (
                np.exp(self.w)
                * (self.discount_factor * self.lambda_)
                ** (self.t - self.t_rho[self.n_rho])
                * td_error
            )
            assert np.isfinite(self.y_a[self.n_rho])
            assert np.isfinite(self.y_b[self.n_rho])

        return discovered

    def get_potential(self, g_index, h_index):
        g = self.featureIndex2feature[g_index].f_set
        h = self.featureIndex2feature[h_index].f_set
        f = g.union(h)
        feature = self.iFDD_features.get(f)

        if feature is not None:
            # Already exists
            return None

        # Look it up in potentials
        potential = self.iFDD_potentials.get(f)
        if potential is None:
            # Generate a new potential and put it in the dictionary
            potential = iFDDK_potential(f, g_index, h_index)
            self.iFDD_potentials[f] = potential
        return potential

    def inspectPair(self, g_index, h_index, td_error, phi_s, rho, plus):
        """
        Inspect feature f = g union h where g_index and h_index are the indices of
        features g and h.
        If the relevance is > Threshold add it to the list of features.
        Returns True if a new feature is added,
        """
        potential = self.get_potential(g_index, h_index)
        phi = phi_s[g_index] * phi_s[h_index]
        potential.update_lazy_statistics(
            rho,
            td_error,
            self.lambda_,
            self.discount_factor,
            phi,
            self.y_a,
            self.y_b,
            self.t_rho,
            self.w,
            self.t,
            self.n_rho,
        )
        # Check for discovery

        relevance = potential.relevance(plus=plus)
        if relevance >= self.discovery_threshold:
            self.maxRelevance = -np.inf
            self.addFeature(potential)
            del self.iFDD_potentials[potential.f_set]
            return 1
        else:
            self.updateMaxRelevance(relevance)
            return 0


from log.mylogger import get_logger
from bot.client.client import get_web_client

def post(channel, message):
    get_logger().info(f'Posting message: Channel: {channel}. Message: {message}.')
    get_web_client().chat_postMessage(
        as_user="true",
        channel=channel,
        text=message
    )


from http import HTTPStatus

from django.contrib.auth import get_user_model
from django.test import TestCase, Client

from ..models import Group, Post

User = get_user_model()

class StaticURLTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.user = User.objects.create_user(username='auth_user')
        cls.author = User.objects.create_user(username='auth_author')
        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test-slug',
            description='Тестовое описание группы',
        )
        cls.post = Post.objects.create(
            author=cls.author,
            text='Тестовый текст поста',
        )
        cls.post_url = f'/posts/{cls.post.id}/'
        cls.post_url_edit = f'/posts/{cls.post.id}/edit/'
        cls.comment_url = f'/posts/{cls.post.id}/comment/'
        cls.public_urls = (
            ('/', 'posts/index.html'),
            ('/about/author/', 'about/author.html'),
            ('/about/tech/', 'about/tech.html'),
            ('/group/test-slug/', 'posts/group_list.html'),
            ('/profile/auth_user/', 'posts/profile.html'),
            (cls.post_url, 'posts/post_detail.html'),
        )
        cls.private_urls = (
            ('/create/', 'posts/create_post.html'),
            (cls.post_url_edit, 'posts/create_post.html'),
            ('/follow/', 'posts/follow.html'),
        )

    def setUp(self):
        """Создание гостя и авторизованного пользователя, автора."""
        self.guest_client = Client()
        self.author_client = Client()
        self.author_client.force_login(self.author)
        self.authorized_client = Client()
        self.authorized_client.force_login(self.user)

    def test_public_urls_work(self):
        """Проверяем url доступные любому пользователю."""
        for url, _ in self.public_urls:
            with self.subTest(url=url):
                response = self.guest_client.get(url)
                self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_unauth_user_cannot_access_private_urls(self):
        """Проверяем недоступные url для неавторизованных users."""
        login_url = '/auth/login/'
        for url, _ in self.private_urls:
            with self.subTest(url=url):
                response = self.guest_client.get(url)
                self.assertEqual(response.status_code, HTTPStatus.FOUND)
                target_url = f'{login_url}?next={url}'
                self.assertRedirects(response, target_url)

    def test_authenticated_author_can_access_private_urls(self):
        """Проверяем недоступные url для авторизованного автора."""
        for url, _ in self.private_urls:
            with self.subTest(url=url):
                response = self.author_client.get(url)
                self.assertEqual(response.status_code, HTTPStatus.OK)

    def test_public_urls_use_correct_templates(self):
        """Проверяем шаблоны для всех users."""
        for url, template in self.public_urls:
            with self.subTest(url=url):
                response = self.guest_client.get(url)
                self.assertTemplateUsed(response, template)

    def test_private_urls_use_correct_template_for_post_author(self):
        """Проверяем шаблоны для авторов."""
        for url, template in self.private_urls:
            with self.subTest(url=url):
                response = self.author_client.get(url)
                self.assertEqual(response.status_code, HTTPStatus.OK)
                self.assertTemplateUsed(response, template)

    def test_guest_user_cannot_edit_post(self):
        """Проверка: пост редактирует пост только автор."""
        response = self.authorized_client.get(self.post_url_edit)
        self.assertRedirects(response, self.post_url)

    def test_guest_user_cannot_add_comment(self):
        """Проверка: комментарий добавляет
        только авторизованный пользователь."""
        response = self.guest_client.get(self.comment_url)
        target_url = f'/auth/login/?next={self.comment_url}'
        self.assertRedirects(response, target_url)

    def test_server_responds_404_for_unexisting_page(self):
        response = self.authorized_client.get('/unexisting-page/')
        self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND)
        self.assertTemplateUsed(response, 'core/404.html')

    def test_authorized_user_follow_page(self):
        """Проверка: только авторизованному пользователю доступна
        страничка подписок."""
        response = self.guest_client.get('/follow/')
        target_url = '/auth/login/?next=/follow/'
        self.assertRedirects(response, target_url)


from django.urls import path, include
from rest_framework.routers import SimpleRouter
from .views import ThreadModelViewSet, UnreadMessageListCreateViewSet, MessageListCreateAPIView

router = SimpleRouter(trailing_slash=False)
router.register(r'threads', ThreadModelViewSet, basename='thread')
router.register(r'messages/unread', UnreadMessageListCreateViewSet, basename='unread')

urlpatterns = [
    path('', include(router.urls)),
    path('messages/<str:username>', MessageListCreateAPIView.as_view(), name='messages'),
]


import unittest,os
import fetch_data

class TestGetRquest(unittest.TestCase):
    def test_get_request(self):
        url = "https://reqres.in/api/users?page=2"
        data = fetch_data.get_request(url)
        assert type(data) is dict

        url = "https://non-existing-url"
        data = fetch_data.get_request(url)
        assert type(data) is not dict

class TestListUsers(unittest.TestCase):
    def test_list_users(self):
        url = "https://reqres.in/api/users?page=2"
        self.assertEqual(fetch_data.list_users(url), True, "Should be True")

    def test_error_list_users(self):
        url = "https://non-existing-url"
        self.assertEqual(fetch_data.list_users(url), False, "Should be False")

class TestWriteFile(unittest.TestCase):
    def test_Write_file(self):
        fetch_data.write_file("testfile","testusername", "testmail", "https://reqres.in/img/faces/10-image.jpg")
        os.path.isfile("testfile")
        os.remove("testfile")

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