import os
import unittest
import re
from unittest import mock
import tempfile
with mock.patch('cffi.FFI.dlopen', return_value=mock.MagicMock()):
    from geopmdpy.system_files import ActiveSessions, AccessLists, WriteLock

# Patch dlopen to allow the tests to run when there is no build
with mock.patch('cffi.FFI.dlopen', return_value=mock.MagicMock()):
    from geopmdpy.service import PlatformService
    from geopmdpy.service import TopoService

class TestPlatformService(unittest.TestCase):
    def setUp(self):
        self._test_name = 'TestPlatformService'
        self._RUN_PATH = tempfile.TemporaryDirectory('{}_run'.format(self._test_name))

        self._mock_active_sessions = mock.create_autospec(ActiveSessions)
        self._mock_active_sessions.get_clients.return_value = []
        self._check_client_active_err_msg = "Injected error"
        self._mock_active_sessions.check_client_active.side_effect = \
            RuntimeError(self._check_client_active_err_msg) # Until open_mock_session is called

        self._mock_access_lists = mock.create_autospec(AccessLists)
        self._mock_write_lock = mock.create_autospec(WriteLock)
        self._mock_write_lock.try_lock.return_value = None
        self._mock_write_lock.unlock.return_value = None

        with mock.patch('geopmdpy.system_files.ActiveSessions', return_value=self._mock_active_sessions), \
             mock.patch('geopmdpy.system_files.AccessLists', return_value=self._mock_access_lists), \
             mock.patch('geopmdpy.system_files.WriteLock', return_value=self._mock_write_lock):
            self._platform_service = PlatformService()

        self._platform_service._RUN_PATH = self._RUN_PATH.name
        self._platform_service._active_sessions._RUN_PATH = self._RUN_PATH.name
        self._session_file_format = os.path.join(self._RUN_PATH.name, 'session-{client_pid}.json')

    def tearDown(self):
        self._RUN_PATH.cleanup()

    def test_close_already_closed(self):
        # We already have two independent components with the session.
        client_pid = -999
        self.open_mock_session('user_name', client_pid, True, 2)  # 2
        self._platform_service.close_session(client_pid)              # 1
        self._platform_service.close_session(client_pid)              # 0
        self._platform_service._active_sessions.check_client_active = mock.MagicMock(side_effect=RuntimeError)
        with self.assertRaises(RuntimeError):
            self._platform_service.close_session(client_pid) # error here

    def test_read_already_closed(self):
        # We already have two independent components with the session.
        client_pid = -999
        self.open_mock_session('user_name', client_pid, True, 2)  # 2
        self._platform_service.close_session(client_pid)              # 1
        self._platform_service.close_session(client_pid)              # 0
        self._platform_service._active_sessions.check_client_active = mock.MagicMock(side_effect=RuntimeError)
        with self.assertRaises(RuntimeError):
            self._platform_service.read_signal(client_pid, 'CPU_FREQUENCY', 0, 0) # error here

    def test_get_signal_info(self):
        signals = ['energy', 'frequency', 'power']
        descriptions = ['desc0', 'desc1', 'desc2']
        domains = [0, 1, 2]
        infos = [(0, 0, 0), (1, 1, 1), (2, 2, 2)]

        expected_result = list(zip(signals, descriptions, domains))
        for idx in range(len(expected_result)):
            expected_result[idx] = expected_result[idx] + infos[idx]

        with mock.patch('geopmdpy.pio.signal_description', side_effect=descriptions) as mock_desc, \
             mock.patch('geopmdpy.pio.signal_domain_type', side_effect=domains) as mock_dom, \
             mock.patch('geopmdpy.pio.signal_info', side_effect=infos) as mock_inf:

            signal_info = self._platform_service.get_signal_info(signals)
            self.assertEqual(expected_result, signal_info)

            calls = [mock.call(cc) for cc in signals]
            mock_desc.assert_has_calls(calls)
            mock_dom.assert_has_calls(calls)
            mock_inf.assert_has_calls(calls)

    def test_get_control_info(self):
        controls = ['fan', 'frequency', 'power']
        descriptions = ['desc0', 'desc1', 'desc2']
        domains = [0, 1, 2]
        expected_result = list(zip(controls, descriptions, domains))

        with mock.patch('geopmdpy.pio.control_description', side_effect=descriptions) as mock_desc, \
             mock.patch('geopmdpy.pio.control_domain_type', side_effect=domains) as mock_dom:

            control_info = self._platform_service.get_control_info(controls)
            self.assertEqual(expected_result, control_info)

            calls = [mock.call(cc) for cc in controls]
            mock_desc.assert_has_calls(calls)
            mock_dom.assert_has_calls(calls)

    def test_lock_control(self):
        err_msg = 'PlatformService: Implementation incomplete'
        with self.assertRaisesRegex(NotImplementedError, err_msg):
            self._platform_service.lock_control()

    def test_unlock_control(self):
        err_msg = 'PlatformService: Implementation incomplete'
        with self.assertRaisesRegex(NotImplementedError, err_msg):
            self._platform_service.unlock_control()

    def test_open_session_twice(self):
        self.open_mock_session('', active=True)

    def _gen_session_data_helper(self, client_pid, reference_count):
        signals_default = ['energy', 'frequency']
        controls_default = ['controls', 'geopm', 'named', 'power']

        watch_id = 888
        session_data = {'client_pid': client_pid,
                        'reference_count': reference_count,
                        'mode': 'r',
                        'signals': signals_default,
                        'controls': controls_default,
                        'watch_id': watch_id}
        return session_data

    def open_mock_session(self, session_user, client_pid=-999, active=False, reference_count=1):

        session_data = self._gen_session_data_helper(client_pid, reference_count)
        client_pid = session_data['client_pid']
        reference_count = session_data['reference_count']
        watch_id = session_data['watch_id']
        signals = session_data['signals']
        controls = session_data['controls']

        self._mock_active_sessions.is_client_active.return_value = active
        self._mock_active_sessions.get_controls.return_value = controls
        self._mock_active_sessions.get_signals.return_value = signals
        self._mock_active_sessions.get_reference_count.return_value = reference_count
        self._mock_active_sessions.get_watch_id.return_value = watch_id
        self._mock_active_sessions.get_batch_server.return_value = None
        self._mock_active_sessions.remove_client.return_value = session_data

        self._mock_access_lists.get_user_access.return_value = (signals, controls)

        with mock.patch('geopmdpy.system_files.AccessLists._get_user_groups', return_value=[]), \
             mock.patch('geopmdpy.service.PlatformService._watch_client', return_value=watch_id):

            self._platform_service.open_session(session_user, client_pid)

            self._mock_active_sessions.is_client_active.assert_called_with(client_pid)
            if not active:
                self._mock_active_sessions.add_client.assert_called_with(client_pid, signals, controls, watch_id)
                self._mock_access_lists.get_user_access.assert_called()
            else:
                self._mock_active_sessions.add_client.assert_not_called()

        self._mock_active_sessions.check_client_active.side_effect = None # session is now active

        return session_data

    def test_open_session(self):
        self.open_mock_session('')

    def test_close_session_invalid(self):
        client_pid = 999
        with self.assertRaisesRegex(RuntimeError, self._check_client_active_err_msg):
            self._platform_service.close_session(client_pid)

    def test_close_session_read(self):
        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']
        watch_id = session_data['watch_id']

        with mock.patch('gi.repository.GLib.source_remove', return_value=[]) as mock_source_remove, \
             mock.patch('geopmdpy.pio.restore_control_dir') as mock_restore_control_dir, \
             mock.patch('shutil.rmtree', return_value=[]) as mock_rmtree:

            self._platform_service.close_session(client_pid)
            mock_restore_control_dir.assert_not_called()
            mock_rmtree.assert_not_called()
            mock_source_remove.assert_called_once_with(watch_id)
            self._mock_active_sessions.remove_client.assert_called_once_with(client_pid)

    def test_close_session_write(self):
        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']
        watch_id = session_data['watch_id']
        self._mock_write_lock.try_lock.return_value = client_pid
        with mock.patch('geopmdpy.pio.save_control_dir') as mock_save_control_dir, \
             mock.patch('geopmdpy.pio.write_control') as mock_write_control, \
             mock.patch('os.getsid', return_value=client_pid) as mock_getsid:
            self._platform_service.write_control(client_pid, 'geopm', 'board', 0, 42.024)
            mock_save_control_dir.assert_called_once()
            mock_write_control.assert_called_once_with('geopm', 'board', 0, 42.024)

        with mock.patch('gi.repository.GLib.source_remove', return_value=[]) as mock_source_remove, \
             mock.patch('geopmdpy.pio.restore_control_dir', return_value=[]) as mock_restore_control_dir, \
             mock.patch('os.getsid', return_value=client_pid) as mock_getsid:
            self._platform_service.close_session(client_pid)
            mock_restore_control_dir.assert_called_once()
            save_dir = os.path.join(self._platform_service._RUN_PATH,
                                    self._platform_service._SAVE_DIR)
            mock_source_remove.assert_called_once_with(watch_id)
            self.assertFalse(self._platform_service._active_sessions.is_client_active(client_pid))
            session_file = self._session_file_format.format(client_pid=client_pid)
            self.assertFalse(os.path.exists(session_file))

    def test_start_batch_invalid(self):
        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']
        watch_id = session_data['watch_id']

        valid_signals = session_data['signals']
        signal_config = [(0, 0, sig) for sig in valid_signals]

        valid_controls = session_data['controls']
        bogus_controls = [(0, 0, 'invalid_frequency'), (0, 0, 'invalid_energy')]
        control_config = [(0, 0, con) for con in valid_controls]
        control_config.extend(bogus_controls)

        err_msg = re.escape('Requested controls that are not in allowed list: {}' \
                            .format(sorted({bc[2] for bc in bogus_controls})))

        with self.assertRaisesRegex(RuntimeError, err_msg):
            self._platform_service.start_batch(client_pid, signal_config,
                                               control_config)

        bogus_signals = [(0, 0, 'invalid_uncore'), (0, 0, 'invalid_power')]
        signal_config.extend(bogus_signals)

        err_msg = re.escape('Requested signals that are not in allowed list: {}' \
                            .format(sorted({bs[2] for bs in bogus_signals})))
        with self.assertRaisesRegex(RuntimeError, err_msg):
            self._platform_service.start_batch(client_pid, signal_config,
                                               control_config)

    def test_start_batch_write_blocked(self):
        """Write mode batch server will not start when write lock is held

        This test calls write_control without a session leader, and then a
        different PID tries to create a write mode batch server with a session
        leader.  This request should fail.

        """
        client_pid = 999
        client_sid = 333
        other_pid = 666
        control_name = 'geopm'
        domain = 7
        domain_idx = 42
        setting = 777
        session_data = self.open_mock_session('other', other_pid)

        mock_pwuid = mock.MagicMock()
        self._mock_write_lock.try_lock.return_value = other_pid
        with mock.patch('geopmdpy.pio.write_control', return_value=[]) as mock_write_control, \
             mock.patch('geopmdpy.pio.save_control_dir'), \
             mock.patch('os.getsid', return_value=other_pid) as mock_getsid:
            self._platform_service.write_control(other_pid, control_name, domain, domain_idx, setting)
            mock_write_control.assert_called_once_with(control_name, domain, domain_idx, setting)

        session_data = self.open_mock_session('', client_pid)
        valid_signals = session_data['signals']
        valid_controls = session_data['controls']
        signal_config = [(0, 0, sig) for sig in valid_signals]
        control_config = [(0, 0, con) for con in valid_controls]
        mock_pwuid.pw_name = 'test_user'
        err_msg = f'The PID {client_pid} requested write access, but the geopm service already has write mode client with PID or SID of {abs(other_pid)}'

        with self.assertRaisesRegex(RuntimeError, err_msg), \
             mock.patch('geopmdpy.pio.start_batch_server', return_value = (2345, "2345")), \
             mock.patch('os.getsid', return_value=client_sid) as mock_getsid, \
             mock.patch('pwd.getpwuid', return_value=mock_pwuid) as mock_getpwuid, \
             mock.patch('psutil.pid_exists', return_value=True) as mock_pid_exists:
            self._platform_service.start_batch(client_pid, signal_config,
                                               control_config)

    def test_start_batch(self):
        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']
        watch_id = session_data['watch_id']

        valid_signals = session_data['signals']
        valid_controls = session_data['controls']
        signal_config = [(0, 0, sig) for sig in valid_signals]
        control_config = [(0, 0, con) for con in valid_controls]

        expected_result = (1234, "1234")

        self._mock_write_lock.try_lock.return_value = client_pid
        with mock.patch('geopmdpy.pio.start_batch_server', return_value=expected_result), \
             mock.patch('geopmdpy.pio.save_control_dir'), \
             mock.patch('os.getsid', return_value=client_pid) as mock_getsid:
            actual_result = self._platform_service.start_batch(client_pid, signal_config,
                                                               control_config)
        self.assertEqual(expected_result, actual_result,
                         msg='start_batch() did not pass back correct result')

        save_dir = os.path.join(self._platform_service._RUN_PATH,
                                self._platform_service._SAVE_DIR)
        self.assertTrue(os.path.isdir(save_dir),
                        msg = 'Directory does not exist: {}'.format(save_dir))

        self._mock_active_sessions.get_batch_server.return_value = expected_result[0]
        with mock.patch('geopmdpy.pio.stop_batch_server', return_value=[]) as mock_stop_batch_server, \
             mock.patch('psutil.pid_exists', return_value=True) as mock_pid_exists:
            self._platform_service.stop_batch(client_pid, expected_result[0])
            mock_stop_batch_server.assert_called_once_with(expected_result[0])

    def test_stop_batch_invalid(self):
        with self.assertRaisesRegex(RuntimeError, self._check_client_active_err_msg):
            self._platform_service.stop_batch('', '')

    def test_read_signal_invalid(self):
        with self.assertRaisesRegex(RuntimeError, self._check_client_active_err_msg):
            self._platform_service.read_signal('', '', '', '')

        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']

        signal_name = 'geopm'
        err_msg = 'Requested signal that is not in allowed list: {}'.format(signal_name)
        with self.assertRaisesRegex(RuntimeError, err_msg):
            self._platform_service.read_signal(client_pid, signal_name, '', '')

    def test_read_signal(self):
        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']

        signal_name = 'energy'
        domain = 7
        domain_idx = 42
        with mock.patch('geopmdpy.pio.read_signal', return_value=[]) as rs:
            self._platform_service.read_signal(client_pid, signal_name, domain, domain_idx)
            rs.assert_called_once_with(signal_name, domain, domain_idx)

    def test_write_control_invalid(self):
        with self.assertRaisesRegex(RuntimeError, self._check_client_active_err_msg):
            self._platform_service.write_control('', '', '', '', '')

        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']

        control_name = 'energy'
        err_msg = 'Requested control that is not in allowed list: {}'.format(control_name)
        with self.assertRaisesRegex(RuntimeError, err_msg):
            self._platform_service.write_control(client_pid, control_name, '', '', '')

    def test_write_control(self):
        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']

        self._mock_write_lock.try_lock.return_value = client_pid
        control_name = 'geopm'
        domain = 7
        domain_idx = 42
        setting = 777
        with mock.patch('geopmdpy.pio.write_control', return_value=[]) as mock_write_control, \
             mock.patch('geopmdpy.pio.save_control_dir'), \
             mock.patch('os.getsid', return_value=client_pid) as mock_getsid:
            self._platform_service.write_control(client_pid, control_name, domain, domain_idx, setting)
            mock_write_control.assert_called_once_with(control_name, domain, domain_idx, setting)

    def test_restore_already_closed(self):
        client_pid = -999
        session_data = self.open_mock_session('user_name', client_pid, True, 2)  # 2
        self._platform_service.close_session(client_pid)  # 1
        self._platform_service.close_session(client_pid)  # 0
        self._platform_service._active_sessions.check_client_active = mock.MagicMock(side_effect=RuntimeError)
        with self.assertRaises(RuntimeError):
            self._platform_service.restore_control(client_pid)

    def test_restore_write_blocked(self):
        client_pid = 999
        client_sid = 333
        other_pid = 666
        control_name = 'geopm'
        domain = 7
        domain_idx = 42
        setting = 777

        self.open_mock_session('other', other_pid)
        with mock.patch('geopmdpy.pio.write_control', return_value=[]) as mock_write_control, \
             mock.patch('geopmdpy.pio.save_control_dir'), \
             mock.patch('os.getsid', return_value=other_pid):
            self._platform_service.write_control(other_pid, control_name, domain, domain_idx, setting)
            mock_write_control.assert_called_once_with(control_name, domain, domain_idx, setting)

        self.open_mock_session('', client_pid)
        mock_pwuid = mock.MagicMock()
        mock_pwuid.pw_name = 'test_user'
        self._mock_write_lock.try_lock.return_value = other_pid
        err_msg = f'The PID {client_pid} requested write access, but the geopm service already has write mode client with PID or SID of {abs(other_pid)}'
        with self.assertRaisesRegex(RuntimeError, err_msg), \
             mock.patch('geopmdpy.pio.restore_control_dir'), \
             mock.patch('os.getsid', return_value=client_sid), \
             mock.patch('pwd.getpwuid', return_value=mock_pwuid), \
             mock.patch('psutil.pid_exists', return_value=True):
            self._platform_service.restore_control(client_pid)

    def test_restore_control(self):
        session_data = self.open_mock_session('')
        client_pid = session_data['client_pid']
        self._mock_write_lock.try_lock.return_value = client_pid
        with mock.patch('geopmdpy.pio.save_control_dir'), \
             mock.patch('os.getsid', return_value=client_pid), \
             mock.patch('geopmdpy.pio.restore_control_dir') as mock_restore_control_dir:
            self._platform_service.restore_control(client_pid)
            save_dir = os.path.join(self._platform_service._RUN_PATH,
                                    self._platform_service._SAVE_DIR)
            mock_restore_control_dir.assert_called_once_with(save_dir)

    def test_get_cache(self):
        topo = mock.MagicMock()
        topo_service = TopoService(topo=topo)

        mock_open = mock.mock_open(read_data='data')
        cache_file = '/run/geopm/geopm-topo-cache'
        with mock.patch('builtins.open', mock_open):
            cache_data = topo_service.get_cache()
            self.assertEqual('data', cache_data)
            topo.assert_has_calls([mock.call.create_cache()])
            calls = [mock.call(cache_file),
                     mock.call().__enter__(),
                     mock.call().read(),
                     mock.call().__exit__(None, None, None)]
            mock_open.assert_has_calls(calls)

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


