from __future__ import annotations

from decimal import Decimal
from functools import lru_cache
from math import floor
from typing import List, Optional, TypeVar, Union

from kraken.base_api import KrakenBaseSpotAPI, defined, ensure_string
from kraken.spot.market import Market

Self = TypeVar("Self")

class Trade(KrakenBaseSpotAPI):
    """
    Class that implements the Kraken Trade Spot client

    :param key: Spot API public key (default: ``""``)
    :type key: str, optional
    :param secret: Spot API secret key (default: ``""``)
    :type secret: str, optional
    :param url: The URL to access the Kraken API (default: https://api.kraken.com)
    :type url: str, optional
    :param sandbox: Use the sandbox (not supported for Spot trading so far, default: ``False``)
    :type sandbox: bool, optional

    .. code-block:: python
        :linenos:
        :caption: Spot Trade: Create the trade client

        >>> from kraken.spot import Trade
        >>> trade = Trade() # unauthenticated
        >>> auth_trade = Trade(key="api-key", secret="secret-key") # authenticated

    .. code-block:: python
        :linenos:
        :caption: Spot Trade: Create the trade client as context manager

        >>> from kraken.spot import Trade
        >>> with Trade(key="api-key", secret="secret-key") as trade:
        ...     print(trade.create_order(...))

    """

    def __init__(
        self: Trade,
        key: str = "",
        secret: str = "",
        url: str = "",
    ) -> None:
        super().__init__(key=key, secret=secret, url=url)
        self.__market: Market = Market()

    def __enter__(self: Self) -> Self:
        super().__enter__()
        return self

    @ensure_string("oflags")
    def create_order(  # noqa: PLR0913 PLR0912
        self: Trade,
        ordertype: str,
        side: str,
        pair: str,
        volume: Union[str, float],
        price: Optional[Union[str, float]] = None,
        price2: Optional[Union[str, float]] = None,
        truncate: bool = False,
        trigger: Optional[str] = None,
        leverage: Optional[str] = None,
        reduce_only: Optional[bool] = False,
        stptype: Optional[str] = "cancel-newest",
        oflags: Optional[Union[str, List[str]]] = None,
        timeinforce: Optional[str] = None,
        displayvol: Optional[str] = None,
        starttm: Optional[str] = "0",
        expiretm: Optional[str] = None,
        close_ordertype: Optional[str] = None,
        close_price: Optional[Union[str, float]] = None,
        close_price2: Optional[Union[str, float]] = None,
        deadline: Optional[str] = None,
        validate: bool = False,
        userref: Optional[int] = None,
    ) -> dict:
        """
        Create a new order and place it on the market.

        Requires the ``Create and modify orders`` permission in
        the API key settings.

        - https://docs.kraken.com/rest/#operation/addOrder

        :param ordertype: The kind of the order, one of: ``market``, ``limit``, ``take-profit``,
            ``stop-loss-limit``, ``take-profit-limit`` and ``settle-position``
            (see: https://support.kraken.com/hc/en-us/sections/200577136-Order-types)
        :type ordertype: str
        :param side: ``buy`` or ``sell``
        :type side: str
        :param pair: The asset to trade
        :type pair: str
        :param volume: The volume of the position to create
        :type volume: str | float
        :param price: The limit price for ``limit`` orders and the trigger price for orders with
            ``ordertype`` one of ``stop-loss``, ``stop-loss-limit``, ``take-profit``, and ``take-profit-limit``
        :type price: str | float, optional
        :param price2: The limit price for ``stop-loss-limit`` and ``take-profit-limit`` orders
            The price2 can also be set to absolut or relative changes.
                * Prefixed using ``+`` or ``-`` defines the change in the quote asset
                * Prefixed by # is the same as ``+`` and ``-`` but the sign is set automatically
                * The percentage sign ``%`` can be used to define relative changes.
        :type price2: str | float, optional
        :param truncate: If enabled: round the ``price`` and ``volume`` to Kraken's
            maximum allowed decimal places. See https://support.kraken.com/hc/en-us/articles/4521313131540
            fore more information about decimals.
        :type truncate: bool, optional
        :param trigger: What triggers the position of ``stop-loss``, ``stop-loss-limit``, ``take-profit``, and
            ``take-profit-limit`` orders. Will also be used for associated conditional close orders.
            Kraken will use ``last`` if nothing is specified.
        :type trigger: str, optional
        :param leverage: The leverage
        :type leverage: str | float, optional
        :param reduce_only: Reduce existing orders (default: ``False``)
        :type reduce_only: bool, optional
        :param stptype: Define what cancels the order, one of ``cancel-newest``,
            ``cancel-oldest``, ``cancel-both`` (default: ``cancel-newest``)
        :type stptype: str, optional
        :param oflags: Order flags like ``post``, ``fcib``, ``fciq``, ``nomp``,
            ``viqc`` (see the referenced Kraken documentation for more information)
        :type oflags: str | List[str], optional
        :param timeinforce: how long the order remains in the orderbook, one of:
            ``GTC``, ``IOC``, ``GTD`` (see the referenced Kraken documentation for more information)
        :type timeinforce: str, optional
        :param displayvol: Define how much of the volume is visible in the orderbook (iceberg)
        :type displayvol: str | float, optional
        :param starttim: Unix timestamp or seconds defining the start time (default: ``"0"``)
        :type starttim: str, optional
        :param expiretm: Unix timestamp or time in seconds defining the expiration of the order,
            (default: ``"0"`` - i.e., no expiration)
        :type expiretm: str, optional
        :param close_ordertype: Conditional close order type, one of: ``limit``, ``stop-loss``,
            ``take-profit``, ``stop-loss-limit``, ``take-profit-limit``
            (see the referenced Kraken documentation for more information)
        :type close_ordertype: str, optional
        :param close_price: Conditional close price
        :type close_price: str | float, optional
        :param close_price2: The price2 for the conditional order - see the price2 parameter description
        :type close_price2: str | float, optional
        :param deadline: RFC3339 timestamp + {0..60} seconds that defines when the matching
            engine should reject the order.
        :type deadline: str, optional
        :param validate: Validate the order without placing on the market (default: ``False``)
        :type validate: bool, optional
        :param userref: User reference id for example to group orders
        :type userref: int, optional
        :raises ValueError: If input is not correct
        :return: The transaction id
        :rtype: dict

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Create a market order

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.create_order(
            ...     ordertype="market",
            ...     side="buy",
            ...     pair="XBTUSD",
            ...     volume="0.0001"
            ... )
            {
                'txid': ['TNGMNU-XQSRA-LKCWOK'],
                'descr': {
                    'order': 'buy 4.00000000 XBTUSD @ limit 23000.0'
                }
            }

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Create limit order

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.create_order(
            ...     ordertype="limit",
            ...     side="buy",
            ...     pair="XBTUSD",
            ...     volume=4,
            ...     price=23000,
            ...     expiretm=121,
            ...     displayvol=0.5,
            ...     oflags=["post", "fcib"]
            ... )
            {
                'txid': ['TPPI2H-CUZZ2-EQR2IE'],
                'descr': {
                    'order': 'buy 4.0000 XBTUSD @ limit 23000.0'
                }
            }

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Create a stop loss order

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.create_order(
            ...     ordertype="stop-loss",
            ...     pair="XBTUSD",
            ...     volume=20,
            ...     price=22000,
            ...     side="buy",
            ... )
            {
                'txid': ['THNUL1-8ZAS5-EEF3A8'],
                'descr': {
                    'order': 'buy 20.00000000 XBTUSD @ stop loss 22000.0'
                }
            }

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Create stop-loss-limit and take-profit-limit orders

            '''
            When the price hits $25000:
               1. A limit buy order will be placed at $24000 with 2x leverage.
               2. When the limit order gets closed/filled at $24000
                  The stop-loss-limit part is done and the tale-profit-limit
                  part begins.
               3. When the price hits $27000 a limit order will be placed at
                  $26800 to sell 1.2 BTC. This ensures that the asset will
                  be sold for $26800 or better.
            '''
            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> from datetime import datetime, timedelta, timezone
            >>> deadline = (
            ...     datetime.now(timezone.utc) + timedelta(seconds=20)
            ... ).isoformat()
            >>> trade.create_order(
            ...     ordertype="stop-loss-limit",
            ...     pair="XBTUSD",
            ...     side="buy",
            ...     volume=1.2,
            ...     price=24000,
            ...     price2=25000,
            ...     validate=True, # just validate the input, do not place on the market
            ...     trigger="last",
            ...     timeinforce="GTC",
            ...     leverage=4,
            ...     deadline=deadline,
            ...     close_ordertype="take-profit-limit",
            ...     close_price=27000,
            ...     close_price2=26800,
            ... )
            {
                'descr': {
                    'order': 'buy 0.00100000 XBTUSD @ stop loss 24000.0 -> limit 25000.0 with 2:1 leverage',
                    'close': 'close position @ take profit 27000.0 -> limit 26800.0'
                }
            }

            '''
            The price2 and close_price2 can also be set to absolut or relative changes.
                * Prefixed using "+" or "-" defines the change in the quote asset
                * Prefixed by # is the same as "+" and "-" but the sign is set automatically
                * The the percentage sign "%" can be used to define relative changes.
            '''
            >>> trade.create_order(
            ...     ordertype="stop-loss-limit",
            ...     pair="XBTUSD",
            ...     side="buy",
            ...     volume=1.2,
            ...     price=24000,
            ...     price2="+1000",
            ...     validate=True,
            ...     trigger="last",
            ...     timeinforce="GTC",
            ...     close_ordertype="take-profit-limit",
            ...     close_price=27000,
            ...     close_price2="#2%",
            ... )
            {
                'descr': {
                    'order': 'buy 0.00100000 XBTUSD @ stop loss 24000.0 -> limit +1000.0',
                    'close': 'close position @ take profit 27000.0 -> limit -2.0000%'
                }
            }
        """
        params: dict = {
            "ordertype": ordertype,
            "type": side,
            "pair": pair,
            "volume": volume
            if not truncate
            else self.truncate(amount=volume, amount_type="volume", pair=pair),
            "stp_type": stptype,
            "starttm": starttm,
            "validate": validate,
            "reduce_only": reduce_only,
        }

        trigger_ordertypes: tuple = (
            "stop-loss",
            "stop-loss-limit",
            "take-profit-limit",
            "take-profit-limit",
        )

        if defined(trigger):
            if ordertype not in trigger_ordertypes:
                raise ValueError(f"Cannot use trigger on ordertype {ordertype}!")
            params["trigger"] = trigger
        if defined(timeinforce):
            params["timeinforce"] = timeinforce
        if defined(expiretm):
            params["expiretm"] = str(expiretm)
        if defined(price):
            params["price"] = (
                price
                if not truncate
                else self.truncate(amount=price, amount_type="price", pair=pair)
            )
        if ordertype in ("stop-loss-limit", "take-profit-limit"):
            if not defined(price2):
                raise ValueError(
                    f"Ordertype {ordertype} requires a secondary price (price2)!",
                )
            params["price2"] = str(price2)
        elif price2 is not None:
            raise ValueError(
                f"Ordertype {ordertype} dos not allow a second price (price2)!",
            )
        if defined(leverage):
            params["leverage"] = str(leverage)
        if defined(oflags):
            params["oflags"] = oflags
        if defined(close_ordertype):
            params["close[ordertype]"] = close_ordertype
        if defined(close_price):
            params["close[price]"] = str(close_price)
        if defined(close_price2):
            params["close[price2]"] = str(close_price2)
        if defined(deadline):
            params["deadline"] = deadline
        if defined(userref):
            params["userref"] = userref
        if defined(displayvol):
            params["displayvol"] = str(displayvol)

        return self._request(  # type: ignore[return-value]
            method="POST",
            uri="/private/AddOrder",
            params=params,
        )

    def create_order_batch(
        self: Trade,
        orders: List[dict],
        pair: str,
        deadline: Optional[str] = None,
        validate: bool = False,
    ) -> dict:
        """
        Create a batch of max 15 orders for a specific asset pair.

        Requires the ``Create and modify orders`` permission in
        the API key settings.

        - https://docs.kraken.com/rest/#operation/addOrderBatch

        :param orders: Dictionary of order objects (see the referenced Kraken documentation for more information)
        :type orders: List[dict]
        :param pair: Asset pair to place the orders for
        :type pair: str
        :param deadline: RFC3339 timestamp + {0..60} seconds that defines when the matching engine should reject the order.
        :type deadline: str, optional
        :param validate: Validate the orders without placing them. (default: ``False``)
        :type validate: bool, optional
        :return: Information about the placed orders
        :rtype: dict

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Create a batch order

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.create_order_batch(orders=[
            ...         {
            ...             "close": {
            ...                 "ordertype": "stop-loss-limit",
            ...                 "price": 21000,
            ...                 "price2": 20000,
            ...             },
            ...             "ordertype": "limit",
            ...             "price": 25000,
            ...             "timeinforce": "GTC",
            ...             "type": "buy",
            ...             "userref": 16861348843,
            ...             "volume": 1,
            ...         },
            ...         {
            ...             "ordertype": "limit",
            ...             "price": 1000000,
            ...             "timeinforce": "GTC",
            ...             "type": "sell",
            ...             "userref": 16861348843,
            ...             "volume": 2,
            ...         },
            ...     ],
            ...     pair="BTC/USD"
            ... )
            {
                'orders': [{
                    'order': 'buy 1 BTCUSD @ limit 25000',
                    'txid': 'O5TLGX-DKKTU-WKRAZ5',
                    'close': 'close position @ stop loss 21000.0 -> limit 20000.0'
                }, {
                    'order': "sell 2 BTCUSD @ limit 1000000',
                    'txid': 'OBGFYP-XVQNL-P4GMWF'
                }]
            }
        """
        params: dict = {"orders": orders, "pair": pair, "validate": validate}
        if defined(deadline):
            params["deadline"] = deadline
        return self._request(  # type: ignore[return-value]
            method="POST",
            uri="/private/AddOrderBatch",
            params=params,
            do_json=True,
        )

    @ensure_string("oflags")
    def edit_order(  # noqa: PLR0913
        self: Trade,
        txid: str,
        pair: str,
        volume: Optional[Union[str, int, float]] = None,
        price: Optional[Union[str, int, float]] = None,
        price2: Optional[Union[str, int, float]] = None,
        truncate: bool = False,
        oflags: Optional[str] = None,
        deadline: Optional[str] = None,
        cancel_response: Optional[bool] = None,
        validate: bool = False,
        userref: Optional[int] = None,
    ) -> dict:
        """
        Edit an open order.

        Requires the ``Create and modify orders`` permission in
        the API key settings.

        - https://docs.kraken.com/rest/#operation/editOrder

        :param txid: The txid of the order to edit
        :type txid: str
        :param pair: The asset pair of the order
        :type pair: str
        :param volume: Set a new volume
        :type volume: str | int | float, optional
        :param price: Set a new price
        :type price: str | int | float, optional
        :param price2: Set a new second price
        :type price2: str | int | float, optional
        :param truncate: If enabled: round the ``price`` and ``volume`` to Kraken's
            maximum allowed decimal places. See https://support.kraken.com/hc/en-us/articles/4521313131540
            fore more information about decimals.
        :type truncate: bool, optional
        :param oflags: Order flags like ``post``, ``fcib``, ``fciq``, ``nomp``,
            ``viqc`` (see the referenced Kraken documentation for more information)
        :type oflags: str | List[str], optional
        :param deadline: (see the referenced Kraken documentation for more information)
        :type deadline: string
        :param cancel_response: See the referenced Kraken documentation for more information
        :type cancel_response: bool, optional
        :param validate: Validate the order without placing on the market (default: ``False``)
        :type validate: bool, optional
        :param userref: User reference id for example to group orders
        :type userref: int
        :return: Success or failure
        :rtype: dict

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Modify an order

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.edit_order(txid="OBGFYP-XVQNL-P4GMWF",
            ...     volume=0.75,
            ...     pair="XBTUSD",
            ...     price=1250000
            ... )
            {
                'status': 'ok',
                'txid': 'OFVXHJ-KPQ3B-VS7ELA',
                'originaltxid': 'OBGFYP-XVQNL-P4GMWF',
                'volume': '0.75',
                'price': '1250000',
                'orders_cancelled': 1,
                'descr': {
                    'order': 'sell 0.75 XXBTZUSD @ limit 1250000'
                }
            }
        """
        params: dict = {"txid": txid, "pair": pair, "validate": validate}
        if defined(userref):
            params["userref"] = userref
        if defined(volume):
            params["volume"] = (
                str(volume)
                if not truncate
                else self.truncate(amount=volume, amount_type="volume", pair=pair)
            )
        if defined(price):
            params["price"] = (
                str(price)
                if not truncate
                else self.truncate(amount=price, amount_type="price", pair=pair)
            )
        if defined(price2):
            params["price2"] = price2
        if defined(oflags):
            params["oflags"] = oflags
        if defined(cancel_response):
            params["cancel_response"] = cancel_response
        if defined(deadline):
            params["deadline"] = deadline
        return self._request(  # type: ignore[return-value]
            "POST",
            uri="/private/EditOrder",
            params=params,
        )

    @ensure_string("txid")
    def cancel_order(self: Trade, txid: str) -> dict:
        """
        Cancel a specific order by ``txid``. Instead of a transaction id
        a user reference id can be passed.

        Requires the ``Cancel/close orders`` permission in
        the API key settings.

        - https://docs.kraken.com/rest/#operation/cancelOrder

        :param txid: Transaction id or comma delimited list of user reference ids to cancel.
        :type txid: str
        :return: Success or failure - Number of closed orders
        :rtype: dict

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Cancel an order

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.cancel_order(txid="OAUHYR-YCVK6-P22G6P")
            { 'count': 1 }
        """
        return self._request(  # type: ignore[return-value]
            method="POST",
            uri="/private/CancelOrder",
            params={"txid": txid},
        )

    def cancel_all_orders(self: Trade) -> dict:
        """
        Cancel all open orders.

        Requires the ``Cancel/close orders`` permission in
        the API key settings.

        - https://docs.kraken.com/rest/#operation/cancelAllOrders

        :return: Success or failure - Number of closed orders
        :rtype: dict

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Cancel all open orders

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.cancel_all_orders()
            { 'count': 2 }
        """
        return self._request(  # type: ignore[return-value]
            method="POST",
            uri="/private/CancelAll",
        )

    def cancel_all_orders_after_x(self: Trade, timeout: int = 0) -> dict:
        """
        Cancel all orders after a timeout. This can be used as Dead Man's Switch.

        Requires the ``Create and modify orders`` permission in
        the API key settings.

        - https://docs.kraken.com/rest/#operation/cancelAllOrdersAfter

        :param timeout: Optional The timeout in seconds, deactivate by passing the default: ``0``
        :type timeout: int, optional
        :return: Current time and trigger time
        :rtype: dict

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Set the Death Man's Switch

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.cancel_all_orders_after_x(timeout=60)
            {
                'currentTime': '2023-04-06T06:51:56Z',
                'triggerTime': '2023-04-06T06:52:56Z'
            }
        """
        return self._request(  # type: ignore[return-value]
            method="POST",
            uri="/private/CancelAllOrdersAfter",
            params={"timeout": timeout},
        )

    def cancel_order_batch(self: Trade, orders: List[Union[str, int]]) -> dict:
        """
        Cancel a a list of orders by ``txid`` or ``userref``

        Requires the ``Cancel/close orders`` permission in
        the API key settings.

        - https://docs.kraken.com/rest/#operation/cancelOrderBatch

        :param orders: List of orders to cancel
        :type orders: List[str | int]
        :return: Success or failure - Number of closed orders
        :rtype: dict

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Cancel multiple orders

            >>> from kraken.spot import Trade
            >>> trade = Trade(key="api-key", secret="secret-key")
            >>> trade.cancel_order_batch(
            ...     orders=["OG5IL4-6AR7I-ZAPZEZ", "OAUHYR-YCVK6-P22G6P"]
            ... )
            { count': 2 }
        """
        return self._request(  # type: ignore[return-value]
            method="POST",
            uri="/private/CancelOrderBatch",
            params={"orders": orders},
            do_json=True,
        )

    @lru_cache()
    def truncate(
        self: Trade,
        amount: Union[Decimal, float, str],
        amount_type: str,
        pair: str,
    ) -> str:
        """
        Kraken only allows volume and price amounts to be specified with a specific number of
        decimal places, and these vary depending on the currency pair used.

        This function converts an amount of a specific type and pair to a string that uses
        the correct number of decimal places.

        - https://support.kraken.com/hc/en-us/articles/4521313131540

        This function uses caching. Run ``truncate.clear_cache()`` to clear.

        :param amount: The floating point number to represent
        :type amount: Decimal | float | str
        :param amount_type: What the amount represents. Either ``"price"`` or ``"volume"``
        :type amount_type: str
        :param pair: The currency pair the amount is in reference to.
        :type pair: str
        :raises ValueError: If the ``amount_type`` is ``price`` and the price is less
            than the costmin.
        :raises ValueError: If the ``amount_type`` is ``volume`` and the volume is
            less than the ordermin.
        :raises ValueError: If no valid ``amount_type`` was passed.
        :return: A string representation of the amount.
        :rtype: str

        .. code-block:: python
            :linenos:
            :caption: Spot Trade: Truncate

            >>> print(trade.truncate(
            ...     amount=0.123456789,
            ...     amount_type="volume",
            ...     pair="XBTUSD"
            ... ))
            0.12345678

            >>> print(trade.truncate(
            ...     amount=21123.12849829993,
            ...     amount_type="price",
            ...     pair="XBTUSD")
            ... ))
            21123.1

            >>> print(trade.truncate(
            ...     amount=0.1,
            ...     amount_type="volume",
            ...     pair="XBTUSD"
            ... ))
            0.10000000

            >>> print(trade.truncate(
            ...     amount=21123,
            ...     amount_type="price",
            ...     pair="XBTUSD"
            ... ))
            21123.0
        """
        if amount_type not in ("price", "volume"):
            raise ValueError("Amount type must be 'volume' or 'price'!")

        pair_data: dict = self.__market.get_asset_pairs(pair=pair)
        data: dict = pair_data[next(iter(pair_data))]

        pair_decimals: int = int(data["pair_decimals"])
        lot_decimals: int = int(data["lot_decimals"])

        ordermin: Decimal = Decimal(data["ordermin"])
        costmin: Decimal = Decimal(data["costmin"])

        amount = Decimal(amount)
        decimals: int

        if amount_type == "price":
            if costmin > amount:
                raise ValueError(f"Price is less than the costmin: {costmin}!")
            decimals = pair_decimals
        else:  # amount_type == "volume":
            if ordermin > amount:
                raise ValueError(f"Volume is less than the ordermin: {ordermin}!")
            decimals = lot_decimals

        amount_rounded: float = floor(float(amount) * 10**decimals) / 10**decimals
        return f"{amount_rounded:.{decimals}f}"

