################################################################################
# part2.py
################################################################################

import logging
from enum import Enum
from typing import Tuple

logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)

#

class Direction(Enum):
    DOWN = 'D'
    LEFT = 'L'
    RIGHT = 'R'
    UP = 'U'

#

class Rope():

    def __init__(self, knot_count: int = 10):
        self.knot_count = knot_count
        self._knots = []
        for _ in range(0, knot_count):
            self._knots.append({'x': 0, 'y': 0})
        self._tail_trail = []

    def _calculate_delta(self, lead_knot_id: int, follower_knot_id: int) -> Tuple:
        delta_x = self._knots[lead_knot_id]['x'] - self._knots[follower_knot_id]['x']
        delta_y = self._knots[lead_knot_id]['y'] - self._knots[follower_knot_id]['y']
        return delta_x, delta_y

    def move(self, direction: Direction, steps: int):

        log.debug('moving %s by %d steps...', direction.name, steps)

        for _ in range(0, steps):
            if direction == Direction.DOWN:
                log.debug('moving K0 Y by -1...')
                self._knots[0]['y'] -= 1
            elif direction == Direction.LEFT:
                log.debug('moving K0 X by -1...')
                self._knots[0]['x'] -= 1
            elif direction == Direction.RIGHT:
                log.debug('moving K0 X by 1...')
                self._knots[0]['x'] += 1
            elif direction == Direction.UP:
                log.debug('moving K0 Y by 1...')
                self._knots[0]['y'] += 1

            log.debug('K0: %d:%d', self._knots[0]['x'], self._knots[0]['y'])

            self._move_knots()

            self._record_tail_position()

    def _move_knots(self):

        for knot_id in range(1, len(self._knots), 1):

            log.debug('K%d BEFORE: %d:%d', knot_id, self._knots[knot_id]['x'], self._knots[knot_id]['y'])

            moved_x = False
            moved_y = False

            delta_x, delta_y = self._calculate_delta((knot_id - 1), knot_id)
            delta_x_abs = abs(delta_x)
            delta_y_abs = abs(delta_y)

            log.debug('delta: %s:%s', delta_x, delta_y)

            if delta_x_abs == 2:
                move_by = delta_x / delta_x_abs
                log.debug('moving %d x by %d...', knot_id, move_by)
                self._knots[knot_id]['x'] += move_by
                moved_x = True

            if delta_y_abs == 2:
                move_by = delta_y / delta_y_abs
                log.debug('moving %d y by %d...', knot_id, move_by)
                self._knots[knot_id]['y'] += move_by
                moved_y = True

            if moved_y and delta_x_abs == 1:
                log.debug('moving %d x by %d...', knot_id, delta_x)
                self._knots[knot_id]['x'] += delta_x

            if moved_x and delta_y_abs == 1:
                log.debug('moving %d y by %d...', knot_id, delta_y)
                self._knots[knot_id]['y'] += delta_y

            log.debug('K%d AFTER: %d:%d', knot_id, self._knots[knot_id]['x'], self._knots[knot_id]['y'])

    def _record_tail_position(self):
        tail_knot = self._knots[self.knot_count - 1]
        position = str(int(tail_knot['x'])) + ':' + str(int(tail_knot['y']))
        if position not in self._tail_trail:
            self._tail_trail.append(position)

    @property
    def tail_location_count(self) -> int:
        return len(self._tail_trail)

# Read in the contents of our INPUT.

with open('input.txt') as input_file:
    input_data = input_file.readlines()

rope = Rope(10)

for command_raw in input_data:
    command = command_raw.strip()
    command_parts = command.split(' ')

    rope.move(Direction(command_parts[0]), int(command_parts[1]))

for loc in rope._tail_trail:
    print(loc)
print(rope.tail_location_count)

################################################################################
# END
################################################################################


import copy
import mock

from conveyor.compute import nova
from conveyor import context
from conveyor import exception
from conveyor.network import neutron
from conveyor.resource.driver import instances
from conveyor.resource.driver import networks
from conveyor.resource import resource
from conveyor.tests import test

fake_server_dict = {
    "id": "server_123",
    "name": "ubuntu14.04",
    "OS-EXT-STS:vm_state": "stopped",
    "OS-EXT-STS:power_state": 4,
    "metadata": {},
    "OS-EXT-SRV-ATTR:user_data": "",
    "image": {"id": "image_123"},
    "flavor": {"id": "6"},
    "addresses": {"test02": [{
        "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:e5:66:fc",
        "version": 4,
        "addr": "197.168.16.56",
        "OS-EXT-IPS:type": "fixed"}
    ]},
    "key_name": "keypair_123",
    "os-extended-volumes:volumes_attached": '',
    "OS-EXT-AZ:availability_zone": "az01",
    'status': 'stopped'
}

fake_flavor_dict = {
    "id": 6,
    "name": '',
    "ram": 1024,
    "vcpus": 1,
    "disk": 5,
    "rxtx_factor": 1,
    "os-flavor-access:is_public": True,
    "OS-FLV-EXT-DATA:ephemeral": 0,
}

fake_keypair_dict = {
    "id": "keypair_123",
    "name": "keyapir",
    "public_key": "public_key"
}

fake_port_dict = {
    "status": "UP",
    "created_at": "2017-04-24T12:32:10",
    "binding:host_id": "",
    "description": "",
    "allowed_address_pairs": [],
    "admin_state_up": True,
    "network_id": "01329398-2050-4152-a034-c1b302e70619",
    "tenant_id": "d23b65e027f9461ebe900916c0412ade",
    "extra_dhcp_opts": [],
    "updated_at": "2017-04-24T13:06:34",
    "name": "",
    "binding:vif_type": "unbound", "device_owner": "",
    "mac_address": "fa:16:3e:e5:66:fc", "binding:vif_details": {},
    "binding:profile": {},
    "binding:vnic_type": "normal",
    "fixed_ips": [{"subnet_id": "ecc01e23-ed69-4c4a-a93c-6ab3d76e59d8",
                   "ip_address": "197.168.16.56"}],
    "id": "00c94695-077e-4b2d-9858-f902e4f6a932",
    "security_groups": ["6207c842-f8a1-4ce7-9931-acfbe7929df1"],
    "device_id": ""
}

