"""Test Scene for manager using pysdl2.

SDL_Texture* target_tex =SDL_CreateTexture(.....); //Add arg according to you
SDL_SetRenderTarget(my_renderer, target_tex);

SDL_Texture* t1 = SDL_CreateTextureFromSurface(my_renderer, someSurface);
SDL_Texture* t2 = SDL_CreateTextureFromSurface(my_renderer, someOtherSurface);
.
.
.
.
SDL_RenderCopy(my_renderer, t1, NULL, NULL);
SDL_RenderCopy(my_renderer, t2, NULL, NULL);
SDL_RenderCopy(my_renderer, t3, NULL, NULL);
.
.
.
SDL_SetRenderTarget(my_renderer, NULL);
SDL_RendererPresent(my_renderer);

SDL_RenderClear(my_renderer);
SDL_RenderCopy(my_renderer, target_tex, NULL, NULL);
SDL_RendererPresent(my_renderer);
"""

from math import pi, cos, sin
import unittest

import sdl2
from sdl2 import sdlgfx

from dnf_game.scene_manager import Manager
from dnf_game.scene_manager.scenes import base_scenes
from dnf_game.scene_manager.layers import base_layers
from dnf_game.util.ext.rect import Rect

class PySDL2GfxdrawTest(unittest.TestCase):
    """..."""

    def setUp(self):
        """..."""
        print("\n", "#" * 30, "\n%s" % __file__)

    def test_scene(self):
        """..."""
        Manager(scene=ScenePySDL2GfxdrawTest, test=False).execute()

class DrawLayer(base_layers.Layer):
    """..."""

    def __init__(self, **kwargs):
        """..."""
        super().__init__(**kwargs)
        w = 256
        h = 128
        rect = Rect(0, 0, w, h)
        sdlrenderer = self.manager.renderer.sdlrenderer
        factory = self.manager.factory

        button = factory.from_new_texture(w, h)
        button_tex = button.texture
        with factory.new_render_target(button_tex):
            draw_button(sdlrenderer, rect, 16, (95, 95, 95, 255))
        button.move(8, 8)

        self.create_gradient_surface()
        self.sprite = button

    def on_update(self):
        """..."""
        self.manager.spriterenderer.render(sprites=(
            self.surface, self.sprite))

class ScenePySDL2GfxdrawTest(base_scenes.SceneMultiLayer):
    """..."""

    def __init__(self, **kwargs):
        """..."""
        super().__init__(**kwargs)
        self.draw_layer = DrawLayer(parent=self).activate().show()
        self.insert_layer(self.draw_layer)

def _draw_circle(renderer, cx, cy, rad, color, sides=0):

    c = sdl2.ext.Color(*color)
    r, g, b, a = c.r, c.g, c.g, c.a

    _2pi = pi * 2

    if (sides == 0):
        sides = int(_2pi * rad / 2)

    d_a = _2pi / sides
    angle = d_a

    end_x = rad + cx
    end_y = 0.0 + cy
    i = 0
    sdl2.SDL_SetRenderDrawColor(renderer, r, g, b, a)
    while i != sides:
        start_x = end_x
        start_y = end_y
        end_x = cos(angle) * rad
        end_y = sin(angle) * rad
        end_x += cx
        end_y += cy
        angle += d_a

        sdl2.SDL_RenderDrawLine(renderer,
                                int(start_x), int(start_y),
                                int(end_x), int(end_y))
        i += 1

def draw_button(renderer, rect, rad, color):
    """..."""
    _draw_circle(renderer, rad, rad, rad, color)
    return

    c = sdl2.ext.Color(*color)
    r, g, b, a = c.r, c.g, c.g, c.a

    circle = sdlgfx.filledCircleRGBA
    # circle = sdlgfx.aacircleRGBA
    rectangle = sdlgfx.boxRGBA
    # rectangle = sdlgfx.rectangleRGBA

    # topleft
    circle(renderer, rad, rad, rad, r, g, b, a)
    # bottomleft
    circle(renderer, rad, rect.height - rad, rad, r, g, b, a)
    # left
    rectangle(renderer,
              0,  # x
              rect.top + rad + 1,  # y
              rad,  # w
              rect.height - rad // 2 - 4,  # h
              r, g, b, a)

    # topright
    circle(renderer, rect.right - rad, rect.top + rad, rad, r, g, b, a)
    # top
    rectangle(renderer,
              rect.left + rad + 1,  # x
              0,  # y
              rect.width - rad // 2 - 4,  # w
              rad,  # h
              r, g, b, a)

def draw_button1(renderer, rect, rad, color):
    """..."""
    c = sdl2.ext.Color(*color)
    r, g, b, a = c.r, c.g, c.g, c.a
    x1 = rect.right
    y1 = rect.top
    x2 = rect.left
    y2 = rect.bottom

    cx = 0
    cy = rad

    cx = 0
    cy = rad
    ocx = None
    ocy = None
    df = 1 - rad
    d_e = 3
    d_se = -2 * rad + 5

    # Test for special cases of straight lines or single point

    # Swap x1, x2 if required
    if (x1 > x2):
        x1, x2 = x2, x1

    # Swap y1, y2 if required
    if (y1 > y2):
        y1, y2 = y2, y1

    # Calculate width & height
    w = x2 - x1 + 1
    h = y2 - y1 + 1

    # Maybe adjust radius
    r2 = rad + rad
    if (r2 > w):
        rad = w // 2
        r2 = rad + rad
    if (r2 > h):
        rad = h // 2

    # Setup filled circle drawing for corners
    x = x1 + rad
    y = y1 + rad
    dx = x2 - x1 - rad - rad
    dy = y2 - y1 - rad - rad

    # Draw corners
    while cx < cy:
        xpcx = x + cx
        xmcx = x - cx
        xpcy = x + cy
        xmcy = x - cy
        if (ocy != cy):
            if (cy > 0):
                ypcy = y + cy
                ymcy = y - cy
                # !!!!!!!!!
                sdlgfx.hlineRGBA(renderer, xmcx, xpcx + dx, ypcy + dy,
                                 r, g, b, a)
                sdlgfx.hlineRGBA(renderer, xmcx, xpcx + dx, ymcy,
                                 r, g, b, a)
            else:
                sdlgfx.hlineRGBA(renderer, xmcx, xpcx + dx, y,
                                 r, g, b, a)
            ocy = cy

        if (ocx != cx):
            if (cx != cy):
                if (cx > 0):
                    ypcx = y + cx
                    ymcx = y - cx
                    sdlgfx.hlineRGBA(renderer, xmcy, xpcy + dx, ymcx,
                                     r, g, b, a)
                    sdlgfx.hlineRGBA(renderer, xmcy, xpcy + dx, ypcx + dy,
                                     r, g, b, a)
                else:
                    sdlgfx.hlineRGBA(renderer, xmcy, xpcy + dx, y,
                                     r, g, b, a)
            ocx = cx

        # Update
        if (df < 0):
            df += d_e
            d_e += 2
            d_se += 2
        else:
            df += d_se
            d_e += 2
            d_se += 4
            cy -= 1
        cx += 1

    # Inside
    if (dx > 0 and dy > 0):
        sdlgfx.boxRGBA(renderer, x1, y1 + rad + 1, x2, y2 - rad,
                       r, g, b, a)

    sdlgfx.hlineRGBA(renderer, rad // 2, x2 - rad // 2, 0,
                     227, 227, 216, 23)
    sdlgfx.hlineRGBA(renderer, rad // 2 - 1, x2 - rad // 2 + 1, 1,
                     227, 227, 216, 23)

    sdlgfx.vlineRGBA(renderer, 0, rad // 2, y2 - rad // 2,
                     227, 227, 216, 23)
    sdlgfx.vlineRGBA(renderer, 1, rad // 2 - 1, y2 - rad // 2 + 1,
                     227, 227, 216, 23)

    sdlgfx.hlineRGBA(renderer, rad // 2 - 1, x2 - rad // 2 + 1, y2 - 1 - 1,
                     0, 0, 0, 47)
    sdlgfx.hlineRGBA(renderer, rad // 2, x2 - rad // 2, y2 - 1,
                     0, 0, 0, 47)

    sdlgfx.vlineRGBA(renderer, x2 - 1 - 1, rad // 2 - 1, y2 - rad // 2 + 1,
                     0, 0, 0, 47)
    sdlgfx.vlineRGBA(renderer, x2 - 1, rad // 2, y2 - rad // 2,
                     0, 0, 0, 47)

    # 227, 227, 216, 31)
    # 0, 0, 0, 63)

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


# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
from typing import Union, List, Tuple

import paddle
from paddle import nn
import paddle.nn.functional as F
import numpy as np
from paddlehub.module.module import moduleinfo
import paddlehub.vision.segmentation_transforms as T
from paddlehub.module.cv_module import ImageSegmentationModule
from paddleseg.utils import utils
from paddleseg.models import layers

from ginet_resnet50vd_cityscapes.resnet import ResNet50_vd

@moduleinfo(
    name="ginet_resnet50vd_cityscapes",
    type="CV/semantic_segmentation",
    author="paddlepaddle",
    author_email="",
    summary="GINetResnet50 is a segmentation model.",
    version="1.0.0",
    meta=ImageSegmentationModule)
