from __future__ import annotations
from datetime import datetime
from typing import Any, List
from app.db import Base
from sqlalchemy import Column, Integer, ForeignKey, String, Text, DateTime, func
from sqlalchemy.orm import Session, relationship
import bleach
import app.lib as lib
import app.db.models as models

class Brand(Base):
    __tablename__ = "Brand"

    id: int = Column(Integer, primary_key=True, autoincrement=True)

    name: str = Column(Text, nullable=False)

    created_at: datetime = Column(DateTime)
    updated_at: datetime = Column(DateTime)

    username: str = Column(String(32), ForeignKey("User.username", ondelete="CASCADE"), nullable=False)

    articles: List[models.Article] = relationship("Article", back_populates="brand")
    user: models.User = relationship("User", back_populates="brands")

    def __str__(self) -> str:
        return self.name

    def set_name(self, name: Any) -> None:
        name = Brand.process_name(name, self.user, self)
        if name != self.name:
            self.name = name
            self.updated_at = datetime.utcnow()

    @staticmethod
    def create(user: models.User) -> Brand:
        store = Brand()
        store.created_at = datetime.utcnow()
        store.user = user

        return store

    @staticmethod
    def get(brand_id: Any, user: models.User, db: Session) -> Brand:
        try:
            brand_id = int(brand_id)
        except:
            raise LookupError(f"Invalid brand ID: {brand_id}")

        brand = db.query(Brand).filter(Brand.id == brand_id).first()
        if brand is None:
            raise LookupError(f"No such brand: {brand_id}")
        if user.role != lib.UserRoles.ADMIN:
            if brand not in user.brands:
                raise LookupError(f"No such brand: {brand_id}")

        return brand

    @staticmethod
    def byName(brand_name: str, user: models.User, db: Session) -> Brand:
        if not isinstance(brand_name, str) or not brand_name:
            raise LookupError(f"No such brand: {brand_name}")

        brand_name = bleach.clean(brand_name.strip(), tags=[])

        brand = db.query(Brand).filter(func.lower(Brand.name) == func.lower(brand_name)).first()
        if brand is None:
            raise LookupError(f"No such brand: {brand_name}")
        if user.role != lib.UserRoles.ADMIN:
            if brand not in user.brands:
                raise LookupError(f"No such brand: {brand_name}")

        return brand

    @staticmethod
    def find(name: Any, user: models.User) -> List[Brand]:
        if not isinstance(name, str) or not name:
            raise ValueError("Invalid name")

        name: str = bleach.clean(name.strip(), tags=[])

        brands: List[Brand] = []
        for brand in user.brands:
            if name.casefold() in brand.name.casefold():
                brands.append(brand)

        return brands

    @staticmethod
    def process_name(name: Any, user: models.User, reference: Brand) -> str:
        if not isinstance(name, str) or not name:
            raise ValueError("Invalid name")

        name: str = bleach.clean(name.strip(), tags=[])

        names = [brand.name.casefold() for brand in user.brands if reference != brand]
        if name.lower() in names:
            raise ValueError(f"Brand {name} already exists")

        return name


import sys, os
from ROOT import gSystem
from ROOT import ertool
from ROOT import larlite as fmwk
from basictool import GeoViewer, geoalgo
from seltool import ERViewer
import matplotlib.pyplot as plt

#viewers
plt.ion()

def getViewer(name,w=4,h=8):
    display = ERViewer(name,width=w,height=h)
    #display.set_window_title(name)
    return display

def viewAll(mcDisplay, mcData, mcPart, recoDisplay, recoData, recoPart):

    mcDisplay.clear()
    recoDisplay.clear()

    recoDisplay.add(recoPart,recoData,False)
    mcDisplay.add(mcPart,mcData,False)

    mcDisplay.show()
    recoDisplay.show()

    # The ranges for the two planes "should" be identical
    mcrange   = mcDisplay.get_ax_range()
    recorange = recoDisplay.get_ax_range()
    #for dim in xrange(3):
    #    if (recorange[0][dim] < mcrange[0][dim]): mcrange[0][dim] = recorange[0][dim]
    #    if (recorange[1][dim] > mcrange[1][dim]): mcrange[1][dim] = recorange[1][dim]

    #recoDisplay.set_ax_range(mcrange[0],mcrange[1])
    #mcDisplay.set_ax_range(mcrange[0],mcrange[1])

def view(display, data, part):

    display.clear()

    #display_reco = ERViewer("view")
    #display_reco.set_window_title("Reco Objects")

   # del display_mc

    display.add(part,data,False)

    display.show()
    #return display


import http.server
import python.main as main
from urllib import parse
import base64
import json

# 読み込み
def read(path):
    with open(path, 'r', encoding="utf-8") as file:
        return json.load(file)

CONFIG = read("config.json")
PORT = CONFIG["port"]["Python"]
IP = CONFIG["ip"]["Python"]

class MyHandler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        url = parse.urlparse(self.path)

        # リクエストパスが"/play"の場合は"play"という文字を返す
        if url.path == "/play":

            self.send_response(200)
            self.send_header("Content-type", "text/plain")
            self.end_headers()
            self.wfile.write(b"play")

            query = parse.parse_qs(url.query)
            main.playList.append([
                int(query["voice_channel"][0]),
                base64.b64decode(query["url"][0]).decode()
            ])

        elif url.path == "/stop":

            self.send_response(200)
            self.send_header("Content-type", "text/plain")
            self.end_headers()
            self.wfile.write(b"stop")
            main.isStop = True

        elif url.path == "/skip":

            self.send_response(200)
            self.send_header("Content-type", "text/plain")
            self.end_headers()
            self.wfile.write(b"skip")
            main.isSkip = True

        else:
            # それ以外の場合は404の処理を行う
            self.send_response(200)
            self.send_header("Content-type", "text/plain")
            self.end_headers()
            self.wfile.write(b"none")

# ポート番号は任意
server = http.server.HTTPServer((IP, PORT), MyHandler)

def setup():
    server.serve_forever()


#!/usr/bin/env python3

import argparse

import matplotlib.pyplot as plt
import numpy as np

if __name__ == '__main__':

    # Parse command-line arguments
    parser = argparse.ArgumentParser(description='Box-counting fractal dimension plot')
    parser.add_argument('out_folder',
                        action='store',
                        metavar='OUT_FOLDER',
                        type=str,
                        help='Directory containing output files.')
    parser.add_argument('--show',
                        action='store_true',
                        default=False,
                        help='Show plot instead of saving to file.')
    arg = parser.parse_args()

    # Creating graph for the normalised histogram
    plt.figure(dpi=125)
    plt.title("Box-counting fractal dimension", fontsize=18)
    plt.xlabel(r'$\epsilon$', fontsize=16)
    plt.ylabel(r'-$\frac{\partial \ln{N(\epsilon)}}{\partial \ln{\epsilon}}$', fontsize=16)
    plt.ylim(0, 3.1)
    plt.grid()

    # Reading histogram file from output folder and fitting the curve
    style = {'pore': 'rs-', 'surf': 'go-', 'rock': 'bv-'}
    for phase in ["pore", "surf", "rock"]:
        size, number = np.loadtxt(arg.out_folder + "/" + phase + "_frac_plot.dat", unpack=True)
        frac_dim = - np.gradient(np.log(number), size) / np.gradient(np.log(size), size)
        plt.semilogx(size, frac_dim, style[phase], label=phase)
    plt.legend(loc='best', fancybox=True, shadow=True)

    if (arg.show):
        plt.show()
    else:
        plt.savefig(arg.out_folder + "/frac_plot.png", dpi=125, bbox_inches='tight')


#!/usr/bin/env python3
import os
import rospy
from geometry_msgs.msg import Twist
from sensor_msgs.msg import Image
import rospkg
from hera_face.srv import face_list

from cv_bridge import CvBridge
from ultralytics import YOLO
import dlib
import numpy as np
import fnmatch
import cv2
import time

