"""
Module for controlling/interface with Bluetooth devices
"""

import asyncio
import itertools
import logging
import re
from syslog import syslog, LOG_ERR, LOG_INFO
from typing import Any, Optional, List, Dict
from dbus_fast import Message, MessageType, Variant
from dbus_fast.aio.proxy_object import ProxyInterface
import falcon
from summit_rcm.dbus_manager import DBusManager
from summit_rcm_bluetooth.services import bt_plugin
from summit_rcm import definition
from summit_rcm_bluetooth.services.ble import (
    DBUS_PROP_IFACE,
    controller_pretty_name,
    find_device,
    DEVICE_IFACE,
    ADAPTER_IFACE,
    DBUS_OM_IFACE,
    AgentSingleton,
    BLUEZ_SERVICE_NAME,
    uri_to_uuid,
    GATT_MANAGER_IFACE,
    create_agent_singleton,
)
from summit_rcm_bluetooth.services.bt_controller_state import BluetoothControllerState
from summit_rcm.utils import Singleton, variant_to_python

PAIR_TIMEOUT_SECONDS = 60
CONNECT_TIMEOUT_SECONDS = 60

# These device properties can be directly set, without requiring any special-case logic.
SETTABLE_DEVICE_PROPS = [
    ("Trusted", bool, "b"),
    ("AutoConnect", bool, "b"),
    ("AutoConnectAutoDisable", bool, "b"),
]

CACHED_DEVICE_PROPS = ["connected", "autoConnect", "autoConnectAutoDisable"]

# These controller properties can be directly set, without requiring any special-case logic.
PASS_ADAPTER_PROPS = ["Discovering", "Powered", "Discoverable"]

# Additionally transportFilter is cached, but by special-case logic that confirms
# value is accepted.
CACHED_ADAPTER_PROPS = ["discovering", "powered", "discoverable"]

ADAPTER_PATH_PATTERN = re.compile("^/org/bluez/hci\\d+$")
DEVICE_PATH_PATTERN = re.compile("^/org/bluez/hci\\d+/dev_\\w+$")
DEVICE_ADAPTER_GROUP_PATTERN = re.compile("^(/org/bluez/hci\\d+)/dev_\\w+$")

bluetooth_plugins: List[bt_plugin.BluetoothPlugin] = []

try:
    from summit_rcm_bluetooth.hid.barcode_scanner import HidBarcodeScannerPlugin

    hid_barcode_scanner_plugin = HidBarcodeScannerPlugin()
    if hid_barcode_scanner_plugin not in bluetooth_plugins:
        bluetooth_plugins.append(hid_barcode_scanner_plugin)
    syslog("bluetooth: HidBarcodeScannerPlugin loaded")
except ImportError:
    syslog("bluetooth: HidBarcodeScannerPlugin NOT loaded")

try:
    from summit_rcm_bluetooth.vsp.vsp_connection import VspConnectionPlugin

    vsp_connection_plugin = VspConnectionPlugin()
    if vsp_connection_plugin not in bluetooth_plugins:
        bluetooth_plugins.append(vsp_connection_plugin)
    syslog("bluetooth: VspConnectionPlugin loaded")
except ImportError:
    syslog("bluetooth: VspConnectionPlugin NOT loaded")

try:
    bluetooth_ble_plugin = None
    from summit_rcm_bluetooth.services.bt_ble import BluetoothBlePlugin

    bluetooth_ble_plugin = BluetoothBlePlugin()
    if bluetooth_ble_plugin not in bluetooth_plugins:
        bluetooth_plugins.append(bluetooth_ble_plugin)
    syslog("bluetooth: BluetoothBlePlugin loaded")
except ImportError:
    syslog("bluetooth: BluetoothBlePlugin NOT loaded")

async def get_controller_obj(controller: str = ""):
    result = {}
    # get the system bus
    bus = await DBusManager().get_bus()
    # get the ble controller
    if not controller:
        result[
            "InfoMsg"
        ] = f"Controller {controller_pretty_name(controller)} not found."
        result["SDCERR"] = definition.SUMMIT_RCM_ERRORS.get("SDCERR_FAIL", 1)
        controller_obj = None
    else:
        controller_obj = bus.get_proxy_object(
            BLUEZ_SERVICE_NAME,
            controller,
            await bus.introspect(BLUEZ_SERVICE_NAME, controller),
        )

    return bus, controller_obj, result

def lower_camel_case(upper_camel_string: str):
    """Return supplied UpperCamelCase string in lowerCamelCase"""
    return upper_camel_string[:1].lower() + upper_camel_string[1:]

