from __future__ import annotations
from copy import deepcopy
from math import prod

class Dot(object):
    x: float
    y: float

    def __init__(self, x: float, y: float):
        self.x, self.y = x, y

    def __str__(self):
        return "(" + str(self.x) + ";" + str(self.y) + ")"

class Polynomial(object):
    terms: list[callable[float]:float]

    def __init__(self, terms: list[callable[float]:float]):
        self.terms = terms

    def __call__(self, arg: float) -> float:
        return sum([term(arg) for term in self.terms])

class NewtonPolynomial(Polynomial):

    @staticmethod
    def build(points: list[Dot], arg: Dot, n: int) -> NewtonPolynomial:
        table = NewtonPolynomial._make_table(points, arg, n)

        return NewtonPolynomial(
            [lambda x:table[1][0]] +
            [NewtonPolynomial._term(table[i][0],  table[0][:i - 1])
             for i in range(2, len(table))]
        )

    @staticmethod
    def _term(va: float, vl: list[float]) -> callable:
        return lambda x: va * prod(map(lambda a: (x - a), vl))

    @staticmethod
    def _make_table(points: list[Dot], arg: Dot, n: int) -> list[list[Dot]]:
        base = sorted(
            sorted(points, key=lambda p: abs(p.x - arg.x))[:n + 1],
            key=lambda p: p.x
        )

        t = [[None for i in range(len(base))] for j in range(n + 2)]

        for i in range(len(t[0])):
            t[0][i], t[1][i] = base[i].x, base[i].y

        for i in range(2, len(t)):
            for j in range(len(base) - i + 1):
                t[i][j] = (t[i - 1][j] - t[i - 1][j + 1]) / \
                    (t[0][j] - t[0][j + i - 1])

        return t

class BiNewtonPolynomial(Polynomial):

    __second_interp_set: list
    __ny: float

    def __init__(self, temp: list, ny: int):
        self.__second_interp_set = temp
        self.__ny = ny

    @staticmethod
    def build(dots: list[list[Dot]], arg: Dot, nx: int, ny: int) -> BiNewtonPolynomial:
        points = deepcopy(dots)
        xrow, ycol, matrix = BiNewtonPolynomial.__split_data(points)
        baseX, baseY = BiNewtonPolynomial.__get_bases(xrow, ycol, arg, nx, ny)

        t = [[None for i in range(nx + 1)] for j in range(ny + 1)]

        k = 0
        for i in range(xrow.index(baseX[0]), xrow.index(baseX[0]) + nx + 1):
            l = 0
            for j in range(ycol.index(baseY[0]), ycol.index(baseY[0]) + ny + 1):
                t[l][k] = matrix[i][j]
                l += 1
            k += 1

        second_set = []
        for i in range(len(t)):
            for j in range(len(baseX)):
                t[i][j].y = baseX[j].x
                t[i][j].x, t[i][j].y = t[i][j].y, t[i][j].x
            second_set += [
                Dot(
                    baseY[i].x,
                    NewtonPolynomial.build(t[i], Dot(arg.y, arg.x), nx)
                )
            ]

        return BiNewtonPolynomial(
            second_set,
            ny
        )

    @staticmethod
    def __split_data(matrix: list[list[Dot]]) -> tuple[list[Dot], list[Dot], list[list[Dot]]]:
        xrow = matrix[0]
        matrix = matrix[1:]
        ycol = [row[0] for row in matrix]
        matrix = [row[1:] for row in matrix]

        return xrow, ycol, matrix

    @staticmethod
    def __get_bases(x: list[Dot], y: list[Dot], arg: Dot, nx: int, ny: int):
        baseX = sorted(
            sorted(x, key=lambda p: abs(p.x - arg.x))[:nx + 1],
            key=lambda p: p.x
        )
        baseY = sorted(
            sorted(y, key=lambda p: abs(p.x - arg.y))[:ny + 1],
            key=lambda p: p.x
        )
        return baseX, baseY

    def __call__(self, arg: Dot) -> float:
        t = [Dot(i.x, i.y(arg.y)) for i in self.__second_interp_set]
        return NewtonPolynomial.build(t, arg, self.__ny)(arg.x)


import pandas as pd
from pulp import *
import itertools

df = pd.read_excel('beers.xlsx')

costs = df.\
    assign(Warehouse_to_Bar = lambda x: x.Warehouse_to_Bar.astype(str)).\
        set_index('Warehouse_to_Bar').\
            to_dict()

warehouses = ['A','B']
bars = [str(x) for x in range(1,6)]

supply_ = [1000,4000]
demand_ = [500,900,1800,200,700]

supply = dict(zip(warehouses,supply_))
demand = dict(zip(bars, demand_))

routes = list(itertools.product(warehouses,bars))

'''
dv : how many beers for every warehouse - bar pair
obj : minimize dv * cost
1) supply : sum of beers leaving a warehouse <= supply
2) demand : sum of beers reaching a bar == demand
'''

# instantiate minimization problem
prob = LpProblem('Beer_Transportation', LpMinimize)

# define decision variables
decision_vars = LpVariable.dicts('routes',(warehouses,bars),0,None,LpInteger)

# define objective function
prob += lpSum([decision_vars[w][b] * costs[w][b] for w,b in routes])

# define supply constrains
for w in warehouses:
    prob += lpSum([decision_vars[w][b] for b in bars]) <= supply[w]

# define demand constrains
for b in bars:
    prob += lpSum([decision_vars[w][b] for w in warehouses]) >= demand[b]

# solve problem
prob.solve()

# The status of the solution is printed to the screen
print("Status:", LpStatus[prob.status])

# print out solution
for w in warehouses:
    for b in bars:
        if value(decision_vars[w][b]):
            print(f'from {w} to {b} - {value(decision_vars[w][b])}')


import eventlet

from Skull import ServerSkull
from Ezgame import Ezgame
from Vote import Vote

class Player:
    def __init__(self, name, sid):
        self.name = name
        self.sid = sid
        self.connected = True

class Room:
    def __init__(self, sio):
        self.sio = sio
        self.ev = "room"
        self.playing = []
        self.watching = []
        self.game = None
        self.current_vote = None
        sio.on('connect', self.on_connect)
        sio.on('disconnect', self.on_disconnect)
        sio.on('message', self.io_handler)

        self.proposed_game = None
        self.game_dict = {}
        self.game_dict["skull"] = ServerSkull
        self.game_dict["nines"] = Ezgame

    def on_connect(self, sid, environ):
        print('connect ', sid)
        self.sio.emit(self.ev, ("display", self.get_emit_data()), room=sid);
        print("emit data sent")

    def on_disconnect(self, sid):
        print('disconnect ', sid)
        for pp in self.playing:
            if pp.sid == sid:
                pp.connected = False

        for i in reversed(range(len(self.watching))):
            if self.watching[i].sid == sid:
                self.watching.pop(i)

    def io_handler(self, sid, data):
        print("room::io_handler: ", data)
        if "room" in data:
            rd = data["room"]
            if "name" in rd:
                self.set_name(sid, rd["name"])
                return
            if rd == "play":
                self.ready(sid)
                return
            if "kwalexadmin" in rd:
                self.start_game(rd["kwalexadmin"])
            if "ping" in rd:
                self.notify_main("pong", sid)
            if rd == "watch":
                self.watch(sid)
            if "poll" in rd:
                self.poll(rd["poll"], sid)
            if "gamevote" in rd:
                self.gamevote(rd["gamevote"],sid)
            # if "callvote" in rd:
            #     if self.find_player(sid=sid) != None:
            #         cd = rd["callvote"]
            #         if "type" not in cd or "text" not in cd:
            #             self.notify_main("garbage callvote")
            #             return
            #         self.callvote(cd["type"], cd["text"])
            #     else:
            #         self.notify_main(sid, "you aren't playing yet")
            if "vote" in rd:
                self.vote(sid, rd["vote"])
                # vote_type = cd["type"]
                # vote_text = cd["text"]
        elif self.game_ev in data:
            self.game.io_handler(sid, data)
                # eventlet.spawn_after(3, self.notify_main, sid, "pong2")

    def find_player(self, sid=None, name=None):
        l = self.playing
        if sid != None:
            m = [p for p in l if p.sid == sid]
        elif name != None:
            m = [p for p in l if p.name == name]
        else:
            m = []

        if len(m) > 0:
            return m[0]
        else:
            return None

    def poll(self, text=None, sid=None):
        # self.notify_side(msg="poll: {}".format(vote_text))
        if text == None:
            self.notify_main("garbage poll", sid)
            return
        if self.current_vote != None:
            self.notify_main("There's already a vote happening", sid)
            return
        if self.find_player(sid=sid) == None:
            self.notify_main("You aren't even playing yet", sid)
            return

        st = str(text)
        plist = [p.name for p in self.playing]
        self.current_vote = Vote(plist, "poll", st, self.poll_result, 24)
        self.send_vote_data()

    def gamevote(self, g, sid=None):
        gs = str(g)
        print("gamevote", gs)
        if self.current_vote != None:
            self.notify_main("There's already a vote happening", sid)
            return
        if gs not in self.game_dict:
            self.notify_main("what game are *you* trying to play?", sid)
            return
        if self.find_player(sid=sid) == None:
            self.notify_main("You aren't even playing yet", sid)
            return

        self.proposed_game = gs
        plist = [p.name for p in self.playing]
        self.current_vote = Vote(plist, "game", "Vote to play: {}".format(gs), self.play_result, 24)
        self.send_vote_data()

    # def callvote(self, vote_type, vote_text):
    #     if self.current_vote == None:
    #         n_players = len(self.playing)
    #         plist = [p.name for p in self.playing]
    #         if vote_type == "poll":
    #             # self.notify_side(msg="poll: {}".format(vote_text))
    #             self.current_vote = Vote(plist, vote_type, vote_text, self.poll_result, 24)
    #             self.send_vote_data()
    #         if vote_type == "play":
    #             self.proposed_game = vote_text
    #             self.current_vote = Vote(plist, vote_type, "Vote to play: {}".format(vote_text), self.play_result, 24)
    #             self.send_vote_data()
    #     else:
    #         self.notify_main("There's already a vote in progress.")

    def vote(self, sid, v):
        if self.current_vote != None:
            if v == "yes":
                tf = True
            elif v == "no":
                tf = False
            else:
                print("bad vote: ", sid, v)
                self.notify_main("bad vote...", sid)
                return

            fp = self.find_player(sid=sid)
            if fp == None:
                self.notify_main("you aren't playing", sid)
                return
            r = self.current_vote.vote(fp.name, tf)
            if r == False:
                self.notify_main("you can't vote", sid)
            self.send_vote_data()

    def send_vote_data(self):
        if self.current_vote == None:
            return
        dd = self.current_vote.data()
        self.sio.emit(self.ev, ("voteData", dd))

    def poll_result(self, res):
        self.send_vote_data()
        self.current_vote = None
        print("poll_result: ", res)

    def play_result(self, res):
        self.send_vote_data()
        self.current_vote = None
        if res == True:
            self.start_game()

    def set_name(self, sid, longname):
        ls = "{}".format(longname)
        name = longname[0:8]
        # print("set name: ", name)

        # watching_names = [cp.name for cp in self.watching]
        # watching_sockets = [cp.sid for cp in self.watching]
        # playing_names = [cp.name for cp in self.playing]
        # playing_sockets = [cp.sid for cp in self.playing]
        #
        # match_watching = [cp for cp in self.watching if cp.sid == sid]
        # match_playing = [cp for cp in self.playing if cp.sid == sid]

        mws = [cp for cp in self.watching if cp.sid == sid]
        mps = [cp for cp in self.playing if cp.sid == sid]
        mwn = [cp for cp in self.watching if cp.name == name]
        mpn = [cp for cp in self.playing if cp.name == name]

        matched_watcher = mws[0] if len(mws) > 0 else None
        matched_player = mps[0] if len(mps) > 0 else None

        if len(mwn) > 0:
            self.notify_main("someone already got that one", sid)
            return

        if matched_player:
            self.notify_main("can't change it now", sid)
            return
        elif len(mpn) > 0:
            if mpn[0].connected == False:
                matched_player = mpn[0]
            else:
                self.notify_main("name taken you idiots", sid)
                return

        if not matched_player and not matched_watcher:
            self.notify_main("logging in as: {}".format(name), sid)
            self.watching.append(Player(name, sid))
            if self.game:
                self.emit_start_game(sid)
        elif not matched_player and matched_watcher:
            self.notify_main("name changed to: {}".format(name), sid)
            matched_watcher.name = name
        elif matched_player and not matched_watcher:
            matched_player.sid = sid
            matched_player.connected = True
            self.notify_main("logging back in as: {}".format(name), sid)

        self.emit_display()

    def ready(self, sid):
        print("ready: ", sid)
        if self.find_player(sid=sid) != None:
            if self.game:
                self.emit_start_game(sid)
                return

        for i in reversed(range(len(self.watching))):
            if self.watching[i].sid == sid:
                if self.game:
                    self.notifyMain(sid, "Wait for the current game to end.")
                    return
                else:
                    # console.log("ready: ", id, self.watching.length)
                    self.playing.append(self.watching[i])
                    self.watching.pop(i)

        self.emit_display()

    def watch(self, sid):
        for i in reversed(range(len(self.playing))):
            if self.playing[i].sid == sid:
                cp = self.playing[i]
                self.playing.pop(i)
                self.watching.append(cp)
                self.emit_display()

    def start_game(self, gamename=None):
        self.current_vote = None
        gamename = gamename if gamename else self.proposed_game
        if gamename == "skull":
            self.game_ev = gamename
            self.game = ServerSkull(self);
        elif gamename == "nines":
            self.game_ev = gamename
            self.game = Ezgame(self);
        if self.game:
            for cp in self.playing:
                self.emit_start_game(cp.sid)
        self.game.start()
        self.emit_display()

    def emit_start_game(self, sid):
        gamename = self.game_ev
        iData = self.game.initialData(sid)
        fData = ["startGame", gamename]
        fData.extend(iData)
        self.sio.emit(self.ev, tuple(fData), room=sid)

    def end_game(self):
        self.game = None;
        self.sio.emit(self.ev, "endGame");

    def notify_main(self, msg, sid=None):
        self.sio.emit(self.ev, ("notifyMain", msg), room=sid)
        # print("notify_main: ", msg)

    def notify_vote(self, msg, sid=None):
        self.sio.emit(self.ev, ("notifyVote", msg), room=sid)
    def notify_side(self, sid=None, msg=None):
        self.sio.emit(self.ev, ("notifySide", msg),room=sid)

    def get_emit_data(self):
        output = {"playing":[cp.name for cp in self.playing],
                "watching":[cp.name for cp in self.watching],
                "game":self.game.ev if self.game else None}
        return output

    def emit_display(self):
        self.sio.emit(self.ev, ("display", self.get_emit_data()))

    def emit_player(self, player, d):
        self.sio.emit(self.game_ev, d, room=player.sid)

    def emit_game(self, d):
        self.sio.emit(self.game_ev, d)