class FaceRecog:
    recog = 0

    def __init__(self):
        """
        Constructor for the FaceRecog class.
        Initializes necessary ROS parameters, services and publishers.
        Also, it sets up the face recognition model and other necessary parameters.
        """
        rospy.Service('face_recog', face_list, self.handler)
        rospy.loginfo("Start FaceRecogniser Init process...")
        self.rate = rospy.Rate(5)
        rospack = rospkg.RosPack()

        self.path_to_package = rospack.get_path('hera_face')
        self.yolo = YOLO(self.path_to_package + '/src/coco.pt')
        self.bridge_object = CvBridge()
        rospy.loginfo("Start camera suscriber...")
        self.topic = "/zed_node/right_raw/image_raw_color"
        self._check_cam_ready()
        self.image_sub = rospy.Subscriber(self.topic, Image, self.camera_callback)

        self.center_place = None
        self.detector = dlib.get_frontal_face_detector()
        self.sp = dlib.shape_predictor(os.path.join(self.path_to_package, "src/shape_predictor_5_face_landmarks.dat"))
        self.model = dlib.face_recognition_model_v1(
            os.path.join(self.path_to_package, "src/dlib_face_recognition_resnet_model_v1.dat"))
        self.people_dir = os.path.join(self.path_to_package, 'face_images')

        self.pub_cmd_vel = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
        rospy.loginfo("Finished FaceRecogniser Init process...Ready")

    def _check_cam_ready(self):
        """
        Checks if the camera is ready by trying to get an image from the specified topic.
        """
        self.cam_image = None
        while self.cam_image is None and not rospy.is_shutdown():
            try:
                self.cam_image = rospy.wait_for_message(self.topic, Image, timeout=1.0)
                rospy.logdebug("Current " + self.topic + " READY=>" + str(self.cam_image))
            except:
                rospy.logerr("Current " + self.topic + " not ready yet, retrying.")

    def camera_callback(self, data):
        """
        Callback function for the camera topic. Stores the received image data.
        Args:
            data (sensor_msgs.msg.Image): Image data received from the camera.
        """
        self.cam_image = data

    def load_data(self):
        """
        Load data from the face_images directory. Processes the jpg files and extracts face representations.
        """
        self.known_face = []
        self.known_name = []
        files = fnmatch.filter(os.listdir(self.people_dir), '*.jpg')
        self._process_files(files)

    def _process_files(self, files):
        """
        Processes the given files by loading the images and extracting face representations.
        Args:
            files (list): A list of file names to process.
        """
        for file_name in files:
            img = dlib.load_rgb_image(os.path.join(self.people_dir, file_name))
            self._process_image(img, file_name)

    def _process_image(self, img, file_name):
        """
        Processes the given image by detecting faces and extracting the largest face.
        Args:
            img (np.array): The image to process.
            file_name (str): The name of the file (used for logging purposes).
        """
        img_detected = self.detector(img, 1)
        if not img_detected:
            rospy.loginfo("No face detected in image: " + file_name)
            return
        self._extract_biggest_face(img, img_detected, file_name)

    def _extract_biggest_face(self, img, img_detected, file_name):
        """
        Extracts the biggest face from the detected faces in an image.
        Args:
            img (np.array): The image containing the faces.
            img_detected (list): A list of detected faces.
            file_name (str): The name of the file (used for logging purposes).
        """
        bounding_boxes = [rect.width() * rect.height() for rect in img_detected]
        biggest_box_index = bounding_boxes.index(max(bounding_boxes))
        biggest_box = img_detected[biggest_box_index]
        self._align_and_add_face(img, biggest_box, file_name)

    def _align_and_add_face(self, img, box, file_name):
        """
        Aligns and adds the face represented by the given bounding box to the known faces.
        Args:
            img (np.array): The image containing the face.
            box (dlib.rectangle): The bounding box of the face.
            file_name (str): The name of the file (used for logging purposes).
        """
        img_shape = self.sp(img, box)
        align_img = dlib.get_face_chip(img, img_shape)
        img_rep = np.array(self.model.compute_face_descriptor(align_img))
        self.known_face.append(img_rep)
        self.known_name.append(file_name.split('.')[0].lower())

    def spin(self, velocidade=0.4):
        """
        Spins the robot at the given speed.
        Args:
            velocidade (float, optional): The speed at which to spin. Defaults to 0.4.
        """
        vel_cmd = Twist()
        vel_cmd.angular.z = velocidade
        self.pub_cmd_vel.publish(vel_cmd)

    def predict(self):
        """
        Predicts the bounding boxes in the current frame using the YOLO object detection model.
        Returns:
            results[0].boxes (list): A list of predicted bounding boxes.
        """
        small_frame = self.bridge_object.imgmsg_to_cv2(self.cam_image, desired_encoding="bgr8")
        small_frame = small_frame[:720, :]
        results = self.yolo.predict(source=small_frame, conf=0.4, device=0, classes=[56,57])
        print('Len boxes: ', len(results[0].boxes))
        return results[0].boxes

    def find_sit(self):
        """
        Finds an empty location by spinning and using object detection.
        Returns:
            center_place (float): The center of the found empty space.
        """
        boxes = self.predict()

        while len(boxes) == 0:
            print('First while')
            self.spin(0.4)
            boxes = self.predict()

        self.spin(0)

        while True:
            print('Second while')
            self.checked_places = []

            boxes = self.predict()
            if len(boxes) > 0:
                print('box > 0')
                self.spin(0)
                time.sleep(1)
                self.center_place = self.find_empty_place(boxes)

            if self.center_place is not None:
                print('break')
                break
            else:
                print('Spin and detect')
                self.spin(0.4)

        return self.center_place

    def find_empty_place(self, boxes):
        """
         Find an empty place not occupied by any recognized faces.

         Args:
             boxes (List[dlib.rectangles]): List of bounding boxes detected in the frame.

         Returns:
             center_place (float): The center of the free space.
         """
        print('Looking for an empty place')
        if len(boxes) == 0:
            print("No boxes detected, spinning...")
            self.spin(0.4)
            return None

        for box in boxes:
            center_place = self._get_center_place(box)

            if center_place is not None and center_place not in self.checked_places:
                self.checked_places.append(center_place)
                return center_place

        # If all places are checked, spin again to find a new place
        print("All places are checked, spinning...")
        self.spin(0.4)
        return None

    def _get_center_place(self, box):
        """
        Get the center of the free space for a given bounding box.

        Args:
            box (dlib.rectangles): Detected bounding box.

        Returns:
            center_place (float): The center of the free space.
        """
        obj_class = self.yolo.names[int(box.cls)]
        print(obj_class)

        if self.face_center:
            center_place = self._check_known_faces(box, obj_class)
        else:
            center_place = self._calculate_center_place(box, obj_class)

        return center_place

    def _check_known_faces(self, box, obj_class, center_place=None):
        """
        Check for known faces in the specified bounding box.

        Args:
            box (dlib.rectangles): Detected bounding box.
            obj_class (str): The class of the object ('chair' or 'couch').

        Returns:
            center_place (float): The center of the free space.
        """
        for i, face_name in enumerate(self.face_name):
            if face_name in self.known_name:
                center_place = self._calculate_center_place(box, obj_class, i, face_name)

        return center_place

    def _calculate_center_place(self, box, obj_class, index=None, face_name=None, center_place=None):
        """
        Calculate the center of the free space for a given object class.

        Args:
            box (dlib.rectangles): Detected bounding box.
            obj_class (str): The class of the object ('chair' or 'couch').

        Returns:
            center_place (float): The center of the free space.
        """
        box = box.xyxy[0]
        if index is not None and face_name is not None:
            print('box0:', box[0])
            print('box2:', box[2])
            print('center:', self.face_center[index])
        if obj_class == 'chair' and not any(box[0] < center_face < box[2] for center_face in self.face_center):
            center_place = (box[0] + box[2]) / 2
            print("lugar 0")
        elif obj_class == 'couch':
            media_x = (box[0] + box[2]) / 2
            if not any(box[0] < center_face < media_x for center_face in self.face_center):
                center_place = (box[0] + media_x) / 2
                print('lugar 1')
            elif not any(media_x < center_face < box[2] for center_face in self.face_center):
                center_place = (media_x + box[2]) / 2
                print('lugar 2')

        return center_place

    def recognize(self, small_frame):
        """
        Recognizes the faces in the given frame and draws bounding boxes around them.
        Args:
            small_frame (np.array): The frame in which to recognize faces.
        Returns:
            len(img_detected) (int): The number of detected faces.
        """
        self.face_center = []
        self.face_name = []

        img_detected = self.detector(small_frame, 1)

        if len(img_detected) == 0:
            rospy.loginfo("No face detected")
            self.find_sit()
            return len(img_detected)

        faces = dlib.full_object_detections()
        for detection in img_detected:
            faces.append(self.sp(small_frame, detection))
        align_img = dlib.get_face_chips(small_frame, faces)
        img_rep = np.array(self.model.compute_face_descriptor(align_img))

        for i in range(len(img_detected)):
            name = self._get_face_name(img_rep[i])
            self.face_name.insert(i, name)

        for i, rects in enumerate(img_detected):
            if self.face_name[i] in self.known_name:
                self._draw_rectangle(small_frame, rects, (0, 255, 0), self.face_name[i])
            else:
                self._draw_rectangle(small_frame, rects, (255, 0, 0), self.face_name[i])
            center_x = (rects.right() + rects.left()) / 2
            self.face_center.append(center_x)

        window = dlib.image_window()
        window.set_image(small_frame)
        cv2.imwrite(self.path_to_package + '/face_recogs/recog.jpg', small_frame)

        return len(img_detected)

    def _get_face_name(self, img_rep):
        """
        Gets the name of the face represented by the given representation by comparing it with known faces.
        Args:
            img_rep (np.array): The face representation to identify.
        Returns:
            name (str): The name of the recognized face, or 'Face' if not recognized.
        """
        name = 'Face'
        for j in range(len(self.known_face)):
            euclidean_dist = list(np.linalg.norm(self.known_face - img_rep, axis=1) <= 0.62)
            if True in euclidean_dist:
                fst = euclidean_dist.index(True)
                name = self.known_name[fst]
            else:
                continue
        return name

    def _draw_rectangle(self, frame, rects, color, name):
        """
                Draws a rectangle around the face in the frame and annotates it with the name.
                Args:
                    frame (np.array): The frame in which to draw the rectangle
        """
        cv2.rectangle(frame, (rects.left(), rects.top()), (rects.right(), rects.bottom()), color, 2)
        cv2.putText(frame, name, (rects.left(), rects.top()), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2, cv2.LINE_AA)

    def start(self, data, nome_main):
        nome_main = nome_main.lower()
        self.load_data()

        small_frame = self.bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8")

        num_faces = self.recognize(small_frame)

        name = 'Face'
        center = 0.0
        if nome_main == '':
            self.find_sit()
            print(self.center_place)
            self.recog = 1
        elif nome_main in self.face_name:
            name = nome_main
            index = self.face_name.index(nome_main)
            center = self.face_center[index]
            print(self.face_center)
            print(center)

            self.recog = 1

        return name, center, num_faces, self.center_place

    def handler(self, request):
        self.recog = 0
        while self.recog == 0:
            self.image_sub = rospy.Subscriber(self.topic, Image, self.camera_callback)
            name, center, num, empty = self.start(self.cam_image, request.name)
            self.rate.sleep()
            return name, float(center), num, empty
        cv2.destroyAllWindows()

if __name__ == '__main__':
    rospy.init_node('face_recog', log_level=rospy.INFO)
    FaceRecog()
    try:
        rospy.spin()
    except rospy.ROSInterruptException:
        pass


import json

class Database:
    def __init__(self, filename):
        self.filename = filename
        self.prod_name = self._load_data()

    def _load_data(self):
        try:
            with open(self.filename, 'r') as file:
                return json.load(file)
        except FileNotFoundError:
            return []

    def _save_data(self):
        with open(self.filename, 'w') as file:
            json.dump(self.prod_name, file, indent=2)

    def create(self, product):
        self.prod_name.append(product)
        self._save_data()

    def read(self, product_id=None):
        if product_id is None:
            return self.prod_name
        for product in self.prod_name:
            if product['id'] == product_id:
                return product
        return None

    def update(self, product_id, new_name):
        for product in self.prod_name:
            if product['id'] == product_id:
                product.update(new_name)
                self._save_data()
                return True
        return False

    def delete(self, product_id):
        for index, product in enumerate(self.prod_name):
            if product['id'] == product_id:
                del self.prod_name[index]
                self._save_data()
                return True
        return False

class Model:
    def __init__(self, data):
        self.prod_name = data

    def validate(self):
        return True

class View:
    @staticmethod
    def print_products(products):
        for product in products:
            print(product)

    @staticmethod
    def print_message(message):
        print(message)

class Controller:
    def __init__(self, db):
        self.db = db

    def create_product(self, name):
        model = Model(name)
        if model.validate():
            self.db.create(name)
            View.print_message("Запись успешно создана.")
        else:
            View.print_message("Ошибка валидации данных. Запись не создана.")

    def read_products(self, product_id=None):
        if product_id is not None:
            product = self.db.read(product_id)
            if product:
                View.print_products([product])
            else:
                View.print_message("Запись не найдена.")
        else:
            products = self.db.read()
            View.print_products(products)

    def update_product(self, product_id, new_name):
        if self.db.update(product_id, new_name):
            View.print_message("Запись успешно обновлена.")
        else:
            View.print_message("Запись не найдена. Обновление не выполнено.")

    def delete_product(self, product_id):
        if self.db.delete(product_id):
            View.print_message("Запись успешно удалена.")
        else:
            View.print_message("Запись не найдена. Удаление не выполнено.")

db = Database("data.json")
controller = Controller(db)

data1 = {"id": 1, "name": "John"}
# data1 = {"id": 2, "name": "John", "age": 30}
controller.create_product(data1)

# controller.read_products()

# new_name = {'id': 2 ,"name": "John Doe", "age": 31}
# controller.update_product(2, new_name)

# controller.delete_product(2)
# controller.delete_product(1)
controller.read_products()


import numpy as np
import xml.etree.cElementTree as ET
from xml.etree import ElementTree
from structures import room as sr
from shapely.geometry import Polygon

def buildBoundingBoxExtremes(minX, minY, maxX, maxY):
	boundingBoxStr  = '<bounding_box>\n'
	boundingBoxStr += '<point x="'+str(minX)+'" y="'+str(minY)+'" />'+'\n'
	boundingBoxStr += '<point x="'+str(minX)+'" y="'+str(maxY)+'" />'+'\n'
	boundingBoxStr += '<point x="'+str(maxX)+'" y="'+str(maxY)+'" />'+'\n'
	boundingBoxStr += '<point x="'+str(maxX)+'" y="'+str(minY)+'" />'+'\n'
	boundingBoxStr += '</bounding_box>'
	return boundingBoxStr