import inspect
import json
import sys
from pathlib import Path

import pytest
from _pytest import fixtures
from _pytest.compat import get_real_func

def get_func_path(func):
    real_func = get_real_func(func)
    return inspect.getfile(real_func)

def get_fixturedef(fixture_request, name):
    fixturedef = fixture_request._fixture_defs.get(name)
    if fixturedef:
        return fixturedef
    try:
        return fixture_request._getnextfixturedef(name)
    except fixtures.FixtureLookupError:
        return None

def process_fixtures(item):
    lockfile_definitions = []
    fixture_request = fixtures.FixtureRequest(item, _ispytest=True)
    for fixture_name in fixture_request.fixturenames:
        fixture_def = get_fixturedef(fixture_request, fixture_name)
        if not fixture_def:
            continue

        func = fixture_def.func
        annotations = getattr(func, "__annotations__")
        if not annotations or annotations.get("return") != "JVMLockfileFixtureDefinition":
            continue

        # Note: We just invoke the fixture_def function assuming it takes no arguments. The other two
        # ways of invoking for the fixture value cause errors. I have left them here commented-out as an example
        # of what failed:
        #   lockfile_definition = fixture_request.getfixturevalue(fixture_name)
        #   lockfile_definition = fixture_def.execute(request=request)
        try:
            lockfile_definition = func()
        except Exception as err:
            raise ValueError(
                f"Exception while getting lockfile definition (file {item.path}): {err}"
            )
        if lockfile_definition.__class__.__name__ != "JVMLockfileFixtureDefinition":
            continue

        cwd = Path.cwd()
        func_path = Path(get_func_path(func)).relative_to(cwd)
        lockfile_definitions.append(
            {
                "lockfile_rel_path": str(lockfile_definition.lockfile_rel_path),
                "requirements": [c.to_coord_str() for c in lockfile_definition.requirements],
                "test_file_path": str(func_path),
            }
        )
    return lockfile_definitions

class CollectionPlugin:
    def __init__(self):
        self.collected = []

    def pytest_collection_modifyitems(self, items):
        for item in items:
            self.collected.append(item)

collection_plugin = CollectionPlugin()
pytest.main(["--setup-only", *sys.argv[1:]], plugins=[collection_plugin])

output = []
cwd = Path.cwd()

for item in collection_plugin.collected:
    output.extend(process_fixtures(item))

with open("tests.json", "w") as f:
    f.write(json.dumps(output))


from contextlib import suppress
import random
import asyncio
from typing import *
import traceback

import hikari
from hikari import Embed
import lightbulb
from lightbulb import events, errors
from lightbulb.context import Context

from core import Inu
from utils.language import Human
from .help import OutsideHelp

from core import getLogger, BotResponseError, Inu, InteractionContext

log = getLogger("Error Handler")
pl = lightbulb.Plugin("Error Handler")
bot: Inu

ERROR_JOKES = [
    "Wait, there is a difference between beta and production?",
    "Seems like someone was to lazy to test me -- _again_",
    "Y'know: _my_ ordinary life is generating errors",
    "You expected me to work properly? Oh please ...",
    (
        "Y'know I can smell your disappointment. It's right about here: ```\n"
        "good                  bad\n"
        "  |--------------------|\n"
        "                             ^\n```"
    )

]

async def on_exception(event: hikari.ExceptionEvent):
    # not user related error
    try:
        log.error(f"{''.join(traceback.format_exception(event.exception))}")
    except Exception:
        log.critical(traceback.format_exc())