class InstanceResourceTesetCase(test.TestCase):

    def setUp(self):
        super(InstanceResourceTesetCase, self).setUp()
        self.context = context.RequestContext('fake', 'fake', is_admin=False)
        self.instance_resource = instances.InstanceResource(self.context)

    @mock.patch.object(networks.NetworkResource, 'extract_ports')
    @mock.patch.object(neutron.API, 'port_list')
    @mock.patch.object(nova.API, 'get_keypair')
    @mock.patch.object(nova.API, 'get_flavor')
    @mock.patch.object(nova.API, 'get_all_servers')
    def test_extract_all_instances(self, mock_server_list, mock_flavor,
                                   mock_keypair, mock_port_list,
                                   mock_extract_ports):
        # NOTE: for extracting servers, the following resources may be need
        # to extract: flavor, keypair, image, volume, network.
        mock_server_list.return_value = [copy.deepcopy(fake_server_dict)]
        mock_flavor.return_value = copy.deepcopy(fake_flavor_dict)
        mock_keypair.return_value = copy.deepcopy(fake_keypair_dict)
        mock_port_list.return_value = [copy.deepcopy(fake_port_dict)]
        mock_extract_ports.return_value = [
            resource.Resource('port_0', 'OS::Neutron::Port',
                              '00c94695-077e-4b2d-9858-f902e4f6a932')
        ]
        self.instance_resource.extract_instances([])
        self.assertTrue(
            len(self.instance_resource.get_collected_resources()) >= 3)

    @mock.patch.object(nova.API, 'get_all_servers')
    def test_extract_instance_with_no_servers(self, mock_server_list):
        mock_server_list.return_value = []
        self.instance_resource.extract_instances([])
        self.assertEqual(0,
                         len(self.instance_resource.get_collected_resources()))

    @mock.patch.object(nova.API, 'get_all_servers')
    def tet_extract_instance_with_invalid_addresses(self, mock_server_list):
        fake_server = copy.deepcopy(fake_server_dict)
        fake_server.pop("image")
        fake_server.pop("flavor")
        fake_server.pop("os-extended-volumes:volumes_attached")
        fake_server.pop("addresses")
        mock_server_list.return_value = [fake_server]
        self.assertRaises(exception.ResourceAttributesException,
                          self.instance_resource.extract_instances,
                          [])

    @mock.patch.object(nova.API, 'get_all_servers')
    def test_extract_instance_with_not_allowed_status(self, mock_server_list):
        fake_server = copy.deepcopy(fake_server_dict)
        fake_server.update({"OS-EXT-STS:vm_state": "error", 'status': 'error'})
        mock_server_list.return_value = [fake_server]
        self.assertRaises(exception.PlanCreateFailed,
                          self.instance_resource.extract_instances,
                          [])

    @mock.patch.object(networks.NetworkResource, 'extract_ports')
    @mock.patch.object(neutron.API, 'port_list')
    @mock.patch.object(nova.API, 'get_keypair')
    @mock.patch.object(nova.API, 'get_flavor')
    @mock.patch.object(nova.API, 'get_server')
    def test_extract_instances_with_ids(
            self, mock_server, mock_flavor, mock_keypair, mock_port_list,
            mock_extract_ports):
        # NOTE: for extracting servers, the following resources may be need
        # to extract: flavor, keypair, image, volume, network.
        mock_server.return_value = copy.deepcopy(fake_server_dict)
        mock_flavor.return_value = copy.deepcopy(fake_flavor_dict)
        mock_keypair.return_value = copy.deepcopy(fake_keypair_dict)
        mock_port_list.return_value = [copy.deepcopy(fake_port_dict)]
        mock_extract_ports.return_value = [
            resource.Resource('port_0', 'OS::Neutron::Port',
                              '00c94695-077e-4b2d-9858-f902e4f6a932')
        ]
        self.instance_resource.extract_instances([fake_server_dict["id"]])
        self.assertTrue(
            len(self.instance_resource.get_collected_resources()) >= 3)

    @mock.patch.object(nova.API, 'flavor_list')
    def test_extract_all_flavors(self, mock_flavor_list):
        mock_flavor_list.return_value = [{
            "id": 6,
            "name": '',
            "ram": 1024,
            "vcpus": 1,
            "disk": 5,
            "rxtx_factor": 1,
            "os-flavor-access:is_public": True,
            "OS-FLV-EXT-DATA:ephemeral": 0,
        }]
        flavor_res = self.instance_resource.extract_flavors([])
        self.assertEqual(1, len(flavor_res))
        self.assertIn(6, self.instance_resource.get_collected_resources())
        self.assertIn(6, self.instance_resource.get_collected_dependencies())

    @mock.patch.object(nova.API, 'get_flavor')
    def test_extract_flavor_with_ids(self, mock_get_flavor):
        mock_get_flavor.return_value = {
            "id": 6,
            "name": '',
            "ram": 1024,
            "vcpus": 1,
            "disk": 5,
            "rxtx_factor": 1,
            "os-flavor-access:is_public": True,
            "OS-FLV-EXT-DATA:ephemeral": 0,
        }
        flavor_res = self.instance_resource.extract_flavors([6])
        self.assertEqual(1, len(flavor_res))
        self.assertIn(6, self.instance_resource.get_collected_resources())
        self.assertIn(6, self.instance_resource.get_collected_dependencies())

    @mock.patch.object(nova.API, 'flavor_list')
    @mock.patch.object(resource, 'Resource')
    def test_extract_flavor_from_cache(self, mock_res, mock_flavor_list):
        """The request flavors ia already in collected resources"""
        fake_flavor = {
            "id": 6,
            "name": "flavor_0",
            "type": "OS::Nova::Flavor"
        }
        fake_flavor_res = resource.Resource(**fake_flavor)
        fake_flavor_dep = resource.ResourceDependency(
            6, 'flavor_0', "flavor_0", "OS::Nova::Flavor")
        self.instance_resource = instances.InstanceResource(
            self.context,
            collected_resources={6: fake_flavor_res},
            collected_dependencies={6: fake_flavor_dep})
        mock_flavor_list.return_value = [{
            "id": 6,
            "name": '',
            "ram": 1024,
            "vcpus": 1,
            "disk": 5,
            "rxtx_factor": 1,
            "os-flavor-access:is_public": True,
            "OS-FLV-EXT-DATA:ephemeral": 0,
        }]

        flavor_res = self.instance_resource.extract_flavors([])
        self.assertEqual(1, len(flavor_res))

    @mock.patch.object(nova.API, 'get_flavor', side_effect=Exception)
    def test_extract_flavor_failed(self, mock_get_flavor):
        self.assertRaises(exception.ResourceNotFound,
                          self.instance_resource.extract_flavors,
                          [6])

    @mock.patch.object(nova.API, 'keypair_list')
    def test_extract_all_keypairs(self, mock_keypair_list):
        # NOTE: This test no support input parameter, and inited
        # instnace_resource does not contain any collected resources or
        # dependencies.
        mock_keypair_list.return_value = [
            {
                "id": "keypair_0",
                "name": "keyapir",
                "public_key": "public_key"
            }
        ]

        keypair_res = self.instance_resource.extract_keypairs([])
        self.assertEqual(1, len(keypair_res))
        self.assertIn('keypair_0',
                      self.instance_resource.get_collected_resources())
        self.assertIn('keypair_0',
                      self.instance_resource.get_collected_dependencies())

    @mock.patch.object(nova.API, 'get_keypair')
    def test_extract_keypairs_with_ids(self, mock_get_keypair):
        mock_get_keypair.return_value = {
            "id": "keypair_0",
            "name": "keyapir",
            "public_key": "public_key"
        }

        fake_keypair_ids = ['keypair_0']
        keypair_res = self.instance_resource.extract_keypairs(fake_keypair_ids)
        self.assertEqual(1, len(keypair_res))
        self.assertIn('keypair_0',
                      self.instance_resource.get_collected_resources())
        self.assertIn('keypair_0',
                      self.instance_resource.get_collected_dependencies())

    @mock.patch.object(nova.API, 'keypair_list')
    @mock.patch.object(resource, 'Resource')
    def test_extract_keypairs_from_cache(self, mock_res, mock_keypair_list):
        """The request keypair ia already in collected resources"""
        fake_keypair = {
            "id": "keypair_0",
            "name": "keypair_0",
            "type": "OS::Nova::KeyPair"
        }
        fake_keypair_res = resource.Resource(**fake_keypair)
        fake_keypair_dep = resource.ResourceDependency(
            "keypair_0", "keypair_0", "keypair_0", "OS::Nova::KeyPair")
        self.instance_resource = instances.InstanceResource(
            self.context,
            collected_resources={'keypair_0': fake_keypair_res},
            collected_dependencies={'keypair_0': fake_keypair_dep})
        mock_keypair_list.return_value = [
            {
                "id": "keypair_0",
                "name": "keyapir",
                "public_key": "public_key"
            }
        ]

        keypair_res = self.instance_resource.extract_keypairs([])
        self.assertEqual(1, len(keypair_res))

    def test_extract_keyapirs_failed(self):
        with mock.patch.object(nova.API, 'get_keypair', side_effect=Exception):
            self.assertRaises(exception.ResourceNotFound,
                              self.instance_resource.extract_keypairs,
                              ['keypair_0'])

    def test_extract_image(self):
        fake_image_id = "image_123"
        result = self.instance_resource.extract_image(fake_image_id)
        self.assertIsNotNone(result)
        self.assertIn(fake_image_id,
                      self.instance_resource._collected_parameters)


class Solution(object):
    def sumOddLengthSubarrays(self, arr):

        _sum = 0
        length = len(arr)
        sub_len = 1
        start = 0

        while sub_len <= length:
            for start in range(length - sub_len + 1):
                for i in range(start, start + sub_len):
                    _sum = _sum + arr[i]
            sub_len = sub_len + 2

        return _sum


#!/usr/bin/env python
import logging
import unittest
from decimal import Decimal

import pandas as pd