def buildDatasetExtremes(vertices):
	extremes = ""
	for v in vertices:
		extremes += '<point x="'+str(int(v[0]))+'" y="'+str(int(v[1]))+'" />\n'
	return extremes

def crea_xml(nome_xml_segmentato, spazi, imageScale, vertices, connectedRooms):
	'''
	Creo xml delle stanze segmentate.
	'''
	#------------------CREO XML--------------------------------------------------------------------

	import uuid
	id_stanze = []
	connessi = {}
	for i,s in enumerate(spazi):
		id_stanze.append(i)
	for [r1,r2] in connectedRooms:
		if r1 not in connessi:
			connessi[r1] = []
		if r2 not in connessi:
			connessi[r2] = []
		connessi[r1].append(r2)
		connessi[r2].append(r1)

	xml = open(nome_xml_segmentato, "w")
	xml_id = uuid.uuid4()
	xml.write('<building id="'+str(xml_id)+'">\n<name>'+str(nome_xml_segmentato)+'</name>\n<scale>\n<represented_distance>\n<value>1</value>\n<um>pixel</um>\n</represented_distance>\n<real_distance>\n<value>'+str(imageScale)+'</value>\n<um>m</um>\n</real_distance>\n</scale>\n<Info>Inserire informazioni sull\'edificio</Info>\n<building_type>\n<main_type>SCHOOL</main_type>\n</building_type>\n<floor>\n')
	extremes = buildDatasetExtremes(vertices)
	xml.write('<bounding_polygon>\n'+extremes+'</bounding_polygon>\n')
	xml.write('<spaces>\n')
	for i,s in enumerate(spazi):
		#indice_gt_corrisp = indici_gt_corrispondenti_fwd[i]
		xml.write('<space id="'+str(id_stanze[i])+'">\n')
		xml.write('<partial_room>'+str(s.parziale)+'</partial_room>\n')
		boundingBoxStr = buildBoundingBoxExtremes(int(s.spazio.bounds[0]), int(s.spazio.bounds[1]), int(s.spazio.bounds[2]), int(s.spazio.bounds[3]))
		xml.write('<centroid>\n<point x="'+str(int(s.spazio.centroid.x))+'" y="'+str(int(s.spazio.centroid.x))+'" />\n</centroid>\n'+boundingBoxStr+'\n<bounding_polygon>\n')
		if s.spazio.boundary.type is 'MultiLineString':
			for l in s.spazio.boundary:
				b = l.coords.xy
				for n in xrange(0,len(b[0])):
					xml.write('<point x="'+str(int(b[0][n]))+'" y="'+str(int(b[1][n]))+'" />\n')

			xml.write('</bounding_polygon>\n<space_representation>\n')
			for l in s.spazio.boundary:
				b = l.coords.xy
				for n in xrange(0,len(b[0])-1):
					xml.write('<linesegment id="'+str(uuid.uuid4())+'">\n<point x="'+str(int(b[0][n]))+'" y="'+str(int(b[1][n]))+'" />\n<point x="'+str(int(b[0][n+1]))+'" y="'+str(int(b[1][n+1]))+'" />\n<class>WALL</class>\n<type>EXPLICIT</type>\n<features>NORMAL</features>\n</linesegment>\n')

		else:
			b = s.spazio.boundary.coords.xy
			for n in xrange(0,len(b[0])):
				xml.write('<point x="'+str(int(b[0][n]))+'" y="'+str(int(b[1][n]))+'" />\n')

			xml.write('</bounding_polygon>\n<space_representation>\n')
			for n in xrange(0,len(b[0])-1):
				xml.write('<linesegment id="'+str(uuid.uuid4())+'">\n<point x="'+str(int(b[0][n]))+'" y="'+str(int(b[1][n]))+'" />\n<point x="'+str(int(b[0][n+1]))+'" y="'+str(int(b[1][n+1]))+'" />\n<class>WALL</class>\n<type>EXPLICIT</type>\n<features>NORMAL</features>\n</linesegment>\n')
		r1 = i
		if r1 in connessi:
			xml.write('<portals>\n')
			for r2 in connessi[r1]:
				xml.write('<portal>\n')
				xml.write('<linesegment>UNKNOWN</linesegment>\n')
				xml.write('<class>UNKNOWN</class>\n')
				xml.write('<type>EXPLICIT</type>\n')
				xml.write('<direction>BOTH</direction>\n')
				xml.write('<target>\n')
				if r1 < r2:
					xml.write('<id>'+str(id_stanze[r1])+'</id>\n')
					xml.write('<id>'+str(id_stanze[r2])+'</id>\n')
				else:
					xml.write('<id>'+str(id_stanze[r2])+'</id>\n')
					xml.write('<id>'+str(id_stanze[r1])+'</id>\n')
				xml.write('</target>\n')
				xml.write('<features>NORMAL</features>\n')
				xml.write('</portal>\n')
			xml.write('</portals>\n')

		xml.write('</space_representation>\n')

		xml.write('</space>\n')

	xml.write('</spaces>\n</floor>\n</building>')
	xml.close()

	return id_stanze

def extractCoordsFromPoint(point):
	return float(point.get("x")), float(point.get("y"))

def extractBoundingPolygon(boxNode):
	vertices = boxNode.findall("point")
	return Polygon([extractCoordsFromPoint(v) for v in vertices])

def loadXML(XMLFile):
	''' Loads an XML Layout File and returns the set of rooms that it describes.'''
	tree = ET.parse(XMLFile)
	# get the root node (in this case, the "building" element)
	root = tree.getroot()
	# from here, there are a few interesting pieces of information to dump
	# get all children
	children = list(root)
	# bounding polygon
	boundingPolygonTag = root.find("floor").find("bounding_polygon")
	boundingPolygon = extractBoundingPolygon(boundingPolygonTag)
	# extract scale information as 1 pixel : n meters
	pixelScale = root.find("scale").findall(".//value")[0].text
	meterScale = root.find("scale").findall(".//value")[1].text
	scalingFactor = float(meterScale) / float(pixelScale)
	# extract information about rooms
	spaces = root.find("floor").find("spaces").findall("space")
	rooms = []
	connectedRooms = []
	# iterate over the rooms
	for space in spaces:
		# we need to recreate a polygon
		# collect its walls
		roomId = space.get("id")
		walls = space.findall(".//linesegment")
		vertices = []
		for w in walls:
			if w.find("point")!=None: # if this linesegment is really a line and not just a pointer
				vertices.append(w.find("point"))
		roomPolygon = Polygon([extractCoordsFromPoint(v) for v in vertices])
		# bounding box
		roomBoundingBoxTag = space.find("./bounding_box")
		roomBoundingBox = extractBoundingPolygon(roomBoundingBoxTag)
		# bounding polygon
		roomBoundingPolygonTag = space.find("./bounding_polygon")
		roomBoundingPolygon = extractBoundingPolygon(roomBoundingPolygonTag)
		room = sr.Room(roomId, roomPolygon, roomBoundingBox, roomBoundingPolygon, scalingFactor)
		rooms.append(room)
		# list all connections
		portals = space.findall(".//portal")
		for portal in portals:
			srcId = int(portal.find("target").findall("id")[0].text)
			dstId = int(portal.find("target").findall("id")[1].text)
			if srcId < dstId:
				connectedRooms.append([srcId,dstId])
		# print room
	return rooms, connectedRooms, boundingPolygon, scalingFactor


from PyQt5.QtWidgets import QGraphicsScene
from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QTransform, QCursor
from node import GraphicsNode
from edge import GraphicsEdge

class GraphicsGraph(QGraphicsScene):
    def __init__(self, *args, **kwargs):
        QGraphicsScene.__init__(self, *args, **kwargs)

        ellipse1 = GraphicsNode(label="lolilol")
        ellipse1.setPos(QPointF(-200,100))
        self.addItem(ellipse1)

        ellipse2 = GraphicsNode(label="lolilol")
        ellipse2.setPos(QPointF(200,100))
        self.addItem(ellipse2)

        edge = GraphicsEdge(ellipse1, ellipse2)
        self.addItem(edge)

    def mouseDoubleClickEvent(self, e):
        item = self.focusItem()
        if item != None:
            item.mouseDoubleClickEvent(e)
        elif e.button() == Qt.LeftButton and self.itemAt(e.scenePos(), QTransform()) == None:
            pos = e.scenePos()
            ellipse = GraphicsNode(label="lolilol")
            ellipse.setPos(pos)
            self.addItem(ellipse)
        else:
            e.ignore()

    def dragEnterEvent(self, e):
        if e.mimeData().hasText() :
            if e.mimeData().text() == "node":
                e.acceptProposedAction()
            else :
                e.ignore()
        else:
            e.ignore()

    def dragMoveEvent(self, e):
        if e.mimeData().hasText() :
            if e.mimeData().text() == "node":
                self.mouseGrabberItem().setPos(e.scenePos())
                self.update()
            else :
                e.ignore()
        else :
            e.ignore()

    def dropEvent(self,e):
        if e.mimeData().hasText() :
            if e.mimeData().text() == "node":
                self.mouseGrabberItem().setPos(e.scenePos())
                self.update()
            else :
                e.ignore()
        else :
            e.ignore()

    def keyPressEvent(self, e):
        items = self.selectedItems()
        if len(items) != 0:
            for item in items:
                if e.key() == Qt.Key_Delete :
                    if isinstance(item, GraphicsNode):
                        item.removeEdges()
                    self.removeItem(item)
        else:
            if self.focusItem() != None:
                self.focusItem().keyPressEvent(e)


# Face and eyes detection using Haar Cascade
import numpy as np
import cv2

face_cascade=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade=cv2.CascadeClassifier('haarcascade_eye_tree_eyeglasses.xml')

# img=cv2.imread('lena.jpg')
cap=cv2.VideoCapture(0)

while cap.isOpened():
    _,img=cap.read()
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    faces=face_cascade.detectMultiScale(gray,1.1,4)

    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),3)
        roi_gray=gray[y:y+h,x:x+w]
        roi_color=img[y:y+h,x:x+w]

        eyes=eye_cascade.detectMultiScale(roi_gray)

        for(xe,ye,we,he) in eyes:
            cv2.rectangle(roi_color,(xe,ye),(xe+we,ye+he),(255,0,0),2)

    cv2.imshow('img',img)
    if cv2.waitKey(1) & 0xFF==ord('q'):
        break

cap.release()


from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet

from ..accounts.permissions import IsReadOnly, IsStaffReadOnlyOrVendor
from .models import Cart, CartItem
from .serializers import (
    CartItemRootSerializer,
    CartItemSerializer,
    CartRootSerializer,
    CartSerializer,
)

class CartViewSet(ModelViewSet):
    queryset = Cart.objects.all()
    permission_classes = [IsAuthenticated, IsReadOnly]

    def get_queryset(self):
        if self.request.user.is_superuser or self.request.user.is_staff:
            qs = Cart.objects.all()
        else:
            qs = Cart.objects.filter(user=self.request.user)
        return qs

    def get_serializer_class(self):
        if self.request.user.is_superuser:
            return CartRootSerializer
        return CartSerializer