@pl.listener(events.CommandErrorEvent)
async def on_error(event: events.CommandErrorEvent):
    """
    """
    try:
        ctx: Context | None = event.context

        if not isinstance(ctx, Context):
            log.debug(f"Exception uncaught: {event.__class__}")
            return
        error = event.exception
        async def message_dialog(error_embed: hikari.Embed):
            error_id = f"{bot.restart_num}-{bot.id_creator.create_id()}-{bot.me.username[0]}"
            component=(
                hikari.impl.MessageActionRowBuilder()
                .add_interactive_button(
                    hikari.ButtonStyle.PRIMARY,
                    "error_send_dev_silent",
                    label="🍭 Send report silently"
                )
                .add_interactive_button(
                    hikari.ButtonStyle.PRIMARY,
                    "error_send_dev",
                    label="🍭 Add note & send"
                )
            )
            try:
                message = await (await ctx.respond(
                    embed=error_embed,
                    component=component
                )).message()
            except Exception:
                message = await bot.rest.create_message(
                    ctx.channel_id,
                    embed=error_embed,
                    component=component
                )

            def check(event: hikari.ReactionAddEvent):
                if event.user_id != bot.me.id and event.message_id == message.id:
                    return True
                return False

            custom_id, _, interaction = await bot.wait_for_interaction(
                custom_ids=["error_send_dev", "error_show", "error_send_dev_silent"],
                message_id=message.id,
                user_id=ctx.user.id
            )
            # await interaction.delete_message(message)
            embeds: List[Embed] = [Embed(title=f"Bug #{error_id}", description=str(error)[:2000])]
            embeds[0].set_author(
                name=f'Invoked by: {ctx.user.username}',
                icon=ctx.author.avatar_url
            )
            embeds[0].add_field(
                "invoked with",
                value=(
                    f"Command: {ctx.invoked_with}\n"
                    "\n".join([f"`{k}`: ```\n{v}```" for k, v in ctx.raw_options.items()])
                )[:1000]
            )
            nonlocal event
            traceback_list = traceback.format_exception(*event.exc_info)
            if len(traceback_list) > 0:
                log.warning(str("\n".join(traceback_list)))
            error_embed.add_field(
                name=f'{str(error.__class__)[8:-2]}',
                value=f'Error:\n{error}'[:1024],
            )
            i = 0
            for index, tb in enumerate(traceback_list):
                if embeds[-1].total_length() > 6000:
                    field = embeds[-1]._fields.pop(-1)
                    embeds.append(Embed(description=f"Bug #{error_id}"))
                    embeds[-1]._fields.append(field)
                    i = 0
                if i % 20 == 0 and i != 0:
                    embeds.append(Embed(description=f"Bug #{error_id}"))
                embeds[-1].add_field(
                    name=f'Traceback - layer {index + 1}',
                    value=f'```python\n{Human.short_text_from_center(tb, 1000)}```',
                    inline=False
                )
                i += 1
            messages: List[List[Embed]] = [[]]
            message_len = 0
            for e in embeds:
                for field in e._fields:
                    if not field.value:
                        field.value = "-"
                if message_len == 0:
                    messages[-1].append(e)
                    message_len += e.total_length()
                else:
                    if message_len + e.total_length() > 6000:
                        messages.append([e])
                        message_len = e.total_length()
                    else:
                        messages[-1].append(e)
                        message_len += e.total_length()

            kwargs: Dict[str, Any] = {"embeds": embeds}
            answer = ""
            if custom_id == "error_show":
                await message.edit(embeds=embeds)

            if custom_id == "error_send_dev":
                try:
                    answer, interaction, event = await bot.shortcuts.ask_with_modal(
                        f"Bug report",
                        question_s="Do you have additional information?",
                        interaction=interaction,
                        pre_value_s="/",
                    )
                except asyncio.TimeoutError:
                    answer = "/"
                if answer == "/":
                    answer = ""

            kwargs["content"] = f"**{40*'#'}\nBug #{error_id}\n{40*'#'}**\n\n\n{Human.short_text(answer, 1930)}"
            del kwargs["embeds"]
            for i, embeds in enumerate(messages):
                if i == 0:
                    message = await bot.rest.create_message(
                        channel=bot.conf.bot.bug_channel_id,
                        embeds=embeds,
                        **kwargs
                    )
                else:
                    message = await bot.rest.create_message(
                        channel=bot.conf.bot.bug_channel_id,
                        embeds=embeds,
                    )
            if interaction:
                with suppress():
                    await interaction.create_initial_response(
                        hikari.ResponseType.MESSAGE_CREATE,
                        content=(
                            f"**Bug #{error_id}** has been reported.\n"
                            f"You can find the bug report [here]({message.make_link(message.guild_id)})\n"
                            f"If you can't go to this message, or need additional help,\n"
                            f"consider to join the [help server]({bot.conf.bot.guild_invite_url})"

                        ),
                        flags=hikari.MessageFlag.EPHEMERAL,
                    )
            return

        # errors which will be handled also without prefix
        if isinstance(error, errors.NotEnoughArguments):
            return await OutsideHelp.search(
                obj=ctx.invoked_with,
                ctx=ctx,
                message=(
                    f"to use the `{ctx.invoked.qualname}` command, "
                    f"I need {Human.list_([o.name for o in error.missing_options], '`')} to use it"
                ),
                only_one_entry=True,
            )
        elif isinstance(error, errors.CommandIsOnCooldown):
            return await ctx.respond(
                f"You have used `{ctx.invoked.qualname}` to often. Retry it in `{error.retry_after:.01f} seconds` again"
            )
        elif isinstance(error, errors.ConverterFailure):
            return await OutsideHelp.search(
                obj=ctx.invoked_with,
                ctx=ctx,
                message=(
                    f"the option `{error.option.name}` has to be {Human.type_(error.option.arg_type, True)}"
                ),
                only_one_entry=True,
            )
        elif isinstance(error, errors.MissingRequiredPermission):
            return await ctx.respond(
                f"You need the `{error.missing_perms.name}` permission, to use `{ctx.invoked_with}`",
                flags=hikari.MessageFlag.EPHEMERAL,
            )
        elif isinstance(error, errors.CheckFailure):
            fails = set(
                str(error)
                .replace("Multiple checks failed: ","")
                .replace("This command", f"`{ctx.invoked_with}`")
                .split(", ")
            )
            if len(fails) > 1:
                str_fails = [f"{i+1}: {e}"
                    for i, e in enumerate(fails)
                ]
                return await ctx.respond(
                    "\n".join(fails)
                )
            else:
                return await ctx.respond(fails.pop())
        elif isinstance(error, errors.CommandInvocationError) and isinstance(error.original, BotResponseError):
            try:
                return await ctx.respond(**error.original.kwargs)
            except hikari.BadRequestError:
                # interaction probably already acknowledged
                # TODO: implement Error handling into InuContext
                ctx._responded = True
                return await ctx.respond(**error.original.kwargs)

        # errors which will only be handled, if the command was invoked with a prefix
        if not ctx.prefix:
            return # log.debug(f"Suppress error of type: {error.__class__.__name__}")
        if isinstance(error, errors.CommandNotFound):
            return await OutsideHelp.search(
                obj=error.invoked_with,
                ctx=ctx,
                message=f"There is no command called `{error.invoked_with}`\nMaybe you mean one from the following ones?"
            )
        else:
            error_embed = hikari.Embed()
            error_embed.title = "Oh no! A bug occurred"
            error_embed.description = random.choice(ERROR_JOKES)
            with suppress(hikari.ForbiddenError):
                await message_dialog(error_embed)
    except Exception:
        log.critical(traceback.format_exc())

def load(inu: Inu):
    global bot
    bot = inu
    @bot.listen(hikari.events.ExceptionEvent)
    async def on_error(event: hikari.events.ExceptionEvent) -> None:
        try:
            log.error(f"{''.join(traceback.format_exception(event.exception))}")
        except Exception:
            log.critical(traceback.format_exc())
    inu.add_plugin(pl)


##############################################
# Q1 --- find sum of all inputs
##############################################

# Read input - (f.read() for char-by-char read) & (loop file object for LINE-by-LINE reading)

with open('./1201.in', 'r') as f:
    freqList = [line.strip() for line in f]

# Compute sum
from functools import reduce
summed = reduce(lambda acc, curr: acc + int(curr), freqList, 0)

# print(summed)

##############################################
# Q1 --- find first cumulative value that repeats
# --- use itertools (efficient looping) : cycle!! because need to REPEAT given input indefinitely
##############################################

from itertools import cycle
cumulative, visited = 0, set()
for n in cycle(freqList):
    # print(summed)
    visited.add(cumulative)
    cumulative += int(n)
    # print(cumulative)
    if (cumulative in visited):
        print(cumulative)
        break


import numpy as np
from itertools import product
from vgc_project.maze import Maze

def test_basic_maze_properties():
    pw=.94
    ps=.6

    m = Maze(
        tile_array=(
            ".j.",
            "x#3"
        ),
        absorbing_features=("j",),
        wall_features=("#","3"),
        default_features=(".",),
        initial_features=("x",),
        step_cost=-1,
        wall_bump_cost=0,
        wall_block_prob=pw,
        success_prob=ps,
        discount_rate=1.0,
        include_action_effect=True,
        include_wall_effect=True,
        include_terminal_state_effect=True,
        wall_bias=0.
    )

    # all locations are part of state space
    assert list(m.state_list) == list(product(range(3), range(2)))

    # fixed action ordering
    assert list(m.action_list) == [(1, 0), (-1, 0), (0, 0), (0, 1), (0, -1)]
    right, left, wait, up, down = m.action_list

    # all non-terminal state-actions should have the step cost
    sa_rf = (m.reward_matrix*m.transition_matrix).sum(-1)
    non_term_sa_rf = sa_rf[m.nonterminal_state_vec]
    assert (non_term_sa_rf == m.step_cost).all()

    # transition function
    tf = m.transition_matrix
    nss = tf.shape[0]
    aa = m.action_list
    ss = m.state_list

    # wait action
    assert (tf[np.arange(nss), 2, np.arange(nss)] == 1).all()

    # going off edge of grid leads you to stay in place
    assert tf[ss.index((0, 0)), aa.index(left), ss.index((0, 0))] == 1
    assert tf[ss.index((2, 0)), aa.index(right), ss.index((2, 0))] == 1

    # dynamics of goign from nonwall to nonwall
    assert tf[ss.index((0, 0)), aa.index(up), ss.index((0, 1))] == ps

    # exiting a wall into a non-wall or wall has the same probability
    # namely, we ignore the wall dynamics
    assert tf[ss.index((1, 0)), aa.index(left), ss.index((0, 0))] == ps
    assert tf[ss.index((1, 0)), aa.index(right), ss.index((2, 0))] == ps

    # dynamics of crashing into a wall
    assert np.isclose(
        tf[ss.index((0, 0)), aa.index(right), ss.index((1, 0))],
        (ps*(1 - pw))/(ps*(1 - pw) + pw*(1 - ps))
    )

    # terminal state leads to itself with probability 1
    # and being in it always gives reward 0
    assert not m.nonterminal_state_vec[ss.index((1, 1))]
    assert m.nonterminal_state_vec.sum() == 5
    assert (tf[ss.index((1, 1)), :, ss.index((1, 1))] == 1).all()
    assert (sa_rf[ss.index((1, 1))] == 0).all()


import os
import cv2
import numpy as np
import torch
from PIL import Image
import torchvision

class SegDataset(object):
    def __init__(self, root, transforms):
        self.root = root
        self.transforms = transforms
        # load all image files, sorting them to
        # ensure that they are aligned

        # cut_dataset_at=10000

        self.imgs = list(sorted(os.listdir(os.path.join(root, "images"))))#[:cut_dataset_at]
        self.masks = list(sorted(os.listdir(os.path.join(root, "masks"))))#[:cut_dataset_at]
        self.polys = list(sorted(os.listdir(os.path.join(root, "polygons"))))#[:cut_dataset_at]

    def __getitem__(self, idx):
        # load images ad masks
        img_path = os.path.join(self.root, "images", self.imgs[idx])
        mask_path = os.path.join(self.root, "masks", self.masks[idx])
        poly_path = os.path.join(self.root, "polygons", self.polys[idx])

        img = Image.open(img_path).convert("RGB")
        img = np.array(img)
        mask = Image.open(mask_path)
        mask = np.array(mask)

        # instances are encoded as different colors
        obj_ids = np.unique(mask)
        # first id is the background, so remove it
        obj_ids = obj_ids[1:]
        # split the color-encoded mask into a set of binary masks
        masks = mask == obj_ids[:, None, None]

        polys = np.load(poly_path)

        # get bounding box coordinates for each mask
        num_objs = len(obj_ids)
        boxes = []
        for i in range(num_objs):
            pos = np.where(masks[i])
            xmin = np.min(pos[1])
            xmax = np.max(pos[1])
            ymin = np.min(pos[0])
            ymax = np.max(pos[0])
            boxes.append([xmin, ymin, xmax, ymax])

        # convert everything into a torch.Tensor
        boxes = torch.as_tensor(boxes, dtype=torch.float32)

        mask =  np.zeros((img.shape[0], img.shape[1]))
        cv2.drawContours(mask, [polys], -1, 1, 5)

        model_input_size = (300, 300)

        img = cv2.resize(img, model_input_size)
        mask = cv2.resize(mask, model_input_size)

        img = torchvision.transforms.ToTensor()(img)
        mask = torch.tensor(np.expand_dims(mask, axis=0), dtype=torch.float)

        # if self.transforms is not None:
        #     for transform in self.transforms:
        #         print(transform)
        #         img = transform(img)
        #         mask = transform(target)

        return img, mask

    def __len__(self):
        return len(self.imgs)