from hummingbot.client.config.client_config_map import ClientConfigMap
from hummingbot.client.config.config_helpers import ClientConfigAdapter
from hummingbot.connector.exchange.paper_trade.paper_trade_exchange import QuantizationParams
from hummingbot.connector.test_support.mock_paper_exchange import MockPaperExchange
from hummingbot.core.clock import Clock, ClockMode
from hummingbot.core.data_type.common import TradeType
from hummingbot.core.data_type.order_book_row import OrderBookRow
from hummingbot.core.event.event_logger import EventLogger
from hummingbot.core.event.events import MarketEvent, OrderBookTradeEvent
from hummingbot.strategy.market_trading_pair_tuple import MarketTradingPairTuple
from hummingbot.strategy.pure_market_making.pure_market_making import PureMarketMakingStrategy

logging.basicConfig(level=logging.ERROR)

class PMMRefreshToleranceUnitTest(unittest.TestCase):
    start: pd.Timestamp = pd.Timestamp("2019-01-01", tz="UTC")
    end: pd.Timestamp = pd.Timestamp("2019-01-01 01:00:00", tz="UTC")
    start_timestamp: float = start.timestamp()
    end_timestamp: float = end.timestamp()
    trading_pair = "HBOT-ETH"
    base_asset = trading_pair.split("-")[0]
    quote_asset = trading_pair.split("-")[1]

    def simulate_maker_market_trade(self, is_buy: bool, quantity: Decimal, price: Decimal):
        order_book = self.market.get_order_book(self.trading_pair)
        trade_event = OrderBookTradeEvent(
            self.trading_pair,
            self.clock.current_timestamp,
            TradeType.BUY if is_buy else TradeType.SELL,
            price,
            quantity
        )
        order_book.apply_trade(trade_event)

    def setUp(self):
        self.clock_tick_size = 1
        self.clock: Clock = Clock(ClockMode.BACKTEST, self.clock_tick_size, self.start_timestamp, self.end_timestamp)
        self.market: MockPaperExchange = MockPaperExchange(
            client_config_map=ClientConfigAdapter(ClientConfigMap())
        )
        self.mid_price = 100
        self.bid_spread = 0.01
        self.ask_spread = 0.01
        self.order_refresh_time = 30
        self.market.set_balanced_order_book(trading_pair=self.trading_pair,
                                            mid_price=self.mid_price,
                                            min_price=1,
                                            max_price=200,
                                            price_step_size=1,
                                            volume_step_size=10)
        self.market.set_balance("HBOT", 500)
        self.market.set_balance("ETH", 5000)
        self.market.set_quantization_param(
            QuantizationParams(
                self.trading_pair, 6, 6, 6, 6
            )
        )
        self.market_info = MarketTradingPairTuple(self.market, self.trading_pair,
                                                  self.base_asset, self.quote_asset)
        self.clock.add_iterator(self.market)
        self.maker_order_fill_logger: EventLogger = EventLogger()
        self.cancel_order_logger: EventLogger = EventLogger()
        self.market.add_listener(MarketEvent.OrderFilled, self.maker_order_fill_logger)
        self.market.add_listener(MarketEvent.OrderCancelled, self.cancel_order_logger)

        self.one_level_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
        self.one_level_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_refresh_time=4,
            filled_order_delay=8,
            hanging_orders_enabled=True,
            hanging_orders_cancel_pct=0.05,
            order_refresh_tolerance_pct=0
        )
        self.multi_levels_strategy: PureMarketMakingStrategy = PureMarketMakingStrategy()
        self.multi_levels_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_refresh_time=4,
            filled_order_delay=8,
            order_refresh_tolerance_pct=0
        )
        self.hanging_order_multiple_strategy = PureMarketMakingStrategy()
        self.hanging_order_multiple_strategy.init_params(
            self.market_info,
            bid_spread=Decimal("0.01"),
            ask_spread=Decimal("0.01"),
            order_amount=Decimal("1"),
            order_levels=5,
            order_level_spread=Decimal("0.01"),
            order_refresh_time=4,
            filled_order_delay=8,
            order_refresh_tolerance_pct=0,
            hanging_orders_enabled=True
        )

    def test_active_orders_are_cancelled_when_mid_price_moves(self):
        strategy = self.one_level_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        old_bid = strategy.active_buys[0]
        old_ask = strategy.active_sells[0]
        # Not the order refresh time yet, orders should remain the same
        self.clock.backtest_til(self.start_timestamp + 3 * self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        self.assertEqual(old_bid.client_order_id, strategy.active_buys[0].client_order_id)
        self.assertEqual(old_ask.client_order_id, strategy.active_sells[0].client_order_id)
        self.market.order_books[self.trading_pair].apply_diffs([OrderBookRow(99.5, 30, 2)],
                                                               [OrderBookRow(100.1, 30, 2)], 2)
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        new_bid = strategy.active_buys[0]
        new_ask = strategy.active_sells[0]
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        self.assertNotEqual(old_ask, new_ask)
        self.assertNotEqual(old_bid, new_bid)

    def test_active_orders_are_kept_when_within_tolerance(self):
        strategy = self.one_level_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        old_bid = strategy.active_buys[0]
        old_ask = strategy.active_sells[0]
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        new_bid = strategy.active_buys[0]
        new_ask = strategy.active_sells[0]
        self.assertEqual(old_ask, new_ask)
        self.assertEqual(old_bid, new_bid)
        self.clock.backtest_til(self.start_timestamp + 10 * self.clock_tick_size)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(1, len(strategy.active_sells))
        new_bid = strategy.active_buys[0]
        new_ask = strategy.active_sells[0]
        self.assertEqual(old_ask, new_ask)
        self.assertEqual(old_bid, new_bid)

    def test_multi_levels_active_orders_are_cancelled_when_mid_price_moves(self):
        strategy = self.multi_levels_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        old_buys = strategy.active_buys
        old_sells = strategy.active_sells
        self.market.order_books[self.trading_pair].apply_diffs([OrderBookRow(99.5, 30, 2)],
                                                               [OrderBookRow(100.1, 30, 2)], 2)
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        new_buys = strategy.active_buys
        new_sells = strategy.active_sells
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        self.assertNotEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertNotEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])

    def test_multiple_active_orders_are_kept_when_within_tolerance(self):
        strategy = self.multi_levels_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        old_buys = strategy.active_buys
        old_sells = strategy.active_sells
        self.clock.backtest_til(self.start_timestamp + 6 * self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        new_buys = strategy.active_buys
        new_sells = strategy.active_sells
        self.assertEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])
        self.clock.backtest_til(self.start_timestamp + 10 * self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        new_buys = strategy.active_buys
        new_sells = strategy.active_sells
        self.assertEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])

    def test_hanging_orders_multiple_orders_with_refresh_tolerance(self):
        strategy = self.hanging_order_multiple_strategy
        self.clock.add_iterator(strategy)
        self.clock.backtest_til(self.start_timestamp + self.clock_tick_size)
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))

        self.simulate_maker_market_trade(True, Decimal("100"), Decimal("101.1"))

        # Before refresh_time hanging orders are not yet created
        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time / 2)
        self.assertEqual(1, len(self.maker_order_fill_logger.event_log))
        self.assertEqual(5, len(strategy.active_buys))
        self.assertEqual(4, len(strategy.active_sells))
        self.assertEqual(0, len(strategy.hanging_order_ids))

        # At order_refresh_time (4 seconds), hanging order are created
        # Ask is filled and due to delay is not replenished immediately
        # Bid orders are now hanging and active
        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time + 1)
        self.assertEqual(1, len(strategy.active_buys))
        self.assertEqual(0, len(strategy.active_sells))
        self.assertEqual(1, len(strategy.hanging_order_ids))

        # At filled_order_delay (8 seconds), new sets of bid and ask orders are created
        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time + strategy.filled_order_delay + 1)
        self.assertEqual(6, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))
        self.assertEqual(1, len(strategy.hanging_order_ids))

        # Check all hanging order ids are indeed in active bids list
        self.assertTrue(all(h in [order.client_order_id for order in strategy.active_buys]
                            for h in strategy.hanging_order_ids))

        old_buys = [o for o in strategy.active_buys if o.client_order_id not in strategy.hanging_order_ids]
        old_sells = [o for o in strategy.active_sells if o.client_order_id not in strategy.hanging_order_ids]

        self.clock.backtest_til(self.start_timestamp + strategy.order_refresh_time + strategy.filled_order_delay + 1)
        self.assertEqual(6, len(strategy.active_buys))
        self.assertEqual(5, len(strategy.active_sells))

        new_buys = [o for o in strategy.active_buys if o.client_order_id not in strategy.hanging_order_ids]
        new_sells = [o for o in strategy.active_sells if o.client_order_id not in strategy.hanging_order_ids]
        self.assertEqual([o.client_order_id for o in old_sells], [o.client_order_id for o in new_sells])
        self.assertEqual([o.client_order_id for o in old_buys], [o.client_order_id for o in new_buys])