class CartItemViewSet(ModelViewSet):
    queryset = CartItem.objects.all()
    permission_classes = [IsAuthenticated, IsStaffReadOnlyOrVendor]

    def get_queryset(self):
        if self.request.user.is_superuser or self.request.user.is_staff:
            qs = CartItem.objects.all()
        else:
            qs = CartItem.objects.filter(cart=self.request.user.cart)
        return qs

    def get_serializer_class(self):
        if self.request.user.is_superuser:
            return CartItemRootSerializer
        return CartItemSerializer


# PANDS project on Fisher's Iris Data set

# Part of the overall course of Diploma in Computing in Data Analytics

# Thsi program is intend to read an input from a csv file of the 'Fisher’s Iris data set', then the program analyses the iris data set, outputs a number of csv summary files
# and gives the user an option to create a number of different scatter plots.

# Author: Nikolay Sezonov

# Submission date 16-Apr-22 as I have to submitted earlier :)

# After conducting some research 2 modules that i most likely will use with this programme are as follows:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

# Import matplotlib pyplot, pandasmodules and seaborn abbreviated to plt, pd and sns

# Code for plotting Histograms using seaborn
# Source:http://cmdlinetips.com/2019/02/how-to-make-histogram-in-python-with-pandas-and-seaborn/

iris_data = pd.read_csv("Iris-data-set.csv", header=None)

# Here I am setting up a variable for use in the program

sns.set(style="whitegrid", rc={'figure.figsize':(10,6)})
#sns.set is helping to set up the display box that you will be showing your graph in.

iris_data.columns =["Sepal length (cm)","Sepal width (cm)","Petal length (cm)","Petal width (cm)","Species"]
# Adding headers to attributes (columns); source: https://stackoverflow.com/a/28162530

print(' ') # Use of space to make the output more user - friendly

print ("Investigations on Iris Dataset") # Title of program being run

print ("All Graphs within this program will be automatically saved in the folder for viewing")

print(' ')

print('Unique Species Names') # This programme is being run to allow the user to indentify
# the three types of iris flower available in the dataset

print(' ')

print(iris_data['Species'].unique()) # Prints out the three types of iris species captured

print(' ')
print('------------------------------------------------------------------------------------------------------------')
print(' ')
# The above block is used as a spacing tool

print('Shape of the Iris Dataset')# Provides an overview of the data captured and potential outputs
# of further investigation Sourced: https://stackoverflow.com/questions/10200268/what-does-shape-do-in-for-i-in-rangey-shape0

print(' ')

print(iris_data.shape) # Prints the number of data entries in the data set along with number of the attributes
#.shape is a module from the pandas package

print(' ')
print('------------------------------------------------------------------------------------------------------------')
print(' ')

print ('Sample of Data contained in the Iris Dataset of all 150 records')# Random sample of the dataset.
# source: https://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.sample.html
print(' ')
print (iris_data.sample (5)) # Prints five random complete data entries from the data set
x = iris_data.sample(5)
#.sample is a module from the pandas package to enable user to see a random selection of data
# from the dataset

print(' ')
print('------------------------------------------------------------------------------------------------------------')
print(' ')

print ("Summary of Key Statistics from Iris Dataset of all 150 records")
# generates statistical analysis of the features of the measures of centre points and
# distribution of values
# source:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.describe.html

print(' ')
print (iris_data.describe())
# Prints in tabular form key statistics from the data.
# Provide high level analysis for the user
#.describe - a module that outputs the key statistics of the dataset
# Output sets the scene for following investigations that are more indepth and particular to each species
print(' ')
print('------------------------------------------------------------------------------------------------------------')
print(' ')

print('Median of attributes from Iris Dataset of all 150 records')
# This is an additional analysis conducted on the centre points of the data
# source: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.median.html

print(' ')
print(iris_data.median()) # Print the median of each of the attributes in tabular form

print(' ')
print('------------------------------------------------------------------------------------------------------------')
print(' ')

print ('Minimum, Maximum, Mean and Median of each attribute for each species in dataset')
# The following analysis looks at the maximum, minimum, mean and median of each of the numerical categories
print(' ')
# all modules are from the pandas package

print('Min ')
# Extracts the minimum values of each of the attributes
print(iris_data.groupby('Species').min()) # Prints in tabular form and also groups the data by the three species
# Graph variables set up for bar chart to be displayed and saved into the repository

iris_min = iris_data.groupby('Species').min()
iris_min.plot.bar()
# Module to create table of minimum values for each species.
# Source: https://pandas.pydata.org/pandas-docs/version/0.23/generated/pandas.DataFrame.plot.bar.html

plt.gcf().subplots_adjust(bottom=0.15)
# Adjusting the table to enable table to be fully seen in the window.
# Source: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots_adjust.html

plt.xlabel('Iris Species', fontsize=14, weight='normal')
# Applying text and font to the table on the x axis.
# Source: https://stackoverflow.com/questions/12444716/how-do-i-set-the-figure-title-and-axes-labels-font-size-in-matplotlib

plt.ylabel("Min Values", fontsize=14, weight='normal')
# Applying text and font to the table on the y axis

title = "Min Value of Attributes of each of Iris Species"
# Applying a title to the dataset

filename = "Min Value of Attributes of each of Iris Species.jpg"
# The name of the file to which the graph will be saved to

plt.title(title, fontsize=14, weight='bold')
# Apply text and font detail to the title

plt.gcf().subplots_adjust(bottom=0.3)
# plt.show()
# plt.close()

filename = "Min of Attributes of each of Iris Species.jpg"

plt.savefig(filename)
# File will be saved and then will close to allow continuing of the program execution.
# Source:https://stackoverflow.com/questions/44383638/how-to-save-matplotlib-plot-with-the-same-file-name-as-its-filename-py

plt.close()
print(' ')

print('Max')  # Extracts the maximum values of each of the attributes
print(iris_data.groupby('Species').max())

# The sources and explaination are the same for all tables in this group

# Graph variables set up for bar chart to be displayed and saved into the repository

iris_max = iris_data.groupby('Species').max()
iris_max.plot.bar()
plt.gcf().subplots_adjust(bottom=0.15)
plt.xlabel('Species', fontsize=14, weight='normal')
plt.ylabel("Max Values", fontsize=14, weight='normal')
title = "Max Value of Attributes of each of Iris Species"
plt.title(title, fontsize=14, weight='bold')
plt.gcf().subplots_adjust(bottom=0.3)
#plt.show()
#plt.close()

filename = "Max of Attributes of each of Iris Species.jpg"
plt.savefig(filename)
plt.close()
print(' ')

print('Mean')  # Extracts the mean values of each of the attributes
print(iris_data.groupby('Species').mean()) # Prints in tabular form
print(' ')

# Graph variables set up for bar chart to be displayed and saved into the repository

iris_mean = iris_data.groupby('Species').mean()
iris_mean.plot.bar()
plt.gcf().subplots_adjust(bottom=0.15)
plt.xlabel('Species', fontsize=14, weight='normal')
plt.ylabel("Mean Values", fontsize=14, weight='normal')
title = "Mean Value of Attributes of each of Iris Species"
filename = "Mean Value of Attributes of each of Iris Species.jpg"
plt.title(title, fontsize=14, weight='bold')
plt.gcf().subplots_adjust(bottom=0.3)

filename = "Mean of Attributes of each of Iris Species.jpg"
plt.savefig(filename)
plt.close()
print(' ')

print('Median')  # Extracts the median values of each of the attributes
print(iris_data.groupby('Species').median()) # Prints in tabular form
print(' ')

#Graph variables set up for bar chart to be displayed and saved into the repository

iris_median = iris_data.groupby('Species').median()
iris_median.plot.bar()
plt.gcf().subplots_adjust(bottom=0.15)
plt.xlabel('Species',fontsize=14, weight='normal')
plt.ylabel("Median Values", fontsize=14, weight='normal')
title = "Median Value of Attributes of each of Iris Species"
filename = "Median Value of Attributes of each of Iris Species.jpg"
plt.title(title, fontsize=26, weight='bold')
plt.gcf().subplots_adjust(bottom=0.3)

filename = "Median of Attributes of each of Iris Species.jpg"
plt.savefig(filename)
plt.close()
print(' ')

print('This is a summary of all species and their attributes') #This program aims to output all
# the summary data for the three species
for i in iris_data['Species'].unique():
# While the .unique module is running, the program will gather data for each of
# the unique values and output a summary table

    build_list = iris_data['Species'] == i
    # This for loop will run for a long as there are new data being generated from the Species column.

    species = iris_data[build_list] # the module build list, creates a table for each species and outputs
    # the summary data as per.describe module

    print('\n', i, '\n', species.describe(), '\n')

    # Source: http://www.lac.inpe.br/~rafael.santos/Docs/CAP394/WholeStory-Iris.html

print(' ')
print('------------------------------------------------------------------------------------------------------------')
print(' ')

print ("Distributions of Each Attributes")
print(' ')
print ("All Graphs within this program will be automatically saved in the folder for viewing")
print(' ')
title = "Comparison of the Distributions of Sepal Length"
sns.boxplot(x="Species", y="Sepal length (cm)", data=iris_data)
# the seaborn boxplot function enables comparison between the distributions of each attribute.
# Source: https://seaborn.pydata.org/generated/seaborn.boxplot.html

plt.title(title, fontsize=14, weight='bold')
# Source: https://python-graph-gallery.com/30-basic-boxplot-with-seaborn/

plt.gcf().subplots_adjust(bottom=0.3)
plt.xlabel('Species', fontsize=14, weight='normal')
plt.ylabel("Sepal Length", fontsize=14, weight='normal')

filename = "Comparison of the Distributions of Sepal Length.jpg"
plt.savefig(filename)
plt.close()
print(' ')

title="Comparison of the Distributions of Sepal Width"
sns.boxplot(x="Species", y="Sepal width (cm)", data=iris_data)
plt.title(title, fontsize=14, weight='bold')
plt.gcf().subplots_adjust(bottom=0.3)
plt.xlabel('Species', fontsize=14, weight='normal')
plt.ylabel("Width", fontsize=14, weight='normal')

filename = "Comparison of the Distributions of Sepal Width.jpg"
plt.savefig(filename)
plt.close()
print(' ')

title="Comparison of the Distributions of Petal Length"
sns.boxplot(x="Species", y="Petal length (cm)", data=iris_data)
plt.title(title, fontsize=14, weight='bold')
plt.gcf().subplots_adjust(bottom=0.3)
plt.xlabel('Species', fontsize=14, weight='normal')
plt.ylabel("Petal Length", fontsize=14, weight='normal')
filename = "Comparison of the Distributions of Petal Length.jpg"
plt.savefig(filename)
plt.close()
print(' ')

title="Comparison of the distributions of Petal Width"
sns.boxplot(x="Species", y="Petal width (cm)", data=iris_data)
plt.title(title, fontsize=14, weight='bold')
plt.gcf().subplots_adjust(bottom=0.3)
plt.xlabel('Species', fontsize=14, weight='normal')
plt.ylabel("Petal Width", fontsize=14, weight='normal')
filename = "Comparison of the Distributions of Petal Width.jpg"
plt.savefig(filename)
plt.close()

print(' ')
print('------------------------------------------------------------------------------------------------------------')
print(' ')

print ("Correlation between the Sepal Characteristics and the Petal Characteristics to examine prediction factors")
print ("All Graphs within this program will be automatically saved in the folder for viewing")
print('Correlation of all')
print(iris_data.iloc[0:].corr())

# Plotting Petal Length vs Petal Width & Sepal Length vs Sepal width