import pandas as pd
import os
import numpy as np
from math import floor
from sqlalchemy import create_engine, MetaData, Table
import tushare as ts
from utils import get_all_tdx_symbols
import click

import struct
"""
读取通达信数据
"""

class TdxFileNotFoundException(Exception):
    pass

class TdxReader:

    def __init__(self, vipdoc_path):
        self.vipdoc_path = vipdoc_path
        self.engine = None

    def get_kline_by_code(self, code, exchange):
        fname = os.path.join(self.vipdoc_path, exchange)
        fname = os.path.join(fname, 'lday')
        fname = os.path.join(fname, '%s%s.day' % (exchange, code))
        return self.parse_data_by_file(fname)

    def get_mline_by_code(self, code, exchange):
        fname = os.path.join(self.vipdoc_path, exchange)
        fname = os.path.join(fname, 'minline')
        fname = os.path.join(fname, '%s%s.lc1' % (exchange, code))
        return self.parse_mdata_by_file(fname)

    def parse_data_by_file(self, fname):

        if not os.path.isfile(fname):
            raise TdxFileNotFoundException('no tdx kline data, please check path %s', fname)

        with open(fname, 'rb') as f:
            content = f.read()
            return self.unpack_records('<iiiiifii', content)
        return []

    def parse_mdata_by_file(self, fname):

        if not os.path.isfile(fname):
            raise  TdxFileNotFoundException("no tdx mline data, please check path %s", fname)

        with open(fname, 'rb') as f:
            content = f.read()
            return self.unpack_records('<HHfffffIxxxx', content)
        return []

    def unpack_records(self, format, data):
        record_struct = struct.Struct(format)
        return (record_struct.unpack_from(data, offset)
                for offset in range(0, len(data), record_struct.size))

    def get_df(self, code, exchange):
        data = [self._df_convert(row) for row in self.get_kline_by_code(code, exchange)]
        df =  pd.DataFrame(data=data, columns=('date', 'open', 'high', 'low', 'close', 'amount', 'volume'))
        df.index = pd.to_datetime(df.date)
        return df[['open', 'high', 'low', 'close', 'volume']]

    def get_mindf(self, code, exchange):
        data = [self._mindf_convert(row) for row in self.get_mline_by_code(code, exchange)]
        df = pd.DataFrame(data=data, columns=('datetime', 'open', 'high', 'low', 'close', 'amount', 'volume'))
        try:
            df.index = pd.to_datetime(df.datetime)
        except ValueError as err:
            print("ValueError: ", df.datetime)
            raise err
        return df[['open', 'high', 'low', 'close', 'amount', 'volume']]

    def _df_convert(self, row):
        t_date = str(row[0])
        datestr = t_date[:4] + "-" + t_date[4:6] + "-" + t_date[6:]

        new_row = (
            datestr,
            row[1] * 0.01, # * 0.01 * 1000 , zipline need 1000 times to original price
            row[2] * 0.01,
            row[3] * 0.01,
            row[4] * 0.01,
            row[5],
            row[6]
        )

        return new_row

    def _mindf_convert(self, row):
        t_date = row[0]
        year = floor(t_date / 2048) + 2004
        month = floor((t_date % 2048) / 100)
        day = (t_date % 2048) % 100
        datestr = "%d-%02d-%02d" % (year, month, day)
        t_minute = row[1]
        hour = floor(t_minute / 60)
        minute = t_minute % 60
        timestr = "%02d:%02d:00" % (hour, minute)
        datetimestr = "%s %s" % (datestr, timestr)

        new_row = (
            datetimestr,
            row[2],
            row[3],
            row[4],
            row[5],
            row[6],
            row[7]
        )

        return new_row

    def to_sql(self, symbol, exchange):
        table_name = exchange+symbol
        table = Table(table_name, MetaData(bind=self.engine))
        new = self.get_mindf(symbol, exchange)
        if table.exists():
            old = pd.read_sql_table(exchange+symbol, self.engine, index_col='datetime')
            if new.index[-1] <= old.index[-1]:
                return
            else:
                df_to_append = new[old.index[-1]:]
        else:
            df_to_append = new
        df_to_append.to_sql(table_name, self.engine, if_exists='append')

    def save_minute_line(self, sql_url):
        self.engine = create_engine(sql_url)
        tdx_symbol_list = get_all_tdx_symbols()
        total = len(tdx_symbol_list)
        i = 0
        for symbol in tdx_symbol_list:
            i += 1
            click.echo("saving symbol %s%s (%d/%d)" %(symbol[1], symbol[0], i, total))
            self.to_sql(symbol=symbol[0], exchange=symbol[1])

@click.command()
@click.argument('vipdoc', type=click.Path(exists=True))
@click.argument('sql_url', type=click.Path())
def main(vipdoc, sql_url):
    click.echo('minute line saving...')
    tdx_reader = TdxReader(vipdoc)
    tdx_reader.save_minute_line("sqlite:///" + sql_url)

if __name__ == '__main__':
    main()
    #tdx_reader = TdxReader('c:\\new_zx_allin1\\vipdoc\\')
    # try:
    #     #for row in tdx_reader.parse_data_by_file('/Volumes/more/data/vipdoc/sh/lday/sh600000.day'):
    #     #    print(row)
    #     for row in tdx_reader.get_mline_by_code('600433', 'sh'):
    #         print(row)
    # except TdxFileNotFoundException as e:
    #     pass
    #
    # print(tdx_reader.get_mindf('600433', 'sh'))
    #sql_url = "sqlite:///lc1.db"
    #tdx_reader.save_minute_line(sql_url=sql_url)


import logging
from enum import Enum

import openai
from fastapi import Query
from openai.error import AuthenticationError, InvalidRequestError, RateLimitError
from tenacity import (
    retry,
    stop_after_attempt,
    wait_random_exponential,
    retry_if_exception_type,
)  # for exponential backoff

from app.config.messages import (
    model_description,
    max_tokens_description,
    temperature_description,
    top_p_description,
    presence_penalty_description,
    frequency_penalty_description,
)

class Model(Enum):
    TEXT_DAVINCI_003 = "text-davinci-003"

@retry(
    wait=wait_random_exponential(min=2, max=5),
    stop=stop_after_attempt(5),
    retry=retry_if_exception_type(RateLimitError),
)
async def completions_with_backoff(**kwargs):
    return await openai.Completion.acreate(**kwargs)

async def get_completions(
    api_key: str,
    message: str,
    model: Model = Query(Model.TEXT_DAVINCI_003, description=model_description),
    max_tokens: int = Query(2048, description=max_tokens_description),
    temperature: float = Query(1, description=temperature_description),
    top_p: float = Query(1, description=top_p_description),
    presence_penalty: float = Query(0.5, description=presence_penalty_description),
    frequency_penalty: float = Query(0.5, description=frequency_penalty_description),
):
    openai.api_key = api_key

    # https://platform.openai.com/docs/api-reference/completions
    try:
        result = await completions_with_backoff(
            model=model.value,
            max_tokens=max_tokens,
            temperature=temperature,
            top_p=top_p,
            presence_penalty=presence_penalty,
            frequency_penalty=frequency_penalty,
            prompt=message,
            request_timeout=60,
        )
    except AuthenticationError as e:
        logging.error(e)
        return "The token is invalid."
    except InvalidRequestError as e:
        logging.error(e)
        if "This model's maximum context length is 4097 tokens" in str(e):
            return "너무 긴 답변을 유도하셨습니다."
        else:
            return "오류가 발생했습니다 :sob: 다시 시도해 주세요."
    except Exception as e:
        logging.exception(e)
        return "오류가 발생했습니다 :sob: 다시 시도해 주세요."

    try:
        return result.get("choices")[0].get("text")
    except KeyError as e:
        logging.exception(e)
        return "오류가 발생했습니다 :sob: 다시 시도해 주세요."


from django.contrib import admin
from django.db import models
from django.db.models import Q
from django.utils.translation import gettext_lazy as _

from ...settings import ADMIN_MEDIA_JS
from .actions import save_all_theses_to_xls
from .models import Thesis

# Copied from https://gist.github.com/rafen/eff7adae38903eee76600cff40b8b659,
# also present in theses admin and jobs admin
class ExtendedActionsMixin(object):
    # actions that can be executed with no items selected on the admin change list.
    # The filtered queryset displayed to the user will be used instead
    extended_actions = []

    def changelist_view(self, request, extra_context=None):
        # if a extended action is called and there's no checkbox selected, select one with
        # invalid id, to get an empty queryset
        if "action" in request.POST and request.POST["action"] in self.extended_actions:
            if not request.POST.getlist(admin.ACTION_CHECKBOX_NAME):
                post = request.POST.copy()
                post.update({admin.ACTION_CHECKBOX_NAME: 0})
                request._set_post(post)
        return super(ExtendedActionsMixin, self).changelist_view(request, extra_context)

    def get_changelist_instance(self, request):
        """
        Returns a simple ChangeList view instance of the current ModelView.
        (It's a simple instance since we don't populate the actions and list filter
        as expected since those are not used by this class)
        """
        list_display = self.get_list_display(request)
        list_display_links = self.get_list_display_links(request, list_display)
        list_filter = self.get_list_filter(request)
        search_fields = self.get_search_fields(request)
        list_select_related = self.get_list_select_related(request)

        ChangeList = self.get_changelist(request)

        return ChangeList(
            request,
            self.model,
            list_display,
            list_display_links,
            list_filter,
            self.date_hierarchy,
            search_fields,
            list_select_related,
            self.list_per_page,
            self.list_max_show_all,
            self.list_editable,
            self,
            self.sortable_by,
        )

    def get_filtered_queryset(self, request):
        """
        Returns a queryset filtered by the URLs parameters
        """
        cl = self.get_changelist_instance(request)
        return cl.get_queryset(request)

class ThesisListFilter(admin.SimpleListFilter):
    title = _("empty thesis title")
    parameter_name = "have_title"

    def lookups(self, request, model_admin):
        return (
            ("yes", _("Yes")),
            ("no", _("No")),
        )

    def queryset(self, request, queryset):
        if self.value() == "no":
            return queryset.filter(title__isnull=False).exclude(title="")

        if self.value() == "yes":
            return queryset.filter(Q(title__isnull=True) | Q(title__exact=""))