# encoding: utf8

import re
from random import *
from collections import Counter
from pprint import pprint
from heapq import nlargest
from time import time

# -> http://obphio.us/pdfs/lda_tutorial.pdf
# -> http://brooksandrew.github.io/simpleblog/articles/latent-dirichlet-allocation-under-the-hood/

K = 4
ITERATIONS = 1000
alpha = 0.1 # document alpha factor
eta = 0.1 # word eta factor
RANDOMIZE = True
MULTIPLICATION = 10

TOP_N = 6

documents = [
"reksio szczeka na koty",
"pies glosno szczeka",
"koty cicho mrucza",
"reksio to madry pies",
"kerbale buduja rakiety",
"rakiety wynosza satelity",
"satelity sa na orbicie",
"rakiety glosno startuja",
"szybowce leca cicho",
"szybowce startuja z wyciagarki",
"samoloty szturmowe leca nisko",
"krowy jedza trawe",
"kury jedza ziarno",
"krowy pija wode"
]
documents *= MULTIPLICATION

def get_tf(text):
	terms = re.findall('(?u)\w+',text.lower())
	#terms = [t for t in terms if t not in set(['sa','na','z'])]
	terms = [t for t in terms if len(t)>=4]
	tf = Counter(terms)
	return dict(tf)

def weighted_choice(w_map):
	items = w_map.items()
	cum_weights = [0]*len(items)
	cum_weights[0] = items[0][1]
	for i,item in enumerate(items):
		if i==0: continue
		w = item[1]
		cum_weights[i] = cum_weights[i-1]+w
	total = cum_weights[-1]
	r = random() * total
	for i,c in enumerate(cum_weights):
		if r<c: return items[i][0]

#print(weighted_choice({11:.1,22:.1,33:.1}))

docs = list(map(get_tf,documents))
corpus = Counter()
for doc in docs:
	corpus.update(doc)
corpus = dict(corpus)

# TODO min_df

topics = list(range(1,K+1))

# initialize
t_of_w_in_d = {w:{} for w in corpus}
total_d_in_t = {d:{t:0 for t in topics} for d in range(len(docs))} # ~phi
total_w_in_t = {w:{t:0 for t in topics} for w in corpus} # ~theta
total_in_t = {t:0 for t in topics}
## pass # gamma

# randomly select new topic for word in document
i=0
for d,doc in enumerate(docs):
	for w in doc:
		t = randint(1,K) if RANDOMIZE else (i%K)+1
		t_of_w_in_d[w][d] = t
		total_in_t[t] += 1
		total_d_in_t[d][t] += 1
		total_w_in_t[w][t] += 1
		i += 1

if 0:
	pprint(total_d_in_t)
	pprint(total_w_in_t)
	pprint(total_in_t)
	#exit()

t0=time()
for _ in range(ITERATIONS):
	# select new topic for word in document
	for d,doc in enumerate(docs):
		for w in doc:

			# gdzie to powinno byc?
			t = t_of_w_in_d[w][d]
			total_in_t[t] -= 1
			total_d_in_t[d][t] -= 1
			total_w_in_t[w][t] -= 1
			old_t = t

			p_of_t = {}
			for t in topics:
				# ??? czu tu nie powinna powstac macierz kwadratowa?
				denom_a = len(doc) + K*alpha
				denom_b = total_in_t[t] + len(corpus)*eta
				p_of_word_in_t = 1.* (total_w_in_t[w][t] + eta)   / denom_b
				p_of_t_in_doc  = 1.* (total_d_in_t[d][t] + alpha) / denom_a
				p_of_t[t] = p_of_word_in_t * p_of_t_in_doc
				#print(d,w,t,p_of_word_in_t,p_of_t_in_doc)
			#print(p_of_t)

			t = weighted_choice(p_of_t)

			t_of_w_in_d[w][d] = t
			total_in_t[t] += 1
			total_d_in_t[d][t] += 1
			total_w_in_t[w][t] += 1

if 1:
	#pprint(total_d_in_t)
	pprint(total_w_in_t)
	pprint(total_in_t)

# theta - topics probabilities per document
p_d_in_t = {d:{} for d in range(len(docs))}
for d,doc in enumerate(docs):
	denom_a = 1.* len(doc) + K*alpha
	for t in topics:
		p_d_in_t[d][t] = 1.* (total_d_in_t[d][t] + alpha) / denom_a

#pprint(p_d_in_t)

# phi - topic probabilities per word
p_w_in_t = {w:{} for w in corpus} # phi
for w in corpus:
	for t in topics:
		denom_b = total_in_t[t] + len(corpus)*eta
		p_w_in_t[w][t] = 1.* (total_w_in_t[w][t] + eta) / denom_b
pprint(p_w_in_t)

print(time()-t0,'s',ITERATIONS/(time()-t0),'iter/s')

# topic best words
by_t = {t:{} for t in topics}
for w in p_w_in_t:
	for t in total_w_in_t[w]:
		p = p_w_in_t[w][t]
		by_t[t][w] = p
for t in by_t:
	total = sum(by_t[t].values())
	for w in by_t[t]:
		by_t[t][w] /= total
	pprint((t,nlargest(TOP_N,by_t[t].items(),key=lambda x:x[1])))
	#print(t,by_t[t])


"""
Builds an LSI model on the transformed data

"""

import pandas as pd
import gensim
from gensim import models
from gensim.models import LsiModel
from gensim.models.coherencemodel import CoherenceModel

from modules import transformer_tools as tt

if __name__ == "__main__":
    berichte = pd.read_csv("../out/Polizeiberichte_transformed.csv",
                           sep=";",
                           encoding="UTF-8")

    dataset = berichte["Hauptartikel_lem_clean_no_stop"].apply(lambda x: str(x).split(" "))
    dataset_head = berichte["Ueberschrift_lem_clean_no_stop"].apply(lambda x: str(x).split(" "))

    vocab = gensim.corpora.Dictionary(dataset)
    vocab_heads = gensim.corpora.Dictionary(dataset_head)

    bow_corpus = [vocab.doc2bow(doc) for doc in dataset]
    bow_corpus_heads = [vocab.doc2bow(doc) for doc in dataset_head]

    tfidf = models.TfidfModel(bow_corpus)
    tfidf_head = models.TfidfModel(bow_corpus_heads)

    corpus_tfidf = tfidf[bow_corpus]
    corpus_tfidf_head = tfidf[bow_corpus_heads]

    dataset = dataset.apply(tt.get_string_from_list)

    lsimodel = LsiModel(corpus=corpus_tfidf, num_topics=7, id2word=vocab)
    lsimodelUpdate = models.LsiModel(corpus_tfidf, id2word=vocab, num_topics=7)
    lsimodelUpdate.add_documents(corpus_tfidf_head, decay=0.5)  # now LSI has been trained on tfidf_corpus + another_tfidf_corpus

    lsitopics = [[word for word, prob in topic] for topicid, topic in lsimodel.show_topics(formatted=False)]
    lsitopics_update = [[word for word, prob in topic] for topicid, topic in lsimodelUpdate.show_topics(formatted=False)]

    print(lsitopics)
    print(lsitopics_update)

    #lsi_coherence = CoherenceModel(topics=lsitopics[:10], texts = berichte["Hauptartikel_lemmatized_cleaned_no_stopwords"], dictionary=vocab, window_size=10).get_coherence()
    #lsi_coherence_Update = CoherenceModel(topics=lsitopics_update[:10], texts = berichte["Hauptartikel_lemmatized_cleaned_no_stopwords"], dictionary=vocab, window_size=10).get_coherence()


# coding: utf-8

# In[2]:

import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder
import seaborn as sns

# In[3]:

irisdata = pd.read_excel('Iris.xls')
irisdata.head()

# In[5]:

