from collections import OrderedDict
import hwtypes
import pyverilog.dataflow.visit
import pyverilog.vparser.parser
from ..array import Array
from ..bit import Bit
from ..bits import Bits
from ..circuit import Circuit
from ..interface import IO
from ..passes.tsort import tsort
from ..t import In, Out, InOut
from .verilog_importer import (ImportMode, MultipleModuleDeclarationError,
                               MultiplePortDeclarationError, VerilogImporter,
                               VerilogImportError)
from .verilog_utils import int_const_str_to_int
from magma.bitutils import clog2

class PyverilogImportError(VerilogImportError):
    pass

def _evaluate_node(node, params):
    """Evaluates the pyverilog node @node"""
    if isinstance(node, pyverilog.vparser.ast.IntConst):
        return int_const_str_to_int(node.value)
    if isinstance(node, pyverilog.vparser.ast.Rvalue):
        return _evaluate_node(node.var, params)
    if isinstance(node,
                  (pyverilog.vparser.ast.Minus, pyverilog.vparser.ast.Uminus)):
        l = _evaluate_node(node.left, params)
        r = _evaluate_node(node.right, params)
        return l - r
    if isinstance(node, pyverilog.vparser.ast.Plus):
        l = _evaluate_node(node.left, params)
        r = _evaluate_node(node.right, params)
        return l + r
    if isinstance(node, pyverilog.vparser.ast.Divide):
        l = _evaluate_node(node.left, params)
        r = _evaluate_node(node.right, params)
        return l // r  # floor division
    if isinstance(node, pyverilog.vparser.ast.Times):
        l = _evaluate_node(node.left, params)
        r = _evaluate_node(node.right, params)
        return l * r  # floor division
    if isinstance(node, pyverilog.vparser.ast.Identifier):
        return params[node.name]
    if isinstance(node, pyverilog.vparser.ast.SystemCall):
        syscall = node.syscall
        if syscall == "clog2":
            operand = _evaluate_node(node.children()[0], params)
            return clog2(operand)
        raise PyverilogImportError(
            f"Unsupported verilog system call: {syscall}")
    raise PyverilogImportError(f"Unsupported expression: {type(node)}")

def _get_width(width, param_map):
    """Evaluates width.msb, width.lsb and returns their difference"""
    msb = _evaluate_node(width.msb, param_map)
    lsb = _evaluate_node(width.lsb, param_map)
    return msb - lsb + 1

def _parse_port(port):
    """
    Returns the pair (name: str, io: Union[(Input|Output|Inout), None]), where
    the second element is the pyverilog encoded type of the input, or None (if
    the port list name-only.
    """
    if isinstance(port, pyverilog.vparser.parser.Ioport):
        io = port.first
        return (io.name, io)
    if isinstance(port, pyverilog.vparser.parser.Port):
        return (port.name, None)
    # Not expected to reach here.
    raise PyverilogImportError(f"Unsupported port type: {type(port)}")

def _magma_type(io, params):
    """
    Returns the magma type corresponding to @io, which is a pyverilog Input,
    Output, or Inout.
    """
    direction = InOut
    if isinstance(io, pyverilog.vparser.parser.Input):
        direction = In
    elif isinstance(io, pyverilog.vparser.parser.Output):
        direction = Out

    typ = Bit
    if io.width is not None:
        width = _get_width(io.width, params)
        typ = Bits[width]

    # Generate multidimensional arrays if necessary. Note that we guard with
    # hasattr to make this backwards compatible.
    if hasattr(io, "dimensions") and io.dimensions is not None:
        for length in reversed(io.dimensions.lengths):
            width = _get_width(length, params)
            typ = Array[width, typ]

    return direction(typ)

def _get_lines(src, start, end):
    return "\n".join(src.split("\n")[start - 1:end])

class _ModuleGraphVisitor(pyverilog.dataflow.visit.NodeVisitor):
    """
    This implementation of pyverilog's NodeVisitor collects all module
    definitions in the root node.
    """
    def __init__(self):
        self.defns = OrderedDict()

    def visit_ModuleDef(self, defn):
        if defn.name in self.defns:
            raise MultipleModuleDeclarationError(defn.name)
        self.defns[defn.name] = defn

class PyverilogImporter(VerilogImporter):
    """Implementation of VerilogImporter using pyverilog"""
    def _import_defn(self, defn, mode):
        ports = {}
        default_params = {}
        # Parse module declaration for parameters (and default values) and port
        # declarations.
        for param_list in defn.paramlist.params:
            for param in param_list.list:
                default_params[param.name] = _evaluate_node(
                    param.value, default_params)
        for port in defn.portlist.ports:
            name, io = _parse_port(port)
            if name in ports:
                raise MultiplePortDeclarationError(name)
            ports[name] = io
        # Check that the port declaration is not mixed-style, i.e. either all
        # declared in the module declaration, or all declared in the body.
        is_io = (p is not None for p in ports.values())
        if not all(is_io) and any(is_io):
            raise MixedPortDeclarationsError()
        # Iterate on the body of the moudle definition for paramters (and
        # default values) and port declarations.
        for child in defn.children():
            if not isinstance(child, pyverilog.vparser.parser.Decl):
                continue
            for subchild in child.children():
                if isinstance(subchild, pyverilog.vparser.parser.Parameter):
                    default_params[subchild.name] = _evaluate_node(
                        subchild.value, default_params)
                elif isinstance(subchild, (pyverilog.vparser.parser.Input,
                                           pyverilog.vparser.parser.Output,
                                           pyverilog.vparser.parser.Inout)):
                    ports[subchild.name] = subchild
        # Convert pyverilog ports to magma types and define a magma circuit.
        decl = {n: self.map_type(n, _magma_type(port, default_params))
                for n, port in ports.items()}

        class _FromVerilog(Circuit):
            name = defn.name
            io = IO(**decl)

        return _FromVerilog, default_params

    def import_(self, src, mode):
        parser = pyverilog.vparser.parser.VerilogParser()
        ast = parser.parse(src)
        visitor = _ModuleGraphVisitor()
        visitor.visit(ast)
        for name, defn in visitor.defns.items():
            circ, default_params = self._import_defn(defn, mode)
            if mode is ImportMode.DEFINE:
                circ.verilogFile = _get_lines(src, defn.lineno, defn.end_lineno)
                circ.verilog_source = src
            circ.coreir_config_param_types = {
                k: type(v)
                for k, v in default_params.items()
            }
            circ.default_kwargs = default_params
            self.add_module(circ)


def breakingRecords(scores):
    highScore = scores[0]
    lowScore = scores[0]
    countHighBreak = 0
    countLowBreak = 0

    for i in range(len(scores)):
        currentScore = scores[i]
        if currentScore > highScore:
            countHighBreak +=1
            highScore = currentScore
        if currentScore < lowScore:
            countLowBreak +=1
            lowScore = currentScore


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

"""Object models and methods for space missions.
"""

import json
import isodate
import datetime
from numbers import Number
import itertools

from .util import Entity, EnumEntity
from .agency import Agency
from .space import Satellite, Constellation
from .ground import GroundStation, GroundNetwork, Region, GLOBAL_REGION
from .launch import LaunchVehicle
from .instrument import Instrument

class MissionConcept(Entity):
    """Top-level functional description of an Earth-observing mission.

    Attributes:
        name        Full name of this entity.
        acronym     Acronym, initialism, or abbreviation.
        agency      Designer, provider, or operator of this entity.
        start       Mission start in ISO-8601 datetime format.
                    (default: today)
        duration    Mission duration in ISO-8601 duration format.
                    (default: P90D, 90 days)
        target      Target region of interest for mission objectives.
                    (default: GLOBAL_REGION)
        objectives  List of mission objectives.
    """

    def __init__(self, name=None, acronym=None, agency=None,
                start=datetime.date.today().isoformat(), duration="P90D",
                target=GLOBAL_REGION, objectives=None, _id=None):
        """Initialize a mission concept object.
        """
        self.name = name
        self.acronym = acronym if acronym else name
        self.agency = agency
        self.start = start
        if isinstance(duration, Number):
            self.duration = isodate.duration_isoformat(datetime.timedelta(days=duration))
        else: self.duration = duration
        self.target = target
        # convert objectives to list, if necessary
        if isinstance(objectives, str): self.objectives = [objectives]
        else: self.objectives = objectives
        super(MissionConcept, self).__init__(_id, "MissionConcept")

    @staticmethod
    def from_dict(d):
        """Parses a mission concept from a normalized JSON dictionary."""
        return MissionConcept(
                name = d.get("name", None),
                acronym = d.get("acronym", None),
                agency = Agency.from_json(d.get("agency", None)),
                start = d.get("start", datetime.date.today().isoformat()),
                duration = d.get("duration", "P90D"),
                target = Region.from_json(d.get("target", GLOBAL_REGION)),
                objectives = MissionObjective.from_json(d.get("objectives", None)),
                _id = d.get("@id", None)
            )

class MissionObjective(Entity):
    """A variable to be maximized or minimized to acheive mission objectives.

    Attributes:
        name        The full name of this objective.
        parent      The full name of the parent objective.
        weight      Weight or importance of this metric, ranging between 0 to inf
        type        Type of metric. Recognized case-insensitive values include:
                        MAX (maximize)
                        MIN (minimize)
                        TAR (target)
        target      Target value for the objective. Required for TAR type only.
    """

    def __init__(self, name=None, parent=None, weight=None, type=None,
            target=None, _id=None):
        """Initialize a mission objective.
        """
        self.name = name
        self.parent = parent
        self.weight = weight
        self.type = ObjectiveType.get(type)
        self.target = target
        super(MissionObjective,self).__init__(_id, "MissionObjective")

    @staticmethod
    def from_dict(d):
        """Parses a mission objective from a normalized JSON dictionary."""
        return MissionObjective(
                name = d.get("name", None),
                parent = d.get("parent", None),
                weight = d.get("weight", None),
                type = d.get("type", None),
                target = d.get("target", None),
                _id = d.get("@id", None)
        )

class ObjectiveType(EnumEntity):
    """Enumeration of recognized objective types."""
    MAX = "MAX"
    MIN = "MIN"
    TAR = "TAR"