plt.figure()
# Source: https://www.kaggle.com/sridharcr/data-analysis-iris-dataset
fig,ax=plt.subplots(1,2,figsize=(18, 10))

# Source: https://www.kaggle.com/abhishekkrg/python-iris-data-visualization-and-explanation

iris_data.plot(x="Sepal length (cm)",y="Sepal width (cm)",kind="scatter",ax=ax[0],sharex=False,sharey=False,label="Sepal",color='r')
iris_data.plot(x="Petal length (cm)",y="Petal width (cm)",kind="scatter",ax=ax[1],sharex=False,sharey=False,label="Petal",color='b')
ax[0].set(title='Sepal Comparison ', ylabel='Sepal width (cm)')
ax[1].set(title='Petal Comparison ', ylabel='Petal width (cm)')
ax[0].set(xlabel='Sepal Length (cm)')
ax[1].set(xlabel='Petal Length (cm)')
ax[0].legend()
ax[1].legend()
plt.gcf().subplots_adjust(bottom=0.3)
filename = "Corellation between Petal Length vs Petal Width & Sepal Length vs Sepal width.jpg"
plt.savefig(filename)
plt.close()


import copy
import cnn_data
import cnn_output_data as cod
import model_cnn
import model_cnn_output as mco
import numpy as np
import path
import sklearn.metrics
import tensorflow as tf
import utils
import windower

class classify_artifact:
	'''Classify the artifacts and clean parts of a eeg block.'''
	def __init__(self,name = None,model_cnn_name = 'rep-3_perc-50_fold-2_part-90' , mco_name = 'cnn_output_model_wl-201_perc-93',fo = None,block = None,make_adj_pred = False):
		tf.reset_default_graph()
		self.fo = fo
		if not self.set_block_name(block,name): return None
		self.model_cnn_name = model_cnn_name
		self.mco_name = mco_name
		if make_adj_pred:
			self.load_predicted()
			self.generate_predicted_adj()

	def __str__(self):
		m = 'name:\t\t\t' + str(self.name) + '\n'
		m += 'model_cnn_name:\t\t' + str(self.model_cnn_name) + '\n'
		m += 'mco:\t\t\t' + str(self.mco_name) + '\n'
		if hasattr(self,'predicted') and isinstance(self.predicted,np.ndarray): m += 'predicted:\t\tavailable\n'
		else: m += 'predicted:\t\tNA\n'
		if hasattr(self,'predicted_adj') and isinstance(self.predicted_adj,np.ndarray): m += 'predicted_adj:\t\tavailable\n'
		else: m += 'predicted_adj:\t\tNA\n'
		if hasattr(self,'predicted_perc') and isinstance(self.predicted_perc,np.ndarray): m += 'predicted_perc:\t\tavailable\n'
		else: m += 'predicted_perc:\t\tNA\n'
		return m

	def __repr__(self):
		return 'classify-artifact: ' +self.name.replace('_',' ')

	def load_predicted(self):
		'''Load artifact classifications.'''
		self.do = cod.cnn_output2data(name= self.name, model_name = self.model_cnn_name)
		self.predicted = self.do.predicted

	def generate_predicted(self, clean_up = True, save = True):
		'''Classify eeg data on artifacts.'''
		d = cnn_data.cnn_data(2) # fold 2 was used for training, 10 fold training and testing was computationally to expensive
		self.m = model_cnn.load_model(path.model + self.model_cnn_name,d)
		self.predicted_class, self.predicted_perc = self.m.predict_block(self.block, save = save)
		# self.predicted = self.predicted_perc[:,1]
		self.load_predicted()
		self.m.clean_up()

	def generate_predicted_adj(self, identifier = '', save = True):
		'''Adjust predicted artifacts generated by model_cnn with mco model.
		compare with ground trouth if available.
		'''
		self.predicted_adj = copy.copy(self.do.pc)

		if self.do.predicted_artifact_data.shape[0] > 0:
			self.mo = mco.load_model(path.cnn_output_data + self.mco_name,self.do)
			self.predicted_artifact_adj = self.mo.compute_prediction_class(data=self.do.predicted_artifact_data)
			self.predicted_adj[self.do.predicted_artifact_indices] = self.predicted_artifact_adj
			self.mo.clean_up()

		if not isinstance(self.do.ground_truth,np.ndarray) or np.max(self.do.ground_truth) >1 : self.confusion_matrix_adj = np.zeros((2,2))
		else: self.confusion_matrix_adj = sklearn.metrics.confusion_matrix(self.do.ground_truth,self.predicted_adj, labels = [0,1])
		self.output_name = path.snippet_annotation+ identifier + self.model_cnn_name + '_' + self.name
		self.eval_name = path.confusion_matrices + identifier + self.model_cnn_name + '_' + self.name
		if save:
			np.save(self.output_name + '_class-adj', self.predicted_adj)
			if isinstance(self.do.ground_truth, np.ndarray):
				np.save(self.eval_name+ '_cm', self.do.confusion_matrix)
				np.save(self.eval_name+ '_cm-adj', self.confusion_matrix_adj)
			else:print('no ground truth for',self.name)

	def set_block_name(self,block,name):
		'''Sets name and loads corresponding block object.'''
		if name == None and block == None:
			print('Please provide name or block object.')
			return False
		if name == None:
			self.name = windower.make_name(block)
			self.block = block
		if block == None:
			self.block = utils.name2block(name,self.fo)
			self.name = name
		return True

def get_names_output_files(model_name = 'rep-3_perc-50_fold-2_part-90'):
	'''Get the filenames of the perc files, which are output from a cnn model.

	model_name  	name of the cnn model to generate the output files.
	'''
	fn = glob.glob(path.snippet_annotation + model_name + '_pp*class.npy')
	names = [f.split('part-90_')[-1].split('_class.npy')[0] for f in fn]
	return names


from typing import Optional

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# O(h + k) time | O(h) space, h --> height of the tree
class Solution:
    def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        stack = []
        count = 0
        node = root
        while node or stack:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            count += 1
            if count == k:
                return node.val
            node = node.right


# !/usr/python2.7
# main.py
'''
If adding a new page, need to add a new tuple into the handlers list
'''
import webapp2
from handler import *

handlers = [('/base', BasePage),
			('/', MainPage),
			('/building', BuildPage),
			('/about', AboutPage),
			('/contact', ContactPage),
			# these are for later
			('/donation', DonationPage),
			('/error', ErrorPage),
			('/rank', RankPage),

			('/signup', SignupPage),
			('/login', LoginPage),
			('/logout', LogoutPage),
			(r'/game-([^/-]+)-([^/-]+)', GamePage),
			(r'/profile', ProfilePage),

			#the following is lessons, later
			(r'/course-([^/-]+)', CoursePage),
			(r'/course-([^/-]+)-lesson-([^/-]+)', LessonPage),

			('/buildLesson', BuildLesson),
			('/buildCourse', BuildCourse),
			('/chart', chartPage),
			('/courseProgress', ProgressPage)
]

application = webapp2.WSGIApplication(handlers, debug=True)


import random
from cmath import sqrt
from collections import Counter
from statistics import mode

import numpy as np
import pandas as pd
import operator
# from natsort import index_natsorted, order_by_index

# Calculate the Euclidean distance between two vectors
# q, p: are lists
def euclidean_distance(q, p):
    p = np.array(p)
    q = np.array(q)
    distance = 0.0
    for i in range(len(p[0])-1):
        distance += (q[0][i] - p[0][i])**2
    return sqrt(distance).real

# def sort_according_to_class_lbl(data):
#     return data.reindex(index=order_by_index(data.index, index_natsorted(data['class_lbl'])))

# Get the most nearest
def get_neighbors(train_data, test_row, k):
    distances = []
    for i in range(len(train_data)):
        train_row = train_data[i:i+1]
        train_row = np.array(train_row)
        dist = euclidean_distance(test_row, train_row)
        distances.append((train_row, dist))
    # Sort according to the second parameter which is the distance
    distances.sort(key=lambda tupl: tupl[1])
    neighbors = []
    for i in range(k):
        neighbors.append(distances[i][0])
    return neighbors

def get_response(neighbors):
    class_lbls = {}
    for i in range(len(neighbors)):
        response = neighbors[i][0][-1]
        if response in class_lbls:
            class_lbls[response] += 1
        else:
            class_lbls[response] = 1
    sorted_class_lbls = sorted(class_lbls.items(), key=operator.itemgetter(1), reverse=True)
    return sorted_class_lbls

def predict_classification(train_data, test_row, k):
    neighbors = get_neighbors(train_data, test_row, k)
    # output_values: is the distances of each neighbor
    output_values = [row[-1] for row in neighbors]
    class_lbls = [row[-1] for row in output_values]
    # Get the most repeated value.
    prediction = get_most_rep_class_lbl(class_lbls)

    # print(mode(class_lbls))
    return prediction

def get_most_rep_class_lbl(class_lbls):
    # get a dict, key is the elements in class_lbls, value is count of the element
    d_mem_count = Counter(class_lbls)
    maxi = max(d_mem_count, key=d_mem_count.get)
    return maxi

def predict_all_tests(train_data, test_data, k):
    predictions = []
    for i in range(len(test_data)):
        predic = predict_classification(train_data, test_data[i:i+1], k)
        actual = test_data[i:i+1]['class_lbl'].to_string()[-3:]
        print("Predicted class: %s" %predic + ", Actual class: %s" %actual)
        predictions.append(predic)
    return predictions

def cal_accuracy(test_data, predictions):
    right = 0.0
    for i in range(len(test_data)):
        actual = test_data[i:i+1]['class_lbl'].to_string()[-3:]
        # print(actual, predictions[i])
        if actual == predictions[i]:
            right += 1.0
    print("Number of correctly classified instances : %d" %right + ", Total number of instances : %d" %len(test_data))
    accuracy = right/len(test_data)
    return accuracy