class Bluetooth(metaclass=Singleton):
    def __init__(self):
        self._controller_states: Dict[str, BluetoothControllerState] = {}
        """Controller state tracking - indexed by friendly (REST API) name"""
        self._controller_addresses: Dict[str, str] = {}
        """Controller addresses - indexed by friendly (REST API) name"""
        self._controller_callbacks_registered = False
        self._logger = logging.getLogger(__name__)
        self._devices_to_restore: Dict[str, type(None)] = {}
        """Map of device uuids to restore state due to associated controller reset"""
        self.setup_initiated: bool = False

    async def setup(self, app: falcon.asgi.App) -> None:
        """
        Run async logic required to setup Bluetooth intergration
        """
        if not self.setup_initiated:
            self.setup_initiated = True
            for plugin in bluetooth_plugins:
                if isinstance(plugin, BluetoothBlePlugin):
                    plugin.set_app(app)
                    break
            await self.discover_controllers()

    def add_ws_route(self, ws_route: str, is_legacy: bool = False):
        """Add a websocket route to the list of supported routes"""
        for plugin in bluetooth_plugins:
            if isinstance(plugin, BluetoothBlePlugin):
                plugin.add_ws_route(ws_route, is_legacy)
                return

    @property
    def device_commands(self) -> List[str]:
        return list(
            itertools.chain.from_iterable(
                plugin.device_commands for plugin in bluetooth_plugins
            )
        ) + ["getConnInfo"]

    @property
    def adapter_commands(self) -> List[str]:
        return list(
            itertools.chain.from_iterable(
                plugin.adapter_commands for plugin in bluetooth_plugins
            )
        )

    @property
    def controller_addresses(self) -> Dict[str, str]:
        return self._controller_addresses

    async def get_remapped_controller(self, controller_friendly_name: str):
        """Scan present controllers and find the controller with address associated with
        controller_friendly_name, in _controller_addresses dictionary.
        This allows for consistent referencing of controller by REST API name in the event
        the controller bluez object path changes in the system. (e.g. /org/bluez/hci5)
        """
        if controller_friendly_name not in self._controller_addresses.keys():
            return None
        address = self._controller_addresses[controller_friendly_name]
        bus = await DBusManager().get_bus()
        remote_om = bus.get_proxy_object(
            BLUEZ_SERVICE_NAME, "/", await bus.introspect(BLUEZ_SERVICE_NAME, "/")
        ).get_interface(DBUS_OM_IFACE)
        objects = await remote_om.call_get_managed_objects()

        for controller, props in objects.items():
            if GATT_MANAGER_IFACE in props.keys():
                if (
                    ADAPTER_IFACE in props.keys()
                    and "Address" in props[ADAPTER_IFACE].keys()
                ):
                    if address == variant_to_python(props[ADAPTER_IFACE]["Address"]):
                        return controller
        return None

    async def remapped_controller_to_friendly_name(self, controller: str) -> str:
        """Lookup the REST API name of the controller with the address matching the provided
        controller by dbus path.
        """
        bus = await DBusManager().get_bus()
        controller_obj = bus.get_proxy_object(
            BLUEZ_SERVICE_NAME,
            controller,
            await bus.introspect(BLUEZ_SERVICE_NAME, controller),
        )

        if not controller_obj:
            return ""
        adapter_interface = controller_obj.get_interface(ADAPTER_IFACE)
        requested_address = variant_to_python(await adapter_interface.get_address())
        for controller_friendly_name, address in self._controller_addresses.items():
            if requested_address == address:
                return controller_friendly_name
        return ""

    async def discover_controllers(self, renumber=True):
        """
        Find objects that have the bluez service and a GattManager1 interface,
        building _controller_addresses dictionary to later allow referencing of
        controllers by fixed name, even if their dbus object path changes.
        The assumption is that all controllers will be present in the system
        with the names the REST API wants to expose them under when Summit RCM starts,
        and that Summit RCM will never restart.
        If these assumptions are not true, renumber can be set to simply number
        discovered controllers as controller0 and up.
        """
        bus = await DBusManager().get_bus()
        remote_om = bus.get_proxy_object(
            BLUEZ_SERVICE_NAME, "/", await bus.introspect(BLUEZ_SERVICE_NAME, "/")
        ).get_interface(DBUS_OM_IFACE)
        objects = await remote_om.call_get_managed_objects()
        controller_number = len(self._controller_addresses.keys())

        for controller, props in objects.items():
            if GATT_MANAGER_IFACE in props.keys():
                if renumber:
                    controller_friendly_name: str = f"controller{controller_number}"
                else:
                    controller_friendly_name: str = controller_pretty_name(controller)
                if (
                    ADAPTER_IFACE in props.keys()
                    and "Address" in props[ADAPTER_IFACE].keys()
                ):
                    address = variant_to_python(props[ADAPTER_IFACE]["Address"])
                    if address not in self._controller_addresses.values():
                        self._controller_addresses[controller_friendly_name] = address
                        syslog(
                            LOG_INFO,
                            f"assigning controller {controller} at address {address} "
                            f"to REST API name {controller_friendly_name}",
                        )
                        controller_number += 1

    async def register_controller_callbacks(self):
        if not self._controller_callbacks_registered:
            try:
                self._controller_callbacks_registered = True

                bus = await DBusManager().get_bus()
                interface = bus.get_proxy_object(
                    BLUEZ_SERVICE_NAME,
                    "/",
                    await bus.introspect(BLUEZ_SERVICE_NAME, "/"),
                ).get_interface(DBUS_OM_IFACE)
                interface.on_interfaces_removed(self.interface_removed_cb)
                interface.on_interfaces_added(self.interface_added_cb)
            except Exception as exception:
                self.log_exception(exception)

    async def interface_added_cb(self, interface: str, *args):
        try:
            if ADAPTER_PATH_PATTERN.match(interface):
                syslog(LOG_INFO, f"Bluetooth interface added: {str(interface)}")
                # IF bluetoothd crashed, may want to AgentSingleton.clear_instance()
                # For now, assume the controller was previously removed and has been re-attached.
                await self.controller_restore(interface)
            elif DEVICE_PATH_PATTERN.match(interface):
                syslog(LOG_INFO, f"Bluetooth device added: {str(interface)}")
                await self.device_restore(interface)
        except Exception as exception:
            self.log_exception(exception)

    def log_exception(self, exception, message: str = ""):
        self._logger.exception(exception)
        syslog(LOG_ERR, message + str(exception))

    async def interface_removed_cb(self, interface: str, *args):
        try:
            if ADAPTER_PATH_PATTERN.match(interface):
                syslog(LOG_INFO, f"Bluetooth interface removed: {str(interface)}")
                _, adapter_obj, _ = await get_controller_obj(interface)
                for plugin in bluetooth_plugins:
                    try:
                        await plugin.ControllerRemovedNotify(interface, adapter_obj)
                    except Exception as exception:
                        self.log_exception(exception)
        except Exception as exception:
            self.log_exception(exception)

    async def controller_restore(self, controller: str = "/org/bluez/hci0"):
        """
        :param controller: controller whose state will be restored
        :return: None

        Call when the specified controller experienced a HW reset, for example, in case
        of a HW malfunction, or system power-save sleep.
        Attempts to re-establish previously commanded controller state.
        * Note the assumption is that this LCM process was used to establish controller state -
        assumption unsatisfied if prior run of LCM or another tool was used to alter controller
        state.
        """
        # we remove the bus path by convention, so the index names match that used by hosts
        # in REST API
        controller_friendly_name: str = await self.remapped_controller_to_friendly_name(
            controller
        )
        syslog(
            LOG_INFO,
            f"controller_restore: restoring controller state for REST API name "
            f"{controller_friendly_name}",
        )
        controller_state = self.get_controller_state(controller_friendly_name)

        _, adapter_obj, _ = await get_controller_obj(controller)

        if not adapter_obj:
            syslog(
                LOG_ERR,
                f"Reset notification received for controller {controller}, "
                "but adapter_obj not found",
            )
            return

        # First, set controller properties, powering it on if previously powered.
        adapter_interface = adapter_obj.get_interface(ADAPTER_IFACE)
        try:
            await self.set_adapter_properties(
                adapter_interface,
                controller,
                controller_state.properties,
            )
        except Exception as exception:
            self.log_exception(exception)

        # Second, schedule set of each device's properties.
        for device_uuid, _ in controller_state.device_properties_uuids.items():
            self._devices_to_restore.update({device_uuid: None})

    async def device_restore(self, device: str):
        """Set device's properties, and plugin protocol connections if applicable."""
        bus, device_obj, _ = await get_controller_obj(device)

        if not device_obj:
            syslog(
                LOG_ERR,
                f"Reset notification received for device {device}, "
                "but device_obj not found",
            )
            return
        device_interface = device_obj.get_interface(DEVICE_IFACE)
        device_uuid = uri_to_uuid(
            variant_to_python(await device_interface.get_address())
        )

        if device_uuid not in self._devices_to_restore.keys():
            return

        self._devices_to_restore.pop(device_uuid)

        match = DEVICE_ADAPTER_GROUP_PATTERN.match(device)
        if not match or match.lastindex < 1:
            syslog(
                LOG_ERR,
                f"device_restore couldn't determine controller of device {device}",
            )
            return
        controller = match[1]
        controller_friendly_name: str = await self.remapped_controller_to_friendly_name(
            controller
        )
        syslog(
            LOG_INFO,
            f"device_restore: restoring device state for {device} on controller "
            f"REST API name {controller_friendly_name}",
        )
        controller_state = self.get_controller_state(controller_friendly_name)
        bus, adapter_obj, _ = await get_controller_obj(controller)
        adapter_interface = adapter_obj.get_interface(ADAPTER_IFACE)

        cached_device_properties = self.get_device_properties(
            controller_state, device_uuid
        )
        device, _ = await find_device(bus, device_uuid)
        if device is not None:
            device_obj = bus.get_proxy_object(
                BLUEZ_SERVICE_NAME,
                device,
                await bus.introspect(BLUEZ_SERVICE_NAME, device),
            )
            device_interface = device_obj.get_interface(DEVICE_IFACE)
            try:
                await self.set_device_properties(
                    adapter_interface,
                    device_interface,
                    device_uuid,
                    cached_device_properties,
                )
            except Exception as exception:
                self.log_exception(exception, "failed setting device properties: ")
        else:
            syslog(
                LOG_ERR, f"***couldn't find device {device_uuid} to restore properties"
            )

        # Notify plugins, re-establishing protocol links.
        # We do not wait for BT connections to restore, so service discovery may not be complete
        # when plugins receive notification.
        for plugin in bluetooth_plugins:
            try:
                await plugin.DeviceAddedNotify(device, device_uuid, device_obj)
            except Exception as exception:
                self.log_exception(exception)

    async def get_device_property(
        self, obj_path: str, interface: str, property_name: str
    ) -> Any:
        """Get the specified interface property for the object at the given path."""
        bus = await DBusManager().get_bus()

        reply = await bus.call(
            Message(
                destination=BLUEZ_SERVICE_NAME,
                path=obj_path,
                interface=DBUS_PROP_IFACE,
                member="Get",
                signature="ss",
                body=[interface, property_name],
            )
        )

        if reply.message_type == MessageType.ERROR:
            raise Exception(reply.body[0])

        return variant_to_python(reply.body[0])

    async def set_device_property(
        self,
        obj_path: str,
        interface: str,
        property_name: str,
        value: Any,
        value_signature: str,
    ) -> None:
        """
        Set the specified interface property for the object at the given path to the defined value
        using the provided signature.
        """
        bus = await DBusManager().get_bus()

        reply = await bus.call(
            Message(
                destination=BLUEZ_SERVICE_NAME,
                path=obj_path,
                interface=DBUS_PROP_IFACE,
                member="Set",
                signature="ssv",
                body=[interface, property_name, Variant(value_signature, value)],
            )
        )

        if reply.message_type == MessageType.ERROR:
            raise Exception(reply.body[0])

    def get_controller_state(
        self, controller_friendly_name: str
    ) -> BluetoothControllerState:
        controller_friendly_name = controller_pretty_name(controller_friendly_name)
        if controller_friendly_name not in self._controller_states:
            self._controller_states[
                controller_friendly_name
            ] = BluetoothControllerState()
        return self._controller_states[controller_friendly_name]

    def get_device_properties(
        self, controller_state: BluetoothControllerState, device_uuid: str
    ):
        """
        :param controller_state: controller device is on
        :param device_uuid: see uri_to_uuid()
        :return: dictionary map of device property names and values
        """
        if device_uuid not in controller_state.device_properties_uuids:
            controller_state.device_properties_uuids[device_uuid] = {}
        return controller_state.device_properties_uuids[device_uuid]

    @staticmethod
    def result_parameter_not_one_of(parameter: str, not_one_of):
        return {
            "SDCERR": definition.SUMMIT_RCM_ERRORS["SDCERR_FAIL"],
            "InfoMsg": f"supplied {parameter} parameter must be one of {not_one_of}",
        }

    async def set_adapter_properties(
        self,
        adapter_interface: ProxyInterface,
        controller_friendly_name,
        post_data,
    ):
        """Set properties on an adapter (controller)"""
        result = {}
        powered = post_data.get("powered", None)
        discovering = post_data.get("discovering", None)
        discoverable = post_data.get("discoverable", None)
        transport_filter = post_data.get("transportFilter", None)
        if powered is not None:
            await adapter_interface.set_powered(bool(powered))
            if not powered:
                # Do not attempt to set discoverable or discovering state if powering off
                discoverable = discoverable if discoverable else None
                discovering = discovering if discovering else None

        if transport_filter is not None:
            result.update(
                await self.set_adapter_transport_filter(
                    adapter_interface, controller_friendly_name, transport_filter
                )
            )
            if (
                "SDCERR" in result
                and result["SDCERR"] != definition.SUMMIT_RCM_ERRORS["SDCERR_SUCCESS"]
            ):
                return result
        if discoverable is not None:
            await adapter_interface.set_discoverable(bool(discoverable))
        if discovering is not None:
            discovering_state = variant_to_python(
                await adapter_interface.get_discovering()
            )
            if discovering_state != discovering:
                if discovering:
                    await adapter_interface.call_start_discovery()
                else:
                    await adapter_interface.call_stop_discovery()

        if "SDCERR" not in result:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_SUCCESS"]

        return result

    def get_adapter_transport_filter(self, controller_friendly_name):
        controller_state = self.get_controller_state(controller_friendly_name)
        return controller_state.properties.get("transportFilter", None)

    async def set_adapter_transport_filter(
        self,
        adapter_interface: ProxyInterface,
        controller_friendly_name,
        transport_filter,
    ):
        """Set a transport filter on the controller.  Note that "When multiple clients call
        SetDiscoveryFilter, their filters are internally merged" """
        result = {}
        discovery_filters = {"Transport": Variant("s", str(transport_filter))}
        try:
            await adapter_interface.call_set_discovery_filter(discovery_filters)
        except Exception:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_FAIL"]
            result["InfoMsg"] = f"Transport filter {transport_filter} not accepted"
            return result

        controller_state = self.get_controller_state(controller_friendly_name)
        controller_state.properties["transportFilter"] = transport_filter
        return result

    async def set_device_properties(
        self,
        adapter_interface: ProxyInterface,
        device_interface: ProxyInterface,
        device_uuid: str,
        post_data,
    ):
        result = {}
        for settable_property in SETTABLE_DEVICE_PROPS:
            prop_name, prop_type, prop_signature = settable_property
            value = post_data.get(lower_camel_case(prop_name), None)
            if value is not None:
                await self.set_device_property(
                    obj_path=device_interface.path,
                    interface=DEVICE_IFACE,
                    property_name=prop_name,
                    value=prop_type(value),
                    value_signature=prop_signature,
                )
        auto_connect = post_data.get("autoConnect", None)
        if auto_connect == 1:
            await create_agent_singleton()
        paired = post_data.get("paired", None)
        if paired == 1:
            paired_state = (
                1 if variant_to_python(await device_interface.get_paired()) else 0
            )
            if paired_state != paired:
                await create_agent_singleton()
                await asyncio.wait_for(
                    device_interface.call_pair(), PAIR_TIMEOUT_SECONDS
                )
        elif paired == 0:
            await self.remove_device_method(adapter_interface, device_interface)
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_SUCCESS"]
            return result
        connected = post_data.get("connected", None)
        connected_state = (
            1 if variant_to_python(await device_interface.get_connected()) else 0
        )
        if connected_state != connected:
            if connected == 1:
                # Note - device may need to be paired prior to connecting
                # AgentSingleton can be registered to allow BlueZ to auto-pair (without bonding)
                await create_agent_singleton()
                if bluetooth_ble_plugin:
                    await bluetooth_ble_plugin.initialize()
                if bluetooth_ble_plugin and bluetooth_ble_plugin.bt:
                    # Use ig BLE plugin if available, because it will refuse to
                    # interact with devices it has not explicitly connected to.
                    # Pass device path to ig BLE plugin, as it will fail
                    # to connect to devices it has not previously "discovered".
                    await bluetooth_ble_plugin.bt.connect(
                        device_uuid, device_interface.path
                    )
                else:
                    await asyncio.wait_for(
                        device_interface.call_connect(), CONNECT_TIMEOUT_SECONDS
                    )
            elif connected == 0:
                await device_interface.call_disconnect()
        passkey = post_data.get("passkey", None)
        if passkey is not None:
            agent_instance = await AgentSingleton.get_instance()
            if agent_instance:
                agent_instance.passkeys[device_interface.path] = passkey
        # Found device, set any requested properties.  Assume success.
        result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_SUCCESS"]

        return result

    async def remove_device_method(
        self, adapter_interface: ProxyInterface, device_interface: ProxyInterface
    ):
        device_connected = variant_to_python(await device_interface.get_connected())
        if device_connected:
            await device_interface.call_disconnect()
        device_address = variant_to_python(await device_interface.get_address())
        await adapter_interface.call_remove_device(device_interface.path)
        # If RemoveDevice is successful, further work on device will not be possible.
        device_uuid = uri_to_uuid(device_address)
        for plugin in bluetooth_plugins:
            try:
                await plugin.DeviceRemovedNotify(device_uuid, device_interface)
            except Exception as exception:
                self.log_exception(exception)

    async def execute_device_command(
        self,
        bus,
        command,
        device_uuid: str,
        device_interface: Optional[ProxyInterface],
        adapter_interface: Optional[ProxyInterface],
        post_data: Optional[dict] = None,
    ):
        result = {}
        error_message = None
        processed = False
        if command == "getConnInfo":
            processed = True

            try:
                reply = await bus.call(
                    Message(
                        destination=BLUEZ_SERVICE_NAME,
                        path=device_interface.path,
                        interface=DEVICE_IFACE,
                        member="GetConnInfo",
                    )
                )

                if reply.message_type == MessageType.ERROR:
                    raise Exception(reply.body[0])

                result["rssi"] = reply.body[0]
                result["tx_power"] = reply.body[1]
                result["max_tx_power"] = reply.body[2]
            except Exception as exception:
                self.log_exception(exception)
                error_message = "Unable to get connection info"
        else:
            for plugin in bluetooth_plugins:
                try:
                    processed, error_message = await plugin.ProcessDeviceCommand(
                        bus,
                        command,
                        device_uuid,
                        device_interface,
                        adapter_interface,
                        post_data,
                        self.remove_device_method,
                    )
                except Exception as exception:
                    self.log_exception(exception)
                    processed = True
                    error_message = f"Command {command} failed with {str(exception)}"
                    break
                if processed:
                    break

        if not processed:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_FAIL"]
            result["InfoMsg"] = f"Unrecognized command {command}"
        elif error_message:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_FAIL"]
            result["InfoMsg"] = error_message
        else:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_SUCCESS"]
            result["InfoMsg"] = ""

        return result

    async def execute_adapter_command(
        self,
        bus,
        command,
        controller_friendly_name: str,
        adapter_interface: Optional[ProxyInterface],
        post_data: Optional[dict] = None,
    ):
        result = {}
        error_message = None
        processed = False
        for plugin in bluetooth_plugins:
            try:
                (
                    processed,
                    error_message,
                    process_result,
                ) = await plugin.ProcessAdapterCommand(
                    bus, command, controller_friendly_name, adapter_interface, post_data
                )
                if process_result:
                    result.update(process_result)
            except Exception as exception:
                self.log_exception(exception)
                processed = True
                error_message = f"Command {command} failed with {str(exception)}"
                break
            if processed:
                break

        if not processed:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_FAIL"]
            result["InfoMsg"] = f"Unrecognized command {command}"
        elif error_message:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_FAIL"]
            result["InfoMsg"] = error_message
        else:
            result["SDCERR"] = definition.SUMMIT_RCM_ERRORS["SDCERR_SUCCESS"]
            result["InfoMsg"] = ""

        return result