#print(irisdata.describe())
cols = ['sepal length','sepal width','petal length','petal width','iris']
irisdata = irisdata[cols]
irisdata.head()

# In[4]:

get_ipython().run_line_magic('matplotlib', 'inline')

# In[6]:

le = LabelEncoder()
le.fit(irisdata['iris'].astype(str))
irisdata['iris']=le.transform(irisdata['iris'].astype(str))
irisdata.head()

# In[7]:

import matplotlib.pyplot as plt

jc = {'0':100,'1':170,'2':220}
g = irisdata['iris']
map(g,jc)
plt.scatter(irisdata['sepal length'],irisdata['sepal width'],c = g)
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.title('Plot')
plt.show()

# In[8]:

plt.subplot(221)
plt.hist(irisdata['iris'])
plt.subplot(222)
plt.hist(irisdata['petal length'])
plt.subplot(223)
plt.hist(irisdata['petal width'])
plt.subplot(224)
plt.hist(irisdata['sepal width'])
plt.show()

# In[11]:

sns.pairplot(irisdata,hue="iris",vars = cols[0:4])

# In[13]:

from sklearn.ensemble import RandomForestClassifier
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix

# In[61]:

x,x_t,y,y_t = train_test_split(irisdata[cols[0:4]],irisdata['iris'],test_size=0.2)

# In[62]:

#LinearSVC() it uses one versus the rest..
tr = svm.LinearSVC()
tr.fit(x,y)
h = tr.predict(x_t)

cfm = confusion_matrix(y_t,h)
print(tr.score(x_t,y_t))
print(cfm)

# In[63]:

#RandomForestClassifier()
tr = RandomForestClassifier(n_estimators = 100)
tr.fit(x,y)
h = tr.predict(x_t)

cfm = confusion_matrix(y_t,h)
print(tr.score(x_t,y_t))
print(cfm)

# In[65]:

#DecisionTreeClassifier()
from sklearn.tree import DecisionTreeClassifier

tr = DecisionTreeClassifier()
tr.fit(x,y)
h = tr.predict(x_t)

cfm = confusion_matrix(y_t,h)
print(tr.score(x_t,y_t))
print(cfm)

# In[69]:

#KNeighborsClassifier

from sklearn.neighbors import KNeighborsClassifier

tr = KNeighborsClassifier()
tr.fit(x,y)
h = tr.predict(x_t)

cfm = confusion_matrix(y_t,h)
print(tr.score(x_t,y_t))
print(cfm)


"""
Problem Link: https://leetcode.com/problems/isomorphic-strings/

Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character
while preserving the order of characters. No two characters may map
to the same character but a character may map to itself.

Example 1:
Input: s = "egg", t = "add"
Output: true

Example 2:
Input: s = "foo", t = "bar"
Output: false

Example 3:
Input: s = "paper", t = "title"
Output: true
Note:
You may assume both s and t have the same length.
"""
class Solution:
    def isIsomorphic(self, s: str, t: str) -> bool:
        d1 , d2 = [-1] * 128, [-1] * 128
        for i in range(len(s)):
          if d1[ord(s[i])] != d2[ord(t[i])]:
            return False
          d1[ord(s[i])] = i
          d2[ord(t[i])] = i
        return True

    def isIsomorphic1(self, s: str, t: str) -> bool:
        d1 , d2 = {}, {}
        for i in range(len(s)):
          if d1.get(ord(s[i]),-1) != d2.get(ord(t[i]),-1):
            return False
          d1[ord(s[i])] = i
          d2[ord(t[i])] = i
        return True


from Battleground import Battleground
from src.Actors.AbstractActor import AbstractActor

class BattleSimulation:
    def __init__(self,
                 actor: AbstractActor.__class__,
                 actor_health: int,
                 actor_deck: list,
                 monsters: list,
                 ascension: int):

        # Save information needed to create a bot
        self.actor = actor
        self.actor_health = actor_health
        self.actor_deck = actor_deck
        self.monsters = monsters
        self.ascension = ascension

    def simulate(self, quantity, verbose=False):
        # We're going to run this battle a few times
        for battle in range(quantity):
            print(f"Simulating battle {battle + 1}:")

            # Instantiate the actor (player/AI) and the enemies
            actor = self.actor(cards=self.actor_deck, max_health=self.actor_health)
            enemies = list(map(lambda enemy: enemy(ascension=self.ascension), self.monsters))

            # Create a battleground and insert actor and enemies into it
            bg = Battleground(actor=actor, enemies=enemies)
            print(bg.overview()) if verbose else None

            while not bg.battle_over():
                bg.next_round(verbose=verbose)


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform
from collections import OrderedDict

#根据反向近邻求噪声
def zaoSheng(n,k1,k_mindist,distMatrix):
    fknn = OrderedDict()
    zaoshenglist=[]
    lenzaosheng=0
    zaosheng = np.zeros(n, dtype=int)
    if k1!=0:
        for i in range(n):
            fknn[i] = []
        k = 0
        while k != -1:
            for j in range(n):
                fknn[k_mindist[j][k]].append(j)
            k = k + 1
            if k == k1:
                break
        lenfknn = np.zeros(n, dtype=int)
        for i in range(n):
            lenfknn[i] = len(fknn[i])
        juli = np.zeros(n, dtype=float)
        for i in range(n):
            for j in range(k1):
                juli[i] = juli[i] + distMatrix[i, k_mindist[i][j]]
        mean_juli = np.mean(juli)
        median_fknn=np.median(lenfknn)
        for i in range(n):
            if juli[i] > mean_juli and lenfknn[i]<median_fknn:
            # if lenfknn[i]<median_fknn:
                zaosheng[i]=1
                zaoshenglist.append(i)
                lenzaosheng = lenzaosheng + 1
    return zaosheng,lenzaosheng,zaoshenglist

def getRho(n,k1,k_mindist):
    fknn = OrderedDict()
    for i in range(n):
        fknn[i] = []
    k = 0
    while k != -1:
        for j in range(n):
            fknn[k_mindist[j][k]].append(j)
        k = k + 1
        if k == k1:
            break
    lenfknn = np.zeros(n, dtype=int)
    for i in range(n):
        lenfknn[i] = len(fknn[i])
    rho = np.zeros(n, dtype=float)
    for i in range(n):
        if len(fknn[i])==0:
            continue
        else:
            for j in range(len(fknn[i])):
                rho[i] = rho[i] + lenfknn[fknn[i][j]]
        rho[i]=lenfknn[i]
    return rho,fknn

#求每个点的最近距离k个点
def k_Mindist(n,distMatrix,k):
    k_mindist=np.zeros((n,k), dtype=int)
    for i in range(n):
        sortdist = np.argsort(distMatrix[i])
        if sortdist[0]!=i:
            for j in range(1,len(sortdist)):
                if sortdist[j]==i:
                    temp=sortdist[0]
                    sortdist[0]=i
                    sortdist[j]=temp
                    break
        k_mindist[i]=sortdist[1:k+1]
    return k_mindist

def hexindianshibie(n,k,k_mindist1,rho,distMatrix):
    sortrho = np.sort(rho)
    print(sortrho)
    maxrhoindex=np.zeros(n, dtype=int)
    median_rho = np.median(rho)
    print(median_rho)
    kdist = np.zeros(n, dtype=float)
    for i in range(0,n):
        for j in range(0,k):
            kdist[i]=kdist[i]+distMatrix[i,k_mindist1[i][j]]
    meankdist=np.mean(kdist)
    maxkdist=np.max(kdist)
    for i in range(0,n):
        maxrho=rho[i]
        maxrhoindex[i]=i
        if rho[i]<=median_rho and kdist[i]>(meankdist+(maxkdist-meankdist)/2):
            continue
        else:
            for j in range(0,k):
                if rho[k_mindist1[i][j]]>maxrho:
                    maxrho=rho[k_mindist1[i][j]]
                    maxrhoindex[i]=k_mindist1[i][j]
    return maxrhoindex

#删除重复核心点
def delete_repeat_hexindian(maxrhoindex):
    finalmaxrhoindex=np.unique(maxrhoindex)
    return finalmaxrhoindex