names = ['f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'class_lbl']

test_data = pd.read_csv('TestData.txt', header=None, names=names)
train_data = pd.read_csv('TrainData.txt', header=None, names=names)
# print(euclidean_distance(train_data[0:1], train_data[1:2]))
k = 3
print("k value = %d" %k)
neighbors = get_neighbors(train_data, test_data[0:1], k)
predictions = predict_all_tests(train_data, test_data, k)
accuracy = cal_accuracy(test_data, predictions)
print("Accuracy : %f" %accuracy)


from django.contrib import admin

from mainapp import models

class MovieAdmin(admin.ModelAdmin):
    list_filter = ('release_date',)
    fieldsets = (
        (None, {
            'fields': ('title', 'release_date')
        }),
        ('Details', {
            'classes': ('collapse',),
            'fields': ('description',),
        }),
    )

admin.site.register(models.Movie, MovieAdmin)


from typing import Literal, Optional, Union

from playwright.sync_api import (
    Browser,
    BrowserContext,
    ElementHandle,
    Locator,
    Page,
    Playwright,
)
from robocorp_ls_core.robotframework_log import get_logger

from ._browser_engines import BrowserEngine

__version__ = "2.1.0"
version_info = [int(x) for x in __version__.split(".")]

log = get_logger(__name__)

def configure(**kwargs) -> None:
    """
    May be called before any other method to configure the browser settings.

    Calling this method is optional (if not called a default configuration will
    be used -- note that calling this method after the browser is already
    initialized will have no effect).

    Args:
        browser_engine: Browser engine which should be used (default: Chromium)
        headless: If set to False the browser UI will be shown. If set to True
            the browser UI will be kept hidden. If unset or set to None it'll
            show the browser UI only if a debugger is detected.
        slowmo: Run interactions in slow motion.
        screenshot: Whether to automatically capture a screenshot after each task.
            Options are `on`, `off`, and `only-on-failure` (default).
        viewport_size: Size to be set for the viewport. Specified as tuple(width, height).

    Note:
        See also: `robocorp.browser.configure_context` to change other
        arguments related to the browser context creation.
    """  # noqa
    from ._browser_context import _browser_config

    config = _browser_config()

    for key, value in kwargs.items():
        if key == "viewport_size":
            width, height = value
            configure_context(viewport={"width": width, "height": height})
            continue

        if not hasattr(config, key):
            raise ValueError(f"Invalid configuration: {key}.")
        setattr(config, key, value)

def configure_context(**kwargs) -> None:
    """
    While the most common configurations may be configured through `configure`,
    not all arguments passed to `playwright.Browser.new_context` are covered.

    For cases where different context keyword arguments are needed it's possible
    to use this method to customize the keyword arguments passed to
    `playwright.Browser.new_context`.

    Example:
        ```python
        from robocorp import browser
        browser.configure_context(ignore_https_errors = True)
        ```

    Note:
        The changes done persist through the full session, so, new tasks which
        create a browser context will also get the configuration changes.
        If the change should not be used across tasks it's possible
        to call `robocorp.browser.context(...)` with the required arguments
        directly.
    """
    from . import _browser_context

    browser_context_kwargs = _browser_context.browser_context_kwargs()
    browser_context_kwargs.update(kwargs)

def page() -> Page:
    """
    Provides a managed instance of the browser page to interact with.

    Returns:
        The browser page to interact with.

        Note that after a page is created, the same page is returned until the
        current task finishes or the page is closed.

        If a new page is required without closing the current page use:

        ```python
        from robocorp import browser
        page = browser.context().new_page()
        ```
    """
    from . import _browser_context

    return _browser_context.page()

def browser() -> Browser:
    """
    Provides a managed instance of the browser to interact with.

    Returns:
        The browser which should be interacted with.

        If no browser is created yet one is created and the same one
        is returned on new invocations.

        To customize the browser use the `configure` method (prior
        to calling this method).

        Note that the returned browser must not be closed. It will be
        automatically closed when the task run session finishes.
    """
    from . import _browser_context

    return _browser_context.browser()

def playwright() -> Playwright:
    """
    Provides a managed instance of playwright to interact with.

    Returns:
        The playwright instance to interact with.

        If no playwright instance is created yet one is created and the same one
        is returned on new invocations.

        To customize it use the `configure` method (prior
        to calling this method).

        Note that the returned instance must not be closed. It will be
        automatically closed when the task run session finishes.
    """
    from . import _browser_context

    return _browser_context.playwright()

def context(**kwargs) -> BrowserContext:
    """
    Provides a managed instance of the browser context to interact with.

    Returns:
        The browser context instance to interact with.

        If no browser context instance is created yet one is created and the
        same one is returned on new invocations.

        Note that the returned instance must not be closed. It will be
        automatically closed when the task run session finishes.

    Note:
        If the context is not created it's possible to customize the context
        arguments through the kwargs provided, by using the `configure(...)`
        method or by editing the `configure_context(...)` returned dict.

        If the context was already previously created the **kwargs passed will
        be ignored.
    """
    from . import _browser_context

    return _browser_context.context(**kwargs)

def goto(url: str) -> Page:
    """
    Changes the url of the current page (creating a page if needed).

    Args:
        url: Navigates to the provided URL.

    Returns:
        The page instance managed by the robocorp.tasks framework
        (it will be automatically closed when the task finishes).
    """
    p = page()
    p.goto(url)
    return p

def screenshot(
    element: Optional[Union[Page, ElementHandle, Locator]] = None,
    timeout: int = 5000,
    image_type: Literal["png", "jpeg"] = "png",
) -> bytes:
    """
    Takes a screenshot of the given page/element/locator and saves it to the
    log. If no element is provided the screenshot will target the current page.

    Note: the element.screenshot can be used if the screenshot is not expected
    to be added to the log.

    Args:
        element: The page/element/locator which should have its screenshot taken. If not
        given the managed page instance will be used.

    Returns:
        The bytes from the screenshot.
    """
    import base64

    if element is None:
        from . import _browser_context

        element = _browser_context.page()

    in_bytes = element.screenshot(timeout=timeout, type=image_type)
    # in_base64 = base64.b64encode(in_bytes).decode("ascii")

    return in_bytes

def install(browser_engine: BrowserEngine):
    """
    Downloads and installs the given browser engine.

    Note: Google Chrome or Microsoft Edge installations will be installed
    at the default global location of your operating system overriding your
    current browser installation.

    Args:
        browser_engine: Browser engine which should be installed
    """
    from . import _browser_engines

    _browser_engines.install_browser(browser_engine, force=False)

__all__ = [
    "configure",
    "configure_context",
    "page",
    "browser",
    "playwright",
    "context",
    "goto",
    "screenshot",
    "install",
    "BrowserEngine",
]


from django.urls import include, path
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

from django.contrib import admin
admin.autodiscover()

from . import views

app_name = 'ats'

urlpatterns = [
    path('', views.index, name='index'),
    path('error_internal/', views.errorinternal, name='error_internal'),
    path('top/', views.top, name='top'),
    path('login/', views.login_view, name='login_view'),
    path('logout/', views.logout_view, name='logout_view'),
    path('regist/', views.regist, name='regist'),
    #
    # path('summary/', views.summary, name='summary'),
    path('summary/project/', views.summary_p, name='summary_p'),
    path('summary/job/', views.summary_j, name='summary_j'),
    path('summary/user/', views.summary_u, name='summary_u'),
    #
    # direct link
    #
    # path('summary/(?P<project_id>\d+)/', views.summary_p),
    # path('summary/(?P<project_id>\d+)/(?P<from_date>\d+)_(?P<to_date>\d+)/', vi ews.summary_pd),
    # path('summary/(?P<project_id>\d+)/(?P<from_date>\d+)_(?P<to_date>\d+)/u(?P<user_id>\d+)/', views.summary_pdu),
    # path('summary/(?P<project_id>\d+)/(?P<from_date>\d+)_(?P<to_date>\d+)/j(?P<job_id>\d+)/, views.summary_pdj),
    #
    path('query/', views.query, name='query'),
    #
    # path('api/', views.api),
    #
    path('manage/', views.manage, name='manage'),
    #
    path('manage/chpasswd/', views.manage_chpasswd, name='manage_chpasswd'),
    # path('manage/user/', views.manage_user_list, name='manage_user_list'),
    # path('manage/user/(?P<user_id>\d+)/', views.manage_user_detail, name='manage_user_detail'),
    # path('manage/project/', views.manage_project_list, name='manage_project_list'),
    # path('manage/project/(?P<project_id>\d+)/', views.manage_project_detail, name='manage_project_detail'),
    # path('manage/task/', views.manage_task_list, name='manage_task_list'),
    # path('manage/task/(?P<task_id>\d+)/', views.manage_task_detail, name='manage_task_detail'),
    # path('manage/job/', views.manage_job_list, name='manage_job_list'),
    # path('manage/job/(?P<job_id>\d+)/', views.manage_job_detail, name='manage_job_detail'),
]

urlpatterns += staticfiles_urlpatterns()


from numpy import array,exp
import sys
import matplotlib.pyplot as plt
import getopt
from os.path import exists
from lib import parse_doscar,parse_poscar,tunneling_factor

def plot_weighted_dos(doscar,poscar,V,phi,**args):
    dos, energies, ef = parse_doscar(doscar)
    atomtypes, atomnums = parse_poscar(poscar)[2:4]

    if 'irange' in args and len(args['irange'])>0:
        integrate_dos=True
        irange=args['irange']
        erange=[]
        for i in range(len(energies)):
            if energies[i]>min(irange) and energies[i]<max(irange):
                erange.append(energies[i])
            elif energies[i]<min(irange):
                emin=i
            elif energies[i]>max(irange):
                emax=i
                break
    else:
        integrate_dos=False

    if 'nums' in args:
        nums=args['nums']
    else:
        nums=[]
    if 'types' in args:
        types=args['types']
    else:
        types=[]
    selected_atoms=[]
    if len(types)>0 and len(nums)>0:
        counter=1
        for i in atomtypes:
            if i in types:
                for j in range(atomnums[atomtypes.index(i)]):
                    if counter in nums:
                        selected_atoms.append(counter)
                    counter+=1
            else:
                counter+=atomnums[atomtypes.index(i)]
    elif len(nums)>0:
        selected_atoms=nums
    elif len(types)>0:
        counter=0
        for i in atomtypes:
            if i in types:
                for j in range(atomnums[atomtypes.index(i)]):
                    selected_atoms.append(counter)
                    counter+=1
            else:
                counter+=atomnums[atomtypes.index(i)]
    else:
        selected_atoms=[i for i in range(sum(atomnums))]

    K=array([exp(-1.0e-10*tunneling_factor(V,i,phi)) for i in energies])

    plt.figure()
    for i in selected_atoms:
        for j in range(len(atomnums)):
            if i<sum(atomnums[:j+1]):
                atomlabel=atomtypes[j]
                break
        if not integrate_dos:
            tempy=array([0.0 for j in range(len(energies))])
            for j in range(len(dos[i+1])):
                tempy+=dos[i+1][j]*K
            plt.plot(energies,tempy,label='{} #{}'.format(atomlabel,i-sum(atomnums[:atomtypes.index(atomlabel)])))
        else:
            tempy=array([0.0 for j in range(len(erange))])
            for j in range(len(dos[i+1])):
                tempy+=dos[i+1][j][emin+1:emax]*K[emin+1:emax]
            for j in range(1,len(tempy)):
                tempy[j]+=tempy[j-1]
            plt.plot(erange,tempy,label='{} #{}'.format(atomlabel,i-sum(atomnums[:atomtypes.index(atomlabel)])))
    plt.xlabel('energy - $E_f$ / eV')
    if not integrate_dos:
        plt.ylabel('DOS / states $eV^{-1}$')
    else:
        plt.ylabel('integrated DOS / # states')
    plt.legend()
    plt.show()

if __name__=='__main__':
    irange=[]
    doscar='./DOSCAR'
    if exists('./CONTCAR'):
        poscar='./CONTCAR'
    else:
        poscar='./POSCAR'
    atomnums=[]
    atomtypes=[]
    try:
        opts,args=getopt.getopt(sys.argv[1:],'a:t:i:hp:',['atomnums=','types=','integrated=','help','phi='])
    except getopt.GetoptError:
        print('error in command line syntax')
        sys.exit(2)
    for i,j in opts:
        if i in ['-a','--atomnums']:
            atomnums=[int(k) for k in j.split(',')]
        if i in ['-t','--types']:
            atomtypes=[str(k) for k in j.split(',')]
        if i in ['-i','--integrated']:
            irange=[float(k) for k in j.split(',')]
        if i in ['-h','--help']:
            print('''
required arguments:
-p, --phi               specify the work function, which is used to weight the DOS by the probability of tunneling into a state at its corresponding energy

plotting options:
-a, --atomnums          specify site projected DOS to plot by the index of atoms: 1,2,3,etc...
-t, --types             specify which site projected DOS to plot by atom type: Au,C,etc...
-i, --integrated        integrate the DOS between the range specified. ie -i 0,3 will plot the integrated DOS from 0 to 3 eV above the Fermi level

help options:
-h, --help               display this help message
                  ''')
            sys.exit()
    if exists(doscar):
        plot_weighted_dos(doscar,poscar,nums=atomnums,types=atomtypes,irange=irange)


import numpy as np
from numpy import linalg as lin
import math
import filterpy
from filterpy.kalman import KalmanFilter
from munkres import Munkres

# Theorie GNN : https://www.youtube.com/watch?v=MDMNsQJl6-Q&list=PLadnyz93xCLiCBQq1105j5Jeqi1Q6wjoJ&index=21&t=0s
def gnn(data,p_d,lambda_c,F,H,n,R,Q,init_values):
    #data Messung aller Zeitschritten
    #p_d =detection rate
    #lambda_c Clutter Intensität
    #F, H  System bzw Ausgangsmatrux
    #n Anzahl Objekten
    #R,Q Kovarianz Matrizen
    #Algorithmus eignet sich nur für GNN mit einem linearen und gaußverteilten Modell
         #Initialisierung
        hungarian = Munkres() # Objekt, welches den Hungarian Algorithmus darstellt
        number_states = len(F) # Zuständezahl
        theta_k = np.zeros((1,n)) #Data Assossiation Vektor
        number_coordinates = int(number_states/2) # Zahl Koordinaten: 1 wenn z= x, 2 wenn z=[x;y]
        estimate = np.zeros((number_states,n)) # Zustände geschätz
        estimate[0:number_states,0:n] = init_values #Anfangswerte hinzufügen
        P = np.zeros((number_states,n*number_states)) #Kovarianzmatrix des Schätzfehlers
        #total_cost = 0 #Kosten Data Assossiation
        estimate_all =[]
        estimate_all.append(init_values.tolist()) #Liste mit  Erwartungswerten von allen Zuständen aller Objekten über alle Zeitschritten
        z_opt_assossiation= 0 # Messung der wahrscheinlichsten Hypothese

        ## Berechnung mit Messdaten/Testdaten
        while len(data)>0: #While: data nicht leer
            measurement_k = data.pop(0)  #Erste Messung aus Datensatz (wird danach aus Datenliste entfernt)
            m= len(measurement_k) #Anzahl Messungen pro Zeitschritt k
            L_detection = np.zeros((n,m)) #Kostfunktion detektiert
            L_missdetection = np.zeros((n,n)) #Kostfunktion nicht-detektiert
            L_missdetection[:,:] = np.inf # Alle Einträge gleich unendlich setzen
            L = np.zeros((n,m+n)) #Gesamte Kostenmatrix

            for i in range(n):
                estimate_i = np.transpose(estimate[0:number_states,i] )   #Zustandände pro Objekt aus der gesamten estimates Matrix extraieren. Muss Transponiert werden, da Python mit stehenden Vektoren nicht umgehen kann
                P_i= P[0:number_states,i*number_states:number_states*(i+1)] #Kovarianz pro Objekt aus der gesamten P matrix extraieren
            #Prädiktion mit Kalmanfilter
                estimate_i,P_i = kalman_filter_prediction(estimate_i, P_i,F,Q)

            #Kostenmatrix erzeugen
                S = R+ np.matmul(H,np.matmul(P_i,np.transpose(H))) #Inovation Kovarianz
                z_hat = np.matmul(H,estimate_i) #Predicted detection
                L_missdetection[i][i] = np.log(1-p_d)
                for j in range(m):
                    if number_coordinates == 1:

                        L_detection[i][j] =  np.log(p_d/lambda_c) - 0.5*np.log(2*math.pi*abs(S))-0.5*1/S*(measurement_k[j]-z_hat)*(measurement_k[j]-z_hat)

                    else:
                        L_detection[i][j] = np.log(p_d/lambda_c) - 0.5*np.log(np.linalg.det(2*math.pi*S))-0.5*(np.matmul(np.transpose((measurement_k[j]-z_dach)),np.matmul(np.linalg.inv(S),(z_dach-measurement_k[j]))))

            L= np.concatenate((L_detection,L_missdetection),axis=1) #L_detection und L_missdetection zusammensetzen

            #Berechnen assignment Matrix A mit Hungarian Algorithmus
            indexes_opt = hungarian.compute(L) #Assignment matrix indexes

            # Berechnung von Data Assossiation theta_k
            for i in range(n):

                #total_cost += L[i][indexes_opt[i][1]]
                #weight_opt = np.exp(-total_cost)
                #Fallunterscheidung: theta = index von Messung wenn die Detektion einem Objekt entspicht, theta = 0 wenn die Detektion einem Clutter entspricht
                if indexes_opt[i][1]< m :
                    theta_k[0][i] = indexes_opt[i][1] +1
                    if number_coordinates ==1 :
                       z_opt_assossiation = measurement_k[indexes_opt[i][1]] # Messung der wahrscheinlichsten Hypothese
                    else:
                       z_opt_assossiation = measurement_k[np.arange(0,number_coordinates,1)][indexes_opt[i][1]]

                else:
                    theta_k[0][i] = 0

                estimate_i,P_i = kalman_filter_update(estimate_i,P_i,H,z_opt_assossiation,theta_k[0][i],R,number_coordinates) #Update P und estimate_i mit Kalman-Korrekturschritt
                P[0:number_states,i*number_states:number_states*(i+1)] = P_i #P_i in die gesamte P Matrix wieder einfügen
                estimate[0:number_states,i] = estimate_i #estimates_i in die gesamte estimates Matrix wieder einfügen

            estimate_all.append(estimate.tolist())

        return estimate_all

def kalman_filter_prediction(estimates_i, P_i,F,Q):
    estimates_i, P_i = filterpy.kalman.predict(estimates_i, P_i,F,Q) #Kalman Prädiktion estimates und P
    return estimates_i, P_i

def kalman_filter_update(estimate_i,P_i,H,z_opt_assossiation,theta_i,R,number_coordinates):
    if theta_i != 0: #Wenn Objekt detektiert wurde => Kalmanprediktion durchführen
        estimate_i, P_i = filterpy.kalman.update(estimate_i, P_i,z_opt_assossiation,R, H) #Kalman Korrektur für estimates und P
    else: #Objekt nicht erkannt => Werte durchreichen
        P_i = P_i
        estimate_i = estimate_i
    return estimate_i,P_i


from pprint import pprint
from itertools import product
class Person:
    def __init__(self, name, surname,father_name, age, address):
        self.name,self.surname, self.father_name, self.age, self.address = name, surname, father_name, age, address
        self.key = (name, address)

    def __repr__(self):
        return "Person('%s', '%s', '%s', %s, '%s')" % (self.name,self.surname,self.father_name, self.age, self.address)

    def __eq__(self, obj):
        if type(obj) == Person:
            return (self.name, self.surname, self.father_name, self.age, self.address) == (obj.name, obj.surname,
                                                                                obj.father_name, obj.age,
                                                                                obj.address)
        elif type(obj) == str:
            return self.fuzzy_compare(obj)
        else:
            return self.__repr__() == obj.__repr__()

    ## реализация нечеткого запроса
    ADDRESS_WORDS = {'дом', 'улица', 'живет'}
    NAME_WORDS = {'имя', 'зовут'}
    AGE_WORDS = {'возраст', 'старше', 'младше'}
    SURNAME_WORDS ={'фамилия'}
    FATHERNAME_WORDS = {'отчество', 'по-батюшке'}

    def compare(self, s1, s2):
        s1, s2 = [s.lower() for s in [s1,s2]]
        ngrams = [s1[i:i+3] for i in range(len(s1))]
        count = 0
        for ngram in ngrams:
            count += s2.count(ngram)
        return count / max(len(s1),len(s2))

    def int_val(self,s):
        try:
            return int(s)
        except ValueError:
            return 0

    def fuzzy_compare(self, query):
        def by_address(Q):
            Q = Q - self.ADDRESS_WORDS
            W = set(self.address.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]

        def by_age(Q):
            q_age = max([self.int_val(q) for q in Q])
            if 'старше' in Q:
                return q_age < self.age
            if 'младше' in Q:
                return q_age > self.age
            return q_age + 5 >= self.age >= q_age - 5

        def by_name(Q):
            Q = Q - self.NAME_WORDS
            W = set(self.name.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]
        def by_surname(Q):
            Q = Q - self.SURNAME_WORDS
            W = set(self.surname.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]

        def by_fathername(Q):
            Q = Q - self.FATHERNAME_WORDS
            W = set(self.father_name.split())
            rez = []
            for a, b in product(Q, W):
                rez += [(self.compare(a, b), a, b)]
            return max(rez)[0]

        q_words = set(query.split())
        score = 0
        for m_words, method in zip([self.ADDRESS_WORDS, self.NAME_WORDS, self.AGE_WORDS, self.SURNAME_WORDS,
                                    self.FATHERNAME_WORDS],
                        [by_address, by_name, by_age, by_surname, by_fathername]):
            if m_words & q_words:
                score += method(q_words)
        return score > 0.49

lena = Person("Лена","Ленина", "Александровна", 19, "Пушкина, 14, 115")
oleg = Person("Олег", "Ленский", "Михайлович", 34, "Ленского, 10, 11")
olga = Person("Ольга","Хоритонова", "Константиновна",  28, "Онегина,  11,  12")
nata = Person("Наташа","Шемякина", "Александровна", 17, "Ростова,  16,  15")

people = {
    lena.key: lena,
    oleg.key: oleg,
    olga.key: olga,
    nata.key: nata,
}

##pprint(people)

queries = [
    'имя Ольга', 'возраст 30', 'старше 20', 'младше 20', 'живет на Пушкина', 'дом 10', 'фамилия ростова', 'зовут нташа',
    'женского пола', 'фамилия Ленна', 'по-батюшке Александровна',
]

for query, person in product(queries, people.values()):
    if person == query:
       pprint((query,person))

##Добавлены фамилия и отчество, разбитые в другие поля
##Ошибка в видео - self для функций не был указан


"""neuron_on_iris.py: show performance of a neuron on iris dataset"""
import matplotlib.pyplot as plt
import numpy as np
import logging
from random import seed
from learning_perceptron import Neuron
from useful.math_functions import sigmoid
from useful.preprocess_dataset import import_data, split_set
from useful.results import confusion_matrix, accuracy, recall

FIG_SIZE = (20, 20)
TRAIN_SIZE = 0.8
LR = 0.5

np.random.seed(123)
seed(123)

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)

    # Initialize neuron
    neuron = Neuron("On iris", 4, sigmoid, LR)

    # iris dataset
    dataset = import_data("../../data/iris.data").T[0:100].T

    dataset[4][0:50] = 1.0
    dataset[4][50:100] = 0.0

    train_set, test_set = split_set(dataset, TRAIN_SIZE)

    epochs = []
    accuracies = []
    recalls = []

    for x1, x2, x3, x4, label in train_set.T.tolist():
        epochs.append(
            neuron.train([x1, x2, x3, x4], label)
        )
        prediction = []
        labels = []
        for y1, y2, y3, y4, label2 in test_set.T.tolist():
            prediction.append(neuron.feed([y1, y2, y3, y4]))
            labels.append(label2)

        c_m = confusion_matrix(np.array(prediction), np.array(labels))
        accuracies.append(accuracy(c_m))
        recalls.append(recall(c_m)[0])

    fig, ax = plt.subplots(figsize=FIG_SIZE)
    ax.plot(epochs, accuracies, label="Accuracy", linewidth=3.5)
    ax.plot(epochs, recalls, "--", label="Recall", linewidth=2.0)
    ax.set_xlabel("Epochs", fontsize=20)
    ax.set_ylabel("Measure", fontsize=20)
    ax.set_title("Sigmoid neuron on Iris Dataset\n", fontsize=30)
    ax.legend(fontsize=20)
    ax.grid()

    plt.savefig("../results/neuron_on_iris.png")


