import asyncio
from decimal import Decimal
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple

from bidict import bidict

import hummingbot.connector.exchange.bybit.bybit_constants as CONSTANTS
import hummingbot.connector.exchange.bybit.bybit_utils as bybit_utils
import hummingbot.connector.exchange.bybit.bybit_web_utils as web_utils
from hummingbot.connector.exchange.bybit.bybit_api_order_book_data_source import BybitAPIOrderBookDataSource
from hummingbot.connector.exchange.bybit.bybit_api_user_stream_data_source import BybitAPIUserStreamDataSource
from hummingbot.connector.exchange.bybit.bybit_auth import BybitAuth
from hummingbot.connector.exchange_py_base import ExchangePyBase
from hummingbot.connector.trading_rule import TradingRule
from hummingbot.connector.utils import combine_to_hb_trading_pair
from hummingbot.core.data_type.common import OrderType, TradeType
from hummingbot.core.data_type.in_flight_order import InFlightOrder, OrderUpdate, TradeUpdate
from hummingbot.core.data_type.order_book_tracker_data_source import OrderBookTrackerDataSource
from hummingbot.core.data_type.trade_fee import TokenAmount, TradeFeeBase
from hummingbot.core.data_type.user_stream_tracker_data_source import UserStreamTrackerDataSource
from hummingbot.core.utils.estimate_fee import build_trade_fee
from hummingbot.core.web_assistant.connections.data_types import RESTMethod
from hummingbot.core.web_assistant.web_assistants_factory import WebAssistantsFactory

if TYPE_CHECKING:
    from hummingbot.client.config.config_helpers import ClientConfigAdapter

s_logger = None
s_decimal_NaN = Decimal("nan")

class BybitExchange(ExchangePyBase):
    web_utils = web_utils

    def __init__(self,
                 client_config_map: "ClientConfigAdapter",
                 bybit_api_key: str,
                 bybit_api_secret: str,
                 trading_pairs: Optional[List[str]] = None,
                 trading_required: bool = True,
                 domain: str = CONSTANTS.DEFAULT_DOMAIN,
                 ):
        self.api_key = bybit_api_key
        self.secret_key = bybit_api_secret
        self._domain = domain
        self._trading_required = trading_required
        self._trading_pairs = trading_pairs
        self._last_trades_poll_bybit_timestamp = 1.0
        super().__init__(client_config_map)

    @staticmethod
    def bybit_order_type(order_type: OrderType) -> str:
        return order_type.name.upper()

    @staticmethod
    def to_hb_order_type(bybit_type: str) -> OrderType:
        return OrderType[bybit_type]

    @property
    def authenticator(self):
        return BybitAuth(
            api_key=self.api_key,
            secret_key=self.secret_key,
            time_provider=self._time_synchronizer)

    @property
    def name(self) -> str:
        if self._domain == "bybit_main":
            return "bybit"
        else:
            return f"bybit_{self._domain}"

    @property
    def rate_limits_rules(self):
        return CONSTANTS.RATE_LIMITS

    @property
    def domain(self):
        return self._domain

    @property
    def client_order_id_max_length(self):
        return CONSTANTS.MAX_ORDER_ID_LEN

    @property
    def client_order_id_prefix(self):
        return CONSTANTS.HBOT_ORDER_ID_PREFIX

    @property
    def trading_rules_request_path(self):
        return CONSTANTS.EXCHANGE_INFO_PATH_URL

    @property
    def trading_pairs_request_path(self):
        return CONSTANTS.EXCHANGE_INFO_PATH_URL

    @property
    def check_network_request_path(self):
        return CONSTANTS.SERVER_TIME_PATH_URL

    @property
    def trading_pairs(self):
        return self._trading_pairs

    @property
    def is_cancel_request_in_exchange_synchronous(self) -> bool:
        return True

    @property
    def is_trading_required(self) -> bool:
        return self._trading_required

    def supported_order_types(self):
        return [OrderType.MARKET, OrderType.LIMIT, OrderType.LIMIT_MAKER]

    def _is_request_exception_related_to_time_synchronizer(self, request_exception: Exception):
        error_description = str(request_exception)
        is_time_synchronizer_related = ("-1021" in error_description
                                        and "Timestamp for the request" in error_description)
        return is_time_synchronizer_related

    def _is_order_not_found_during_status_update_error(self, status_update_exception: Exception) -> bool:
        # TODO: implement this method correctly for the connector
        # The default implementation was added when the functionality to detect not found orders was introduced in the
        # ExchangePyBase class. Also fix the unit test test_lost_order_removed_if_not_found_during_order_status_update
        # when replacing the dummy implementation
        return False

    def _is_order_not_found_during_cancelation_error(self, cancelation_exception: Exception) -> bool:
        # TODO: implement this method correctly for the connector
        # The default implementation was added when the functionality to detect not found orders was introduced in the
        # ExchangePyBase class. Also fix the unit test test_cancel_order_not_found_in_the_exchange when replacing the
        # dummy implementation
        return False

    def _create_web_assistants_factory(self) -> WebAssistantsFactory:
        return web_utils.build_api_factory(
            throttler=self._throttler,
            time_synchronizer=self._time_synchronizer,
            domain=self._domain,
            auth=self._auth)

    def _create_order_book_data_source(self) -> OrderBookTrackerDataSource:
        return BybitAPIOrderBookDataSource(
            trading_pairs=self._trading_pairs,
            connector=self,
            domain=self.domain,
            api_factory=self._web_assistants_factory,
            throttler=self._throttler,
            time_synchronizer=self._time_synchronizer)

    def _create_user_stream_data_source(self) -> UserStreamTrackerDataSource:
        return BybitAPIUserStreamDataSource(
            auth=self._auth,
            throttler=self._throttler,
            time_synchronizer=self._time_synchronizer,
            api_factory=self._web_assistants_factory,
            domain=self.domain,
        )

    def _get_fee(self,
                 base_currency: str,
                 quote_currency: str,
                 order_type: OrderType,
                 order_side: TradeType,
                 amount: Decimal,
                 price: Decimal = s_decimal_NaN,
                 is_maker: Optional[bool] = None) -> TradeFeeBase:
        is_maker = order_type is OrderType.LIMIT_MAKER
        trade_base_fee = build_trade_fee(
            exchange=self.name,
            is_maker=is_maker,
            order_side=order_side,
            order_type=order_type,
            amount=amount,
            price=price,
            base_currency=base_currency,
            quote_currency=quote_currency
        )
        return trade_base_fee

    async def _place_order(self,
                           order_id: str,
                           trading_pair: str,
                           amount: Decimal,
                           trade_type: TradeType,
                           order_type: OrderType,
                           price: Decimal,
                           **kwargs) -> Tuple[str, float]:
        amount_str = f"{amount:f}"
        type_str = self.bybit_order_type(order_type)

        side_str = CONSTANTS.SIDE_BUY if trade_type is TradeType.BUY else CONSTANTS.SIDE_SELL
        symbol = await self.exchange_symbol_associated_to_pair(trading_pair=trading_pair)
        api_params = {"symbol": symbol,
                      "side": side_str,
                      "qty": amount_str,
                      "type": type_str,
                      "orderLinkId": order_id}
        if order_type != OrderType.MARKET:
            api_params["price"] = f"{price:f}"
        if order_type == OrderType.LIMIT:
            api_params["timeInForce"] = CONSTANTS.TIME_IN_FORCE_GTC

        order_result = await self._api_post(
            path_url=CONSTANTS.ORDER_PATH_URL,
            params=api_params,
            is_auth_required=True,
            trading_pair=trading_pair,
            headers={"referer": CONSTANTS.HBOT_BROKER_ID},
        )

        o_id = str(order_result["result"]["orderId"])
        transact_time = int(order_result["result"]["transactTime"]) * 1e-3
        return (o_id, transact_time)

    async def _place_cancel(self, order_id: str, tracked_order: InFlightOrder):
        api_params = {}
        if tracked_order.exchange_order_id:
            api_params["orderId"] = tracked_order.exchange_order_id
        else:
            api_params["orderLinkId"] = tracked_order.client_order_id
        cancel_result = await self._api_delete(
            path_url=CONSTANTS.ORDER_PATH_URL,
            params=api_params,
            is_auth_required=True)

        if isinstance(cancel_result, dict) and "orderLinkId" in cancel_result["result"]:
            return True
        return False

    async def _format_trading_rules(self, exchange_info_dict: Dict[str, Any]) -> List[TradingRule]:
        """
        Example:
                {
            "ret_code": 0,
            "ret_msg": "",
            "ext_code": null,
            "ext_info": null,
            "result": [
                {
                    "name": "BTCUSDT",
                    "alias": "BTCUSDT",
                    "baseCurrency": "BTC",
                    "quoteCurrency": "USDT",
                    "basePrecision": "0.000001",
                    "quotePrecision": "0.01",
                    "minTradeQuantity": "0.0001",
                    "minTradeAmount": "10",
                    "minPricePrecision": "0.01",
                    "maxTradeQuantity": "2",
                    "maxTradeAmount": "200",
                    "category": 1
                },
                {
                    "name": "ETHUSDT",
                    "alias": "ETHUSDT",
                    "baseCurrency": "ETH",
                    "quoteCurrency": "USDT",
                    "basePrecision": "0.0001",
                    "quotePrecision": "0.01",
                    "minTradeQuantity": "0.0001",
                    "minTradeAmount": "10",
                    "minPricePrecision": "0.01",
                    "maxTradeQuantity": "2",
                    "maxTradeAmount": "200",
                    "category": 1
                }
            ]
        }
        """
        trading_pair_rules = exchange_info_dict.get("result", [])
        retval = []
        for rule in trading_pair_rules:
            try:
                trading_pair = await self.trading_pair_associated_to_exchange_symbol(symbol=rule.get("name"))

                min_order_size = rule.get("minTradeQuantity")
                min_price_increment = rule.get("minPricePrecision")
                min_base_amount_increment = rule.get("basePrecision")
                min_notional_size = rule.get("minTradeAmount")

                retval.append(
                    TradingRule(trading_pair,
                                min_order_size=Decimal(min_order_size),
                                min_price_increment=Decimal(min_price_increment),
                                min_base_amount_increment=Decimal(min_base_amount_increment),
                                min_notional_size=Decimal(min_notional_size)))

            except Exception:
                self.logger().exception(f"Error parsing the trading pair rule {rule.get('name')}. Skipping.")
        return retval

    async def _update_trading_fees(self):
        """
        Update fees information from the exchange
        """
        pass

    async def _user_stream_event_listener(self):
        """
        This functions runs in background continuously processing the events received from the exchange by the user
        stream data source. It keeps reading events from the queue until the task is interrupted.
        The events received are balance updates, order updates and trade events.
        """
        async for event_message in self._iter_user_event_queue():
            try:
                event_type = event_message.get("e")
                if event_type == "executionReport":
                    execution_type = event_message.get("X")
                    client_order_id = event_message.get("c")
                    tracked_order = self._order_tracker.fetch_order(client_order_id=client_order_id)
                    if tracked_order is not None:
                        if execution_type in ["PARTIALLY_FILLED", "FILLED"]:
                            fee = TradeFeeBase.new_spot_fee(
                                fee_schema=self.trade_fee_schema(),
                                trade_type=tracked_order.trade_type,
                                flat_fees=[TokenAmount(amount=Decimal(event_message["n"]), token=event_message["N"])]
                            )
                            trade_update = TradeUpdate(
                                trade_id=str(event_message["t"]),
                                client_order_id=client_order_id,
                                exchange_order_id=str(event_message["i"]),
                                trading_pair=tracked_order.trading_pair,
                                fee=fee,
                                fill_base_amount=Decimal(event_message["l"]),
                                fill_quote_amount=Decimal(event_message["l"]) * Decimal(event_message["L"]),
                                fill_price=Decimal(event_message["L"]),
                                fill_timestamp=int(event_message["E"]) * 1e-3,
                            )
                            self._order_tracker.process_trade_update(trade_update)

                        order_update = OrderUpdate(
                            trading_pair=tracked_order.trading_pair,
                            update_timestamp=int(event_message["E"]) * 1e-3,
                            new_state=CONSTANTS.ORDER_STATE[event_message["X"]],
                            client_order_id=client_order_id,
                            exchange_order_id=str(event_message["i"]),
                        )
                        self._order_tracker.process_order_update(order_update=order_update)

                elif event_type == "outboundAccountInfo":
                    balances = event_message["B"]
                    for balance_entry in balances:
                        asset_name = balance_entry["a"]
                        free_balance = Decimal(balance_entry["f"])
                        total_balance = Decimal(balance_entry["f"]) + Decimal(balance_entry["l"])
                        self._account_available_balances[asset_name] = free_balance
                        self._account_balances[asset_name] = total_balance

            except asyncio.CancelledError:
                raise
            except Exception:
                self.logger().error("Unexpected error in user stream listener loop.", exc_info=True)
                await self._sleep(5.0)

    async def _all_trade_updates_for_order(self, order: InFlightOrder) -> List[TradeUpdate]:
        trade_updates = []

        if order.exchange_order_id is not None:
            exchange_order_id = int(order.exchange_order_id)
            trading_pair = await self.exchange_symbol_associated_to_pair(trading_pair=order.trading_pair)
            all_fills_response = await self._api_get(
                path_url=CONSTANTS.MY_TRADES_PATH_URL,
                params={
                    "symbol": trading_pair,
                    "orderId": exchange_order_id
                },
                is_auth_required=True,
                limit_id=CONSTANTS.MY_TRADES_PATH_URL)
            fills_data = all_fills_response.get("result", [])
            if fills_data is not None:
                for trade in fills_data:
                    exchange_order_id = str(trade["orderId"])
                    fee = TradeFeeBase.new_spot_fee(
                        fee_schema=self.trade_fee_schema(),
                        trade_type=order.trade_type,
                        percent_token=trade["commissionAsset"],
                        flat_fees=[TokenAmount(amount=Decimal(trade["commission"]), token=trade["commissionAsset"])]
                    )
                    trade_update = TradeUpdate(
                        trade_id=str(trade["ticketId"]),
                        client_order_id=order.client_order_id,
                        exchange_order_id=exchange_order_id,
                        trading_pair=trading_pair,
                        fee=fee,
                        fill_base_amount=Decimal(trade["qty"]),
                        fill_quote_amount=Decimal(trade["price"]) * Decimal(trade["qty"]),
                        fill_price=Decimal(trade["price"]),
                        fill_timestamp=int(trade["executionTime"]) * 1e-3,
                    )
                    trade_updates.append(trade_update)

        return trade_updates

    async def _request_order_status(self, tracked_order: InFlightOrder) -> OrderUpdate:
        updated_order_data = await self._api_get(
            path_url=CONSTANTS.ORDER_PATH_URL,
            params={
                "orderLinkId": tracked_order.client_order_id},
            is_auth_required=True)

        new_state = CONSTANTS.ORDER_STATE[updated_order_data["result"]["status"]]

        order_update = OrderUpdate(
            client_order_id=tracked_order.client_order_id,
            exchange_order_id=str(updated_order_data["result"]["orderId"]),
            trading_pair=tracked_order.trading_pair,
            update_timestamp=int(updated_order_data["result"]["updateTime"]) * 1e-3,
            new_state=new_state,
        )

        return order_update

    async def _update_balances(self):
        local_asset_names = set(self._account_balances.keys())
        remote_asset_names = set()

        account_info = await self._api_request(
            method=RESTMethod.GET,
            path_url=CONSTANTS.ACCOUNTS_PATH_URL,
            is_auth_required=True)
        balances = account_info["result"]["balances"]
        for balance_entry in balances:
            asset_name = balance_entry["coin"]
            free_balance = Decimal(balance_entry["free"])
            total_balance = Decimal(balance_entry["total"])
            self._account_available_balances[asset_name] = free_balance
            self._account_balances[asset_name] = total_balance
            remote_asset_names.add(asset_name)

        asset_names_to_remove = local_asset_names.difference(remote_asset_names)
        for asset_name in asset_names_to_remove:
            del self._account_available_balances[asset_name]
            del self._account_balances[asset_name]

    def _initialize_trading_pair_symbols_from_exchange_info(self, exchange_info: Dict[str, Any]):
        mapping = bidict()
        for symbol_data in filter(bybit_utils.is_exchange_information_valid, exchange_info["result"]):
            mapping[symbol_data["name"]] = combine_to_hb_trading_pair(base=symbol_data["baseCurrency"],
                                                                      quote=symbol_data["quoteCurrency"])
        self._set_trading_pair_symbol_map(mapping)

    async def _get_last_traded_price(self, trading_pair: str) -> float:
        params = {
            "symbol": await self.exchange_symbol_associated_to_pair(trading_pair=trading_pair),
        }
        resp_json = await self._api_request(
            method=RESTMethod.GET,
            path_url=CONSTANTS.LAST_TRADED_PRICE_PATH,
            params=params,
        )

        return float(resp_json["result"]["price"])

    async def _api_request(self,
                           path_url,
                           method: RESTMethod = RESTMethod.GET,
                           params: Optional[Dict[str, Any]] = None,
                           data: Optional[Dict[str, Any]] = None,
                           is_auth_required: bool = False,
                           return_err: bool = False,
                           limit_id: Optional[str] = None,
                           trading_pair: Optional[str] = None,
                           **kwargs) -> Dict[str, Any]:
        last_exception = None
        rest_assistant = await self._web_assistants_factory.get_rest_assistant()
        url = web_utils.rest_url(path_url, domain=self.domain)
        local_headers = {
            "Content-Type": "application/x-www-form-urlencoded"}
        for _ in range(2):
            try:
                request_result = await rest_assistant.execute_request(
                    url=url,
                    params=params,
                    data=data,
                    method=method,
                    is_auth_required=is_auth_required,
                    return_err=return_err,
                    headers=local_headers,
                    throttler_limit_id=limit_id if limit_id else path_url,
                )
                return request_result
            except IOError as request_exception:
                last_exception = request_exception
                if self._is_request_exception_related_to_time_synchronizer(request_exception=request_exception):
                    self._time_synchronizer.clear_time_offset_ms_samples()
                    await self._update_time_synchronizer()
                else:
                    raise

        # Failed even after the last retry
        raise last_exception