import simplejson as json
from datetime import datetime

DEBUG = False

# Zigbee catch-all decoder, just adds the following properties:
# Only changes topic:
#  csn-zigbee/acp_id -> acp/acp_id/csn-zigbee
class Decoder(object):
    def __init__(self, settings=None):
        print("   zigbee_catchall init()")

        return

    def test(self, topic, message_bytes):

        if DEBUG:
            print("zigbee_catchall test() {} {}".format(topic, message_bytes))
        #regular topic format:
        #cambridge-sensor-network/devices/zigbee_catchall-test-3/up

        if ("csn-zigbee" in topic):  #check if application name appears in the topic
            if DEBUG:
                print("zigbee_catchall test() success")
            return True
        #elif ("dev_id" in msg):  #dev_id for example, can be any other key
        #    msg=json.loads(message.payload)
        #    if (decoder_name in msg["dev_id"]):
        #        return True
        #    #elif...
        #    else:
        #        return False
        if DEBUG:
            print("zigbee_catchall test() fail")
        return False

    def decode(self, topic, message_bytes):
        inc_msg = str(message_bytes,'utf-8')

        if DEBUG:
            print("zigbee_catchall decode str {}".format(inc_msg))

        # Zigbee topic is "csn-zigbee/<acp_id>[/<other stuff>]"
        topic_parts = topic.split('/',2) # split into max 4 topic_parts

        output_topic = "acp/"+topic_parts[1]+"/"+topic_parts[0]

        if len(topic_parts) > 2:
            output_topic += "/" + topic_parts[2]

        # For this version of the decoder the original message from
        # deconz2acp will be published unchanged.
        msg_dict = json.loads(message_bytes)
        return msg_dict

    # end zigbee_catchall


from transformers import BertForTokenClassification, BertJapaneseTokenizer, get_linear_schedule_with_warmup
from flask import Flask, render_template, request
import argparse
import json
from predict import predict
import torch
import sys
from pathlib import Path
base_dir = Path(__file__).resolve().parents[1]
sys.path.append(str(base_dir))

from utils import iob2json

device = 'cuda' if torch.cuda.is_available() else 'cpu'

app = Flask(__name__)

@app.route("/", methods=['POST'])
def index():
    word = request.form["text"]
    input_json = json.loads(word)
    input_x = [input_json[str(i)] for i in range(len(input_json))]
    input_x = [tokenizer.tokenize(t) for t in input_x]
    input_x = [tokenizer.convert_tokens_to_ids(['[CLS]'] + x) for x in input_x]
    tags = predict(model, input_x,  device)

    labels = [[id2label[t] for t in tag] for tag in tags]
    input_x = [tokenizer.convert_ids_to_tokens(t)[1:] for t in input_x]

    output = [zip(x, l) for x, l in zip(input_x, labels)]
    output = [iob2json.decode_iob(i) for i in output]

    return iob2json.create_json(output)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Train BERT')
    parser.add_argument('--model_dir', type=str, help='data path')
    args = parser.parse_args()

    tokenizer = BertJapaneseTokenizer.from_pretrained("bert-base-japanese-char")

    with open(args.model_dir + '/label_vocab.json', 'r') as f:
        label_vocab = json.load(f)
    id2label = {v:k for k, v in label_vocab.items()}

    model = BertForTokenClassification.from_pretrained('bert-base-japanese-char', num_labels=len(label_vocab))

    model_path = args.model_dir + '/final.model'
    model.load_state_dict(torch.load(model_path))

    app.run(port='8000', host='0.0.0.0', debug=True)


print('1')

#from src.__init__ import main

from flask import Flask, request
from flask_restx import Api, Namespace, fields, Resource

## local
from settings import model_path, vocab_path, cnn_path
from torch import nn

# from src.controller.analyzeController import Analyze
from src.controller.keywordController import Keyword
from src.controller.testController import Sample
from src.controller.divideHighlightController import Divide_Highlight

if __name__ == "__main__" :
    from load_models import koBERT_CNN_Classifier
    prediction = koBERT_CNN_Classifier(model_path=model_path, vocab_path=vocab_path, cnn_path=cnn_path)
    # app.run(debug=True, host='0.0.0.0')

class Classifier(nn.Module):
    def __init__(self,
                     hidden_size=768,
                     num_classes=8,
                     dr_rate=0.0):
        super(Classifier, self).__init__()
            # 16, 2848
            # 32, 5696
            # 1312
        self.kernel_num = 16
        self.conv1d_maxpooling1 = nn.Sequential(
                nn.Conv1d(hidden_size, self.kernel_num, 4, stride=2),
                nn.ReLU(),
                nn.MaxPool1d(2, 1),
                nn.Dropout(dr_rate)
            )
        self.conv1d_maxpooling2 = nn.Sequential(
                nn.Conv1d(hidden_size, self.kernel_num, 8, stride=2),
                nn.ReLU(),
                nn.MaxPool1d(2, 1),
                nn.Dropout(dr_rate)
            )
        self.conv1d_maxpooling3 = nn.Sequential(
                nn.Conv1d(hidden_size, self.kernel_num, 16, stride=2),
                nn.ReLU(),
                nn.MaxPool1d(2, 1),
                nn.Dropout(dr_rate)
            )

        self.classifier = nn.Linear(1312, num_classes)

    def forward(self, x) :
        out1 = self.conv1d_maxpooling1(x.transpose(1, 2))
        out2 = self.conv1d_maxpooling2(x.transpose(1, 2))
        out3 = self.conv1d_maxpooling3(x.transpose(1, 2))
        out = torch.cat((out1, out2, out3), 2)
        out = out.reshape(out.size(0), -1)
        return  self.classifier(out)

#from load_models import koBERT_CNN_Classifier
from settings import model_path, cnn_path, vocab_path

from torch import nn
import torch

from src.preprocessor.textPreprocessor import textPreprocessor

print('2')

app = Flask(__name__)
api = Api(
    app,
    version='0.1',
    title="PS HELPER API Server",
    description="PS HELPER API 문서입니다.",
    terms_url="/",
    contact_url="donghoon149@gmail.com / hmcck27@gmail.com",
    license="MIT"
)

Analyze = Namespace(
    name="Analyze Algorithm",
    description='문제 지문을 받고 적절한 알고리즘 태그를 반환합니다.',
)

api.add_namespace(Divide_Highlight, '/api/v1/divide_highlight')
api.add_namespace(Keyword, '/api/v1/keyword')
api.add_namespace(Analyze, '/api/v1/analyze')
api.add_namespace(Sample, '/api/v1/test')

# Model 객체 생성
analyze_fields = Analyze.model('Problem', {
    'problem_id': fields.Integer(description='문제 번호', required=True, example="1007"),
    'content': fields.String(description='문제 지문', required=True,
                             example="평면 상에 N개의 점이 찍혀있고, 그 점을 집합 P라고 하자. 하지만 집합 P의 벡터 매칭은 벡터의 집합인데, 모든 벡터는 집합 P의 한 점에서 시작해서, 또 다른 점에서 끝나는 벡터의 집합이다. 또, P에 속하는 모든 점은 한 번씩 쓰여야 한다.V에 있는 벡터의 개수는 P에 있는 점의 절반이다.평면 상의 점이 주어졌을 때, 집합 P의 벡터 매칭에 있는 벡터의 합의 길이의 최솟값을 출력하는 프로그램을 작성하시오."),
    'input': fields.String(description='문제 입력사항', required=False,
                           example="첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 다음과 같이 구성되어있다. 테스트 케이스의 첫째 줄에 점의 개수 N이 주어진다. N은 짝수이다. 둘째 줄부터 N개의 줄에 점의 좌표가 주어진다. N은 20보다 작거나 같은 자연수이고, 좌표는 절댓값이 100,000보다 작거나 같은 정수다. 모든 점은 서로 다르다."),
})

algorithm_fields = fields.Wildcard(fields.String)

analyze_response = Analyze.model('Problem_response', {
    'problem_id': fields.String(description='문제 번호', required=True, example="1007"),
    'problem_url': fields.String(description="문제 url", required=True, example="www.psHelper.de"),
    'algorithm_type': algorithm_fields
})

''' test '''
print('sdfsdfsdfsdf')