class DesignSpace(Entity):
    """Specification of fixed and variable quantities for a space mission.

    Attributes:
        constellations  List of potential constellations to consider.
        launchers       List of available launch vehicles to consider
                        (overrides default database).
        satellites      List of available satellites.
        groundNetworks  List of potential ground networks to consider.
        groundStations  List of available ground stations.
    """

    def __init__(self, constellations=None, launchers=None, satellites=None,
                 groundNetworks=None, groundStations=None, _id=None):
        """Initialize a design space object.
        """
        # convert constellations to list, if necessary
        if isinstance(constellations, Constellation): self.constellations = [constellations]
        else: self.constellations = constellations
        # convert launchers to list, if necessary
        if isinstance(launchers, LaunchVehicle): self.launchers = [launchers]
        else: self.launchers = launchers
        # convert satellites to list, if necessary
        if isinstance(satellites, Satellite): self.satellites  = [satellites]
        else: self.satellites = satellites
        # convert ground networks to list, if necessary
        if isinstance(groundNetworks, GroundNetwork): self.groundNetworks = [groundNetworks]
        else: self.groundNetworks = groundNetworks
        # convert ground stations to list, if necessary
        if isinstance(groundStations, GroundStation): self.groundStations = [groundStations]
        else: self.groundStations = groundStations
        super(DesignSpace,self).__init__(_id, "DesignSpace")

    def generate_architectures(self):
        """Generates architectures in this design space."""
        # merge lists of iterated constellations
        constellationsList = iter(iter(i) for i in self.constellations)
        constellationsIter = iter(set().union(*constellationsList))
        # merge lists of iterated ground networks
        groundNetworksList = iter(iter(i) for i in self.groundNetworks)
        groundNetworksIter = iter(set().union(*groundNetworksList))

        return iter([
                Architecture(
                    constellation=constellation,
                    groundNetwork=groundNetwork
                )
                for constellation, groundNetwork
                in itertools.product(
                    [i.generate_constellations(self.satellites) for i in constellationsIter],
                    [i.generate_networks(self.groundStations) for i in groundNetworksIter]
                )
            ])

    @staticmethod
    def from_dict(d):
        """Parses a design space from a normalized JSON dictionary."""
        return DesignSpace(
                constellations = Constellation.from_json(d.get("constellations", None)),
                launchers = LaunchVehicle.from_json(d.get("launchers", None)),
                satellites = Satellite.from_json(d.get("satellites", None)),
                groundNetworks = GroundNetwork.from_json(d.get("groundNetworks", None)),
                groundStations = GroundStation.from_json(d.get("groundStations", None)),
                _id = d.get("@id", None)
            )

class Architecture(Entity):
    """Instantiation of a space mission including satellites and ground stations.

    Attributes:
        constellation   Constellation of member satellites.
        groundNetwork   Network of member ground stations.
    """

    def __init__(self, constellation=None, groundNetwork=None, _id=None):
        """Initialize an architecture object.
        """
        self.constellation = constellation
        self.groundNetwork = groundNetwork
        super(Architecture, self).__init__(_id, "Architecture")

    @staticmethod
    def from_dict(d):
        """Parses an architecture from a normalized JSON dictionary."""
        return Architecture(
                constellation = Constellation.from_json(d.get("constellation", None)),
                groundNetwork = GroundNetwork.from_json(d.get("groundNetwork", None)),
                _id = d.get("@id", None)
            )


from __future__ import annotations

from typing import Iterable, TYPE_CHECKING

import numpy
from tcod.console import Console

import tile_types

if TYPE_CHECKING:
    from entity import Entity

class GameMap:

    def __init__(self,
                 width: int,
                 height: int,
                 entities: Iterable[Entity] = ()):
        self.width, self.height = width, height
        self.entities = set(entities)
        self.tiles = numpy.full((width, height), fill_value=tile_types.wall, order="F")

        self.visible = numpy.full((width, height), fill_value=False, order='F')
        self.explored = numpy.full((width, height), fill_value=False, order='F')

        self.tiles[30:33, 22] = tile_types.wall

    def in_bounds(self, x: int, y: int) -> bool:
        return 0 <= x < self.width and 0 <= y < self.height

    def render(self, console: Console) -> None:
        console.tiles_rgb[0:self.width, 0:self.height] = numpy.select(
            condlist=[self.visible, self.explored],
            choicelist=[self.tiles["light"], self.tiles["dark"]],
            default=tile_types.SHROUD
        )

        for entity in self.entities:
            if self.visible[entity.x, entity.y]:
                console.print(x=entity.x, y=entity.y, string=entity.char, fg=entity.color)


#1.2 Write a program that determines whether a year entered by the user is a leap year or not using ifelif-else statements

def is_leap_year(year):
  if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
    return True
  else:
    return False

# Input from the user
year = int(input("Enter a year: "))

if is_leap_year(year):
  print(f"{year} is a leap year.")
else:
  print(f"{year} is not a leap year.")


""" Self written binary tree. """

def ancestor(tree, a, b):
    """ Find the value of the lowest common ancestor of `a` and `b`. """
    a, b = sorted((a, b))
    return tree.ancestor(a, b).value

class Node(object):
    """
    A node of a binary tree.
    """

    def __init__(self, value):
        """ Create a node with a value. """
        self.left = None
        self.right = None
        self.value = value

    def insert(self, value):
        """ Insert a value into the tree, search for where to put the node. """
        if value > self.value:
            if self.right is None:
                self.right = Node(value)
            else:
                self.right.insert(value)
        elif value < self.value:
            if self.left is None:
                self.left = Node(value)
            else:
                self.left.insert(value)
        return self

    def find(self, value):
        """ Return the value if it exists in the tree, else None. """
        if value > self.value:
            return None if self.right is None else self.right.find(value)
        elif value < self.value:
            return None if self.left is None else self.left.find(value)
        else:
            return self

    def ancestor(self, a, b):
        """ Return the lowest common ancestor of nodes with values a, b. """
        if self.value > a and self.value > b:
            return self.left.ancestor(a, b)
        elif self.value >= a and self.value <= b:
            return self
        else:
            return self.right.ancestor(a, b)

    def __repr__(self):
        """ String representation of the tree. """
        string = []
        if self.left:
            string += [repr(self.left)]
        string += [str(self.value)]
        if self.right:
            string += [repr(self.right)]
        return ','.join(string)


#!/usr/bin/env python3
#mydir = {}
#mylist = [mydir]
mylist =[]
username = input("Name :")
userage = input("age :")
userheight = input("height :")

#mydir.update(username.split("Name : ", username))
#mydir.update(userage.split("Age : ", userage))
#mydir.update(userheight.split("Height : ", userheight))

mylist.append(username)
mylist.append(userage)
mylist.append(userheight)
print(mylist)


#!/usr/bin/env python
# encoding: utf-8
u"""
@version: ??
@author: shaofeng.yang
@contact: marvin_yang@novowater.com.cn
@software: PyCharm Community Edition
@file: test4.py
@time: 2017/9/21 9:58
"""

import pymysql
import traceback

# 打开数据库连接
db = pymysql.connect("58.250.17.19", "root", "yqjp123456", "yqjp_db", 13306, use_unicode=True, charset="utf8")
# db = pymysql.connect("58.250.17.19", "root", "yqjp123456", "yqjp_db", 13306, use_unicode=True)

# 使用cursor()方法获取操作游标
cursor = db.cursor()

# SQL 插入语句
sql = """UPDATE `t_customer` SET nickname= '<<<EOT"  \ud83d\udca5  "EOT' WHERE customer_no = '15989453055''"""
cursor.execute('SET NAMES utf8mb4;')
# cursor.execute('SET CHARACTER SET utf8mb4;')
# cursor.execute('SET character_set_connection=utf8mb4;')
try:
    # 执行sql语句
    cursor.execute(sql)
    # 提交到数据库执行
    db.commit()
except Exception as ex:
    # 如果发生错误则回滚
    # print(ex)
    print(traceback.print_exc())
    db.rollback()

# 关闭数据库连接
db.close()


# coding=utf-8
import os
import time
basedir = '../../Lemon/src'
filelists = []
# 指定想要统计的文件类型
whitelist = ['php', 'py', 'java', 'js', 'vue']
#遍历文件, 递归遍历文件夹中的所有

def getFile(basedir):
    global filelists
    for parent, dirnames, filenames in os.walk(basedir):
        for filename in filenames:
            ext = filename.split('.')[-1]
            # 只统计指定的文件类型，略过一些log和cache文件
            if ext in whitelist:
                filelists.append(os.path.join(parent, filename))
# 统计一个文件的行数

def countLine(fname):
    count = 0
    for file_line in open(fname).readlines():
        count += 1
    print(fname + '----', count)
    return count

if __name__ == '__main__':
    startTime = time.clock()
    getFile(basedir)
    totalline = 0
    for filelist in filelists:
        totalline = totalline + countLine(filelist)
    print('total lines:', totalline)
    print('Done! Cost Time: %0.2f second' % (time.clock() - startTime))


from collections import deque
class LCA:
    def __init__(self, n, edges):
        # Assuming Tree is rooted at 1
        q = deque()
        q.append(1)
        self.parents = [ [1]*18 for _ in range(n+1)]

        self.depth = [-1] * (n + 1)
        self.depth[1] = 0

        while q:
            u = q.popleft()
            for v in edges[u]:
                if self.depth[v] == -1:
                    q.append(v)
                    self.depth[v] = self.depth[u] + 1
                    self.parents[v][0] = u

                    for i in range(1,18):
                        self.parents[v][i] = self.parents[self.parents[v][i-1]][i-1]

    def get_parent(self, node, dist):
        while dist:
            i = dist.bit_length() - 1
            node = self.parents[node][i]
            dist ^= 1 << i
        return node

    def get_lca(self, u, v):
        if self.depth[u] > self.depth[v]:
            u, v = v, u
        v = self.get_parent(v, self.depth[v] - self.depth[u])

        for i in reversed(range(18)):
            pu = self.parents[u][i]
            pv = self.parents[v][i]

            if pu!=pv:
                u = pu
                v = pv
        return u if u == v else self.parents[u][0]


import numpy as np

class EM:
    def __init__(self,r0=0., sigr=1., z0=0., sigz=1):
        # offset gauss in R,z
        self.r0 = r0
        self.sigr = sigr
        self.z0 = z0
        self.sigz = sigz

    def set_par(self, r0=0., sigr=1., z0=0., sigz=1):
        # offset gauss in R,z
        self.r0 = r0
        self.sigr = sigr
        self.z0 = z0
        self.sigz = sigz

    def __call__(self,r,z):
        gr = np.exp( -0.5*((r-self.r0)/self.sigr)**2)
        gz = np.exp( -0.5*((z-self.z0)/self.sigz)**2)
        return gr*gz


#!/usr/bin/env python
###########################################################################
#
# PROGRAMMER:   Drew Stefanik and Greg Gorajski - Group 2
# PROGRAM:      Assignment 4 - Port Scan and RC4 Decryption Program
# DATE DUE:     7/27/2016
# PURPOSE:      Scans a server for an open UDP port, and receives a secret
#					key from the open port.  Then scans the server for an
#					open TCP port and receives an encrypted message from
#					from the open port.  The encrypted message is
#					decrypted using RC4 with the secret key obtained from
#					UDP.  Prints out the message, which ports where open,
#					and the time of each connection.
#
###########################################################################

import socket, sys, datetime
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

print("Starting UDP Port Scan: ")

#create UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#for each port in the given range
for port in range(9000,9100):
	#attempt to connect to the port
	#if the port is open, create a timestamp, receive the secret key,
	#save the number of the open port, and break the loop
	try:
		sock.settimeout(0.05)
		sock.sendto(b"group 2", (("10.158.56.43", port)))
		time_UDP = datetime.datetime.now()
		key, addr = sock.recvfrom(1024)
		print("Port %s Open" % port)
		port_UDP = port
		break
	#if the port is closed, print message and continue the loop
	except socket.error:
		print ("Port %s Closed" % port)

sock.close()

print("Starting TCP Port Scan: ")

#create TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

#for each port in the given range
for port in range(9000,9100):
	#attempt to connect to the port
	#if the port is open, create a timestamp, receive the encrypted message,
	#save the number of the open port, and break the loop
	try:
		sock.connect(("10.158.56.43", port))
		time_TCP = datetime.datetime.now()
		sock.send("group 2", )
		ciphertext = sock.recv(1024)
		print("Port %s Open" % port)
		port_TCP = port
		break
	#if the port is closed, print message and continue the loop
	except socket.error:
		print ("Port %s Closed" % port)