from sklearn.neural_network.multilayer_perceptron import MLPClassifier
from sklearn import datasets

# Since the book came out, the cross_validation method has been moved to
# the model_selection library from the cross_validation library
#from sklearn.cross_validation import train_test_split
from sklearn.model_selection import train_test_split

from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score

import numpy
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt

#Apply standardization
standardised = True

M = {0:"sepal length", 1:"sepal width", 2:"petal length", 3:"petal width"}

#Choose two features
x=1 #1 corresponds to the sepal width
y=3 #3 corresponds to the petal width

iris = datasets.load_iris()
data = iris.data[:,[x,y]]

labels = iris.target

X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size=0.5, random_state=1)

reg = StandardScaler()
reg.fit(data)
X_train_std = reg.transform(X_train)
X_test_std = reg.transform(X_test)

if (standardised == False):
  X_train_std = X_train
  X_test_std = X_test

# We add max_iter=1000 becaue the default is max_iter=200 and
# it is not enough for full convergence
mlp = MLPClassifier(random_state=1, max_iter=1000)
mlp.fit(X_train_std, y_train)

y_pred = mlp.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())

print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

def plot_decision_regions(data, labels, classifier, resolution=0.01):
    markers = ('s', '*', '^')
    colors = ('blue', 'green', 'red')
    cmap = ListedColormap(colors)
    # plot the decision surface
    x_min, x_max = data[:, 0].min() - 1, data[:, 0].max() + 1
    y_min, y_max = data[:, 1].min() - 1, data[:, 1].max() + 1

    x, y = numpy.meshgrid(numpy.arange(x_min, x_max, resolution), numpy.arange(y_min, y_max, resolution))
    Z = classifier.predict(numpy.array([x.ravel(), y.ravel()]).T)
    Z = Z.reshape(x.shape)

    plt.pcolormesh(x, y, Z, cmap=cmap)
    plt.xlim(x.min(), x.max())
    plt.ylim(y.min(), y.max())

    colors = ('yellow', 'white', 'black')
    #cmap = ListedColormap(colors)
    #plot the data
    classes = ["setosa", "versicolor", "verginica"]
    for index, cl in enumerate(numpy.unique(labels)):
        plt.scatter(data[labels == cl, 0], data[labels == cl, 1], c=cmap(index), marker=markers[index], edgecolor="black", alpha=1.0, s=50, label=classes[index])