@Analyze.route('')
class AnalyzeController(Resource):

    @Analyze.expect(analyze_fields)
    @Analyze.response(201, "Success", analyze_response)
    def post(self):
        content = request.json.get('content')
        text_preprocessor = textPreprocessor()
        '''
            TO-DO
            0. preprocess text
            1. analyze the description
        '''
        preprocessed_text = text_preprocessor.preprocessing(content)
        # tag = TagAnalyzer.findTag(preprocessed_text)
        tag,ratio = prediction.predict(preprocessed_text)
        # print(content)

        return {
                   'problem_id': request.json.get('problem_id'),
                   'problem_url': "https://www.acmicpc.net/problem/" + str(request.json.get('problem_id')),
                   'algorithm_type' : tag,
                   'algorithm_ratio' : ratio
               }, 201

print('sdfsdfwerwer')

# class Classifier(nn.Module):
#     def __init__(self,
#                  hidden_size=768,
#                  num_classes=8,
#                  dr_rate=0.0):
#         super(Classifier, self).__init__()
#         # 16, 2848
#         # 32, 5696
#         # 1312
#         self.kernel_num = 16
#         self.conv1d_maxpooling1 = nn.Sequential(
#             nn.Conv1d(hidden_size, self.kernel_num, 4, stride=2),
#             nn.ReLU(),
#             nn.MaxPool1d(2, 1),
#             nn.Dropout(dr_rate)
#         )
#         self.conv1d_maxpooling2 = nn.Sequential(
#             nn.Conv1d(hidden_size, self.kernel_num, 8, stride=2),
#             nn.ReLU(),
#             nn.MaxPool1d(2, 1),
#             nn.Dropout(dr_rate)
#         )
#         self.conv1d_maxpooling3 = nn.Sequential(
#             nn.Conv1d(hidden_size, self.kernel_num, 16, stride=2),
#             nn.ReLU(),
#             nn.MaxPool1d(2, 1),
#             nn.Dropout(dr_rate)
#         )
#
#         self.classifier = nn.Linear(1312, num_classes)
#
#     def forward(self, x) :
#       out1 = self.conv1d_maxpooling1(x.transpose(1, 2))
#       out2 = self.conv1d_maxpooling2(x.transpose(1, 2))
#       out3 = self.conv1d_maxpooling3(x.transpose(1, 2))
#       out = torch.cat((out1, out2, out3), 2)
#       out = out.reshape(out.size(0), -1)
#       return  self.classifier(out)

#if __name__ == "__main__":
#    app.run(debug=True, host='0.0.0.0')


from collections import defaultdict

class Solution:
    def longestStrChain(self, words: List[str]) -> int:
        n = len(words)
        words.sort(key=lambda word: len(word))
        graph = defaultdict(set)

        for i, word in enumerate(words):
            for j in range(len(word)):
                graph[word[:j] + word[j + 1:]].add(i)

        dists = [1] * n
        res = 1

        for u in range(n):
            for v in graph[words[u]]:
                dists[v] = max(dists[v], dists[u] + 1)
                res = max(res, dists[v])

        return res


import json
import boto3
from datetime import datetime

current_date_time = datetime.now()

sqs = boto3.resource('sqs', region_name='us-east-1')

def lambda_handler(event, context):

    queue = sqs.get_queue_by_name (QueueName='CustomerOrders')

    date_time = current_date_time.strftime("%d/%m/%Y %H:%M:%S")

    message = ("The current date and time at point of trigger was " + str(date_time) + ".")

    response = queue.send_message (MessageBody=message)

    return {
        'statusCode': 200,
        'body': json.dumps(message)
    }


import os
import subprocess

path = os.getcwd()

# train the new model
qu_train_data = path + "/data/quarterly.csv"
qu_model = "linear_quarterly"
exec_cmd1 = "python3 " + path + "/train_linear.py " + qu_train_data + " ./data/test.csv " + qu_model
exec_cmd2 = "python3 " + path + "/train_log.py " + qu_train_data + " ./data/test.csv " + qu_model
subprocess.call([exec_cmd1, exec_cmd2], shell=True)


# Create a class Car with attributes Model, year, and price
# and a method cost() for displaying price.
# Create two instances of the class and call the method for each instance
class car:
  def __init__(self,mod,yr,prz):
    self.Model=mod
    self.year=yr
    self.price=prz
  def cost(self):
    print("cost: ",self.price)

c1=car("jk4302",2022,10000000)
c2=car("san",2021,5000000)

c1.cost()
c2.cost()


from matplotlib import pyplot as plt

# 题目：某月气温变化表

# 知识点总结：
# 1.x,y的输入
# 2.绘制  plt.plot()
# 3.设置图片大小 plt.figure()
# 4，保存到本地 plt.savefig()
# 5.描述信息 xlabel() ylable() title()
# 6.调整x，y的间距 xticks(),yticks()
# 7.线条的样式 linestyle=
# 8.标记出特殊的点
# 9.添加水印

# 设置图片大小
plt.figure(figsize=(16, 8), dpi=80)

# 左闭右开
x = range(2, 26, 2)
y = [15, 13, 14.5, 17, 20, 25, 26, 26, 24, 22, 18, 15]

# 传入x，y通过plot绘制出折线图
plt.plot(x, y)

# 设置x，y轴的刻度
# plt.xticks(x)
# plt.xticks(range(2, 25))
num = []
for i in range(2, 25):
    num.append(i)
    num.append(i + 0.5)
# plt.xticks(num[::3])

num = [i / 2 for i in range(4, 50)]
plt.xticks(num)
plt.yticks(range(min(y), max(y) + 1))

# 保存
# plt.savefig("./SaveDate/p1.png")

# 输出
plt.show()

# 关于range：
# 在 Python 3 中，range() 函数返回的对象并不是列表，而是一个类型为 range 的可迭代对象（iterable），
# 它按需生成指定范围内的整数。这种方式称为“惰性求值”（lazy evaluation），它可以节省空间和时间。

# 因为 range 对象并不是列表，所以它并不占用与列表相同的内存空间。
# 相反，它只需要存储 start、stop 和 step 这三个参数，以及根据这些参数生成整数序列的算法。

# 当使用 range 对象时，Python 会根据需要逐个生成序列中的元素，而不是一次性生成所有元素并存储在内存中。

# 如果您需要将 range 对象转换为列表，可以使用 list() 函数将其转换为列表


from django.urls import resolve, reverse

from .. import views
from .test_recipes_base import RecipesTestBase

class RecipesSearchViewTest(RecipesTestBase):
    def test_search_view_function_is_correct(self):
        view = resolve(reverse('recipes:search'))
        self.assertIs(view.func, views.search)

    def test_search_loads_correct_template(self):
        response = self.client.get(reverse('recipes:search') + '?q=test')
        self.assertTemplateUsed(response, 'recipes/pages/search.html')

    def test_search_raises_404_if_no_search_term(self):
        response = self.client.get(reverse('recipes:search'))
        self.assertEqual(response.status_code, 404)

    def test_search_term_is_on_page_title_and_escaped(self):
        response = self.client.get(reverse('recipes:search') + '?q=<test>')
        self.assertIn('Search for "<test>"',
                      response.content.decode('utf-8'))

    def test_search_can_find_by_title(self):
        title1 = 'This is recipe one'
        title2 = 'This is recipe two'

        recipe1 = self.create_recipe(
            slug='one', title=title1, author={'username': 'one'})
        recipe2 = self.create_recipe(
            slug='two', title=title2, author={'username': 'two'})

        search_url = reverse('recipes:search')

        response1 = self.client.get(f'{search_url}?q={title1}')
        response2 = self.client.get(f'{search_url}?q={title2}')
        response3 = self.client.get(f'{search_url}?q=this')

        self.assertIn(recipe1, response1.context['recipes'])
        self.assertNotIn(recipe2, response1.context['recipes'])

        self.assertIn(recipe2, response2.context['recipes'])
        self.assertNotIn(recipe1, response2.context['recipes'])

        self.assertIn(recipe1, response3.context['recipes'])
        self.assertIn(recipe2, response3.context['recipes'])


# Updated code for part 1 in order to get part 2
# and didn't save copy.  Only have  Part II code

with open('d8p1.txt', 'r') as f:
    data = [p.split() for p in f.read().strip().split('\n')]

accumulator = 0
visited = {}
start = 0
next_code = 1
stop_code = False
last_index = len(data) - 1
occurrances = 0

while not stop_code:
    if start == last_index:
        stop_code = True
    instruction, value = data[start][0], int(data[start][1])

    if instruction in ["jmp", "nop"]:
        occurrances += 1
        if instruction == 'jmp' and occurrances == next_code:
            instruction = 'nop'
        elif instruction == "nop" and occurrances == next_code:
            instruction = 'jmp'

    if start in visited:
        visited = {}
        next_code += 1
        accumulator = 0
        start = 0
        occurrances = 0

    else:
        visited[start] = 1

        if instruction == 'acc':
            start += 1
            accumulator += value
        elif instruction == 'jmp':
            start += value
        else:
            start += 1

print(f'value of accumulator: {accumulator}')


import sqlite3
import time
from telethon import TelegramClient
from telethon import sync, events
import re
import json

db = sqlite3.connect('Account.db')
cur = db.cursor()

x = 1
m = 0

while(True):
    if x == 23:
        print("Всего добыто:")
        print(m)
        break
    cur.execute(f"SELECT PHONE FROM Account WHERE ID = '{x}'")
    time.sleep(0.4)
    Phone = str(cur.fetchone()[0])
    print("Входим в аккаунт: " + Phone)

    cur.execute(f"SELECT API_ID FROM Account WHERE ID = '{x}'")
    time.sleep(0.4)
    api_id = str(cur.fetchone()[0])
    cur.execute(f"SELECT API_HASH FROM Account WHERE ID = '{x}'")
    time.sleep(0.4)
    api_hash = str(cur.fetchone()[0])
    session = str("anon" + str(x))
    client = TelegramClient(session, api_id, api_hash)
    client.start()

    dlgs = client.get_dialogs()
    for dlg in dlgs:
        if dlg.title == 'LTC Click Bot':
            tegmo = dlg

    client.send_message('LTC Click Bot', "/balance")
    time.sleep(3)
    msgs = client.get_messages(tegmo, limit=1)

    for mes in msgs:
        str_a = str(mes.message)
        zz = str_a.replace('Available balance: ', '')
        qq = zz.replace(' LTC', '')
        print(qq)
        waitin = float(qq)

    m = m + waitin
    #print(m)
    x = x + 1
    time.sleep(1)


#! /usr/bin/env python
import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.io import wavfile # get the api
from scipy.signal import fftconvolve, convolve, stft, butter
import numpy as np
from scipy import signal
import warnings
warnings.filterwarnings("ignore")

from numpy import array, diff, where, split
from scipy import arange

# fs, data = wavfile.read('Ding.wav') # load OG file
# a = data.T[0]

# fs2, data2 = wavfile.read('Long.wav') # load the data
# a2 = data2.T[0]

# d = fftconvolve(a, a2)
# print(d.shape)
# for i in range(len(d)):
# 	if d[i] > 0.85: #Tune this for the DING
# 		print('Do something')
# 		break
# plt.plot(d)
# plt.show()

#import keyboard