sock.close()

#prepare the RC4 cipher with the UDP secret key, and derypt the TCP message

#print the ports, timestamps, and plaintext message
print ("Open UDP Port: %s" % port_UDP)
print ("Open UDP Timestamp: %s" % time_UDP)
print ("Open TCP Port: %s" % port_TCP)
print ("Open TCP Timestamp: %s" % time_TCP)
print ("Message:")

print("***Program Execution Complete***")


from __future__ import annotations

import json
import sys
from asyncio import run
from collections.abc import Callable, Coroutine
from logging import Logger, StreamHandler
from pathlib import Path
from plistlib import load as plist_load
from shutil import copy2, move
from tempfile import TemporaryDirectory
from traceback import format_exc
from typing import NoReturn
from zipfile import ZIP_DEFLATED, ZipFile

import pkg_resources
from yaml import safe_dump, safe_load

from .errors import WorkflowError
from .models import SNIPPET_INFO_TEMPLATE, Result, Snippet

class SnippetClient:
    snippets: list[Snippet]

    def __init__(self) -> None:
        self.snippets: list[Snippet] = []

    def insert_snippet(self, snippet: str, name: str, keyword: str):
        self.snippets.append(Snippet(snippet, name, keyword))

    def package(
        self,
        name: str,
        dst: str = "",
        prefix: str = "",
        suffix: str = "",
        iconpath: str = "",
    ):
        """Package snippets into a .alfredsnippets file"""
        with TemporaryDirectory() as tempdir:
            workdir = Path(tempdir)
            infopath = workdir / "info.plist"
            infopath.write_text(SNIPPET_INFO_TEMPLATE.format(prefix, suffix))

            snippet_path = workdir / f"{name}.alfredsnippets"
            with ZipFile(snippet_path, "w", ZIP_DEFLATED) as zipfile:
                for snippet in self.snippets:
                    path = snippet.save(workdir)
                    zipfile.write(path, path.name)
                zipfile.write(infopath, infopath.name)
                if iconpath:
                    snippet_iconpath = workdir / "icon.png"
                    copy2(iconpath, snippet_iconpath)
                    zipfile.write(snippet_iconpath, snippet_iconpath.name)

            destination = (Path(dst) if dst else Path.cwd()) / f"{name}.alfredsnippets"
            move(snippet_path, destination)

class WorkflowClient:
    bare_query: str | None
    query: str | None
    page_count: int

    bundleid: str
    package_dir: Path
    icondir: Path
    datadir: Path
    db_results: Path
    results: list[Result]

    logger: Logger

    def __init__(self, package_dir: str = "src/libs") -> None:
        self.logger = Logger("alfred5")
        self.logger.addHandler(StreamHandler(sys.stderr))
        self.log(f"logger initted")

        if len(sys.argv) > 1:
            self.bare_query = sys.argv[1]
            self.page_count = self.bare_query.count("+") + 1
            self.query = self.bare_query.replace("+", "")
        else:
            self.bare_query = None
            self.page_count = 0
            self.query = None

        self.log(
            f"sys.argv: {sys.argv} page_count: {self.page_count} query: {self.query}"
        )

        self.package_dir = Path(package_dir)
        self.icondir = Path(__file__).parent / "icons"

        self.log(f"bundleid reading from info.plist...")
        with Path("info.plist").open("rb") as f:
            self.bundleid = plist_load(f)["bundleid"]
            self.log(f"bundleid: {self.bundleid}")
        self.datadir = Path("db")
        self.datadir.mkdir(parents=True, exist_ok=True)

        self.log(f"datadir: {self.datadir.absolute()}")
        self.db_results = self.datadir / "results.yml"
        self.log(f"db_results: {self.db_results}")

        self.results = []

    def log(self, msg: str):
        self.logger.debug(msg)

    def install_requirements(self) -> None:
        """Check if requirements are met"""
        self.log(f"checking requirements...")
        req_file = self.package_dir / ".." / "requirements.txt"
        if req_file.exists():
            packages = req_file.read_text().splitlines()
            self.log(f"found requirements.txt: {packages}")

            try:
                pkg_resources.require(packages)
            except pkg_resources.DistributionNotFound:
                import subprocess

                command = [
                    "python3",
                    "-m",
                    "pip",
                    "install",
                    f"--target={self.package_dir}",
                    *packages,
                ]
                subprocess.Popen(
                    command,
                    start_new_session=True,
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                )
                self.add_result(
                    title="Requirements are installing (you can close alfred)",
                    subtitle=f"Executed command: {' '.join(command)}",
                    icon_path=self.icondir / "download.png",
                    arg=" ".join(command),
                )
                self.response_with_results()
        else:
            self.log(f"no requirements.txt found")

    def cache_response(self) -> None:
        """Cache response to workflow db_results"""
        if not self.db_results.exists():
            self.db_results.parent.mkdir(parents=True, exist_ok=True)
            self.db_results.touch()
        with self.db_results.open("r") as f:
            data = safe_load(f) or {}
        data[self.bare_query] = [
            {
                "title": result.title,
                "subtitle": result.subtitle,
                "icon_path": result.icon.path if result.icon else None,
                "arg": result.arg,
            }
            for result in self.results
        ]
        with self.db_results.open("w") as f:
            safe_dump(data, f)
            self.log(f"cached response to {self.db_results}")

    def load_cached_response(self) -> bool:
        """Load cached result from alfred"""
        if self.bare_query:
            self.log("skipped, bare_query is None")
            return False

        self.log(f"checking if `{self.bare_query}` exists in `{self.db_results}`")
        if self.db_results.exists():
            with self.db_results.open("r") as f:
                data: dict[str, list[dict[str, str]]] = safe_load(f)
                self.log(f"loaded data from {self.db_results} {len(data.keys())}")
                if self.bare_query and self.bare_query in data:
                    self.results = [
                        Result(
                            title=result["title"],
                            subtitle=result["subtitle"],
                            icon=Result.Icon(result["icon_path"])
                            if result["icon_path"]
                            else None,
                            arg=result["arg"],
                        )
                        for result in data[self.bare_query]
                    ]
                    self.log(f"found: {self.bare_query} in {self.db_results}")
                    return True
        self.log(f"not found `{self.bare_query}` in `{self.db_results}`")
        return False

    @classmethod
    def run(
        cls,
        func: Callable[[WorkflowClient], Coroutine[None, None, None]],
        cache: bool = False,
        package_dir: str = "src/libs",
    ) -> NoReturn:
        """Give async main function, no need to call `client.response` method

        Args:
            `func`: async main function that takes `client` as argument
            `cache`: cache response to workflow db_results, if cache exists, it will be loaded instead of executing `func`
            `package_dir`: directory to install `requirements.txt` packages

        - To install `from requirements.txt` do all import packages inside it
            - Use `global` keyword to access imported packages globally
        - `client.bare_query` is the bare query string
        - `client.query` is the query string without `+` (page count)
        - `client.page_count` is the page count for pagination results

        Example:
            ```
            from alfred import WorkflowClient

            async def main(client: WorkflowClient, cache=True):
                global get
                from requests import get
                pass

            if __name__ == "__main__":
                WorkflowClient.run(main)
            ```
        """
        client = cls(package_dir=package_dir)
        sys.path.insert(0, package_dir)
        if cache and client.load_cached_response():
            client.response_with_results()
        try:
            client.install_requirements()
            run(func(client))
            if cache:
                client.cache_response()
            client.response_with_results()
        except Exception as e:
            if isinstance(e, WorkflowError):
                client.error_response(
                    title=e.title,
                    subtitle=e.subtitle,
                    arg=e.arg,
                )
            else:
                client.error_response(
                    title=str(e),
                    subtitle=format_exc().strip().split("\n")[-1],
                    arg=format_exc().strip(),
                )

    def add_result(
        self,
        title: str,
        subtitle: str = "",
        icon_path: str | Path | None = None,
        arg: str = "",
        http_downloader: Callable[[str], str] | None = None,
        index: int | None = None,
    ) -> None:
        """Create and add alfred result

        - title: result title
        - subtitle: result subtitle
        - icon_path: result icon path
        - arg: argument to pass to alfred
        - http_downloader: function to download http icon
        """
        icon = None
        if icon_path:
            if http_downloader and "http" in str(icon_path):
                self.log(f"downloading icon from {icon_path}")
                icon_path = http_downloader(str(icon_path))
            icon = Result.Icon(str(icon_path))
        if index is not None:
            self.results.insert(
                index, Result(title=title, subtitle=subtitle, icon=icon, arg=arg)
            )
        else:
            self.results.append(
                Result(title=title, subtitle=subtitle, icon=icon, arg=arg)
            )

    def error_response(
        self,
        title: str,
        subtitle: str,
        icon_path: str | Path | None = None,
        arg: str = "",
    ) -> NoReturn:
        """Create and add alfred error result

        - title: error title
        - subtitle: error subtitle
        - icon_path: error icon path
        - arg: argument to pass to alfred
        - terminate: terminate workflow
        """
        self.add_result(
            title=title,
            subtitle=subtitle,
            icon_path=icon_path or self.icondir / "error.png",
            arg=arg,
        )
        self.response_with_results()

    def response_with_results(self) -> NoReturn:
        """Print saved alfred results and exit

        - terminate: terminate workflow
        """
        print(json.dumps({"items": [result.to_dict() for result in self.results]}))
        exit(0)

    def response(
        self,
        title: str,
        subtitle: str = "",
        icon_path: str | Path | None = None,
        arg: str = "",
    ) -> NoReturn:
        """Print alfred result and exit

        - title: result title
        - subtitle: result subtitle
        - icon_path: result icon path
        - arg: argument to pass to alfred
        """
        print(
            json.dumps(
                {
                    "items": [
                        Result(
                            title=title,
                            subtitle=subtitle,
                            icon=Result.Icon(str(icon_path)) if icon_path else None,
                            arg=arg,
                        ).to_dict()
                    ]
                }
            )
        )
        exit(0)


from flask import (
    Blueprint, flash, g, redirect, render_template, request, url_for, session
)

from .auth import login_required
from .db import get_db

from flask_pymongo import pymongo
import json

bp = Blueprint('groups', __name__)

@bp.route("/groups")
@login_required
def all_groups():
    current_user_id = session.get('user_id')
    db_instance = get_db()

    myclient = pymongo.MongoClient("mongodb://localhost:27017/")
    mydb = myclient["mydatabase"]
    mycol = mydb["groups"]

    my_groups = list(mycol.find({ "members": current_user_id }))
    group_owners = []
    for group in my_groups:
        group_owner_row = db_instance.execute("SELECT * FROM User WHERE id = ?", (group['admin_id'],)).fetchone()
        group_owners.append(group_owner_row[1] + " " + group_owner_row[2])

    group_name_to_owner = [(my_groups[i]['id'], my_groups[i]['name'], group_owners[i]) for i in range(len(my_groups))]

    return render_template("groups/my_groups.html", data =group_name_to_owner )