import asyncio
import logging
from datetime import datetime, timezone, timedelta
from functools import partial
from typing import Optional, Callable, Any, Dict, List

import discord
from discord import app_commands, Interaction, ui
from discord.ext import commands

from bot.social.provider_cog import ProviderCog, Provider, ProviderTaskService
from mixins.config import ConfigMixin
from services import establish_member_config, string_timedelta

log = logging.getLogger(__name__)

class SubscriberCog(ConfigMixin, commands.GroupCog, name='subscriber-display'):

    def __init__(self, bot: commands.Bot, provider_cog: ProviderCog):
        self.bot = bot
        self.provider_cog = provider_cog
        self.channel: Optional[discord.TextChannel] = None
        self.tasks: Dict[str, asyncio.Task] = {}  # Composite key guild_id + member_id + provider_name
        self.provider_choices = [pd.name
            for pd in self.provider_cog.provider_definitions
        ]
        self.autocomplete_func = self.provider_name_autocomplete

        super(SubscriberCog, self).__init__()
        self.first_run = True

    @commands.Cog.listener()
    async def on_ready(self):
        if self.first_run:
            self.start_services()
            self.first_run = False

    def find_task_key(self, task: asyncio.Task):
        for key, t in self.tasks.items():
            if t == task:
                return key

    def provider_factory(self, member: discord.Member, name: str):
        return self.provider_cog.find_provider_instance_by_member_and_name(member, name)

    def start_services(self):
        for guild_str in self.config_settings.keys():
            guild = self.bot.get_guild(int(guild_str))
            if guild is None:
                continue
            for member_str in self.config_settings[guild_str].keys():
                member = guild.get_member(int(member_str))
                if member is None:
                    continue
                provider_names = self.config_settings[guild_str][member_str]['provider_settings'].keys()
                for name in list(provider_names):
                    interval = string_timedelta(self.config_settings[guild_str][member_str]['provider_settings'][name]['interval'])
                    provider = self.provider_cog.find_provider_instance_by_member_and_name(member, name)
                    factory = partial(self.provider_factory, member=member, name=name)
                    if provider is not None:
                        self.start_provider_service(guild_str, member_str, name, factory, interval)

    def start_provider_service(self, guild_id: str, member_id: str, name: str, factory: Callable, interval: timedelta):
        composite_key = f"{guild_id}{member_id}{name}"
        if composite_key in self.tasks:
            task = self.tasks[composite_key]
            if task is not None:
                log.debug("Cancelling Task")
                task.cancel()
        pts = ProviderTaskService(name, factory, self.task_callback, interval)
        task = pts.start()
        self.tasks[composite_key] = task
        log.debug(f"Provider Service Task started for {member_id}")

    def establish_config(self, guild_id: str, member_id: str):
        establish_member_config(self.config_settings, guild_id, member_id)
        if len(self.config_settings[guild_id][member_id].keys()) == 0:
            self.config_settings[guild_id][member_id]['provider_settings'] = {}

    async def provider_name_autocomplete(self, itx: Interaction, current: str) -> List[app_commands.Choice[str]]:
        choices = [
            app_commands.Choice(name=name, value=name)
            for name in self.provider_choices
            if current.lower() in name.lower()
        ]

        return choices

    @app_commands.command()
    async def config(self, itx: Interaction, provider_name: str):
        try:

            current_config = self.config_settings[str(itx.guild_id)][str(itx.user.id)]['provider_settings'][provider_name]
        except KeyError:
            current_config = {}
        await itx.response.send_modal(SubscriberConfigModal(provider_name, self.modal_callback, current_config))

    def make_embed(self, count: int, settings) -> discord.Embed:
        embed = discord.Embed(description=settings['text'].format(count=count))
        embed.set_image(url=settings['banner_url'])
        embed.timestamp = datetime.now(timezone.utc)
        return embed

    async def update_embed(self, member: discord.Member, embed:  discord.Embed, settings):
        channel_id = int(settings['channel_id'])
        message_id = settings['message_id'] and int(settings['message_id'])
        channel = member.guild.get_channel(channel_id)
        new_message = False
        message = None
        if channel is None:
            log.warning(f"{channel_id} on Guild {member.guild.name} No longer available")
            return
        try:

            if message_id is not None:
                log.debug(f"Editing partial message for {settings['message_id']}")
                partial_message = channel.get_partial_message(message_id)
                message = await partial_message.edit(embed=embed)
            else:
                log.debug("Sending new message")
                message = await channel.send(embed=embed)
                new_message = True
        except discord.NotFound:
            log.info(f"Discord unable to locate message {message_id}")
            message = await channel.send(embed=embed)
            new_message = True
        except discord.Forbidden as e:
            log.error(f"Coud not send message to {channel.name} in Guild {member.guild.name} No Permissions {e}")

        return message, new_message

    async def task_callback(self, provider_name: str, provider: Provider):
        log.debug(f"In task callback for {provider_name}")
        for guild_str in self.config_settings.keys():
            guild = self.bot.get_guild(int(guild_str))
            if guild is None:
                continue
            for member_str in self.config_settings[guild_str].keys():
                member = guild.get_member(int(member_str))
                if member is None:
                    log.debug(f"Member {member_str} does not exist in Guild {guild_str}")
                    continue
                log.debug(f"Found member {member}")
                settings = self.config_settings[guild_str][member_str]['provider_settings'].get(provider_name)
                if settings is not None:
                    try:
                        count = await provider.subscriber_count()
                        embed = self.make_embed(count, settings)
                        message, new_message = await self.update_embed(member, embed, settings)
                        if message is not None and new_message:
                            settings = self.config_settings[guild_str][member_str]['provider_settings'][provider_name]['message_id'] = message.id
                            self.save_settings()
                    except KeyError as e:
                        log.error(f"KeyError on subscription settings: {settings}: {e}")
                else:
                    log.warning(f"Could not find settings for {provider_name} Guild: {guild_str} Member: {member_str}")
        log.debug("Task callback finished")

    async def modal_callback(self, itx: Interaction, provider_name: str, payload: Dict[str, Any]):
        guild_str = str(itx.guild_id)
        member_str = str(itx.user.id)
        log.debug(payload)
        channel = itx.guild.get_channel(int(payload['channel_id']))
        interval = string_timedelta(payload['interval'])
        if interval is None:
            await itx.followup.send("Interval not valid format. ex: 1d2h3m4s. Changes not saved.", ephemeral=True)
            return
        if channel is None:
            await itx.followup.send("Channel not found. Changes not saved.", ephemeral=True)
            return

        self.establish_config(guild_str, member_str)
        if provider_name not in self.config_settings[guild_str][member_str]['provider_settings'].keys():
            self.config_settings[guild_str][member_str]['provider_settings'][provider_name] = {}
        if len(self.config_settings[guild_str][member_str]['provider_settings'][provider_name].keys()) >= 1:
            self.config_settings[guild_str][member_str]['provider_settings'][provider_name].update(payload)
        else:
            payload.update({'message_id': None})
            self.config_settings[guild_str][member_str]['provider_settings'][provider_name] = payload
        self.save_settings()
        provider = self.provider_cog.find_provider_instance_by_member_and_name(itx.user, provider_name)
        if provider is not None:
            factory = partial(self.provider_factory, member=itx.user, name=provider_name)
            self.start_provider_service(guild_str, member_str, provider_name, factory, interval)
        else:
            log.error(f"Could not start provider service {provider_name} for {itx.user.name} in {itx.guild.name}")
        await itx.followup.send(f"Settings for {provider_name} saved.", ephemeral=True)