def findPeak(magnitude_values, noise_level=2000):

    splitter = 0
    # zero out low values in the magnitude array to remove noise (if any)
    magnitude_values = np.asarray(magnitude_values)
    low_values_indices = magnitude_values < noise_level  # Where values are low
    magnitude_values[low_values_indices] = 0  # All low values will be zero out

    indices = []

    flag_start_looking = False

    both_ends_indices = []

    length = len(magnitude_values)
    for i in range(length):
        if magnitude_values[i] != splitter:
            if not flag_start_looking:
                flag_start_looking = True
                both_ends_indices = [0, 0]
                both_ends_indices[0] = i
        else:
            if flag_start_looking:
                flag_start_looking = False
                both_ends_indices[1] = i
                # add both_ends_indices in to indices
                indices.append(both_ends_indices)

    return indices

def extractFrequency(indices, freq_bins, freq_threshold=2):

    extracted_freqs = []

    for index in indices:
        freqs_range = freq_bins[index[0]: index[1]]
        avg_freq = round(np.average(freqs_range))

        if avg_freq not in extracted_freqs:
            extracted_freqs.append(avg_freq)

    # group extracted frequency by nearby=freq_threshold (tolerate gaps=freq_threshold)
    group_similar_values = split(extracted_freqs, where(diff(extracted_freqs) > freq_threshold)[0]+1 )

    # calculate the average of similar value
    extracted_freqs = []
    for group in group_similar_values:
        extracted_freqs.append(round(np.average(group)))

    #print("freq_components", extracted_freqs)
    return extracted_freqs

import pyaudio

ding_left = np.load('ding_select_floor2_left_mic.npy')
ding_right = np.load('ding_select_floor7_right_mic.npy')

CHUNK = 4096 # number of data points to read at a time
RATE = 48000 # time resolution of the recording device (Hz)

p=pyaudio.PyAudio() # start the PyAudio class
stream=p.open(format=pyaudio.paInt16,channels=1,rate=RATE,input=True,
              frames_per_buffer=CHUNK) #uses default input device

while 1:
	data_buffer = np.array([])
	# create a numpy array holding a single read of audio data
	for i in range(10): #to it a few times just to see
	    data = np.frombuffer(stream.read(CHUNK),dtype=np.int16)
	    data_buffer = np.concatenate([data_buffer, data])

	fs = RATE
	# f1, t1, ding_left2 = signal.stft(ding_left, fs, nperseg=1000)
	# f2, t2, ding_right2 = signal.stft(ding_right, fs, nperseg=1000)
	# f,t,data_buffer2= signal.stft(data_buffer, fs, nperseg=1000)

	number_samples = len(data_buffer)

	freq_bins = arange(number_samples) * RATE/number_samples

	#ding_left2 = fft(ding_left)
	#ding_right2 = fft(ding_right)
	data_buffer_fft = fft(data_buffer)
	#data_buffer_fft = np.fft.fftfreq(len(data_buffer), data_buffer)
	#print(data_buffer2)

	normalization_data = data_buffer_fft/number_samples
	magnitude_values = normalization_data[range(len(data_buffer_fft)//2)]
	magnitude_values = np.abs(magnitude_values)

	indices = findPeak(magnitude_values=magnitude_values, noise_level=100)
	frequencies = extractFrequency(indices, freq_bins)

	#print(frequencies)

	# amp = 2 * np.sqrt(2)
	# plt.pcolormesh(t1, f1, np.abs(ding_left), vmin=0)
	# plt.pcolormesh(t2, f2, np.abs(ding_right), vmin=0)
	# plt.ylabel('Frequency [Hz]')
	# plt.xlabel('Time [sec]')
	# plt.show()
	#x = np.abs(data_buffer2).mean()
	x = max(frequencies)
	#x = x/1000
	print(x)
	if x > 750 and x < 800:
		print("RIGHT DING MAYBE")
	# if x > 270 and x < 350:
	# 	print("LEFT DING MAYBE")
	# if x > 1300 and x < 1400:
	# 	print("RIGHT DING MAYBE")
	# if x > 500 and x < 550:
	# 	print("LEFT DING MAYBE")

	#print(np.abs(data_buffer).max())
	# d_left = convolve(ding_left, data_buffer)
	# d_right = convolve(ding_right, data_buffer)

	# dlmax = d_left.mean()
	# drmax = d_right.mean()
	#print("left ding is:" +str(dlmax) + "right ding is:" +str(drmax))
	#print("right new is:" + str(d_right_fft.mean()))
	#FLOOR 7
	# if dlmax > 20173224741.999992:
	# 	print('Left DING')
	# if drmax > 30888468567.000004:
	# 	print('Right DING')
	# if dlmax > 10008361056.999992:
	# 	print('Left DING')
	# if drmax > 2000511377.789566:

	# 	print('Right DING')

# data_buffer = np.load('ding2.npy')[73000: 130000]

# np.save('ding_select.npy', data_buffer)
# plt.plot(data_buffer)
# plt.show()
# d = fftconvolve(a, data)
# plt.plot(d)
# print(d.max())
# plt.show()

# close the stream gracefully
stream.stop_stream()
stream.close()
p.terminate()


import warnings

from cupy import testing
import cupyx.scipy.signal.windows as cu_windows

import pytest
from pytest import raises as assert_raises

try:
    import scipy.signal.windows as cpu_windows  # NOQA
    import scipy.fft  # NOQA
except ImportError:
    pass

window_funcs = [
    ('boxcar', ()),
    ('triang', ()),
    ('parzen', ()),
    ('bohman', ()),
    ('blackman', ()),
    ('nuttall', ()),
    ('blackmanharris', ()),
    ('flattop', ()),
    ('bartlett', ()),
    ('barthann', ()),
    ('hamming', ()),
    ('kaiser', (1,)),
    ('gaussian', (0.5,)),
    ('general_gaussian', (1.5, 2)),
    ('chebwin', (1,)),
    ('cosine', ()),
    ('hann', ()),
    ('exponential', ()),
    ('taylor', ()),
    ('tukey', (0.5,)),
]

class TestBartHann:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-15, atol=1e-15)
    def test_basic(self, xp, scp):
        w1 = scp.signal.windows.barthann(6, sym=True)
        w2 = scp.signal.windows.barthann(7)
        w3 = scp.signal.windows.barthann(6, False)
        return w1, w2, w3

class TestBartlett:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-15, atol=1e-15)
    def test_basic(self, xp, scp):
        w1 = scp.signal.windows.bartlett(6)
        w2 = scp.signal.windows.bartlett(7)
        w3 = scp.signal.windows.bartlett(6, False)
        return w1, w2, w3

class TestBlackman:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-15, atol=1e-15)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.blackman(6, sym=False),
                scp.signal.windows.blackman(7, sym=False),
                scp.signal.windows.blackman(6),
                scp.signal.windows.blackman(7, True))

class TestBlackmanHarris:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-15, atol=1e-15)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.blackmanharris(6, False),
                scp.signal.windows.blackmanharris(7, sym=False),
                scp.signal.windows.blackmanharris(6),
                scp.signal.windows.blackmanharris(7, sym=True))

class TestTaylor:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-15, atol=1e-15)
    def test_normalized(self, xp, scp):
        """Tests windows of small length that are normalized to 1. See the
        documentation for the Taylor window for more information on
        normalization.
        """
        w1 = scp.signal.windows.taylor(1, 2, 15)
        w2 = scp.signal.windows.taylor(6, 2, 15)
        return w1, w2

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-15, atol=1e-15)
    def test_non_normalized(self, xp, scp):
        """Test windows of small length that are not normalized to 1. See
        the documentation for the Taylor window for more information on
        normalization.
        """
        return (scp.signal.windows.taylor(5, 2, 15, norm=False),
                scp.signal.windows.taylor(6, 2, 15, norm=False))

    @testing.numpy_cupy_allclose(scipy_name='scp')
    def test_correctness(self, xp, scp):
        """This test ensures the correctness of the implemented Taylor
        Windowing function. A Taylor Window of 1024 points is created, its FFT
        is taken, and the Peak Sidelobe Level (PSLL) and 3dB and 18dB bandwidth
        are found and checked.

        A publication from Sandia National Laboratories was used as reference
        for the correctness values [1]_.

        References
        -----
        .. [1] Armin Doerry, "Catalog of Window Taper Functions for
               Sidelobe Control", 2017.
               https://www.researchgate.net/profile/Armin_Doerry/publication/316281181_Catalog_of_Window_Taper_Functions_for_Sidelobe_Control/links/58f92cb2a6fdccb121c9d54d/Catalog-of-Window-Taper-Functions-for-Sidelobe-Control.pdf
        """
        M_win = 1024
        N_fft = 131072
        # Set norm=False for correctness as the values obtained from the
        # scientific publication do not normalize the values. Normalizing
        # changes the sidelobe level from the desired value.
        w = scp.signal.windows.taylor(
            M_win, nbar=4, sll=35, norm=False, sym=False)
        f = scp.fft.fft(w, N_fft)
        spec = 20 * xp.log10(xp.abs(f / xp.amax(f)))

        first_zero = xp.argmax(xp.diff(spec) > 0)

        PSLL = xp.amax(spec[first_zero:-first_zero])

        BW_3dB = 2 * xp.argmax(spec <= -3.0102999566398121) / N_fft * M_win
        BW_18dB = 2 * xp.argmax(spec <= -18.061799739838872) / N_fft * M_win

        return PSLL, BW_3dB, BW_18dB

class TestBohman:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.bohman(6),
                scp.signal.windows.bohman(7, sym=True),
                scp.signal.windows.bohman(6, False))

class TestBoxcar:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.boxcar(6),
                scp.signal.windows.boxcar(7),
                scp.signal.windows.boxcar(6, False))

class TestChebWin:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        with warnings.catch_warnings():
            # sup.filter(UserWarning, "This window is not suitable")
            ret = (scp.signal.windows.chebwin(6, 100),
                   scp.signal.windows.chebwin(7, 100),
                   scp.signal.windows.chebwin(6, 10),
                   scp.signal.windows.chebwin(7, 10),
                   scp.signal.windows.chebwin(6, 10, False))
        return ret

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_cheb_odd_high_attenuation(self, xp, scp):
        with warnings.catch_warnings():
            # sup.filter(UserWarning, "This window is not suitable")
            cheb_odd = scp.signal.windows.chebwin(53, at=-40)
        return cheb_odd

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_cheb_even_high_attenuation(self, xp, scp):
        with warnings.catch_warnings():
            # sup.filter(UserWarning, "This window is not suitable")
            cheb_even = scp.signal.windows.chebwin(54, at=40)
        return cheb_even

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_cheb_odd_low_attenuation(self, xp, scp):
        with warnings.catch_warnings():
            # sup.filter(UserWarning, "This window is not suitable")
            cheb_odd = scp.signal.windows.chebwin(7, at=10)
        return cheb_odd

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_cheb_even_low_attenuation(self, xp, scp):
        with warnings.catch_warnings():
            # sup.filter(UserWarning, "This window is not suitable")
            cheb_even = scp.signal.windows.chebwin(8, at=-10)
        return cheb_even

exponential_data = {
    (4, None, 0.2, False): True,
    (4, None, 0.2, True): True,
    (4, None, 1.0, False): True,
    (4, None, 1.0, True): True,
    (4, 2, 0.2, False): True,
    (4, 2, 0.2, True): False,
    (4, 2, 1.0, False): True,
    (4, 2, 1.0, True): False,
    (5, None, 0.2, True): True,
    (5, None, 1.0, True): True,
    (5, 2, 0.2, True): False,
    (5, 2, 1.0, True): False
}

@testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
def test_exponential(xp, scp):
    for args, valid in exponential_data.items():
        if not valid:
            assert_raises(ValueError, scp.signal.windows.exponential, *args)
        else:
            win = scp.signal.windows.exponential(*args)
            return win