X_combined_std = numpy.vstack((X_train_std, X_test_std))
y_combined = numpy.hstack((y_train, y_test))
plot_decision_regions(X_combined_std, y_combined, classifier=mlp)

if (standardised == False):
  xString = M[x] + " [not standardized]"
  yString = M[y] + " [not standardized]"
else:
  xString = M[x] + " [standardized]"
  yString = M[y] + " [standardized]"

plt.xlabel(xString)
plt.ylabel(yString)
plt.legend(loc='upper left')
plt.show()


#lambda / anonymous functions in python :

#square of a number :

'''
lambda function used only when we
have to evaluate only 1 expression
in a function.
'''
func = lambda a:a*a
print(func(5))

add = lambda a,b:a+b
print(add(2,4))

#filter evens and perfect squares from list

from math import ceil
from math import sqrt
from math import floor

lst = [2,4,6,9,11,12,13,14,16]

even_numbers = list(filter(lambda a:a%2==0,lst))
print(*even_numbers)

perfect_squares = list(filter(lambda i:ceil(sqrt(i))==int(sqrt(i)),lst))
print(perfect_squares)

#lambda with map:
'''
map is used when we want to map our values to something else:
lime we can double all values in perfect_squares
'''
double_perfect = list(map(lambda a : a*2,perfect_squares))
print(double_perfect)

#lambda with reduce :
'''
reduce is used when we want to reduce our value
to a single value, like we want to sum our
double_perfect list
'''
from functools import reduce
sum = reduce(lambda a,b:a+b, double_perfect)
print(sum)


import pytest
import time, itertools, traceback
from colorama import init, Fore, Style
init()

from lib.logger import Logger, Level
from lib.config_loader import ConfigLoader
from lib.event import Event
from lib.message import Message
from lib.message_bus import MessageBus
from lib.message_factory import MessageFactory
from lib.clock import Clock
from lib.ifs import IntegratedFrontSensor
#from lib.indicator import Indicator

# ..............................................................................
class MockMessageQueue():
    '''
    This message queue just displays IFS events as they arrive.
    '''
    def __init__(self, level):
        super().__init__()
        self._count = 0
        self._counter = itertools.count()
        self._log = Logger("queue", Level.INFO)
        self._listeners = []
        self._triggered_ir_port_side = False
        self._triggered_ir_port      = False
        self._triggered_ir_cntr      = False
        self._triggered_ir_stbd      = False
        self._triggered_ir_stbd_side = False
        self._triggered_bmp_port     = False
        self._triggered_bmp_cntr     = False
        self._triggered_bmp_stbd     = False
        self._log.info('ready.')

    # ......................................................
    def add(self, message):
        self._log.debug(Fore.BLUE + 'add message {}'.format(message))
        self.add(message)

    # ......................................................
    def add(self, message):
        self._count = next(self._counter)
        message.number = self._count
        _event = message.event
        self._log.debug('added message #{}; priority {}: {}; event: {}'.format(message.number, message.priority, message.description, _event))
        _value = message.value

        if _event is Event.BUMPER_PORT and not self._triggered_bmp_port:
            self._log.info(Fore.RED + Style.BRIGHT + 'BUMPER_PORT: {}; value: {}'.format(_event.description, _value))
            self._triggered_bmp_port     = True
        elif _event is Event.BUMPER_CNTR and not self._triggered_bmp_cntr:
            self._log.info(Fore.BLUE + Style.BRIGHT + 'BUMPER_CNTR: {}; value: {}'.format(_event.description, _value))
            self._triggered_bmp_cntr     = True
        elif _event is Event.BUMPER_STBD and not self._triggered_bmp_stbd:
            self._log.info(Fore.GREEN + Style.BRIGHT + 'BUMPER_STBD: {}; value: {}'.format(_event.description, _value))
            self._triggered_bmp_stbd     = True

        elif _event is Event.INFRARED_PORT_SIDE and not self._triggered_ir_port_side:
            self._log.debug(Fore.RED  + '> INFRARED_PORT_SIDE: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_port_side = True
        elif _event is Event.INFRARED_PORT and not self._triggered_ir_port:
            self._log.debug(Fore.RED  + '> INFRARED_PORT: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_port      = True
        elif _event is Event.INFRARED_CNTR and not self._triggered_ir_cntr:
            self._log.debug(Fore.BLUE + '> INFRARED_CNTR:     distance: {:>5.2f}cm'.format(_value))
            self._triggered_ir_cntr      = True
        elif _event is Event.INFRARED_STBD and not self._triggered_ir_stbd:
            self._log.debug(Fore.GREEN + '> INFRARED_STBD: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_stbd      = True
        elif _event is Event.INFRARED_STBD_SIDE and not self._triggered_ir_stbd_side:
            self._log.debug(Fore.GREEN + '> INFRARED_STBD_SIDE: {}; value: {}'.format(_event.description, _value))
            self._triggered_ir_stbd_side = True

        else:
            self._log.debug(Fore.BLACK + Style.BRIGHT + 'other event: {}'.format(_event.description))

    # ..........................................................................
    def add_listener(self, listener):
        '''
        Add a listener to the optional list of message listeners.
        '''
        return self._listeners.append(listener)

    # ..........................................................................
    def remove_listener(self, listener):
        '''
        Remove the listener from the list of message listeners.
        '''
        try:
            self._listeners.remove(listener)
        except ValueError:
            self._log.warn('message listener was not in list.')

    # ......................................................
    @property
    def all_triggered(self):
        _all_ir_triggered  = self._triggered_ir_port_side and self._triggered_ir_port and self._triggered_ir_cntr and self._triggered_ir_stbd and self._triggered_ir_stbd_side
        _all_bmp_triggered = self._triggered_bmp_port and self._triggered_bmp_cntr and self._triggered_bmp_stbd
        return _all_ir_triggered and _all_bmp_triggered

    # ......................................................
    @property
    def count(self):
        return self._count

    # ..........................................................................
    def waiting_for_message(self):
        _fmt = '{0:>9}'
        self._log.info('waiting for: | ' \
                + Fore.RED   + _fmt.format( 'PORT_SIDE' if not self._triggered_ir_port_side else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.RED   + _fmt.format( 'PORT' if not self._triggered_ir_port else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.BLUE  + _fmt.format( 'CNTR' if not self._triggered_ir_cntr else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.GREEN + _fmt.format( 'STBD' if not self._triggered_ir_stbd else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.GREEN + _fmt.format( 'STBD_SIDE' if not self._triggered_ir_stbd_side else '' )
                + Fore.CYAN  + ' || ' \
                + Fore.RED   + _fmt.format( 'BMP_PORT' if not self._triggered_bmp_port else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.BLUE  + _fmt.format( 'BMP_CNTR' if not self._triggered_bmp_cntr else '' ) \
                + Fore.CYAN  + ' | ' \
                + Fore.GREEN + _fmt.format( 'BMP_STBD' if not self._triggered_bmp_stbd else '' ) \
                + Fore.CYAN  + ' |' )

# ..............................................................................
@pytest.mark.unit
def test_ifs():
    '''
    Test the functionality of Integrated Front Sensor.
    '''
    _log = Logger("test-ifs", Level.INFO)

    # read YAML configuration
    _loader = ConfigLoader(Level.INFO)
    filename = 'config.yaml'
    _config = _loader.configure(filename)

    _message_factory = MessageFactory(Level.INFO)
    _message_bus = MessageBus(Level.INFO)

    _log.info('creating clock...')
    _clock = Clock(_config, _message_bus, _message_factory, Level.WARN)

    _ifs = IntegratedFrontSensor(_config, _clock, Level.INFO)

    # establish queue to receive messages
    _queue = MockMessageQueue(Level.INFO)
    _message_bus.add_handler(Message, _queue.add)

    _ifs.enable()
    _clock.enable()

    while not _queue.all_triggered:
        _queue.waiting_for_message()
        time.sleep(0.5)
    _ifs.disable()

    assert _queue.count > 0
    _log.info('test complete.' + Style.RESET_ALL)

# ..............................................................................
def main():

    try:
        test_ifs()
    except KeyboardInterrupt:
        print(Fore.RED + 'Ctrl-C caught; exiting...' + Style.RESET_ALL)
    except Exception as e:
        print(Fore.RED + Style.BRIGHT + 'error testing ifs: {}\n{}'.format(e, traceback.format_exc()) + Style.RESET_ALL)

if __name__== "__main__":
    main()

#EOF