async def setup(bot: commands.Bot):
    provider_cog = bot.get_cog('provider')
    if provider_cog is not None:
        await bot.add_cog(SubscriberCog(bot, provider_cog))
        log.debug("Subscriber Cog loaded with Provider Cog instnace")
    else:
        log.error("SubscriberCog could not find reference to ProviderCog. Not Loaded.")

class SubscriberConfigModal(ui.Modal):
    channel_id = ui.TextInput(label="Enter Channel ID to post to.")
    text = ui.TextInput(label="Enter message. Use {count} to substitute")
    banner_url = ui.TextInput(label="Banner Image URL")
    interval = ui.TextInput(label="Enter the update interval (ex 1d2h3m4s)", placeholder="5m")

    def __init__(self, provider_name: str, callback: Callable, current_config: Optional[Dict[str, str]], **kwargs):
        log.debug(current_config)
        if current_config is not None:
            self.channel_id.default = current_config.get('channel_id', '')
            self.text.default = current_config.get('text', '')
            self.banner_url.default = current_config.get('banner_url', '')
            self.interval.default = current_config.get('interval', '')
        super().__init__(title=f"Configure Subscriber Alert for {provider_name}", **kwargs)
        self.provider_name = provider_name
        self.callback = callback

    async def on_submit(self, itx: Interaction) -> None:
        await itx.response.defer()
        payload = {
            'text': self.text.value,
            'banner_url': self.banner_url.value,
            'channel_id': self.channel_id.value,
            'interval': self.interval.value
        }
        await self.callback(itx, self.provider_name, payload)


# -*- coding: utf-8 -*-
"""
Created on Tue May  8 13:33:25 2018

@author: Admin
"""

import sys
from pyspark import SparkContext

if __name__ == "__main__":
    sc = SparkContext("local[3]", "word count")

    sc.setLogLevel("ERROR")

    lines = sc.textFile("in/word_count.text")

    words = lines.flatMap(lambda line: line.split(" "))

    wordCounts = words.countByValue()
    for word, count in wordCounts.items():
        print(word, count)


# Import: Standard Python Libraries

import os
import sys
import yaml
import time
import shutil
import atexit
import subprocess

from kubernetes import client, config
from jinja2 import Environment, FileSystemLoader

# Create: Response, Program Exit

def exit_handler():

    config.load_kube_config()

    v1 = client.CoreV1Api()

    pod_list = v1.list_namespaced_pod(namespace = params["resources"]["namespace"])

    current_group = [ele.metadata.owner_references[0].name for ele in pod_list.items if(params["helpers"]["kill_tag"] in ele.metadata.name)]

    current_group = list(set(current_group))

    for job_name in current_group:
        subprocess.run(["kubectl", "delete", "job", job_name])

    print("\nCleaned up any jobs that include tag : %s\n" % params["helpers"]["kill_tag"])

# Create: Results Folders

def create_folder(path):

    if(os.path.exists(path)):
        shutil.rmtree(path)

    os.makedirs(path)

# Save: Template File

def save_file(path, data):

    data_file = open(path, "w")

    data_file.write(data)

    data_file.close()

# Load: Template File

def load_file(path):

    data_file = open(path, "r")

    info = ""

    for line in data_file:
        info += line

    data_file.close()

    return info

# Run: Parallelized Physics Simulatiion

def run_generation(params):

    # Load: Job Template

    template = load_file(params["paths"]["template"])

    tag = params["paths"]["template"].split("/")[-1]
    folder = params["paths"]["template"].replace("/%s" % tag, "")
    environment = Environment(loader = FileSystemLoader(folder))
    template = environment.get_template(tag)

    # Launch: Algorithm Jobs

    create_folder(params["paths"]["job_files"])

    # - Begin: Algorithm Analysis

    print("\nLaunching Algorithm Jobs\n")

    num_exps = len(params["helpers"]["dataset_names"]) * len(params["helpers"]["algorithm_names"])

    counter = 0

    current_group = []

    for data_name in params["helpers"]["dataset_names"]:

        path_train = os.path.join(params["paths"]["root_data"], data_name, "train")
        path_valid = os.path.join(params["paths"]["root_data"], data_name, "valid")
        path_test = os.path.join(params["paths"]["root_data"], data_name, "test")

        for alg_name in params["helpers"]["algorithm_names"]:

            path_results = os.path.join(params["paths"]["root_results"], data_name, alg_name)

            if(sys.platform == "win32"):
                path_results = path_results.replace("\\", "/")
                path_train = path_train.replace("\\", "/")
                path_valid = path_valid.replace("\\", "/")
                path_test = path_test.replace("\\", "/")

            # -- Launch jobs if there is room in processing group

            if(len(current_group) < params["helpers"]["parallel_ops"]):

                num_to_launch = params["helpers"]["parallel_ops"] - len(current_group)

                for i in range(num_to_launch):

                    # --- Configure algorithm job

                    job_name = "%s-%s" % (params["helpers"]["kill_tag"], str(counter).zfill(6))

                    path_log = os.path.join(params["paths"]["root_logs"], "%s.log" % (job_name))

                    if(sys.platform == "win32"):
                        path_log = path_log.replace("\\", "/")

                    current_group.append(job_name)

                    template_info = {"job_name": job_name,
                                     "mem_lim": params["resources"]["mem_lim"],
                                     "mem_req": params["resources"]["mem_req"],
                                     "num_cpus": str(params["resources"]["cpus_per_op"]),
                                     "num_gpus": str(params["resources"]["gpus_per_op"]),

                                     "log": path_log,
                                     "test": path_test,
                                     "valid": path_valid,
                                     "train": path_train,
                                     "results": path_results,

                                     "arch": alg_name,

                                     "image": params["paths"]["container_image"]}

                    filled_template = template.render(template_info)

                    path_job = os.path.join(params["paths"]["job_files"], job_name + ".yaml")

                    if(sys.platform == "win32"):
                        path_job = path_job.replace("\\", "/").replace("/", "\\")

                    # --- Save simulation job file

                    save_file(path_job, filled_template)

                    # --- Launch simulation job

                    subprocess.run(["kubectl", "apply", "-f", path_job])

                    counter += 1

            # -- Otherwise wait for a processes to finish

            else:

                k = 0
                check_time_min = 2
                wait_time_sec = 60

                while(len(current_group) == params["helpers"]["parallel_ops"]):

                    time.sleep(wait_time_sec)

                    # --- Check progress every n minutes

                    if(k % check_time_min == 0):

                        # --- Gather kubernetes information

                        config.load_kube_config()
                        v1 = client.CoreV1Api()
                        pod_list = v1.list_namespaced_pod(namespace = params["resources"]["namespace"], timeout_seconds = 300)

                        if(k == 0):
                            print()

                        pod_list = [item for item in pod_list.items if(params["helpers"]["kill_tag"] in item.metadata.name)]

                        pod_names = [item.metadata.name for item in pod_list]
                        pod_statuses = [item.status.phase for item in pod_list]

                        # --- Remove pods that have finished. Jobs and pods share the same name.

                        pod_progress = [1 if(phase == "Succeeded" or phase == "Error") else 0 for phase in pod_statuses]

                        for i, (job_name, remove_flag) in enumerate(zip(current_group, pod_progress)):
                            if(remove_flag):
                                print()
                                #time.sleep(wait_time_sec)
                                subprocess.run(["kubectl", "delete", "job", job_name])
                                current_group.pop(i)
                                print()

                        print("Log: Elapsed Time = %s minutes, Group Size = %s, Total (In Progress) = %s / %s" % ((wait_time_sec * (k + 1)) / 60, len(current_group), counter, num_exps))

                        if(sum(pod_progress) > 0):
                            print("\nJobs Finished. Updating...\n")
                            break

                    k += 1

    print("\nData Generation Complete\n")

# Validate: Configuration File

def load_config(argument):

    try:
        return yaml.load(open(argument), Loader = yaml.FullLoader)

    except Exception as e:
        print("\nError: Loading YAML Configuration File")
        print("\nSuggestion: Using YAML file? Check File For Errors\n")
        print(e)
        exit()

# Parse: Command-line Arguments

def parse_args(all_args, tags = ["--", "-"]):

    all_args = all_args[1:]

    if(len(all_args) % 2 != 0):
        print("Argument '%s' not defined" % all_args[-1])
        exit()

    results = {}

    i = 0
    while(i < len(all_args) - 1):
        arg = all_args[i].lower()
        for current_tag in tags:
            if(current_tag in arg):
                arg = arg.replace(current_tag, "")
        results[arg] = all_args[i + 1]
        i += 2

    return results

# Main: Load Configuration File

if __name__ == "__main__":

    args = parse_args(sys.argv)

    params = load_config(args["config"])

    atexit.register(exit_handler)  # this is how we clean up jobs.

    run_generation(params)


#encoding utf-8

import math
from functools import reduce

#複数の最大コゥ約数
def gcd(a,b):
    l = max(a,b)
    m = min(a,b)
    while m != 0:
        extra = l%m
        l = m
        m = extra
    return l

def gcd_multi(numbers):
    return reduce(gcd,numbers)

n,X = map(int, input().split())

x = [int(i) for i in input().split()]

x.append(X)
x.sort()

minus=[]

for i in range(len(x)-1):
    minus.append(x[i+1]-x[i])

D = gcd_multi(minus)

print(int(D))


from django import forms
from .models import Sheet, Checklist

class SheetForm(forms.ModelForm):
    class Meta:
        model = Sheet
        fields = [
            'name',
            'start_date',
            'employment_type',
            'title',
            'department',
            'sub_department',
            'team',
            'sub_team',
            'reports_to',
            'location',
            'personal_email',
            'address',
            'email',
            'manager',

        ]
    # Ensures validity of null ImageField
    def __init__(self, *args, **kwargs):
        super(SheetForm, self).__init__(*args, **kwargs)