class TestFlatTop:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.flattop(6, sym=False),
                scp.signal.windows.flattop(7, sym=False),
                scp.signal.windows.flattop(6),
                scp.signal.windows.flattop(7, True),)

class TestGaussian:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.gaussian(6, 1.0),
                scp.signal.windows.gaussian(7, 1.2),
                scp.signal.windows.gaussian(7, 3),
                scp.signal.windows.gaussian(6, 3, False),)

class TestGeneralCosine:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.general_cosine(5, [0.5, 0.3, 0.2]),
                scp.signal.windows.general_cosine(4, [0.5, 0.3, 0.2],
                                                  sym=False),)

class TestGeneralHamming:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.general_hamming(5, 0.7),
                scp.signal.windows.general_hamming(5, 0.75, sym=False),
                scp.signal.windows.general_hamming(6, 0.75, sym=True),)

class TestHamming:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.hamming(6, False),
                scp.signal.windows.hamming(7, sym=False),
                scp.signal.windows.hamming(6),
                scp.signal.windows.hamming(7, sym=True),)

class TestHann:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.hann(6, sym=False),
                scp.signal.windows.hann(7, sym=False),
                scp.signal.windows.hann(6, True),
                scp.signal.windows.hann(7),)

class TestKaiser:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.kaiser(6, 0.5),
                scp.signal.windows.kaiser(7, 0.5),
                scp.signal.windows.kaiser(6, 2.7),
                scp.signal.windows.kaiser(7, 2.7),
                scp.signal.windows.kaiser(6, 2.7, False),)

@pytest.mark.skip('This has not been implemented yet in CuPy')
class TestKaiserBesselDerived:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        M = 100
        w = scp.signal.windows.kaiser_bessel_derived(M, beta=4.0)
        w2 = scp.signal.windows.get_window(
            ('kaiser bessel derived', 4.0), M, fftbins=False)
        w3 = scp.signal.windows.kaiser_bessel_derived(2, beta=xp.pi / 2)
        w4 = scp.signal.windows.kaiser_bessel_derived(4, beta=xp.pi / 2)
        w5 = scp.signal.windows.kaiser_bessel_derived(6, beta=xp.pi / 2)
        return w, w2, w3, w4, w5

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_exceptions(self, xp, scp):
        M = 100
        # Assert ValueError for odd window length
        msg = ("Kaiser-Bessel Derived windows are only defined for even "
               "number of points")
        with assert_raises(ValueError, match=msg):
            scp.signal.windows.kaiser_bessel_derived(M + 1, beta=4.)

        # Assert ValueError for non-symmetric setting
        msg = ("Kaiser-Bessel Derived windows are only defined for "
               "symmetric shapes")
        with assert_raises(ValueError, match=msg):
            scp.signal.windows.kaiser_bessel_derived(M + 1, beta=4., sym=False)

class TestNuttall:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.nuttall(6, sym=False),
                scp.signal.windows.nuttall(7, sym=False),
                scp.signal.windows.nuttall(6),
                scp.signal.windows.nuttall(7, True),)

class TestParzen:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.parzen(6),
                scp.signal.windows.parzen(7, sym=True),
                scp.signal.windows.parzen(6, False),)

class TestTriang:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        return (scp.signal.windows.triang(6, True),
                scp.signal.windows.triang(7),
                scp.signal.windows.triang(6, sym=False),)

tukey_data = [
    (4, 0.5, True),
    (4, 0.9, True),
    (4, 1.0, True),
    (4, 0.5, False),
    (4, 0.9, False),
    (4, 1.0, False),
    (5, 0.0, True),
    (5, 0.8, True),
    (5, 1.0, True),
    (6, 0),
    (7, 0),
    (6, .25),
    (7, .25),
    (6,),
    (7,),
    (6, .75),
    (7, .75),
    (6, 1),
    (7, 1),
]

class TestTukey:
    @pytest.mark.parametrize('args', tukey_data)
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, args, xp, scp):
        # Test against hardcoded data
        win = scp.signal.windows.tukey(*args)
        return win

dpss_data = [
    (4, 0.1, 2),
    (3, 1.4, 3),
    (5, 1.5, 5),
    (100, 2, 4),
]

@pytest.mark.skip('This has not been implemented yet in CuPy')
class TestDPSS:
    @pytest.mark.parametrize('args', tukey_data)
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, args, xp, scp):
        win, ratios = scp.signal.windows.dpss(*args, return_ratios=True)
        return win, ratios

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_unity(self, xp, scp):
        # Test unity value handling (gh-2221)
        results = []
        for M in range(1, 21):
            # corrected w/approximation (default)
            win = scp.signal.windows.dpss(M, M / 2.1)
            results.append(win)
            # corrected w/subsample delay (slower)
            win_sub = scp.signal.windows.dpss(M, M / 2.1, norm='subsample')
            if M > 2:
                # @M=2 the subsample doesn't do anything
                results.append(win_sub)
            # not the same, l2-norm
            win_2 = scp.signal.windows.dpss(M, M / 2.1, norm=2)
            results.append(win_2)
        return results

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_extremes(self, xp, scp):
        # Test extremes of alpha
        lam1 = scp.signal.windows.dpss(31, 6, 4, return_ratios=True)[1]
        lam2 = scp.signal.windows.dpss(31, 7, 4, return_ratios=True)[1]
        lam3 = scp.signal.windows.dpss(31, 8, 4, return_ratios=True)[1]
        return lam1, lam2, lam3

    @pytest.mark.parametrize('windows', [cu_windows, cpu_windows])
    def test_degenerate(self, windows):
        # Test failures
        assert_raises(ValueError, windows.dpss, 4, 1.5, -1)  # Bad Kmax
        assert_raises(ValueError, windows.dpss, 4, 1.5, -5)
        assert_raises(TypeError, windows.dpss, 4, 1.5, 1.1)
        assert_raises(ValueError, windows.dpss, 3, 1.5, 3)  # NW must be < N/2.
        assert_raises(ValueError, windows.dpss, 3, -1, 3)  # NW must be pos
        assert_raises(ValueError, windows.dpss, 3, 0, 3)
        assert_raises(ValueError, windows.dpss, -1, 1, 3)  # negative M

@pytest.mark.skip('This has not been implemented yet in CuPy')
class TestLanczos:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_basic(self, xp, scp):
        # Analytical results:
        # sinc(x) = sinc(-x)
        # sinc(pi) = 0, sinc(0) = 1
        # Hand computation on WolframAlpha:
        # sinc(2 pi / 3) = 0.413496672
        # sinc(pi / 3) = 0.826993343
        # sinc(3 pi / 5) = 0.504551152
        # sinc(pi / 5) = 0.935489284
        return (scp.signal.windows.lanczos(6, sym=False),
                scp.signal.windows.lanczos(6),
                scp.signal.windows.lanczos(7, sym=True),)

    @pytest.mark.parametrize('windows', [cu_windows, cpu_windows])
    def test_array_size(self, windows):
        for n in [0, 10, 11]:
            assert len(windows.lanczos(n, sym=False)) == n
            assert len(windows.lanczos(n, sym=True)) == n