class GINetResNet50(nn.Layer):
    """
    The GINetResNet50 implementation based on PaddlePaddle.
    The original article refers to
    Wu, Tianyi, Yu Lu, Yu Zhu, Chuang Zhang, Ming Wu, Zhanyu Ma, and Guodong Guo. "GINet: Graph interaction network for scene parsing." In European Conference on Computer Vision, pp. 34-51. Springer, Cham, 2020.
    (https://arxiv.org/pdf/2009.06160).
    Args:
        num_classes (int): The unique number of target classes.
        backbone_indices (tuple, optional): Values in the tuple indicate the indices of output of backbone.
        enable_auxiliary_loss (bool, optional): A bool value indicates whether adding auxiliary loss.
            If true, auxiliary loss will be added after LearningToDownsample module. Default: False.
        align_corners (bool): An argument of F.interpolate. It should be set to False when the output size of feature
            is even, e.g. 1024x512, otherwise it is True, e.g. 769x769.. Default: False.
        jpu (bool, optional)): whether to use jpu unit in the base forward. Default:True.
        pretrained (str, optional): The path or url of pretrained model. Default: None.
    """

    def __init__(self,
                 num_classes: int = 19,
                 backbone_indices: Tuple[int]=(0, 1, 2, 3),
                 enable_auxiliary_loss: bool = True,
                 align_corners: bool = True,
                 jpu: bool = True,
                 pretrained: str = None):
        super(GINetResNet50, self).__init__()
        self.nclass = num_classes
        self.aux = enable_auxiliary_loss
        self.jpu = jpu

        self.backbone = ResNet50_vd()
        self.backbone_indices = backbone_indices
        self.align_corners = align_corners
        self.transforms = T.Compose([T.Normalize()])

        self.jpu = layers.JPU([512, 1024, 2048], width=512) if jpu else None
        self.head = GIHead(in_channels=2048, nclass=num_classes)

        if self.aux:
            self.auxlayer = layers.AuxLayer(
                1024, 1024 // 4, num_classes, bias_attr=False)

        if pretrained is not None:
            model_dict = paddle.load(pretrained)
            self.set_dict(model_dict)
            print("load custom parameters success")

        else:
            checkpoint = os.path.join(self.directory, 'model.pdparams')
            model_dict = paddle.load(checkpoint)
            self.set_dict(model_dict)
            print("load pretrained parameters success")

    def transform(self, img: Union[np.ndarray, str]) -> Union[np.ndarray, str]:
        return self.transforms(img)

    def base_forward(self, x: paddle.Tensor) -> paddle.Tensor:
        feat_list = self.backbone(x)
        c1, c2, c3, c4 = [feat_list[i] for i in self.backbone_indices]

        if self.jpu:
            return self.jpu(c1, c2, c3, c4)
        else:
            return c1, c2, c3, c4

    def forward(self, x: paddle.Tensor) -> paddle.Tensor:
        _, _, h, w = x.shape
        _, _, c3, c4 = self.base_forward(x)

        logit_list = []
        x, _ = self.head(c4)
        logit_list.append(x)

        if self.aux:
            auxout = self.auxlayer(c3)

            logit_list.append(auxout)

        return [
            F.interpolate(
                logit, (h, w),
                mode='bilinear',
                align_corners=self.align_corners) for logit in logit_list
        ]

class GIHead(nn.Layer):
    """The Graph Interaction Network head."""

    def __init__(self, in_channels: int, nclass: int):
        super().__init__()
        self.nclass = nclass
        inter_channels = in_channels // 4
        self.inp = paddle.zeros(shape=(nclass, 300), dtype='float32')
        self.inp = paddle.create_parameter(
            shape=self.inp.shape,
            dtype=str(self.inp.numpy().dtype),
            default_initializer=paddle.nn.initializer.Assign(self.inp))

        self.fc1 = nn.Sequential(
            nn.Linear(300, 128), nn.BatchNorm1D(128), nn.ReLU())
        self.fc2 = nn.Sequential(
            nn.Linear(128, 256), nn.BatchNorm1D(256), nn.ReLU())
        self.conv5 = layers.ConvBNReLU(
            in_channels,
            inter_channels,
            3,
            padding=1,
            bias_attr=False,
            stride=1)

        self.gloru = GlobalReasonUnit(
            in_channels=inter_channels,
            num_state=256,
            num_node=84,
            nclass=nclass)
        self.conv6 = nn.Sequential(
            nn.Dropout(0.1), nn.Conv2D(inter_channels, nclass, 1))

    def forward(self, x: paddle.Tensor) -> paddle.Tensor:
        B, C, H, W = x.shape
        inp = self.inp.detach()

        inp = self.fc1(inp)
        inp = self.fc2(inp).unsqueeze(axis=0).transpose((0, 2, 1))\
                           .expand((B, 256, self.nclass))

        out = self.conv5(x)

        out, se_out = self.gloru(out, inp)
        out = self.conv6(out)
        return out, se_out

class GlobalReasonUnit(nn.Layer):
    """
        The original paper refers to:
            Chen, Yunpeng, et al. "Graph-Based Global Reasoning Networks" (https://arxiv.org/abs/1811.12814)
    """

    def __init__(self, in_channels: int, num_state: int = 256, num_node: int = 84, nclass: int = 59):
        super().__init__()
        self.num_state = num_state
        self.conv_theta = nn.Conv2D(
            in_channels, num_node, kernel_size=1, stride=1, padding=0)
        self.conv_phi = nn.Conv2D(
            in_channels, num_state, kernel_size=1, stride=1, padding=0)
        self.graph = GraphLayer(num_state, num_node, nclass)
        self.extend_dim = nn.Conv2D(
            num_state, in_channels, kernel_size=1, bias_attr=False)

        self.bn = layers.SyncBatchNorm(in_channels)

    def forward(self, x: paddle.Tensor, inp: paddle.Tensor) -> paddle.Tensor:
        B = self.conv_theta(x)
        sizeB = B.shape
        B = B.reshape((sizeB[0], sizeB[1], -1))

        sizex = x.shape
        x_reduce = self.conv_phi(x)
        x_reduce = x_reduce.reshape((sizex[0], -1, sizex[2] * sizex[3]))\
                           .transpose((0, 2, 1))

        V = paddle.bmm(B, x_reduce).transpose((0, 2, 1))
        V = paddle.divide(
            V, paddle.to_tensor([sizex[2] * sizex[3]], dtype='float32'))

        class_node, new_V = self.graph(inp, V)
        D = B.reshape((sizeB[0], -1, sizeB[2] * sizeB[3])).transpose((0, 2, 1))
        Y = paddle.bmm(D, new_V.transpose((0, 2, 1)))
        Y = Y.transpose((0, 2, 1)).reshape((sizex[0], self.num_state, \
                                            sizex[2], -1))
        Y = self.extend_dim(Y)
        Y = self.bn(Y)
        out = Y + x

        return out, class_node

class GraphLayer(nn.Layer):
    def __init__(self, num_state: int, num_node: int, num_class: int):
        super().__init__()
        self.vis_gcn = GCN(num_state, num_node)
        self.word_gcn = GCN(num_state, num_class)
        self.transfer = GraphTransfer(num_state)
        self.gamma_vis = paddle.zeros([num_node])
        self.gamma_word = paddle.zeros([num_class])
        self.gamma_vis = paddle.create_parameter(
            shape=self.gamma_vis.shape,
            dtype=str(self.gamma_vis.numpy().dtype),
            default_initializer=paddle.nn.initializer.Assign(self.gamma_vis))
        self.gamma_word = paddle.create_parameter(
            shape=self.gamma_word.shape,
            dtype=str(self.gamma_word.numpy().dtype),
            default_initializer=paddle.nn.initializer.Assign(self.gamma_word))

    def forward(self, inp: paddle.Tensor, vis_node: paddle.Tensor) -> List[paddle.Tensor]:
        inp = self.word_gcn(inp)
        new_V = self.vis_gcn(vis_node)
        class_node, vis_node = self.transfer(inp, new_V)

        class_node = self.gamma_word * inp + class_node
        new_V = self.gamma_vis * vis_node + new_V
        return class_node, new_V

class GCN(nn.Layer):
    def __init__(self, num_state: int = 128, num_node: int = 64, bias: bool = False):
        super().__init__()
        self.conv1 = nn.Conv1D(
            num_node,
            num_node,
            kernel_size=1,
            padding=0,
            stride=1,
            groups=1,
        )
        self.relu = nn.ReLU()
        self.conv2 = nn.Conv1D(
            num_state,
            num_state,
            kernel_size=1,
            padding=0,
            stride=1,
            groups=1,
            bias_attr=bias)

    def forward(self, x: paddle.Tensor) -> paddle.Tensor:
        h = self.conv1(x.transpose((0, 2, 1))).transpose((0, 2, 1))
        h = h + x
        h = self.relu(h)
        h = self.conv2(h)
        return h

class GraphTransfer(nn.Layer):
    """Transfer vis graph to class node, transfer class node to vis feature"""

    def __init__(self, in_dim: int):
        super().__init__()
        self.channle_in = in_dim
        self.query_conv = nn.Conv1D(
            in_channels=in_dim, out_channels=in_dim // 2, kernel_size=1)
        self.key_conv = nn.Conv1D(
            in_channels=in_dim, out_channels=in_dim // 2, kernel_size=1)
        self.value_conv_vis = nn.Conv1D(
            in_channels=in_dim, out_channels=in_dim, kernel_size=1)
        self.value_conv_word = nn.Conv1D(
            in_channels=in_dim, out_channels=in_dim, kernel_size=1)
        self.softmax_vis = nn.Softmax(axis=-1)
        self.softmax_word = nn.Softmax(axis=-2)

    def forward(self, word: paddle.Tensor, vis_node: paddle.Tensor) -> List[paddle.Tensor]:
        m_batchsize, C, Nc = word.shape
        m_batchsize, C, Nn = vis_node.shape

        proj_query = self.query_conv(word).reshape((m_batchsize, -1, Nc))\
                                          .transpose((0, 2, 1))
        proj_key = self.key_conv(vis_node).reshape((m_batchsize, -1, Nn))

        energy = paddle.bmm(proj_query, proj_key)
        attention_vis = self.softmax_vis(energy).transpose((0, 2, 1))
        attention_word = self.softmax_word(energy)

        proj_value_vis = self.value_conv_vis(vis_node).reshape((m_batchsize, -1,
                                                                Nn))
        proj_value_word = self.value_conv_word(word).reshape((m_batchsize, -1,
                                                              Nc))

        class_out = paddle.bmm(proj_value_vis, attention_vis)
        node_out = paddle.bmm(proj_value_word, attention_word)
        return class_out, node_out


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 23 18:03:49 2018

@author: djibrilsall
"""

import sys, os
from time import sleep
import cv2
import numpy as np
import imutils

sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))

from uf.wrapper.swift_api import SwiftAPI
from uf.utils.log import *
from arm import Arm

#logger_init(logging.VERBOSE)
#logger_init(logging.DEBUG)
logger_init(logging.INFO)

print('setup swift ...')

#swift = SwiftAPI(dev_port = '/dev/ttyACM0')
#swift = SwiftAPI(filters = {'hwid': 'USB VID:PID=2341:0042'})
swift = SwiftAPI() # default by filters: {'hwid': 'USB VID:PID=2341:0042'}

print('sleep 2 sec ...')
sleep(2)

print('device info: ')
print(swift.get_device_info())

swift.flush_cmd() # avoid follow 5 command timeout

swift.flush_cmd()
#come Back Home

def home():
    swift.set_position(10, 0, 80, speed = 9000, wait = True)

def movex(x,y,z):
    swift.set_position(x,y,z+20, speed = 10000, wait = True)
    swift.set_position(x,y,z, speed = 1000, wait = True)
    swift.set_pump(True)
    swift.set_position(x,y,z+10, speed = 10000, wait = True)
    swift.set_position(100,-200,80, speed = 9000, wait = True)
    swift.set_pump(False)

cap = cv2.VideoCapture(1)
cap1 = cv2.VideoCapture(1)

class find:
    def detect_object(self, v, w,a,b,c,d,e,f,z):
        _, frame = v.read(c)
        frame = imutils.resize(frame, width=w)
        lower_color = np.array([a,b,c])
        upper_color = np.array([d,e,f])
        blurred = cv2.GaussianBlur(frame, (11, 11), 0)
        hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
        kernel = np.ones((11,11),np.float32)/225
        mask = cv2.inRange(hsv, lower_color, upper_color)
        mask1 = cv2.inRange(hsv, lower_color, upper_color)
        mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
        mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
        kernel = np.ones((11,11),np.float32)/225
        red_center = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
            cv2.CHAIN_APPROX_SIMPLE)[-2]
        center_red = None
        xc = 0
        yc = 0

        if len(red_center) > 0 :
            c = max(red_center, key=cv2.contourArea)
            #((x, y), radius) = cv2.minEnclosingCircle(c)
            M = cv2.moments(c)

            xc = int(M["m10"] / M["m00"])
            yc = int(M["m01"] / M["m00"])

        self.color = z
        self.xcoord = xc
        self.ycoord = yc
        cv2.imshow("mask", mask1)
    def getcoordx(self):
        return self.xcoord
    def getcoordy(self):
        return self.ycoord
    def getcolor(self):
        return self.color
    def getOuput(self):
        return self.maskoutput

def detect_w_avg(s,w,a,b,c,d,e,f,color):
    i = 0
    xred = 0
    yred = 0
    x = 0,
    y = 0;
    red = find()
    red.detect_object(s, w,a,b,c,d,e,f,color)
    while i < 10:
        xred = xred + red.getcoordx()
        yred = yred + red.getcoordy()
        i += 1
    return (color,(xred/i), (yred/i))

i = 1
while i == 1:
    home()
    sleep(3)
    #color, x,y = detect_w_avg(cap, 600,0,100,100,189,255,255,"red")

    color1, x1,y1 = detect_w_avg(cap, 600,65,60,60,80,255,255,"green")
    color, x,y = detect_w_avg(cap, 600,0,50,50,180,255,255,"brightred")
    print (color, x,y )
    print (color1, x1,y1 )
    movex(80,-20,50)
    sleep(3)
    color1, x1,y1 = detect_w_avg(cap, 600,65,60,60,80,255,255,"green")
    color, x,y = detect_w_avg(cap, 600,0,50,50,180,255,255,"brightred")
    sleep(3)
    print (color, x,y )
    print (color1, x1,y1 )
    i+=1
    #pos=swift.getposition()
    #else:
        #print("No object detected")
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

#i = 0
cv2.destroyAllWindows()
cap.release


import unittest2 as unittest
import lxml
from DateTime import DateTime

import zope.event
from Products.CMFCore.utils import getToolByName
from Products.PluggableAuthService.events import PropertiesUpdated

from plone.app.testing import TEST_USER_ID
from plone.app.testing import logout, login, setRoles

from emas.theme.tests.base import FUNCTIONAL_TESTING
from emas.theme.browser.tests.test_practice_service_messages_viewlet import \
    find_viewlet
from emas.theme.interfaces import IEmasThemeLayer
from emas.theme.eventhandlers import *

class TestEventhandlers(unittest.TestCase):
    """ Test the intelligent practice messages service viewlets  """

    layer = FUNCTIONAL_TESTING

    def setUp(self):
        super(TestEventhandlers, self).setUp()
        self.portal = self.layer['portal']
        setRoles(self.portal, TEST_USER_ID, ['Reader'])
        self.context = self.portal.maths
        self.request = self.portal.REQUEST
        self.manager_name = 'plone.belowcontenttitle'
        self.themelayer = IEmasThemeLayer
        self.viewlet_name = 'emas.practice_service_messages'

    def test_first_login_message(self):
        portal_state = self.portal.restrictedTraverse('@@plone_portal_state')
        member = portal_state.member()
        setRoles(self.portal, TEST_USER_ID, ['Reader'])
        default = DateTime('2000/01/01')
        member.setProperties(login_time=default,
                             last_login_time=default)

        # The call to loginUser is the one that fires the required event.
        # The testcase's login method simly creates a new security manager, it
        # does not lead to the IUserLoggedInEvent.
        pmt = getToolByName(self.portal, 'portal_membership')
        pmt.loginUser(self.portal.REQUEST)

        viewlet = find_viewlet(self.context,
                               self.request,
                               self.manager_name,
                               self.viewlet_name,
                               self.themelayer)

        result = viewlet.render()
        doc = lxml.html.fromstring(result)
        elements = doc.xpath('//a[contains(.,"@@practice")]')
        self.assertEqual(len(elements), 0,
                         'No link to @@practice found.')

    def test_onMemberPropsUpdates_subscribe(self):
        portal_state = self.portal.restrictedTraverse('@@plone_portal_state')
        member = portal_state.member()
        member.setProperties(subscribe_to_newsletter=True)
        event = PropertiesUpdated(member, 'subscribe_to_newsletter')
        update_newsletter_subscription(member, event)

    def test_onMemberPropsUpdates_unsubscribe(self):
        portal_state = self.portal.restrictedTraverse('@@plone_portal_state')
        member = portal_state.member()
        member.setProperties(subscribe_to_newsletter=False)
        event = PropertiesUpdated(member, 'subscribe_to_newsletter')
        update_newsletter_subscription(member, event)

    def test_update_newsletter_subscription(self):
        self.fail()


# -*- coding: utf-8 -*-
from openerp.tests import common
import logging
logger = logging.getLogger(__name__)

class TestResPartnerSecurityFields(common.TransactionCase):
    def setUp(self):
        super(TestResPartnerSecurityFields, self).setUp()

        # ATTENTION: It is necessary to clean the ir.model.data cache or fragments will remain between tests which
        #            would lead to wrong results for self.env.ref()
        @self.addCleanup
        def reset_model_data_cache():
            self.env.invalidate_all()
            self.env['ir.model.data'].clear_caches()
            self.env['res.groups'].clear_caches()

        # Create a partner with a phone number
        self.partner = self.env["res.partner"].create({
            "name": "Test User",
            "phone": " 0043 03172 12-34-56-7 ",
            "mobile": " 0043 (0) 660 12-34-56-7 ",
        })

    def test_01_find_phone_single_match(self):
        partner_obj = self.env['res.partner']
        found = partner_obj.search_phone_fuzzy('+43 3172 123 456 7')
        self.assertTrue(len(found) == 1)

    def test_02_find_mobile_single_match(self):
        partner_obj = self.env['res.partner']
        found = partner_obj.search_phone_fuzzy('+43 660_12__34-56--(7)')
        self.assertTrue(len(found) == 1)

    def test_03_find_phone_single_match_multiple_zeros(self):
        partner_obj = self.env['res.partner']
        found = partner_obj.search_phone_fuzzy('00043 (0) 3172 123 456 7')
        self.assertTrue(len(found) == 1)

    def test_04_find_phone_single_match_multiple_plus(self):
        partner_obj = self.env['res.partner']
        found = partner_obj.search_phone_fuzzy('++43 (0) 3172+123++456+7+')
        self.assertTrue(len(found) == 1)

    def test_05_find_phone_and_mobile_single_match(self):
        self.partner.phone = self.partner.mobile
        partner_obj = self.env['res.partner']
        found = partner_obj.search_phone_fuzzy('  0043 0 660 1234567  ')
        self.assertTrue(len(found) == 1)
        for record, values in found.iteritems():
            self.assertTrue(all(field in values.keys() for field in ['phone', 'mobile']))

    def test_06_find_phone_multi_match(self):
        self.partner2 = self.env["res.partner"].create({
            "name": "Test User 2",
            "mobile": "  ++43 (0) 660 1234 567 ",
        })
        partner_obj = self.env['res.partner']
        found = partner_obj.search_phone_fuzzy('  +43 660 1234567  ')
        self.assertTrue(len(found) == 2)

    def test_07_find_phone_no_country_no_match(self):
        partner_obj = self.env['res.partner']
        found = partner_obj.search_phone_fuzzy('03172 1234567')
        self.assertTrue(len(found) == 0)

    def test_08_find_phone_no_country_in_both_match(self):
        partner_obj = self.env['res.partner']
        self.partner.phone = '03172 1234567'
        found = partner_obj.search_phone_fuzzy('(0) 3172 123-456-7')
        self.assertTrue(len(found) == 1)


from django.contrib.auth.decorators import login_required

from django.db.models import Sum
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import CreateView, UpdateView, ListView, DetailView
from .models import Project, ProjectPicture, Category, ProjectReport, Comment, CommentReport, Denote

from django.http import JsonResponse
from django.shortcuts import render,redirect, get_object_or_404
from django.views.generic import CreateView, UpdateView, ListView, DetailView
from .models import Project, ProjectPicture, Category , Rate

from .forms import ProjectForm
from django.contrib import messages
from django.contrib.auth.models import User
from taggit.models import Tag
from django.template.defaultfilters import slugify
from django.conf import settings
from django.contrib.auth import login
from django.core.mail import send_mail

# Create your views here.

def index(request):
    return render(request, 'project/index.html', {})

@login_required
def create_project(request):
    form = ProjectForm()
    if request.method == "POST":
        form = ProjectForm(request.POST, request.FILES)
        if form.is_valid():
            project = form.save(commit=False)
            project.user = request.user
            # project.user = User.objects.first()
            project.slug = slugify(project.title)
            project.save()
            form.save_m2m()
            for image in request.FILES.getlist('images'):
                ProjectPicture.objects.create(project=project, image=image)
            messages.success(request, 'project has been created')
            return redirect('home')
        return render(request, 'project/createproject.html', {"form": form})
    return render(request, 'project/createproject.html', {"form": form})

def project_detail(request, project_id):
    project = get_object_or_404(Project, pk=project_id)
    context = {
        "project": project,
        "project_target_collected": Denote.objects.filter(project=project).aggregate(Sum('amount'))['amount__sum'] or 0.0
    }
    return render(request, 'project/project_detail.html', context)

@login_required
def project_report(request):
    rec = ProjectReport.objects.create(user=request.user, body=request.GET.get('body'), project_id=request.GET.get('project'))
    if rec:
        data = {'return': True}
    else:
        data = {'return': False}
    return JsonResponse(data)

@login_required
def post_comment(request, project_id):
    if request.method == "POST":
        if Project.objects.filter(pk=project_id).exists():
            comment = Comment.objects.create(body=request.POST.get('comment-body'), user=request.user, project_id=project_id)
            return redirect('project_detail', project_id)
    return redirect('project_detail', project_id)

def comment_report(request, comment_id):
    if Comment.objects.filter(pk=comment_id).exists():
        rec = CommentReport.objects.create(body=request.GET.get('body'), user=request.user, comment_id=comment_id)
    if rec:
        return JsonResponse({"return": True})
    return JsonResponse({"return": False})

@login_required
def fund_project(request, project_id):
    if request.method == 'POST':
        if Project.objects.filter(pk=project_id).exists():
            rec = Denote.objects.create(user=request.user, project_id=project_id, amount=request.POST.get('amount'))
            if rec:
                messages.success(request, 'Your fund has been submitted')
                return redirect('project_detail', project_id)
            else:
                messages.success(request, 'error submitting the fund')
                return redirect('project_detail', project_id)

@login_required
def rating_project(request, project_id, rating_val):
    # user = get_object_or_404(User, pk=request.user.id)
    # project = get_object_or_404(Project, pk=project_id)

    try:
        # if user update his rating
        rating = Rate.objects.get(user=request.user, project_id=project_id)
        rating.rating = rating_val
        rating.save()
        message = {
            'status': 'update rating',
            'number_of_rating': rating.project.number_of_rating()
            }
    except:
        # user make first rating on this project
        rating = Rate(user=request.user, project_id=project_id, rating=rating_val)
        rating.save()
        message = {
            'status': 'new rating',
            'number_of_rating': rating.project.number_of_rating(),
            }

    return JsonResponse(message)


import requests
request = requests.get( 'http://adventofcode.com/day/7/input',
                   cookies = {'session':'53616c7465645f5f1f67ff685d72b6b7cc9c32e892bf4f09b44422b5ed91dff733905aaf35fa7d6895554ad0f8bfd069'}
                   )
instr = request.content.decode()

wires = {}
connections = instr.split('\n')
for line in connections:
    try:
        operation, target = line.split(' -> ')
        wires[target.strip()] = operation.strip()
    except:
        pass

wiresSave = wires.copy()

def calculate( expr ):
    try:
        return int(expr)
    except:
        parts = expr.split(' ')
        if len(parts) == 1: #один ідентифікатор
            if type(wires[parts[0]]) == int:
                return wires[parts[0]]
            else:
                wires[parts[0]] = calculate(wires[parts[0]])
                return wires[parts[0]]
        elif len(parts) == 2: #унарний оператор один - NOT
            if parts[0] != 'NOT':
                raise 'ERROR!' + parts[0]
            return ~calculate(parts[1])
        else: #бінарний оператор
            op1 = calculate(parts[0])
            op2 = calculate(parts[2])
            if   parts[1] == 'AND':
                return op1 & op2
            elif parts[1] == 'OR':
                return op1 | op2
            elif parts[1] == 'LSHIFT':
                return op1 << op2
            elif parts[1] == 'RSHIFT':
                return op1 >> op2
            else:
                raise 'ERROR ' + parts[1]

newB = calculate('a')

wires = wiresSave.copy()
wires['b'] = newB
print(calculate('a'))


# coding:utf-8

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

if __name__ == "__main__":
    MMSIList = [413376760]
    data = pd.read_csv("/home/qiu/Documents/data/DP-DATA/中国沿海AIS/"
                       "201609_chinaCoast.csv")
    data = data.loc[:, ['unique_ID', 'acquisition_time', 'longitude', 'latitude']]
    data = data[data["unique_ID"].isin(MMSIList)]
    data = data[(data["latitude"] < 36.5 * 1000000.) & (data["acquisition_time"] <= 1472691018)]
    data = data.sort_values(by=["unique_ID", "acquisition_time"])
    # data.columns = ["unique_ID", "acquisition_time", "longitude", "latitude"]
    data["longitude"] = data["longitude"] / 1000000.0
    data["latitude"] = data["latitude"] / 1000000.0
    print(len(data))

    X1 = np.array(data["longitude"])
    Y1 = np.array(data["latitude"])
    Z1 = np.array(data["acquisition_time"])
    ###########################################################################
    dataCompressDF = pd.read_csv("/home/qiu/Documents/data/DP-DATA/QDPOPT/"
                                 "413376760_qdpopt_50m_area.csv")
    dataCompressDF = dataCompressDF.sort_values(by=["unique_ID", "acquisition_time"])
    X2 = np.array(dataCompressDF["longitude"])
    Y2 = np.array(dataCompressDF["latitude"])
    Z2 = np.array(dataCompressDF["acquisition_time"])
    print(len(dataCompressDF))

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.plot(X1, Y1, Z1, "b-o")
    ax.plot(X2, Y2, Z2, "r-x")
    ax.legend()
    plt.show()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('blog', '0004_comment'),
    ]

    operations = [
        migrations.AlterField(
            model_name='comment',
            name='id',
            field=models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
        ),
        migrations.AlterField(
            model_name='note',
            name='id',
            field=models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
        ),
    ]


from sqlalchemy.orm import scoped_session
from app import create_app
import unittest
import mock
from background import calc_stats_async
from database import db, StatsTab
from tests.common_tests_utility import mocked_get_ok, user1_json

class TestStatsDB(unittest.TestCase):

    def test_initDB(self):
        _app = create_app(debug=True)
        with _app.app_context():
            db.drop_all()
            db.create_all()

            session: scoped_session = db.session

            stats_record1: StatsTab = StatsTab()

            stats_record1.user_id = 30
            stats_record1.email = 'email@email.com'
            stats_record1.firstname = 'Mario'
            stats_record1.lastname = 'Rossi'

            session.add(stats_record1)
            session.commit()

            stats_check: StatsTab = session.query(StatsTab).filter(StatsTab.user_id == 30).first()
            self.assertIsNotNone(stats_check)
            self.assertEqual(stats_record1.user_id, stats_check.user_id)
            self.assertEqual(stats_record1.email, stats_check.email)

            stats_check.email = 'modified.email@email.ru'
            session.commit()

            stats_check_mod: StatsTab = session.query(StatsTab).filter(StatsTab.user_id == 30).first()
            self.assertIsNotNone(stats_check_mod)
            self.assertNotEqual('email@email.com', stats_check_mod.email)

            stats = stats_check_mod.to_json()
            print(stats)

    @mock.patch('requests.get', side_effect=mocked_get_ok)
    def test_Update(self, pippo):
        _app = create_app(debug=True)
        with _app.app_context():
            db.drop_all()
            db.create_all()

            calc_stats_async(user1_json['id'])

            session = db.session

            stats_check: StatsTab = session.query(StatsTab).filter(StatsTab.user_id == user1_json['id']).first()
            self.assertIsNotNone(stats_check)
            self.assertEqual(user1_json['id'], stats_check.user_id)
            self.assertEqual(user1_json['email'], stats_check.email)

    # @mock.patch('requests.get', side_effect=mocked_get_ok)
    # def test_Update_Async(self, pippo):
    #     _app = create_app(debug=True)
    #     with _app.app_context():
    #         db.drop_all()
    #         db.create_all()
    #
    #         # task = calc_stats_async
    #         # delay: AsyncResult = task.delay(user_id=user1_json['id'])
    #         # get = delay.get(timeout=10)
    #
    #         calc_stats_async.delay(user_id=user1_json['id']).get(timeout=5)
    #
    #         # sleep(10.0)
    #
    #         session = db.session
    #         stats_check: StatsTab = session.query(StatsTab).filter(StatsTab.user_id == user1_json['id']).first()
    #         self.assertIsNotNone(stats_check)
    #         self.assertEqual(user1_json['id'], stats_check.user_id)
    #         self.assertEqual(user1_json['email'], stats_check.email)


import numpy as np

from sklearn.linear_model import LinearRegression

class BiasRegressor(object):

    def __init__(self, model=LinearRegression()):
        self.model = model
        self.m_vals = []
        self.k_vals = []
        self.ftr_means: list = []
        self.over_under_lst = []
        self.p = 0
        self.over_under = 0

    @classmethod
    def get_params(self):
        return self.model

    def fit(self, X: np.ndarray, y: np.ndarray, split_size: float = 0.5, verbose: bool = False):
        '''
        This function does an initial fit with calibration along the way.
        '''

        p = 0

        if X.shape[0] != y.shape[0]:
            raise Exception("X and y must have the same shape.")
        split_idx = int(round(float(len(X) * split_size)))
        ftr_lsts = [[] for i in range(X.shape[1])]
        for ftr in X:
            for idx, val in enumerate(ftr):
                ftr_lsts[idx].append(val)
        for lst in ftr_lsts:
            self.ftr_means = np.append(self.ftr_means, (sum(lst)/len(lst)))
        self.ftr_means = np.array(self.ftr_means).reshape(-1, len(X[0]))

        X_train = X[:split_idx]
        X_val = X[split_idx:]

        y_train = y[:split_idx]
        y_val = y[split_idx:]

        self.model.fit(X_train, y_train)
        try:
            self.k_vals = np.zeros(y.shape[1]).tolist()
        except IndexError:
            self.k_vals = np.zeros(1).tolist()

        self.m_vals = self.model.predict(self.ftr_means)
        self.m_vals = self.m_vals[0]

        for idx, ftr in enumerate(X_val):
            ftr = ftr.reshape(1, -1)
            y_preds = self.model.predict(ftr)
            if sum(self.over_under_lst) > 0:
                y_preds = np.array([pred + p for pred in y_preds])
            elif sum(self.over_under_lst) < 0:
                y_preds = np.array([pred - p for pred in y_preds])
        p = self._calibrate(y_preds[0], y_val[idx])
        return p, self.model, sum(self.over_under_lst)

    def _calibrate(self, y_pred, y_val):
        if type(y_val) != np.ndarray:
            y_val = np.array([y_val])
        for i in range(len(y_val)):
            error = float(y_val[i] - y_pred[i])
            if error > 0.05:
                self.over_under_lst.append(1)
            elif error < -0.05:
                self.over_under_lst.append(-1)
            else:
                self.over_under_lst.append(0)
            m_val = float(self.m_vals[i])
            k = np.abs(error) / (m_val + 1)
            self.k_vals.append(k)
        return float(sum(self.k_vals) / len(self.k_vals))

    def predict(self, X: np.ndarray):
        y_preds = np.array([self.model.predict(X)])
        if self.over_under > 0:
            y_preds = np.array([pred + self.p for pred in y_preds])
        elif self.over_under < 0:
            y_preds = np.array([pred - self.p for pred in y_preds])
        return y_preds


from typing import Any

import proto

class AssetSetErrorEnum(proto.Message):
    class AssetSetError(proto.Enum):
        UNSPECIFIED = 0
        UNKNOWN = 1
        DUPLICATE_ASSET_SET_NAME = 2
        INVALID_PARENT_ASSET_SET_TYPE = 3
        ASSET_SET_SOURCE_INCOMPATIBLE_WITH_PARENT_ASSET_SET = 4
        ASSET_SET_TYPE_CANNOT_BE_LINKED_TO_CUSTOMER = 5
        INVALID_CHAIN_IDS = 6
        LOCATION_SYNC_ASSET_SET_DOES_NOT_SUPPORT_RELATIONSHIP_TYPE = 7
        NOT_UNIQUE_ENABLED_LOCATION_SYNC_TYPED_ASSET_SET = 8
        INVALID_PLACE_IDS = 9
        OAUTH_INFO_INVALID = 11
        OAUTH_INFO_MISSING = 12
        CANNOT_DELETE_AS_ENABLED_LINKAGES_EXIST = 10
    def __init__(
        self,
        mapping: Any | None = ...,
        *,
        ignore_unknown_fields: bool = ...,
    ) -> None: ...


from __future__ import unicode_literals

import re
from django.core import validators
from django.core.exceptions import ValidationError

from django.core.exceptions import ImproperlyConfigured
from django import forms
from django.forms.widgets import Input
from django.forms.extras import SelectDateWidget
from django.utils.translation import ugettext_lazy as _

from forms_builder.forms.settings import USE_HTML5, EXTRA_FIELDS, EXTRA_WIDGETS
from forms_builder.forms.utils import html5_field, import_attr

class UrlMediaFileInput(Input):
    input_type = 'file'

    def __init__(self, *args, **kwargs):
        super(UrlMediaFileInput, self).__init__(*args, **kwargs)
        self.needs_multipart_form = False

    def render(self, name, value, attrs=None):
        attrs = attrs or {}
        attrs['upload_media'] = ""
        return super(UrlMediaFileInput, self).render(name, None, attrs=attrs)

    def value_from_datadict(self, data, files, name):
        "Url Media widgets take link to data from POST, not FILES"
        url = data.get(name, None)
        uploaded_file = files.get(name, None)
        if url:
            url = str(url.strip()) if url else None
        elif uploaded_file:
            uploaded_file.name = re.sub('[\'\!\@\#\$\%\^\&\*\(\)]', "", uploaded_file.name, 0, 0)
            self.needs_multipart_form = True
        return url or uploaded_file

    def _has_changed(self, initial, data):
        if data is None:
            return False
        return True

class MediaFileField(forms.CharField):

    @property
    def is_store_file(self):
        return self.widget.needs_multipart_form

    def to_python(self, value):
        """Return unicode if widget needs_multipart_form is False,
        otherwise UploadedFile
        """
        if not self.is_store_file:
            return super(forms.CharField, self).to_python(value)
        else:
            return self.file_to_python(value)

    def file_to_python(self, data):
        """
        Treet data like it do FileField!
        """
        if data in validators.EMPTY_VALUES:
            return None

        # UploadedFile objects should have name and size attributes.
        try:
            file_name = data.name
            file_size = data.size
        except AttributeError:
            raise ValidationError(self.error_messages['invalid'])
        return data

    def clean(self, value):
        """Custom method!
        Will not run validators if widget needs_multipart_form is True.

        Motivation:
          It can store file or link to GCS object.
        """
        value = self.to_python(value)
        self.validate(value)
        if not self.is_store_file:
            self.run_validators(value)
        return value

# Constants for all available field types.
TEXT = 1
TEXTAREA = 2
EMAIL = 3
CHECKBOX = 4
CHECKBOX_MULTIPLE = 5
SELECT = 6
SELECT_MULTIPLE = 7
RADIO_MULTIPLE = 8
FILE = 9
DATE = 10
DATE_TIME = 11
HIDDEN = 12
NUMBER = 13
URL = 14
DOB = 15
MEDIA_FILE = 16

# Names for all available field types.
NAMES = (
    (TEXT, _("Single line text")),
    (TEXTAREA, _("Multi line text")),
    (EMAIL, _("Email")),
    (NUMBER, _("Number")),
    (URL, _("URL")),
    (CHECKBOX, _("Check box")),
    (CHECKBOX_MULTIPLE, _("Check boxes")),
    (SELECT, _("Drop down")),
    (SELECT_MULTIPLE, _("Multi select")),
    (RADIO_MULTIPLE, _("Radio buttons")),
    (FILE, _("File upload")),
    (DATE, _("Date")),
    (DATE_TIME, _("Date/time")),
    (DOB, _("Date of birth")),
    (MEDIA_FILE, _("Media file")),
    (HIDDEN, _("Hidden")),
)

# Field classes for all available field types.
CLASSES = {
    TEXT: forms.CharField,
    TEXTAREA: forms.CharField,
    EMAIL: forms.EmailField,
    CHECKBOX: forms.BooleanField,
    CHECKBOX_MULTIPLE: forms.MultipleChoiceField,
    SELECT: forms.ChoiceField,
    SELECT_MULTIPLE: forms.MultipleChoiceField,
    RADIO_MULTIPLE: forms.ChoiceField,
    FILE: forms.FileField,
    DATE: forms.DateField,
    DATE_TIME: forms.DateTimeField,
    DOB: forms.DateField,
    HIDDEN: forms.CharField,
    NUMBER: forms.FloatField,
    URL: forms.URLField,
    MEDIA_FILE: MediaFileField,
}

# Widgets for field types where a specialised widget is required.
WIDGETS = {
    TEXTAREA: forms.Textarea,
    CHECKBOX_MULTIPLE: forms.CheckboxSelectMultiple,
    RADIO_MULTIPLE: forms.RadioSelect,
    DATE: SelectDateWidget,
    DOB: SelectDateWidget,
    MEDIA_FILE: UrlMediaFileInput,
    HIDDEN: forms.HiddenInput,
}

# Some helper groupings of field types.
CHOICES = (CHECKBOX, SELECT, RADIO_MULTIPLE)
DATES = (DATE, DATE_TIME, DOB)
MULTIPLE = (CHECKBOX_MULTIPLE, SELECT_MULTIPLE)

# HTML5 Widgets
if USE_HTML5:
    WIDGETS.update({
        DATE: html5_field("date", forms.DateInput),
        DATE_TIME: html5_field("datetime", forms.DateTimeInput),
        DOB: html5_field("date", forms.DateInput),
        EMAIL: html5_field("email", forms.TextInput),
        NUMBER: html5_field("number", forms.TextInput),
        URL: html5_field("url", forms.TextInput),
    })

# Add any custom fields defined.
for field_id, field_path, field_name in EXTRA_FIELDS:
    if field_id in CLASSES:
        err = "ID %s for field %s in FORMS_EXTRA_FIELDS already exists"
        raise ImproperlyConfigured(err % (field_id, field_name))
    CLASSES[field_id] = import_attr(field_path)
    NAMES += ((field_id, _(field_name)),)

# Add/update custom widgets.
for field_id, widget_path in EXTRA_WIDGETS:
    if field_id not in CLASSES:
        err = "ID %s in FORMS_EXTRA_WIDGETS does not match a field"
        raise ImproperlyConfigured(err % field_id)
    WIDGETS[field_id] = import_attr(widget_path)


import pytest
from selenium import webdriver

def pytest_addoption(parser):
    parser.addoption("--browser",action="store",default="chrome",help="Type in browser name eg.chrome OR firefox")

@pytest.fixture(scope="class")
def test_setup(request):
        browser=request.config.getoption("--browser")
        if browser == 'chrome':
            driver=webdriver.Chrome(executable_path="../drivers/chromedriver.exe")
        #driver=webdriver.Chrome(executable_path="../drivers/chromedriver.exe")
        elif browser == 'firefox':
            driver=webdriver.Firefox(executable_path="../drivers/geckodriver.exe")

        driver.maximize_window()
        request.cls.driver=driver
        driver.implicitly_wait(5)
        yield
        driver.close()
        driver.quit()


'''Trains a simple deep NN on the MNIST dataset.
Gets to 98.40% test accuracy after 20 epochs
(there is *a lot* of margin for parameter tuning).
2 seconds per epoch on a K520 GPU.
'''

# from __future__ import print_function

from framework.metric_learning.basemetriclearning import BasemetricLearning
from framework.metric_learning.metriclearningterms import MetricLearningTerms

import copy
import numpy as np
import numpy.random as rng
import pandas as pd
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Activation, Add, Merge, Input, add, merge
from keras.optimizers import RMSprop, Adam
from keras.preprocessing import sequence
from keras import backend as K
from keras.layers.normalization import BatchNormalization
from keras.callbacks import ModelCheckpoint
from keras.regularizers import l2
from sklearn.preprocessing import StandardScaler
from sklearn.metrics.pairwise import pairwise_distances
import os
import copy

import copy
import numpy as np
import numpy.random as rng
import pandas as pd
import keras
from keras.layers import Input,merge
from keras.models import Sequential, Model
from sklearn.preprocessing import StandardScaler
from keras.layers.core import *
import pandas as pd
import pdb
import matplotlib.pyplot as plt
import multiprocessing as mp

# np.random.seed(0)

class NonlinearDeepMetric(BasemetricLearning):
    def __init__(self, **kwargs):
        super().__init__(MetricLearningTerms.NONLINEAR)
        self.kwargs = kwargs
        self.batch_size = 10
        self.epochs = 4

    def train(self, data_pairs, similarity_labels,**kwargs):
        self.scaler = StandardScaler()
        X1 = []
        X2 = []
        for x, y in data_pairs:
            X1.append(x)
            X2.append(y)
        # print(len(X1), len(X2), len(similarity_labels))
        number_classes = len(np.unique(similarity_labels))
        # convert class vectors to binary class matrices

        train_portion = 0.8
        input_shape = data_pairs[0][0].shape

        kernels = 100
        s_size = len(similarity_labels)
        x1_train = X1[:int(s_size * train_portion)]
        x2_train = X2[:int(s_size * train_portion)]
        x1_test = X1[int(s_size * train_portion):]
        x2_test = X2[int(s_size * train_portion):]
        y_train = similarity_labels[:int(s_size * train_portion)]
        y_test = similarity_labels[int(s_size * train_portion): ]

        labels = keras.utils.to_categorical(similarity_labels, number_classes)
        y_train = keras.utils.to_categorical(y_train, number_classes)
        y_test = keras.utils.to_categorical(y_test, number_classes)

        left_input = Input(input_shape)
        right_input = Input(input_shape)

        #build f(x) to use in each siamese 'leg'
        model = Sequential()
        # model.add(Dense(kernels, activation='relu', input_shape = input_shape, kernel_regularizer=l2(2e-4)))
        # model.add(Dense(kernels, activation='relu', kernel_regularizer=l2(2e-4)))
        # model.add(Dense(kernels, activation='sigmoid', kernel_regularizer=l2(1e-3)))

        model.add(Dense(kernels, activation='relu', input_shape = input_shape))
        model.add(Dropout(0.2))
        model.add(Dense(kernels, activation='relu'))
        model.add(Dropout(0.2))
        model.add(Dense(kernels, activation='sigmoid'))

        #encode each of the two inputs into a vector with the model
        encoded_l = model(left_input)
        encoded_r = model(right_input)

        #merge two encoded inputs with the l1 distance between them
        L1_distance = lambda x: K.abs(x[0]-x[1])

        both = merge([encoded_l, encoded_r], mode = L1_distance, output_shape=lambda x: x[0])
        prediction = Dense(number_classes,activation='sigmoid')(both)
        siamese_net = keras.models.Model(inputs=[left_input,right_input],outputs=prediction)

        optimizer = RMSprop()
        siamese_net.compile(loss=self.contrastive_loss, optimizer=optimizer)

        siamese_net.count_params()

        x1_train = np.array(x1_train)
        x2_train = np.array(x2_train)
        y_train = np.array(y_train)

        x1_test = np.array(x1_test)
        x2_test = np.array(x2_test)
        y_test = np.array(y_test)

        x1_train = np.array(X1)
        x2_train = np.array(X2)
        y_train = keras.utils.to_categorical(similarity_labels, number_classes)

        data = np.append(x1_train, x2_train, axis=0)

        self.scaler.fit(data)
        x1_train = self.scaler.transform(x1_train)
        x2_train = self.scaler.transform(x2_train)

        history = siamese_net.fit([x1_train, x2_train], y_train,
                            batch_size=self.batch_size,
                            epochs=self.epochs,
                            validation_data=([x1_train, x2_train], y_train), verbose=0)

        score = siamese_net.evaluate([x1_test, x2_test], y_test, verbose=0)
        print('Test loss:', score)
        print('Test accuracy:', score)

        inp1, inp2 = siamese_net.input

        func = siamese_net.layers[-2].input
        dist = siamese_net.layers[-2].output
        self.functor1 = K.function([inp1]+ [K.learning_phase()], [func[0]])
        self.functor2 = K.function([inp2]+ [K.learning_phase()], [func[1]])
        self.functor3 = K.function([*[inp1, inp2]]+ [K.learning_phase()], [dist])
        return score

    # def transform(self, data_pairs):
    #     x, y = data_pairs
    #     x = self.scaler.transform(np.array([x]))
    #     y = self.scaler.transform(np.array([y]))

    #     distance = self.functor3([*[x, y], 1.])
    #     return distance[0].mean()

    def contrastive_loss(self, y_true, y_pred):
        margin = 1
        return K.mean((1-y_true) * 0.5 * K.square(y_pred) + 0.5 * y_true * K.square(K.maximum(margin - y_pred, 0)))

    def penalized_loss(self, branch1, branch2):
        def loss(y_true, y_pred):
            return K.mean(K.square(y_pred - y_true) - K.square(y_true - y_pred), axis=-1)
        return loss

    def euclideanSqDistance(self, inputs):
        if (len(inputs) != 2):
            raise 'oops'
        output = K.mean(K.square(inputs[0] - inputs[1]), axis=-1)
        output = K.expand_dims(output, 1)
        return output

    def W_init(self, shape,name="weigt"):
        """Initialize weights as in paper"""
        values = rng.normal(loc=0,scale=1e-2,size=shape)
        return K.variable(values,name=name)
        #//TODO: figure out how to initialize layer biases in keras.

    def b_init(self, shape,name="bais"):
        """Initialize bias as in paper"""
        values = rng.normal(loc=0.5,scale=1e-2,size=shape)
        return K.variable(values,name=name)

# def euc_dist(x):
#     'Merge function: euclidean_distance(u,v)'
#     s = x[0] - x[1]
#     output = K.sum(K.square(s),axis=1,keepdims=True)
#     return output

# def euc_dist_shape(input_shape):
#     'Merge output shape'
#     shape = list(input_shape)
#     outshape = (shape[0][0],1)
#     return tuple(outshape)

# class Deep_Metric(BasemetricLearning):
#     def __init__(self, **kwargs):
#         super().__init__(MetricLearningTerms.NONLINEAR)
#         self.kwargs = kwargs
#         self.batch_size = 10
#         self.epochs = 4

#     # def train(self, x1_train,x2_train,y_train,x1_test,x2_test,y_test):
#     def train(self, data_pairs, similarity_labels):
#         import keras

#         self.scaler = StandardScaler()
#         self.batch_size = 32
#         self.epochs = 100

#         X1 = []
#         X2 = []
#         for x, y in data_pairs:
#             X1.append(x)
#             X2.append(y)

#         kernels = 20
#         s_size = len(similarity_labels)

#         train_portion = 0.8
#         input_shape = data_pairs[0][0].shape

#         x1_train = X1[:int(s_size * train_portion)]
#         x2_train = X2[:int(s_size * train_portion)]
#         x1_test = X1[int(s_size * train_portion):]
#         x2_test = X2[int(s_size * train_portion):]
#         y_train = similarity_labels[:int(s_size * train_portion)]
#         y_test = similarity_labels[int(s_size * train_portion): ]

#         # input_shape = x1_train[0].shape

#         x1_train = np.array(x1_train)
#         x2_train = np.array(x2_train)
#         y_train = np.array(y_train)

#         x1_test = np.array(x1_test)
#         x2_test = np.array(x2_test)
#         y_test = np.array(y_test)

#         # x1_train = np.array(X1)
#         # x2_train = np.array(X2)

#         # y_train = keras.utils.to_categorical(similarity_labels, number_classes)

#         print(input_shape)

#         # define networks
#         left_input = Input(input_shape)
#         right_input = Input(input_shape)
#         model = Sequential()
#         model.add(Dense(kernels, activation='relu', input_shape = input_shape))
#         model.add(Dropout(0.3))
#         model.add(Dense(int(kernels/2), activation='relu'))
#         model.add(Dropout(0.3))
#         model.add(Dense(kernels, activation='relu'))
#         model.add(Dropout(0.3))
#         encoded_l = model(left_input)
#         encoded_r = model(right_input)
#         both = merge([encoded_l,encoded_r],mode=euc_dist,output_shape=euc_dist_shape)
#         self.distance_model = Model(input=[left_input,right_input],outputs=both)
#         self.distance_model.compile(loss=self.contrastive_loss, optimizer='Adam')

#         print('===training===')
#         self.distance_model.fit([x1_train, x2_train],y_train,
#                             batch_size=self.batch_size,
#                             epochs=self.epochs,
#                             validation_data=([x1_test, x2_test], y_test), verbose=1)

#         self.d_test = self.distance_model.predict([x1_test,x2_test])
#         similar_ind = np.where(y_test == 1) [0]
#         dissimilar_ind = np.where(y_test == 0)[0]
#         print('similar distances %s'%np.mean(self.d_test[similar_ind]))
#         print('similar distances var %s' % np.std(self.d_test[similar_ind]))
#         print('dissimilar distances %s' % np.mean(self.d_test[dissimilar_ind]))
#         print('dissimilar distances var %s' % np.std(self.d_test[dissimilar_ind]))

#     def transform(self, data_pairs):
#         x, y = data_pairs
#         x = x.reshape((1,len(x)))
#         y = y.reshape((1,len(y)))
#         distance = self.distance_model.predict([x,y])
#         return distance
#         # processes = []
#         # for i in range(4):
#         #     p = mp.Process(target=self.transform_multi, args=(data_pairs,))
#         #     processes.append(p)
#         # distance =  [x.start() for x in processes]
#         # return distance

#     # def transform_multi(self, data_pairs):
#     #     x, y = data_pairs
#     #     x = x.reshape((1,len(x)))
#     #     y = y.reshape((1,len(y)))
#     #     distance = self.distance_model.predict([x,y], batch_size=2048)
#     #     return distance

#     def contrastive_loss(self, y_true, d):
#         # 1 means simlar, and 0 means dissimilar
#         margin = 1
#         return K.mean(y_true*0.5*d + (1-y_true)*0.5*K.maximum(margin-d,0))


# emacs: -*- mode: python-mode; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil; coding: utf-8 -*-
# ex: set sts=4 ts=4 sw=4 noet:
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
#   See COPYING file distributed along with the datalad package for the
#   copyright and license terms.
#
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
"""Test all extractors at a basic level"""

from six import (
    text_type,
)
from pkg_resources import iter_entry_points
from datalad.api import (
    Dataset,
    meta_extract,
    save,
    install,
)
from datalad.support.gitrepo import GitRepo

from nose import SkipTest
from datalad.tests.utils import (
    assert_repo_status,
    assert_true,
    assert_not_in,
    assert_in,
    assert_raises,
    assert_result_count,
    eq_,
    known_failure,
    with_tree,
    with_tempfile,
)
from ...tests import (
    make_ds_hierarchy_with_metadata,
    _get_dsid_from_core_metadata,
    _get_dsmeta_from_core_metadata,
)

@with_tree(tree={'file.dat': ''})
def check_api(annex, path):
    ds = Dataset(path).create(force=True, annex=annex)
    ds.save()
    assert_repo_status(ds.path)

    processed_extractors, skipped_extractors = [], []
    for extractor_ep in iter_entry_points('datalad.metadata.extractors'):
        # we need to be able to query for metadata, even if there is none
        # from any extractor
        try:
            res = meta_extract(
                dataset=ds,
                sources=[extractor_ep.name],
            )
        except Exception as exc:
            exc_ = str(exc)
            skipped_extractors += [exc_]
            continue
        # metalad_core does provide some information about our precious file
        if extractor_ep.name == 'metalad_core':
            assert_result_count(
                res,
                1,
                path=ds.path,
                type='dataset',
                status='ok',
            )
            assert_true(
                all('metalad_core' in r.get('metadata', {}) for r in res))
            # every single report comes with an identifier
            assert_true(all(
                (_get_dsid_from_core_metadata(r['metadata']['metalad_core'])
                    if r.get('type', None) == 'dataset'
                    else r['metadata']['metalad_core'].get('@id', None)) \
                is not None
                for r in res))
        processed_extractors.append(extractor_ep.name)
    assert "metalad_core" in processed_extractors, \
        "Should have managed to find at least the core extractor extractor"
    if skipped_extractors:
        raise SkipTest(
            "Not fully tested/succeded since some extractors failed"
            " to load:\n%s" % ("\n".join(skipped_extractors)))

@known_failure
def test_api_git():
    # should tolerate both pure git and annex repos
    yield check_api, False

@known_failure
def test_api_annex():
    yield check_api, True

@known_failure
@with_tempfile(mkdir=True)
def test_plainest(path):
    # blow on nothing
    assert_raises(
        ValueError,
        meta_extract, dataset=path, sources=['metalad_core'])
    r = GitRepo(path, create=True)
    # proper error, no crash, when there is the thinnest of all traces
    # of a dataset: but nothing to describe
    assert_result_count(
        meta_extract(
            dataset=r.path,
            on_failure='ignore',
        ),
        1,
        status='error',
        # message contains exception
        type='dataset',
        path=r.path,
    )
    # not we add some dummy content that does not count as metadata-relevant
    # and we still fail
    (r.pathobj / '.datalad').mkdir()
    (r.pathobj / '.datalad' / 'dummy').write_text(text_type('stamp'))
    ds = Dataset(r.path)
    ds.save()
    assert_result_count(
        meta_extract(
            dataset=ds.path,
            sources=['metalad_core'],
            on_failure='ignore',
        ),
        1,
        status='error',
        # message contains exception
        type='dataset',
        path=ds.path,
    )

@known_failure
@with_tempfile
@with_tempfile
def test_report(path, orig):
    origds, subds = make_ds_hierarchy_with_metadata(orig)
    # now clone to a new place to ensure no content is present
    ds = install(source=origds.path, path=path)
    # only dataset-global metadata
    res = meta_extract(dataset=ds, process_type='dataset')
    assert_result_count(res, 1)
    core_dsmeta = _get_dsmeta_from_core_metadata(
        res[0]['metadata']['metalad_core']
    )
    assert_in(
            {'@type': 'Dataset',
            '@id': 'datalad:{}'.format(subds.repo.get_hexsha()),
            'identifier': 'datalad:{}'.format(subds.id), 'name': 'sub'},
        core_dsmeta['hasPart']
    )
    # has not seen the content
    assert_not_in(
        'contentbytesize',
        core_dsmeta
    )
    res = meta_extract(dataset=ds, process_type='content')
    assert(any(
        dict(tag=['one', 'two']) == r['metadata'].get('metalad_annex', None)
        for r in res
    ))
    # we have a report on file(s)
    assert(len(res) > 0)
    # but no subdataset reports
    assert_result_count(res, 0, type='dataset')
    content_size = sum(
        (_get_dsmeta_from_core_metadata(
            r['metadata']['metalad_core'])
         if r['type'] == 'dataset'
         else r['metadata']['metalad_core'])['contentbytesize'] for r in res)
    # and now all together
    res = meta_extract(dataset=ds, process_type='all')
    # got a content size report that sums up all individual sizes
    eq_(
        (_get_dsmeta_from_core_metadata(
            res[0]['metadata']['metalad_core'])
         if res[0]['type'] == 'dataset'
         else res[0]['metadata']['metalad_core'])['contentbytesize'],
        content_size
    )


from bs4 import BeautifulSoup
from urllib.parse import quote
import urllib3
import pandas as pd

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def twitter():
# trackanalytics 'Most Followed Twitter Profiles' url pagina
    url = 'https://www.trackalytics.com/the-most-followed-twitter-profiles/page/'

    user_list = []
    screen_name_list = []
    username_list = []
    # Itera por las paginas
    for num in range(1, 2):
        try:
            # Carga pagina
            query = url + str(num) + '/'
            response = urllib3.PoolManager().request('GET', query).data

            # Evita warnings de decoding
            FromRaw = lambda r: r if isinstance(r, str) else r.decode('utf-8', 'ignore')

            # Parsea html de la pag
            soup = BeautifulSoup(FromRaw(response), 'html.parser')

            # Extrae los elementos de la fila en la tabla de usuarios
            rows = soup.find_all('tr')[1:16]
            for row in rows:
                try:
                    # Parsea las filas para extraer el link con el usuario de twitter
                    new = BeautifulSoup(str(row), 'html.parser').find_all('a')[1]
                    new2 = BeautifulSoup(str(row), 'html.parser').find_all('td')[2]
                    screen_name = new.get('title')
                    username = "@" + new.get('href').split('/')[-2]  # coge usuario por link

                    followers = str(new2).split('\n')
                    followers = followers[1].strip()
                    followers = followers.split(' ')
                    followers = followers[0]

                    # Almacena usuarios en user_list
                    user_list.append({'Nombre': screen_name, 'Usuario': username, 'Seguidores': followers})

                except Exception as e:
                    print('link error:', num, e)
                    continue
        except Exception as e:
            print('page error:', num, e)
            continue

    df = pd.DataFrame(user_list)
    print(df)
    return df
#df.to_csv('MasSeguidosTwitter19.csv')


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Refuel',
            fields=[
                ('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)),
                ('line', models.CharField(max_length=23)),
                ('consumption', models.PositiveIntegerField()),
                ('refuel_time', models.DateTimeField(auto_now_add=True)),
            ],
        ),
        migrations.CreateModel(
            name='User',
            fields=[
                ('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)),
                ('password', models.CharField(verbose_name='password', max_length=128)),
                ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
                ('tag_id', models.CharField(unique=True, max_length=50)),
                ('name', models.CharField(max_length=50)),
                ('email', models.EmailField(unique=True, max_length=254)),
                ('plate', models.CharField(max_length=30)),
                ('bank', models.CharField(max_length=30)),
                ('tel', models.CharField(max_length=50)),
                ('is_active', models.BooleanField(default=False)),
                ('is_admin', models.BooleanField(default=False)),
                ('date_joined', models.DateTimeField(auto_now_add=True)),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.AddField(
            model_name='refuel',
            name='user',
            field=models.ForeignKey(related_name='refuels', to='carreg_app.User'),
        ),
    ]


import sqlite3
global c, conn

conn = sqlite3.connect('jerbot-neo.db')
conn.row_factory = lambda cursor, row: row[0]
c = conn.cursor()

def try_create_table(table: str, keys: tuple):
    """
    Creates a table if it does not exist.
    :param table: String corresponding to a table in the SQLite database.
    :param keys: Tuple of keys for new table.
    :return: False if table exists or could not be created, True if created
    """
    try:
        c.execute(f'CREATE TABLE {table} {keys}')
        conn.commit()
        return True
    except sqlite3.OperationalError:
        return False

def drop_table(table: str):
    """
    Drops a table from the database.
    :param table: String corresponding to a table in the SQLite database.
    :return: True if table was successfully dropped.
    """
    try:
        c.execute(f'DROP TABLE {table}')
        conn.commit()
        return True
    except sqlite3.OperationalError:
        return False

def insert(table: str, values: tuple):
    """
    Inserts values into a table.
    :param table: String corresponding to a table in the SQLite database.
    :param values: Tuple of values to insert into the table.
    :return: False if data could not be inserted, True if inserted
    """
    c.execute(f'INSERT INTO {table} VALUES {values}')
    conn.commit()

def remove(table:str, exp: str):
    """
    Removes values from a table.
    :param table: String corresponding to a table in the SQLite database.
    :param exp: Expression for deletion.
    """
    c.execute(f'DELETE FROM {table} WHERE {exp}')
    conn.commit()

def query(query: str):
    """
    Queries from the database.
    Dangerous. DO NOT EXPOSE to a user command.
    :param query: String containing the query for the database.
    :return: fetchall() from query
    """
    c.execute(query)
    return c.fetchall()


from flask import request, make_response
from flask import render_template, flash
from flask.json import jsonify, dumps

from hummaps import app
from hummaps.search import do_search, ParseError
from hummaps.xhr import xhr_request

from hummaps.gpx import gpx_read, gpx_out
from hummaps.gpx import dxf_read, dxf_out
from hummaps.gpx import pnts_read, pnts_out

import os.path
from time import time

# Custom filter for the Jinja2 template processor
@app.template_filter('basename')
def basename_filter(s):
    return os.path.basename(s)

@app.route('/', methods=['GET', 'POST'])
def index():
    args = request.args
    if request.is_xhr:
        resp = jsonify(xhr_request(args.get('req', '')))
        resp.cache_control.public = True
        resp.cache_control.max_age = 3600
        resp.expires = int(time() + 3600)
        return resp
    elif request.method == 'POST':
        form = request.form
    else:
        form = None

    q = args.get('q', '')
    if q == '':
        return render_template('index.html', query='', results=[])

        # Server side processing of form data
        # if form:
        #     q = ' '.join([form['section'], form['township'], form['range']]).strip();
        #     if form['recdate']:
        #         if form['recdate-to']:
        #             q += ' date="' + form['recdate'] + ' ' + form['recdate-to'] + '"'
        #         else:
        #             q += ' date="' + form['recdate'] + '"'
        #     if form['surveyor']:
        #         q += ' by="' + re.sub(r'\s*\(.*', '', form['surveyor']) + '"'
        #     if form['client']:
        #         q += ' for="' + form['client'] + '"'
        #     if form['description']:
        #         q += ' desc="' + form['description'] + '"'
        #     if q:
        #         maptypes = []
        #         for t in ('cr', 'pm', 'rm', 'rs', 'ur'):
        #             if 'maptype-' + t in form:
        #                 maptypes.append(t)
        #         if 'maptype-other' in form:
        #             maptypes += ['hm|mm']
        #         if maptypes and len(maptypes) < 6:
        #             q += ' type=' + '|'.join(maptypes)
        #     if form['maps']:
        #         q = ' '.join([q, form['maps']])

    results = []
    try:
        results = do_search(q)
    except ParseError as e:
        term = ' (%s)' % e.term if e.term else ''
        flash('Search error%s: %s' % (term, e.err), 'error')
    except Exception as e:
        flash('Search error: %s' % str(e), 'error')

    total = len(results)
    if total > 200:
        results = results[0:200]

    return render_template('index.html', query=q, form=form, results=results, total=total)

@app.route('/gpx', methods=['GET', 'POST'])
def gpx():
    if request.method == 'POST':
        datatype = request.form['datatype']
        srid = int(request.form['srid'])
        outfile = request.form['filename']
        if outfile:
            i = outfile.rfind('.')
            if i > 0:
                outfile = outfile[0:i]  # strip extension
        else:
            outfile = 'results'
        # files = request.files.getlist('file')
        # headers = 'type: ' + datatype + ', srid: ' + str(srid) + ', files: ' + ', '.join([f.filename for f in files]) + '\n'
        geom = []
        for f in request.files.getlist('file'):
            filename = f.filename
            ext = filename.lower().rsplit('.', 1)[-1]
            if ext == 'txt':
                geom += pnts_read(f.stream, srid)
            elif ext == 'dxf':
                geom += dxf_read(f.stream, srid)
            elif ext == 'gpx':
                geom += gpx_read(f.stream)
        if datatype == 'pnts':
            resp = make_response(pnts_out(geom, srid))
            outfile += '.txt'
        elif datatype == 'dxf':
            resp = make_response(dxf_out(geom, srid))
            outfile += '.dxf'
        elif datatype == 'gpx':
            resp = make_response(gpx_out(geom))
            outfile += '.gpx'
        else:
            return('Bad type: %s' % datatype, 400)

        resp.headers['Content-Disposition'] = 'attachment; filename="%s"' % outfile
        resp.mimetype = 'application/octet-stream'
        resp.cache_control.no_cache = True
        resp.cache_control.no_store = True
        return resp

    return render_template('gpx.html')

#
# Service unavailable
#

@app.route('/error/503.html', methods=['GET'])
def unavailable():
    return render_template('503.html'), 503

#
# /robots.txt
#

@app.route ('/robots.txt')
def robots_txt():
    txt = ''.join((
        'User-agent: *\n',
        'Disallow: /map/\n',
        'Disallow: /pdf/\n',
        'Disallow: /scan/\n'
    ))
    return make_response(txt)

#
# HTTP error handlers
#

@app.errorhandler(400)
def bad_request(e):
    return render_template('400.html'), 400

@app.errorhandler(403)
def forbidden(e):
    return render_template('403.html'), 403

@app.errorhandler(404)
def not_found(e):
    return render_template('404.html'), 404

@app.errorhandler(500)
def server_error(e):
    return render_template('500.html'), 500


import os
import pathlib
import shutil
import sys

def create_sub_dirs(project_dir):
    sub_dirs = ["css", "js", "imgs"]
    for sub_dir in sub_dirs:
        sub_path = pathlib.PurePath(project_dir, sub_dir)
        os.mkdir(sub_path)

def generate_files(project_dir, site_starter_path):
    def create_index_html_file():
        index_template_path = pathlib.PurePath(site_starter_path,"index_template.html")
        index_file_path = pathlib.PurePath(project_dir, "index.html")
        shutil.copyfile(index_template_path, index_file_path)

    def create_css_files():
        css_file_path = pathlib.PurePath(project_dir, "css", "styles.css")
        f = open(css_file_path, "w")
        f.close()

    def create_js_file():
        js_file_path = pathlib.PurePath(project_dir, "js", "main.js")
        f = open(js_file_path, "w")
        f.close()

    create_index_html_file()
    create_css_files()
    create_js_file()

def main():
    if len(sys.argv) <= 1:
        print("Site Starter generates a project file with the specified project name in the cwd.")
        print("Usage: python3 path_to_generate.py <project_name>")
    else:
        cwd = os.getcwd()
        site_starter_path = pathlib.PurePath(sys.argv[0]).parent
        project_dir = pathlib.PurePath(cwd, sys.argv[1])
        os.mkdir(project_dir)
        create_sub_dirs(project_dir)
        generate_files(project_dir, site_starter_path)

if __name__ == '__main__': main()


import textdistance
import numpy as np

orig_order_ids = ['5269129170', '4269129163', '3269129163', '6269129163', '7269129163', '8269129155','12444456']

orig_shelves_list = [['R1', 'G1', 'C1', 'D1', 'D2'],
                ['A1', 'C3', 'B1'],
                ['R1', 'S1', 'BG1', 'FA1'],
                ['C3', 'R1', 'M1', 'M2'],
                ['P1', 'P3', 'P4', 'G6', 'G7'],
                ['P3', 'P4', 'G6', 'G7'],
                ['P1','P3''G7']]

aisles_unsorted =  ['RGCD', 'ACB', 'RSBA', 'CRM', 'PG', 'PG','PG']     #list will be generated by part1 code

print("******Original******")
print(aisles_unsorted)
print(orig_order_ids)
print(orig_shelves_list)

aisles = sorted(aisles_unsorted, key = aisles_unsorted.count,
                                reverse = True)
length = len(aisles)

indexes = []
indexes_done = []
for i in range(0,length):
	for j in range(0,length):
		if aisles[i] == aisles_unsorted[j] and j not in indexes_done:
			indexes.append(j)
			indexes_done.append(j)
print("******indexes****",indexes)
order_ids = []
shelves_list = []
leven_matrix = np.zeros((length,length),dtype=int)                            #initialise an empty matrix

for ind in indexes:
	order_ids.append(orig_order_ids[ind])
	shelves_list.append(orig_shelves_list[ind])
print("****sorted***")
print(aisles)
print(order_ids)
print(shelves_list)
def invalidate(start,id,col):               #once aisles of user are processed, mark them as 999 so that they won't be
    if col:                                 #considered for further batches
        for i in range(start,length):
            leven_matrix[id][i] = 999
        for j in range(0,length):
            leven_matrix[j][id] = 999
    else:                                   #we don't want to overwrite the current index column.
        for i in range(start,length):
            leven_matrix[id][i] = 999

for i in range(0,length):                   #mark the diagnoals 999
    for j in range(0,length):
        if i == j:
            leven_matrix[i][j] = 999

n = 3
done = []                                   #list of processed elements
batches = []                                #list of aisles in group of 3
order_batches = []                          #list of orders in group of 3
shelves_batches = []                        #list of shelves corresponding to 3 order_ids
for i in range(0,length):
    if i not in done and length-len(done)>=n:
        current = aisles[i]
        col = []
        top_n = []
        order_n = []
        shelves_n = []

        for j in range(0,length):
            if i == j:
                col.append(leven_matrix[i][j])
            else:
                if j not in done:
                    dst = textdistance.levenshtein(current,aisles[j])
                    leven_matrix[j][i] = dst
                    col.append(dst)
                else:
                    col.append(leven_matrix[j][i])      #999

        sorted_list = sorted(range(len(col)), key=lambda k: col[k])    #sort the column values and get indexes of sorted values.

        top_indexes = sorted_list[:n-1]
        top_n.append(current)
        order_n.append(order_ids[i])
        shelves_n.append(shelves_list[i])

        for id in top_indexes:
        	done.append(id)                    #mark it as "processed"
        	invalidate(i+1,id,True)
        	top_n.append(aisles[id])
        	order_n.append(order_ids[id])
        	shelves_n.append(shelves_list[id])

        if i not in done: done.append(i)
        invalidate(i+1,i,False)

        batches.append(top_n)
        order_batches.append(order_n)
        shelves_batches.append(shelves_n)

left_aisles = []
left_orders = []
left_shelves = []
print("\n Final matrix values: \n")

print(leven_matrix)            #print final matrix

for i in range(0,length):
    '''
    as batches of three, if the total number of orders received are not a multiple of three,
    orders will be left, add it to "left_aisles" and left_orders
    '''
    if i not in done:
        left_aisles.append(aisles[i])
        left_orders.append(order_ids[i])
        left_shelves.append(shelves_list[i])

if len(left_aisles) != 0:
    batches.append(left_aisles)
    order_batches.append(left_orders)
    shelves_batches.append(left_shelves)

print("\nAisles grouped together:\n",batches)                 #final batches
print("\nOrder ids grouped together:\n",order_batches)           #orders batches
print("\nShelves grouped together:\n",shelves_batches)         #shelves batches

'''
Output:

(base) F:\WalKet-Basket\Part2>python lavenstein.py

 Final matrix values:

[[999. 999. 999. 999. 999. 999.]
 [  3. 999. 999. 999. 999. 999.]
 [  3. 999. 999. 999. 999. 999.]
 [  4. 999. 999. 999. 999. 999.]
 [  3. 999. 999.   3. 999. 999.]
 [  3. 999. 999.   3. 999. 999.]]

Aisles grouped together:
 [['RGCD', 'ACB', 'RSBA'], ['CRM', 'PG', 'PG']]

Order ids grouped together:
 [['5269129170', '4269129163', '3269129163'], ['6269129163', '7269129163', '8269129155']]

Shelves grouped together:
 [[['R1', 'G1', 'C1', 'D1', 'D2'], ['A1', 'C3', 'B1'], ['R1', 'S1', 'BG1', 'FA1']], [['C3', 'R1', 'M1', 'M2'], ['P1', 'P3', 'P4', 'G6', 'G7'], ['P3', 'P4', 'G6', 'G7']]]
'''


print(_doc_)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import styles

from sklearn.datasets import fetch_olivetti_faces
from sklearn.utils.validation import check_random_state

from sklearn.ensemble import ExtraTreesRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import RidgeCV

#Load the faces dataset
data = fetch_olivetti_faces()
targets = data.target

data = data.images.reshape((len(data.images), -1))
train = data[targets < 30]
test = data[targets > 30] # Test on independent people

#Test on a subset of people
n_faces = 5
rng = check_random_state(4)
face_ids = rng.randint(test.shape[0], size=(nfaces, )) #?
test = test[faceids, :]

n_pixels = data.shape[1]
#Upper half of the faces
X_train = train[:, :np.ceil(0.5 * n_pixels)]
#Upper half of faces
y_train = train[:, np.floor(0.5 * n_pixels):]

#Testing sets for both labels and features
X_test = test[:, :np.ceil(0.5 * n_pixels)]
y_test = test[:, np.floor(0.5 * n_pixels):]

ESTIMATORS = {
	"Extra trees": ExtraTreesRegressor(n_estimators=10, max_features=32, random_state=0),
	"K-nn": KNeighborsRegressor(),
	"Linear regression": LinearRegression(),
	"Ridge": RidgeCV(),
}

y_test_predict = dict()
for name, estimator in ESTIMATORS.items():
	estimator.fit(X_train, y_train)
	y_test_predict[name] = estimator.predict(X_test)

#Plot the completed faces
image_shape = (64, 64)

n_cols = 1 + len(ESTIMATORS)
plt.figure(figsize=(2. * n_cols, 2.26 * n_faces))
plt.suptitle("Face completion with multi-output estimators", size=16)

for i in range(n_faces):
	true_face = np.haystack((X_test[i], y_test[i]))