class ChecklistForm(forms.ModelForm):
    class Meta:
        model = Checklist
        fields = [
            'jira_ticket_closed',
            'reach_out_to_manager',
            'device_type',
            'computer_shipped',

            'confirm_in_gmail',
            'reach_out_hiring_managers_with_email',
            'reach_out_to_Lorraine_with_email_and_tracking_info',
            'add_employee_id_to_google_profile',
            'add_to_google_groups',

            'add_to_active_directory',
            'add_to_active_directory_developers',
            'add_to_active_directory_infrastructure',

            'invite_to_Atlassian',

            'confirm_in_okta',
            'add_to_okta_groups',

            'invite_to_1Password',
            'invite_to_Slack',
            'invite_to_Looker',
            'invite_to_CodeSignal',

            'add_vmware_workspace',

            # SGE
            'add_to_SGE_google_groups',
            'add_to_Teamwork_Global',
            'add_to_Salesforce_in_okta',
            'send_username_to_Autumn_Young_for_Salesforce',
            'add_to_TalkDesk',
            'add_to_OpenAdmin',
            'add_to_extra_Google_Groups',
            'add_to_1Password_US_SGE_Group',
            'add_to_microsoft_office_365',

            # After user logs ins
            'sign_in_Okta',
            'user_index_flip_to_128',

            'ask_clx_sge_new_hire_to_allow_access_to_nro',
            'create_nro_account',
        ]
    # Ensures validity of null ImageField
    def __init__(self, *args, **kwargs):
        super(ChecklistForm, self).__init__(*args, **kwargs)


import os.path

# noinspection PyPackageRequirements
from behave import given, then

from django.utils.text import slugify

from ..utils import get_screenshot, get_url

from library.testing.data_compare.image import image_diff

@then('the page is verified to be correct')
def verify_page(context):
    _verify_page(context)

@given('the user goes to the home page')
def home_page(context):
    context.browser.visit(get_url(context, '/'))

def _verify_page(context, crop=None, full_page=True, remove_mouse=True, tolerance=10):
    if context.check_images:
        base_filename = '{}-{:0>2}.png'.format(slugify(context.scenario.name), context.screen_shot)
        expected_image_file = os.path.join(context.top_dir, context.master_image_dir, base_filename)

        assert os.path.isfile(expected_image_file), \
            f'can not find "{expected_image_file}" for comparison to screen shot'

        # The trade-off for getting the full page is that it's slower than just getting a screenshot but will get the
        # entire web page no matter what parts are off the screen

        image_diff(
            expected_image_file,
            get_screenshot(context, full_page=full_page, remove_mouse=remove_mouse),
            crop2=crop,
            save2_if_err=base_filename,
            tolerance=tolerance
        )

    context.screen_shot += 1


import sys
import cv2 as cv

# defining face detector
face_cascade = cv.CascadeClassifier(cv.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv.CascadeClassifier(cv.data.haarcascades + 'haarcascade_eye.xml')
ds_factor = 0.6

class VideoCamera:
    """
    No docs :)
    """

    def __init__(self):
        self.video = cv.VideoCapture(0)

    def __del__(self):
        self.video.release()

    def get_frame(self, detect_faces=True):
        ret, frame = self.video.read()
        if not ret:
            print('Can not retrieve a frame. Exit.')
            sys.exit()
        if detect_faces:
            frame = self.detect_faces(frame)
        colour = cv.cvtColor(frame, cv.COLOR_BGR2BGRA)

        return colour

    def get_jpg_frame(self):
        ret, jpeg = cv.imencode('.jpg', img=self.get_frame())
        return jpeg.tobytes()

    def show_frames(self):
        print('Click "q" to exit')

        while True:
            gray_frame = self.get_frame()
            cv.imshow('frame', gray_frame)
            if cv.waitKey(1) == ord('q'):
                break
        cv.destroyAllWindows()

    @staticmethod
    def detect_faces(frame):
        frame = cv.resize(frame, None, fx=ds_factor, fy=ds_factor, interpolation=cv.INTER_AREA)
        gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)

        for (x, y, w, h) in faces:
            cv.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = frame[y:y + h, x:x + w]
            eyes = eye_cascade.detectMultiScale(roi_gray)
            for (ex, ey, ew, eh) in eyes:
                cv.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)

        return frame

if __name__ == '__main__':
    # just to test a face detection directly without web stuff
    vc = VideoCamera()
    vc.show_frames()
    del vc


# 1600. 皇位继承顺序

# 一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点，这个家庭里有人出生也有人死亡。

# 这个王国有一个明确规定的皇位继承顺序，第一继承人总是国王自己。我们定义递归函数 Successor(x, curOrder) ，给定一个人 x 和当前的继承顺序，该函数返回 x 的下一继承人。

# Successor(x, curOrder):
#     如果 x 没有孩子或者所有 x 的孩子都在 curOrder 中：
#         如果 x 是国王，那么返回 null
#         否则，返回 Successor(x 的父亲, curOrder)
#     否则，返回 x 不在 curOrder 中最年长的孩子
# 比方说，假设王国由国王，他的孩子 Alice 和 Bob （Alice 比 Bob 年长）和 Alice 的孩子 Jack 组成。

# 一开始， curOrder 为 ["king"].
# 调用 Successor(king, curOrder) ，返回 Alice ，所以我们将 Alice 放入 curOrder 中，得到 ["king", "Alice"] 。
# 调用 Successor(Alice, curOrder) ，返回 Jack ，所以我们将 Jack 放入 curOrder 中，得到 ["king", "Alice", "Jack"] 。
# 调用 Successor(Jack, curOrder) ，返回 Bob ，所以我们将 Bob 放入 curOrder 中，得到 ["king", "Alice", "Jack", "Bob"] 。
# 调用 Successor(Bob, curOrder) ，返回 null 。最终得到继承顺序为 ["king", "Alice", "Jack", "Bob"] 。
# 通过以上的函数，我们总是能得到一个唯一的继承顺序。

# 请你实现 ThroneInheritance 类：

# ThroneInheritance(string kingName) 初始化一个 ThroneInheritance 类的对象。国王的名字作为构造函数的参数传入。
# void birth(string parentName, string childName) 表示 parentName 新拥有了一个名为 childName 的孩子。
# void death(string name) 表示名为 name 的人死亡。一个人的死亡不会影响 Successor 函数，也不会影响当前的继承顺序。你可以只将这个人标记为死亡状态。
# string[] getInheritanceOrder() 返回 除去 死亡人员的当前继承顺序列表。

import collections
from typing import List

class ThroneInheritance:

    def __init__(self, kingName: str):
        self.root = kingName
        self.treeDict = collections.defaultdict(list)
        self.deathStatus = set()

    def birth(self, parentName: str, childName: str) -> None:
        self.treeDict[parentName].append(childName)

    def death(self, name: str) -> None:
        self.deathStatus.add(name)

    def getInheritanceOrder(self) -> List[str]:
        ans = []
        if  self.root not in self.deathStatus:
            ans.append(self.root)
        def inOrder(r):
            for node in self.treeDict[r]:
                if node not in self.deathStatus:
                    ans.append(node)
                if node in self.treeDict:
                    inOrder(node)
        inOrder(self.root)
        return ans

t= ThroneInheritance("king") #继承顺序：king
t.birth("king", "andy") #继承顺序：king > andy
t.birth("king", "bob") #继承顺序：king > andy > bob
t.birth("king", "catherine") #继承顺序：king > andy > bob > catherine
t.birth("andy", "matthew") #继承顺序：king > andy > matthew > bob > catherine
t.birth("bob", "alex") #继承顺序：king > andy > matthew > bob > alex > catherine
t.birth("bob", "asha") #继承顺序：king > andy > matthew > bob > alex > asha > catherine
print(t.getInheritanceOrder()) #返回 ["king", "andy", "matthew", "bob", "alex", "asha", "catherine"]
t.death("bob") #继承顺序：king > andy > matthew > bob（已经去世）> alex > asha > catherine
print(t.getInheritanceOrder()) #返回 ["king", "andy", "matthew", "alex", "asha", "catherine"]


#!/usr/bin/env python

#importing modules

import cv2
import numpy as np

import rospy
from youbot_ros_hello_world.msg import Num

from std_msgs.msg import String

Px = 0
Py = 0
Mx = 0
My = 0
Cx = 0
Cy = 0
x = 0

#capturing video through webcam. If using an external webcame, change the "0" to "1"
cap=cv2.VideoCapture(0)

#talker() is how we send info to the cpp file
def talker():
    pub = rospy.Publisher('centroids', Num)
    rospy.init_node('centroids_talker', anonymous=True)
    msg= Num()
    msg.Pepsi_x = Px
    msg.Pepsi_y = Py
    msg.DietMTD_x = Mx
    msg.DietMTD_y = My
    msg.Coke_x = Cx
    msg.Coke_y = Cy
    rospy.loginfo(msg)
    pub.publish(msg)

#This is the main program.
def camera():

    _, original = cap.read()
    _, img = cap.read()

	#crops the imag. Original is 480x640
    img = img[200:400, 0:640]

	#blurs the image to eliminate noise
    img = cv2.medianBlur(img,15)

    #converting to HSV (hue-saturation-value)
    hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

    #definig the range of Coke color
    red_lower=np.array([136,87,111],np.uint8)
    red_upper=np.array([180,255,255],np.uint8)

    #defining the Range of Pepsi lid
    Pepsi_lower=np.array([105,110,50],np.uint8)
    Pepsi_upper=np.array([119,200,200],np.uint8)

    #defining the Range of Diet Mt. Dew lid (DietMTD/white)
    DietMTD_lower=np.array([75,0,228],np.uint8)
    DietMTD_upper=np.array([103,52,255],np.uint8)

    #finding the range of red,Pepsi and DietMTD color in the image
    red=cv2.inRange(hsv, red_lower, red_upper)
    Pepsi=cv2.inRange(hsv,Pepsi_lower,Pepsi_upper)
    DietMTD=cv2.inRange(hsv,DietMTD_lower,DietMTD_upper)

    #Morphological transformation, Dilation
    kernal = np.ones((5 ,5), "uint8")

    red=cv2.dilate(red, kernal)
    res=cv2.bitwise_and(img, img, mask = red)

    Pepsi=cv2.dilate(Pepsi,kernal)
    res1=cv2.bitwise_and(img, img, mask = Pepsi)

    DietMTD=cv2.dilate(DietMTD,kernal)
    res2=cv2.bitwise_and(img, img, mask = DietMTD)

    #Tracking the Coke Color
    (_,contours,hierarchy)=cv2.findContours(red,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

    for pic, contour in enumerate(contours):
        area = cv2.contourArea(contour)
        if(area>300):

            x,y,w,h = cv2.boundingRect(contour)
            img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)
            cv2.putText(img,"RED color",(x,y),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,255))

           	# compute the center of the contour
            M = cv2.moments(contour)
            global Cx
            global Cy
            Cx = int(M["m10"] / M["m00"])
            Cy = int(M["m01"] / M["m00"])

	        # draw the contour and center of the shape on the image
            cv2.circle(img, (Cx, Cy), 3, (255, 255, 255), -1)

    #Tracking the Pepsi Color
    (_,contours,hierarchy)=cv2.findContours(Pepsi,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    for pic, contour in enumerate(contours):
        area = cv2.contourArea(contour)
        if(area>500):
            x,y,w,h = cv2.boundingRect(contour)
            img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
            cv2.putText(img,"Pepsi",(x,y),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,0,0))

           	# compute the center of the contour
            M = cv2.moments(contour)
            global Px
            global Py
            Px = int(M["m10"] / M["m00"])
            Py = int(M["m01"] / M["m00"])

	        # draw the contour and center of the shape on the image
            cv2.circle(img, (Px, Py), 3, (255, 255, 255), -1)

    #Tracking the DietMTD Color
    (_,contours,hierarchy)=cv2.findContours(DietMTD,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    for pic, contour in enumerate(contours):
        area = cv2.contourArea(contour)
        if(area>500):
            x,y,w,h = cv2.boundingRect(contour)
            img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
            cv2.putText(img,"Diet Mountain Dew",(x,y),cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0,255,0))

           	# compute the center of the contour
            M = cv2.moments(contour)
            global Mx
            global My
            Mx = int(M["m10"] / M["m00"])
            My = int(M["m01"] / M["m00"])

	        # draw the contour and center of the shape on the image
            cv2.circle(img, (Mx, My), 3, (255, 255, 255), -1)

    cv2.imshow("Color Tracking",img)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        cap.release()
        cv2.destroyAllWindows()