class TestGetWindow:
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_boxcar(self, xp, scp):
        w1 = scp.signal.windows.get_window('boxcar', 12)

        # window is a tuple of len 1
        w2 = scp.signal.windows.get_window(('boxcar',), 16)
        return w1, w2

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_cheb_odd(self, xp, scp):
        with warnings.catch_warnings():
            # sup.filter(UserWarning, "This window is not suitable")
            w = scp.signal.windows.get_window(
                ('chebwin', -40), 53, fftbins=False)
        return w

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_cheb_even(self, xp, scp):
        with warnings.catch_warnings():
            # sup.filter(UserWarning, "This window is not suitable")
            w = scp.signal.windows.get_window(
                ('chebwin', 40), 54, fftbins=False)
        return w

    @pytest.mark.skip('This has not been implemented yet in CuPy')
    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_dpss(self, xp, scp):
        win1 = scp.signal.windows.get_window(('dpss', 3), 64, fftbins=False)
        win2 = scp.signal.windows.dpss(64, 3)
        return win1, win2

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_kaiser_float(self, xp, scp):
        win1 = scp.signal.windows.get_window(7.2, 64)
        win2 = scp.signal.windows.kaiser(64, 7.2, False)
        return win1, win2

    @pytest.mark.parametrize('windows', [cu_windows, cpu_windows])
    def test_invalid_inputs(self, windows):
        # Window is not a float, tuple, or string
        assert_raises(ValueError, windows.get_window, set('hann'), 8)

        # Unknown window type error
        assert_raises(ValueError, windows.get_window, 'broken', 4)

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_array_as_window(self, xp, scp):
        # scipy github issue 3603
        osfactor = 128
        sig = xp.arange(128)

        win = scp.signal.windows.get_window(('kaiser', 8.0), osfactor // 2)
        if hasattr(scp.signal, 'resample'):
            with assert_raises(ValueError, match='must have the same length'):
                scp.signal.resample(sig, len(sig) * osfactor, window=win)
        return win

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_general_cosine(self, xp, scp):
        return (scp.signal.get_window(('general_cosine', [0.5, 0.3, 0.2]), 4),
                scp.signal.get_window(('general_cosine', [0.5, 0.3, 0.2]), 4,
                                      fftbins=False))

    @testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
    def test_general_hamming(self, xp, scp):
        return (
            scp.signal.get_window(('general_hamming', 0.7), 5),
            scp.signal.get_window(('general_hamming', 0.7), 5, fftbins=False),)

    @pytest.mark.skip('This has not been implemented yet in CuPy')
    def test_lanczos(self, xp, scp):
        return (scp.signal.get_window('lanczos', 6),
                scp.signal.get_window('lanczos', 6, fftbins=False),
                scp.signal.get_window('lanczos', 6),
                scp.signal.get_window('sinc', 6))

@pytest.mark.parametrize('window_info', window_funcs)
@testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
def test_windowfunc_basics(window_info, xp, scp):
    window_name, params = window_info
    if window_name in {'parzen', 'tukey'}:
        pytest.skip()

    window = getattr(scp.signal.windows, window_name)
    results = []
    with warnings.catch_warnings():
        # Check symmetry for odd and even lengths
        w1 = window(8, *params, sym=True)
        w2 = window(7, *params, sym=False)
        results += [w1, w2]

        w1 = window(9, *params, sym=True)
        w2 = window(8, *params, sym=False)
        results += [w1, w2]

        # Check that functions run and output lengths are correct
        results.append(len(window(6, *params, sym=True)))
        results.append(len(window(6, *params, sym=False)))
        results.append(len(window(7, *params, sym=True)))
        results.append(len(window(7, *params, sym=False)))

        # Check invalid lengths
        assert_raises((ValueError, TypeError), window, 5.5, *params)
        assert_raises((ValueError, TypeError), window, -7, *params)

        # Check degenerate cases
        results.append(window(0, *params, sym=True))
        results.append(window(0, *params, sym=False))
        results.append(window(1, *params, sym=True))
        results.append(window(1, *params, sym=False))

        # Check normalization
        results.append(window(10, *params, sym=True))
        results.append(window(10, *params, sym=False))
        results.append(window(9, *params, sym=True))
        results.append(window(9, *params, sym=False))

        # Check that DFT-even spectrum is purely real for odd and even
        results.append(scp.fft.fft(window(10, *params, sym=False)).imag)
        results.append(scp.fft.fft(window(11, *params, sym=False)).imag)

    return results

@pytest.mark.parametrize('windows', [cu_windows, cpu_windows])
def test_needs_params(windows):
    for winstr in ['kaiser', 'ksr', 'kaiser_bessel_derived', 'kbd',
                   'gaussian', 'gauss', 'gss',
                   'general gaussian', 'general_gaussian',
                   'general gauss', 'general_gauss', 'ggs',
                   'dss', 'dpss', 'general cosine', 'general_cosine',
                   'chebwin', 'cheb', 'general hamming', 'general_hamming',
                   ]:
        assert_raises(ValueError, windows.get_window, winstr, 7)

@testing.numpy_cupy_allclose(scipy_name='scp', rtol=1e-13, atol=1e-13)
def test_not_needs_params(xp, scp):
    for winstr in ['barthann',
                   'bartlett',
                   'blackman',
                   'blackmanharris',
                   'bohman',
                   'boxcar',
                   'cosine',
                   'flattop',
                   'hamming',
                   'nuttall',
                   'parzen',
                   'taylor',
                   'exponential',
                   'poisson',
                   'tukey',
                   'tuk',
                   'triangle',
                   ]:
        win = scp.signal.get_window(winstr, 7)
        return win


import logging

logger = logging.getLogger(__name__)

def app(environ, start_response):
    path = environ.get('PATH_INFO', '')
    if path == '/exception':
        raise Exception('My exception!')

    data = "Request on %s \n" % path
    logger.info(data, extra={'tags': ['role:web', 'env:prod']})
    start_response("200 OK", [
          ("Content-Type", "text/plain"),
          ("Content-Length", str(len(data)))
      ])
    return iter([data])


import numpy as np
import random as r

# In this module 2-point crossover and non-(uniform) mutation will be implemented

pc = r.uniform(0.4, 0.7)    #probability of crossover
pm = r.uniform(0.001, 0.3)  #Probability of mutation

def two_point_crossover(x1, x2):
    # X1: first parent chromosome
    # X2: Second parent Chromosome

    p1 = int(r.uniform(1, len(x1)-1))   # First crossover point
    p2 = int(r.uniform(1, len(x1)-1))   # Second crossover point

    # if two points are identical re-generate them
    # Hint : it will be a strange accident if p1 equals p2 after re-generation
    if (p1 == p2):
        p1 = int(r.uniform(1, len(x1)-1))
        p2 = int(r.uniform(1, len(x1)-1))

    # Crossover indicator
    rc = r.uniform(0, 1)

    print(p1, p2)
    print(rc, pc)
    if (rc <= pc):
        # Perform Crossover
        if (p1 < p2):       # Where point1 < point 2
            temp = x1[p1:p2+1]
            x1[p1:p2+1] = x2[p1:p2+1]
            x2[p1:p2+1] = temp
        else :              # Where point 1 > point 2
            temp[p2:p1+1] = x1[p2:p1+1]
            x1[p2:p1+1] = x2[p2:p1+1]
            x2[p2:p1+1] = temp
        return list([x1, x2])
    else:
        #NO Crossover
        return list([x1, x2]) # Return Parents without Change

def uniform_mutation(chrom, LU_list):
    # chrom: chromosome which it's fitness lower than the other selected

    Delta = None  # Delta var which indicates xnew

    # LU_list : lower and upper bound list passed from another function
                # to make sure the sequence is safe

    # first step : calculate delta lower and delta upper for each gene

    for i in range(0, len(chrom)):
        rm = r.uniform(0,1)
        if (rm <= pm):
            # Calculating delta lower and delta upper
            lb, ub = LU_list[i]
            delta_lo = chrom[i] - lb
            delta_hi = ub - chrom[i]
            r1 = r.uniform(0,1)
            if (r1 <= 0.5):
                Delta = delta_lo
                r2 = r.uniform(0, Delta)
                chrom[i] = chrom[i] - r2
            else :
                Delta = delta_hi
                r2 = r.uniform(0, Delta)
                chrom[i] = r2 - chrom[i]
    return chrom

def nonuniform_mutation(chrom, LU_list, t, T):
    # Like uniform mutation but value of mutation is calculated another way
    # t : Current Generation
    # T : max number of generations

    Y = None # Delta indicator
    for i in range(0, len(chrom)):
        rm = r.uniform(0,1)
        if (rm <= pm):
            # Calculating delta lower and delta upper
            lb, ub = LU_list[i]
            delta_lo = chrom[i] - lb
            delta_hi = ub - chrom[i]
            r1 = r.uniform(0,1)
            if (r1 <= 0.5):
                Y = delta_lo
                ra = r.uniform(0,1)
                b = r.uniform(0.5, 5.5)
                mut_fun = Y * (1-ra)**(1-t/T)**b
                #print(mut_fun)
                chrom[i] = chrom[i] - mut_fun
            else :
                Y = delta_hi
                ra = r.uniform(0,1)
                b = r.uniform(0.5, 5.5)
                mut_fun = Y * (1-ra)**(1-t/T)**b
                #print(mut_fun)
                chrom[i] = mut_fun - chrom[i]
    return chrom

#print(uniform_mutation([0.08, 0.12, 0.07, 0.11], [(2.7,58),(20.5,38),(5,18),(10,30)]))
#print(two_point_crossover([0.1, 0.5, 0.6, 0.3, 0.2, 0.56, 0.11]
#                         ,[1, 5, 6, 3, 2, 56, 11]))
#print(nonuniform_mutation([0.08, 0.12, 0.07, 0.11], [(2.7,58),(20.5,38),(5,18),(10,30)], 2, 7))

                ### Debugged AND TESTED ###


from spa.clientside.asyncdbhandler import CAsyncDBHandler
from spa import BaseServiceID, tagBaseRequestID

class CPostgres(CAsyncDBHandler):
    # Asynchronous and SQL streaming postgreSQL service id
    sidPostgres = BaseServiceID.sidReserved + 0x6FFFFFF4

    """
    An Open flag option, which is specific to PostgreSQL plugin.
    It is noted that this flag option is not implemented within SocketPro plugin yet.
    """
    ROWSET_META_FLAGS_REQUIRED = 0x40000000

    """
    An Open flag option, which is specific to PostgreSQL plugin.
    When the flag option is used with the method Open or open,
    it forces fetching data from remote PostgreSQL server to SocketPro plugin row-by-row instead of all.
    The flag option should be used if there is a large number of data within a rowset.
    """
    USE_SINGLE_ROW_MODE = 0x20000000

    # error codes for unexpected programming errors
    ER_NO_DB_OPENED_YET = -1981
    ER_BAD_END_TRANSTACTION_PLAN = -1982
    ER_NO_PARAMETER_SPECIFIED = -1983
    ER_BAD_PARAMETER_COLUMN_SIZE = -1984
    ER_BAD_PARAMETER_DATA_ARRAY_SIZE = -1985
    ER_DATA_TYPE_NOT_SUPPORTED = -1986
    ER_BAD_TRANSTACTION_STAGE = -1987

    def __init__(self, sid=sidPostgres):
        super(CPostgres, self).__init__(sid)


import os
import cv2 as cv
import numpy as np

people = []

for i in os.listdir(r'C:\Users\Atul\Downloads\OpenCV_course\opencv-course-master\Resources\Faces\train'):
    people.append(i)  #each folder in the faces folder corresponds to one person ben affleck,mindy,etc and name of folder is person's name so we store target variables

DIR = r'C:\Users\Atul\Downloads\OpenCV_course\opencv-course-master\Resources\Faces\train'

haar_cascade = cv.CascadeClassifier('haar_face.xml')  #calling haarcascade detector

# Creating the training set
features = []
labels = []

def create_train():  #loop over all folders in the training folder and then loop over all images within and store in training set. Within each image detect only the face and crop it out using haarcascade face detector
    for person in people:
        path = os.path.join(DIR, person)   #to get path for folder of each person
        label = people.index(person)  #text classes need to be converted to numerical categories

        for img in os.listdir(path):
            img_path = os.path.join(path, img)  #create path for each image in each person's folder

            img_array = cv.imread(img_path)
            gray = cv.cvtColor(img_array, cv.COLOR_BGR2GRAY)

            faces_rect = haar_cascade.detectMultiScale(gray, scaleFactor = 1.1, minNeighbors=4)

            for (x,y,w,h) in faces_rect:
                faces_roi = gray[y:y+h ,x:x+w]   #cropping out just the face from the image

                features.append(faces_roi)
                labels.append(label)

create_train()
print('Training data created -------------')

features = np.array(features, dtype='object')  #all pixels of each image are flattened out to a single row of all pixel values for an image
labels = np.array(labels)

face_recognizer = cv.face.LBPHFaceRecognizer_create()  #instantiating out in-built face recognizer model

# Train recognizer on features list and labels list
face_recognizer.train(features,labels)

face_recognizer.save('face_trained.yml')  # OpenCv allows us to save our trained model as a yaml which can be reused in other files instead of going through the entire training process again
np.save('features.npy', features)
np.save('labels.npy', labels)


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

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('user_profile', '0003_remove_userprofile_title'),
    ]

    operations = [
        migrations.CreateModel(
            name='RegistrationPath',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('title', models.CharField(max_length=100)),
            ],
        ),
        migrations.AlterField(
            model_name='userprofile',
            name='mobile_number',
            field=models.CharField(max_length=11, null=True, blank=True),
        ),
        migrations.AddField(
            model_name='userprofile',
            name='registration_path',
            field=models.ForeignKey(blank=True, to='user_profile.RegistrationPath', null=True),
        ),
    ]


from django.test import TestCase
from django.urls import resolve
from django.http import HttpRequest
from django.template.loader import render_to_string
from django.utils.html import escape

from lists.views import home_page, view_list
from lists.models import Item, List
from lists.forms import STR_EMPYT_LIST_ERROR, ItemForm, ExistingListItemForm

# Create your tests here.

class SmokeTest(TestCase):
    def test_bad_maths(self):
        self.assertEqual(1 + 1, 2)

class HomePageTest(TestCase):
    def test_root_url_resolves_to_home_page_view(self):
        found = resolve("/")
        self.assertEqual(found.func, home_page)

    def test_0001_home_page_returns_correct_html(self):
        request = HttpRequest()
        response = home_page(request)
        content = response.content.decode("utf-8-sig").encode('utf-8')
        # print(f'{type(content) =}, {content}')

        self.assertTrue(content.startswith(b"<html>"))
        self.assertIn(b'<title>To-Do Lists</title>', content)
        self.assertTrue(content.endswith(b"</html>"))
        # failed for csrf
        # self.assertEqual(response.content.decode(), render_to_string('home.html'))

    '''
    def test_0004_home_page_displays_all_list_item(self):
        list_ = List.objects.create()
        Item.objects.create(text='itemey 1', list=list_)
        Item.objects.create(text='itemey 2', list=list_)
        request = HttpRequest()
        response = view_list(request)
        self.assertIn('itemey 1', response.content.decode())
        self.assertIn('itemey 2', response.content.decode())
    '''