def prime(gaorho,distMatrix):
    gaorho=gaorho.tolist()
    n=len(gaorho)
    selected_nodes = []  # 存储选中节点的集合
    candidate_nodes = gaorho  # 备选的集合
    result_edges = []
    dist_edges=[]
    for i in range(n):
        if i == 0:  # 这里随机选择第一个顶点作为起始点，这个起始点
            selected_nodes.append(gaorho[i])
            candidate_nodes.remove(gaorho[i])
        else:
            candidate_cost = distMatrix[selected_nodes, :][:, candidate_nodes]
            idx = np.nonzero(candidate_cost == np.min(candidate_cost))  # 选出从选中节点的出度中最短的边
            #         print(candidate_cost)
            start_p = selected_nodes[idx[0][0]]
            end_p = candidate_nodes[idx[1][0]]
            #         print(start_p, end_p)
            selected_nodes.append(end_p)
            candidate_nodes.remove(end_p)
            result_edges.append([start_p, end_p])
            dist_edges.append(distMatrix[start_p, end_p])
    return selected_nodes,result_edges,dist_edges

def qiebian(dist_edges,result_edges,maxrhoindex,k_mindist1,k):
    dist_edges_sort = np.argsort(dist_edges)
    cut_edges = []
    # cut_edges.append(dist_edges_sort[len(dist_edges_sort) - 1])
    # cut_edges.append(dist_edges_sort[len(dist_edges_sort) - 2])
    for i in range(len(dist_edges_sort) - 1, 0, -1):
        dingdian_and_fushudian1 = []
        dingdian_and_fushudian2 = []
        dingdian_and_fushudian1.append(result_edges[dist_edges_sort[i]][0])
        dingdian_and_fushudian2.append(result_edges[dist_edges_sort[i]][1])
        for j in range(0,len(maxrhoindex)):
            if maxrhoindex[j] == result_edges[dist_edges_sort[i]][0]:
                dingdian_and_fushudian1.append(j)
            if maxrhoindex[j] == result_edges[dist_edges_sort[i]][1]:
                dingdian_and_fushudian2.append(j)
        biaoji=0
        for j in range(0,len(dingdian_and_fushudian1)):
            for h in range(0,len(dingdian_and_fushudian2)):
                if dingdian_and_fushudian1[j] in k_mindist1[dingdian_and_fushudian2[h]]:
                    if dingdian_and_fushudian2[h] in k_mindist1[dingdian_and_fushudian1[j]]:
                        biaoji=1
                        break
            if biaoji==1:
                break
        if biaoji==1:
            break
        if biaoji==0:
            cut_edges.append(dist_edges_sort[i])
    return cut_edges

#每个噪声点分配给离他最近的非噪声点所属的簇
def fenpeizaoshengdian(zaoshenglist,distMatrix,n,zaosheng):
    mindistzaosheng=np.zeros(n,dtype=int)
    for i in range(len(zaoshenglist)):
        mindist=np.max(distMatrix[zaoshenglist[i]])
        for j in range(2,n):
            if i==j:
                continue
            if zaosheng[j]==1:
                continue
            if distMatrix[zaoshenglist[i]][j]<mindist:
                mindist=distMatrix[zaoshenglist[i]][j]
                mindistzaosheng[zaoshenglist[i]]=j
    return mindistzaosheng

def selected_nodes_Cluster(selected_nodes,cut_edges,result_edges):
    selected_nodes_cluster = OrderedDict()  # 存储选中节点的集合字典
    selected_nodes_label = np.ones(len(selected_nodes), dtype=int)
    for i in range(len(cut_edges)):
        selected_nodes_label[selected_nodes.index(result_edges[cut_edges[i]][1])] = -1
    count = 1
    selected_nodes_cluster[count] = []
    for i in range(len(selected_nodes)):
        if selected_nodes_label[i] == -1:
            count = count + 1
            selected_nodes_cluster[count] = []
            selected_nodes_cluster[count].append(selected_nodes[i])
        else:
            selected_nodes_cluster[count].append(selected_nodes[i])
    return selected_nodes_cluster,count