@bp.route('/new_group', methods=('GET', 'POST'))
@login_required
def new_group():
    current_user_id = session.get('user_id')

    myclient = pymongo.MongoClient("mongodb://localhost:27017/")
    mydb = myclient["mydatabase"]
    mycol = mydb["groups"]
    error = None

    new_group = {}
    if request.method == 'POST':
        db = get_db()

        group_name = request.form['groupName']

        my_groups = list(mycol.find({ "admin_id": current_user_id }, {"name": 1, "_id": 0}))
        for group in my_groups:
            if group['name'] == group_name:
                error = "Group Name exists"
                break

        if error:
            flash(error, 'danger')
            return render_template('groups/add_group.html')

        new_group = {"id": mycol.count() + 1, "name": group_name, "admin_id": current_user_id, "members": [current_user_id]}
        mycol.insert_one(new_group)

        return redirect(url_for('groups.all_groups'))

    return render_template('groups/add_group.html')

@bp.route("/groups/id/<int:group_id>", methods=['GET', 'POST'])
@login_required
def group_page(group_id):
    current_user_id = session.get('user_id')
    db_instance = get_db()
    myclient = pymongo.MongoClient("mongodb://localhost:27017/")
    mydb = myclient["mydatabase"]
    mycol = mydb["groups"]
    error = None

    group = list(mycol.find({ "id": group_id }))[0]

    if request.method == 'POST':
        user_id_to_add = int(request.form['id'])
        mycol.update({"id": group['id']}, { '$push' : { 'members': user_id_to_add }})

    group = list(mycol.find({ "id": group_id }))[0]

    group_member_ids = group['members']

    if current_user_id not in group_member_ids:
        flash(error, 'danger')
        return redirect(url_for('home.index'))

    group_members_table = db_instance.execute("SELECT * FROM User WHERE id IN (%s)" % ','.join('?'*len(group_member_ids)), group_member_ids).fetchall()

    group_members = []

    for member in group_members_table:
        member_dict = {}
        member_dict["id"] = member[0]
        member_dict["name"] = member[1] + " " + member[2]
        member_dict["sotw"] = member[5]
        group_members.append(member_dict)

    return render_template("groups/group_page.html", data=(group, group_members)  )

@bp.route("/groups/id/<int:group_id>/add_member", methods=['GET', 'POST'])
@login_required
def add_member(group_id):
    db_instance = get_db()
    myclient = pymongo.MongoClient("mongodb://localhost:27017/")
    mydb = myclient["mydatabase"]
    mycol = mydb["groups"]
    error = None

    group = list(mycol.find({ "id": group_id }))[0]

    all_results = {}

    if request.method == 'POST':

        query = request.form['searchName']
        formatted_query = "\"%" + query + "%\""
        sql_query = "SELECT * FROM User WHERE FirstName || ' ' || LastName LIKE " + formatted_query
        query_results = db_instance.execute(sql_query)
        all_results = []
        for item in query_results.fetchall():
            user_dict = {}
            user_dict["id"] = item[0]
            user_dict["name"] = item[1] + ' ' + item[2]
            all_results.append(user_dict)
        return render_template("groups/add_member.html", data=(group, all_results)  )

    return render_template("groups/add_member.html", data=(group, [])  )


# 백준 6497번 문제: 전력난
import sys
input = sys.stdin.readline

# 해당 노드의 부모 노드를 반환해주는 함수
def find_parent(parent, x):
  if parent[x] != x:
    parent[x] = find_parent(parent, parent[x])
  return parent[x]

# 두 노드의 부모 노드를 같게해주는 함수(같은 집합으로 만듬)
def union(parent, a, b):
  a = find_parent(parent, a)
  b = find_parent(parent, b)

  if a < b:
    parent[b] = a
  else:
    parent[a] = b

while True:
  n, m = map(int, input().split())

  # 테스트 케이스 종료 조건
  if n == 0 and m == 0:
    break

  edges = []
  max_result = 0
  result = 0
  parent = [0] * (n)

  for i in range(0, n):
    parent[i] = i

  for _ in range(m):
    x, y, z = map(int, input().split())
    edges.append((z, x, y))

  edges.sort() # 간선을 기준으로 정렬함

  for edge in edges:
    cost, x, y = edge

    max_result += cost # 모든 간선의 합

    # 두 노드의 부모노드가 같지 않으면(같은 집합이 아니면) 두 노드의 부모 노드를 같게 해줌(두 노드를 같은 집합으로 만듬)
    if find_parent(parent, x) != find_parent(parent, y):
      union(parent, x, y)
      result += cost

  # 모든 간선의 합에서 최소 경로를 빼주고 출력
  print(max_result - result)


# commands
from user import User
from stock import StockListCommand
from strategy import BuyStrategy
from transaction import TransactionEvent, TransactionManager, TransactionObserver, TransactionHistory
from datetime import datetime

class SearchCommand:
    def execute(self, transaction_manager):
        while True:
            print("Search by")
            print("1. Name")
            print("2. Symbol Ticker")
            print("3. Back")

            search_choice = input("Your choice: ")

            if search_choice == "1":
                search_by_name(transaction_manager)
            elif search_choice == "2":
                search_by_ticker(transaction_manager)
            elif search_choice == "3":
                break
            else:
                print("Invalid choice. Please enter a valid option.")

search_command = SearchCommand()

# Această funcție gestioneaza căutarea
def search_by_name(transaction_manager):
    stock_names = ["Microsoft Corporation", "Apple Inc.", "Amazon.com Inc.", "Tesla Inc."]
    stock_tickers = ["MSFT", "AAPL", "AMZN", "TSLA"]

    while True:
        print("Enter the name of the stock:")
        for index, name in enumerate(stock_names, start=1):
            print(f"{index}. {name}")

        print(f"{len(stock_names) + 1}. Back")

        choice = input("Your choice: ")

        if choice.isdigit():
            choice = int(choice)
            if 1 <= choice <= len(stock_names):
                stock_name = stock_names[choice - 1]
                display_stock_info(stock_name)
            elif choice == len(stock_names) + 1:
                break
            else:
                print("Invalid choice. Please enter a valid option.")
        else:
            print("Invalid choice. Please enter a valid option.")

def search_by_ticker(transaction_manager):
    stock_tickers = ["MSFT", "AAPL", "AMZN", "TSLA"]

    while True:
        print("Enter the symbol ticker of the stock:")
        for index, ticker in enumerate(stock_tickers, start=1):
            print(f"{index}. {ticker}")

        print(f"{len(stock_tickers) + 1}. Back")

        choice = input("Your choice: ")

        if choice.isdigit():
            choice = int(choice)
            if 1 <= choice <= len(stock_tickers):
                stock_ticker = stock_tickers[choice - 1]
                display_stock_info(stock_ticker)
            elif choice == len(stock_tickers) + 1:
                break
            else:
                print("Invalid choice. Please enter a valid option.")
        else:
            print("Invalid choice. Please enter a valid option.")

def display_stock_info(stock_key):
    stock_data = {
        "MSFT": {"name": "Microsoft Corporation", "quantity": 20, "price": 300},
        "AAPL": {"name": "Apple Inc.", "quantity": 15, "price": 175},
        "AMZN": {"name": "Amazon.com Inc.", "quantity": 10, "price": 3200},
        "TSLA": {"name": "Tesla Inc.", "quantity": 5, "price": 800}
    }

    stock_info = stock_data.get(stock_key)
    if stock_info:
        print(f"**{stock_info['name']} ({stock_key})**")
        print(f"   - Number of Shares: {stock_info['quantity']}")
        print(f"   - Price: ${stock_info['price']}")
        print("B. Back\n")

class TradingCommand:
    def __init__(self):
        self.buy_strategy = BuyStrategy()

    def execute(self, transaction_manager):
        while True:
            print("1. Search")
            print("2. Buy")
            print("3. Sell")
            print("4. Back")

            trading_choice = input("Your choice: ")

            if trading_choice == "1":
                search_choice = input("Search by\n1. Name\n2. Symbol Ticker\n3. Back\nYour choice: ")
                if search_choice == "1":
                    search_by_name(transaction_manager)
                elif search_choice == "2":
                    search_by_ticker(transaction_manager)
                elif search_choice == "3":
                    break
                else:
                    print("Invalid choice. Please enter a valid option.")
            elif trading_choice == "2":
                self.buy_transaction()
            elif trading_choice == "3":
                self.sell_transaction(transaction_manager)
            elif trading_choice == "4":
                break
            else:
                print("Invalid choice. Please enter a valid option.")

    def sell_transaction(self, transaction_manager):
        user = User.get_instance()
        user.display_portfolio()

        sell_choice = input("Sell: 1. Yes 2. No\nYour choice: ")

        if sell_choice == "1":
            symbol = input("Symbol: (e.g., MSFT, AAPL, AMZN, TSLA)\nYour choice: ")
            quantity = int(input("Number of Shares: (e.g., 1, 2, 3, ...)\nYour choice: "))

            for transaction in user.portfolio:
                if transaction['symbol'] == symbol and transaction['quantity'] >= quantity:
                    # Actualizăm portofoliul
                    transaction['quantity'] -= quantity

                    # Găsim acțiunea în Stock List
                    stock = StockListCommand._stocks.get(symbol)

                    if stock:
                        # Actualizăm Stock List cu acțiunile vândute
                        stock['quantity'] += quantity

                        # Notificăm observatorii despre acțiunea de vânzare
                        event = TransactionEvent("Sell", transaction['name'], symbol, quantity, stock['price'], datetime.now())
                        user.transaction_history.add_transaction(event)

                        # Afiseaza portofoliul actualizat
                        user.display_portfolio()

                        print(f"You have successfully sold {quantity} shares of {symbol}.")
                        print(f"Remaining {symbol} shares: {stock['quantity']}")
                        print(f"Sell {quantity} shares of {symbol} at ${stock['price']} each...")

                        break
            else:
                print("Insufficient quantity or invalid symbol. Please check your input.")
        elif sell_choice == "2":
            print("Sell canceled.")
        else:
            print("Invalid choice. Please enter a valid option.")

    def buy_transaction(self):
        while True:
            print("Symbol: (e.g., MSFT, AAPL, AMZN, TSLA)")
            symbol = input("Your choice: ")
            quantity = int(input("Number of Shares: (e.g., 1, 2, 3, ...)\nYour choice: "))
            strategy_sl = input("Strategy S/L (e.g., S for short, L for long):\nYour choice: ")

            # Verifică valoarea introdusă în strategy_sl
            if strategy_sl.upper() == 'S':
                print("Executing short-term buy transaction...")
            elif strategy_sl.upper() == 'L':
                print("Executing long-term buy transaction...")
            else:
                print("Invalid choice. Please enter S or L.")
                continue

            # Update Stock List
            stock = StockListCommand._stocks.get(symbol)
            if stock and stock['quantity'] >= quantity:
                stock['quantity'] -= quantity
                print(f"You have successfully bought {quantity} shares of {symbol}.")
                print(f"Remaining {symbol} shares: {stock['quantity']}")

                # Adaugăm tranzacția în portofoliu
                user = User.get_instance()
                user.add_to_portfolio(stock['name'], symbol, quantity, stock['price'])

                # Notificăm observatorii despre acțiunea de cumpărare
                event = TransactionEvent("Buy", stock['name'], symbol, quantity, stock['price'], datetime.now())
                TransactionManager.notify_observers(event)

                # Adăugăm tranzacția în istoric
                user.transaction_history.add_transaction(event)

                # Afiseaza portofoliul actualizat
                user.display_portfolio()

                break
            else:
                print("Insufficient quantity or invalid symbol. Please check your input.")
                break

    def is_valid_strategy(self, strategy_sl):
        import re
        pattern = re.compile(r"S\d+L\d+")
        return bool(pattern.match(strategy_sl))