while not rospy.is_shutdown():
    camera()
    talker()

	#Lets me see the approx frames/second the webcam is getting
    x = x+1
    print(x)


import pandas as pd
import json

from pandas import DataFrame
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import linear_kernel

class Keys:
    def __init__(self, target, user_input="input/user_input.json"):
        self.similarity_matrix = list()
        self.mapping = list()
        self.target = target
        self.modules = json.loads(open("input/modules.json").read())
        self.user_input = json.loads(open(user_input).read())
        self.user_df = pd.DataFrame()
        self.tf_idf = TfidfVectorizer(stop_words="english")

    def __convert_json_scalars__(self, scalar: list) -> str:
        """
        Converts a list of scalars into a comma separated string. This is used to convert the skills, education, etc.
        into a single string that can be appended to a DataFrame row.
        :param scalar: A list of strings to be converted into a comma separated string.
        :rtype: str
        """
        temp_string = ""
        for index, value in enumerate(scalar):
            if index == len(scalar) - 1:
                temp_string += value
            else:
                temp_string += value + ", "

        return temp_string

    def __read_input(self):
        df = pd.DataFrame(
            columns=[
                "id",
                "skills",
                "education",
                "work_experience",
                "courses",
                "focus",
                "degree",
            ],
            index=[0],
        )

        df["id"] = self.user_input["id"]

        df["skills"] = self.__convert_json_scalars__(scalar=self.user_input["skills"])

        df["education"] = self.__convert_json_scalars__(
            scalar=self.user_input["education"]
        )

        df["work_experience"] = self.__convert_json_scalars__(
            scalar=self.user_input["work_experience"]
        )

        df["courses"] = self.user_input["courses"]

        df["focus"] = self.user_input["focus"]

        df["degree"] = self.user_input["degree"]

        self.user_df = df

    def __read_modules(self):
        df = pd.DataFrame(
            columns=[
                "id",
                "moduleName",
                "description",
                "intro",
                "keywords",
                "objectives",
            ],
            index=[i for i in range(len(self.modules))],
        )

        for index, module in enumerate(self.modules):
            df.iloc[index]["id"] = module["id"]["$oid"]
            df.iloc[index]["moduleName"] = module["moduleName"]
            df.iloc[index]["description"] = module["description"]
            df.iloc[index]["intro"] = module["intro"]
            df.iloc[index]["keywords"] = self.__convert_json_scalars__(
                scalar=module["keywords"]
            )
            df.iloc[index]["objectives"] = self.__convert_json_scalars__(
                scalar=module["objectives"]
            )

        self.modules_df = df

    def __analyze_modules(self):
        keyword_matrix = self.tf_idf.fit_transform(self.modules_df["keywords"])

        similarity_matrix = linear_kernel(keyword_matrix, keyword_matrix)

        mapping = pd.Series(self.modules_df.index, index=self.modules_df["moduleName"])

        self.similarity_matrix = similarity_matrix

        self.mapping = mapping

    def recommend_movies_based_on_plot(self, query, mapping, matrix):
        movie_index = mapping[query]

        # get similarity values with other movies
        # similarity_score is the list of index and similarity matrix
        similarity_score = list(enumerate(matrix[movie_index]))

        # sort in descending order the similarity score of movie inputted with all the other movies
        for index, s in enumerate(similarity_score):
            id = s[0]
            scores = s[1]

            # sort scores in descending order
            scores = sorted(scores, key=lambda x: x, reverse=True)

            similarity_score[index] = (id, scores)

        # Get the scores of the 15 most similar movies. Ignore the first movie.
        similarity_score = similarity_score[1:15]

        # return movie names using the mapping series
        movie_indices = [i[0] for i in similarity_score]

        return self.modules_df.iloc[movie_indices]

    def run(self) -> str:
        """
        Runs the entire system in a sequential order.
        """
        self.__read_input()
        self.__read_modules()
        self.__analyze_modules()
        recommendation: DataFrame = self.recommend_movies_based_on_plot(
            self.target, mapping=self.mapping, matrix=self.similarity_matrix
        )
        return recommendation.to_json(orient="records")

def main():
    """
    Main function to run the system. Instantiates the Keys class and runs the entry method.
    """
    keys = Keys(target="Namfix")
    keys.run()

if __name__ == "__main__":
    main()


from django.urls import path
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
    TokenVerifyView,
)

from . import views

urlpatterns = [
    path("signup/", views.SignUpView.as_view(), name="signup"),
    path("login/", views.LoginView.as_view(), name="login"),
    path("jwt/create/", TokenObtainPairView.as_view(), name="jwt_create"),
    path("jwt/refresh/", TokenRefreshView.as_view(), name="token_refresh"),
    path("jwt/verify/", TokenVerifyView.as_view(), name="token_verify"),
]


import argparse
import random
from datetime import datetime, timedelta
from math import log
import os
from time import sleep

from sqlalchemy import create_engine
from sqlalchemy.sql import text

DSN = None

parser = argparse.ArgumentParser(
    description='AlarStudios test task 2. Test data generates for current date as start point')
parser.add_argument('min_date')
parser.add_argument('max_date')
args = parser.parse_args()

min_date, max_date = args.min_date, args.max_date

engine = create_engine(DSN, convert_unicode=True)
connection = engine.connect()

connection.execute(open(os.path.dirname(os.path.dirname(__file__)) + 'init.sql', 'r').read())

min_id, max_id = list(connection.execute("SELECT MIN(id), MAX(id) FROM task"))[0]
max_date = (datetime.strptime(max_date, "%Y-%m-%d") + timedelta(days=1)).strftime("%Y-%m-%d")

def get_id_with_bt(ts, min_id, max_id, direction="min"):
    max_iteration_number = int(log(max_id - min_id + 1, 2)) + 1

    for _ in xrange(max_iteration_number):
        middle = (max_id - min_id) / 2 + min_id

        sql = """SELECT "timestamp" FROM task WHERE id = :middle AND "timestamp" >= :ts"""
        is_grater = len(list(connection.execute(text(sql), middle=middle, ts=ts))) == 1

        if is_grater:
            max_id = middle
        else:
            min_id = middle

    return max_id if direction == "min" else min_id

min_id = get_id_with_bt(min_date, min_id, max_id, direction="min")
max_id = get_id_with_bt(max_date, min_id, max_id, direction="max")

for i in xrange(min_id, max_id + 1, 100):
    connection.execute(text("""DELETE FROM task WHERE id BETWEEN :min AND :max AND
                               "timestamp" >= :min_date AND "timestamp" < :max_date"""),
                       min=i, max=(i + 99), min_date=min_date, max_date=max_date)
    sleep(0.1 + random.random() * 0.2)

connection.close()


import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import os

from model import *

os.makedirs("../BPNN", exist_ok=True)
dir_selected = '../BPNN/'

def data_plot(M=None, M_without_noise=None, M_filtered=None, t=None, material=None, ta=None, tb=None, shape=None,
              file=None, filter=None, dir_save=None, label=None):
    fig, ax = plt.subplots()
    ax.set_xscale("log")
    ax.set_yscale("log")
    ax.set_xlim(1e-8, 1e1)
    plt.plot(t, M_without_noise, '--', color="r", label=label + "_noiseless")
    plt.plot(t, M, 'o', color="g", label=label + "_noise")
    plt.plot(t, M_filtered, '*', color="y", label=label + "_filted")
    plt.xlabel("t /s")
    plt.ylabel("Response")
    plt.title("snr=" + "%d" % file + " material=" + material + " ta=" + "%.2f" % ta + " tb=" + "%.2f" % tb +
              " shape=" + "%d" % shape + " filter=" + filter + " " + str(label))
    plt.savefig(dir_save + " " + "snr=" + "%d" % file + " material=" + material + " ta=" + "%.2f" % ta +
                " tb=" + "%.2f" % tb + " shape=" + "%d" % shape + " filter=" + filter + " " + str(label) + '.png')
    plt.savefig(dir_save + " " + "snr=" + "%d" % file + " material=" + material + " ta=" + "%.2f" % ta +
                " tb=" + "%.2f" % tb + " shape=" + "%d" % shape + " filter=" + filter + " " + str(label) + '.eps')
    plt.legend()
    # plt.show()
    plt.close()

# 以信噪比20为例，对数据集进行划分
def data_split():
    data = pd.read_csv('./generate data/noisy signal/M1_response_curve_sum_snr20_M1.csv', )
    # 数据概况预览
    feature_lable = np.array(data)
    feature = feature_lable[:, 3:feature_lable.shape[1]]
    X = feature
    print("开始划分数据集:-------------------------------")
    X_train, X_test = X[:-100], X[-100:]
    pd.DataFrame(X_train).to_csv('./generate data/noisy signal/M1_response_curve_sum_snr20_M1_train.csv')
    pd.DataFrame(X_test).to_csv('./generate data/noisy signal/M1_response_curve_sum_snr20_M1_test.csv')
    return X_train, X_test

# 获取数据
signal_path = './generate data/test1/M1_response_curve_sum_summary_total_train.csv'
signal = np.array(pd.read_csv(signal_path))
signal_noisy = signal[:, 7:207]
signal_clean = signal[:, 212:413]

# 获取测试数据
signal_test_path = './generate data/test1/M1_response_curve_sum_summary_total_test.csv'
signal_test = np.array(pd.read_csv(signal_test_path))
signal_clean_special = signal_test[:1000, 212:413]
signal_noisy_special = signal_test[:1000, 7:207]
ta = signal_test[:1000, 2:3]
tb = signal_test[:1000, 3:4]
material_num = signal_test[:1000, 4:5]
snr = signal_test[:1000, 5:6]
shape_flag = signal_test[:1000, 6:7]

# --------------------------------------------------------------------------------------------
model = BP() # 使用不同优化算法的神经网络
model.compile(loss='mean_squared_error', optimizer='Adam')  # 编译模型
model.fit(signal_noisy, signal_clean, epochs=500, batch_size=128)  # 训练模型nb_epoch=50次
model.summary()  # 模型描述

# 在训练集上的拟合结果
y_train_predict = model.predict(signal_noisy)
y_test_predict = model.predict(signal_noisy_special)
pd.DataFrame(y_test_predict).to_csv('./generate data/test1/' + 'y_test_predict.csv')

pd.DataFrame(np.vstack((signal_clean_special, signal_noisy_special, y_test_predict))).to_csv('./generate data/test1/' + 'signal_test.csv')