class ListViewTest(TestCase):
    '''
    def test_users_list_template(self):
        response = self.client.get('/lists/all/')

        self.assertTemplateUsed(response, 'list.html')
    '''

    def test_0002_users_list_template(self):
        list_ = List.objects.create()
        response = self.client.get(f'/lists/{list_.id}/')

        self.assertTemplateUsed(response, 'list.html')

    def test_0002a_users_list_template(self):
        list_ = List.objects.create()
        response = self.client.get(f'/lists/{list_.id}/')
        self.assertIsInstance(response.context['form'], ExistingListItemForm)
        self.assertContains(response, 'name="text"')

    def test_0003_display_only_items_for_that_list(self):
        list1 = List.objects.create()
        Item.objects.create(text='itemey 1.1', list=list1)
        Item.objects.create(text='itemey 1.2', list=list1)
        list2 = List.objects.create()
        Item.objects.create(text='itemey 2.1', list=list2)
        Item.objects.create(text='itemey 2.2', list=list2)
        response = self.client.get(f"/lists/{list1.id}/")
        content = response.content.decode("utf-8-sig").encode('utf-8')
        # print(f'{type(content) =}, {content}')

        self.assertContains(response, 'itemey 1.1')
        self.assertContains(response, 'itemey 1.2')
        self.assertNotContains(response, 'itemey 2.1')
        self.assertNotContains(response, 'itemey 2.2')

    """
    def test_display_all_items(self):
        list_ = List.objects.create()
        Item.objects.create(text='itemey 1', list=list_)
        Item.objects.create(text='itemey 2', list=list_)
        response = self.client.get("/lists/all/")

        self.assertContains(response, 'itemey 1')
        self.assertContains(response, 'itemey 2')
    """

    def test_0005_passes_correst_list_to_templeate(self):
        list2 = List.objects.create()
        list1 = List.objects.create()
        response = self.client.get(f'/lists/{list1.id}/')
        self.assertEqual(response.context['list'], list1)

    def test_0006_validation_error_end_up_on_list_page(self):
        list_ = List.objects.create()
        response = self.client.post(f'/lists/{list_.id}/', data={"text": ''})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'list.html')

        content = response.content.decode("utf-8-sig").encode('utf-8')
        # print(f'test_0006_validation_error_end_up_on_list_page {type(content) =}, {content}')

        self.assertContains(response, escape("You can't have an empty list item"))

    def post_invalid_input(self):
        list_ = List.objects.create()
        response = self.client.post(f'/lists/{list_.id}/', data={"text": ''})
        return response

    def test_0007_invalid_input_nothing_saved_to(self):
        self.post_invalid_input()
        self.assertEqual(Item.objects.count(), 0)

    def test_0008_invalid_input_renders_list_template(self):
        response = self.post_invalid_input()
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'list.html')

    def test_0009_invalid_input_passes_form_to_template(self):
        response = self.post_invalid_input()
        self.assertIsInstance(response.context['form'], ExistingListItemForm)

    def test_0010_invalid_input_shows_error_on_page(self):
        response = self.post_invalid_input()
        self.assertContains(response, escape(STR_EMPYT_LIST_ERROR))

class NewListTest(TestCase):
    def test_0001_saving_a_POST_request(self):
        # print(f'Before post')
        self.client.post('/lists/new', data={'text': 'A new list item'})

        # print(f'{Item.objects.count()}, {Item.objects =}')
        self.assertEqual(Item.objects.count(), 1)
        new_item = Item.objects.first()
        self.assertEqual(new_item.text, 'A new list item')

    def test_0003_home_page_redirect_after_post(self):
        response = self.client.post('/lists/new', data={'text': 'A new list item'})
        list_ = List.objects.first()
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response['location'], f'/lists/{list_.id}/')

    def test_0004a_validation_errors_are_sent_back_to_home_page_template(self):
        response = self.client.post('/lists/new', data={'text': ''})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'home.html')

    def test_0004b_validation_errors_are_sent_back_to_home_page_template(self):
        response = self.client.post('/lists/new', data={'text': ''})
        self.assertContains(response, escape(STR_EMPYT_LIST_ERROR))

    def test_0004c_validation_errors_are_sent_back_to_home_page_template(self):
        response = self.client.post('/lists/new', data={'text': ''})
        self.assertIsInstance(response.context['form'], ItemForm)

    def test_0005_invalid_list_items_arent_saved(self):
        response = self.client.post('/lists/new', data={'text': ''})
        self.assertEqual(List.objects.count(), 0)
        self.assertEqual(Item.objects.count(), 0)

class NewItemTest(TestCase):
    def test_0001_can_save_a_POST_request_to_an_existing_list(self):
        list2 = List.objects.create()
        list1 = List.objects.create()
        response = self.client.post(f'/lists/{list1.id}/',
                                    data={'text': 'A new list item for existing list'})
        # print(f'test_0001_can_save_a_POST_request_to_an_existing_list: {response.status_code}, {response = }')
        # print(f'{list(Item.objects.all()) = }')
        self.assertEqual(Item.objects.count(), 1)
        new_item = Item.objects.first()
        self.assertEqual(new_item.text, 'A new list item for existing list')
        self.assertEqual(new_item.list, list1)

    def test_0002_redirect_to_list_view(self):
        list2 = List.objects.create()
        list1 = List.objects.create()
        response = self.client.post(f'/lists/{list1.id}/',
                                    data={'text': 'A new list item for existing list'})
        self.assertRedirects(response, f'/lists/{list1.id}/')


# -*- coding: utf-8 -*-

from __future__ import division, print_function, unicode_literals

__all__ = ["IterativeTwoDSearch"]

import os
import h5py
import numpy as np

from .two_d_search import TwoDSearch
from ._grid_search import grid_search

class IterativeTwoDSearch(TwoDSearch):

    cache_ext = ".h5"
    query_parameters = dict(
        min_period=(None, True),
        max_period=(None, True),
        delta_log_period=(None, False),
        dt=(None, False),
        alpha=(None, False),
        npeaks=(3, False),
        mask_frac=(2.0, False),
        min_points=(500, False),
        min_transits=(3, False),
    )

    def get_alpha(self, query, parent_response):
        a = query.get("alpha", None)
        if a is not None:
            return float(a)
        lcs = parent_response.model_light_curves
        n = sum(len(lc.time) for lc in lcs)
        k = parent_response.nbasis
        return k * np.log(n)

    def get_result(self, query, parent_response):
        periods = self.get_period_grid(query, parent_response)
        dt = self.get_offset_spacing(query, parent_response)
        alpha = self.get_alpha(query, parent_response)

        # Get the parameters of the time grid from the 1-d search.
        time_spacing = parent_response.time_spacing
        mean_time = parent_response.mean_time_1d
        tmin = parent_response.min_time_1d - mean_time
        tmax = parent_response.max_time_1d - mean_time
        time_grid = np.arange(0, tmax-tmin, time_spacing)

        # Get the results of the 1-d search.
        depth_1d = np.array(parent_response.depth_1d)
        depth_ivar_1d = np.array(parent_response.depth_ivar_1d)
        dll_1d = np.array(parent_response.dll_1d)

        # Find the peaks.
        peaks = []
        for _ in range(query["npeaks"]):
            # Run a 2D search.
            results = grid_search(query["min_transits"], alpha,
                                  tmin, tmax, time_spacing, depth_1d,
                                  depth_ivar_1d, dll_1d, periods, dt)
            (t0_2d, phic_same, phic_same_2, phic_variable, depth_2d,
             depth_ivar_2d) = results

            # Profile over duration.
            inds = np.arange(len(phic_same)), np.argmax(phic_same, axis=1)
            t0_2d = t0_2d[inds]
            depth_2d = depth_2d[inds]
            depth_ivar_2d = depth_ivar_2d[inds]
            phic_same = phic_same[inds]
            phic_variable = phic_variable[inds]
            phic_same_2 = phic_same_2[inds]

            # Find the top peak.
            s2n = depth_2d * np.sqrt(depth_ivar_2d)
            top_peak = np.argmax(s2n)
            p, t0 = periods[top_peak], t0_2d[top_peak]
            duration = query["durations"][inds[1][top_peak]]

            # Save the peak.
            peaks.append(dict(
                period=p, t0=(t0 + tmin + mean_time) % p,
                duration=duration,
                depth=depth_2d[top_peak],
                depth_ivar=depth_ivar_2d[top_peak],
                s2n=s2n[top_peak],
                phic_same=phic_same[top_peak],
                phic_same_second=phic_same_2[top_peak],
                phic_variable=phic_variable[top_peak],
                duty_cycle=np.sum(depth_ivar_1d > 0.0) / len(depth_ivar_1d),
                data_span=tmax - tmin,
            ))

            # Mask out these transits.
            m = (np.abs((time_grid-t0+0.5*p) % p-0.5*p)
                 < query["mask_frac"]*duration)
            depth_1d[m] = 0.0
            depth_ivar_1d[m] = 0.0
            dll_1d[m] = 0.0
            if (np.sum(np.any(depth_ivar_1d > 0.0, axis=1))
                    < query["min_points"]):
                break

        return dict(
            peaks=peaks,
        )

    def save_to_cache(self, fn, response):
        try:
            os.makedirs(os.path.dirname(fn))
        except os.error:
            pass

        # Parse the peaks into a structured array.
        peaks = response["peaks"]
        if len(peaks):
            dtype = [(k, np.float64) for k in sorted(peaks[0].keys())]
            peaks = [tuple(peak[k] for k, _ in dtype) for peak in peaks]
            peaks = np.array(peaks, dtype=dtype)

        with h5py.File(fn, "w") as f:
            f.create_dataset("peaks", data=peaks, compression="gzip")

    def load_from_cache(self, fn):
        if os.path.exists(fn):
            with h5py.File(fn, "r") as f:
                try:
                    peaks = [dict((k, peak[k]) for k in peak.dtype.names)
                             for peak in f["peaks"]]
                    return dict(
                        peaks=peaks,
                    )
                except KeyError:
                    pass
        return None


from django.urls import path
from . import views

# register app namespace which is going to be used in URL names
app_name = "my_app"

urlpatterns = [
    path("", views.example_view, name="example"),
    path("variable/", views.variable_view, name="variable")
]


__author__ = 'Ong See Hai'
__date__ = 'Nov 2020'
__copyright__ = '(C) 2020, Ong See Hai'

from qgis.core import (QgsProcessing,
                    QgsProcessingAlgorithm,
                    QgsProcessingParameterVectorLayer,
                    QgsProcessingParameterMapLayer,
                    QgsProcessingParameterVectorDestination,
                    QgsProcessingParameterRasterLayer,
                    QgsProcessingException,
                    QgsProcessingUtils,
                    QgsExpressionContextUtils,
                    QgsCoordinateReferenceSystem,
                    QgsProject, QgsProperty)
import processing