trading_command = TradingCommand()

class BuyStrategy:
    def execute(self, symbol, quantity, price):
        pass

# Această clasă gestioneaza comanda History
class HistoryCommand:
    def execute(self):
        user = User.get_instance()
        user.transaction_history.display_history()
        while True:
            print("1. Back")

            history_choice = input("Your choice: ")

            if history_choice == "1":
                break
            else:
                print("Invalid choice. Please enter a valid option.")

history_command = HistoryCommand()

Proiect Stock  Trading System/commands.py


"""Train a model on SQuAD.

Author:
    Chris Chute (chute@stanford.edu)
"""

import random
from collections import OrderedDict
from json import dumps

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data as data
from tensorboardX import SummaryWriter
from tqdm import tqdm
from ujson import load as json_load

import util
from args import get_train_args
from models import init_training
from util import SQuAD

def main(args):
    # Set up logging and devices
    args.save_dir = util.get_save_dir(args.save_dir, args.name, args.dataset, mode="train")
    log = util.get_logger(args.save_dir, args.name)
    tbx = SummaryWriter(args.save_dir)
    device, args.gpu_ids = util.get_available_devices()
    log.info(f'Args: {dumps(vars(args), indent=4, sort_keys=True)}')
    args.batch_size *= max(1, len(args.gpu_ids))

    # Set random seed
    log.info(f'Using random seed {args.seed}...')
    random.seed(args.seed)
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)
    torch.cuda.manual_seed_all(args.seed)

    # Get data loader
    log.info('Building dataset...')
    collate_fn = None if args.name in ['qanet'] else util.collate_fn
    train_loader, train_size, dev_loader, dev_size = build_datasets(args, collate_fn)
    dev_eval_dict = util.load_eval_file(args, args.dev_eval_file)

    # Get model
    log.info(f'Building {args.name} model...')
    config = None
    if args.config_file:
        with open(args.config_file, 'r') as pf: config = json_load(pf)
        log.info(f"Model config: {dumps(config, indent=4, sort_keys=True)}")
    model, optimizer, scheduler, ema, step = init_training(args, *(load_embeddings(args)), device, config=config)

    # Get saver
    saver = util.CheckpointSaver(args.save_dir,
                                 max_checkpoints=args.max_checkpoints,
                                 metric_name=args.metric_name,
                                 maximize_metric=args.maximize_metric,
                                 log=log)

    # Train
    log.info('Training...')
    steps_till_eval = args.eval_steps
    epoch = step // train_size
    while epoch != args.num_epochs:
        epoch += 1
        log.info(f'Starting epoch {epoch}...')
        with torch.enable_grad(), tqdm(total=train_size) as progress_bar:
            for cw_idxs, cc_idxs, qw_idxs, qc_idxs, y1, y2, ids in train_loader:
                # Setup for forward
                cw_idxs = cw_idxs.to(device)
                cc_idxs = cc_idxs.to(device)
                qw_idxs = qw_idxs.to(device)
                qc_idxs = qc_idxs.to(device)
                batch_size = cw_idxs.size(0)
                optimizer.zero_grad()

                # Forward
                # if use_char_vectors:
                #     log_p1, log_p2 = model(cw_idxs.to(device), qw_idxs.to(device))
                # else:
                log_p1, log_p2 = model(cw_idxs.to(device), cc_idxs.to(device), qw_idxs.to(device), qc_idxs.to(device))

                y1, y2 = y1.to(device), y2.to(device)
                nll_loss_1 = F.nll_loss(log_p1, y1)
                nll_loss_2 = F.nll_loss(log_p2, y2)
                loss = nll_loss_1 + nll_loss_2
                loss_val = loss.item()

                # Backward
                loss.backward()
                nn.utils.clip_grad_norm_(model.parameters(), args.max_grad_norm)
                optimizer.step()
                scheduler.step()
                ema(model, step // batch_size)

                # Log info
                step += batch_size
                progress_bar.update(batch_size)
                current_lr = optimizer.param_groups[0]['lr']
                progress_bar.set_postfix(epoch=epoch, STEP=util.millify(step), LR=current_lr, NLL=loss_val)

                tbx.add_scalar('train/NLL', loss_val, step)
                tbx.add_scalar('train/LR',
                               current_lr,
                               step)

                steps_till_eval -= batch_size
                if steps_till_eval <= 0:
                    steps_till_eval = args.eval_steps

                    # Evaluate and save checkpoint
                    log.info(f'Evaluating at step {step}...')
                    ema.assign(model)
                    dev_eval_file = util.preprocessed_path(args.dev_eval_file, args.data_dir, args.dataset)
                    results, pred_dict = evaluate(model, dev_loader, device,
                                                  dev_eval_file,
                                                  args.max_ans_len,
                                                  args.use_squad_v2)
                    saver.save(step, model, results[args.metric_name], device)
                    ema.resume(model)

                    # Log to console
                    results_str = ', '.join(f'{k}: {v:05.2f}' for k, v in results.items())
                    log.info(f'Dev {results_str}')

                    # Log to TensorBoard
                    log.info('Visualizing in TensorBoard...')
                    for k, v in results.items():
                        tbx.add_scalar(f'dev/{k}', v, step)

                    util.visualize(tbx,
                                   pred_dict=pred_dict,
                                   eval_dict=dev_eval_dict,
                                   step=step,
                                   split='dev',
                                   num_visuals=args.num_visuals)

def build_datasets(args, collate_fn=None):
    train_loader, train_size = build_loader(args.train_record_file, args.data_dir, args.dataset, args.batch_size, args.num_workers, True, args.use_squad_v2, collate_fn)
    dev_loader, dev_size = build_loader(args.dev_record_file, args.data_dir, args.dataset, args.batch_size, args.num_workers, False, args.use_squad_v2, collate_fn)
    return train_loader, train_size, dev_loader, dev_size

def build_loader(record_file, data_dir, dataset, batch_size, num_workers, shuffle, use_squad_v2=True, collate_fn=None):
    record_file_path = util.preprocessed_path(record_file, data_dir, dataset)
    dataset = SQuAD(record_file_path, use_squad_v2)
    num_samples = len(dataset)
    loader = data.DataLoader(
        dataset,
        batch_size=batch_size,
        shuffle=shuffle,
        num_workers=num_workers,
        collate_fn=collate_fn
    )
    return loader, num_samples

def load_embeddings(args):
    word_emb_file = util.preprocessed_path(args.word_emb_file, args.data_dir, args.dataset)
    char_emb_file = util.preprocessed_path(args.char_emb_file, args.data_dir, args.dataset)
    word_vectors = util.torch_from_json(word_emb_file)
    char_vectors = util.torch_from_json(char_emb_file)
    return word_vectors, char_vectors

def evaluate(model, data_loader, device, eval_file, max_len, use_squad_v2):
    nll_meter = util.AverageMeter()

    model.eval()
    pred_dict = {}
    with open(eval_file, 'r') as fh:
        gold_dict = json_load(fh)
    with torch.no_grad(), tqdm(total=len(data_loader.dataset)) as progress_bar:
        for cw_idxs, cc_idxs, qw_idxs, qc_idxs, y1, y2, ids in data_loader:
            # Setup for forward
            cw_idxs = cw_idxs.to(device)
            cc_idxs = cc_idxs.to(device)
            qw_idxs = qw_idxs.to(device)
            qc_idxs = qc_idxs.to(device)
            batch_size = cw_idxs.size(0)

            # Forward
            log_p1, log_p2 = model(cw_idxs.to(device), cc_idxs.to(device), qw_idxs.to(device), qc_idxs.to(device))
            y1, y2 = y1.to(device), y2.to(device)
            loss = F.nll_loss(log_p1, y1) + F.nll_loss(log_p2, y2)
            nll_meter.update(loss.item(), batch_size)

            # Get F1 and EM scores
            p1, p2 = log_p1.exp(), log_p2.exp()
            starts, ends = util.discretize(p1, p2, max_len, use_squad_v2)

            # Log info
            progress_bar.update(batch_size)
            progress_bar.set_postfix(NLL=nll_meter.avg)

            preds, _ = util.convert_tokens(gold_dict,
                                           ids.tolist(),
                                           starts.tolist(),
                                           ends.tolist(),
                                           use_squad_v2)
            pred_dict.update(preds)

    model.train()

    results = util.eval_dicts(gold_dict, pred_dict, use_squad_v2)
    results_list = [('NLL', nll_meter.avg),
                    ('F1', results['F1']),
                    ('EM', results['EM'])]
    if use_squad_v2:
        results_list.append(('AvNA', results['AvNA']))
    results = OrderedDict(results_list)

    return results, pred_dict

if __name__ == '__main__':
    main(get_train_args())


from textblob import TextBlob
import nltk
import json
from nltk import ne_chunk, pos_tag, word_tokenize
import string
import re
import pprint
from urllib.request import urlopen
from bs4 import BeautifulSoup
import random
import danparser
from fractions import Fraction

unhealthy_list = ['ghee', 'oil', 'butter', 'salt', 'sugar', 'fat']

def make_healthy(ingredients):
	replaced = []
	for ingredient in ingredients:
		for unhealthy_item in unhealthy_list:
			if unhealthy_item in ingredient._name.lower():
				print (unhealthy_item)
				if ingredient._quantity != 'n/a' and ingredient._name not in replaced:
					ingredient._quantity = 0.5 * float(sum(Fraction(s) for s in ingredient._quantity.split()))
					replaced.append(ingredient._name)
	return ingredients

#print(make_healthy(LakshmanParser.ingredient_info("https://www.allrecipes.com/recipe/228293/curry-stand-chicken-tikka-masala-sauce/")))

def make_vegetarian(ingredients):
	replaced = []
	meat_list = []
	meat_txt = open('meats.txt', 'r')
	meat_line = meat_txt.readlines()
	for m in meat_line:
		temp = m.rstrip('\n')
		meat_list.append(str(temp.lower()))

	for ingredient in ingredients:
		for meat_item in meat_list:
			if meat_item in ingredient._name.lower():
				print (ingredient._name)
				if ingredient._name not in replaced:
					ingredient._name = 'Paneer'
					ingredient._descriptor = 'n/a'
					replaced.append(ingredient._name)
	return ingredients

indian_list = []
indian_ing_1 = danparser.Ingredient()
indian_ing_1._name = 'garlic'
indian_ing_1._preperation = 'paste'
indian_ing_1._quantity = ''
indian_ing_1._descriptor = ["n/a"]
indian_list.append(indian_ing_1)

indian_ing_2 = danparser.Ingredient()
indian_ing_2._name = 'ginger'
indian_ing_2._preperation = 'paste'
indian_ing_2._quantity = ''
indian_ing_2._descriptor = ["n/a"]
indian_list.append(indian_ing_2)

indian_ing_3 = danparser.Ingredient()
indian_ing_3._name = 'curry powder'
indian_ing_3._preperation = 'n/a'
indian_ing_3._quantity = ''
indian_ing_3._descriptor = ["n/a"]
indian_list.append(indian_ing_3)

indian_ing_4 = danparser.Ingredient()
indian_ing_4._name = 'garam masala'
indian_ing_4._preperation = 'n/a'
indian_ing_4._quantity = ''
indian_ing_4._descriptor = ["n/a"]
indian_list.append(indian_ing_4)

indian_ing_5 = danparser.Ingredient()
indian_ing_5._name = 'cumin'
indian_ing_5._preperation = 'n/a'
indian_ing_5._quantity = ''
indian_ing_5._descriptor = ["n/a"]
indian_list.append(indian_ing_5)

indian_ing_6 = danparser.Ingredient()
indian_ing_6._name = 'coriander'
indian_ing_6._preperation = 'leaves'
indian_ing_6._quantity = ''
indian_ing_6._descriptor = ["n/a"]
indian_list.append(indian_ing_6)

indian_ing_7 = danparser.Ingredient()
indian_ing_7._name = 'mustard seeds'
indian_ing_7._preperation = 'n/a'
indian_ing_7._quantity = ''
indian_ing_7._descriptor = ["black"]
indian_list.append(indian_ing_7)

indian_ing_8 = danparser.Ingredient()
indian_ing_8._name = 'chilli pepper'
indian_ing_8._preperation = 'n/a'
indian_ing_8._quantity = ''
indian_ing_8._descriptor = ["dried", "red"]
indian_list.append(indian_ing_8)

#print (indian_list)

main_ingredient_list = ['chicken', 'turkey', 'beef', 'fish', 'tuna', 'paneer', 'tofu', 'mushroom', 'sausage', 'pork', 'samon', 'pig', 'tofu', '']

italian_list_names = ['basil', 'mozzarella', 'wine', 'ricotta', 'olive', 'parmesan', 'caper', 'balsamic', 'oregano', 'italian']

def make_indian(ingredients):
	replaced = []
	for ingredient in ingredients:
		for italian_list_item in italian_list_names:
			if italian_list_item.lower() in ingredient._name.lower() or italian_list_item in ingredient._descriptor.lower():
				ingredients.remove(ingredient)
	ingredients = ingredients+indian_list

	return ingredients

print(make_indian(danparser.ingredient_info("https://www.allrecipes.com/recipe/14592/italian-style-meatloaf-i/")))

#print(make_vegetarian(LakshmanParser.ingredient_info("https://www.allrecipes.com/recipe/228293/curry-stand-chicken-tikka-masala-sauce/")))


# import modul library
from .config import NMS_THRESH
from .config import MIN_CONF
import numpy as np
import cv2

#function untuk mendeteksi orang
def detections(frame, net, ln, personIdx=0):

#ambil dimensi bingkai dan inisialisasi daftar hasil
    (H, W) = frame.shape[:2]
    results = []
    blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)
    net.setInput(blob)
    layerOutputs = net.forward(ln)

    # inisialisasi deteksi bounding boxes, centroids, and confidence
    boxes = []
    centroids = []
    confidences = []

    # looping
    for output in layerOutputs:
        for detection in output:
            # ekstrak kelas ID dan confidence(probabilitas) dari deteksi objek saat in
            scores = detection[5:]
            classID = np.argmax(scores)
            confidence = scores[classID]

            # deteksi filter dengan memastikan bahwa objek yang terdeteksi adalah orang dan bahwa confidence minimum terpenuhi
            if classID == personIdx and confidence > MIN_CONF:
                # skala koordinat bounding box  kembali relatif terhadap ukuran gambar mengembalikan koordinat pusat (x, y) diikuti dengan lebar dan tinggi kotak
                box = detection[0:4] * np.array([W, H, W, H])
                (centerX, centerY, width, height) = box.astype("int")

                # menggunakan koordinat pusat (x,y) untuk menurunkan sudut atas dan kiri dari bounding box / kotak pembatas
                x = int(centerX - (width / 2))
                y = int(centerY - (height / 2))

                # mengupdate  bounding box coordinates, centroids dan confidences
                boxes.append([x, y, int(width), int(height)])
                centroids.append((centerX, centerY))
                confidences.append(float(confidence))

    idx = cv2.dnn.NMSBoxes(boxes, confidences, MIN_CONF, NMS_THRESH)

    # memastikan setidaknya ada satu deteksi
    if len(idx) > 0:
        # loop di atas indeks yang disimpan
        for i in idx.flatten():
            # ekstrak koordinat bounding box/kotak pembatas
            (x, y) = (boxes[i][0], boxes[i][1])
            (w, h) = (boxes[i][2], boxes[i][3])
            # memperbarui hasil dari list probabilitas prediksi orang, bounding box coordinates, dan centroid
            r = (confidences[i], (x, y, x + w, y + h), centroids[i])
            results.append(r)

    # mengembalikan results
    return results