def BP_run():
    t = np.array(10 ** (np.linspace(-8, 0, 200)))
    material = ''
    lable = 'M1'
    success_list = []

    for i in range(len(y_test_predict)):
        print(i)

        filted_result = ''
        lable = 'M1'
        M = signal_noisy_special[i]
        M_without_noise = signal_clean_special[i]
        M_filtered = y_test_predict[i]
        ta_special = ta[i]
        material_num_special = material_num[i]
        tb_special = tb[i]
        snr_special = snr[i]
        shape_flag_special = shape_flag[i]

        if material_num_special == 0:
            material = 'Steel'
        if material_num_special == 1:
            material = 'Ni'
        if material_num_special == 2:
            material = 'Al'

        data_plot(M=M, M_without_noise=M_without_noise, M_filtered=M_filtered, t=t, material=material, ta=ta_special, tb=tb_special,
                  shape=shape_flag_special, file=snr_special, filter='BPNN-OP', dir_save=dir_selected, label=lable)

        # 保存数据
        snr_denoised = 10 * np.log10(np.sum(M ** 2) / np.sum((M - np.array(M_filtered)) ** 2))
        M_snr = np.hstack((snr_special, M))
        M_without_noise_snr = np.hstack(('None', M_without_noise))
        M_filtered_snr = np.hstack((snr_denoised, M_filtered))
        if snr_denoised >= snr_special:
            success = "snr=" + "%d" % snr_special + " material=" + material + " ta=" + "%.2f" % ta_special + " tb=" + "%.2f" % tb_special + " shape=" + "%d" % shape_flag_special + " filter=BPNN-OP " + lable
            success = np.hstack(
                (snr_special, snr_denoised, material, ta_special, tb_special, shape_flag_special, 'BPNN', lable))
            if len(success_list) == 0:
                success_list = success
            else:
                success_list = np.vstack((success_list, success))
        filted_result = np.vstack((M_without_noise, M, M_filtered))
        pd.DataFrame(filted_result, index=['signal_clean', 'signal_noisy', 'filted']).to_csv(dir_selected + " " + "snr=" + "%d" % snr_special + " material=" + material + " ta=" +
                                           "%.2f" % ta_special + " tb=" + "%.2f" % tb_special + " shape=" + "%d" % shape_flag_special +
                                           " filter=BPNN-OP " + lable + '.csv')
    return

if __name__ == '__main__':
    BP_run()
    # if i >= 2:
    #     break


import numpy as np
import keras
import matplotlib.pyplot as plt
import time
np.random.seed(1337)  # for reproducibility
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import RMSprop

class LossHistory(keras.callbacks.Callback):
    # 函数开始时创建盛放loss与acc的容器
    def on_train_begin(self, logs={}):
        self.losses = {'batch': [], 'epoch': []}
        self.accuracy = {'batch': [], 'epoch': []}
        self.val_loss = {'batch': [], 'epoch': []}
        self.val_acc = {'batch': [], 'epoch': []}

    # 按照batch来进行追加数据
    def on_batch_end(self, batch, logs={}):
        # 每一个batch完成后向容器里面追加loss，acc
        self.losses['batch'].append(logs.get('loss'))
        self.accuracy['batch'].append(logs.get('acc'))
        self.val_loss['batch'].append(logs.get('val_loss'))
        self.val_acc['batch'].append(logs.get('val_acc'))
        # 每五秒按照当前容器里的值来绘图
        if int(time.time()) % 5 == 0:
            self.draw_p(self.losses['batch'], 'loss', 'train_batch')
            self.draw_p(self.accuracy['batch'], 'acc', 'train_batch')
            self.draw_p(self.val_loss['batch'], 'loss', 'val_batch')
            self.draw_p(self.val_acc['batch'], 'acc', 'val_batch')

    def on_epoch_end(self, batch, logs={}):
        # 每一个epoch完成后向容器里面追加loss，acc
        self.losses['epoch'].append(logs.get('loss'))
        self.accuracy['epoch'].append(logs.get('acc'))
        self.val_loss['epoch'].append(logs.get('val_loss'))
        self.val_acc['epoch'].append(logs.get('val_acc'))
        # 每五秒按照当前容器里的值来绘图
        if int(time.time()) % 5 == 0:
            self.draw_p(self.losses['epoch'], 'loss', 'train_epoch')
            self.draw_p(self.accuracy['epoch'], 'acc', 'train_epoch')
            self.draw_p(self.val_loss['epoch'], 'loss', 'val_epoch')
            self.draw_p(self.val_acc['epoch'], 'acc', 'val_epoch')

    # 绘图，这里把每一种曲线都单独绘图，若想把各种曲线绘制在一张图上的话可修改此方法
    def draw_p(self, lists, label, type):
        plt.figure()
        plt.plot(range(len(lists)), lists, 'r', label=label)
        plt.ylabel(label)
        plt.xlabel(type)
        plt.legend(loc="upper right")
        plt.savefig(type + '_' + label + '.jpg')

    # 由于这里的绘图设置的是5s绘制一次，当训练结束后得到的图可能不是一个完整的训练过程（最后一次绘图结束，有训练了0-5秒的时间）
    # 所以这里的方法会在整个训练结束以后调用
    def end_draw(self):
        self.draw_p(self.losses['batch'], 'loss', 'train_batch')
        self.draw_p(self.accuracy['batch'], 'acc', 'train_batch')
        self.draw_p(self.val_loss['batch'], 'loss', 'val_batch')
        self.draw_p(self.val_acc['batch'], 'acc', 'val_batch')
        self.draw_p(self.losses['epoch'], 'loss', 'train_epoch')
        self.draw_p(self.accuracy['epoch'], 'acc', 'train_epoch')
        self.draw_p(self.val_loss['epoch'], 'loss', 'val_epoch')
        self.draw_p(self.val_acc['epoch'], 'acc', 'val_epoch')

# X shape (60,000 28x28), y shape (10,000, )
(X_train, y_train), (X_test, y_test) = mnist.load_data()  # 获取数据

# 数据预处理
X_train = X_train.reshape(X_train.shape[0], -1) / 255.  # 标准化
X_test = X_test.reshape(X_test.shape[0], -1) / 255.
# 转换为one_hot形式
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)

# 构建模型阶段
# 一次性搭建神经网络模型的方法，注意是将模型元素放在一个list中
model = Sequential([
    Dense(32, input_dim=784),
    Activation('relu'),
    Dense(10),
    Activation('softmax'),
])

# 激活模型
# 自定义RMS优化器
rmsprop = RMSprop(lr=0.01, rho=0.9, epsilon=1e-08, decay=0.0)
adagrad = keras.optimizers.Adagrad(lr=0.001)
sgd  = keras.optimizers.SGD(lr=0.01, momentum=0.0, nesterov=False)
adadelta = keras.optimizers.Adadelta(lr=1.0, rho=0.95)