import pygame
from random import *
import time
import itertools
import sys
import math
from HamCycle import HCyc
pygame.init()
sys.setrecursionlimit(3000)

class Snake:
    heading = 0 # 0: Right, 1: Up, 2: Left, 3: Down
    snakeParts = []
    dirs = [[1,0],[0,-1],[-1,0],[0,1]] #Directions corresponding to Heading Vals
    speed = 1
    partSize = 0
    foodPosition = []
    def __init__(self,speed,allP,gridBSize):
        self.snakeParts = [choice(allP)]
        self.heading = 0
        self.partSize = gridBSize
        self.foodPosition = self.getFoodPos(allPos,self.snakeParts)

    def pathDist(self,start,end,hCyc):
        c = 0
        while True:
            c+=1
            if start==end:
                break
            else:
                start = hCyc[start]
        return c

    def distDict(self,possPoints,foodNode,gX,hCyc):
        d = {}
        for point in possPoints:
            node = point[0]+gX*point[1]
            d[self.pathDist(node,foodNode,hCyc)] = point
        return d

    def bestMove(self,possPoints,foodNode,gX,hCyc,hNode):
        distD = self.distDict(possPoints,foodNode,gX,hCyc)
        for dist in sorted(distD):
            point = distD[dist]
            nNode = point[0]+point[1]*gX
            if hCyc[hNode]==nNode:
                return nNode
            else:
                c = 0
                start = nNode
                while True:
                    c += 1
                    if allPos[hCyc[start]] in self.snakeParts:
                        break
                    else:
                        start = hCyc[start]
                if len(self.snakeParts)<c:
                    return nNode
        return hCyc[hNode]

    def move_forw(self,allPos,gridX,gridY, hCyc):
        head = self.snakeParts[0][:]
        hNode = head[0]+head[1]*gridX
        foodNode = self.foodPosition[0]+self.foodPosition[1]*gridX

        posP = []
        for direc in self.dirs:
            nPX = head[0]+direc[0]
            nPY = head[1]+direc[1]
            nP = [nPX,nPY]
            if 0<=nPX<gridX and 0<=nPY<gridY and nP not in self.snakeParts:
                posP.append(nP)
        nNode = self.bestMove(posP,foodNode,gridX,hCyc,hNode)
        head = allPos[nNode]

        if self.foodPosition in self.snakeParts:
            self.foodPosition = self.getFoodPos(allPos,self.snakeParts)
        else:
            self.snakeParts.pop()
        self.snakeParts=[head]+self.snakeParts

    def draw_snake_food(self,display,done):
        display.fill((0,0,0))
        fCol = (255,255,0)

        for part in range(len(self.snakeParts)):

            pygame.draw.rect(display,(0,0,0), (self.snakeParts[part][0]*self.partSize,self.snakeParts[part][1]*self.partSize,
                                                     self.partSize,self.partSize),2)
            pygame.draw.rect(display,(0,255,0), (self.snakeParts[part][0]*self.partSize+1,self.snakeParts[part][1]*self.partSize+1,
                                                     self.partSize-2,self.partSize-2))
            if part>0:
                posX = (self.snakeParts[part-1][0]*self.partSize+self.snakeParts[part][0]*self.partSize)/2+1
                posY = (self.snakeParts[part-1][1]*self.partSize+self.snakeParts[part][1]*self.partSize)/2+1
                pygame.draw.rect(display,(0,255,0), (posX,posY,
                                                     self.partSize-2,self.partSize-2))

        if not done:
            pygame.draw.rect(display,fCol, (self.foodPosition[0]*self.partSize,self.foodPosition[1]*self.partSize,
                                              self.partSize,self.partSize))

    def change_heading(self,key):
        if key==pygame.K_RIGHT:
            self.heading = 0
        elif key==pygame.K_UP:
            self.heading = 1
        elif key==pygame.K_LEFT:
            self.heading = 2
        elif key==pygame.K_DOWN:
            self.heading = 3

    def getFoodPos(self,allPositions,posTaken):
        allPo = allPositions[:]
        shuffle(allPo)
        for pos in allPo:
            if pos not in posTaken:
                return [pos[0],pos[1]]
        return [0,0] #no positions left. perfect snake.

    def containsDups(self, lis):
        for i in range(len(lis)-1):
            if lis[i] in lis[i+1:]:
                return True
        return False

    def check_death(self, gX, gY):
        head = self.snakeParts[0]
        if self.containsDups(self.snakeParts):
            return True
        elif not (0<=head[0]<gX and 0<=head[1]<gY):
            return True
        else:
                return False

gridX = 20
gridY = 20
gridBSize= 20
screen = pygame.display.set_mode([gridX*gridBSize,gridY*gridBSize])

hCyc = HCyc(gridX,gridY).hcyc

allPos = []
for y in range(gridY):
    for x in range(gridX):
        allPos.append([x,y])

mySnake = Snake(1,allPos,gridBSize)
running = True
gameDone = False
speed = 1
start = 0
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    start = time.time()
    if mySnake.check_death(gridX,gridY):
        gameDone = True
    for i in range(speed):
        if not gameDone:
            mySnake.move_forw(allPos,gridX,gridY,hCyc)
        mySnake.draw_snake_food(screen,gameDone)
    pygame.display.flip()
pygame.quit()

Classic Snake AI/Hamiltonian Method/game-with-ai.py


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

from datetime import datetime
from flask import render_template

from TgwlDataCenter import db
from TgwlDataCenter.models import Fruit
from TgwlDataCenter.main import main

@main.route('/')
@main.route('/home')
def home():
    """Renders the home page."""
    fruit = Fruit(fruit=u"苹果")
    db.session.add(fruit)
    db.session.commit()
    return render_template(
        'index.html',
        title='Home Page',
        year=datetime.now().year,
    )