# -*- coding: utf-8 -*-
"""
Created on Tue Jan 11 12:09:02 2022

Class and function used for handling data files with mixed UBX data from ublox GNSS modules and frm LDS70A Laser altimeter.

@author: Laktop
"""

import numpy as np
import re
import math
from datetime import datetime
import matplotlib.pyplot as pl
import os,sys
from cmcrameri import cm
from geopy import distance
import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import io
from urllib.request import urlopen, Request
from PIL import Image

# %%  data class

class MSG_type:

    def __init__(self,MSG):
        self.len=0
        self.MSG=MSG

    def addData(self,keys,values):
        self.len=(len(values))
        if len(keys)!=len(values[0]):
            print("Keys and values don't have same length!!")
            print(values[0])
            print(keys)

            return
        self.keys=keys.copy()
        for i,k in enumerate(keys):
            setattr(self,k,np.array([l[i] for l in values]))

_MSG_list_=['Laser','PINS1','PSTRB','PINS2']    # NMEA message list to parse
_keyList_=[['h','signQ','T','TOW'],
          ['TOW','GPSWeek','insStatus','hdwStatus','roll','pitch','heading','velX', 'velY', 'velZ','lat', 'lon', 'height','OffsetLLA_N','OffsetLLA_E','OffsetLLA_D'],
          ['GPSWeek','TOW','pin','count'],
          ['TOW','GPSWeek','insStatus','hdwStatus','QuatW','QuatX','QuatY','QuatZ','velX', 'velY', 'velZ','lat', 'lon', 'height']]  # order matters!!

class INSLASERdata:

    # extr_list=['PINS1','Laser']

    def __init__(self,filepath,name='',load=True, droplaserTow0=True,
                 correct_Laser=True,distCenter=0, pitch0=0, roll0=0,laser_time_offset=0,c_pitch=1,c_roll=1):
        """
            Read GNSS and Laser data from .ubx data file. Additional methods are available for plotting and handling data.

            Inputs:
            ---------------------------------------------------
            filepath:           file path

        """

        if name!='':
            self.name=name
        else:
             self.name=filepath.split('\\')[-1]

        self.filepath=filepath
        self.ToW=0
        self.distCenter=distCenter
        self.pitch0=pitch0
        self.roll0=roll0
        self.c_pitch=c_pitch
        self.c_roll=c_roll

        self.keyList=_keyList_.copy()
        self.MSG_list=_MSG_list_.copy()

        if load:
            self.loadData(correct_Laser=correct_Laser,droplaserTow0=droplaserTow0)

    def loadData(self,correct_Laser=0,droplaserTow0=True):
        if not os.path.isfile(self.filepath) :
            print("File not found!!!")
            raise FileNotFoundError()

        print('Reading file: ',self.filepath)
        print('----------------------------')
        file = open(self.filepath, 'rt')

        for msg in (self.MSG_list):
            setattr(self,msg+'List',[])

        i=0

        self.corrupt=[]
        self.other=[]
        self.dropped=[]

        for l in file:
            # print(l)
            # l2=str(l)
            i+=1
            if l[0]=='#':
                continue
            elif l.find('$')!=-1:
                Msg_key,data=parseNMEAfloat(l)

                if Msg_key=='PINS1':
                    self.ToW=data[0]

                if Msg_key=='Error':
                    self.corrupt.append(l)
                    # print("Message {:s} not in NMEA message list".format(Msg_key))
                    try:
                        self.dropped.index(Msg_key)
                    except ValueError:
                        self.dropped.append(Msg_key)
                    continue

                try:
                  j=self.MSG_list.index(Msg_key)
                  if len(data)!=len(self.keyList[j]):
                      self.corrupt.append(l)
                      continue
                except ValueError:
                    print("Message {:s} not in NMEA message list. Dropping it.".format(Msg_key))
                    continue

                getattr(self,Msg_key+'List').append(data)

            elif l.find('D ')!=-1:
                self.LaserList.append(parseLaser(l)+(self.ToW,) )

            else:
                self.other.append(l)

        # drop  laser points with ToW=0
        if droplaserTow0:
            for j,l in enumerate(self.LaserList):
                if l[-1]!=0:
                    break
            self.LaserList=self.LaserList[j:]

        for msg in (self.MSG_list):
            setattr(self,msg,MSG_type(msg) )
            if len(getattr(self,msg+'List'))>0:
                values=np.array(getattr(self,msg+'List'))
                keys=self.keyList[self.MSG_list.index(msg)]
                print(keys)
                getattr(self,msg).addData(keys,values)

            # delattr(self,msg+'List')

        print("Total lines read: ", i)

        # correct h with angles from INS
        if correct_Laser:
                self.corr_h_laser()

    def corr_h_laser(self):
        """
        correct height with angles from INS
        """
        try:
            i=self.PINS1.TOW.searchsorted( self.Laser.TOW)
            j=np.array(i)-1

            pitch=self.PINS1.pitch[j]+(self.PINS1.pitch[i]-self.PINS1.pitch[j])/(self.PINS1.TOW[i]-self.PINS1.TOW[j])*(self.Laser.TOW-self.PINS1.TOW[j])
            roll=self.PINS1.roll[j]+(self.PINS1.roll[i]-self.PINS1.roll[j])/(self.PINS1.TOW[i]-self.PINS1.TOW[j])*(self.Laser.TOW-self.PINS1.TOW[j])

            roll-=self.roll0
            pitch-=self.pitch0
            # roll*=self.c_roll
            # pitch*=self.c_pitch

            self.Laser.pitch=pitch
            self.Laser.roll=roll
            self.Laser.h_corr=self.Laser.h*(np.cos(pitch)*np.cos(roll))-self.distCenter*np.sin(pitch)
            self.Laser.keys.extend(['h_corr','roll','pitch'])

        except Exception as e:
            print(e)
            print('Failed to correct Laser height')
            try:
                self.Laser.h_corr=np.zeros_like(self.Laser.h)
            except AttributeError:
                print('Laser data not found.')

    def plot_att(self,ax=[]):
        plot_att(self,ax=ax)

    def plot_elevation_time(self,ax=[],title=[]):
        plot_elevation_time(self,ax=ax,title=title)

    def plot_longlat(self,z='height',ax=[],cmap= cm.batlow):
        plot_longlat(self,z=z,ax=ax,cmap=cmap)

    def plot_map(self,z='height',ax=[],cmap= cm.batlow):
        plot_map(self,z=z,ax=ax,cmap=cmap)

    def plot_mapOSM(self,z='TOW',ax=[],cmap= cm.batlow,title=[],extent=[]):
        plot_mapOSM(self,z=z,ax=ax,cmap= cmap,title=title,extent=extent)

    def subset(self, timelim=[],timeformat='s'):
        """
        Parameters
        ----------
        timelim : List, optional
            limits in time. The default is [].
        timeformat : string, optional
            units of time limits. Either 'TOW' or 's' (relative to start of data).

        Returns
        -------
        data2 : UBX2data object with subset of data into time limits

        """
        d=self.PINS1
        if timeformat=='TOW':
              lim=d.TOW.searchsorted(timelim)
              TOW_lim=timelim
        elif timeformat=='s':
              lim=((d.TOW -d.TOW[0]) ).searchsorted(timelim)
              TOW_lim=d.TOW[lim]
        else:
            print('timeformat not valid')
            return 0

        data2=INSLASERdata(self.filepath,name=self.name,load=False)

        for attr in (self.MSG_list):
            # print(attr)
            try:
                msg_data=getattr(self,attr)
                lim2=msg_data.TOW.searchsorted(TOW_lim)
            except Exception as e:
                    print(e)
                    print(attr)
                    # continue
            d2=MSG_type(attr)

            for a in msg_data.__dict__.keys():
                # print('\t',a)
                try:
                    setattr(d2,a,np.array(getattr(msg_data, a)[lim2[0]:lim2[1]] ))
                except:
                    setattr(d2,a,getattr(msg_data, a))
            setattr(d2,'len',lim2[1]-lim2[0])
            setattr(data2,attr,d2)
        return data2