@admin.register(Thesis)
class ThesisAdmin(admin.ModelAdmin):
    list_display = ("get_author", "title", "show_year", "type")
    list_filter = ("type", ThesisListFilter)
    search_fields = (
        "title",
        "alumnus__last_name",
        "alumnus__first_name",
        "date_start",
        "date_stop",
        "date_of_defence",
    )
    ordering = ("alumnus__username",)
    filter_horizontal = ("advisor",)
    readonly_fields = (
        "date_created",
        "date_updated",
        "last_updated_by",
        "slug",
    )
    actions = (
        "export_selected_degrees_to_excel",
        "export_all_degrees_to_excel",
        "export_filtered_degrees_to_excel",
    )
    extended_actions = (
        "export_all_degrees_to_excel",
        "export_filtered_degrees_to_excel",
    )

    max_num = 2

    fieldsets = [
        (
            "Thesis Information",
            {"fields": ["alumnus", "type", "date_start", "date_stop"]},
        ),
        (
            "Thesis Information",
            {
                "fields": [
                    "title",
                    "date_of_defence",
                    "url",
                    "dissertation_nr",
                    "slug",
                    "in_library",
                ]
            },
        ),
        ("Thesis Advisor ", {"fields": ["advisor"]}),
        ("Full Text and Cover Photo", {"fields": ["pdf", "photo"]}),
        (
            "Extra information",
            {
                "classes": ["collapse"],
                "fields": [
                    "comments",
                    "date_created",
                    "date_updated",
                    "last_updated_by",
                ],
            },
        ),
    ]

    class Media:
        js = ADMIN_MEDIA_JS
        css = {"all": ("css/admin_extra.css",)}

    def save_model(self, request, obj, form, change):
        obj.last_updated_by = request.user
        obj.save()

    # def changelist_view(self, request, extra_context=None):
    #     """ Hack the default changelist_view to allow action "export_all_degrees_to_excel"
    #         to run without selecting any objects """
    #     if "action" in request.POST and request.POST["action"] == "export_all_degrees_to_excel":
    #         if not request.POST.getlist(admin.ACTION_CHECKBOX_NAME):
    #             post = request.POST.copy()
    #             for u in Thesis.objects.all():
    #                 post.update({admin.ACTION_CHECKBOX_NAME: str(u.id)})
    #             request._set_post(post)
    #     return super(ThesisAdmin, self).changelist_view(request, extra_context)

    def get_queryset(self, request):
        """This function defines how to sort on alumnus column in the list_display
        http://stackoverflow.com/a/29083623"""
        qs = super(ThesisAdmin, self).get_queryset(request)
        qs = qs.annotate()
        # TODO: this does not take into account the type of the Thesis. Also, when
        # filtering on type = "PhD" ordering of the Theses could be done on the MSc Thesis
        qs = qs.annotate(
            sort_author=models.Count("alumnus__last_name", distinct=True)
        ).annotate(
            sort_year=models.Count("alumnus__theses__date_of_defence", distinct=True)
        )
        return qs

    # def formfield_for_manytomany(self, db_field, request, **kwargs):
    #     try:  # Breaks for add thesis
    #         current_thesis = Thesis.objects.get(pk=request.resolver_match.args[0])
    #         if db_field.name == "advisor":
    #             kwargs["queryset"] = Alumnus.objects.exclude(username=current_thesis.alumnus.username)
    #         return super(ThesisAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
    #     except IndexError as e:
    #         if str(e) == "tuple index out of range":
    #             pass

    def get_author(self, obj):
        """We could use author instead of get_alumnus in list_display"""
        return obj.alumnus.full_name

    get_author.short_description = "Author"
    get_author.admin_order_field = "sort_author"

    def show_year(self, obj):
        if obj.date_of_defence:
            return obj.date_of_defence.strftime("%Y")
        elif obj.date_stop:
            return obj.date_stop.strftime("%Y")
        return None

    show_year.short_description = "Year"
    show_year.admin_order_field = "sort_year"

    def export_selected_degrees_to_excel(self, request, queryset):
        return save_all_theses_to_xls(request, queryset)

    export_selected_degrees_to_excel.short_description = (
        "Export selected Theses to Excel"
    )

    def export_all_degrees_to_excel(self, request, queryset):
        return save_all_theses_to_xls(request, None)

    export_all_degrees_to_excel.short_description = "Export all Theses to Excel"

    def export_filtered_degrees_to_excel(self, request, queryset):
        queryset = self.get_filtered_queryset(request)
        return save_all_theses_to_xls(request, queryset)

    export_filtered_degrees_to_excel.short_description = (
        "Export filtered list of Theses to Excel"
    )


import sqlite3

def execute_with_output(conn, query_txt, fetch_quant="one"):
    """
    Takes the connection file variable and executes the query text within that connection
    :param fetch_quant:
    :param conn:
    :param query_txt:
    :return:
    """
    try:
        c = conn.cursor()
        c.execute(query_txt)
        if fetch_quant == "one":
            return c.fetchone()
        else:
            return c.fetchall()
    except sqlite3.Error as e:
        print(e)

def execute_no_output(conn, query_txt):
    """
    :param conn:
    :param query_txt:
    :return:
    """
    try:
        c = conn.cursor()
        c.execute(query_txt)
    except sqlite3.Error as e:
        print(e)


# %%
import pandas as pd
import plotly.io as pio
import plotly.express as px
import plotly