@main.route('/contact')
def contact():
    """Renders the contact page."""
    return render_template(
        'contact.html',
        title='Contact',
        year=datetime.now().year,
        message='Your contact page.'
    )

@main.route('/about')
def about():
    """Renders the about page."""
    return render_template(
        'about.html',
        title='About',
        year=datetime.now().year,
        message='Your application description page.'
    )


import datetime
import whisper
import json
filename = "example"
model = whisper.load_model("base")
result = model.transcribe(f"{filename}.mp3")
print(result)
with open("{}.txt".format(filename), "w") as f:
  f.write(result["text"])

with open("{}.json".format(filename), "w", encoding="utf-8") as f:
  json.dump(result, f, ensure_ascii=False)
withTime = {}

for segment in result["segments"]:
   withTime[str(datetime.timedelta(seconds=segment["start"])).split(".")[0]] = segment["text"]

with open("{}.json".format("withTime"), "w", encoding="utf-8") as f:
  json.dump(withTime, f, ensure_ascii=False)


import os
from config import *
import numpy as np

from utils_cpu import cpu_window
from utils import *
import matplotlib.pyplot as plt
import matplotlib

plt.rcParams['figure.figsize'] = (8.0, 12.0) # 设置figure_size尺寸
# plt.rcParams['image.interpolation'] = 'nearest' # 设置 interpolation style
# plt.rcParams['image.cmap'] = 'black' # 设置 颜色 style

fig_name = 'exp_2_'+band_str+'.jpg'

# ra = range(len_layers)
ra = [0, 1, 2, 3]
for i in ra:
    layer_result = []
    for j in range(len_methods):
        method_result = []
        for idx in range(start, end):
            cpu_powers, cpu_types = cpu_window(idx, idx + 5)
            if cpu_powers == False:
                # print('Error! The required amount of cpus is larger than that available.')
                break
            # print(band)
            method_result.append(1 / methods[j](layers[i], cpu_powers, band))

        layer_result.append(method_result)
    x=list(range(1, len(layer_result[0])+1))
    plt.subplot(len(ra), 1, list(ra).index(i)+1)
    for j in range(len_methods):
        plt.plot(x, layer_result[j], label=legend[j],
                 marker=markers[j], color=fcs_line[j],
                 markevery=markevery)
        # if legend[j]=='DADS':
        #     print('DADS', layer_result[j])
        # elif legend[j]=='NM':
        #     print('NM', layer_result[j])
        # print(legend[j], layer_result[j])
    plt.legend(fontsize=fs, loc='best')
    plt.grid(color='black')
    # plt.xlabel('DNN', fontsize=fs)
    plt.ylabel('FPS\n(' + name_list[i]+')', fontsize=fs)
    plt.xticks(fontsize=fs)
    plt.yticks(fontsize=fs)

plt.xlabel('Index', fontsize=fs)
plt.tight_layout()
plt.savefig(fig_name, dpi=600)
plt.show()


from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render

from store.models import Product, Variation

from .models import Cart, CartItem

# Create your views here.
def _cart_id(request):
    cart = request.session.session_key
    if not cart:
        cart = request.session.create()
    return cart

def _get_cart_item(request, product_id, cart_item_id):
    product = get_object_or_404(Product, id=product_id)
    if request.user.is_authenticated:
        return CartItem.objects.get(product=product, user=request.user, id=cart_item_id)
    else:
        cart = Cart.objects.get(cart_id=_cart_id(request=request))
        return CartItem.objects.get(product=product, cart=cart, id=cart_item_id)

def add_cart(request, product_id):
    current_user = request.user
    product = Product.objects.get(id=product_id)  # get the product
    product_variations = []
    if request.method == "POST":
        for param in request.POST:
            key = param
            value = request.POST[key]
            try:
                variation = Variation.objects.get(
                    product=product,
                    variation_category__iexact=key,
                    variation_value__iexact=value,
                )
                product_variations.append(variation)
            except:
                pass

    if current_user.is_authenticated:
        cart = None
        cart_items = CartItem.objects.filter(product=product, user=current_user)
    else:
        try:
            cart = Cart.objects.get(
                cart_id=_cart_id(request=request)
            )  # get the cart using the cart_id presents in the session
        except Cart.DoesNotExist:
            cart = Cart.objects.create(cart_id=_cart_id(request=request))
        cart.save()
        cart_items = CartItem.objects.filter(product=product, cart=cart)

    cart_item = None
    for single_cart_item in cart_items:
        if product_variations == list(single_cart_item.variations.all()):
            # increase the cart item quantity
            single_cart_item.quantity += 1
            single_cart_item.save()
            cart_item = single_cart_item
            break

    # if nothing existing found - create a new item
    if cart_item is None:
        if current_user.is_authenticated:
            cart_item = CartItem.objects.create(
                product=product, quantity=1, user=current_user
            )
        else:
            cart_item = CartItem.objects.create(product=product, quantity=1, cart=cart)

    if len(product_variations) > 0:
        cart_item.variations.add(*product_variations)

    cart_item.save()
    return redirect("cart")

def remove_cart(request, product_id, cart_item_id):
    cart_item = _get_cart_item(
        request=request, product_id=product_id, cart_item_id=cart_item_id
    )
    if cart_item.quantity > 1:
        cart_item.quantity -= 1
        cart_item.save()
    else:
        cart_item.delete()
    return redirect("cart")

def remove_cart_item(request, product_id, cart_item_id):
    cart_item = _get_cart_item(
        request=request, product_id=product_id, cart_item_id=cart_item_id
    )
    cart_item.delete()
    return redirect("cart")

def cart(request, total=0, quantity=0, cart_items=None):
    try:
        if request.user.is_authenticated:
            cart_items = CartItem.objects.filter(user=request.user, is_active=True)
        else:
            cart = Cart.objects.get(cart_id=_cart_id(request=request))
            cart_items = CartItem.objects.filter(cart=cart, is_active=True)
        for cart_item in cart_items:
            total += cart_item.product.price * cart_item.quantity
            quantity += cart_item.quantity
        tax = (2 * total) / 100
        grand_total = total + tax
    except ObjectDoesNotExist:
        grand_total = 0
        tax = 0
    context = {
        "total": total,
        "quantity": quantity,
        "tax": tax,
        "grand_total": grand_total,
        "cart_items": cart_items,
    }
    return render(request=request, template_name="store/cart.html", context=context)

@login_required(login_url="login")
def checkout(request, total=0, quantity=0, cart_items=None):
    try:
        if request.user.is_authenticated:
            cart_items = CartItem.objects.filter(user=request.user, is_active=True)
        else:
            cart = Cart.objects.get(cart_id=_cart_id(request=request))
            cart_items = CartItem.objects.filter(cart=cart, is_active=True)

        for cart_item in cart_items:
            total += cart_item.product.price * cart_item.quantity
            quantity += cart_item.quantity
        tax = (2 * total) / 100
        grand_total = total + tax
    except ObjectDoesNotExist:
        grand_total = 0
        tax = 0
    context = {
        "total": total,
        "quantity": quantity,
        "tax": tax,
        "grand_total": grand_total,
        "cart_items": cart_items,
    }
    return render(request, "store/checkout.html", context)


from django.urls import path, re_path, include
from django.views.generic.base import TemplateView

from . import views

urlpatterns = [
    path('mine/', views.UserQuestionsList.as_view(), name='my_questions'),
    re_path('^create/$', views.QuestionCreate.as_view(), name='create_question'),
    re_path('^details/(?P<pk>\d+)/$', views.QuestionDetail.as_view(), name='question-detail'),
    re_path('^delete/(?P<pk>\d+)/$', views.QuestionDelete.as_view(), name='question-delete'),
    re_path('^edit/(?P<pk>\d+)/$', views.QuestionEdit.as_view(), name='question-edit'),
    path('unchecked/', views.UncheckedQuestionsList.as_view(), name='unchecked_questions'),
]


from dataclasses import dataclass, field
from datetime import datetime
from decimal import Decimal

_DATE_FORMAT = "%Y%m%d"

@dataclass
class CashDividendsEntity:
    asset_issued: str
    payment_date: datetime.date
    rate: Decimal
    related_to: str
    approved_on: datetime.date
    isin_code: str
    label: str
    last_date_prior: datetime.date
    remarks: str = ""
    id: str = None

    def __post_init__(self):
        if isinstance(self.payment_date, str):
            self.payment_date = datetime.strptime(self.payment_date, _DATE_FORMAT).date()
        if isinstance(self.approved_on, str):
            self.approved_on = datetime.strptime(self.approved_on, _DATE_FORMAT).date()
        if isinstance(self.last_date_prior, str):
            self.last_date_prior = datetime.strptime(self.last_date_prior, _DATE_FORMAT).date()
        if not isinstance(self.rate, Decimal):
            self.rate = Decimal(self.rate).quantize(Decimal("0.00000000001"))
        if not self.id:
            self.id = f"{self.payment_date.strftime(_DATE_FORMAT)}" \
                      f"#{self.label}#{self.approved_on.strftime(_DATE_FORMAT)}" \
                      f"#{self.last_date_prior.strftime(_DATE_FORMAT)}"

    def to_dict(self):
        return {
            **self.__dict__,
            "payment_date": self.payment_date.strftime(_DATE_FORMAT),
            "approved_on": self.approved_on.strftime(_DATE_FORMAT),
            "last_date_prior": self.last_date_prior.strftime(_DATE_FORMAT),
        }


from tkinter import *
import qrcode
from PIL import Image,ImageTk
from resizeimage import resizeimage