# %% #########function definitions #############

def parseNMEA(l):
    """
    l: string with data
    TOW: time of Week to append to message data

    return height, signal quality, temperature

    """

    Msg_key=l[l.find('$')+1:l.find(',') ]
    start=l.find('$'+Msg_key)
    end=l.find('*')

    # Check if message is valid
    if (start!=-1 and end!=-1 and start<end and chksum_nmea(l[start:end+3])):

      try:
          a=np.array(l[start+len(Msg_key)+2:end].split(','),dtype=float)

      except:
          try:
              a=np.array(l[start+len(Msg_key)+2:end].split(','))
          except:
              print('Coud not parse valid NMEA string:', l)
              return 'Error',l
    else:
        print('Coud not parse string:', l)
        return 'Error',l

    return Msg_key,a

def parseNMEAfloat(l):
    """
    l: string with data
    TOW: time of Week to append to message data

    return height, signal quality, temperature

    """

    Msg_key=l[l.find('$')+1:l.find(',') ]
    start=l.find('$'+Msg_key)
    end=l.find('*')

    # Check if message is valid
    if (start!=-1 and end!=-1 and start<end and chksum_nmea(l[start:end+3])):

      try:
          a=np.array(l[start+len(Msg_key)+2:end].split(','),dtype=float)

      except:
              print('Coud not parse valid NMEA string:', l)
              return 'Error',l
    else:
        print('Coud not parse string:', l)
        return 'Error',l

    return Msg_key,a

def parseLaser(l):
    """
    l: string with data
    TOW: time of Week to append to message data

    return height, signal quality, temperature

    """

    h=[]
    T=[]
    signQ=[]
    TOW=[]

    i=0
    j=0
    t=0
    length=len(l)

    if l[0]=='D':

        a=l.split()
        if len(a)==2:
            signQ= np.nan
            T= np.nan
            try:
                h= float(a[1])
            except:
                h= np.nan
                print('coud not parse string:', l)
        else:
            error=0
            try:
                h= float(a[1])
            except:
                h= np.nan
                error=1
            try:
                signQ= float(a[2])
            except:
                signQ= np.nan
                error=1
            try:
                T= float(a[3])
            except:
                T= np.nan
                error=1
            if error:
                print('coud not parse string:', l)
    else:
        h= np.nan
        signQ= np.nan
        T= np.nan
        print('coud not parse string:', l)

    return h,signQ,T

def chksum_nmea(sentence):
    # From: http://doschman.blogspot.com/2013/01/calculating-nmea-sentence-checksums.html

    # This is a string, will need to convert it to hex for
    # proper comparsion below
    end=sentence.find("*")
    cksum = sentence[end+1:end+3]

    # String slicing: Grabs all the characters
    # between '$' and '*' and nukes any lingering
    # newline or CRLF
    chksumdata = re.sub("(\n|\r\n)","", sentence[sentence.find("$")+1:sentence.find("*")])

    # Initializing our first XOR value
    csum = 0

    # For each char in chksumdata, XOR against the previous
    # XOR'd char.  The final XOR of the last char will be our
    # checksum to verify against the checksum we sliced off
    # the NMEA sentence

    for c in chksumdata:
       # XOR'ing value of csum against the next char in line
       # and storing the new XOR value in csum
       csum ^= ord(c)

    # Do we have a validated sentence?
    try:
        if hex(csum) == hex(int(cksum, 16)):
           return True
    except  ValueError:
        print('Invalid checksum: ',cksum)
    return False

def check_data(data):
    """
    Check data and produce some plots

    Input:
    --------------
    data        Member of class UBXdata

    """

    print('\n\n###############################\n-----------------------------\n',
          data.name,
          '\n----------------------------\n###############################\n')

    for attr in data.MSG_list:
        try:
            d=getattr(data,attr)
            print('\n',attr,'\n----------------------------')
            print('Length:')
            print(d.len)
            print('Time intervall (s):')
            print((d.TOW[:5]-d.TOW[0]) )
        except Exception as e:
                print(e)

    print('\nOthers: \n----------------------------')
    print('Length:')
    try:
        print(len(data.other))
    except:
        print('no data')
    # for c in data.other[:10]:
    #     print(c)

    print('\nCorrupted: \n----------------------------')
    try:
        print(len(data.corrupt))
    except:
        print('no data')
    # for c in data.corrupt[:10]:
    #     print(c)

    try:
        data.plot_att()
    except AttributeError:
        print('no attitude messages found')

    try:
        if len(data.Laser.h)==0:
            raise AttributeError

        pl.figure()
        ax=pl.subplot(111)
        ax2=ax.twinx()
        ax.set_ylabel('Laser h (m)')
        ax2.set_ylabel('GNSS Delta_h (m)')
        ax.set_xlabel('time (ms)')

        ax.plot(data.Laser.TOW-data.PINS1.TOW[0],data.Laser.h,'--xk',label='Laser')
        # ax.plot(data.Laser.TOW2-data.PINS1.TOW[0],data.Laser.h,'--ob',label='Laser, time2')
        ax2.plot((data.PINS1.TOW-data.PINS1.TOW[0]),data.PINS1.height -(data.PINS1.height[0] -data.Laser.h[0]),'+:r',label='GPS height')

        lines, labels = ax.get_legend_handles_labels()
        lines2, labels2 = ax2.get_legend_handles_labels()
        ax2.legend(lines + lines2, labels + labels2, loc=0)
        pl.title(data.name)
    except AttributeError:
        print('No laser data found')

def plot_att(data,ax=[],title='',heading=True):
    if ax==[]:
        fig=pl.figure()
        ax=pl.subplot(111)
    else:
        pl.sca(ax)

    d=data.PINS1

    if heading:
            ax2=ax.twinx()

    ax.plot((d.TOW-d.TOW[0]),np.degrees(d.pitch),'o-r',label='pitch')
    ax.plot((d.TOW-d.TOW[0]),np.degrees(d.roll),'x-k',label='roll')
    if heading:
        ax2.plot((d.TOW-d.TOW[0]),np.degrees(d.heading),'x-b',label='heading')

    ax.set_ylabel('pitch/roll (deg)')
    ax.set_xlabel('time (s)')
    if heading:
        ax2.set_ylabel('heading (deg)')
        # ask matplotlib for the plotted objects and their labels
        lines, labels = ax.get_legend_handles_labels()
        lines2, labels2 = ax2.get_legend_handles_labels()
        ax2.legend(lines + lines2, labels + labels2, loc=0)
    else:
        ax.legend(loc=0)

    if title=='':
        pl.title(data.name)
    elif title!='none':
        pl.title(title)

def plot_att_laser(data,ax=[],title='',heading=True):
    if ax==[]:
        fig=pl.figure()
        ax=pl.subplot(111)
    else:
        pl.sca(ax)
        fig=pl.gcf()

    d=data.PINS1

    if heading:
            ax2=ax.twinx()

    ax.plot((d.TOW-d.TOW[0]),np.degrees(d.pitch),'o-r',label='pitch')
    ax.plot((d.TOW-d.TOW[0]),np.degrees(d.roll),'x-k',label='roll')
    if heading:
        ax2.plot((d.TOW-d.TOW[0]),np.degrees(d.heading),'x-b',label='heading')

    ax.set_ylabel('pitch/roll (deg)')
    ax.set_xlabel('time (s)')
    if heading:
        ax2.set_ylabel('heading (deg)')
        # ask matplotlib for the plotted objects and their labels
        lines, labels = ax.get_legend_handles_labels()
        lines2, labels2 = ax2.get_legend_handles_labels()
        ax2.legend(lines + lines2, labels + labels2, loc=0)
        ax2.yaxis.label.set_color('b')
        ax2.tick_params(axis='y', colors='b')
    else:
        ax.legend(loc=0)

    try:
        if len(data.Laser.h)==0:
            raise AttributeError

        ax3=ax.twinx()
        fig.subplots_adjust(right=0.75)
        ax3.spines['right'].set_position(("axes", 1.2))
        ax3.yaxis.label.set_color('g')
        ax3.tick_params(axis='y', colors='g')
        ax3.set_ylabel('Laser h (m)')
        ax3.plot((data.Laser.TOW-d.TOW[0]),data.Laser.h,':og',label='Laser')
        lines3, labels3 = ax3.get_legend_handles_labels()
    except AttributeError:
        print('No laser data found')
        lines3=[]
        labels3=[]

    if title=='':
        pl.title(data.name)
    elif title!='none':
        pl.title(title)

def plot_elevation_time(data,ax=[],title=[]):
    if ax==[]:
        fig=pl.figure()
        ax=pl.subplot(111)
    else:
        pl.sca(ax)

    d=data.PINS1

    ax.plot((d.TOW-d.TOW[0]),d.height,'o-r',label='height')
    ax.set_ylabel('elevation (m a.s.l.)')
    ax.set_xlabel('time (s)')

    if title:
        pl.title(title)
    pl.tight_layout()

def plot_longlat(data,z='height',ax=[],cmap= cm.batlow):
    if ax==[]:
        fig=pl.figure()
        ax=pl.subplot(111)
    else:
        pl.sca(ax)

    d=data.PINS1

    ax2=ax.twinx()
    c=getattr(d,z)
    if z=='height':
        label='elevation (m a.s.l.)'
        c=c
    elif z=='TOW':
        label='time (s)'
        c-=c[0]
        c=c
    else:
        label=z
    lat=np.array([distance.distance((d.lat[0],d.lon[0]),(x,d.lon[0])).m for x in d.lat ])
    lon=np.array([distance.distance((d.lat[0],d.lon[0]),(d.lat[0],x)).m for x in d.lon ])

    im=ax.scatter(lon,lat,c=c,cmap=cmap,marker='x')
    c=pl.colorbar(im, label=label)
    ax.invert_xaxis()
    ax.set_ylabel('N (m)')
    ax.set_xlabel('W (m)')

    pl.title(data.name)
    pl.tight_layout()