model.compile(optimizer=adadelta,
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 训练阶段
logs_loss = LossHistory()
print('Training ------------')
model.fit(X_train, y_train, epochs=10, batch_size=32,validation_data=(X_test, y_test),callbacks=[logs_loss])  # keras_v1 epochs 2 nb_epoch
logs_loss.end_draw()
# 测试阶段
print('\nTesting ------------')
loss, accuracy = model.evaluate(X_test, y_test)
print('test loss: ', loss)
print('test accuracy: ', accuracy)
print(model.summary())


# -*- coding: utf-8 -*-
from easydict import EasyDict as edict

__C                             = edict()
# Consumers can get config by: from config import cfg
cfg                             = __C

# YOLO section
__C.MODEL                       = edict()
__C.MODEL.EPOCHS                = 30
__C.MODEL.BATCH_SIZE            = 16
__C.MODEL.INP_HEIGHT            = 299
__C.MODEL.INP_WIDTH             = 299
__C.MODEL.CHANELS               = 3
__C.MODEL.SAVE_DIR              = "saved_model/"
__C.MODEL.SAVE_FREQ             = 5
__C.MODEL.TRAIN_DIR             = "dataset/train"
__C.MODEL.VALID_DIR             = "dataset/valid"
__C.MODEL.TEST_DIR              = "dataset/test"
__C.MODEL.TFRCORD_TRAIN         = "dataset/train.tfrecord"
__C.MODEL.TFRCORD_VALID         = "dataset/valid.tfrecord"
__C.MODEL.TFRCORD_TEST          = "dataset/test.tfrecord"
__C.MODEL.NUM_CLASSES           = 20

# VALID_SET_RATIO = 1 - TRAIN_SET_RATIO - TEST_SET_RATIO
TRAIN_SET_RATIO = 0.6
TEST_SET_RATIO = 0.2


import requests
import argparse
import sys, os
import re
import threading
import time
from queue import Queue

def test_access(path):
	res = {"r":True,"w":True}
	testfile = path + "87896456453325649876546"
	try:
		f = open(testfile,"w")
		f.write("write test\t\n\n")
		f.close()
	except Exception as e:
		res["w"]  = False
		os.remove(testfile)
	try:
		f = open(testfile,"r")
		s = f.read().splitlines()
		f.close()
	except Exception as e:
		res["r"]  = False
	os.remove(testfile)
	return res

def files_lister(rikendirs,dlq,rootpath,ftypes):
	pat = re.compile("\d+_\d*")
	fnptn = re.compile("\d*\..*")
	for i, rd in enumerate(rikendirs):
		try:
			ldir = re.search(pat,rd).group()
			for ft in ftypes:
				if not os.path.exists(rootpath + ldir + "/" + ft):
					os.makedirs(rootpath + ldir + "/" + ft)
			localfiles = list_localfiles(directory=rootpath + ldir + "/",filetypes=ftypes)
			ldirfns = list_rikenfiles(directory=rd, filetypes=ftypes, localfiles=localfiles)
			for ft in ftypes:
				fcount[ft] += len(ldirfns[ft])
				for fn in ldirfns[ft]:
					tgt = re.search(fnptn,fn).group()
					dlq.put({"url":fn,"path":ldir+"/"+ft+"/"+tgt})
		except Exception as e:
			print("Error: ", end = "")
			print(e, end = "\n")

def download_threadfunct(filequeue,rootpath):
	headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.0; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0'}
	sess = requests.session()
	while True:
		try:
			d = filequeue.get()
			response = sess.get("http://pubchemqc.riken.jp/" + d["url"])
			if response.ok:
				with open(rootpath+d["path"],"wb") as f:
					f.write(response.content)
			filequeue.task_done()
		except Exception as e:
			print("Error downloading file: " + d["url"], file=sys.stderr)
			print(e, file=sys.stderr)
			print("Restarting session...", file=sys.stderr)
			sess = requests.session()
			filequeue.put(d)

def download_http(url):
	sess = requests.session()
	try:
		response = sess.get(url)
		if response.ok:
			return response.content.decode("UTF-8")
		else:
			return None
	except Exception as e:
		print("Exception in download_http:")
		print(e, file=sys.stderr)

def get_riken_index():
	dirpattern = re.compile("Compound.*\.html")
	countpattern = re.compile("(?<=Currently )\d*(?= molecules are available on this site)")
	indexhtml = download_http("http://pubchemqc.riken.jp/")
	dirs = re.findall(dirpattern, indexhtml)
	nbmols = (int)(re.search(countpattern,indexhtml).group())
	return dirs, nbmols

def list_rikenfiles(directory, filetypes, localfiles):
	filecontent = download_http("http://pubchemqc.riken.jp/" + directory)
	fndict = {}
	if "log" in filetypes:
		logptn = re.compile("(?<=href\=\")Compound.*.*b3lyp_6\-31g\(d\)\.log\.xz(?=\")")
		fndict["log"] = re.findall(logptn, filecontent)
	if "tdlog" in filetypes:
		tdlogptn = re.compile("(?<=href\=\")Compound.*td.*\.log\.xz(?=\")")
		fndict["tdlog"] = re.findall(tdlogptn, filecontent)
	if "mol" in filetypes:
		molptn = re.compile("(?<=href\=\")Compound.*\.mol(?=\")")
		fndict["mol"] = re.findall(molptn, filecontent)
	ptn = re.compile("(?<=\/)\d*\..*")
	for ft in fndict:
		torm = []
		for fn in fndict[ft]:
			localfn = re.search(ptn,fn).group()
			if localfn in localfiles:
				torm.append(fn)
				localfiles.remove(localfn)
		fndict[ft] = [fn for fn in fndict[ft] if fn not in torm]
	return fndict

def list_localfiles(directory,filetypes):
	res = []
	for root, dirs, files in os.walk(directory):
		for file in files:
			for ft in filetypes:
				if file.endswith(ft):
					res.append(file)
	return res

if __name__ == '__main__':
	"""
	Args parsing
	"""
	parser = argparse.ArgumentParser()
	parser.add_argument("--log", help="Download .log files", action="store_true")
	parser.add_argument("--tdlog", help="Download .td.log files", action="store_true")
	parser.add_argument("--mol", help="Download .mol files", action="store_true")
	parser.add_argument("target", help="Folder that will contain the downloaded content")
	args = parser.parse_args()
	if not (args.log or args.tdlog or args.mol):
		print("Error: no files to download, please use at least one of {--log, --tdlog, --mol} arguments.",file=sys.stderr)
		sys.exit(1)
	rootpath = args.target + "/" if args.target[-1] != "/" else args.target
	pathrights = test_access(rootpath)
	if not (pathrights["r"] or pathrights["w"]):
		print("Error: Cannot read or write to path " + rootpath,file=sys.stderr)
		print("Please correct this or chose another path.",file=sys.stderr)
		sys.exit(1)
	ftypes = []
	fcount = {}
	if args.log:
		ftypes.append("log")
		fcount["log"] = 0
	if args.tdlog:
		ftypes.append("tdlog")
		fcount["tdlog"] = 0
	if args.mol:
		ftypes.append("mol")
		fcount["mol"] = 0

	print("Getting Riken index...")
	rikendirs, nbmols = get_riken_index()
	dlq = Queue()
	print("Starting files listing thread...")
	flt = threading.Thread(target=files_lister, args=(rikendirs,dlq,rootpath,ftypes))
	flt.daemon = True
	flt.start()

	while dlq.qsize() == 0:
		print("Waiting for first downloads to start...", end = "\r")
		time.sleep(0.3)

	print("Starting download threads...")
	threads = []
	for i in range(3):
		t = threading.Thread(target=download_threadfunct, args=(dlq,rootpath))
		threads.append(t)
		t.daemon = True
		t.start()

	start = time.time()
	print("Downloads started.")
	while flt.isAlive():
		nbfiles = dlq.qsize()
		now = time.time()
		percentdone = 100 * (nbfiles-dlq.qsize()) / nbfiles
		print(str(percentdone)[:4] + "% done in " + str(int(now-start)) + " seconds, " + str(dlq.qsize()) + " files left to download.", end = "\r")
		time.sleep(1)
	print("Downloads finished. Quitting.")


import logging

import discord

from sandpiper.common.discord import find_user_in_mutual_guilds
from sandpiper.common.embeds import *
from sandpiper.common.misc import listify
from sandpiper.user_data import Database, PrivacyType
from ..upgrades import UpgradeHandler

logger = logging.getLogger(__name__)

class Sandpiper_1_6_0(UpgradeHandler):
    def version(self) -> str:
        return "1.6.0"

    async def on_upgrade(self):
        db = await self._get_database()
        if db is None:
            return

        for user_id in await db.get_all_user_ids():
            if (await db.get_birthday(user_id)) is not None:
                await self.tell_about_birthday(user_id, db)

    async def tell_about_birthday(self, user_id: int, db: Database):
        logger.info(
            f"User's birthday is set; telling them about the new feature "
            f"(user_id={user_id})"
        )

        user: discord.User = self.bot.get_user(user_id)
        if user is None:
            logger.info(f"Can't find user {user_id} in any guild")
            return

        # General info about the birthday announcements
        mutual_guilds = listify(
            [
                m.guild.name
                for m in find_user_in_mutual_guilds(self.bot, self.bot.user.id, user_id)
            ],
            2,
        )
        embed = SpecialEmbed(title="Birthday announcements update ðŸ¥³", join="\n\n")
        embed.append(
            f"Hey!! I'm a bot from {mutual_guilds}. I've just gotten a "
            f"birthday announcement feature. I can announce your birthday "
            f"when it arrives to all the servers you and I are both in!"
        )

        # Tell them about how they can control their birthday announcement
        bday_privacy = await db.get_privacy_birthday(user_id)
        if bday_privacy is PrivacyType.PRIVATE:
            embed.append(
                "Your birthday is currently set to **private**, so I will "
                "not announce it. If you want me to announce your birthday "
                "when it comes, type `privacy birthday public`! c:"
            )
        elif bday_privacy is PrivacyType.PUBLIC:
            embed.append(
                "Your birthday is currently set to **public**, so I will "
                "announce it! If you don't want me to announce your birthday "
                "when it comes, type `privacy birthday private`. c:"
            )

        embed.append(
            "You can use `bio show` to see all your data stored with me "
            "and `help` to see all available commands. And if you have no idea "
            "who I am, feel free to use `bio delete` to delete all your data "
            "and be on your way!"
        )

        await embed.send(user)

        await self.tell_about_age(user_id, db)

    async def tell_about_age(self, user_id: int, db: Database):
        logger.info(f"Telling the user about age privacy (user_id={user_id})")

        age_privacy = await db.get_privacy_age(user_id)

        # Change their age to private as a courtesy, so they're not blindsided
        # by their age in a notification if they haven't checked DMs or
        # something
        if age_privacy is PrivacyType.PUBLIC:
            logger.info(
                f"User's age is public; switching it to private " f"(user_id={user_id})"
            )
            await db.set_privacy_age(user_id, PrivacyType.PRIVATE)

        user: discord.User = self.bot.get_user(user_id)
        if user is None:
            logger.info(f"Can't find user {user_id} in any guild")
            return

        # General info about age in the announcement
        embed = SpecialEmbed(title="Age in birthday announcement", join="\n\n")
        embed.append(
            "I can also announce your new age in your birthday message "
            "if your age privacy is set to public!"
        )

        # Info about their privacy value
        if age_privacy is PrivacyType.PUBLIC:
            # Tell them we changed their privacy to private
            embed.append(
                "I know this might be uncomfortable, so I've changed your "
                "age from public to **private** as a precaution. If you want "
                "your age announced, you can type `privacy age public` to "
                "make it public again."
            )
        elif age_privacy is PrivacyType.PRIVATE:
            embed.append(
                "Yours is currently set to **private**, but if you want "
                "to change that, type `privacy age public`."
            )

        # Their birthday doesn't include birth year, so tell them how to set it
        if (await db.get_age(user_id)) is None:
            bday = await db.get_birthday(user_id)
            embed.append(
                f"You will also have to include your birth year in your "
                f"birthday (you currently only have the month and day stored). "
                f"To set your birthday with the year, type "
                f"`birthday set {bday.strftime('YYYY-%m-%d')}`!"
            )

        await embed.send(user)


import json

def calculate_property_score(property, user_weights):
    # Implement scoring logic
    score = 0
    # calculate the score based on property attributes and user weights
    return score

def lambda_handler(event, context):
    user_id = event['user_id']
    # Fetch user preferences
    user_weights = get_user_weights(user_id)
    # Fetch properties
    properties = get_properties()

    # Calculate scores for each property
    for property in properties:
        property['score'] = calculate_property_score(property, user_weights)

    # Return properties with scores
    return {
        'statusCode': 200,
        'body': json.dumps(properties)
    }


'''
Created on May 23, 2017

@author: kevin
'''

# from setuptools import setup, find_packages

# setup(
#     name = "ContinuousContractMaker",
#     version = "0.1",
#     packages=find_packages(),
#     entry_points={
#         'gui_scripts':[
#             'Continuous_Contract_Maker=rollover.main:StartMainWindow']
#     }
# )

# import py2exe
# from distutils.core import setup
#
# setup(windows=[{"script":"main.pyw"}],
#       options={"py2exe":{"includes":["sip"]}})

# from distutils.core import setup
# import py2exe
#
# setup( console=[{"script": "rollover\main.py"}] )

import os
import sys
from cx_Freeze import setup, Executable

os.environ['TCL_LIBRARY'] = "F:\\OneDrive\\Programming\\Python\\Python36\\tcl\\tcl8.6"
os.environ['TK_LIBRARY'] = "F:\\OneDrive\\Programming\\Python\\Python36\\tcl\\tk8.6"
base = None
if sys.platform == 'win32':
    base = 'Win32GUI'

executables = [
    Executable('rollover\\main.pyw', base=base)
]

setup(name='test',
      version='0.1',
      description='test',
      executables=executables
      )


#from setuptools import setup
#from Cython.Build import cythonize
from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy

ext_module = Extension(
    "cmetrics",
    ["cmetrics.pyx"],
    language="c++",
    extra_compile_args=["-std=c++11"],
    extra_link_args=["-std=c++11"]
)

setup(
    ext_modules = cythonize(ext_module),
    include_dirs=[numpy.get_include()]
)


# -*- coding: utf-8 -*-
import pytest
from common.com_browser import BrowserEngine
from page.baidu_page import BaiDuObject

"""
    项目全局配置
    用例前置操作：启动driver
    用例后置操作：关闭浏览器
"""

@pytest.fixture(scope='session')
def get_driver():
    browser = BrowserEngine()
    driver = browser.open_browser()
    bd = BaiDuObject(driver)
    yield bd
    # 后置操作：关闭浏览器
    bd.quit_browser()

# 登陆fixture 示例
# @pytest.fixture(scope='session')
# def login(get_driver):
#     driver = get_driver
#     bd = BaiDuObject(driver)
#     bd.login()
#     return driver


from config import ROOTS
import collection

from pathlib import Path

# test file_json_2_vector
lightweight_json = collection.file_json_2_vector(ROOTS["pending-matrix-root"] / "lightweight_models.json")

assert lightweight_json == [{'resource_id': '10.5281/zenodo.7786492', 'version_id': '7786493'},
                            {'resource_id': '10.5281/zenodo.5914248', 'version_id': '6514622'},
                            {"resource_id": "10.5281/zenodo.8064806", "version_id": "8073617"},
                            {'resource_id': '10.5281/zenodo.6338614', 'version_id': '6338615'}]

# test resources_2_paths

rdf_paths_1 = collection.resources_2_paths({'resource_id': '10.5281/zenodo.7786492', 'version_id': '7786493'})
rdf_paths_2 = collection.resources_2_paths({'resource_id': '10.5281/zenodo.6200999', 'version_id': '**'})
rdf_paths_3 = collection.resources_2_paths({'resource_id': '**', 'version_id': '**'})

assert rdf_paths_1 == [Path(ROOTS["collection-root"], '10.5281/zenodo.7786492', '7786493', "rdf.yaml")]
assert len(rdf_paths_2) == 4
assert 190 <= len(rdf_paths_3) <= 300

# test get_rdfs_to_test
filenames = ["all_models.json", "two_models.json", "two_versions.json"]
files = map(lambda x: ROOTS["pending-matrix-root"] / x, filenames)
resource_vectors = map(lambda x: collection.file_json_2_vector(x), files)
r_a, r_b, r_c = list(map(lambda x: collection.get_rdfs_to_test(x), resource_vectors))

assert len(r_a) >= 165
assert {"7261975", "latest"} == set(map(lambda x: x.parent.name, r_b))
assert {"5888237", "5877226"} == set(map(lambda x: x.parent.name, r_c))


import sqlite3
import json
from sqlite3 import Error

def create_connection():
    conn = None
    try:
        conn = sqlite3.connect(':memory:')
        print(sqlite3.version)

    except Error as e:
        print(e)

    return conn

def create_table(conn, create_table_sql):
    """ create a table from the create_table_sql statement
    :param conn: Connection object
    :param create_table_sql: a CREATE TABLE statement
    :return:
    """
    try:
        c = conn.cursor()
        c.execute(create_table_sql)
    except Error as e:
        print(e)

def configure_tables(conn):
    create_users = """ CREATE TABLE IF NOT EXISTS users (
                                    id integer PRIMARY KEY,
                                    name text,
                                    username text,
                                    password text,
                                    address text,
                                    phone text,
                                    tfn INTEGER
                                    ); """

    create_table(conn, create_users)

def initialize_table(conn, table):
    with open(f"./sampledata/{table}.json") as json_file:
      data = json.load(json_file)

    for element in data:
        keylist = []
        valuelist = []
        valuelength = []
        for iter_key, iter_value in element.items():
            keylist.append(str(iter_key))
            valuelist.append(str(iter_value))
            valuelength += "?"
        ### SQL statements in python with dynamic values is a bit unfortunate.
        sql = f'''INSERT INTO {table}({(",".join(map(str, keylist)))}) VALUES({(",".join(map(str, valuelength)))})'''
        print (sql)
        with conn:
            conn.set_trace_callback(print)
            cur = conn.cursor()
            cur.execute(sql, valuelist)

def main():
    global conn
    conn = create_connection()

    conn.set_trace_callback(print)
    configure_tables(conn)

    initialize_table(conn, "users")

if __name__ == '__main__':
    main()


import os
import pefile
import hashlib
import csv

def extractor(file, tmpdirname, csv_filename):
    file_path = os.path.join(tmpdirname, file.filename)
    file.save(file_path)

    # Open the executable file using PEfile
    pe = pefile.PE(file_path)

    # Extract the desired attributes
    machine = pe.FILE_HEADER.Machine
    size_of_optional_header = pe.FILE_HEADER.SizeOfOptionalHeader
    characteristics = pe.FILE_HEADER.Characteristics
    major_linker_version = pe.OPTIONAL_HEADER.MajorLinkerVersion
    minor_linker_version = pe.OPTIONAL_HEADER.MinorLinkerVersion
    size_of_code = pe.OPTIONAL_HEADER.SizeOfCode
    size_of_initialized_data = pe.OPTIONAL_HEADER.SizeOfInitializedData
    size_of_uninitialized_data = pe.OPTIONAL_HEADER.SizeOfUninitializedData
    address_of_entry_point = pe.OPTIONAL_HEADER.AddressOfEntryPoint
    base_of_code = pe.OPTIONAL_HEADER.BaseOfCode
    base_of_data = pe.OPTIONAL_HEADER.BaseOfData
    image_base = pe.OPTIONAL_HEADER.ImageBase
    section_alignment = pe.OPTIONAL_HEADER.SectionAlignment
    file_alignment = pe.OPTIONAL_HEADER.FileAlignment
    major_os_version = pe.OPTIONAL_HEADER.MajorOperatingSystemVersion
    minor_os_version = pe.OPTIONAL_HEADER.MinorOperatingSystemVersion
    major_image_version = pe.OPTIONAL_HEADER.MajorImageVersion
    minor_image_version = pe.OPTIONAL_HEADER.MinorImageVersion
    major_subsystem_version = pe.OPTIONAL_HEADER.MajorSubsystemVersion
    minor_subsystem_version = pe.OPTIONAL_HEADER.MinorSubsystemVersion
    size_of_image = pe.OPTIONAL_HEADER.SizeOfImage
    size_of_headers = pe.OPTIONAL_HEADER.SizeOfHeaders
    checksum = pe.OPTIONAL_HEADER.CheckSum
    subsystem = pe.OPTIONAL_HEADER.Subsystem
    dll_characteristics = pe.OPTIONAL_HEADER.DllCharacteristics
    size_of_stack_reserve = pe.OPTIONAL_HEADER.SizeOfStackReserve
    size_of_stack_commit = pe.OPTIONAL_HEADER.SizeOfStackCommit
    size_of_heap_reserve = pe.OPTIONAL_HEADER.SizeOfHeapReserve
    size_of_heap_commit = pe.OPTIONAL_HEADER.SizeOfHeapCommit
    loader_flags = pe.OPTIONAL_HEADER.LoaderFlags
    number_of_rva_and_sizes = pe.OPTIONAL_HEADER.NumberOfRvaAndSizes

    # Calculate the number of sections
    sections_nb = len(pe.sections)

    # Create a temporary CSV file to save the attributes
    # Calculate additional attributes using a suitable method or library
    csv_filepath = os.path.join(tmpdirname, csv_filename)
    # Create a CSV file and write the attributes
    with open(csv_filepath, "w", newline="") as csv_file:
        csv_writer = csv.writer(csv_file, delimiter='|')
        csv_writer.writerow([
            "Machine", "SizeOfOptionalHeader", "Characteristics",
            "MajorLinkerVersion", "MinorLinkerVersion", "SizeOfCode", "SizeOfInitializedData",
            "SizeOfUninitializedData", "AddressOfEntryPoint", "BaseOfCode", "BaseOfData",
            "ImageBase", "SectionAlignment", "FileAlignment", "MajorOperatingSystemVersion",
            "MinorOperatingSystemVersion", "MajorImageVersion", "MinorImageVersion",
            "MajorSubsystemVersion", "MinorSubsystemVersion", "SizeOfImage", "SizeOfHeaders",
            "CheckSum", "Subsystem", "DllCharacteristics", "SizeOfStackReserve", "SizeOfStackCommit",
            "SizeOfHeapReserve", "SizeOfHeapCommit", "LoaderFlags", "NumberOfRvaAndSizes",
            "SectionsNb",  # Add more header entries
        ])
        csv_writer.writerow([
            machine, size_of_optional_header, characteristics,
            major_linker_version, minor_linker_version, size_of_code, size_of_initialized_data,
            size_of_uninitialized_data, address_of_entry_point, base_of_code, base_of_data,
            image_base, section_alignment, file_alignment, major_os_version, minor_os_version,
            major_image_version, minor_image_version, major_subsystem_version, minor_subsystem_version,
            size_of_image, size_of_headers, checksum, subsystem, dll_characteristics,
            size_of_stack_reserve, size_of_stack_commit, size_of_heap_reserve, size_of_heap_commit,
            loader_flags, number_of_rva_and_sizes, sections_nb,  # Add more attribute values
        ])
    return csv_filepath


import torch
import math
import torch.nn as nn
from torch.autograd import Variable

class PositionalEncoding(nn.Module):
    def __init__(self, d_model, dropout, max_len=5000):
        """
        :param d_model: pe编码维度，一般与word embedding相同，方便相加
        :param dropout: dorp out
        :param max_len: 语料库中最长句子的长度，即word embedding中的L
        """
        self.out_dim = d_model
        super(PositionalEncoding, self).__init__()
        # 定义drop out
        self.dropout = nn.Dropout(p=dropout)
        # 计算pe编码
        pe = torch.zeros(max_len, d_model)  # 建立空表，每行代表一个词的位置，每列代表一个编码位
        position = torch.arange(0, max_len).unsqueeze(1)  # 建个arrange表示词的位置以便公式计算，size=(max_len,1)
        div_term = torch.exp(torch.arange(0, d_model, 2) *    # 计算公式中10000**（2i/d_model)
                             -(math.log(10000.0) / d_model))
        pe[:, 0::2] = torch.sin(position * div_term)  # 计算偶数维度的pe值
        pe[:, 1::2] = torch.cos(position * div_term)  # 计算奇数维度的pe值
        pe = pe.unsqueeze(0)  # size=(1, L, d_model)，为了后续与word_embedding相加,意为batch维度下的操作相同
        self.register_buffer('pe', pe)  # pe值是不参加训练的

    def forward(self, x):
        # 输入的最终编码 = word_embedding + positional_embedding
        x = x + Variable(self.pe[:, :x.size(0)], requires_grad=False).reshape(x.size(0), self.out_dim)  # size = [batch, L, d_model]
        return self.dropout(x)  # size = [batch, L, d_model]


import utils as u
import cv2
import numpy as np
import math
from scipy import ndimage
# import cnn_predict as p

def prepr(img):     #binarno centrirano
    img = scale(img)
    shx, shy = getBestShift(img)
    shifted = shift(img, shx, shy)
    # ret, shifted = cv2.threshold(shifted, , 255, cv2.THRESH_BINARY)
    ret, shifted = cv2.threshold(
        shifted, 120, 255, cv2.THRESH_BINARY)
    u.show_image_gray(shifted, True)
    shifted = u.scale_to_range(shifted)
    return shifted

def prepare(image): #sivo kropovano
    # image = cv2.blur(image, (3, 3))

    ret, contours, hierarchy = cv2.findContours(
        image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    max_cont = max(contours, key=cv2.contourArea)
    x, y, w, h = cv2.boundingRect(max_cont)
    image = image[y: y + h + 1, x: x + w + 1]
    image = cv2.resize(image, (28, 28), interpolation=cv2.INTER_NEAREST)
    return image

def preproccess(img):   #blur centrirano

    img = cv2.blur(img, (3, 3))

    # blr = cv2.GaussianBlur(img, (0, 0), 3)
    # img = cv2.addWeighted(img, 1.3, blr, -0.7, 0)
    # img = cv2.addWeighted(img, 1.5, blr, -0.5, 0)

    img = scale(img)
    shx, shy = getBestShift(img)
    shifted = shift(img, shx, shy)
    shifted = u.scale_to_range(shifted)
    shifted = shifted * 0.6
    # shifted[shifted > 1] = 1
    return shifted

def shift(img, sx, sy):
    rows, cols = img.shape
    M = np.float32([[1, 0, sx], [0, 1, sy]])
    shifted = cv2.warpAffine(img, M, (cols, rows))
    return shifted

def getBestShift(img):
    cy, cx = ndimage.measurements.center_of_mass(img)

    rows, cols = img.shape
    shiftx = np.round(cols / 2.0 - cx).astype(int)
    shifty = np.round(rows / 2.0 - cy).astype(int)

    return shiftx, shifty

def scale(gray):

    # makni crne ivice
    while np.sum(gray[0]) == 0:
        gray = gray[1:]

    while np.sum(gray[:, 0]) == 0:
        gray = np.delete(gray, 0, 1)

    while np.sum(gray[-1]) == 0:
        gray = gray[:-1]

    while np.sum(gray[:, -1]) == 0:
        gray = np.delete(gray, -1, 1)

    rows, cols = gray.shape

    # 20x20
    if rows > cols:
        factor = 20.0 / rows
        rows = 20
        cols = int(round(cols * factor))
        gray = cv2.resize(gray, (cols, rows))
    else:
        factor = 20.0 / cols
        cols = 20
        rows = int(round(rows * factor))
        gray = cv2.resize(gray, (cols, rows))

    # do 28x28
    colsPadding = (int(math.ceil((28 - cols) / 2.0)),
                   int(math.floor((28 - cols) / 2.0)))
    rowsPadding = (int(math.ceil((28 - rows) / 2.0)),
                   int(math.floor((28 - rows) / 2.0)))
    gray = np.lib.pad(gray, (rowsPadding, colsPadding), 'constant')

    return gray

def preproccess_region(image, size):
    w, h = size

    img = u.remove_noise_gray(image)

    blr = cv2.GaussianBlur(image.copy(), (0, 0), 3)  # ovo je za 33 %
    img = cv2.addWeighted(image.copy(), 1.2, blr, -0.8, 0)

    if w < h:
        px = np.ceil(h / 2) - np.floor(w / 2)
        px = px.astype(np.uint8)
        # dodaj padding na sliku
        img = cv2.copyMakeBorder(
            img, 0, 0, px, px, cv2.BORDER_CONSTANT, value=[0, 0, 0])

    if h < w:
        py = np.ceil(w / 2) - np.floor(h / 2)
        py = py.astype(np.uint8)
        # dodaj padding
        img = cv2.copyMakeBorder(
            img, py, py, 0, 0, cv2.BORDER_CONSTANT, value=[0, 0, 0])

    img = cv2.resize(img, (20, 20), interpolation=cv2.INTER_NEAREST)
    img = cv2.copyMakeBorder(
        img, 4, 4, 4, 4, cv2.BORDER_CONSTANT, value=[0, 0, 0])
    img = u.scale_to_range(img)

    u.show_image_gray(img, True)
    return img