if __name__ == '__main__':
    # data = np.array(pd.read_table(r'D:\project\数据集\Aggregation.txt', sep='\t', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\flame有噪声.txt', sep='\t', engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\Spiral.txt', sep='\t', engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\cth3.txt', sep='\t', engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\d6.txt', sep='\t', engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\ls3.txt', sep='\t', engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\Compound.txt', sep='\t', usecols=[0,1],engine='python', header=None))
    data = np.array(pd.read_table(r'D:\project\数据集\jain.txt', sep='\t', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\lineblobs.txt', sep='   ', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\threecircles.txt', sep='   ', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\Twomoons.txt', sep=' ', usecols=[1,2],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\Zigzag.txt', sep=' ', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\pathbased.txt', sep='\t', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\t4.txt', sep='\t', engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\t7.txt', sep='\t', engine='python', header=None))
    # data, y1 = datasets.make_circles(n_samples=2000, factor=0.6, noise=0.04,shuffle=True,random_state=44)
    # data, y2 = datasets.make_moons(n_samples=500, noise=0.1,shuffle=True,random_state=44)
    # data, y2 = datasets.make_blobs(n_samples=1000,n_features=2,cluster_std=0.8, centers=10,shuffle=True,random_state=44)
    # data = np.array(pd.read_table(r'D:\project\数据集\D31.txt', sep=',', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\grid.txt', sep=' ', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\worms_2d.txt', sep=' ', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\2d-20c-no0.txt', sep=',', usecols=[0,1],engine='python', header=None))
    # data = np.array(pd.read_table(r'D:\project\数据集\heartshaped.txt', sep=',', usecols=[0,1],engine='python', header=None))

    x = data[:, 0]
    y = data[:, 1]
    plt.scatter(x,y,s=0.002,c='black')
    plt.scatter(x,y,c='deepskyblue',s=50,marker='o',edgecolors='black')
    plt.xticks([])
    plt.yticks([])
    # plt.savefig('D:\project\论文需要的图\英文论文算法步骤图\英文论文算法步骤图1.png')
    plt.show()
    n = x.shape[0]
    distList = pdist(data, metric='euclidean')
    distMatrix = squareform(distList)
    k1=0
    k2=7
    k_mindist = k_Mindist(n, distMatrix, k1)
    zaosheng, lenzaosheng, zaoshenglist = zaoSheng(n, k1, k_mindist, distMatrix)
    mindistzaosheng = fenpeizaoshengdian(zaoshenglist, distMatrix, n,zaosheng)
    #
    data1 = []
    data1todata = np.zeros(n - lenzaosheng, dtype=int)
    count = -1
    for i in range(n):
        if zaosheng[i]==1:
            plt.scatter(data[i,0],data[i,1],c='black',s=50,marker='s')
            continue
        else:
            data1.append(data[i])
            count = count + 1
            data1todata[count] = i
            plt.scatter(data[i,0],data[i,1],c='deepskyblue',s=50,marker='o',edgecolors='black')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图\英文论文算法步骤图2.png')
    plt.show()
    distList = pdist(data1, metric='euclidean')
    distMatrix = squareform(distList)
    data1 = np.array(data1)

    xx = data1[:, 0]
    yy = data1[:, 1]
    plt.scatter(xx, yy,c='deepskyblue',s=50,marker='o',edgecolors='black')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图\英文论文算法步骤图3.png')
    plt.show()
    n = xx.shape[0]
    k_mindist1 = k_Mindist(n, distMatrix, k2)
    rho, fknn = getRho(n, k2, k_mindist1)
    maxrhoindex =hexindianshibie(n, k2, k_mindist1, rho,distMatrix)
    finalmaxrhoindex = delete_repeat_hexindian(maxrhoindex)
    print('数量', len(maxrhoindex), len(finalmaxrhoindex))
    for i in range(n):
        if i in finalmaxrhoindex:
            plt.scatter(data1[i,0],data1[i,1],marker='*',c='red',s=30)
        else:
            plt.scatter(data1[i,0],data1[i,1],c='skyblue',s=30,marker='o')
    for i in range(n):
        start = data1[i]
        end = data1[maxrhoindex[i]]
        plt.arrow(start[0], start[1], end[0]-start[0], end[1]-start[1],head_width=0.3, lw=0.2, facecolor="black", length_includes_head=True,fill=False)  # ⻓度计算包含箭头箭尾
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图2\代表点指向图1.png')
    plt.show()
    for i in range(n):
        if i in finalmaxrhoindex:
            plt.scatter(data1[i,0],data1[i,1],marker='*',c='red',s=30)
        else:
            plt.scatter(data1[i,0],data1[i,1],c='skyblue',s=30,marker='o')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图2\代表点无指向图1.png')
    plt.show()
    print("构建最小生成树点的数量", len(finalmaxrhoindex))
    print("开始记录时间")

    selected_nodes, result_edges, dist_edges = prime(finalmaxrhoindex, distMatrix)

    for i in range(len(selected_nodes)):
        plt.scatter(data1[selected_nodes[i], 0], data1[selected_nodes[i], 1], marker='*',c='red',s=50)
    for i in range(len(result_edges)):
        plt.plot([data1[result_edges[i][0], 0], data1[result_edges[i][1], 0]],
                 [data1[result_edges[i][0], 1], data1[result_edges[i][1], 1]], color='b')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图2\英文论文算法步骤图5.png')
    plt.show()

    cut_edges = qiebian(dist_edges, result_edges, maxrhoindex, k_mindist1, k2)
    print('聚类簇数', len(cut_edges) + 1)

    for i in range(len(selected_nodes)):
        plt.scatter(data1[selected_nodes[i], 0], data1[selected_nodes[i], 1], marker='*',c='red',s=30)
    for i in range(len(result_edges)):
        if i not in cut_edges:
            plt.plot([data1[result_edges[i][0], 0], data1[result_edges[i][1], 0]],
                     [data1[result_edges[i][0], 1], data1[result_edges[i][1], 1]], color='b')
        if i in cut_edges:
            plt.plot([data1[result_edges[i][0], 0], data1[result_edges[i][1], 0]],
                     [data1[result_edges[i][0], 1], data1[result_edges[i][1], 1]], color='darkorange')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图2\英文论文算法步骤图6.png')
    plt.show()

    selected_nodes_cluster,count=selected_nodes_Cluster(selected_nodes,cut_edges,result_edges)
    for k, v in selected_nodes_cluster.items():
        E = data1[v]
        plt.scatter(E[:, 0], E[:, 1],s=50,marker='o',edgecolors='black')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图\英文论文算法步骤图7.png')
    plt.show()

    b=[]
    for i in range(n):
        b.append(i)
    dirho=list(set(b).difference(set(finalmaxrhoindex)))  # b中有⽽a中没有的

    for i in range(len(dirho)):
        for j in range(len(selected_nodes_cluster)):
            if maxrhoindex[dirho[i]] in selected_nodes_cluster[j+1]:
                selected_nodes_cluster[j+1].append(dirho[i])
                break

    for k, v in selected_nodes_cluster.items():
        E = data1[v]
        plt.scatter(E[:, 0], E[:, 1],s=50,marker='o',edgecolors='black')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图\英文论文算法步骤图8.png')
    plt.show()

    aset=[]
    for i in range(count):
        aset.append(i+1)
    cluster_data = (-1) * np.ones(x.shape[0], dtype=int)
    for i in range(len(aset)):
        for j in range(len(selected_nodes_cluster[aset[i]])):
            cluster_data[data1todata[selected_nodes_cluster[aset[i]][j]]] = data1todata[aset[i]]
    for i in range(x.shape[0]):
        if cluster_data[i] == -1:
            cluster_data[i] = cluster_data[mindistzaosheng[i]]
    clusterSetFinally = OrderedDict()
    for i in range(len(aset)):
        clusterSetFinally[aset[i]] = []
    for i in range(x.shape[0]):
        for j in range(len(aset)):
            if cluster_data[i] == data1todata[aset[j]]:
                clusterSetFinally[aset[j]].append(i)
                break
    print(clusterSetFinally)

    for k, v in clusterSetFinally.items():
        E = data[v]
        plt.scatter(E[:, 0], E[:, 1],s=50,marker='o',edgecolors='black')
    plt.xticks([])
    plt.yticks([])
    plt.savefig('D:\project\论文需要的图\英文论文算法步骤图\英文论文算法步骤图9.png')
    plt.show()


# Add the root path of the dmrgpy library
import os ; import sys ; sys.path.append(os.getcwd()+'/../../../src')

import numpy as np
from dmrgpy import spinchain
n = 6
spins = ["S=1/2" for i in range(n)] # spin 1/2 heisenberg chain
sc = spinchain.Spin_Chain(spins) # create the spin chain
h = 0 # generate a Heisenberg Hamiltonian
for i in range(n-1):
    h = h +sc.Sx[i]*sc.Sx[i+1]
    h = h +sc.Sy[i]*sc.Sy[i+1]
    h = h +sc.Sz[i]*sc.Sz[i+1]

h = h*h + 1j

print("Trace ED",sc.trace(h,mode="ED"))
print("Trace MPS",sc.trace(h,mode="DMRG"))

print("Inverse trace ED",sc.inverse_trace(h,mode="ED"))
print("Inverse trace MPS",sc.inverse_trace(h,mode="DMRG"))


from sqlalchemy import (
    Column, String, Integer, BigInteger, Date, Boolean,\
    FLOAT, Text, SmallInteger, ForeignKey, UniqueConstraint
)
from sqlalchemy.dialects.postgresql import UUID, JSONB

from application.database import db
from application.database.model import CommonModel

class Salesorder(CommonModel):
    __tablename__ = 'salesorder'
    salesorder_exid = db.Column(String(100), index=True, unique=True) #id tich hop tu he thong khac
    salesorder_no = db.Column(String(100))
    title = db.Column(String(255))

    book_time = db.Column(BigInteger)
    book_day = db.Column(SmallInteger())
    book_month = db.Column(SmallInteger())
    book_year = db.Column(SmallInteger())
    book_hour = db.Column(SmallInteger())
    book_minute = db.Column(SmallInteger())
    book_day_of_week = db.Column(SmallInteger())

    time_perform = db.Column(String(50))

    contact_id = db.Column(UUID(as_uuid=True), ForeignKey('contact.id'), nullable=True)
    contact = db.relationship("Contact")
    room_id = db.Column(UUID(as_uuid=True), ForeignKey("room.id", onupdate="CASCADE", ondelete="RESTRICT"), nullable=False)
    room = db.relationship("Room")
    device_id = db.Column(String(), nullable = False)
    # contact_name = db.Column(String(255))
    # contact_phone = db.Column(String(50))
    # contact_email = db.Column(String(100))
    # contact_address = db.Column(Text())

    # workstation_id = db.Column(UUID(as_uuid=True), ForeignKey('workstation.id'), nullable=True)
    # workstation_name = db.Column(String(255))
    people_number = db.Column(Integer)
    hour_schedule = db.Column(String())
    unwant_order = db.Column(Boolean(), default = False)

    price_adjustment = db.Column(FLOAT(15,8), default=0)  #https://en.wikipedia.org/wiki/Price_adjustment_(retail)
    salescommission = db.Column(FLOAT(15,8), default=0) # hoa hong cho nhan vien ban hang
    exciseduty = db.Column(FLOAT(15,8), default=0) # thu tieu thu dac biet, danh cho hang hoa xa xi.

    taxtype = db.Column(String(25), default="group") #group: thue tren toan bill - individual: thue tren tung item
    tax_percent = db.Column(FLOAT(7,3), default=0)
    tax_amount = db.Column(FLOAT(15,8), default=0)

    net_amount = db.Column(FLOAT(15,8), default=0)
    amount = db.Column(FLOAT(15,8), default=0)
    discount_amount = db.Column(FLOAT(15,8), default=0) # tiền giảm tự túc tại cửa hàng hoặc chỉnh sửa
    discount_percent = db.Column(FLOAT(7,3), default=0)
    voucher_discount_amount = db.Column(FLOAT(15,8), default=0) # tiền giảm theo chương trình KM

    card_swipe_fee_amount = db.Column(FLOAT(15,8), default=0) # Phí quẹt thẻ
    card_swipe_fee_percent = db.Column(FLOAT(7,3), default=0)

    other_fee_percent = db.Column(FLOAT(7,3), default=0) # Phí khác
    other_fee_amount = db.Column(FLOAT(15,8), default=0)

    ship_fee_amount = db.Column(FLOAT(15,8), default=0)
    ship_partner = db.Column(String(200))

    terms_conditions = db.Column(Text())
    purchaseorder = db.Column(String(200))
    sostatus = db.Column(String(200), default = "wait_confirm") # wait_confirm, confirmed, transporting, processing, finished # saleorder_status

    currency_id = db.Column(UUID(as_uuid=True), ForeignKey('currency.id'), nullable=True)
    currency_code = db.Column(String(11), nullable=True)
    currency = db.relationship("Currency")
    conversion_rate = db.Column(FLOAT(10,3)) # ty gia currency

    payment_method = db.Column(String(50))
    payment_status = db.Column(String(20))
    note = db.Column(Text())
    is_delivery = db.Column(Boolean(), default=False)
    delivery_address = db.Column(String(255))

    provider_id = db.Column(UUID(as_uuid=True), ForeignKey("provider.id", onupdate="RESTRICT", ondelete="RESTRICT"), nullable=True)
    provider = db.relationship("Provider")

    service_id = db.Column(UUID(as_uuid=True), ForeignKey("service.id", onupdate="RESTRICT", ondelete="RESTRICT"), nullable=False)
    service = db.relationship("Service")

    salesorder_items = db.relationship("SalesorderItems", order_by="SalesorderItems.created_at", cascade="all, delete-orphan", lazy='dynamic')
    tenant_id = db.Column(String(), ForeignKey("tenant.id", onupdate="RESTRICT", ondelete="RESTRICT"), nullable=False)

class SalesorderItems(CommonModel):
    __tablename__ = 'salesorder_items'
    salesorder_id = db.Column(UUID(as_uuid=True), ForeignKey('salesorder.id'), nullable=False)
    item_id = db.Column(UUID(as_uuid=True), ForeignKey('item.id', ondelete="CASCADE"), nullable=False, index =True)
    item = db.relationship("Item", foreign_keys=[item_id])
    item_type = db.Column(String(40), default="default")
    item_no = db.Column(String(40))
    item_name = db.Column(String(150))
    parent_item_id = db.Column(UUID(as_uuid=True), ForeignKey('item.id', ondelete="CASCADE"), nullable=True, index =True)
    parent_item = db.relationship("Item", foreign_keys=[parent_item_id])
    quantity = db.Column(FLOAT(15,3), default=1)
    current_price = db.Column(FLOAT(27,8), default=0)  #selling price, unit price, don gia
    discount_percent = db.Column(FLOAT(7,3), default=0)
    discount_amount = db.Column(FLOAT(27,8), default=0)
    voucher_discount_amount = db.Column(FLOAT(27,8), default=0)
    amount = db.Column(FLOAT(27,8), default=0)  # thanh tien sau khi tru discount
    net_amount = db.Column(FLOAT(27,8), default=0)  #thanh tien truoc khi tru discount
    description = db.Column(Text())
    tax_percent = db.Column(FLOAT(7,3), default=0)
    tax_amount = db.Column(FLOAT(15,8), default=0)
    purchase_cost = db.Column(FLOAT(27,8), default=0) # giá mua giả phẩm từ đại lý
    tenant_id = db.Column(String(), ForeignKey("tenant.id", onupdate="RESTRICT", ondelete="RESTRICT"), nullable=False)

class SalesorderLog(CommonModel):
    __tablename__ = 'saleorder_log'
    salesorder_id = db.Column(UUID(as_uuid=True), ForeignKey('salesorder.id', ondelete="CASCADE"), nullable=False)
    status = db.Column(String(20), default = "done")
    sostatus = db.Column(String(200)) # wait_confirm, confirmed, transporting, processing, finished # saleorder_status
    tenant_id = db.Column(String(), ForeignKey("tenant.id", onupdate="RESTRICT", ondelete="RESTRICT"), nullable=False)


from rest_framework.generics import RetrieveAPIView, ListAPIView
from rest_framework.response import Response
from rest_framework.views import APIView

from django.http import HttpResponse
from django.shortcuts import render
from django.db import transaction
from django.urls import reverse
from django.views import View

from .serializers import *
from .models import Hall, Booking, BookingDetails
from .services import calculate_cost, calculate_delta, get_hall_by_name
from .utils.exceptions import InvalidDateFormat, BookingDataMissingError, BookingNotFound

import hashlib
from datetime import datetime
from dateutil.parser import parse

URL = 'http://127.0.0.1:8000'

class HallDetailView(RetrieveAPIView):
    queryset = Hall.objects.all()
    serializer_class = HallDetailSerializer
    lookup_field = 'name'

class HallPriceView(RetrieveAPIView):
    queryset = Hall.objects.all()
    serializer_class = HallPriceSerializer
    lookup_field = 'name'

class HallDataView(ListAPIView):
    queryset = Hall.objects.all()

    def get_serializer_class(self):
        data = self.request.GET.get('data')
        if data == 'price':
            return HallPriceSerializer
        elif data == 'description':
            return HallDescriptionSerializer
        elif data == 'rule':
            return HallRulesSerializer
        elif data == 'time':
            return HallTimeSerializer
        elif data == 'name':
            return HallNameSerializer
        else:
            raise ValueError('''
                Тип данных', data, 'ты не можешь получить, вот список доступных типов данных:
                price, description, rule, time, name'''
            )

class CheckBookingsByDayView(APIView):
    def get(self, request, hall_name, date):
        hall = get_hall_by_name(hall_name)

        hall_opening_time = hall.opening_time
        hall_closing_time = hall.closing_time

        try:
            date_obj = datetime.strptime(date, '%d.%m.%Y').date()
        except ValueError:
            raise InvalidDateFormat()

        bookings = Booking.objects.filter(hall=hall, date=date_obj).values('date', 'start_time', 'end_time')
        if bookings.count() == 0:
            raise BookingNotFound()

        bookings_dict = {
            'hall_data': {
                'opening_time': hall_opening_time.strftime('%H'),
                'closing_time': hall_closing_time.strftime('%H')
            },
            'already_booked_time_ranges_by_hours': [{
                'start': b['start_time'].replace(hour=b['start_time'].hour - 1, minute=59).strftime('%H'),
                'end': b['end_time'].replace(hour=b['start_time'].hour - 1, minute=59).strftime('%H')
            } for b in bookings]
        }
        print(bookings_dict)
        return Response(bookings_dict)

class HashBookingView(APIView):
    @transaction.atomic()
    def post(self, request):
        data = request.data
        print('123')
        required_fields = ['hall_name', 'date', 'start_time', 'end_time', 'client_name', 'client_email', 'client_phone', 'num_people']
        missing_fields = [field for field in required_fields if not data.get(field)]
        if missing_fields:
            raise BookingDataMissingError(missing_fields)

        hall_name = data['hall_name']
        client_name = data['client_name']
        client_email = data['client_email']
        client_phone = data['client_phone']
        num_people = data['num_people']

        date = parse(data['date']).date()
        start_time = parse(data['start_time']).time()
        end_time = parse(data['end_time']).time()

        hall = get_hall_by_name(hall_name)
        cost = calculate_cost(
            hall,
            calculate_delta(start_time, end_time)
        )

        details = BookingDetails.objects.create(
            client_name=client_name,
            client_email=client_email,
            client_phone=client_phone,
            num_people=num_people,
            cost=cost
        )

        booking = Booking(
            hall=hall,
            date=date,
            start_time=start_time,
            end_time=end_time,
            details=details,
            is_paid=False,
        )

        hash_object = hashlib.sha256(str(booking).encode('utf-8'))
        hash_key = hash_object.hexdigest()

        booking.hash_key = hash_key

        booking.save()

        return Response(
            {'link': URL + reverse('checkout', args=[hash_key])}
        )

class CheckoutView(View):
    template_name = 'checkout.html'

    def get(self, request, hash_key):
        try:
            booking = Booking.objects.get(hash_key=hash_key)
        except Booking.DoesNotExist:
            return HttpResponse('Хэш ключ не валиден.')

        if booking.details is not None:
            details = booking.details

        context = {
            'booking': booking,
            'details': details,
            'date': booking.date.strftime('%d.%m.%Y'),
            'start_time': booking.start_time.strftime('%H:%M'),
            'end_time': booking.end_time.strftime('%H:%M'),
        }
        return render(request, self.template_name, context)