class Platformx (QgsProcessingAlgorithm):

    INPUT = 'INPUT'
    INPUT2 = 'INPUT2'
    INPUT3 = 'INPUT3'
    INPUT4 = 'INPUT4'
    OUTPUT = 'OUTPUT'

    def name(self):
        return 'platformx'

    def displayName(self):
        return 'Platform extended to road center line'

    def group(self):
        return 'IMP Tools'

    def groupId(self):
        return 'imp'

    def createInstance(self):
        return Platformx()

    def shortHelpString(self):
        return ('Create platform polygons extended to road center lines (platformx)  '
               ' and calculate platform elevation '
               ' based on a slightly lower value than the mean z value of the Digital elevation model cells'
               '\n'
               'The Platform line input map layer can be an AutoCAD DXF file.'
               '\n'
               'The meanz field in the output map layer is the mean z value of DEM cells covered by the polygon. '
               )

    def initAlgorithm(self, config=None):

        self.addParameter(QgsProcessingParameterVectorLayer(
            self.INPUT, 'INPUT: Road node',
            defaultValue='Node',types=[QgsProcessing.TypeVectorPoint]) )

        self.addParameter(QgsProcessingParameterVectorLayer(
            self.INPUT2, 'INPUT2: Road segment',
            defaultValue='Segment',types=[QgsProcessing.TypeVectorLine]) )

        self.addParameter(QgsProcessingParameterVectorLayer(
            self.INPUT3, 'INPUT3: Platform line',
            defaultValue='Platform_line',types=[QgsProcessing.TypeVectorLine]) )

        self.addParameter(QgsProcessingParameterRasterLayer(
            self.INPUT4, 'INPUT4: Digital elevation model',
            defaultValue='DEM_SRTM') )

        self.addParameter(QgsProcessingParameterVectorDestination(
            self.OUTPUT, 'Platformx') )

    def processAlgorithm(self, parameters, context, feedback):

        # Project variables
        project = QgsProject.instance()
        scope = QgsExpressionContextUtils.projectScope(project)
        projfold = scope.variable('project_folder')
        try:
            projcrs = QgsCoordinateReferenceSystem( scope.variable('project_crs') )
        except:
            raise QgsProcessingException ('Project coordinate reference system not set')

        # Buffer and boundary nodes to connect to segment lines
        layer = processing.run('native:buffer',
                {'DISSOLVE': False,
                'DISTANCE': 6,
                'END_CAP_STYLE': 0,
                'INPUT': parameters[self.INPUT],
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 2,
                'SEGMENTS': 5,
                'OUTPUT': 'TEMPORARY_OUTPUT' },
				context=context, feedback=feedback, is_child_algorithm=True
				) ['OUTPUT']

        # Boundary
        layer = processing.run('native:boundary',
                {'INPUT': layer,
                'OUTPUT': 'TEMPORARY_OUTPUT' },
				context=context, feedback=feedback, is_child_algorithm=True
				) ['OUTPUT']

        # Merge vector layers
        layer = processing.run('native:mergevectorlayers',
                {'CRS': projcrs,
                'LAYERS': [ layer, parameters[self.INPUT3], parameters[self.INPUT2] ],
                'OUTPUT': 'TEMPORARY_OUTPUT' },
				context=context, feedback=feedback, is_child_algorithm=True
				) ['OUTPUT']

        # Polygonize
        layer = processing.run('native:polygonize',
                {'INPUT': layer,
                'KEEP_FIELDS': False,
                'OUTPUT': 'TEMPORARY_OUTPUT' },
				context=context, feedback=feedback, is_child_algorithm=True
				) ['OUTPUT']

        # Remove small areas with Extract by expression
        layer = processing.run('native:extractbyexpression',
                {'EXPRESSION': '$area>200',
                'INPUT': layer,
                'OUTPUT': 'TEMPORARY_OUTPUT' },
				context=context, feedback=feedback, is_child_algorithm=True
				) ['OUTPUT']

        # Mean elevation with Zonal statistics
        processing.run('native:zonalstatistics',
                {'INPUT_RASTER': parameters[self.INPUT4],
                'INPUT_VECTOR': layer,
                'COLUMN_PREFIX': '_',
                'RASTER_BAND': 1,
                'STATISTICS': [2] },
				context=context, feedback=feedback, is_child_algorithm=True
				)

        # Refactor fields
        layer = processing.run('native:refactorfields',
                {'FIELDS_MAPPING': [
                    {'expression': '$id','length': 0,'name': 'platid','precision': 0,'type': 2},
                    {'expression': 'round( (\"_mean\" * .996 ) ,1)','length': 0,'name': 'platz','precision': 0,'type': 6},
                    {'expression': 'round(\"_mean\",1)','length': 0,'name': 'meanz','precision': 0,'type': 6} ],
                'INPUT': layer,
                'OUTPUT': 'TEMPORARY_OUTPUT' },
				context=context, feedback=feedback, is_child_algorithm=True
				) ['OUTPUT']

        # Set Z value
        algout = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

        algoutlay = processing.run('native:setzvalue',
                {'INPUT': layer,
                'Z_VALUE': QgsProperty.fromExpression('"platz"'),
                'OUTPUT': algout },
				context=context, feedback=feedback, is_child_algorithm=True
				) ['OUTPUT']

        # necc to overcome bug in runAndLoadResults in QPy console
        context.addLayerToLoadOnCompletion(algoutlay,context.LayerDetails(
                name='Platformx',project=context.project() ))

        layer = QgsProcessingUtils.mapLayerFromString(algoutlay, context)
        platqml = projfold + '\\qsettings\\Platform_rdm_z_downcen.qml'
        layer.loadNamedStyle(platqml)

        feedback.pushInfo( '\n\n ##################################\n')
        feedback.pushInfo( '\n\n{} PLATFORMX CREATED'.format(layer.featureCount() ) )
        feedback.pushInfo( '\n\nOshPlatformx.py v2.1\n'
                           '##################################\n\n')

        return {self.OUTPUT: algoutlay}


import numpy as np
import json
import timeit
import os
import argparse
from pathlib import Path
import sys
from shapely.geometry import Polygon

import numpy as np
import numba
from inspect import getmembers

sys.path.append(os.path.realpath('hausdorff'))
from hausdorff_dist import hausdorff_distance

sys.path.append(os.path.realpath('yolov4'))
from tool.utils import *

from config import config
from utils import *

def parse_args():
	argparser = argparse.ArgumentParser(
		description='Data preparation for vehicle counting')
	argparser.add_argument('-j', '--json_dir', type=str,
						   default='../data/json/', help='Json directory')
	argparser.add_argument('-v', '--video_dir', type=str,
						   default='../data/video/', help='Video directory')
	argparser.add_argument('-t', '--track_dir', type=str,
						   default='data/track', help='Detection result directory')
	argparser.add_argument('-s', '--save_dir', type=str,
						   default='data/count', help='Save result')
	args = vars(argparser.parse_args())
	return args

def load_zone_anno(json_filename):
	with open(json_filename) as jsonfile:
		dd = json.load(jsonfile)
		polygon = [(int(x), int(y)) for x, y in dd['shapes'][0]['points']]
		paths = {}
		for it in dd['shapes'][1:]:
			kk = str(int(it['label'][-2:]))
			paths[kk] = [(int(x), int(y)) for x, y in it['points']]
	return polygon, paths

def check_bbox_overlap_with_roi(box, roi):
	roi_poly =  Polygon(roi)
	x1, y1 = box[0], box[1]
	x2, y2 = box[2], box[3]
	box_poly = Polygon([(x1,y1), (x2, y1), (x2, y2), (x1, y2)])
	return box_poly.intersects(roi_poly)

def is_same_direction(traj1, traj2, angle_thr):
	vec1 = np.array([traj1[-1][0] - traj1[0][0], traj1[-1][1] - traj1[0][1]])
	vec2 = np.array([traj2[-1][0] - traj2[0][0], traj2[-1][1] - traj2[0][1]])
	L1 = np.sqrt(vec1.dot(vec1))
	L2 = np.sqrt(vec2.dot(vec2))
	if L1 == 0 or L2 == 0:
		return False
	cos = vec1.dot(vec2)/(L1*L2)
	angle = np.arccos(cos) * 360/(2*np.pi)

	return angle < angle_thr

def count(json_dir, video_dir, track_dir, save_dir):
	starttime = timeit.default_timer()

	remove_wrong_classes = config['remove_wrong_classes']
	min_track_len = config['tracker']['min_len']

	Path(save_dir).mkdir(parents=True, exist_ok=True)
	cam_datas = get_list_data(json_dir)

	results = []

	for cam_data in cam_datas:
		cam_name = cam_data['camName']
		width = int(cam_data['imageWidth'])
		height = int(cam_data['imageHeight'])
		track_res_path = os.path.join(track_dir, cam_name + '.npy')
		tracks = np.load(track_res_path, allow_pickle=True)

		mm_track = {}
		tipical_trajs = {}
		for mm_id, mm in enumerate(cam_data['shapes'][1:]):
			if 'tracklets' in mm.keys():
				tipical_trajs[mm_id] = [mm['tracklets']]
			else:
				tipical_trajs[mm_id] = [mm['points']]

		track_dict = []
		for class_id, class_tracks in enumerate(tracks):
			track_dict.append({})
			for frame_id, vehicle_tracks in enumerate(class_tracks):
				for track in vehicle_tracks:
					x1 = track[0]
					y1 = track[1]
					x2 = track[2]
					y2 = track[3]
					cx = int((x1 + x2) / 2)
					cy = int((y1 + y2) / 2)
					track_id = int(track[5])
					if track_id in track_dict[class_id]:
						track_dict[class_id][track_id]['endframe'] = frame_id
						track_dict[class_id][track_id]['bbox'].append([frame_id, x1, y1, x2, y2, class_id])
						track_dict[class_id][track_id]['tracklet'].append([cx, cy])
					else:
						track_dict[class_id][track_id] = {'startframe' : frame_id,
										'endframe' : frame_id,
										'bbox' : [[frame_id, x1, y1, x2, y2, class_id]],
										'tracklet' : [[cx, cy]]}

		for class_id, _ in enumerate(track_dict):
			mm_track[class_id] = {}
			track_ids = sorted([k for k in track_dict[class_id].keys()])
			for track_id in track_ids:
				if len(track_dict[class_id][track_id]['tracklet']) < config['tracker']['min_len']:
					continue
				track_traj = track_dict[class_id][track_id]['tracklet']

				# calc hausdorff dist with tipical trajs, assign the movement with the min dist
				all_dists_dict = {k: float('inf') for k in tipical_trajs}
				for m_id, m_t in tipical_trajs.items():
					for t in m_t:
						tmp_dist = hausdorff_distance(np.array(track_traj), np.array(t), distance='euclidean')
						if tmp_dist < all_dists_dict[m_id]:
							all_dists_dict[m_id] = tmp_dist

				# check direction
				all_dists = sorted(all_dists_dict.items(), key=lambda k: k[1])
				min_idx, min_dist = None, config['counter']['dist_thr']
				for i in range(0, len(all_dists)):
					m_id = all_dists[i][0]
					m_dist = all_dists[i][1]
					if m_dist >= config['counter']['dist_thr']: #if min dist > dist_thr, will not assign to any movement
						break
					else:
						if is_same_direction(track_traj, tipical_trajs[m_id][0], config['counter']['angle_thr']): #check direction
							min_idx = m_id
							min_dist = m_dist
							break # if match, end
						else:
							continue # direction not matched, find next m_id

				if min_idx == None and min_dist >= config['counter']['dist_thr']:
					continue
				#save counting results
				mv_idx = min_idx
				#get last frameid in roi
				bboxes = track_dict[class_id][track_id]['bbox']
				bboxes.sort(key=lambda x: x[0])

				dst_frame = bboxes[0][0]
				last_bbox = bboxes[-1]
				roi = cam_data['shapes'][0]['points']
				if check_bbox_overlap_with_roi(last_bbox, roi) == True:
					dst_frame = last_bbox[0]
				else:
					for i in range(len(bboxes) - 2, 0, -1):
						bbox = bboxes[i]
						if check_bbox_overlap_with_roi(bbox, roi) == True:
							dst_frame = bbox[0]
							break
						else:
							continue

				track_types = [k[5] for k in bboxes]
				track_type = max(track_types, key=track_types.count)

				mm_track[class_id][track_id] = mv_idx
				results.append([cam_name, dst_frame, mv_idx, class_id])

		filepath = os.path.join(save_dir, cam_name + '.json')
		with open(filepath, 'w') as f:
			json.dump(mm_track, f)

	results.sort(key=lambda x: ([x[0], x[1], x[2], x[3]]))

	result_filename = os.path.join(save_dir, 'result.txt')
	with open(result_filename, 'w') as result_file:
		for result in results:
			result_file.write('{} {} {} {}\n'.format(result[0], result[1] + 1, result[2] + 1, result[3] + 1))

	endtime = timeit.default_timer()
	print('Count time: {} seconds'.format(endtime - starttime))

if __name__=='__main__':
	args = parse_args()

	json_dir = args['json_dir']
	video_dir = args['video_dir']
	track_dir = args['track_dir']
	save_dir = args['save_dir']

	count(json_dir, video_dir, track_dir, save_dir)