# %%
adani_df = pd.read_csv('Data\Scatterplot\ADANIENT_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
appolo_df = pd.read_csv('Data\Scatterplot\APOLLOHOSP_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
asian_df = pd.read_csv('Data\Scatterplot\ASIANPAINT_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
airtel_df = pd.read_csv('Data\Scatterplot\BHARTIARTL_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
bajaj_df = pd.read_csv('Data\Scatterplot\BAJFINANCE_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
divis_df = pd.read_csv('Data\Scatterplot\DIVISLAB_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
drreddy_df = pd.read_csv('Data\Scatterplot\DRREDDY_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
hind_df = pd.read_csv('Data\Scatterplot\HINDALCO_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
hdfc_df = pd.read_csv('Data\Scatterplot\HDFC_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
hul_df = pd.read_csv('Data\Scatterplot\HINDUNILVR_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
infy_df = pd.read_csv('Data\Scatterplot\INFY_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
itc_df = pd.read_csv('Data\Scatterplot\ITC_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
lt_df = pd.read_csv('Data\Scatterplot\LT_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
mm_df = pd.read_csv('Data\Scatterplot\MM_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
nestle_df = pd.read_csv(r'Data\Scatterplot\NESTLEIND_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
ongc_df = pd.read_csv('Data\Scatterplot\ONGC_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
power_df = pd.read_csv('Data\Scatterplot\POWERGRID_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
rel_df = pd.read_csv('Data\Scatterplot\RELIANCE_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
sbi_df = pd.read_csv('Data\Scatterplot\SBIN_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
sun_df = pd.read_csv('Data\Scatterplot\SUNPHARMA_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
tatam_df = pd.read_csv('Data\Scatterplot\TATAMOTORS_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
tcs_df = pd.read_csv('Data\Scatterplot\TCS_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
ulttech_df = pd.read_csv(r'Data\Scatterplot\ULTRACEMCO_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
upl_df = pd.read_csv(r'Data\Scatterplot\UPL_day_data_processed.csv', parse_dates=['date'], index_col=['date'])
wipro_df = pd.read_csv(r'Data\Scatterplot\WIPRO_day_data_processed.csv', parse_dates=['date'], index_col=['date'])

# %%
adani_df['company'] = 'Adani Enterprises'
appolo_df['company'] = 'Apollo Hospitals'
asian_df['company'] = 'Asian Paints'
airtel_df['company'] = 'Bharti Airtel'
bajaj_df['company'] = 'Bajaj Finance'
drreddy_df['company'] = "Dr. Reddy's Laboratories"
hdfc_df['company'] = "HDFC Bank"
infy_df['company'] = 'Infosys'
itc_df['company'] = 'ITC'
lt_df['company'] = 'Larsen & Toubro'
mm_df['company'] = 'Mahindra & Mahindra'
nestle_df['company'] = 'Nestle India'
ongc_df['company'] = 'Oil and Natural Gas Corporation'
rel_df['company'] = 'Reliance Industries'
sbi_df['company'] = 'State Bank of India'
divis_df['company'] = "Divi's Laboratories"
hind_df['company'] = 'Hindalco Industries'
hul_df['company'] = 'Hindustan Unilever'
power_df['company'] = 'Power Grid Corporation of India'
sun_df['company'] = 'Sun Pharmaceutical'
tatam_df['company'] = 'Tata Motors'
tcs_df['company'] = 'Tata Consultancy Services'
ulttech_df['company'] = 'UltraTech Cement'
upl_df['company'] = 'United Phosphorus Limited'
wipro_df['company'] = 'Wipro'

# %%
df_stocks = pd.concat([adani_df, appolo_df, asian_df, airtel_df, bajaj_df, divis_df, drreddy_df, infy_df, hind_df, hdfc_df,
hul_df, itc_df, lt_df, mm_df, nestle_df, ongc_df, power_df, sbi_df, sun_df, rel_df, tatam_df, tcs_df, ulttech_df, upl_df, wipro_df], axis=0)

# %%
df = []
for company in df_stocks['company'].unique():
    company_df = df_stocks[['volume', 'close']][df_stocks['company'] == company]
    company_df[f'{company}_dollar_volume'] = company_df['volume'] * company_df['close']
    company_df = company_df[[f'{company}_dollar_volume']]
    df.append(company_df)
df = pd.concat(df, axis = 1)

# %%
company_df = df_stocks[['volume', 'close', 'company']]
company_df['dollar_volume'] = company_df['volume'] * company_df['close']

# %%
d= []
for company in df_stocks['company'].unique():
    monthly_volume = pd.DataFrame()
    monthly_dv = company_df['dollar_volume'][company_df['company']==company].resample('M').sum()
    monthly_v = company_df['volume'][company_df['company']==company].resample('M').sum()
    monthly_close = company_df['close'][company_df['company']==company].resample('M').mean()
    monthly_volume['dollar_volume'] = monthly_dv
    monthly_volume['volume'] = monthly_v
    monthly_volume['close'] = monthly_close
    monthly_volume['date'] = monthly_dv.index
    monthly_volume['company'] = company
    d.append(monthly_volume)
d = pd.concat(d)
d['company'].unique()

# %%
sectors = pd.read_csv('Data\sectors.csv')

# %%
s = []
for c in d['company']:
    s.append(sectors['sector'][sectors['company']==c])
s = pd.concat(s)
d['sector'] = list(s)

# %%
fig = px.scatter(d, x="close", y="volume", animation_frame="date", animation_group="company", template='plotly_white',
                 size='dollar_volume',color="sector", hover_name="company", size_max=60, log_y=True, log_x=True, range_x=[60,21000], range_y=[250000,5994900000])
fig.update_layout(
    title='Sectorwise Volume Data',
    title_x=0.44,
    yaxis_title='Volume',
    xaxis_title='Price',
    height=600,
    # width=1200,
    )

x_avg = d['close'].mean()
y_avg = d['volume'].mean()

fig.add_vline(x=x_avg, line_width=1, opacity=0.9)
fig.add_hline(y=y_avg, line_width=1, opacity=1)

fig.add_annotation(dict(font=dict(color="black",size=14),
                        x=0, y=-0.14,#data['score'].min()-0.2, y=data['wgt'].min()-0.2,
                        text="Low Volume - Low Price",
                        xref='paper',
                        yref='paper',
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=14),
                        x=1, y=-0.14,#x=data['score'].max(), y=data['wgt'].min(),
                        text="Low Volume - High Price",
                        xref='paper',
                        yref='paper',
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=14),
                        x=0, y=1.07, #x=data['score'].min(), y=data['wgt'].max(),
                        text="High Volume - Low Price",
                        xref='paper',
                        yref='paper',
                        showarrow=False))
fig.add_annotation(dict(font=dict(color="black",size=14),
                        x=1, y=1.07, #x=data['score'].max(), y=data['wgt'].max(),
                        text="High Volume - High Price",
                        xref='paper',
                        yref='paper',
                        showarrow=False))

fig.show()

plotly.offline.plot(fig, filename='scatterplot.html')
# %%


import requests
from bs4 import BeautifulSoup
from .componentParser import ComponentParser
from .utils import isRelativePostDate, getRelativePostDate

class BlogPost:
	errorCount = 0

	def __init__(self, url, isDevMode=False):
		# 개발 편의
		self.isDevMode = isDevMode
		# init
		self.url = url
		self.postInframeUrl = ''
		self.postEditorVersion = None
		self.postLogNum = None
		self.postDate = None
		self.postInframeSoup = None

		# init check
		if self.isForeignUrl():
			print("[INIT ERROR] URL이 잘못되었습니다. 프로그램을 종료합니다.")
			exit(-1)

	# ============================================================================================

	# 개발편의용 프린트 함수
	def printDevMessage(self, message):
		if self.isDevMode:
			print("[DEV MODE] " + message, end='\n')

	# 유저가 입력한 URL 이 올바른지 체크하는 함수
	def isForeignUrl(self):
		self.printDevMessage("isForeignUrl execution")

		if 'blog.naver.com' in self.url:
			return False
		else:
			return True

	# ============================================================================================

	def postSetup(self):
		try:
			self.printDevMessage("== postSetup execution == ")

			self.postInframeUrl = self.getPostInframeUrl()
			self.postInframeSoup = self.getPostInframeSoup()
			self.postEditorVersion = self.getPostEditorVersion()
			self.postDate = self.getPostDate()

			self.printDevMessage("== postSetup is clear == ")

		# 여기서는 폴더 생성 체크까지만, 다 되었다면 run 함수로 넘긴다.

		except Exception as e:
			print(e)

	def getPostInframeUrl(self):
		self.printDevMessage("== getPostInframeUrl 실행 ==")

		originHtml = requests.get(self.url).text
		originSoup = BeautifulSoup(originHtml, features="html.parser")

		for link in originSoup.select('iframe#mainFrame'):
			postInframeUrl = "http://blog.naver.com" + link.get('src')

		self.printDevMessage(f'return is : {postInframeUrl}')
		return postInframeUrl

	def getPostInframeSoup(self):
		self.printDevMessage("== getPostInframeSoup execution ==")

		if not (self.postInframeUrl == ''):
			inframeHtml = requests.get(self.postInframeUrl).text
			inframeSoup = BeautifulSoup(inframeHtml, features="html.parser")

			self.printDevMessage(f'return is : {len(inframeSoup)} links')
			return inframeSoup
		else:
			raise Exception("[ERROR] getPostInframeSoup가 정상적으로 실행되지 않았습니다.")

	def getPostEditorVersion(self):
		self.printDevMessage("== getPostEditorVersion execution ==")

		for link in self.postInframeSoup.select('div#post_1'):
			postEditiorVersion = link.get('data-post-editor-version')

		if postEditiorVersion == None:
			raise Exception("[ERROR] 지원하지 않는 에디터 버젼입니다.")

		self.printDevMessage(f'return is : {postEditiorVersion}')
		return postEditiorVersion

	def getPostDate(self):
		self.printDevMessage("== getPostDate execution ==")

		links = self.postInframeSoup.select('span.se_publishDate')
		if len(links) == 0:
			raise Exception("[ERROR] 포스트 게시일을 찾지 못했습니다.")

		else:
			for link in links:
				publishDate = link.get_text()

			if isRelativePostDate(publishDate):
				publishDate = getRelativePostDate(publishDate)

			self.printDevMessage(f'return is : {publishDate}')
			return publishDate

	# ============================================================================================

	def run(self, dirPath):
		self.printDevMessage("== run execution ==")
		self.postSetup()

		filePath = dirPath + '/' + 'word.md'
		ComponentParser.assetPath = dirPath + '/asset'
		rawComponents = self.postInframeSoup.select('div.se-component')

		try:
			with open(filePath, mode='w', encoding='utf-8') as fp:
				# 작성될 텍스트 데이터 초기화
				data = ''
				for i, component in enumerate(rawComponents):
					if i == 0:
						# 처음에는 무조건 헤더부분의 다큐먼트 타이틀이 나온다.
						data += ComponentParser(component, isDevMode=self.isDevMode).parsingTitle()
						continue

					data += ComponentParser(component, skipSticker=self.isDevMode).parsing()

					# last loop에서는 해시태그까지 추가해준다.
					if i == (len(rawComponents) - 1):
						txt = '해시태그 : '
						for hashTag in ComponentParser.hashTagList:
							txt += hashTag

						data += ' ' + txt
				# 작성
				fp.write(data)

			if ComponentParser.errorCounter != 0:
				BlogPost.errorCount += 1

			# 포스트 백업 후 클래스 변수 초기화
			ComponentParser.hashTagList = []
			ComponentParser.counter = 0
			ComponentParser.errorCount = 0

			return True

		except Exception as e:
			print(e)
			return False


import sys,usb,struct

USB_TIMEOUT_DEFAULT = 1000

SMS_EP_IN  = 0x81
SMS_EP_OUT = 0x02

HIF_TASK   = 11

class SMS1180USB:
    def __init__(self, dev, timeout=USB_TIMEOUT_DEFAULT):
        self.dev = dev
        self.timeout = timeout

    def usb_read(self):
        try:
            return bytes(self.dev.read(SMS_EP_IN, 512, self.timeout))
        except usb.core.USBTimeoutError:
            return None

    def usb_write(self, data):
        try:
            return self.dev.write(SMS_EP_OUT, data, self.timeout)
        except usb.core.USBTimeoutError:
            return False
    def msg_send_req_ex(self, request, src_id, dst_id, flags, payload):
        data = struct.pack("<HBBHH", request, src_id, dst_id, len(payload) + 8, flags) + payload
        self.usb_write(data)

    def msg_send_req(self, request, payload=bytes([])):
        return self.msg_send_req_ex(request, 0, HIF_TASK, 0, payload)

    #return: response, src_id, dst_id, length, flags, payload
    def msg_get_resp_ex(self):
        data = self.usb_read()
        if data == None or len(data) < 8:
            return None,
        else:
            response, src_id, dst_id, length, flags = struct.unpack("<HBBHH", data[0:8])
            return response, src_id, dst_id, length, flags, data[8:]

    #return: response, payload
    def msg_get_resp(self):
        ret = self.msg_get_resp_ex()
        if len(ret) == 1:
            return None,
        else:
            return ret[0], ret[5]


"""
The field should look like this:

       col0   col1   col2    col3   col4   col5    col6   col7   col8
    ||======|======|======||======|======|======||======|======|======||
    ||  A   |  A   |  A   ||  B   |  B   |  B   ||  C   |  C   |  C   ||
row0||cell0 |cell1 |cell2 ||cell3 |cell4 |cell5 ||cell6 |cell7 |cell8 ||
    ||______|______|______||______|______|______||______|______|______||
    ||  A   |  A   |  A   ||  B   |  B   |  B   ||  C   |  C   |  C   ||
row1||cell9 |cell10|cell11||cell12|cell13|cell14||cell15|cell16|cell17||
    ||______|______|______||______|______|______||______|______|______||
    ||  A   |  A   |  A   ||  B   |  B   |  B   ||  C   |  C   |  C   ||
row2||cell18|cell19|cell20||cell21|cell22|cell23||cell24|cell25|cell26||
    ||======|======|======||======|======|======||======|======|======||
    ||  D   |  D   |  D   ||  E   |  E   |  E   ||  F   |  F   |  F   ||
row3||cell27|cell28|cell29||cell30|cell31|cell32||cell33|cell34|cell35||
    ||______|______|______||______|______|______||______|______|______||
    ||  D   |  D   |  D   ||  E   |  E   |  E   ||  F   |  F   |  F   ||
row4||cell36|cell37|cell38||cell39|cell40|cell41||cell42|cell43|cell44||
    ||______|______|______||______|______|______||______|______|______||
    ||  D   |  D   |  D   ||  E   |  E   |  E   ||  F   |  F   |  F   ||
row5||cell45|cell46|cell47||cell48|cell49|cell50||cell51|cell52|cell53||
    ||======|======|======||======|======|======||======|======|======||
    ||  G   |  G   |  G   ||  H   |  H   |  H   ||  I   |  I   |  I   ||
row6||cell54|cell55|cell56||cell57|cell58|cell59||cell60|cell61|cell62||
    ||______|______|______||______|______|______||______|______|______||
    ||  G   |  G   |  G   ||  H   |  H   |  H   ||  I   |  I   |  I   ||
row7||cell63|cell64|cell65||cell66|cell67|cell68||cell69|cell70|cell71||
    ||______|______|______||______|______|______||______|______|______||
    ||  G   |  G   |  G   ||  H   |  H   |  H   ||  I   |  I   |  I   ||
row8||cell72|cell73|cell74||cell75|cell76|cell77||cell78|cell79|cell80||
    ||======|======|======||======|======|======||======|======|======||
"""
import openpyxl
DIGITS = (1, 2, 3, 4, 5, 6, 7, 8, 9)
rows = []
cols = []
squares = []
cells = {}

class Cell:
    def __init__(self, row, col, value=''):
        self.possible_values = list(DIGITS)
        self.value = value
        self.isSolved = False
        self.row = row
        self.col = col

class CellGroup:
    def __init__(self):
        self.cells = []
        self.possible_values = list(DIGITS)

def init_structure():
    global rows
    global cols
    global squares
    global cells
    # Initialize empty rows, cols and squares
    for index in range(0, 9):
        rows.append(CellGroup())
        cols.append(CellGroup())
        squares.append(CellGroup())
    # Initialize empty cells
    for cell_index in range(0, 81):
        cell_name = f'cell{cell_index}'
        row_index = cell_index // 9
        col_index = cell_index % 9
        # Create cell from class
        cells[cell_name] = Cell(row_index, col_index)
        # Adding it to a row and cols list
        rows[row_index].cells.append(cells[cell_name])
        cols[col_index].cells.append(cells[cell_name])
        # Adding squares
        # Maybe someday something shorter and not that straightforward?
        if row_index < 3:
            if col_index < 3:
                squares[0].cells.append(cells[cell_name])
            elif 3 <= col_index < 6:
                squares[1].cells.append(cells[cell_name])
            elif 6 <= col_index < 9:
                squares[2].cells.append(cells[cell_name])
        elif 3 <= row_index < 6:
            if col_index < 3:
                squares[3].cells.append(cells[cell_name])
            elif 3 <= col_index < 6:
                squares[4].cells.append(cells[cell_name])
            elif 6 <= col_index < 9:
                squares[5].cells.append(cells[cell_name])
        elif 6 <= row_index < 9:
            if col_index < 3:
                squares[6].cells.append(cells[cell_name])
            elif 3 <= col_index < 6:
                squares[7].cells.append(cells[cell_name])
            elif 6 <= col_index < 9:
                squares[8].cells.append(cells[cell_name])

def read_puzzle_xls():
    """Read initial know values from Excel"""
    global cells
    exlw = openpyxl.load_workbook('sudoku.xlsx',
                                  read_only=True,
                                  data_only=True)
    ws = exlw.active
    for cell_name, cell in cells.items():
        excel_cell_row = cell.row+1
        excel_cell_column = cell.col+1
        if ws.cell(excel_cell_row, excel_cell_column).value is not None:
            cell.value = ws.cell(
                excel_cell_row, excel_cell_column
            ).value
            cell.possible_values.clear()

def sanity_check():
    """If cell has value - clear possible_values"""
    global cells
    for cell_name, cell in cells.items():
        if cell.value is not None:
            cell.possible_values.clear()

def solve_group(group):
    for cell in group.cells:
        # Removing know values from line possible values
        if (cell.value != '') and (cell.value in group.possible_values):
            group.possible_values.remove(cell.value)
    # Removing line impossible values from cell possible values
    for cell in group.cells:
        for cell_pv in cell.possible_values:
            if cell_pv not in group.possible_values:
                cell.possible_values.remove(cell_pv)
        # Set value if only 1 possible value available
        if len(cell.possible_values) == 1:
            cell.value = cell.possible_values.pop()

def print_puzzle_debug():
    """Prints puzzle results and debug"""
    global cells
    global rows
    for row in rows:
        OutputLine = ''
        for cell in row.cells:
            OutputLine += str(cell.value) + ' '
        print(OutputLine)

def solve_puzzle():
    """Main program to solve the puzzle"""
    # Geeting all the cells without value to list
    unresolved_cells = []
    for cell_name, cell in cells.items():
        if cell.value == '':
            unresolved_cells.append(cell_name)
    # Solving only unknown cells
    for cell_name in unresolved_cells:
        # Solving groups
        for group in rows + cols + squares:
            solve_group(group)

init_structure()
read_puzzle_xls()
solve_puzzle()
print_puzzle_debug()


#!/usr/bin/python3
from tkinter import Image
import rospy
import sys
import cv2
from cv_bridge import CvBridge, CvBridgeError

class viewer:
    def __init__(self):
        self.bridge = CvBridge()
        #
        self.image_rgb_sub = rospy.Subscriber("/camera/color/image_raw",Image,self.callback)
        self.image_depth_sub = rospy.Subscriber("/camera/depth/image_rect_raw",Image,self.callback)

    def callback(self,data):
        try:
            cv_image = self.bridge.imgmsg_to_cv2(data,"bgr8")
        except CvBridgeError as error:
            print(error)

        cv2.imshow("ball + depth",cv_image)
        cv2.waitKey(30)

def main(args):
    v = viewer()
    rospy.init_node("image_pub",anonymous=True)
    rospy.loginfo('image_pub node started')
    try:
        rospy.spin()
    except KeyboardInterrupt:
        print("Shutting down")
    cv2.destroyAllWindows()

if __name__ == '__main__':
    try:
        main(sys.argv)
    except rospy.ROSInterruptException:
        pass


import svgwrite.extensions
import faiss
import numpy as np
import matplotlib.pyplot as plt
import svgwrite
import networkx as nx

import src.particle_utils as particle_utils

if __name__ == "__main__":
    page_size = (11 * 96, 17 * 96)
    max_iterations = 1000
    max_particles = 1000
    index_training_node_count = 100000
    grid_size = 2000
    np.random.seed(1234)
    center_bias = 0
    d = 2

    # particle radius
    p_radius = 2
    gen_radius = 2

    # Construct the index
    nlist = int(10 * np.sqrt(index_training_node_count))
    quantizer = faiss.IndexFlatL2(d)  # the other index
    index = faiss.IndexIVFFlat(quantizer, d, int(nlist))
    initial_vecs = (np.random.uniform(-1*grid_size, grid_size, (123318, 2))).astype('float32')
    index.train(initial_vecs)
    index.nprobe = 2

    # initialize the count of particles
    fixed_particles = np.zeros((1, d), dtype='float32')
    live_particles = 1
    moving_particles = particle_utils.init_moving_particles(live_particles, gen_radius, d)
    index.add(fixed_particles)

    # begin adding vectors to the index.
    a = 1
    particle_count = 1
    parent_indices = []
    i = 0
    last_particle_count = 1
    last_iteration = 0
    while particle_count < max_particles and i < max_iterations:
        i += 1
        # Increase the number of particles as the bounding circle gets larger
        if a*np.sqrt(particle_count)-5 > len(moving_particles):
            live_particles = int(np.sqrt(particle_count) * a)
            moving_particles = particle_utils.init_moving_particles(live_particles, gen_radius, d)
            print(f"Live: {live_particles:4}, Total: {particle_count:6}, on iteration {i:6} particles gained/iterations {(live_particles-last_particle_count)/(i-last_iteration)}")
            last_particle_count = live_particles
            last_iteration = i

        D, I = index.search(moving_particles, 1)
        fixing_indices = D[:, 0] < p_radius ** 2
        parent_indices.extend(I[fixing_indices])
        if any(fixing_indices):
            particle_count += sum(fixing_indices)
            fixing_particles = moving_particles[fixing_indices]
            index.add(fixing_particles)
            moving_particles, gen_radius = particle_utils.regenerate_fixed_particle(moving_particles, fixing_indices, gen_radius)
        moving_particles += np.random.normal(0, 1, (live_particles, d)).astype('float32')
        moving_particles -= moving_particles * center_bias/np.linalg.norm(moving_particles, axis=1, keepdims=True)
        moving_particles = particle_utils.regenerate_extreme_particles(moving_particles, gen_radius)

    # Reconstruct the points in the order they were added.
    index.make_direct_map()
    fixed_particles = index.reconstruct_n(0, int(particle_count)) + np.asarray(page_size)/2
    parent_indices = np.concatenate(parent_indices)
    parents = fixed_particles[parent_indices]

    # Build a graph
    G = nx.graph.Graph()
    for ind in range(len(fixed_particles)):
        G.add_node(ind)
        if ind > 0:
            G.add_edge(parent_indices[ind-1], ind)

    # Iterate over the edges of the graph
    edges = list(nx.algorithms.traversal.edgedfs.edge_dfs(G, source=0))
    grouped_edges = []
    for a_edge in edges:
        if len(grouped_edges) == 0 or grouped_edges[-1][-1] != a_edge[0]:
            grouped_edges.append(list(a_edge))
        else:
            grouped_edges[-1].append(a_edge[-1])

    # Group the nodes together
    group_strs = []
    paths = []
    fig, ax = plt.subplots()

    # Write the path
    dwg = svgwrite.Drawing("../outputs/out.svg", size=page_size)
    inkscape = svgwrite.extensions.Inkscape(dwg)
    layer = inkscape.layer()
    dwg.add(layer)
    for a_group in grouped_edges:
        curr_pnts = fixed_particles[a_group].astype('int')
        layer.add(svgwrite.shapes.Polyline(curr_pnts.tolist(),
                                           stroke="black",
                                           fill='none'))
    dwg.save()


# level: medium
# 思路：dfs 将节点设为子树和，统计出现最多的字数和

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
from collections import defaultdict

class Solution(object):
    nodes = defaultdict(int)

    def findFrequentTreeSum(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        self.nodes.clear()
        self.dfs(root)
        result = []
        vals = []
        m = -9999
        # print(self.nodes)
        for key, val in self.nodes.items():
            if val > m: m = val
        for key, val in self.nodes.items():
            if val == m:
                result.append(key)
        return result

    def dfs(self, root):
        if root == None:
            return

        if root.left != None:
            self.dfs(root.left)
            root.val += root.left.val

        if root.right != None:
            self.dfs(root.right)
            root.val += root.right.val

        self.nodes[root.val] += 1

if __name__ == '__main__':
    ans = Solution()
    print(ans.findFrequentTreeSum([5, 2, -3]))


# Section12-1
# 파이썬 데이터베이스 연동(SQLite)
# 테이블 생성 및 삽입

import datetime
import sqlite3

# 삽입 날짜 생성
now = datetime.datetime.now()
print('now', now)

nowDatetime = now.strftime('%Y-%m-%d %H:%M:%S')
print('now Datetime', nowDatetime)

# sqlite3 버전
print('sqlite3.version : ', sqlite3.version)
print('sqlite3.sqlite_version', sqlite3.sqlite_version)

print()

# DB생성 & Autocommit & Rollback
# Commit : DB에 변경사항을 반영하는 명령어
# Autocommit : 변경사항을 바로바로 DB에 반영
# Rollback : 변경사항 되돌리기

# 본인 DB 파일 경로
conn = sqlite3.connect('database/database.db', isolation_level=None)

# DB생성(메모리)
# conn = sqlite3.connect(":memory:")

# Cursor연결
c = conn.cursor()
print('Cursor Type : ', type(c))

# 테이블 생성(Datatype : TEXT NUMERIC INTEGER REAL BLOB)
c.execute(
    "CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, username text, email text, phone text, website text, regdate text)")  # AUTOINCREMENT

# 데이터 삽입
c.execute("INSERT INTO users VALUES (1 ,'Kim','Kim@naver.com', '010-0000-0000', 'Kim.com', ?)", (nowDatetime,))
c.execute("INSERT INTO users(id, username, email, phone, website, regdate) VALUES (?, ?, ?, ?, ?, ?)",
          (2, 'Park', 'Park@naver.com', '010-1111-1111', 'Park.com', nowDatetime))

# Many 삽입(튜플, 리스트)
userList = (
    (3, 'Lee', 'Lee@naver.com', '010-2222-2222', 'Lee.com', nowDatetime),
    (4, 'Cho', 'Cho@naver.com', '010-3333-3333', 'Cho.com', nowDatetime),
    (5, 'Yoo', 'Yoo@naver.com', '010-4444-4444', 'Yoo.com', nowDatetime)
)
c.executemany(
    "INSERT INTO users(id, username, email, phone, website, regdate) VALUES (?, ?, ?, ?, ?, ?)", userList)

print()

# 테이블 데이터 삭제
print("users db deleted :", conn.execute("delete from users").rowcount, "rows")

# 커밋 : isolation_level=None 일 경우 Auto Commit(자동 반영)
# conn.commit() # 자동 반영이 아닐 경우 반영 시켜주기위한 명령어

# 롤백
# conn.rollback() # Auto Commit 시에는 사용 불가

# 접속 해제
conn.close()


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

import lzma
import os
import shutil
from datetime import datetime
from datetime import timedelta

import hglib
from bugbug import bugzilla
from bugbug import labels
from bugbug import repository

from bugbug_data.secrets import secrets
from cli_common.log import get_logger
from cli_common.taskcluster import get_service
from cli_common.utils import ThreadPoolExecutorResult

logger = get_logger(__name__)

class Retriever(object):
    def __init__(self, cache_root, client_id, access_token):
        self.cache_root = cache_root

        assert os.path.isdir(cache_root), 'Cache root {} is not a dir.'.format(cache_root)
        self.repo_dir = os.path.join(cache_root, 'mozilla-central')

        self.client_id = client_id
        self.access_token = access_token

        self.index_service = get_service('index', client_id, access_token)

    def retrieve_commits(self):
        shared_dir = self.repo_dir + '-shared'
        cmd = hglib.util.cmdbuilder('robustcheckout',
                                    'https://hg.mozilla.org/mozilla-central',
                                    self.repo_dir,
                                    purge=True,
                                    sharebase=shared_dir,
                                    networkattempts=7,
                                    branch=b'tip')

        cmd.insert(0, hglib.HGPATH)

        proc = hglib.util.popen(cmd)
        out, err = proc.communicate()
        if proc.returncode:
            raise hglib.error.CommandError(cmd, proc.returncode, out, err)

        logger.info('mozilla-central cloned')

        repository.download_commits(self.repo_dir)

        logger.info('commit data extracted from repository')

        self.compress_file('data/commits.json')

    def retrieve_bugs(self):
        bugzilla.set_token(secrets[secrets.BUGZILLA_TOKEN])

        six_months_ago = datetime.utcnow() - timedelta(182)
        two_years_and_six_months_ago = six_months_ago - timedelta(365)
        logger.info('Downloading bugs from {} to {}'.format(two_years_and_six_months_ago, six_months_ago))
        bugzilla.download_bugs_between(two_years_and_six_months_ago, six_months_ago)

        logger.info('Downloading labelled bugs')
        bug_ids = labels.get_all_bug_ids()
        bugzilla.download_bugs(bug_ids)

        self.compress_file('data/bugs.json')

    def compress_file(self, path):
        with open(path, 'rb') as input_f:
            with lzma.open('{}.xz'.format(path), 'wb') as output_f:
                shutil.copyfileobj(input_f, output_f)

    def go(self):
        with ThreadPoolExecutorResult(max_workers=2) as executor:
            # Thread 1 - Download Bugzilla data.
            executor.submit(self.retrieve_bugs)

            # Thread 2 - Clone mozilla-central and retrieve commit data.
            executor.submit(self.retrieve_commits)

        # Index the task in the TaskCluster index.
        self.index_service.insertTask(
            'project.releng.services.project.{}.bugbug_data.latest'.format(secrets[secrets.APP_CHANNEL]),
            {
                'taskId': os.environ['TASK_ID'],
                'rank': 0,
                'data': {},
                'expires': (datetime.utcnow() + timedelta(31)).strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
            }
        )


from wsgiref.simple_server import make_server
from pyramid.view import view_config
from pyramid.config import Configurator

@view_config(route_name='theroute', renderer='json',request_method='POST')
def myview(request):
    import pdb; pdb.set_trace()
    return {'POST':''}

if __name__ == '__main__':
    config = Configurator()
    config.add_route('theroute', '/')
    config.scan()
    app = config.make_wsgi_app()
    server = make_server('0.0.0.0', 6543, app)
    print(server.base_environ)
    server.serve_forever()


import time

import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import datetime
import csv
import json

def get_data():
    current_time = datetime.datetime.now().strftime('%m-%d-%Y')
    with open(f'data/{current_time}_labirint.csv', 'w', newline='', encoding='utf-8-sig') as file:
        writer = csv.writer(file, delimiter=';')

        writer.writerow(
            [
                'Название книги',
                'Автор',
                'Издательство',
                'Цена без скидки',
                'Цена со скидкой',
                'Процент скидки',
                'Наличие на складе'
            ]
        )

    ua = UserAgent()
    headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,'
                  'application/signed-exchange;v=b3;q=0.9',
        'User-Agent': ua.random,
    }
    url = 'https://www.labirint.ru/genres/2498/?display=table&available=1'
    response = requests.get(url=url, headers=headers)
    soup = BeautifulSoup(response.text, 'lxml')
    pages_count = int(soup.find('div', class_='pagination-numbers').find_all('a')[-1].text.strip())
    books_data = []
    for page in range(1,pages_count + 1):
        url = f'https://www.labirint.ru/genres/2498/?display=table&available=1&page={page}'
        response = requests.get(url=url, headers=headers)
        soup = BeautifulSoup(response.text, 'lxml')
        books = soup.find('tbody', class_='products-table__body').find_all('tr')
        for book in books:
            book_data = book.find_all('td')
            try:
                book_title = book_data[0].find('a').text
                if not book_title:
                    continue
            except AttributeError:
                continue
            try:
                book_author = ', '.join(list(map(lambda link: link.text, book_data[1].find_all('a'))))
            except AttributeError:
                book_author = 'Нет автора'
            try:
                book_publisher = ': '.join(list(map(lambda publisher: publisher.text, book_data[2].find_all('a'))))
            except AttributeError:
                book_publisher = 'Нет издательства'
            try:
                old_price = int(book_data[3].find(class_='price-gray').text.replace('₽', '').replace(' ', '').strip())
            except AttributeError:
                old_price = 'Нет старой цены'
            try:
                new_price = int(book_data[3].find(class_='price-val').text.replace('₽', '').replace(' ', '').strip())
            except AttributeError:
                new_price = 'Нет новой цены'
            try:
                discount = f'{round(((old_price - new_price) / old_price) * 100, 2)} %'
            except TypeError:
                discount = 'Скидки нет'
            try:
                availability = book_data[-1].find(class_='mt3 rang-available').text.replace(' ', '').strip()
            except AttributeError:
                availability = 'Нет данных'
            books_data.append(
                {
                    'book_title': book_title,
                    'book_author': book_author,
                    'book_publisher': book_publisher,
                    'old_price': f'{old_price}₽' if type(old_price) is int else old_price,
                    'new_price': f'{new_price}₽' if type(new_price) is int else new_price,
                    'discount': discount,
                    'availability': availability,
                }
            )
            with open(f'data/{current_time}_labirint.csv', 'a', newline='', encoding='utf-8-sig') as file:
                writer = csv.writer(file, delimiter=';')

                writer.writerow(
                    [
                        book_title,
                        book_author,
                        book_publisher,
                        f'{old_price}₽' if type(old_price) is int else old_price,
                        f'{new_price}₽' if type(new_price) is int else new_price,
                        discount,
                        availability
                    ]
                )
        print(f'Обработано {page}/{pages_count} страниц')

    with open(f'data/{current_time}-labirint.json', 'w', encoding='utf-8') as file:
        json.dump(books_data, file, indent=4, ensure_ascii=False)

def main():
    start_time = time.time()
    get_data()
    diff_time = time.time() - start_time
    print(f'Затраченное время на работу скрипта - {diff_time}')

if __name__ == '__main__':
    main()


from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

X = rs_train[['price_per_ticket', 'seat_row', 'paid_full_price', 'paid_online',
       'Regular_Ticket', 'age', 'est_income', 'Male', 'married', 'fam_w_kids',
       'kids_in_house', 'from_Boston', 'from_MA','game_hour',
       'RS_v_Yankees', 'STH_Act', 'BUSINESS_STH_Act',
       'GROUP_Act', 'BUSINESS_act', 'Individual_Act', 'SPONSOR_Act',
       'EMPLOYEE_Act', 'April', 'May', 'June', 'July', 'August', 'September',
       'Thursday', 'Sunday', 'Tuesday', 'Wednesday', 'Saturday', 'Friday',
       'Monday', 'low_scale_seat', 'med_scale_seat', 'high_scale_seat']]

y = rs_train['ticket_used']
names = pd.DataFrame(X.columns)

model_fs = SelectKBest(score_func = chi2, k=4)
fs_results = model_fs.fit(X,y)

#print(fs_results.scores_)
results_df = pd.DataFrame(fs_results.scores_)
scored= pd.concat([names, results_df], axis=1)
scored.columns = ["Feature", "Score"]
scored.sort_values(by=["Score"])


from django.conf import settings
import jwt
from rest_framework import authentication, exceptions
from django.contrib.auth.models import User

class JWTAuthentication(authentication.BasicAuthentication):

    def authenticate(self, request):
        auth_data = authentication.get_authorization_header(request)

        if not auth_data:
            return None

        prefix, token = auth_data.decode('utf-8').split(' ')

        try:
            payload = jwt.decode(token, settings.JWT_SECRET, algorithms=['HS256'])

            user = User.objects.get(id=payload['id'])
            return (user, token)

        except jwt.DecodeError:
            raise exceptions.AuthenticationFailed('Invalid token')

        except jwt.ExpiredSignatureError:
            raise exceptions.AuthenticationFailed('Expired token')


import requests
from jSona import jSona
import pprint
pp = pprint.pprint

class proImagery :
    def __init__(self, CONF_PATH) :
        self.jso  = jSona()
        self.headers = {'json':{'Content-Type':'application/json; charset=utf-8'}}
        self.config = self.jso.loadJson(CONF_PATH)['IMAGERY']
        self.lower  = {color['id']:color for color in self.jso.loadJson(self.config['COLOR']['PATH'])}

    def post(self, data) :
        return requests.post(url=self.post_url, data=self.jso.dumps(data, False), headers=self.headers['json'])

    def connect(self, addr, port) :
        self.url = "{}:{}/".format(addr, port)
        self.post_url = self.url
        temp_data = {'hello':'world'}
        res = self.post(temp_data)
        return 'success' in res.content.decode()

    def segcolor(self, img_url, img_name='default.jpg', options='-d') :
        self.post_url = self.url+'segcolor'
        data = {'path' : img_url, 'name' : img_name, 'options' : options}
        res = self.post(data)
        return self.jso.loads(res.content.decode(), False)

    def ambcolor(self, colors, threshold=0.1) :
        colors = {color[0]:color[1] for color in colors}
        ambics = dict()
        for cid in colors : # brightgrayyellow
            if cid in self.lower :
                new_cid = self.lower[cid]['u']
                if new_cid in ambics : ambics[new_cid] += colors[cid]
                else                 : ambics[new_cid]  = colors[cid]
            else :
                if     cid in ambics : ambics[cid] += colors[cid]
                else                 : ambics[cid]  = colors[cid]
        return list(filter(lambda c : c[1]>threshold, ambics.items()))

    def start(self, img_url, labels=['shirt'], ambi=True, threshold=0.1, img_name='default.jpg', options='-d') :
        segments_and_colors = self.segcolor(img_url, img_name=img_name, options=options)
        if type(segments_and_colors) == type([]) :
            segments, colors = segments_and_colors[1], segments_and_colors[3]
            for sinx in range(len(segments)) :
                if set(labels)&set(self.config['LABEL'][''.join(segments[sinx].split()[:-1])]) and sinx<len(colors):
                    if ambi : return self.ambcolor(colors[sinx], threshold=threshold)
                    else    : return colors[sinx]
        return None


from dolfin import *
import math
import numpy as np
import logging
import matplotlib.pyplot as plt
from unconstrainedMinimization import InexactNewtonCG

logging.getLogger('FFC').setLevel(logging.WARNING)
logging.getLogger('UFL').setLevel(logging.WARNING)
set_log_active(False)

# Set the level of noise:
noise_std_dev = .3

# Load the image from file
data = np.loadtxt('image.dat', delimiter=',')
np.random.seed(seed=1)
noise = noise_std_dev*np.random.randn(data.shape[0], data.shape[1])

# Set up the domain and the finite element space.
Lx = float(data.shape[1])/float(data.shape[0])
Ly = 1.

mesh = RectangleMesh(Point(0,0),Point(Lx,Ly),200, 100)
V = FunctionSpace(mesh, "Lagrange",1)

# Generate the true image (u_true) and the noisy data (u_0)
class Image(Expression):
    def __init__(self, Lx, Ly, data, **kwargs):
        self.data = data
        self.hx = Lx/float(data.shape[1]-1)
        self.hy = Ly/float(data.shape[0]-1)

    def eval(self, values, x):
        j = int(math.floor(x[0]/self.hx))
        i = int(math.floor(x[1]/self.hy))
        values[0] = self.data[i,j]

trueImage = Image(Lx,Ly,data, degree=1)
noisyImage = Image(Lx,Ly,data+noise, degree=1)
u_true  = interpolate(trueImage, V)
u_0 = interpolate(noisyImage, V)

plt.figure(figsize=[12,24])
plt.subplot(1,2,1)
plot(u_true, title="True Image")
plt.subplot(1,2,2)
plot(u_0, title="Noisy Image")
plt.show()


import importlib
import sys
from unittest import mock

class MockConfig:
	def __init__(self):
		self.bot = mock.MagicMock()
		self.state = mock.Mock()

def set_up_class(cls, *module_names):
	mock_config = MockConfig()
	sys.modules['config'] = mock_config
	try:
		for module_name in module_names:
			module = importlib.import_module(module_name)
			setattr(cls, module_name, module)
	except Exception:
		del sys.modules['config']
		raise

def tear_down_class(cls):
	del sys.modules['config']