def plot_summary(data,extent,cmap=cm.batlow,heading=True):

    fig=pl.figure(figsize=(8,10))
    spec = fig.add_gridspec(ncols=1, nrows=9)
    cimgt.OSM.get_image = image_spoof # reformat web request for street map spoofing
    osm_img = cimgt.OSM() # spoofed, downloaded street map

    ax0 = fig.add_subplot(spec[0:3, 0],projection=osm_img.crs)
    data.plot_mapOSM(z='TOW',extent=extent,ax=ax0, cmap=cmap  )

    ax1 = fig.add_subplot(spec[3:5, 0])
    ax1.plot((data.PINS1.TOW-data.PINS1.TOW[0]) ,
              [distance.distance((data.PINS1.lat[0],data.PINS1.lon[0]),(data.PINS1.lat[0],x)).m for x in data.PINS1.lon ],
              'x:',label='East-West')
    ax1.plot((data.PINS1.TOW-data.PINS1.TOW[0]) ,
              [distance.distance((data.PINS1.lat[0],data.PINS1.lon[0]),(x,data.PINS1.lon[0])).m for x in data.PINS1.lat ],
              '+:',label='North-South')
    ax1.set_ylabel('Distance (m)')
    ax1.legend()

    ax2 = fig.add_subplot(spec[5:7, 0],sharex = ax1)
    ax2.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.h, 'x:',label='original')
    ax2.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.h_corr, '+:k',label='corrected')
    ax2.plot((data.PINS1.TOW-data.PINS1.TOW[0]) ,data.PINS1.height -(data.PINS1.height[0] -data.Laser.h[0]),'+:r',label='GPS height')
    ax2.set_ylabel('h_laser (m)')
    ax2.set_xlim(ax1.get_xlim())
    ax2.legend()

    ax3 = fig.add_subplot(spec[7:9, 0],sharex = ax1)
    plot_att(data,ax=ax3,title='none',heading=heading)
    pl.tight_layout()
    return fig

def laser_correction(data,show_corr_angles=0,GPS_h=False,heading=False):

    fig, [ax2,ax3] = pl.subplots(2, 1, figsize=(8, 8), sharex=True, sharey=False)

    ax2.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.h, 'x:',label='original')
    ax2.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.h_corr, '+:',label='corrected')
    if GPS_h:
        ax2.plot((data.PINS1.TOW-data.PINS1.TOW[0]) ,data.PINS1.height -(data.PINS1.height[0] -data.Laser.h[0]),'+:r',label='GPS height')
    ax2.set_ylabel('h_laser (m)')
    ax2.legend()

    plot_att(data,ax=ax3,title='none',heading=heading)

    if show_corr_angles:
        ax3.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,np.degrees(data.Laser.pitch), 'x:',label='pitch laser')
        ax3.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,np.degrees(data.Laser.roll), 'x:',label='roll laser')
        ax3.legend(loc=0)
    return fig

def laser_correction_superimposed(data,GPS_h=False):

    fig, ax2 = pl.subplots(1, 1, figsize=(8, 8))

    ax2.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.h, 'x:',label='original')
    ax2.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.h_corr, '+:',label='corrected')
    if GPS_h:
        ax2.plot((data.PINS1.TOW-data.PINS1.TOW[0]) ,data.PINS1.height -(data.PINS1.height[0] -data.Laser.h[0]),'+:r',label='GPS height')
    ax2.set_ylabel('h_laser (m)')
    ax2.legend(loc=2)

    ax3=ax2.twinx()
    ax3.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.pitch, 'x:k',label='pitch laser')
    ax3.plot((data.Laser.TOW-data.PINS1.TOW[0]) ,data.Laser.roll, '+:r',label='roll laser')
    ax3.legend(loc=1)
    ax3.set_ylabel('Angle (rad)')
    ax2.grid()
    return fig

# %% plot on map
def plot_map(data,z='height',ax=[],cmap= cm.batlow,title=[],timelim=[],timeformat='ms'):

    if ax==[]:
        fig=pl.figure()
        ax = pl.axes(projection=ccrs.PlateCarree())
    else:
        ax.axes(projection=ccrs.PlateCarree())

    d=data.PINS1
    if not timelim==[]:
        if timeformat=='ms':
            lim=d.TOW.searchsorted(timelim)
        if timeformat=='s':
            lim=((d.TOW -d.TOW[0]) ).searchsorted(timelim)

    c=getattr(d,z)[lim[0]:lim[1]] # get data color plot

    if z=='height':
        label='elevation (m a.s.l.)'
        c=c
    elif z=='TOW':
        label='time (s)'
        c-=c[0]
        c=c
    else:
        label=z

    ax.coastlines()
    im=ax.scatter(d.lon[lim[0]:lim[1]],d.lat[lim[0]:lim[1]],c=c,cmap=cmap,marker='x')
    c=pl.colorbar(im, label=label)

    lon_formatter = LongitudeFormatter(number_format='0.1f',degree_symbol='',dateline_direction_label=True) # format lons
    lat_formatter = LatitudeFormatter(number_format='0.1f',degree_symbol='') # format lats
    ax.xaxis.set_major_formatter(lon_formatter) # set lons
    ax.yaxis.set_major_formatter(lat_formatter) # set lats

    if title:
        pl.title(title)
    pl.tight_layout()

def image_spoof(self, tile): # this function pretends not to be a Python script
        url = self._image_url(tile) # get the url of the street map API
        req = Request(url) # start request
        req.add_header('User-agent','Anaconda 3') # add user agent to request
        fh = urlopen(req)
        im_data = io.BytesIO(fh.read()) # get image
        fh.close() # close url
        img = Image.open(im_data) # open image with PIL
        img = img.convert(self.desired_tile_form) # set image format
        return img, self.tileextent(tile), 'lower' # reformat for cartopy

def plot_mapOSM(data,z='height',ax=[],cmap= cm.batlow,title=[], extent=[]):
    """
    Plot data (z) on Open Street Map layer.

    Parameters
    ----------
    data : TYPE
        DESCRIPTION.

    z : TYPE, optional
        DESCRIPTION. The default is 'height'.
    ax : TYPE, optional
        DESCRIPTION. The default is [].
    cmap : TYPE, optional
        DESCRIPTION. The default is cm.batlow.
    title : TYPE, optional
        DESCRIPTION. The default is [].
    extent:     limits of map. In [[lon,lon,lat,lat]]

    Returns
    -------
    None.

    """
    cimgt.OSM.get_image = image_spoof # reformat web request for street map spoofing
    osm_img = cimgt.OSM() # spoofed, downloaded street map

    if ax==[]:
        fig=pl.figure()
        ax = pl.axes(projection=osm_img.crs)

    # prepare data
    d=data.PINS1
    c=np.array( getattr(d,z))
    if z=='height':
        label='elevation (m a.s.l.)'
        c=c
    elif z=='TOW':
        label='time (s)'
        c-=c[0]
        c=c
    else:
        label=z

    if extent==[]:
        dx=(np.max(d.lon)-np.min(d.lon))
        dy=(np.max(d.lat)-np.min(d.lat))
        W=np.max([dx,dy])*3/5
        center=[(np.max(d.lon)+np.min(d.lon))/2, (np.max(d.lat)+np.min(d.lat))/2]
        extent = [center[0]-W,center[0]+W, center[1]-W,center[1]+W] # Contiguous US bounds
        print(extent)

    # setup map
    ax.set_extent(extent) # set extents
    ax.set_xticks(np.linspace(extent[0],extent[1],3),crs=ccrs.PlateCarree()) # set longitude indicators
    ax.set_yticks(np.linspace(extent[2],extent[3],4)[1:],crs=ccrs.PlateCarree()) # set latitude indicators
    lon_formatter = LongitudeFormatter(number_format='0.4f',degree_symbol='',dateline_direction_label=True) # format lons
    lat_formatter = LatitudeFormatter(number_format='0.4f',degree_symbol='') # format lats
    ax.xaxis.set_major_formatter(lon_formatter) # set lons
    ax.yaxis.set_major_formatter(lat_formatter) # set lats
    ax.xaxis.set_tick_params()
    ax.yaxis.set_tick_params()

    scale = np.ceil(-np.sqrt(2)*np.log(np.divide((extent[1]-extent[0])/2.0,350.0))) # empirical solve for scale based on zoom
    scale = (scale<20) and scale or 19 # scale cannot be larger than 19
    ax.add_image(osm_img, int(scale))

    im=ax.scatter(d.lon,d.lat,c=c,cmap=cmap,marker='x',transform=ccrs.PlateCarree())
    c=pl.colorbar(im, label=label)

    if title:
        pl.title(title)
    pl.tight_layout()

def getextent(data):
    minlon=data.PINS1.lon.min()
    maxlon=data.PINS1.lon.max()
    minlat=data.PINS1.lat.min()
    maxlat=data.PINS1.lat.max()
    dlat=maxlat-minlat
    dlon=maxlon-minlon
    return minlon-dlon/10,maxlon+dlon/10,minlat-dlat/10,maxlat+dlat/10


# https://gis.stackexchange.com/questions/265589/change-shapefile-coordinate-system-using-python

# this script not yet tested. Might be able to use ogr2ogr

in_epsg = 5514
out_epsg = 4326
in_shp = 'path/to/input.shp'
out_shp = '/path/to/reprojected.shp'

driver = ogr.GetDriverByName('ESRI Shapefile')

# input SpatialReference
inSpatialRef = osr.SpatialReference()
inSpatialRef.ImportFromEPSG(in_epsg)

# output SpatialReference
outSpatialRef = osr.SpatialReference()
outSpatialRef.ImportFromEPSG(out_epsg)

# create the CoordinateTransformation
coordTrans = osr.CoordinateTransformation(inSpatialRef, outSpatialRef)

# get the input layer
inDataSet = driver.Open(in_path)
inLayer = inDataSet.GetLayer()

# create the output layer
if os.path.exists(out_shp):
    driver.DeleteDataSource(out_shp)
outDataSet = driver.CreateDataSource(out_shp)
outLayer = outDataSet.CreateLayer("reproject", geom_type=ogr.wkbMultiPolygon)

# add fields
inLayerDefn = inLayer.GetLayerDefn()
for i in range(0, inLayerDefn.GetFieldCount()):
    fieldDefn = inLayerDefn.GetFieldDefn(i)
    outLayer.CreateField(fieldDefn)

# get the output layer's feature definition
outLayerDefn = outLayer.GetLayerDefn()

# loop through the input features
inFeature = inLayer.GetNextFeature()
while inFeature:
    # get the input geometry
    geom = inFeature.GetGeometryRef()
    # reproject the geometry
    geom.Transform(coordTrans)
    # create a new feature
    outFeature = ogr.Feature(outLayerDefn)
    # set the geometry and attribute
    outFeature.SetGeometry(geom)
    for i in range(0, outLayerDefn.GetFieldCount()):
        outFeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(), inFeature.GetField(i))
    # add the feature to the shapefile
    outLayer.CreateFeature(outFeature)
    # dereference the features and get the next input feature
    outFeature = None
    inFeature = inLayer.GetNextFeature()

# Save and close the shapefiles
inDataSet = None
outDataSet = None


from flask import Flask
from config import Config
from flask_cors import CORS
from app.models import SQLAConfig
from swagger_stack.swagger_initialize import SwaggerConfig

class AppFactory:

    @classmethod
    def initialize(cls):
        try:
            app = Flask(__name__)
            config = Config()
            CORS(app)
            SwaggerConfig.initialize(app)

            from app.api.api import api_bp
            app.register_blueprint(api_bp)

            SQLAConfig.initialize()
            with app.app_context():
                pass

            return app

        except Exception as e:
            print(e)