__all__ = ["Trade"]


# 导入opencv工具包
import cv2
# 导入numpy
import numpy as np
# 导入姿势识别器
from PoseDetector import PoseDetector

detector = PoseDetector()

# 方向与个数
squatdir = 0  # 0为站立，1为蹲下
squatcount = 0

def squat(decimg):
    global squatcount,squatdir
    # 读取摄像头，img为每帧图片
    img = decimg

    h, w, c = img.shape
    # 识别姿势
    img = detector.find_pose(img, draw=True)
    # 获取姿势数据
    positions = detector.find_positions(img)

    if positions:
        # 获取下蹲的角度
        angle = detector.find_angle(img, 24, 26, 28)
        # 进度条长度
        bar = np.interp(angle, (50, 170), (w // 2 - 100, w // 2 + 100))
        cv2.rectangle(img, (w // 2 - 100, h - 150),
                      (int(bar), h - 100), (0, 255, 0), cv2.FILLED)
        # 角度小于55度认为下蹲
        if angle <= 55:
            if squatdir == 0:
                squatcount  = squatcount  + 0.5
                squatdir = 1
        # 角度大于120度认为站立
        if angle >= 120:
            if squatdir == 1:
                squatcount = squatcount + 0.5
                squatdir = 0
        cv2.putText(img, str(int(squatcount)), (w // 2, h // 2),
                    cv2.FONT_HERSHEY_SIMPLEX, 10, (255, 255, 255), 20, cv2.LINE_AA)

    # 打开一个Image窗口显示视频图片
    cv2.imshow('Image', img)


import sys
import os
import os.path
import shutil

from cx_Freeze import setup, Executable

# Remove the existing folders folder
shutil.rmtree("build", ignore_errors=True)
shutil.rmtree("dist", ignore_errors=True)

sys.path.append(os.path.dirname(__file__))

###############################################################################
# Here is a list of the Executable options
###############################################################################
#
# "script":
#       the name of the file containing the script which is to be frozen
#
# "initScript":
#       the name of the initialization script that will be executed before
#       the actual script is executed; this script is used to set up the
#       environment for the executable; if a name is given without an absolute
#       path the names of files in the initscripts subdirectory of
#       the cx_Freeze package is searched
#
# "base":
#       the name of the base executable;
#       if a name is given without an absolute path the names of files
#       in the bases subdirectory of the cx_Freeze package is searched
#
# "path":
#       list of paths to search for modules
#
# "targetDir":
#       the directory in which to place the target executable
#       and any dependent files
#
# "targetName":
#       the name of the target executable; the default value is the name
#       of the script with the extension exchanged with the extension
#       for the base executable
#
# "includes":
#       list of names of modules to include
#
# "excludes":
#       list of names of modules to exclude
#
# "packages":
#       list of names of packages to include, including all
#       of the package's submodules
#
# "replacePaths":
#       Modify filenames attached to code objects, which appear
#       in tracebacks. Pass a list of 2-tuples containing paths to
#       search for and corresponding replacement values. A search for
#       '*' will match the directory containing the entire package,
#       leaving just the relative path to the module.
#
# "compress":
#       boolean value indicating if the module bytecode
#       should be compressed or not
#
# "copyDependentFiles":
#       boolean value indicating if dependent files should be
#       copied to the target directory or not
#
# "appendScriptToExe":
#       boolean value indicating if the script module should be
#       appended to the executable itself
#
# "appendScriptToLibrary":
#       boolean value indicating if the script module should be
#       appended to the shared library zipfile
#
# "icon":
#       name of icon which should be included in the executable
#       itself on Windows or placed in the target directory
#       for other platforms
#
# "namespacePackages":
#       list of packages to be treated as namespace packages
#       (path is extended using pkgutil)
#
# "shortcutName":
#       the name to give a shortcut for the executable when
#       included in an MSI package
#
# "shortcutDir":
#       the directory in which to place the shortcut when being
#       installed by an MSI package; see the MSI Shortcut table
#       documentation for more information on what values
#       can be placed here.
#
###############################################################################
MY_TARGET_EXE = Executable(
    # what to build
    script="iextract.py",
    initScript=None,
    # base='Win32GUI',
    base='Console',
    #  targetDir = r"dist",
    targetName="inkscape_extract.exe",
    #  compress = True,
    #  copyDependentFiles = True,
    #  appendScriptToExe = False,
    #  appendScriptToLibrary = False,
    icon=os.path.join(os.path.dirname(__file__), '..',
                      'nsis', 'icon', 'inkscape.ico'),
    trademarks="Florent Tournois @2017"
)

###############################################################################
# Here is a list of the build_exe options
###############################################################################
# 1) append the script module to the executable
APPEND_SCRIPT_TO_EXE = False
# 2) the name of the base executable to use which, if given as a relative
#       path, will be joined with the bases subdirectory of the cx_Freeze
#       installation; the default value is "Console"
BASE = "Console"
# 3) list of names of files to exclude when determining dependencies of
#       binary files that would normally be included; note that version
#       numbers that normally follow the shared object extension are
#       stripped prior to performing the comparison
BIN_EXCLUDES = []
# 4) list of names of files to include when determining dependencies of
#       binary files that would normally be excluded; note that version
#       numbers that normally follow the shared object extension are
#       stripped prior to performing the comparison
BIN_INCLUDES = []
# 5) list of paths from which to exclude files when determining
#       dependencies of binary files
BIN_PATH_EXCLUDES = []
# 6) list of paths from which to include files when determining
#       dependencies of binary files
BIN_PATH_INCLUDES = []
# 7) directory for built executables and dependent files,
#       defaults to build/
BUILD_EXE = "../../distribution/"
# 8) create a compressed zip file
COMPRESSED = False
# 9) comma separated list of constant values to include in the constants
#       module called BUILD_CONSTANTS in form <name>=<value>
CONSTANTS = []
# 10) copy all dependent files
COPY_DEPENDENT_FILES = True
# 11) create a shared zip file called library.zip which will contain
#       all modules shared by all executables which are built
CREATE_SHARED_ZIP = True
# 12) comma separated list of names of modules to exclude
EXCLUDES = ['Tkinter', 'email', 'unittest']
# 13) include the icon in the frozen executables on the Windows
#       platform and alongside the frozen executable on other platforms
ICON = os.path.join(os.path.dirname(__file__), '..',
                    'packaging', 'icon', 'ge.ico')
# 13) comma separated list of names of modules to include
INCLUDES = ['inkscape', 'lxml', 'bs4']
# 15) list containing files to be copied to the target directory;
#       it is expected that this list will contain strings or
#           2-tuples for the source and destination;
#       the source can be a file or a directory (in which case
#           the tree is copied except for .svn and CVS directories);
#       the target must not be an absolute path
#
# NOTE: INCLUDE FILES MUST BE OF THIS FORM OTHERWISE freezer.py line
#       128 WILL TRY AND DELETE dist/. AND FAIL!!!
# Here is a list of ALL the DLLs that are included in Python27\Scripts
INCLUDE_FILES = [
    ("inkscape\\template\\", "template\\"),
]
# 16) include the script module in the shared zip file
INCLUDE_IN_SHARED_ZIP = True
# 17) include the Microsoft Visual C runtime DLLs and (if necessary)
#       the manifest file required to run the executable without
#       needing the redistributable package installed
INCLUDE_MSVCR = False
# 18) the name of the script to use during initialization which,
#       if given as a relative path, will be joined with the initscripts
#       subdirectory of the cx_Freeze installation;
#       the default value is "Console"
INIT_SCRIPT = ""
# 19) comma separated list of packages to be treated as
#       namespace packages (path is extended using pkgutil)
NAMESPACE_PACKAGES = []
# 20) optimization level, one of 0 (disabled), 1 or 2
OPTIMIZE = 0
# 21) comma separated list of packages to include, which includes
#       all submodules in the package
PACKAGES = ['lxml', 'gzip']
# 22) comma separated list of paths to search; the default value is sys.path
PATH = sys.path + [os.path.dirname(__file__)]
# 23) Modify filenames attached to code objects, which appear in tracebacks.
#       Pass a comma separated list of paths in the form <search>=<replace>.
#       The value * in the search portion will match the directory
#       containing the entire package, leaving just the
#       relative path to the module.
REPLACE_PATHS = []
# 24) suppress all output except warnings
SILENT = False
# 25) list containing files to be included in the zip file directory;
#       it is expected that this list will contain strings or
#       2-tuples for the source and destination
ZIP_INCLUDES = []

LOCAL_OPTIONS = {
    #                            "append_script_to_exe": APPEND_SCRIPT_TO_EXE,
    #                            "base":                 BASE,
    #                            "bin_excludes":         BIN_EXCLUDES,
    #                            "bin_includes":         BIN_INCLUDES,
    #                            "bin_path_excludes":    BIN_PATH_EXCLUDES,
    #                            "bin_path_includes":    BIN_PATH_INCLUDES,
    "build_exe": BUILD_EXE,
    #  "compressed":           COMPRESSED,
    #                            "constants":            CONSTANTS,
    #  "copy_dependent_files": COPY_DEPENDENT_FILES,
    #                            "create_shared_zip":    CREATE_SHARED_ZIP,
    "excludes": EXCLUDES,
    #  "icon":                 ICON,
    "includes": INCLUDES,
    "include_files": INCLUDE_FILES,
    #                            "include_in_shared_zip":INCLUDE_IN_SHARED_ZIP,
    #                            "include_msvcr":        INCLUDE_MSVCR,
    #                            "init_script":          INIT_SCRIPT,
    #                            "namespace_packages":   NAMESPACE_PACKAGES,
    #                            "optimize":             OPTIMIZE,
    "packages": PACKAGES,
    "path": PATH,
    #                            "replace_paths":        REPLACE_PATHS,
    #                            "silent":               SILENT,
    #                            "zip_includes":         ZIP_INCLUDES,
}

setup(
    name="Inkscape Extract",
    version="0.1",
    description="Inkscape Extract",
    author="Florent Tournois",
    options={"build_exe": LOCAL_OPTIONS},
    executables=[MY_TARGET_EXE]
)


import requests
import json
import os
def get_pic_url(num):
    pic_url= []
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'}
    for i in range(num):

        page_url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E5%9B%BE%E7%89%87&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&word=%E5%9B%BE%E7%89%87&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&pn={}&rn=30&gsm=1e&1561022599290='.format(30*i)
        r = requests.get(page_url, headers=headers).text
        res = json.loads(r)['data']
        if res:
            print(res)
            for j in res:
                try:
                    url = j['hoverURL']
                    pic_url.append(url)
                except:
                    print('该图片的url不存在')

    print(len(pic_url))
    return pic_url

def down_img(num):
    pic_url  =get_pic_url(num)

    if os.path.exists('D:\图片'):
        pass
    else:
        os.makedirs('D:\图片')

    path = 'D:\图片\\'
    for index,i in enumerate(pic_url):
        filename = path +   str(index) + '.jpg'
        print(filename)
        with open(filename, 'wb+') as f:
            f.write(requests.get(i).content)
if __name__ == '__main__':
    num = int(input('爬取几次图片：一次30张'))
    down_img(num)


import nltk
import re

def main():
    nltk.download('words')
    all_words = nltk.corpus.words.words()

    word = word_entry(1)
    check = check_word(word)
    guesses = compile_guesses(all_words, word, check)
    print_guesses(guesses)

def word_entry(n):
    while True:
        word = input(f"Enter word {n}: ")
        if len(word) == 5:
            return word
        print("Length of word is not 5, please enter a 5 letter word")

def check_word(word):
    print(word.upper())
    print("\nEnter (G)reen, (Y)ellow, or (N)ot for each character:\n")
    result = []
    for c in word.upper():
        inp = input(f"{c}: ").lower()
        if inp != 'g' and inp != 'y' and inp !='n':
            inp = 'n'
        result.append(inp)
    return result

def compile_guesses(all_words, word, check):
    yellows = []
    re_str = r'^'
    for i, c in enumerate(word):
        if check[i] == 'g': # Green (match)
            re_str += c
        elif check[i] == 'y': # Yellow (in word)
            yellows.append(c)
            re_str += r'\w'
        else: # Unknown (any character)
            re_str += r'\w'
    re_str += r'$'

    r = re.compile(re_str)

    matched_words = list(filter(r.match, all_words))

    for y in yellows:
        matched_words = list(filter(lambda x: y in x, matched_words))

    return matched_words

def print_guesses(guesses):
    print("\nGuesses: ")
    print("------------------------------")
    for g in guesses:
        print(g, end=' ')
    print("\n------------------------------")

if __name__ == "__main__":
    main()


import socket
import time
import json
import random

# import subprocess

# _ = subprocess.call("route add 10.255.255.255 dev client1-eth0", shell=True)
# _ = subprocess.call("route add 10.255.255.255 dev client1-eth1", shell=True)
# _ = subprocess.call("ifconfig client1-eth1 10.0.0.10 netmask 255.0.0.0 broadcast 10.255.255.255", shell=True)

tx_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
rx_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

tx_socket.bind(("", 8008))  # only to prevent icmp "not reachable"

rx_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
rx_socket.connect(("10.255.255.255", 8016))
# rx_socket.connect(("127.0.0.1", 8004))

cnt: int = 0
loop: int = 0
data = []
for i in range(0, 20):
    data.append(random.randint(a=0, b=1000))
_: str = ""
file = None

# try:
#     file = open("/tmp/log/client.LOG", "w")
#     file.write(f"Client started at {time.time()}")
#     _ = "logfile found"
# except Exception:
#     _ = "no logfile"
#     pass

print(f"starting client, {_}")
while True:
    try:
        msg = json.dumps(
            [
                {
                    "message": f"packet{loop}",
                    "type": "DATA",
                    "time": f"{time.time()}",
                    "data": data,
                }
            ],
            sort_keys=True,
            # indent=4,
            separators=(",", ": "),
        )
        rx_socket.sendall(msg.encode())

        # try:
        #     file = open("/tmp/log/client.txt", "w")
        #     file.write(f"sent msg, time : {time.time()}")
        #     file.close()
        # except Exception:
        #     pass

        if loop < 5:
            loop += 1
        else:
            loop = 0
        # data, addr = tx_socket.recvfrom(4096)  # use select.select() or sock.timeout() to only wait for recv time X
        # print(data)

        # try:
        #     file = open("/tmp/log/client.txt", "w")
        #     file.write(f"received msg : {data} from {addr}, time : {time.time()}")
        #     file.close()
        # except Exception:
        #     pass

        time.sleep(5)
    except Exception:
        # file.close()
        cnt += 1
        if cnt > 5:
            print("abort client")
            break


'''
训练神经网络，并画出其损失曲线
'''

import os
import pickle
import matplotlib.pyplot as plt
from py_model.NN_model import *
from py_model.MNIST_data import *

INPUT_MODE=784
OUTPUT_MODE=10
LAYER_MODE=500
L1=0
L2=0.1
LEARNING_STEPS=1500
LEARNING_RATE=0.001
LEARNING_RATE_DECAY=0.00001
N_BATCHES=60
ALPHA=0.001

class NoModelError(Exception):
	pass

def train(filename='nn1.pkl',replace=False):
	filepath=os.path.join('../data/model/py',filename)
	if os.path.exists(filepath) and replace is False:
		print(f'模型文件：{filepath} 已经存在！')
	else:
		mnist=Mnist('../data/MNIST_uncompressed')
		x=np.where(mnist.train_images>0.4,1,0)
		y_=mnist.train_labels
		nn=NeuralNet(
					INPUT_MODE, OUTPUT_MODE, LAYER_MODE, L1, L2,
					LEARNING_STEPS, LEARNING_RATE, N_BATCHES,
					LEARNING_RATE_DECAY, ALPHA
					)
		nn.train(x,y_)
		with open(filepath,'wb') as f:
			pickle.dump(nn,f)
		show_cost(nn.cost_)

def show_cost(cost):
	plt.figure(figsize=(8,5))
	plt.plot(range(len(cost)),cost)
	plt.ylabel('Cost')
	plt.xlabel('Step')
	plt.tight_layout()
	plt.show()

def load_model(filename='nn1.pkl'):
	filepath=os.path.join('../data/model/py',filename)
	if os.path.exists(filepath):
		with open(filepath,'rb') as f:
			nn=pickle.load(f)
		return nn
	else:
		raise NoModelError(f'需加载的模型文件： {filepath} 不存在！')

def main():
	train()
	input()

if __name__=='__main__':
	main()


import ipaddress
file_mhl = open('./mhl.txt')
try:
    mhl = file_mhl.read()
finally:
    file_mhl.close()

with open('./check_result/temp_file.txt') as file_object:
    for line in file_object:
        line = line[:-1]
        for temp in ipaddress.ip_network(line).hosts():
            if str(temp) in mhl:
                print("Find this:" + str(temp) + " from " + str(line))
                break


from matplotlib.pyplot import cla
from Data_Process import *
import torch

import sys
sys.path.append('D:\OneDrive - mail.nwpu.edu.cn\Optimal\Public\Python\Pre_Process')
from Data_Process import *
import torch as th
import math
from torch.nn.parameter import Parameter
from torch.nn.modules.module import Module
import random
from torch_geometric.nn import TransformerConv,GATConv,HeteroConv
import torch.nn.functional as F

from torch_geometric.nn import Linear, HGTConv
from my_hetero_conv import AttentHeteroConv

from torch_geometric.data import HeteroData
import torch_geometric.transforms as T
class GraphConvolution(Module):
    """
    Simple pygGCN layer, similar to https://arxiv.org/abs/1609.02907
    """

    def __init__(self, in_features, out_features, bias=True):
        super(GraphConvolution, self).__init__()
        self.in_features = in_features
        self.out_features = out_features
        self.weight = Parameter(th.FloatTensor(in_features, out_features))
        if bias:
            self.bias = Parameter(th.FloatTensor(out_features))
        else:
            self.register_parameter('bias', None)
        self.reset_parameters()

    def reset_parameters(self):
        stdv = 1. / math.sqrt(self.weight.size(1))
        self.weight.data.uniform_(-stdv, stdv)
        if self.bias is not None:
            self.bias.data.uniform_(-stdv, stdv)

    def forward(self, infeatn, adj):
        support = th.spmm(infeatn, self.weight)
        output = th.spmm(adj, support)
        if self.bias is not None:
            return output + self.bias
        else:
            return output

    def __repr__(self):
        return self.__class__.__name__ + ' (' \
               + str(self.in_features) + ' -> ' \
               + str(self.out_features) + ')'

class myGAE(torch.nn.Module):
    def __init__(self, data):
        super(myGAE, self).__init__()

        self.decoder_1 = torch.nn.Sequential(torch.nn.Linear(300, 300)).to('cuda:0')
        self.decoder_2 = torch.nn.Sequential(torch.nn.Linear(300, 300)).to('cuda:0')

        self.lin_dict = torch.nn.ModuleDict()
        for node_type in data.node_types:
            self.lin_dict[node_type] = Linear(-1, 300).to('cuda:0')

        self.conv_0 = HeteroConv({
            ('meta', 'is_concept_stock_of', "meta"): TransformerConv(300, 300, heads = 2, concat=False, beta=False),
            ('source_emb', 'is_source_of', "meta"): TransformerConv(300, 300, heads = 2, concat=False, beta=False),
            ("meta", "rev_is_source_of", "source_emb"): TransformerConv(300, 300, heads = 2, concat=False, beta=False),
        }, aggr = "sum").to('cuda:0')

        self.linear_a = torch.nn.Linear(300, 300).to('cuda:0')
        self.linear_b = torch.nn.Linear(300,300).to('cuda:0')
        # self.lin = Linear(300, 300)

        self.self_attention_1 = TransformerConv(300, 300, heads = 1, concat=False, beta=False).to('cuda:1')
        self.self_attention_2 = TransformerConv(300, 300, heads = 1, concat=False, beta=False).to('cuda:1')

    def Encoder(self, edge_concept, H_0, H_a, hetro_data, edge_a, edge_b):
        x_dict = hetro_data.x_dict
        edge_index_dict = hetro_data.edge_index_dict

        H_0 = self.self_attention_1(H_0.to('cuda:1'), edge_a.to('cuda:1'))
        H_a = self.self_attention_2(H_a.to('cuda:1'), edge_b.to('cuda:1'))

        # H_0 = self.linear_a(H_0.to('cuda:0'))
        # H_a = self.linear_b(H_a.to('cuda:0'))
        H_ens = H_0+H_a
        H_0 = F.normalize(H_0, dim=-1, p=2)
        H_a = F.normalize(H_a, dim=-1, p=2)
        H_ens = F.normalize(H_ens, dim=-1, p=2)

        x_dict['source_emb'] = torch.cat([H_0.to('cuda:0'), H_a.to('cuda:0')],dim=0).to('cuda:0')

        x_dict['meta'] = H_ens.to('cuda:0')

        # print(x_dict)
        # print(test)

        x_dict = self.conv_0(x_dict, edge_index_dict)

        representation = (x_dict['meta'])+H_ens.to('cuda:0')
        representation = F.normalize(representation, dim=-1, p=2)
        return representation

    def loss(self, H_2, batch_data, H_0, H_a):
        H_0 = H_0.to('cuda:0')
        H_a = H_a.to('cuda:0')

        concept_idxs = [x[0] for x in batch_data]
        pos_idxs = [x[1] for x in batch_data]
        neg_idxs = [x[2] for x in batch_data]

        emb_concept = H_2[concept_idxs]
        emb_pos_stock = H_2[pos_idxs]
        emb_neg_stock = H_2[neg_idxs]

        triplet_loss = torch.nn.TripletMarginLoss(margin=0.01, p=2)
        graph_loss = triplet_loss(emb_concept, emb_pos_stock, emb_neg_stock)

        # if self.training == False:
        #     print("debug")
        #     print(graph_loss)
        recon_loss = torch.nn.MSELoss()

        recon_H_0 = self.decoder_1(H_2)
        recon_H_a = self.decoder_2(H_2)

        recon_H_0 = F.normalize(recon_H_0, dim=-1, p=2)
        recon_H_a = F.normalize(recon_H_a, dim=-1, p=2)

        batch_size = 128
        sample_idx = random.sample(range(recon_H_0.shape[0]), batch_size)

        recon_loss_1 =  recon_loss(recon_H_0[sample_idx], H_0[sample_idx])
        recon_loss_2 = recon_loss(recon_H_a[sample_idx], H_a[sample_idx])

        alpha = 0.5
        loss = (1-alpha)*recon_loss_1+ alpha*recon_loss_2+ 0.001* graph_loss
        # loss = (1-alpha)*recon_loss_1+ alpha*recon_loss_2
        return loss

    def forward(self, concept_edge, H_0, H_a, batch_data, hetro_data, edge_a, edge_b):
        Latent_Representation = self.Encoder(concept_edge, H_0, H_a, hetro_data, edge_a, edge_b)
        loss = self.loss(Latent_Representation, batch_data, H_0, H_a)
        return loss, Latent_Representation


# -*- coding: utf-8 -*-
def application(environ, start_response):
    if environ["PATH_INFO"] == "/":
        respuesta = "
Página inicial
"
    elif environ["PATH_INFO"] == "/hola":
        respuesta = "
Bienvenidos a mi página web
"
    else:
        respuesta = "
<trong>Página incorrecta
"
    start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])
    return respuesta

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    srv = make_server('localhost', 8080, application)
    srv.serve_forever()


#!/usr/bin/env python3
import os
import socket
import sys
import time

from PyQt5 import QtCore
from PyQt5.QtCore import QSize, pyqtSignal, Qt
from PyQt5.QtCore import QThread, QTimer
from PyQt5.QtGui import QIcon, QPixmap, QTransform
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton, QLabel, QMainWindow, QSlider
from pynput.keyboard import Listener

import rospy
from sensor_msgs.msg import Joy
from duckietown_msgs.msg import BoolStamped

HZ = 30
SCREEN_SIZE = 300
KEY_LEFT = 'left'
KEY_RIGHT = 'right'
KEY_UP = 'up'
KEY_DOWN = 'down'
KEY_A = 'a'
KEY_Q = 'q'
KEY_S = 's'
KEY_I = 'i'
KEY_E = 'e'
KEY_P = 'p'

Keys = {
    'Key.up': KEY_UP,
    'Key.down': KEY_DOWN,
    'Key.left': KEY_LEFT,
    'Key.right': KEY_RIGHT,
    KEY_A: KEY_A,
    KEY_Q: KEY_Q,
    KEY_S: KEY_S,
    KEY_I: KEY_I,
    KEY_E: KEY_E,
    KEY_P: KEY_P
}

speed_tang = 1.0
speed_norm = 1.0
time_to_wait = 10000
estop_deadzone_secs = 0.5
e_stop = False

class ROSManager(QThread):

    def __init__(self, parent):
        QThread.__init__(self, parent)
        self._parent = parent
        rospy.init_node('virtual_joy', anonymous=False)
        self.sub_estop = rospy.Subscriber(
            "~emergency_stop",
            BoolStamped,
            self.cbEStop,
            queue_size=1
        )
        self.pub_joystick = rospy.Publisher(
            "~joy",
            Joy,
            queue_size=1
        )
        self.pub_int = rospy.Publisher(
            "~intersection_go",
            BoolStamped,
            queue_size=1
        )
        self.commands = set()
        self.standing = False
        self.estop_last_time = time.time()
        self.last_ms = 0
        self.emergency_stop = False
        self._is_shutdown = False

    def shutdown(self):
        self._is_shutdown = True

    def cbEStop(self, estop_msg):
        """
        Callback that process the received :obj:`BoolStamped` messages.
        Args:
            estop_msg (:obj:`BoolStamped`): the emergency_stop message to process.
        """
        global e_stop
        e_stop = self.emergency_stop = estop_msg.data

    def run(self):
        while not self._is_shutdown:
            ms_now = int(round(time.time() * 1000))

            try:
                if ms_now - self.last_ms > time_to_wait:
                    rospy.get_master().getSystemState()
                    self.last_ms = ms_now
            except socket.error:
                print("Error starting main loop in virtual joystick gui")

            msg = self.get_raw_message()
            force_joy_publish = self._parent.inFocus

            # Arrows events
            if KEY_LEFT in self.commands:
                msg.axes[3] += speed_norm

            if KEY_RIGHT in self.commands:
                msg.axes[3] -= speed_norm

            if KEY_UP in self.commands:
                msg.axes[1] += speed_tang

            if KEY_DOWN in self.commands:
                msg.axes[1] -= speed_tang

            if KEY_A in self.commands:
                msg.buttons[7] = 1

            if KEY_S in self.commands:
                msg.buttons[6] = 1

            if KEY_I in self.commands:
                msg.buttons[3] = 1

            if KEY_P in self.commands:
                msg_int = BoolStamped()
                msg_int.data = True
                self.pub_int.publish(msg_int)

            if KEY_E in self.commands and \
                    (time.time() - self.estop_last_time > estop_deadzone_secs):
                msg.buttons[3] = 1
                self.estop_last_time = time.time()
                force_joy_publish = True

            if KEY_Q in self.commands:
                print('Received shutdown request (Event `Q` button down).')
                self.shutdown()
                self._parent.shutdown()

            stands = (sum(map(abs, msg.axes)) == 0 and sum(map(abs, msg.buttons)) == 0)

            if not stands or not self.standing or force_joy_publish:
                self.pub_joystick.publish(msg)

            self.standing = stands

            time.sleep(1 / HZ)

    def action(self, commands):
        self.commands = commands

    @staticmethod
    def get_raw_message():
        return Joy(
            axes=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
            buttons=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        )

class MyKeyBoardThread(QThread):
    key_board_event = pyqtSignal(object)

    def __init__(self, parent):
        QThread.__init__(self, parent)
        self._parent = parent
        self.listener = None
        self.commands = set()

    def add_listener(self, listener):
        self.key_board_event.connect(listener)

    def on_press(self, key):
        if not self._parent.inFocus:
            return
        key_val = str(key)
        if len(key_val) == 3:
            key_val = key_val[1]
        if key_val in Keys:
            self.commands.add(Keys[key_val])
        self.key_board_event.emit(self.commands)

    def on_release(self, key):
        if not self._parent.inFocus:
            return
        key_val = str(key)
        if len(key_val) == 3:
            key_val = key_val[1]
        if key_val in Keys:
            self.commands.discard(Keys[key_val])
        self.key_board_event.emit(self.commands)

    def run(self):
        with Listener(on_press=self.on_press, on_release=self.on_release) as listener:
            self.listener = listener
            self.listener.join()

    def shutdown(self):
        self.listener.stop()
        self.quit()

class MainWindow(QMainWindow):

    def __init__(self, title, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        script_path = os.path.dirname(__file__)
        self.script_path = (script_path + "/") if script_path else ""
        self.setWindowTitle(title)
        self.setWindowIcon(QIcon(self.script_path + '../images/logo.png'))
        self._hasfocus = False

        # ros class
        self.ros = ROSManager(self)
        self.ros.start()
        # Key board
        self.key_board_event = MyKeyBoardThread(self)
        self.key_board_event.add_listener(self.visual_joystick)
        self.key_board_event.start()
        # UI JOYSTICK
        self.widget = Joystick(self)
        self.widget.ros_fun.connect(self.visual_joystick)
        self.resize(self.widget.pixmap.width() + 20, self.widget.pixmap.height())
        self.setFixedSize(self.widget.pixmap.width() + 20, self.widget.pixmap.height())
        ####
        self.setCentralWidget(self.widget)
        self.ros_commands = set()
        self.was_added_new_key = False
        self.widget.change_state()
        self.installEventFilter(self)

    def eventFilter(self, object, event):
        if event.type() in [QtCore.QEvent.WindowActivate, QtCore.QEvent.WindowDeactivate, QtCore.QEvent.FocusIn, QtCore.QEvent.FocusOut]:
            self._hasfocus = (event.type() in [QtCore.QEvent.WindowActivate, QtCore.QEvent.FocusIn])
            self.widget.change_state()
        # ---
        return False

    @property
    def inFocus(self):
        return self._hasfocus

    def visual_joystick(self, commands):
        active = self.isActiveWindow()
        if active and self.inFocus:
            self.widget.light_d_pad(commands)
            if commands:
                self.ros.action(commands)

    def shutdown(self):
        self.ros.shutdown()
        self.key_board_event.shutdown()
        self.close()

class Joystick(QWidget):
    ros_fun = pyqtSignal(set)

    def __init__(self, parent, *args, **kwargs):
        super(Joystick, self).__init__(*args, **kwargs)
        self._parent = parent
        # GUI stuff init
        self.label_up = None
        self.label_left = None
        self.label_down = None
        self.label_right = None
        self.label_stop = None
        self.main_label = None
        self.label_publisher = None
        self.pixmap = None
        # state init
        self.state_right = True
        self.state_left = True
        self.state_down = True
        self.state_up = True
        # ---
        script_path = os.path.dirname(__file__)
        self.script_path = (script_path + "/") if script_path else ""
        self.initUI()
        self.command = set()
        self.timer = QTimer()
        self.timer.timeout.connect(self.timer_fun)

    def timer_fun(self):
        self.ros_fun.emit(self.command)

    def on_press_timer(self):
        self.timer.start(int(1000 / HZ))

    def on_release_timer(self):
        self.timer.stop()
        self.command.clear()
        self.ros_fun.emit(set())

    def initUI(self):
        self.main_label = QLabel(self)
        self.pixmap = QPixmap(self.script_path + '../images/d-pad.png')
        self.pixmap = self.pixmap.scaled(SCREEN_SIZE, SCREEN_SIZE, Qt.KeepAspectRatio)
        self.main_label.setPixmap(self.pixmap)
        self.resize(SCREEN_SIZE, SCREEN_SIZE)
        # NOTE: if SCREEN_SIZE changed, need to change funs for buttons
        self.create_up_button()
        self.create_left_button()
        self.create_right_button()
        self.create_down_button()
        self.create_d_pad()
        self.create_slider()

    def create_slider(self):
        self.sld = QSlider(Qt.Vertical, self)
        self.sld.setFocusPolicy(Qt.NoFocus)
        self.sld.setRange(0, 100)
        self.sld.setValue(100)
        self.sld.setPageStep(1)
        self.sld.setGeometry(0, 0, SCREEN_SIZE * 2 + 20, SCREEN_SIZE)
        self.sld.valueChanged.connect(self.changeSlider)

    def changeSlider(self, value):
        global speed_norm, speed_tang
        speed_norm = value / 100
        speed_tang = value / 100

    def light_d_pad(self, commands):
        self.state_left = not (KEY_LEFT in commands)
        self.state_right = not (KEY_RIGHT in commands)
        self.state_up = not (KEY_UP in commands)
        self.state_down = not (KEY_DOWN in commands)
        self.change_state()

    def change_state(self):
        if not e_stop:
            self.label_up.setHidden(self.state_up)
            self.label_down.setHidden(self.state_down)
            self.label_left.setHidden(self.state_left)
            self.label_right.setHidden(self.state_right)
            self.label_stop.setHidden(True)
        else:
            self.label_up.setHidden(True)
            self.label_down.setHidden(True)
            self.label_left.setHidden(True)
            self.label_right.setHidden(True)
            self.label_stop.setHidden(False)
        # ---
        self.label_publisher.setHidden(not self._parent.inFocus)

    def create_d_pad(self):
        self.label_up = QLabel(self)
        self.label_left = QLabel(self)
        self.label_down = QLabel(self)
        self.label_right = QLabel(self)
        self.label_stop = QLabel(self)
        self.label_publisher = QLabel(self)
        img = QPixmap(self.script_path + '../images/d-pad-pressed.png')
        img = img.scaled(SCREEN_SIZE, SCREEN_SIZE, Qt.KeepAspectRatio)
        t = QTransform()
        self.label_up.setPixmap(img)
        t.rotate(90)
        self.label_right.setPixmap(img.transformed(t))
        t.rotate(90)
        self.label_down.setPixmap(img.transformed(t))
        t.rotate(90)
        self.label_left.setPixmap(img.transformed(t))
        # e-stop
        img = QPixmap(self.script_path + '../images/d-e-stop.png')
        img = img.scaled(SCREEN_SIZE, SCREEN_SIZE, Qt.KeepAspectRatio)
        self.label_stop.setPixmap(img)
        # publisher icon
        img = QPixmap(self.script_path + '../images/d-publisher.png')
        img = img.scaled(SCREEN_SIZE, SCREEN_SIZE, Qt.KeepAspectRatio)
        self.label_publisher.setPixmap(img)
        # ---
        self.change_state()

    def create_up_button(self):
        button_up = QPushButton("", self)
        icon = QIcon(self.script_path + '../images/up_button.jpg')
        button_up.setIcon(icon)
        size = 100
        button_up.setIconSize(QSize(size, size))
        button_up.resize(QSize(size - 25, size - 10))
        button_up.move(int(SCREEN_SIZE / 2 - SCREEN_SIZE / 8), 15)
        button_up = self.add_listener_to_button(button_up, {'up'})
        button_up.pressed.connect(lambda: self.change_command({'up'}))

    def change_command(self, cm):
        self.command = cm

    def add_listener_to_button(self, button, command=None):
        if command is None:
            command = {''}

        def fun():
            self.command = command
            self.on_press_timer()

        button.pressed.connect(fun)
        button.released.connect(self.on_release_timer)
        return button

    def create_left_button(self):
        button = QPushButton("", self)
        icon = QIcon(self.script_path + '../images/left_button.jpg')
        button.setIcon(icon)
        size = 120
        button.setIconSize(QSize(size, size))
        button.resize(QSize(size - 25, size - 25))
        button.move(10, int(SCREEN_SIZE / 2 - size / 2 + 25 / 2))
        button = self.add_listener_to_button(button, {'left'})
        button.pressed.connect(lambda: self.change_command({'left'}))

    def create_right_button(self):
        button = QPushButton("", self)
        icon = QIcon(self.script_path + '../images/right_button.jpg')
        button.setIcon(icon)
        size = 120
        button.setIconSize(QSize(size, size))
        button.resize(QSize(size - 25, size - 25))
        button.move(int(SCREEN_SIZE / 2 + size / 2 - 25 / 2), int(SCREEN_SIZE / 2 - 47))
        button = self.add_listener_to_button(button, {'right'})
        button.pressed.connect(lambda: self.change_command({'right'}))

    def create_down_button(self):
        button = QPushButton("", self)
        icon = QIcon(self.script_path + '../images/down_button.jpg')
        button.setIcon(icon)
        size = 120
        button.setIconSize(QSize(size, size))
        button.resize(QSize(size - 25, size - 25))
        button.move(int(SCREEN_SIZE / 2 - size / 2 + 13), int(SCREEN_SIZE / 2 + 47))
        button = self.add_listener_to_button(button, {'down'})
        button.pressed.connect(lambda: self.change_command({'down'}))

def print_hint():
    print("\n\n\n")
    print("Virtual Joystick for your Duckiebot")
    print("-----------------------------------")
    print("\n")
    print("[ARROW_KEYS]:    Use them to steer your Duckiebot")
    print("         [q]:    Quit the program")
    print("         [a]:    Start lane-following a.k.a. autopilot")
    print("         [s]:    Stop lane-following")
    print("         [i]:    Toggle anti-instagram")
    print("         [e]:    Toggle emergency stop")
    print("\n")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        raise Exception("No hostname specified!")
    else:
        veh_name = sys.argv[1]
    # ---
    print_hint()
    app = QApplication(sys.argv)
    app.setApplicationName(f"{veh_name} - Virtual Joystick")
    m = MainWindow(veh_name)
    m.resize(SCREEN_SIZE, SCREEN_SIZE)
    m.show()
    exit_code = app.exec_()
    m.key_board_event.terminate()
    m.key_board_event.wait()
    m.ros.terminate()
    m.ros.wait()
    sys.exit(exit_code)


"""API-Routes to fetch static Data.

eg.: spells, classes, specs
"""

# IMPORT THIRD PARTY LIBRARIES
import fastapi

# IMPORT LOCAL LIBRARIES
from lorgs.models.raid_boss import RaidBoss
from lorgs.models.raid_zone import RaidZone
from lorgs.models.wow_class import WowClass
from lorgs.models.wow_role import WowRole
from lorgs.models.wow_spec import WowSpec
from lorgs.models.wow_spell import WowSpell

router = fastapi.APIRouter()

###############################################################################
#
#       Roles
#
###############################################################################

@router.get("/roles")
async def get_roles():
    """Get all roles (tank, heal, mpds, rdps)."""
    return {"roles": [role.as_dict() for role in WowRole.list()]}

###############################################################################
#
#       Classes
#
###############################################################################

@router.get("/classes")
async def get_classes():
    return {c.name_slug: c.as_dict() for c in WowClass.list()}

###############################################################################
#
#       Specs
#
###############################################################################

@router.get("/specs", tags=["specs"])
async def get_specs_all():
    all_specs = sorted(WowSpec.list())
    all_specs = [spec.as_dict() for spec in all_specs]  # type: ignore
    return {"specs": all_specs}

@router.get("/specs/{spec_slug}", tags=["specs"])
async def get_spec(spec_slug: str):
    spec = WowSpec.get(full_name_slug=spec_slug)
    if not spec:
        return "Invalid Spec.", 404
    return spec.as_dict()

@router.get("/specs/{spec_slug}/spells", tags=["specs"])
async def get_spec_spells(spec_slug: str):
    """Get all spells for a given spec.

    Args:
        spec_slug (str): name of the spec

    """
    spec = WowSpec.get(full_name_slug=spec_slug)
    if not spec:
        return "Invalid Spec.", 404

    abilities = spec.all_spells + spec.all_buffs + spec.all_debuffs + spec.all_events
    return {spell.spell_id: spell.as_dict() for spell in abilities}

###############################################################################
#
#       Spells
#
###############################################################################

@router.get("/spells/{spell_id}", tags=["spells"])
async def spells_one(spell_id: int):
    """Get a single Spell by spell_id."""
    spell = WowSpell.get(spell_id=spell_id)
    if not spell:
        return "Spell not found", 400
    return spell.as_dict()

@router.get("/spells", tags=["spells"])
async def spells_all():
    """Get all Spells."""
    spells = WowSpell.list()
    return {spell.spell_id: spell.as_dict() for spell in spells}

###############################################################################
#
#       Zones
#
###############################################################################

@router.get("/zones", tags=["raids"])
async def get_zones():
    """Get all raid-zones."""
    zones = RaidZone.list()
    return [zone.as_dict() for zone in zones]

@router.get("/zones/{zone_id}", tags=["raids"])
async def get_zone(zone_id: int):
    """Get a specific (raid-)Zone."""
    zone = RaidZone.get(id=zone_id)
    if not zone:
        return "Invalid Zone.", 404
    return zone.as_dict()

@router.get("/zones/{zone_id}/bosses", tags=["raids"])
async def get_zone_bosses(zone_id: int):
    """Get all Bosses in a given Raid Zone."""
    zone = RaidZone.get(id=zone_id)
    if not zone:
        return "Invalid Zone.", 404
    return {boss.name_slug: boss.as_dict() for boss in zone.bosses}

###############################################################################
#
#       Bosses
#
###############################################################################

@router.get("/bosses", tags=["raids"])
async def get_bosses():
    """Gets all Bosses
    Warning:
        this does not filter by raid.
        use "/zone/<zone_id>/bosses" to only get the bosses for a given raid.
    """
    return {"bosses": [boss.as_dict() for boss in RaidBoss.list()]}

@router.get("/bosses/{boss_slug}", tags=["raids"])
async def get_boss(boss_slug: str):
    """Get a single Boss.

    Args:
        boss_slug (string): name of the boss

    """
    boss = RaidBoss.get(full_name_slug=boss_slug)
    if not boss:
        return "Invalid Boss.", 404
    return boss.as_dict()

@router.get("/bosses/{boss_slug}/spells", tags=["raids"])
async def get_boss_spells(boss_slug: str):
    """Get Spells for a given Boss.

    Args:
        boss_slug (string): name of the boss

    """
    boss = RaidBoss.get(full_name_slug=boss_slug)
    if not boss:
        return "Invalid Boss.", 404

    spells = boss.all_spells + boss.all_buffs + boss.all_debuffs + boss.all_events
    return {spell.spell_id: spell.as_dict() for spell in spells}


from math import sqrt
import numpy as np
import warnings
import matplotlib.pyplot as plt
from matplotlib import style
from collections import Counter

style.use('fivethirtyeight')

# plot1 = (1,3)
# plot2 = (2,5)

# euclidian_distance = sqrt((plot1[0]-plot2[0])**2+(plot1[1]-plot2[1])**2)

# print(euclidian_distance)

#create a dictionary with 2 classes:
dataset = {'k': [[1,2],[2,3],[3,1]], 'r': [[6,5],[7,7],[8,6]]}
new_feature = [5,7]

#plotting loop: i as classes (k and r), ii as their attribute lists
for i in dataset:
	for ii in dataset[i]:
		plt.scatter(ii[0],ii[1], s = 100, color = i)
plt.scatter(new_feature[0], new_feature[1])
plt.show()

#define k nearest neigbor algoP: which one is the nearest datapoint: have to calculate all
def k_nearest_neighbors(data, predict, k=3):
	if len(data) >=k:
		warnings.warn('K is set to a value less than total voting group')

	distances = []
	for group in data:
		for features in data[group]:
			#NOt fast enough so use numpy formula instead
			#euclidian_distance = sqrt((feature[0]-predict[0])**2+(feature[1]-predict[1])**2)
			euclidian_distance = np.linalg.norm(np.array(features)-np.array(predict))
			distances.append([euclidian_distance, group])
	votes = [i[1] for i in sorted(distances)[:k]]
	print(Counter(votes).most_common(1))
	vote_result = Counter(votes).most_common(1)[0][0]

	return vote_result

result = k_nearest_neighbors(dataset, new_feature, k=3)
print(result)


from django import http
from django.utils.six.moves.urllib.parse import urlparse

from wagtail.wagtailredirects import models

# Originally pinched from: https://github.com/django/django/blob/master/django/contrib/redirects/middleware.py
class RedirectMiddleware(object):
    def process_response(self, request, response):
        # No need to check for a redirect for non-404 responses.
        if response.status_code != 404:
            return response

        # Get the path
        path = models.Redirect.normalise_path(request.get_full_path())

        # Get the path without the query string or params
        path_without_query = urlparse(path)[2]

        # Find redirect
        try:
            redirect = models.Redirect.get_for_site(request.site).get(old_path=path)
        except models.Redirect.DoesNotExist:
            if path == path_without_query:
                # don't try again if we know we will get the same response
                return response

            site = Site.find_for_request(request)
            try:
                redirect = models.Redirect.get(site=site, old_path=path_without_query)
            except models.Redirect.DoesNotExist:
                return response

        if redirect.is_permanent:
            return http.HttpResponsePermanentRedirect(redirect.link)
        else:
            return http.HttpResponseRedirect(redirect.link)


# -*- coding: utf-8 -*-
from selenium import webdriver
import unittest

# need to install Castro and PyGame
class PopupWindowTest(unittest.TestCase):
    """PopupWindowTest
        Working with popup child windows. Can work with any child window
        as long as it belongs to the current WebDriver context.
    """

    URL = 'https://rawgit.com/upgundecha/learnsewithpython/master/pages/Config.html'

    def setUp(self):

        self.driver = webdriver.Firefox()# Chrome non-op
        self.driver.implicitly_wait(30)
        self.driver.get(self.URL)
        self.driver.maximize_window()

    # def tearDown(self):
    #     self.driver.close()#quit()

    def test_window_popup(self):
        driver = self.driver

        # save Parent Browser's Window WindowHandle
        parent_window_id = driver.current_window_handle
        print("This is parent_window_id: {}".format(parent_window_id))

        # clicking Help Button will open Help Page in a new popup browser window
        help_button = driver.find_element_by_id('helpbutton')
        help_button.click()

        driver.switch_to.window("HelpWindow")
        child_window_id = driver.current_window_handle
        print("This is child_window_id: {}".format(child_window_id))
        driver.close()

        driver.switch_to.window(parent_window_id)
        print("back to window_id: {}".format(driver.current_window_handle))

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


from math import factorial, sqrt#不用引入pow
import numpy as np
# 注意公式迭代的初始值
def Euler(l):
     PiList=np.zeros(l)
     s=0
     for n in range(1,l+1):
        an = 1/n**2
        s = s+an
        PiList[n-1]=sqrt(s*6)
     return PiList
def Leibniz(l):
    PiList=np.zeros(l)
    s=0
    for n in range(1,l+1):
        an=an=1/(2*n-1)*pow(-1,n-1)
        s=s+an
        PiList[n-1]=4*s
    return PiList
def Ramanujan_by_myself(l):
    PiList=np.zeros(l)
    s=0
    k=sqrt(8)/pow(99,2)
    for n in range(0,l):
        an=factorial(4*n)*(1103+26390*n)/pow(factorial(n),4)/pow(396,4*n)
        s=s+an
        PiList[n]=1/(k*s)
    return PiList

from math import factorial,sqrt,log10
from decimal import Decimal, getcontext
import mpmath as mp
mp.dps = 100000  # number of digits
def ramanujan_by_igfasouza(max_step):
    """ Computing an approximation of pi with a Ramanujan's formula."""
    getcontext().prec = max_step*10  # trick to improve precision
    PiList=[]
    Sum = Decimal(0)
    d_1103 = Decimal(1103)
    d_26390 = Decimal(26390)
    d_396 = Decimal(396)
    for k in range(max_step):
        Sum += ((Decimal(factorial(4 * k))) * (d_1103 + d_26390 * Decimal(k))) / ( (Decimal(factorial(k)))**4 * (d_396**(4*k)))
        my_pi_multiple_factor = Sum * 2 * Decimal(2).sqrt() / Decimal(9801)
        my_pi_reciprocal  = my_pi_multiple_factor**(-1)
        PiList.append(my_pi_reciprocal)
    return PiList


# attention.py

import torch
from torch import nn
import math
import torch.nn.functional as F
from train_utils import clones

def attention(query, key, value, mask=None, dropout=None):
    "Implementation of Scaled dot product attention"
    d_k = query.size(-1)
    scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
    if mask is not None:
        scores = scores.masked_fill(mask == 0, -1e9)
    p_attn = F.softmax(scores, dim = -1)
    if dropout is not None:
        p_attn = dropout(p_attn)
    return torch.matmul(p_attn, value), p_attn

class MultiHeadedAttention(nn.Module):
    def __init__(self, h, d_model, dropout=0.1):
        "Take in model size and number of heads."
        super(MultiHeadedAttention, self).__init__()
        assert d_model % h == 0
        # We assume d_v always equals d_k
        self.d_k = d_model // h
        self.h = h
        self.linears = clones(nn.Linear(d_model, d_model), 4)
        self.attn = None
        self.dropout = nn.Dropout(p=dropout)

    def forward(self, query, key, value, mask=None):
        "Implements Multi-head attention"
        if mask is not None:
            # Same mask applied to all h heads.
            mask = mask.unsqueeze(1)
        nbatches = query.size(0)

        # 1) Do all the linear projections in batch from d_model => h x d_k
        query, key, value = \
            [l(x).view(nbatches, -1, self.h, self.d_k).transpose(1, 2)
             for l, x in zip(self.linears, (query, key, value))]

        # 2) Apply attention on all the projected vectors in batch.
        x, self.attn = attention(query, key, value, mask=mask,
                                 dropout=self.dropout)

        # 3) "Concat" using a view and apply a final linear.
        x = x.transpose(1, 2).contiguous() \
             .view(nbatches, -1, self.h * self.d_k)
        return self.linears[-1](x)


import rpm
import os, subprocess, urllib, getpass
from argparse import ArgumentParser

SOURCES = '{0}/rpmbuild/SOURCES'.format(os.getenv('HOME'))

parser = ArgumentParser()

parser.add_argument('-u', '--user', help='SCP User', required=True)
parser.add_argument('--host', help='SCP Host', default='10.0.254.23')
parser.add_argument('-d', '--dest', help='SCP Destination directory', default='/usr/local/www/rpms')
parser.add_argument('-j', '--jail', help='Jail Type (content/database)', default='content')
parser.add_argument('-U', action='store_true', help='Update source archive.')
parser.add_argument('spec', help='RPM Spec file')
options = parser.parse_args()

if not os.path.exists(options.spec):
    raise RuntimeError("Provided spec file does not exists: `{0}`".format(options.spec))

transaction = rpm.ts()
spec = transaction.parseSpec(options.spec)
source_url = spec.sources[0][0]

source_file = spec.sourceHeader[rpm.RPMTAG_SOURCE][0]
if source_file is None:
    raise RuntimeError('Error, source file cannot be None.')

source_archive = '{0}/{1}'.format(SOURCES, source_file)

if not os.path.exists(source_archive) or options.U:
    if os.path.exists(source_archive):
        os.unlink(source_archive)
    print('Downloading `{0}`.'.format(source_url))
    urllib.urlretrieve(source_url, source_archive)

if not os.path.exists(source_archive):
    raise RuntimeError('Source archive missing! ({0})'.format(source_archive))

cmd = ['rpmbuild', '-bb', '--clean', options.spec]

process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
retcode = process.wait()
result_rpm = None
for line in process.stdout:
    # we are looking for something like this: Wrote: /usr/src/redhat/RPMS/i386/cdplayer-1.0-1.i386.rpm
    if not line.startswith('Wrote:'):
        continue

    result_rpm = line.split(" ")[1].strip()

if result_rpm is None or not os.path.exists(result_rpm):
    raise RuntimeError('RPM Build error: File `{0}` does not exists.'.format(result_rpm))

rpm = os.path.basename(result_rpm)

destination = "{0}/{1}/{2}".format(options.dest, options.jail, rpm)

dst = "{0}@{1}:{2}".format(options.user, options.host, destination)
cmd = ['scp']
cmd.append(result_rpm)
cmd.append(dst)
print("Uploading `{0}` to `{1}`".format(rpm, dst))
subprocess.Popen(cmd).wait()


# Геопандас / Cвердловская обл.
import geopandas as gpd
import pandas as pd
from matplotlib import pyplot as plt
pd.set_option('display.max_columns', None)

#Свердловская обл общая граница
gpd_svd_L1 = gpd.read_file('~/PycharmProjects/maps/GeoData/svd/boundary-polygon-lvl4.shp', encoding='utf-8')
# районы и округа 73 шт 65763000
gpd_svd_L2 = gpd.read_file('~/PycharmProjects/maps/GeoData/svd/boundary-polygon-lvl6.shp', encoding='utf-8')
#сельские поселения 22 шт 65628420
gpd_svd_L3 = gpd.read_file('~/PycharmProjects/maps/GeoData/svd/boundary-polygon-lvl8.shp', encoding='utf-8')
#населенные пункты 2272  шт 65755000141
gpd_svd_L4 = gpd.read_file('~/PycharmProjects/maps/GeoData/svd/settlement-point.shp', encoding='utf-8')

print(gpd_svd_L3.info())
print(gpd_svd_L3[['NAME', 'oktmo', 'geometry']])

fig, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4, figsize=(10,5))
gpd_svd_L1.plot(ax=ax1, color='white', edgecolor='black')
gpd_svd_L2.plot(ax=ax2, color='white', edgecolor='black')
gpd_svd_L3.plot(ax=ax3, color='white', edgecolor='black')
gpd_svd_L4.plot(ax=ax4, color='white', edgecolor='black')
plt.show()


#!/usr/bin/env python
#_*_ coding: utf8 _*_

import socket
import sys
import argparse
from colorama import Fore
import platform
import os
import time
from os import path

parse = argparse.ArgumentParser()
parse.add_argument('-t','--target',help='target')
parse.add_argument('-s','--seconds',help='seconds sleep',default=0.3,type=int)
parse.add_argument('-o','--output',help='save')
argsv = parse.parse_args()

def slowprint(cad):
	for c in cad + '\n':
		sys.stdout.write(c)
		sys.stdout.flush()
		time.sleep(.1)

class colors:
	blue = Fore.LIGHTBLUE_EX
	green = Fore.LIGHTGREEN_EX
	red = Fore.LIGHTRED_EX
	yellow = Fore.LIGHTYELLOW_EX
	white = Fore.LIGHTWHITE_EX
	black = Fore.BLACK

ports = [21, 22, 23, 25, 66, 79, 80, 107, 110, 118, 119, 137, 138, 139, 150, 161, 194, 209, 217, 389, 407, 443, 445, 515, 522, 531, 992, 993, 995, 1417, 1420, 1547, 3000, 3128, 3389, 4099, 5190, 5500, 5631, 5632, 5800, 5900, 6346, 6891, 6900, 6901, 20000, 28800, 29000]

def save_ports(lista,file_save):
	if path.exists(file_save):
		print('[{}!{}] {}Exists File'.format(colors.red,colors.white,colors.red))
		sys.exit(1)
	else:
		if len(lista) > 0:
			if file_save.__contains__('.'):
				file = open(file_save+'.txt','w+')
				file.write('======================\n')
				file.write('PORTS SAVE\n')
				file.write('======================\n')
				for n in lista:
					file.write(str(n))
					file.write('\n=====================\n')
				file.close()
				print('\n{}==========================================\n'.format(colors.yellow))
				print('\t{}SAVE => {}'.format(colors.red,file_save))
				print('\n{}==========================================\n'.format(colors.yellow))
			else:
				file = open(file_save+'.txt','w+')
				file.write('======================\n')
				file.write('PORTS SAVE\n')
				file.write('======================\n')
				for n in lista:
					file.write(str(n))
					file.write('\n=====================\n')
				print('\n{}==========================================\n'.format(colors.yellow))
				print('\t{}SAVE => {}.txt'.format(colors.red,file_save))
				print('\n{}==========================================\n'.format(colors.yellow))
				file.close()
		else:
			print('[{}!{}] {}Ports Not Found :('.format(colors.red,colors.white,colors.red))

def scanner(ip):
	list_ports = []
	print('[{}SLEEP{}] {}'.format(colors.green,colors.white,argsv.seconds))
	for p in ports:
		time.sleep(argsv.seconds)
		sc = socket.socket()
		try:
			sc.settimeout(2)
			sc.connect((ip,p))
			print('\n[{}+{}] {}OPEN{} Search Banner In {}...{}\n'.format(colors.red,colors.white,colors.green,colors.red,p,colors.white))
			sc.send(b'a')
			try:
				rb = sc.recv(1024)
				print('\n[{}+{}] {}{}{}'.format(colors.green,colors.white,colors.green,rb,colors.white))
			except socket.timeout:
				print('\n[{}!{}] {}Banner Not Found{}'.format(colors.red,colors.white,colors.red,colors.white))
			list_ports.append(p)
			sc.close()
		except socket.error:
			print('\n[{}!{}] PORT {} {}CLOSED or FILTERED{}'.format(colors.red,colors.white,p,colors.red,colors.white))
		finally:
			sc.close()
	if argsv.output:
		save_ports(list_ports,argsv.output)
	else:
		if len(list_ports) > 0:
			print('\n{}==========================================\n'.format(colors.yellow))
			print('{}\tOPEN PORTS IN {}\n'.format(colors.yellow,ip))
			for l in list_ports:
				print('\t[{}+{}] {} OPEN{}'.format(colors.green,colors.white,l,colors.white))
			print('\n{}==========================================\n'.format(colors.yellow))
		else:
			print('[{}!{}] {}Ports Not Found :('.format(colors.red,colors.white,colors.red))
		sys.exit(1)

def banner():
	print('''

{}   ▄████████  ▄█   ▄█          ▄████████ ███▄▄▄▄       ███
  ███    ███ ███  ███         ███    ███ ███▀▀▀██▄ ▀█████████▄
  ███    █▀  ███▌ ███         ███    █▀  ███   ███    ▀███▀▀██
{} ███        ███▌ ███        ▄███▄▄▄     ███   ███     ███   ▀
▀███████████ ███▌ ███       ▀▀███▀▀▀     ███   ███     ███
         ███ ███  ███         ███    █▄  ███   ███     ███
{}  ▄█    ███ ███  ███▌    ▄   ███    ███ ███   ███     ███
 ▄████████▀  █▀   █████▄▄██   ██████████  ▀█   █▀     ▄████▀
                  ▀
{}
 												 \t\t\t\t\t\t\t\n Twitter: @IDX4CKS
'''.format(colors.black,colors.red,colors.yellow,colors.green))
	print('{}'.format(colors.white))

def main():
	banner()
	if argsv.target:
		target = argsv.target
		if target.startswith('http://'):
			target = target.replace('http://','')
		elif target.startswith('https://'):
			target = target.replace('http://','')
		else:
			pass
		scanner(target)

if __name__ == '__main__':
	try:
		if len(sys.argv) < 2:
			print('Need Arguments')
			sys.exit()
		else:
			if platform.system() == 'Windows':
				cmd = os.system('cls')
				main()
			elif platform.system() == 'Linux':
				cmd = os.system('reset')
				main()
	except KeyboardInterrupt:
		slowprint('{}Bye Bye ^-^/'.format(colors.red))
		sys.exit()


import unittest
from unittest.mock import MagicMock, patch
from requests import Session

from src.kong_gateway_client.api import KongAPIClient
import json

class MockResponse:
    def __init__(self, json_data):
        self.json_data = json_data
        self.content = json.dumps(json_data).encode("utf-8") if json_data else b""

    def json(self):
        return self.json_data

    def ok(self):
        return True

    def raise_for_status(self):
        pass

class TestRoute(unittest.TestCase):
    def setUp(self):
        mock_response_auth = MagicMock()
        mock_response_auth.json.return_value = {"auth_key": "some_auth_value"}
        mock_response_auth.raise_for_status.return_value = None

        self.get_patcher = patch.object(Session, "get", return_value=mock_response_auth)
        self.request_patcher = patch.object(
            Session, "request", return_value=mock_response_auth
        )

        self.mock_get = self.get_patcher.start()
        self.mock_request = self.request_patcher.start()

        self.client = KongAPIClient(
            "http://mock-url", admin_token="mock-pass"
        ).get_kong_client()

    def tearDown(self):
        self.get_patcher.stop()
        self.request_patcher.stop()

    def test_route_create(self):
        mock_response_routes = MockResponse({"id": "123", "name": "test-route-1"})
        self.mock_request.return_value = mock_response_routes
        result = self.client.route.create("test-route-1", protocols=["http", "https"])
        self.assertEqual(result.name, "test-route-1")

    def test_route_get_by_id(self):
        mock_response = MockResponse(
            {
                "id": "123",
                "name": "test-route-1",
                "protocols": ["http"],
                "methods": ["GET"],
                "hosts": ["example.com"],
                "paths": ["/test-route"],
            }
        )
        self.mock_request.return_value = mock_response

        result = self.client.route.get("123")

        self.assertEqual(result.id, "123")
        self.assertEqual(result.name, "test-route-1")
        self.assertEqual(result.paths[0], "/test-route")

    def test_route_patch(self):
        mock_response = MockResponse(
            {
                "id": "123",
                "name": "updated-test-route-1",
                "protocols": ["http"],
                "methods": ["GET"],
                "hosts": ["example.com"],
                "paths": ["/updated-test-route"],
            }
        )
        self.mock_request.return_value = mock_response

        result = self.client.route.patch(
            "123", name="updated-test-route-1", protocols=["http"]
        )

        self.assertEqual(result.name, "updated-test-route-1")
        self.assertEqual(result.paths[0], "/updated-test-route")

    def test_route_put(self):
        mock_response = MockResponse(
            {
                "id": "123",
                "name": "recreated-test-route-1",
                "protocols": ["http"],
                "methods": ["GET"],
                "hosts": ["example.com"],
                "paths": ["/recreated-test-route"],
            }
        )
        self.mock_request.return_value = mock_response

        result = self.client.route.put(
            "123", name="recreated-test-route-1", protocols=["http"]
        )

        self.assertEqual(result.name, "recreated-test-route-1")
        self.assertEqual(result.paths[0], "/recreated-test-route")

    def test_route_delete(self):
        mock_response = MockResponse({})
        self.mock_request.return_value = mock_response

        result = self.client.route.delete("123")
        self.assertIsNone(result)

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