class QRGenerator:
    def __init__(self,root):
        self.root=root
        self.root.geometry("900x500+200+50")
        self.root.title("QR Generator")
        self.root.resizable(False,False)

        title=Label(self.root,text=" QR Generator",font=("times new roman",40),bg='#053246',fg='white',anchor='w').place(x=0,y=0,relwidth=1)

        #frame 1

        #variables
        self.var_id=StringVar()
        self.var_name=StringVar()
        self.var_department=StringVar()
        self.var_desig=StringVar()

        emp_frame=Frame(self.root,bd=2,relief=RIDGE,bg='white')
        emp_frame.place(x=50,y=100,width=500,height=380)

        emptitle=Label(emp_frame,text=" Employee Details",font=("goudy old style",30),bg='#043246',fg='white',anchor='c').place(x=0,y=0,relwidth=1)

        labelEmp=Label(emp_frame,text=" Employee Id",font=("times new roman",15),bg='white',anchor='c').place(x=20,y=60)
        labelName=Label(emp_frame,text=" Name",font=("times new roman",15),bg='white',anchor='c').place(x=20,y=100)
        labelDepart=Label(emp_frame,text=" Department",font=("times new roman",15),bg='white',anchor='c').place(x=20,y=140)
        labelDesig=Label(emp_frame,text=" Designation",font=("times new roman",15),bg='white',anchor='c').place(x=20,y=180)

        txtEmp=Entry(emp_frame,font=("times new roman",15),bg='lightyellow',textvariable=self.var_id).place(x=200,y=60)
        txtlName=Entry(emp_frame,font=("times new roman",15),bg='lightyellow',textvariable=self.var_name).place(x=200,y=100)
        txtlDepart=Entry(emp_frame,font=("times new roman",15),bg='lightyellow',textvariable=self.var_department).place(x=200,y=140)
        txtDesig=Entry(emp_frame,font=("times new roman",15),bg='lightyellow',textvariable=self.var_desig).place(x=200,y=180)

        btn_gen=Button(emp_frame,text="QR generate",command=self.qrgenerate,font=("times new roman",18,'bold'),bg='#2196f3',fg='white').place(x=50,y=250,width=180,height=30)
        btn_clear=Button(emp_frame,text="Clear",command=self.clear,font=("times new roman",18,'bold'),bg='#607d8b',fg='white').place(x=282,y=250,width=120,height=30)

        self.msg=""
        self.msg_label=Label(emp_frame,text=self.msg,font=("goudy old style",20),bg='white',fg='green')
        self.msg_label.place(x=0,y=320,relwidth=1)

        #frame 2
        qr_frame=Frame(self.root,bd=2,relief=RIDGE,bg='white')
        qr_frame.place(x=600,y=100,width=250,height=380)

        self.qrtitle=Label(qr_frame,text=" QR Code",font=("goudy old style",30),bg='#043246',fg='white',anchor='c').place(x=0,y=0,relwidth=1)
        self.qrcode=Label(qr_frame,text="QR Code\nNot Available",font=("times new roman",15),bg='#3f51b5',fg='white',bd=1,relief=RIDGE)
        self.qrcode.place(x=35,y=100,height=180,width=180)

        #function

    def clear(self):
        self.var_id.set('')
        self.var_name.set('')
        self.var_department.set('')
        self.var_desig.set('')
        self.msg=""
        self.msg_label.config(text=self.msg)
        self.qrcode.config(image='')

    def qrgenerate(self):
        if self.var_desig.get()=='' or self.var_id.get()=='' or self.var_name.get()=='' or self.var_department.get()=='':
            self.msg="All fields are required!!"
            self.msg_label.config(text=self.msg,fg='red')
        else:

            qr_data=(f"Employee Id :{self.var_id.get()}\nEmployee Name: {self.var_name.get()}\nDepartment:{self.var_department.get()}\nDesignation:{self.var_desig.get()}")
            qr_code=qrcode.make(qr_data)

            qr_code=resizeimage.resize_cover(qr_code,[180,180])

            self.im=ImageTk.PhotoImage(qr_code)
            self.qrcode.config(image=self.im)

            self.msg="QR Code generated successfully"
            self.msg_label.config(text=self.msg,fg='green')

root=Tk()
obj=QRGenerator(root)

root.mainloop()


from corehq.apps.sms.forms import BackendForm
from corehq.apps.sms.mixin import apply_leniency
from corehq.apps.sms.util import validate_phone_number
from corehq.apps.hqwebapp import crispy as hqcrispy
from crispy_forms import layout as crispy
from crispy_forms.bootstrap import StrictButton, FormActions
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, HTML
from dimagi.utils.django.fields import TrimmedCharField
from django.core.exceptions import ValidationError
from django.forms.fields import ChoiceField
from django.forms.forms import Form
from django.utils.translation import gettext as _, gettext_lazy

class TelerivetBackendForm(BackendForm):
    api_key = TrimmedCharField(
        label=gettext_lazy("API Key"),
    )
    project_id = TrimmedCharField(
        label=gettext_lazy("Project ID"),
    )
    phone_id = TrimmedCharField(
        label=gettext_lazy("Phone ID"),
    )
    webhook_secret = TrimmedCharField(
        label=gettext_lazy("Webhook Secret"),
    )

    def __init__(self, *args, **kwargs):
        super(TelerivetBackendForm, self).__init__(*args, **kwargs)

        if self.backend_id:
            # Don't allow editing the webhook secret.
            # Django ensures that posted values don't change the value here.
            self.fields['webhook_secret'].disabled = True

    @property
    def gateway_specific_fields(self):
        return crispy.Fieldset(
            _("Telerivet (Android) Settings"),
            'api_key',
            'project_id',
            'phone_id',
            'webhook_secret',
        )

    def clean_webhook_secret(self):
        # Circular import
        from corehq.messaging.smsbackends.telerivet.models import SQLTelerivetBackend
        value = self.cleaned_data['webhook_secret']
        backend = SQLTelerivetBackend.by_webhook_secret(value)
        if backend and backend.pk != self.backend_id:
            raise ValidationError(_("Already in use."))
        return value

class TelerivetOutgoingSMSForm(Form):
    api_key = TrimmedCharField(
        label=gettext_lazy("API Key"),
        required=True
    )
    project_id = TrimmedCharField(
        label=gettext_lazy("Project ID"),
        required=True
    )
    phone_id = TrimmedCharField(
        label=gettext_lazy("Phone ID"),
        required=True
    )

    def __init__(self, *args, **kwargs):
        super(TelerivetOutgoingSMSForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form form-horizontal'
        self.helper.label_class = 'col-sm-2 col-md-1'
        self.helper.field_class = 'col-sm-4 col-md-3'
        self.helper.layout = Layout(
            Div(
                hqcrispy.B3MultiField(
                    _("API Key"),
                    Div(
                        hqcrispy.MultiInlineField(
                            'api_key',
                            data_bind='value: apiKey',
                        )
                    ),
                    crispy.Div(
                        css_class="help-block",
                        data_bind="visible: apiKeyError, text: apiKeyError",
                    ),
                    data_bind="css: {'has-error': apiKeyError}",
                ),
                hqcrispy.B3MultiField(
                    _("Project ID"),
                    Div(
                        hqcrispy.MultiInlineField(
                            'project_id',
                            data_bind='value: projectId',
                        )
                    ),
                    crispy.Div(
                        css_class="help-block",
                        data_bind="visible: projectIdError, text: projectIdError",
                    ),
                    data_bind="css: {'has-error': projectIdError}",
                ),
                hqcrispy.B3MultiField(
                    _("Phone ID"),
                    Div(
                        hqcrispy.MultiInlineField(
                            'phone_id',
                            data_bind='value: phoneId',
                        )
                    ),
                    crispy.Div(
                        css_class="help-block",
                        data_bind="visible: phoneIdError, text: phoneIdError",
                    ),
                    data_bind="css: {'has-error': phoneIdError}",
                )
            )
        )

class TelerivetPhoneNumberForm(Form):
    test_phone_number = TrimmedCharField(
        required=True,
        label=gettext_lazy("+ (Country Code) Phone Number")
    )

    def __init__(self, *args, **kwargs):
        super(TelerivetPhoneNumberForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form form-horizontal'
        self.helper.label_class = 'col-sm-2 col-md-1'
        self.helper.field_class = 'col-sm-4 col-md-3'
        self.helper.layout = Layout(
            Div(
                hqcrispy.B3MultiField(
                    _("Test Phone Number"),
                    Div(
                        hqcrispy.MultiInlineField(
                            'test_phone_number',
                            data_bind='value: testPhoneNumber',
                        )
                    ),
                    crispy.Div(
                        css_class="help-block",
                        data_bind="visible: testPhoneNumberError, text: testPhoneNumberError",
                    ),
                    Div(
                        StrictButton(
                            "",
                            id='id_send_sms_button',
                            css_class='btn',
                            data_bind="text: sendSmsButtonText, click: sendTestSMS, "
                                      "css: {'btn-primary': !sendSmsButtonError(), "
                                      "'btn-danger': sendSmsButtonError()}",
                        )
                    ),
                    data_bind="css: {'has-error': testPhoneNumberError}",
                )
            )
        )

    def clean_test_phone_number(self):
        value = self.cleaned_data.get('test_phone_number')
        value = apply_leniency(value)
        validate_phone_number(value,
            error_message=_("Please enter digits only, in international format (country code and phone number)."))
        return value

class FinalizeGatewaySetupForm(Form):
    YES = 'Y'
    NO = 'N'

    YES_NO_CHOICES = (
        (YES, gettext_lazy("Yes")),
        (NO, gettext_lazy("No")),
    )

    name = TrimmedCharField(
        label=gettext_lazy("Name"),
        required=True
    )
    set_as_default = ChoiceField(
        label=gettext_lazy("Set as default gateway"),
        choices=YES_NO_CHOICES,
        required=True
    )

    def __init__(self, *args, **kwargs):
        super(FinalizeGatewaySetupForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_class = 'form form-horizontal'
        self.helper.label_class = 'col-sm-3 col-md-2'
        self.helper.field_class = 'col-sm-3 col-md-2'
        self.helper.layout = Layout(
            Div(
                hqcrispy.B3MultiField(
                    _("Name"),
                    Div(
                        hqcrispy.MultiInlineField(
                            'name',
                            data_bind='value: name',
                        )
                    ),
                    crispy.Div(
                        css_class="help-block",
                        data_bind="visible: nameError, text: nameError",
                    ),
                    data_bind="css: {'has-error': nameError}",
                ),
                hqcrispy.B3MultiField(
                    _("Set as default gateway"),
                    Div(
                        hqcrispy.MultiInlineField(
                            'set_as_default',
                            data_bind='value: setAsDefault',
                            style='margin-left: 0px;'
                        )
                    ),
                    crispy.Div(
                        css_class="help-block",
                        data_bind="visible: setAsDefaultError, text: setAsDefaultError",
                    ),
                    data_bind="css: {'has-error': setAsDefaultError}",
                ),
                FormActions(
                    StrictButton(
                        "",
                        id="id_create_backend",
                        css_class='btn-primary',
                        data_bind="text: backendButtonText, click: createBackend, disable: creatingBackend,"
                                  "css: {'btn-primary': !backendButtonError(), "
                                  "'btn-danger': backendButtonError()}",
                    )
                )
            )
        )


from os import path
from qhue import Bridge, QhueException, create_new_username
import discoverhue,csv,json,os,random,time

#https://pypi.org/project/discoverhue/
#https://github.com/studioimaginaire/phue

# the path for the username credentials file
CRED_FILE_PATH = "qhue_username.txt"

def Get_Bridge_IP():
    # the IP address of your bridge
    found = discoverhue.find_bridges()
    for bridge in found:
        ip = found[bridge]
    ip = ip.replace("http://","")
    ip = ip.replace(":80/","")
    return ip

def Get_Username(ip):
    if not path.exists(CRED_FILE_PATH):
        with open(CRED_FILE_PATH, "w") as csv_file:
            fieldnames = ['ip','username']
            writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
            writer.writeheader()

    # check for a credential file
    found = False
    cred_file = open(CRED_FILE_PATH)
    csv_file = csv.reader(cred_file)
    for row in csv_file:
        if ip in row:
            username = row[1]
            found = True
            break

    if found == True:
        return username
    else:
        try:
            username = create_new_username(ip)
        except QhueException as err:
            print("Error occurred while creating a new username: {}".format(err))

        with open(CRED_FILE_PATH, "a") as csv_file:
            fieldnames = ['ip','username']
            writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
            writer.writerow({'ip': ip, 'username': username})

        return username

def Get_LightInfo():
    lights = {}
    lights = bridge.lights
    with open('lights.json', 'w') as outfile:
        json_lights = json.dumps(lights(), indent=4)
        json.dump(lights(), outfile)
    print(json_lights)

def Start_Rave(light):
    print("Press Ctrl-C to terminate the rave!")
    try:
        while True:
            bridge.lights[random.randint(1,light)].state(on=True, sat=random.randint(0,254), bri=254,hue=random.randint(0,65535))
            time.sleep(.1)
    except KeyboardInterrupt:
        os.system('clear')
        pass

def Turn_Off(lights):
    for x in range(lights):
        light = x + 1
        bridge.lights[light].state(on=False)

def Turn_On(lights):
    for x in range(lights):
        light = x + 1
        bridge.lights[light].state(on=True)

def menu():
    os.system('clear')
    ans=True
    while ans:
        print('Bridge IP {ip} and Username {UN}'.format(ip=BRIDGE_IP, UN=username))
        print ("""
1. View Light Info
2. Start Rave
3. Turn Off All Lights
4. Turn On All Lights
5. View Creds File
6. Exit Program
        """)
        ans=input("What would you like to do? ")
        if ans=="1":
            Get_LightInfo()
            input("Press Enter to continue...")
            menu()
        elif ans=="2":
            num_lights = int(input("Enter the number of hue lights:"))
            Start_Rave(num_lights)
            input("Press Enter to continue...")
            menu()
        elif ans=="3":
            num_lights = int(input("Enter the number of hue lights:"))
            Turn_Off(num_lights)
            input("Press Enter to continue...")
            menu()
        elif ans=="4":
            num_lights = int(input("Enter the number of hue lights:"))
            Turn_On(num_lights)
            input("Press Enter to continue...")
            menu()
        elif ans=="5":
            Creds = open(CRED_FILE_PATH, "r")
            for line in Creds:
                print(line)
            input("Press Enter to continue...")
            menu()
        elif ans=="6":
            exit()
        elif ans !="":
            print("\n Not Valid Choice Try again")
            input("Press Enter to continue...")
            menu()

#Gets Bridge IP
BRIDGE_IP = Get_Bridge_IP()
#Get Bridge Username
username = Get_Username(BRIDGE_IP)
#Creates Bridge Connection
bridge = Bridge(BRIDGE_IP, username)

menu()


from django.contrib import admin
from .models import UserProfile
from django.contrib.auth.admin import UserAdmin
from typing import Set

# Unregister the provided model admin
#admin.site.unregister(UserProfile)

# Register out own model admin, based on the default UserAdmin
@admin.register(UserProfile)
class CustomUserAdmin(UserAdmin):

    readonly_fields = [
        'password',
        'date_joined'
    ]

    def has_delete_permission(self, request, obj=None):
        return False

    def get_form(self, request, obj=None, **kwargs): #Conditionally Prevent Update of Fields
        form = super().get_form(request, obj, **kwargs)
        is_superuser = request.user.is_superuser
        disabled_fields = set()  # type: Set[str]

        if not is_superuser:
            disabled_fields |= {
                'username',
                'email'
                'is_superuser',
            }

        # Prevent non-superusers from editing their own permissions
        if (
            not is_superuser
            and obj is not None
            and obj == request.user
        ):
            disabled_fields |= {
                'is_staff',
                'is_superuser',
                'groups',
                'user_permissions',
            }

        for f in disabled_fields:
            if f in form.base_fields:
                form.base_fields[f].disabled = True

        return form


from django.contrib import admin
from django.urls import path, re_path as url
from benie_app import views

# url patterns/configurations
urlpatterns = [
    url(r'^contacts/all$',views.Contacts.as_view(),name='contacts'),
    url(r'^contact/details/(\d+)$',views.ContactDetails.as_view(),name='contact-details'),
    url(r'^subscriber/details/(\d+)$',views.SubscriberDetails.as_view(),name='subscriber-details'),
    url(r'^stories/add$',views.AddStory.as_view(),name='add-story'),
    url(r'^story/update/(\d+)$',views.UpdateStory.as_view(),name='update-story'),
    url(r'^chapters/add$',views.AddChapter.as_view(),name='add-chapter'),
    url(r'^chapter/update/(\d+)$',views.UpdateChapter.as_view(),name='update-chapter'),
    url(r'^pages/all$',views.AllPages.as_view(),name='all-pages'),
    url(r'^pages/add$',views.AddPage.as_view(),name='add-page'),
    url(r'^page/update/(\d+)$',views.UpdatePage.as_view(),name='update-page'),
    url(r'^tags/add$',views.AddTag.as_view(),name='add-tag'),
    url(r'^tag/details/(\d+)$',views.TagDetails.as_view(),name='tag-details'),
    url(r'^poems/add$',views.AddPoem.as_view(),name='add-poem'),
    url(r'^poem/update/(\d+)$',views.UpdatePoem.as_view(),name='update-poem'),
    url(r'^notification/details/(\d+)$',views.NotificationDetails.as_view(),name='notification-details'),
    url(r'^reaction/details/(\d+)$',views.ReactionDetails.as_view(),name='reaction-details'),
]


import matplotlib.pyplot as plt
import numpy as np
import math
import random

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Cluster:
    def __init__(self, center, points=[]):
        self.center = center
        self.points = points

    def find_new_center(self):
        if len(self.points) <= 0:
            return
        x, y = 0, 0
        for point in self.points:
            x += point.x
            y += point.y
        self.center = Point(x / len(self.points), y / len(self.points))

n = 500
k = 5
colors = []

for _ in range(125):
    color = ["#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)])]
    colors.append(color)

def calculate_dist(a, b):
    return np.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)

def random_points(n, k):
    temp = []
    ces = centers([Point(0, 0), Point(0, 250)], k)
    for i in range(k):
        radius = int((0.5 + random.random()) * 70)
        for j in range(int(n / k)):
            r = radius * math.sqrt(random.random())
            alpha = 2 * math.pi * random.random()
            temp.append(Point(r * math.cos(alpha) + ces[i].x, r * math.sin(alpha) + ces[i].y))

    return temp

def centers(points, k):
    temp = list()
    x_s, y_s = 0, 0
    for point in points:
        x_s += point.x
        y_s += point.y
    x_s /= len(points)
    y_s /= len(points)
    center = Point(x_s, y_s)
    max_dist = 0
    for point in points:
        max_dist = max(max_dist, calculate_dist(point, center))

    for i in range(k):
        x_f = x_s + max_dist * math.cos(2 * i * np.pi / k)
        y_f = y_s + max_dist * math.sin(2 * i * np.pi / k)
        temp.append(Point(x_f, y_f))

    return temp

def draw(clusters, points, matrix):
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(1, 1, 1)
    ax.set_facecolor('grey')
    matrix_per_point = matrix.transpose()

    for p_i, point in enumerate(points):
        cluster_index = max([x for x in enumerate(matrix_per_point[p_i])], key=lambda x: x[1])[0]
        plt.scatter(point.x, point.y, c=colors[cluster_index], alpha=0.3)
    for c_i, cluster in enumerate(clusters):
        plt.scatter(cluster.center.x, cluster.center.y, c=colors[c_i])
    plt.show()

def calculate_matrix(points, clusters, m):
    matrix = np.zeros(shape=(len(clusters), len(points)))
    p = 2 / (m - 1)
    for p_i, point in enumerate(points):
        sum_t = sum([(1 / calculate_dist(point, temp.center)) ** p for temp in clusters])
        for c_i, cluster in enumerate(clusters):
            matrix[c_i][p_i] = ((1 / calculate_dist(point, cluster.center)) ** p) / sum_t
    return matrix

def centroids(points, clusters, matrix):
    for c_i, cluster in enumerate(clusters):
        sum_t = np.zeros(2)
        for p_i, point in enumerate(points):
            sum_t += np.array([point.x * matrix[c_i][p_i], point.y * matrix[c_i][p_i]])
        cluster.center = Point(sum_t[0] / sum(matrix[c_i]), sum_t[1] / sum(matrix[c_i]))

def check(matrix1, matrix2, e, n, k):
    for i in range(k):
        for j in range(n):
            if abs(matrix1[i][j] - matrix2[i][j]) > e: return True
    return False

def c_means(points, centers, m, e):
    clusters = list()
    for center in centers:
        clusters.append(Cluster(center))
    for point in points:
        cluster_temp = clusters[0]
        for cluster in clusters:
            if calculate_dist(point, cluster.center) < calculate_dist(point, cluster_temp.center):
                cluster_temp = cluster
        cluster_temp.points.append(point)
    matrix = calculate_matrix(points, clusters, m)
    draw(clusters, points, matrix)

    centroids(points, clusters, matrix)
    new_matrix = calculate_matrix(points, clusters, m)

    while check(matrix, new_matrix, e, n, k):
        matrix = new_matrix
        centroids(points, clusters, matrix)
        new_matrix = calculate_matrix(points, clusters, m)
        draw(clusters, points, matrix)

points_list = random_points(n, k)
clusters_t = centers(points_list, k)
c_means(points_list, clusters_t, 2, 0.01)


# Importe a classe do idioma inglês
from spacy.lang.en import English

# Crie um objeto nlp
nlp = English()

# Processe o texto
doc = nlp("This is a sentence.")

# Imprima o texto do documento
print(doc.text)


import os
import shutil

from tqdm import tqdm

from ....distributed.group import is_distributed
from ....logger import get_logger
from ....serialization import load, save
from .folder import ImageFolder
from .utils import _default_dataset_root, calculate_md5, untar, untargz

logger = get_logger(__name__)

class ImageNet(ImageFolder):
    r"""Load ImageNet from raw files or folder. Expected folder looks like:

    .. code-block:: shell

        ${root}/
        |       [REQUIRED TAR FILES]
        |-  ILSVRC2012_img_train.tar
        |-  ILSVRC2012_img_val.tar
        |-  ILSVRC2012_devkit_t12.tar.gz
        |       [OPTIONAL IMAGE FOLDERS]
        |-  train/cls/xxx.${img_ext}
        |-  val/cls/xxx.${img_ext}
        |-  ILSVRC2012_devkit_t12/data/meta.mat
        |-  ILSVRC2012_devkit_t12/data/ILSVRC2012_validation_ground_truth.txt

    If the image folders don't exist, raw tar files are required to get extracted and processed.

        * if ``root`` contains ``self.target_folder`` depending on ``train``:

          * initialize ImageFolder with target_folder.

        * else:

          * if all raw files are in ``root``:

            * parse ``self.target_folder`` from raw files.
            * initialize ImageFolder with ``self.target_folder``.

          * else:

            * raise error.

    Args:
        root: root directory of imagenet data, if root is ``None``, use default_dataset_root.
        train: if ``True``, load the train split, otherwise load the validation split.

    """

    raw_file_meta = {
        "train": ("ILSVRC2012_img_train.tar", "1d675b47d978889d74fa0da5fadfb00e"),
        "val": ("ILSVRC2012_img_val.tar", "29b22e2961454d5413ddabcf34fc5622"),
        "devkit": ("ILSVRC2012_devkit_t12.tar.gz", "fa75699e90414af021442c21a62c3abf"),
    }  # ImageNet raw files
    default_train_dir = "train"
    default_val_dir = "val"
    default_devkit_dir = "ILSVRC2012_devkit_t12"

    def __init__(self, root: str = None, train: bool = True, **kwargs):
        # process the root path
        if root is None:
            self.root = self._default_root
        else:
            self.root = root

        if not os.path.exists(self.root):
            raise FileNotFoundError("dir %s does not exist" % self.root)

        self.devkit_dir = os.path.join(self.root, self.default_devkit_dir)

        if not os.path.exists(self.devkit_dir):
            logger.warning("devkit directory %s does not exists", self.devkit_dir)
            self._prepare_devkit()

        self.train = train

        if train:
            self.target_folder = os.path.join(self.root, self.default_train_dir)
        else:
            self.target_folder = os.path.join(self.root, self.default_val_dir)

        if not os.path.exists(self.target_folder):
            logger.warning(
                "expected image folder %s does not exist, try to load from raw file",
                self.target_folder,
            )
            if not self.check_raw_file():
                raise FileNotFoundError(
                    "expected image folder %s does not exist, and raw files do not exist in %s"
                    % (self.target_folder, self.root)
                )
            elif is_distributed():
                raise RuntimeError(
                    "extracting raw file shouldn't be done in distributed mode, use single process instead"
                )
            elif train:
                self._prepare_train()
            else:
                self._prepare_val()

        super().__init__(self.target_folder, **kwargs)

    @property
    def _default_root(self):
        return os.path.join(_default_dataset_root(), self.__class__.__name__)

    @property
    def valid_ground_truth(self):
        groud_truth_path = os.path.join(
            self.devkit_dir, "data", "ILSVRC2012_validation_ground_truth.txt"
        )
        if os.path.exists(groud_truth_path):
            with open(groud_truth_path, "r") as f:
                val_labels = f.readlines()
                return [int(val_label) for val_label in val_labels]
        else:
            raise FileNotFoundError(
                "valid ground truth file %s does not exist" % groud_truth_path
            )

    @property
    def meta(self):
        try:
            return load(os.path.join(self.devkit_dir, "meta.pkl"))
        except FileNotFoundError:
            import scipy.io

            meta_path = os.path.join(self.devkit_dir, "data", "meta.mat")
            if not os.path.exists(meta_path):
                raise FileNotFoundError("meta file %s does not exist" % meta_path)
            meta = scipy.io.loadmat(meta_path, squeeze_me=True)["synsets"]
            nums_children = list(zip(*meta))[4]
            meta = [
                meta[idx]
                for idx, num_children in enumerate(nums_children)
                if num_children == 0
            ]
            idcs, wnids, classes = list(zip(*meta))[:3]
            classes = [tuple(clss.split(", ")) for clss in classes]
            idx_to_wnid = dict(zip(idcs, wnids))
            wnid_to_classes = dict(zip(wnids, classes))
            logger.info(
                "saving cached meta file to %s",
                os.path.join(self.devkit_dir, "meta.pkl"),
            )
            save(
                (idx_to_wnid, wnid_to_classes),
                os.path.join(self.devkit_dir, "meta.pkl"),
            )
            return idx_to_wnid, wnid_to_classes

    def check_raw_file(self) -> bool:
        return all(
            [
                os.path.exists(os.path.join(self.root, value[0]))
                for _, value in self.raw_file_meta.items()
            ]
        )

    def _organize_val_data(self):
        id2wnid = self.meta[0]
        val_idcs = self.valid_ground_truth
        val_wnids = [id2wnid[idx] for idx in val_idcs]

        val_images = sorted(
            [
                os.path.join(self.target_folder, image)
                for image in os.listdir(self.target_folder)
            ]
        )

        logger.debug("mkdir for val set wnids")
        for wnid in set(val_wnids):
            os.makedirs(os.path.join(self.root, self.default_val_dir, wnid))

        logger.debug("mv val images into wnids dir")
        for wnid, img_file in tqdm(zip(val_wnids, val_images)):
            shutil.move(
                img_file,
                os.path.join(
                    self.root, self.default_val_dir, wnid, os.path.basename(img_file)
                ),
            )

    def _prepare_val(self):
        assert not self.train
        raw_filename, checksum = self.raw_file_meta["val"]
        raw_file = os.path.join(self.root, raw_filename)
        logger.info("checksum valid tar file %s ...", raw_file)
        assert (
            calculate_md5(raw_file) == checksum
        ), "checksum mismatch, {} may be damaged".format(raw_file)
        logger.info("extract valid tar file... this may take 10-20 minutes")
        untar(raw_file, self.target_folder)
        self._organize_val_data()

    def _prepare_train(self):
        assert self.train
        raw_filename, checksum = self.raw_file_meta["train"]
        raw_file = os.path.join(self.root, raw_filename)
        logger.info("checksum train tar file %s ...", raw_file)
        assert (
            calculate_md5(raw_file) == checksum
        ), "checksum mismatch, {} may be damaged".format(raw_file)
        logger.info("extract train tar file.. this may take several hours")
        untar(raw_file, self.target_folder)
        paths = [
            os.path.join(self.target_folder, child_dir)
            for child_dir in os.listdir(self.target_folder)
        ]
        for path in tqdm(paths):
            untar(path, os.path.splitext(path)[0], remove=True)

    def _prepare_devkit(self):
        raw_filename, checksum = self.raw_file_meta["devkit"]
        raw_file = os.path.join(self.root, raw_filename)
        logger.info("checksum devkit tar file %s ...", raw_file)
        assert (
            calculate_md5(raw_file) == checksum
        ), "checksum mismatch, {} may be damaged".format(raw_file)
        logger.info("extract devkit file..")
        untargz(os.path.join(self.root, self.raw_file_meta["devkit"][0]))


import pytest
from selenium.webdriver import Chrome
from lesson_20.page.dashboard_page import Dashboard

@pytest.fixture(scope='session')
def driver():
    driver = Chrome()
    driver.get('https://lordofboards.com.ua/')
    driver.maximize_window()

    yield driver
    driver.close()

@pytest.fixture(scope='function')
def dashboard(driver):
    yield Dashboard(driver)


import os
import shutil
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings

class Command(BaseCommand):
    help = 'Moves ADS default images to the correct image directory'

    def handle(self, *args, **options):
        current_dir = os.path.dirname(os.path.realpath(__file__))
        ads_img_dir = os.path.join(current_dir, '../../static/img')
        src_files = os.listdir(ads_img_dir)
        dest = os.path.join(settings.MEDIA_ROOT, 'img')
        if not os.path.exists(dest):
            os.makedirs(dest)
        for file_name in src_files:
            full_file_name = os.path.join(ads_img_dir, file_name)
            if (os.path.isfile(full_file_name)):
                self.stdout.write("Copying " + file_name, ending='\n')
                shutil.copy(full_file_name, dest)
        self.stdout.write("Complete.", ending='\n')


import os
import http.server
import json
import threading
import multiprocessing.pool
import subprocess

events = ["Push Hook",
          "Tag Push Hook",
          "Issue Hook",
          "Note Hook",
          "Merge Request Hook",
          "Wiki Page Hook",
          "Pipeline Hook",
          "Job Hook"]

def handle_hook(event, token, obj, config):
    try:
        handle_hook_c(event, token, obj, config)
    except Exception as e:
        print(e)

def handle_hook_c(event, token, obj, config):
    if 'project' not in obj or type(obj['project']) != dict:
        return
    if 'web_url' not in obj['project'] or type(obj['project']['web_url']) != str:
        return
    weburl = obj['project']['web_url']
    if 'ref' not in obj or type(obj['ref']) != str:
        return
    ref = obj['ref']
    print("Hook: ", event, weburl, ref)
    # find repositories
    found_repos = []
    for repo in config.repositories:
        if repo.gitlaburl == weburl and repo.gitlabtoken == token and (repo.ref == None or repo.ref == ref) and (repo.hooks == None or len(repo.hooks) == 0 or event in repo.hooks):
            print(" *  ", repo.name, repo.gitlaburl, repo.ref, repo.hooks)
            found_repos.append(repo)
    if len(found_repos) == 0:
        return
    # find programs
    found_cmds = []
    for cmd in config.commands:
        for repo in found_repos:
            if cmd.repo == repo.name:
                print(" -> ", cmd.name)
                found_cmds.append(cmd)
                break
    if len(found_cmds) == 0:
        return
    # execute programs
    env = {}
    env['GITLAB_URL'] = weburl
    env['GITLAB_TOKEN'] = token
    env['GITLAB_REF'] = ref
    env['GITLAB_EVENT'] = event
    for cmd in found_cmds:
        res = cmd.exec(env)
        if cmd.ignore_error == False and res != 0:
            break

class GitlabHookHandler(http.server.BaseHTTPRequestHandler):

    def send_error(self, code, message=None, explain=None):
        self.log_request(code)
        self.send_response_only(code, message)
        self.send_header('Connection', 'close')
        self.end_headers()

    def do_POST(self):
        event = None
        token = None
        if "X-Gitlab-Event" in self.headers:
            event = self.headers["X-Gitlab-Event"]
        if "X-Gitlab-Token" in self.headers:
            token = self.headers["X-Gitlab-Token"]
        if event == None or token == None:
            self.send_error(http.HTTPStatus.FORBIDDEN, "Forbidden")
            return

        if 'Content-Length' not in self.headers:
            self.send_error(http.HTTPStatus.BAD_REQUEST, "Bad request")
            return

        # get body
        length = None
        try:
            length = int(self.headers['Content-Length'])
        except:
            pass
        if length == None:
            self.send_error(http.HTTPStatus.BAD_REQUEST, "Bad request")
            return
        text = None
        try:
            text = self.rfile.read(length)
        except:
            self.send_error(http.HTTPStatus.BAD_REQUEST, "Bad request")
            return
        json_obj = None
        try:
            json_obj = json.loads(text)
        except Exception as e:
            pass
        if json_obj == None:
            self.send_error(http.HTTPStatus.BAD_REQUEST, "Bad request")
            return

        self.handle_request(event, token, json_obj)

        self.log_request(http.HTTPStatus.OK)
        self.send_response_only(http.HTTPStatus.OK)
        self.send_header('Connection', 'close')
        self.end_headers()

    def handle_request(self, event, token, json_obj):
        pass

class GitlabHookServer(threading.Thread):
    def __init__(self, interface, port, configjson, workers=2):
        config = GitlabHookConfig.fromConfig(configjson)
        self.config = config
        self.configjson = configjson
        pool = multiprocessing.pool.ThreadPool()
        self.pool = pool
        class PrivateGitlabHookHandler(GitlabHookHandler):
            def handle_request(self, event, token, json_obj):
                pool.apply_async(handle_hook, (event, token, json_obj, config))
        print("Start server on ", interface, port)
        self.httpd = http.server.HTTPServer((interface, port), PrivateGitlabHookHandler)
        threading.Thread.__init__(self)
    def run(self):
        self.httpd.serve_forever()
    def stopServer(self):
        self.httpd.shutdown()
        self.httpd.server_close()
        self.pool.close()
        self.pool.join()
        self.pool.terminate()

class Command:
    def __init__(self, name, prog, reponame):
        # config
        self.name = name
        self.prog = prog
        self.repo = reponame
        self.workingdir = None
        self.ignore_error = False
        self.hooks = None
    def fromConfig(config):
        j = Command(config["name"], config["exec"], config["repo"])
        if "workingdir" in config:
            j.workingdir = config["workingdir"]
        if "ignore_error" in config:
            j.ignore_error = config["ignore_error"]
        if 'hook' in config and type(config['hook']) == list:
            hooks = config['hook']
            for h in hooks:
                if type(h) != str:
                    print("Wrong config value: ", config["name"], "hooks")
                if h not in events:
                    print("Unknown hook event: ", h)
            j.hooks = hooks
        return j
    def exec(self, env):
        cmd = self.prog
        print("Prog", self.name, "execute", " ".join(cmd))
        # create new environment
        new_env = os.environ.copy()
        new_env.update(env)
        # run process
        process = subprocess.Popen(cmd, env=new_env, cwd=self.workingdir)
        process.wait()
        print("Prog", self.name, "Return:", process.returncode)
        return process.returncode

class Repository:
    def __init__(self, name, url, token):
        self.name = name
        self.gitlaburl = url
        self.gitlabtoken = token
        self.ref = None
        self.hooks = None
    def fromConfig(config):
        r = Repository(config["name"], config["gitlaburl"], config["gitlabtoken"])
        if 'ref' in config:
            r.ref = config['ref']
        if 'hook' in config and type(config['hook']) == list:
            hooks = config['hook']
            for h in hooks:
                if type(h) != str:
                    print("Wrong config value: ", config["name"], "hooks")
                if h not in events:
                    print("Unknown hook event: ", h)
            r.hooks = hooks
        return r

class GitlabHookConfig:
    def __init__(self):
        self.interface = ""
        self.port = None
        self.repositories = []
        self.commands = []
    def fromConfig(config):
        c = GitlabHookConfig()
        if 'interface' in config:
            c.interface = config['interface']
        if 'port' in config:
            c.port = config['port']
        for r in config['repositories']:
            r = Repository.fromConfig(r)
            c.repositories.append(r)
        for e in config['commands']:
            cmd = Command.fromConfig(e)
            c.commands.append(cmd)
        return c


# DFS, BFS 탐색 결과 출력하기
from collections import deque
import sys

n, m, v = map(int, sys.stdin.readline().rstrip().split())

# gragh = [[]]
# for _ in range(m):
#     gragh.append(list(map(int, sys.stdin.readline().rstrip().split())))

gragh = [[0] * (n + 1) for i in range(n + 1)]

for i in range(m):
    x, y = map(int, input().split())
    gragh[x][y] = 1
    gragh[y][x] = 1

dfs_visited = [0] * (n + 1)
bfs_visited = [0] * (n + 1)

def dfs(gragh, v):
    # 현재 노드 방문 처리
    dfs_visited[v] = 1
    print(v, end=" ")

    # 현재 노드와 연결된 다른 노드를 재귀적으로 방문
    for node, yn in enumerate(gragh[v]):
        if yn == 1:
            if dfs_visited[node] == 0:
                dfs(gragh, node)

def bfs(gragh, v):
    # 큐 구현
    queue = deque()
    queue.append(v)

    # 현재 노드 방문 처리
    bfs_visited[v] = 1

    # 큐가 빌 때 까지 반복
    while queue:

        # 큐에서 원소 하나를 뺀다
        v = queue.popleft()
        print(v, end=" ")

        # 인접한 노드들 중 방문하지 않은 노드들은 큐에 넣는다
        for node, yn in enumerate(gragh[v]):
            if yn == 1:
                if bfs_visited[node] == 0:
                    queue.append(node)
                    bfs_visited[node] = 1

dfs(gragh, v)
print()
bfs(gragh, v)


from concurrent.futures import ProcessPoolExecutor, as_completed
from copy import deepcopy
from dataclasses import dataclass
from typing import List

import gym
import numpy as np
import numpy.typing as npt
from omegaconf import DictConfig
from tqdm import trange

from agent import Agent
from core import Layer, LinearLayer, Model, relu

@dataclass()
class Candidate:
    model: Model
    fitness: float

@dataclass()
class EvolutionalAgentConfig:
    generations: int
    children_per_parent: int
    mutation_strength: float
    num_parents: int
    nodes: List[int]

    @staticmethod
    def fromDictConfig(config: DictConfig) -> "EvolutionalAgentConfig":
        return EvolutionalAgentConfig(
            config.generations,
            config.children_per_parent,
            config.mutation_strength,
            config.num_parents,
            config.nodes,
        )

class EvolutionalAgent(Agent):
    def __init__(self, config: EvolutionalAgentConfig) -> None:
        self.config = config
        self._policy_model = self._create_policy_model()

    def action(self, state: npt.NDArray[np.float32]) -> npt.NDArray[np.float32]:
        return self._policy_model(state)

    def train(self, env: gym.Env) -> List[float]:
        executor = ProcessPoolExecutor()
        rewards = []
        parents = [
            EvolutionalAgent._create_candidate(env, self._create_policy_model())
            for _ in range(self.config.num_parents)
        ]
        with trange(0, self.config.generations) as tgen:
            for generation in tgen:
                env.reset()
                best_parent_fitness = EvolutionalAgent._best_candidate(parents).fitness
                rewards.append(best_parent_fitness)
                tgen.set_postfix(
                    generation=generation,
                    fitness=best_parent_fitness,
                )

                candidates_f = [
                    executor.submit(
                        EvolutionalAgent._create_candidate,
                        env,
                        parent.model,
                        self.config.mutation_strength,
                    )
                    for parent in parents
                    for _ in range(self.config.children_per_parent)
                ]
                candidates_f.extend(
                    [
                        executor.submit(
                            EvolutionalAgent._create_candidate,
                            env,
                            parent.model,
                        )
                        for parent in parents
                    ]
                )
                candidates = [
                    candidate.result() for candidate in as_completed(candidates_f)
                ]
                candidates.sort(key=lambda x: x.fitness, reverse=True)
                parents = candidates[0 : self.config.num_parents]

        self._policy_model = EvolutionalAgent._best_candidate(parents).model
        executor.shutdown()
        return rewards

    @staticmethod
    def _create_candidate(
        env: gym.Env, parent: Model, mutation_strength: float = 0.0
    ) -> Candidate:
        env_c = deepcopy(env)
        child = deepcopy(parent)
        for layer in child._layers:
            layer.W += np.random.normal(scale=mutation_strength, size=layer.W.shape)
            layer.b += np.random.normal(scale=mutation_strength, size=layer.b.shape)
        fitness = EvolutionalAgent._play(env_c, child)
        return Candidate(child, fitness)

    @staticmethod
    def _play(env: gym.Env, policy_model: Layer) -> float:
        state, done, sum_reward = env.reset(), False, 0
        while not done:
            action = policy_model(state)
            new_state, reward, done, _ = env.step(action)
            sum_reward += reward
            state = new_state

        return sum_reward

    def _create_policy_model(self) -> Model:
        nodes = self.config.nodes

        layers = []
        layers.append(LinearLayer(24, nodes[0], activation=relu))

        for id in range(0, len(self.config.nodes) - 1):
            layers.append(LinearLayer(nodes[id], nodes[id + 1], activation=relu))

        layers.append(LinearLayer(nodes[-1], 4, activation=np.tanh))

        return Model(*layers)

    def _best_candidate(candidates: List[Candidate]) -> Candidate:
        id = np.argmax([candidate.fitness for candidate in candidates])
        return candidates[id]