"""
中国国家统计局数据模块
作者：gansaihua
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import pandas as pd
from datetime import date
from calendar import monthrange
from .base import get_page_response, friendly_download

HOST_URL = "http://data.stats.gov.cn/easyquery.htm"

QUARTERLY_SUFFIX_MAPS = {1: 'A', 2: 'B', 3: 'C', 4: 'D'}

QUARTERLY_SUFFIX_MAPS_INV = {v: k for k, v in QUARTERLY_SUFFIX_MAPS.items()}

def _extract_date(datestr):
    year = int(datestr[:4])
    month = 12

    if len(datestr) == 5:  # quarterly
        quarter = int(QUARTERLY_SUFFIX_MAPS_INV.get(datestr[4]))
        month = quarter * 3
    elif len(datestr) == 6:  # monthly
        month = int(datestr[4:6])

    day = monthrange(year, month)[1]
    return date(year=year, month=month, day=day)

def _sanitize_date(datestr, freq):
    dt = pd.Timestamp(datestr)

    freq = freq.strip().lower()
    ret = dt.year

    if freq == 'quarterly':
        ret = '%d%s' % (ret, QUARTERLY_SUFFIX_MAPS.get(dt.quarter))
    elif freq == 'monthly':
        ret = '%d%s' % (ret, str(dt.day).zfill(2))

    return ret

def _freq_to_dbcode(freq):
    ref = {
        'monthly': 'hgyd',
        'quarterly': 'hgjd',
        'yearly': 'hgnd',
    }
    return ref.get(freq.strip().lower())

@friendly_download(times=66, duration=None, max_sleep=1)
def fetch_economics(code, start, end, freq):
    '''freq = monthly, quarterly, yearly'''
    start = _sanitize_date(start, freq)
    end = _sanitize_date(end, freq)

    date_rng = start + '-' + end

    params = {
        'm':
        'QueryData',
        'rowcode':
        'zb',
        'colcode':
        'sj',
        'wds':
        '[]',
        'dbcode':
        _freq_to_dbcode(freq),
        'dfwds':
        '[{"wdcode":"zb","valuecode":"%s"}, {"wdcode":"sj","valuecode": "%s"}]'
        % (code, date_rng),
    }

    r = get_page_response(HOST_URL, method='post', params=params)

    records = []
    labels = ['code', 'asof_date', 'value']
    for record in r.json()['returndata']['datanodes']:
        val = record['data']
        if val['hasdata']:
            code = record['wds'][0]['valuecode']
            asof_date = record['wds'][1]['valuecode']
            records.append((code, _extract_date(asof_date), val['data']))

    df = pd.DataFrame.from_records(records, columns=labels)
    return df

def get_codes(freq, node_id='zb'):
    '''freq = monthly, quarterly, yearly
   public API
   '''
    return _batch_leaf_codes(freq, node_id)

def get_categories(freq, node_id='zb'):
    ''' return the categories which are parents
   or super-parents codes of series
   node_id should be nodes which are super-parents not direct parents of leafs
   '''
    return _batch_page_codes(freq, node_id)[0]

def _batch_leaf_codes(freq, node_id='zb'):
    '''return all the codes of series which are children to the node of node_id
   default the root node'''
    ret = []

    page_codes = _batch_page_codes(freq, node_id)[1]

    if page_codes.empty:
        page_codes = [node_id]
    else:
        page_codes = page_codes['id']

    for page_code in page_codes:
        res = _get_leaf_codes(freq, page_code)
        ret.append(res)

    if ret:
        ret = pd.concat(ret)
    else:
        ret = pd.DataFrame()
    return ret

@friendly_download(times=66, duration=None, max_sleep=1)
def _get_leaf_codes(freq, page_code):
    '''return list of code which directly denotes a series
   page_code should be the node which are direct parent to leafs'''
    params = {
        'm': 'QueryData',
        'rowcode': 'zb',
        'colcode': 'sj',
        'wds': '[]',
        'dbcode': _freq_to_dbcode(freq),
        'dfwds': '[{"wdcode":"zb","valuecode":"%s"}]' % page_code,
    }

    r = get_page_response(HOST_URL, method='post', params=params)

    res = r.json()

    records = []
    for cval in res['returndata']['wdnodes'][0]['nodes']:
        code = cval['code']
        cname = cval['cname']
        unit = cval['unit']
        row = (code, cname, unit)
        records.append(row)

    labels = ['code', 'cname', 'unit']
    df = pd.DataFrame.from_records(records, columns=labels)

    return df

def _batch_page_codes(freq, node_id='zb'):
    '''freq = monthly, quarterly, yearly
   return all the final tree nodes which can be scrolled
   '''
    nodes = []
    parents_of_leafs = []

    queue = _get_page_codes(freq, node_id)
    while not queue.empty:
        is_parent = queue['isParent']

        parents_of_leafs.append(queue[~is_parent])

        queue = queue[is_parent]
        nodes.append(queue.copy())

        ids = queue['id']
        for nid in ids:
            row_to_remove = (queue['id'] == nid)
            queue = queue[~row_to_remove]

            queue = queue.append(_get_page_codes(node_id=nid, freq=freq),
                                 ignore_index=True)
    if nodes:
        nodes = pd.concat(nodes)
    else:
        nodes = pd.DataFrame()

    if parents_of_leafs:
        parents_of_leafs = pd.concat(parents_of_leafs)
    else:
        parents_of_leafs = pd.DataFrame()

    nodes = pd.concat([nodes, parents_of_leafs], ignore_index=True)

    return (nodes, parents_of_leafs)

@friendly_download(times=33, duration=None, max_sleep=1)
def _get_page_codes(freq='quarterly', node_id='zb'):
    '''default: the children of the root
   return the direct children to the node_id'''
    params = {
        'id': node_id,
        'dbcode': _freq_to_dbcode(freq),
        'wdcode': 'zb',
        'm': 'getTree',
    }

    r = get_page_response(HOST_URL, method='post', params=params)

    return pd.DataFrame.from_records(r.json())


import self_organizing_map

# For plotting the images
from matplotlib import pyplot as plt
import numpy as np

# Training inputs for Building a Grid
training_set = np.array(
    [[0.2, 0.0],
     [0.0, 0.8],
     [1.0, 1.4],
     [1.125, 1.0],
     [1.33, 0.4],
     [1.6, 0.5],
     [0.0, 1.0],
     [1.0, 0.4],
     [1.9, 0.2],
     [0.8, 1.7],
     [0.0, 0.2],
     [0.2, 0.9],
     [0.33,1.33],
     [1.5, 1.5],
     [.66, 1.66]])
#color_names = \
#    ['black', 'blue', 'darkblue', 'skyblue',
#     'greyblue', 'lilac', 'green', 'red',
#     'cyan', 'violet', 'yellow', 'white',
#     'darkgrey', 'mediumgrey', 'lightgrey']

# Train a 20x30 SOM with 400 iterations

som = self_organizing_map.SOM(20, 30, 2, 400)
som.train(training_set)

# Get output grid
image_grid = som.get_centroids()

x = np.array([])
y = np.array([])

for i in range(len(image_grid)):  #seperate x and y values into separate arrays for easy plotting
    x = np.append(x,image_grid[0][i][0])

for i in range(len(image_grid)):
    y = np.append(y, image_grid[0][i][1])

plt.scatter(x ,y)

# Map colours to their closest neurons
# mapped = som.map_vects(training_set)

# Plot
# plt.imshow(image_grid)
# plt.title('Grid SOM')
# for i, m in enumerate(mapped):
#     plt.text(m[1], m[0], color_names[i], ha='center', va='center',
#              bbox=dict(facecolor='white', alpha=0.5, lw=0))
plt.show()


import os
import sys
import logging
import asyncio

from aiogram import Bot, Dispatcher, Router, F
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
from aiogram.filters import CommandStart
from aiogram.types import ErrorEvent, Message, CallbackQuery

from gpt_connector import GPTConnector, define_name_chat
from database import orm
from database.redis_helper import RedisHelper
from bot_markup import MAIN_MENU, END_CHAT, ENDED_CHAT, EXTRACT_CODE, CREATE_GISTS, forming_inline_lists
from tools.message_formater import MessageFormatter, extracting_code, base_context, forming_message
from tools.gist_creator import GistCreator

logging.basicConfig(level=logging.INFO, stream=sys.stdout)
logger = logging.getLogger(__name__)

bot_token = os.getenv('BOT_TOKEN')
admin_id = os.getenv('ADMIN')

router = Router()

cli = RedisHelper()

class Chat(StatesGroup):
    content = State()

class CustomContext(StatesGroup):
    content = State()

class DecissionChat(StatesGroup):
    content = State()

@router.message(CommandStart())
async def start_message(message: Message) -> None:
    orm.add_user(message.from_user.id)
    text = f'Привет {message.from_user.first_name}, я бот, который поможет тебе взаимодействовать с ChatGPT'
    await message.answer(text, reply_markup=MAIN_MENU)

@router.message(F.text == 'Новый чат - базовый контекст')
async def new_base_chat(message: Message, state: FSMContext) -> None:
    await state.set_state(Chat.content)
    cli.set(message.from_user.id, base_context)
    await message.answer(text='Погнали', reply_markup=END_CHAT)

@router.message(F.text == 'Новый чат - свой контекст')
async def custom_context(message: Message, state: FSMContext) -> None:
    await state.set_state(CustomContext.content)
    await message.answer('Какой контекст задать?')

@router.message(CustomContext.content)
async def new_base_chat(message: Message, state: FSMContext) -> None:
    await state.update_data(content=message.text)
    await state.set_state(Chat.content)
    cli.set(message.from_user.id, forming_message(role='system', text=message.text))
    await message.answer(text='Погнали', reply_markup=END_CHAT)

@router.message(F.text == 'Список сохранённых чатов')
async def get_list_contexts(message: Message):
    contexts = orm.get_list_contexts_by_user(message.from_user.id)
    if len(contexts) > 0:
        markup = forming_inline_lists(contexts)
        await message.answer(text='Вот список твоих контекстов', reply_markup=markup)
    else:
        await message.answer('У тебя нет сохранённых контекстов')

@router.callback_query()
async def choose_chat(callback_query: CallbackQuery, state: FSMContext):
    await state.set_state(Chat.content)
    user_id = callback_query.from_user.id
    await callback_query.answer(callback_query.id)
    chat = orm.get_context(user_id, ctx_id=callback_query.data)
    cli.set(user_id, chat.content)
    cli.set(key=f'{user_id}_active', value=chat.name)
    await callback_query.answer(text=f'Погнали!', reply_markup=END_CHAT)

@router.message(Chat.content)
async def chating(message: Message, state: FSMContext):
    await state.update_data(content=message.text)
    user_id = message.from_user.id

    if message.text == 'Завершить чат':
        await message.answer(text='Сохранить текущую беседу или удалить?', reply_markup=ENDED_CHAT)
        await state.clear()
        await state.set_state(DecissionChat.content)

    elif message.text == 'Вытащи код':
        # Достаем из редиса последнее сообщение
        chat = cli.get(user_id)
        last_msg = chat[-1]
        just_code = extracting_code(last_msg['content'])

        chat.append(forming_message(role='assistant', text=just_code))
        cli.set(user_id, chat)

        await message.answer(text=just_code, reply_markup=CREATE_GISTS)
        await state.clear()
        await state.set_state(Chat.content)

    elif message.text == 'Создай gists':
        last_msg = cli.get(user_id)[-1]
        url = GistCreator(last_msg['content']).post()
        await message.answer(text=url, reply_markup=END_CHAT)
        await state.clear()
        await state.set_state(Chat.content)

    else:
        if cli.get(f'{user_id}_active') is None:
            cli.set(key=f'{user_id}_active', value=define_name_chat(message.text))
        chat = cli.get(user_id)
        chat = [chat] if isinstance(chat, dict) else chat
        chat.append(forming_message(role='user', text=message.text))
        answer, tokens = GPTConnector(chat).run()

        answer, its_a_code = MessageFormatter(answer).formating()

        chat.append(forming_message(role='assistant', text=answer))
        cli.set(user_id, chat)

        # Для сообщений с кодом добавляем в менюшку
        # кнопку с просьбой вернуть только код
        markup = EXTRACT_CODE if its_a_code else END_CHAT

        await message.answer(answer, reply_markup=markup)
        await state.clear()
        await state.set_state(Chat.content)

@router.message(DecissionChat.content)
async def decission_end_context(message: Message, state: FSMContext):
    user_id = message.from_user.id
    name_chat = cli.get(f'{user_id}_active')
    if message.text == 'Сохранить':
        chat = cli.get(user_id)
        orm.save_context(user_id, name_chat, chat)
        cli.delete(user_id)
        cli.delete(f'{user_id}_active')
        await state.clear()
        await message.answer(text='Сохранил, можешь начать новый диалог', reply_markup=MAIN_MENU)
    elif message.text == 'Удалить':
        cli.delete(user_id)
        cli.delete(f'{user_id}_active')
        orm.delete_user_context(user_id, name_chat)
        await state.clear()
        await message.answer(text='Удалил, можешь начать новый диалог', reply_markup=MAIN_MENU)

async def main():
    bot = Bot(token=bot_token)

    @router.errors()
    async def error_handler(exception: ErrorEvent) -> None:
        await bot.send_message(
            chat_id=admin_id,
            text=f'Там всё упало - {type(exception).__name__}: {exception}'
        )

    dp = Dispatcher()
    dp.include_router(router)

    await dp.start_polling(bot)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    asyncio.run(main())


#Given an array arr of positive integers sorted in a strictly increasing order, and an integer k.
#Find the kth positive integer that is missing from this array.

arr = [2,3,4,7,11]
k = 5

def kth_missing_positive_number(numbers, k):
    '''
    INPUT: List of numbers in increating order & a positive integer k
    OUTPUT: The kth missing number
    '''
    missing_nums = []
    new_range = max(numbers) + k + 1

    for i in range(new_range):
        if i not in numbers:
            missing_nums.append(i)
    return missing_nums[k]

print(kth_missing_positive_number(arr, k))

def kth_missing_positive_number(numbers, k):
    '''
    INPUT: List of numbers in increating order & a positive integer k
    OUTPUT: The kth missing number'''

    expected = 1
    missing_count = 0

    for number in numbers:
        while expected != number:
            missing_count += 1
            if missing_count == k:
                return expected
            expected += 1

    while missing_count < 1:
        expected += 1
        missing_count +=1

    return expected


import gym
import torch
import numpy as np
from typing import Any, Callable, Dict, List, Union, Tuple

from syllabus.curricula.plr import TaskSampler
from syllabus.core import Curriculum, UsageError, enumerate_axes
from syllabus.task_space import TaskSpace

class RolloutStorage(object):
    def __init__(self, num_steps: int, num_processes: int, requires_value_buffers: bool, action_space: gym.Space = None):
        self._requires_value_buffers = requires_value_buffers
        self.tasks = torch.zeros(num_steps, num_processes, 1, dtype=torch.int)
        self.masks = torch.ones(num_steps + 1, num_processes, 1)

        if requires_value_buffers:
            self.returns = torch.zeros(num_steps + 1, num_processes, 1)
            self.rewards = torch.zeros(num_steps, num_processes, 1)
            self.value_preds = torch.zeros(num_steps + 1, num_processes, 1)
        else:
            if action_space is None:
                raise ValueError("Action space must be provided to PLR for strategies 'policy_entropy', 'least_confidence', 'min_margin'")
            self.action_log_dist = torch.zeros(num_steps, num_processes, action_space.n)

        self.num_steps = num_steps
        self.step = 0

    def to(self, device):
        self.masks = self.masks.to(device)
        self.tasks = self.tasks.to(device)
        if self._requires_value_buffers:
            self.rewards = self.rewards.to(device)
            self.value_preds = self.value_preds.to(device)
            self.returns = self.returns.to(device)
        else:
            self.action_log_dist = self.action_log_dist.to(device)

    def insert(self, masks, action_log_dist=None, value_preds=None, rewards=None, tasks=None):
        if self._requires_value_buffers:
            assert value_preds is not None and rewards is not None, f"Selected strategy {self._requires_value_buffers} requires value_preds and rewards"
            if len(rewards.shape) == 3:
                rewards = rewards.squeeze(2)
            self.value_preds[self.step].copy_(torch.as_tensor(value_preds))
            self.rewards[self.step].copy_(torch.as_tensor(rewards)[:, None])
            self.masks[self.step + 1].copy_(torch.as_tensor(masks)[:, None])
        else:
            self.action_log_dist[self.step].copy_(action_log_dist)
        if tasks is not None:
            assert isinstance(tasks[0], int), "Provided task must be an integer"
            self.tasks[self.step].copy_(torch.as_tensor(tasks)[:, None])
        self.step = (self.step + 1) % self.num_steps

    def after_update(self):
        self.masks[0].copy_(self.masks[-1])

    def compute_returns(self,
                        next_value,
                        gamma,
                        gae_lambda):
        self.value_preds[-1] = next_value
        gae = 0
        for step in reversed(range(self.rewards.size(0))):
            delta = self.rewards[step] + gamma * self.value_preds[step + 1] * self.masks[step + 1] - self.value_preds[step]
            gae = delta + gamma * gae_lambda * self.masks[step + 1] * gae
            self.returns[step] = gae + self.value_preds[step]

class PrioritizedLevelReplay(Curriculum):
    REQUIRES_STEP_UPDATES = False
    REQUIRES_CENTRAL_UPDATES = True
    def __init__(self,
                 task_space: TaskSpace,
                 *curriculum_args,
                 task_sampler_kwargs_dict: dict = {},
                 action_space: gym.Space = None,
                 device: str = "cuda",
                 num_steps: int = 256,
                 num_processes: int = 64,
                 gamma: float = 0.999,
                 gae_lambda: float = 0.95,
                 suppress_usage_warnings=False,
                 **curriculum_kwargs):
        self._strategy = task_sampler_kwargs_dict.get("strategy", None)
        if not isinstance(task_space.gym_space, gym.spaces.Discrete) and not isinstance(task_space.gym_space, gym.spaces.MultiDiscrete):
            raise ValueError(f"Task space must be discrete or multi-discrete, got {task_space.gym_space}.")
        if "num_actors" in task_sampler_kwargs_dict:
            print(f"Overwriting 'num_actors' {task_sampler_kwargs_dict['num_actors']} in task sampler kwargs with PLR num_processes {num_processes}.")

        task_sampler_kwargs_dict["num_actors"] = num_processes
        super().__init__(task_space, *curriculum_args, **curriculum_kwargs)
        self._num_steps = num_steps             # Number of steps stored in rollouts and used to update task sampler
        self._num_processes = num_processes     # Number of parallel environments
        self._gamma = gamma
        self._gae_lambda = gae_lambda
        self._supress_usage_warnings = suppress_usage_warnings
        #self.tasks = self._enumerate_tasks(task_space)
        self._task2index = {task: i for i, task in enumerate(self.tasks)}
        self._task_sampler = TaskSampler(self.tasks, action_space=action_space, **task_sampler_kwargs_dict)
        self._rollouts = RolloutStorage(self._num_steps, self._num_processes, self._task_sampler.requires_value_buffers, action_space=action_space)
        self._rollouts.to(device)
        self.num_updates = 0    # Used to ensure proper usage
        self.num_samples = 0    # Used to ensure proper usage

    def update_on_demand(self, metrics: Dict):
        """
        Update the curriculum with arbitrary inputs.
        """
        self.num_updates += 1
        try:
            masks = metrics["masks"]
            tasks = metrics["tasks"]
            tasks = [self._task2index[t] for t in tasks]
        except KeyError as e:
            raise KeyError("Missing or malformed PLR update. Must include 'masks', and 'tasks'") from e

        # Parse optional update values (required for some strategies)
        value = next_value = rew = action_log_dist = None
        if self._task_sampler.requires_value_buffers:
            if "value" not in metrics or "rew" not in metrics:
                raise KeyError(f"'value' and 'rew' must be provided in every update for the strategy {self._strategy}.")
            value = metrics["value"]
            rew = metrics["rew"]
        else:
            if "action_log_dist" not in metrics:
                raise KeyError(f"'action_log_dist' must be provided in every update for the strategy {self._strategy}.")
            action_log_dist = metrics["action_log_dist"]

        # Update rollouts
        self._rollouts.insert(masks, action_log_dist=action_log_dist, value_preds=value, rewards=rew, tasks=tasks)

        # Update task sampler
        if self._rollouts.step == 0:
            if self._task_sampler.requires_value_buffers:
                if "next_value" not in metrics:
                    raise KeyError("'next_value' must be provided in the update every {self.num_steps} steps for the strategy {self._strategy}.")
                next_value = metrics["next_value"]
                self._rollouts.compute_returns(next_value, self._gamma, self._gae_lambda)
            self._task_sampler.update_with_rollouts(self._rollouts)
            self._rollouts.after_update()
            self._task_sampler.after_update()

    def _sample_distribution(self) -> List[float]:
        """
        Returns a sample distribution over the task space.
        """
        return self._task_sampler.sample_weights()

    def sample(self, k: int = 1) -> Union[List, Any]:
        self.num_samples += 1
        return [self._task_sampler.sample() for k in range(k+1)]

    def update_on_step(self, obs, rew, done, info) -> None:
        """
        Update the curriculum with the current step results from the environment.
        """
        raise NotImplementedError("PrioritizedLevelReplay does not support the step updates. Use on_demand from the learner process.")

    def update_on_step_batch(self, step_results: List[Tuple[int, int, int, int]]) -> None:
        """
        Update the curriculum with a batch of step results from the environment.
        """
        raise NotImplementedError("PrioritizedLevelReplay does not support the step updates. Use on_demand from the learner process.")

    def update_on_episode(self, episode_return: float, trajectory: List = None) -> None:
        """
        Update the curriculum with episode results from the environment.
        """
        raise NotImplementedError("PrioritizedLevelReplay does not support the episode updates. Use on_demand from the learner process.")

    def update_task_progress(self, task: Any, success_prob: float) -> None:
        """
        Update the curriculum with a task and its success probability upon
        success or failure.
        """
        if not self._supress_usage_warnings and self.num_updates == 0 and self.num_samples > self._num_processes * 2:
            raise UsageError("PLR has not been updated yet. Please call update_curriculum() in your learner process.")

    def _enumerate_tasks(self, space):
        assert isinstance(space, gym.spaces.Discrete) or isinstance(space, gym.spaces.MultiDiscrete), f"Unsupported task space {space}: Expected Discrete or MultiDiscrete"
        if isinstance(space, gym.spaces.Discrete):
            return list(range(space.n))
        else:
            return list(enumerate_axes(space.nvec))


import pandas as pd
from selenium import webdriver
# from selenium.webdriver.common.keys import keys
from time import sleep, strftime
# import SMS
from random import randint # sleep random intervals
import SMS

# create class variable
class GPUBot(object):

    """
    Create selenium class to navigate to gamestop.com. From there, should the
    availability of the 3080 GPU change, the bot will send a message to the desired
    recepient
    """

    def __init__(self):
        url = 'https://www.gamestop.com/video-games/pc/components/graphics-cards/products/geforce-rtx-3080-10-gb-gddr6x-strix-graphic-card/11112926.html?condition=New'

        # launch chrome browser
        self.driver = webdriver.Chrome(r'C:\bin\chromedriver.exe')
        self.driver.get(url)
        sleep(randint(2, 10)) # sleep randim interval

    def get_availability(self):
        available = self.driver.find_element_by_xpath('//*[@id="primary-details"]/div[4]/div[13]/div[3]/div/div[1]/button').get_attribute('innerHTML')

        if available != 'Not Available':
            SMS.sendMessage()
        else:
            sleep(randint(2, 120)) # sleep
            self.driver.refresh()
            self.get_availability()

# run bot
GPUBot().get_availability()


#儲存檔案
# file=open("data.txt",mode="w",encoding="utf-8")
# file.write("""helloworld
# 123
# abc
# 中文成功""")
# file.close()
# with open("data.txt",mode="w",encoding="utf-8") as file:
#     file.write("5\n3")

#讀取檔案
# sum=0
# with open("data.txt",mode="r",encoding="utf-8") as file:
#     data=file.read()
#     for line in file:
#         sum=sum+int(line)
# print(data)
# print(sum)

#使用json
import json
with open("config.json",mode="r") as file:
    data=json.load(file)
print(data) #data是一個字典
# print("name:",data["name"])
# print("version:",data["version"])
data["name"]="new name"
with open("config.json",mode="w") as file:
    json.dump(data,file) #複寫json


def solution(n, lost, reserve):
    set_reserve = set(reserve) - set(lost)
    set_lost = set(lost) - set(reserve)
    for i in set_reserve:
        if i-1 in set_lost:
            set_lost.remove(i - 1)
        elif i+1 in set_lost:
            set_lost.remove(i + 1)
    return n-len(set_lost)

'''
틀린 이유 파악 중
    answer = n - len(lost)

    for i in range(len(lost)):
        if lost[i] in reserve:
            reserve.remove(lost[i])
            lost.remove(lost[i])
            answer -= 1

        if lost[i] + 1 <= n:
            if lost[i] + 1 in reserve:
                answer += 1
                reserve.remove(lost[i] + 1)
                # print(reserve)

        elif lost[i] -1 >= 1:
            if lost[i] - 1 in reserve:
                answer += 1
                reserve.remove(lost[i] - 1)
                # print(reserve)

    return answer
'''

print(solution(5, [2, 4], [1, 3, 5]))
print(solution(5, [2, 4], [3]))
print(solution(3, [3], [1]))


# @Author:srattigan
# @Date:2020-12-13 21:07:42
# @LastModifiedBy:srattigan
# @Last Modified time:2020-12-13 22:08:18

# When we "execute" a python file, it is compiled to bytecode and
# then "run" through the python interpreter.

# imports
import dis  # disassembler
import types

# -- classes and functions

class BankAccount:
    """Generic Bank Account
    """
    acc_num = 100000

    def __init__(self, name, balance=0):
        self.name = name
        self.balance = balance
        self.account_num = self.acc_num
        BankAccount.acc_num += 1

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        self.balance -= amount

    def __str__(self):
        rep = f"Bankaccount for {self.name}"
        rep += f"\n\tAcc Num: {self.account_num}"
        rep += f"\n\tBalance: {self.balance}"
        return rep

def simple(n=3.0):
    """Simple demo func

    Args:
        n (float, optional): just a number. Defaults to 3.0.

    Returns:
        num: the arg squared
    """
    return n ** 2

def dict_gen(str_list, num_list):
    """Creates a dict given two lists
    Precondition: Assumes lists are of equal length

    Args:
        str_list (list of str): strs
        num_list (list of num): num

    Returns:
        dict: dict of str: num
    >>> dict_gen(['Ten', 'Twenty', 'Thirty'], [10, 20, 30])
    {'Ten': 10, 'Twenty': 20, 'Thirty': 30}
    """
    assert len(str_list) == len(num_list), "Lists must be same length"
    new_dict = {}  # makes empty dict
    for idx in range(len(str_list)):
        new_dict[str_list[idx]] = num_list[idx]
    return new_dict

def view_internals(objs, func):
    """[summary]

    Args:
        objs (list of objects): may be functions or classes
        func (function): the function to apply to the list of obj
    """
    print("--- PROCESSING OBJECTs ---")
    for obj in objs:
        print(func(obj))
        if isinstance(obj, types.FunctionType):
            print("Here's the code's underlying binary:")
            print(obj.__code__.co_code)
        input("\tPress Enter to proceed...")

if __name__ == "__main__":
    objs = [simple, dict_gen, BankAccount]
    view_internals(objs, dis.dis)


from __future__ import division

import numpy as np

from chainercv.utils.mask.mask_to_bbox import mask_to_bbox
from chainercv.visualizations.colormap import voc_colormap
from chainercv.visualizations import vis_image

def vis_instance_segmentation(
        img, mask, label=None, score=None, label_names=None,
        instance_colors=None, alpha=0.7, ax=None):
    """Visualize instance segmentation.

    Example:

        This example visualizes an image and an instance segmentation.

        >>> from chainercv.datasets import SBDInstanceSegmentationDataset
        >>> from chainercv.datasets \
        ...     import sbd_instance_segmentation_label_names
        >>> from chainercv.visualizations import vis_instance_segmentation
        >>> import matplotlib.pyplot as plt
        >>> dataset = SBDInstanceSegmentationDataset()
        >>> img, mask, label = dataset[0]
        >>> vis_instance_segmentation(
        ...     img, mask, label,
        ...     label_names=sbd_instance_segmentation_label_names)
        >>> plt.show()

        This example visualizes an image, an instance segmentation and
        bounding boxes.

        >>> from chainercv.datasets import SBDInstanceSegmentationDataset
        >>> from chainercv.datasets \
        ...     import sbd_instance_segmentation_label_names
        >>> from chainercv.visualizations import vis_bbox
        >>> from chainercv.visualizations import vis_instance_segmentation
        >>> from chainercv.visualizations.colormap import voc_colormap
        >>> from chainercv.utils import mask_to_bbox
        >>> import matplotlib.pyplot as plt
        >>> dataset = SBDInstanceSegmentationDataset()
        >>> img, mask, label = dataset[0]
        >>> bbox = mask_to_bbox(mask)
        >>> colors = voc_colormap(list(range(1, len(mask) + 1)))
        >>> ax = vis_bbox(img, bbox, label,
        ...     label_names=sbd_instance_segmentation_label_names,
        ...     instance_colors=colors, alpha=0.7, linewidth=0.5)
        >>> vis_instance_segmentation(
        ...     None, mask, instance_colors=colors, alpha=0.7, ax=ax)
        >>> plt.show()

    Args:
        img (~numpy.ndarray): An array of shape :math:`(3, H, W)`.
            This is in RGB format and the range of its value is
            :math:`[0, 255]`. If this is :obj:`None`, no image is displayed.
        mask (~numpy.ndarray): A bool array of shape
            :math`(R, H, W)`.
            If there is an object, the value of the pixel is :obj:`True`,
            and otherwise, it is :obj:`False`.
        label (~numpy.ndarray): An integer array of shape :math:`(R, )`.
            The values correspond to id for label names stored in
            :obj:`label_names`.
        score (~numpy.ndarray): A float array of shape :math:`(R,)`.
             Each value indicates how confident the prediction is.
             This is optional.
        label_names (iterable of strings): Name of labels ordered according
            to label ids.
        instance_colors (iterable of tuple): List of colors.
            Each color is RGB format and the range of its values is
            :math:`[0, 255]`. The :obj:`i`-th element is the color used
            to visualize the :obj:`i`-th instance.
            If :obj:`instance_colors` is :obj:`None`, the default color map
            is used.
        alpha (float): The value which determines transparency of the figure.
            The range of this value is :math:`[0, 1]`. If this
            value is :obj:`0`, the figure will be completely transparent.
            The default value is :obj:`0.7`. This option is useful for
            overlaying the label on the source image.
        ax (matplotlib.axes.Axis): The visualization is displayed on this
            axis. If this is :obj:`None` (default), a new axis is created.

    Returns:
        matploblib.axes.Axes: Returns :obj:`ax`.
        :obj:`ax` is an :class:`matploblib.axes.Axes` with the plot.

    """
    # Returns newly instantiated matplotlib.axes.Axes object if ax is None
    ax = vis_image(img, ax=ax)

    bbox = mask_to_bbox(mask)

    if len(bbox) != len(mask):
        raise ValueError('The length of mask must be same as that of bbox')
    if label is not None and len(bbox) != len(label):
        raise ValueError('The length of label must be same as that of bbox')
    if score is not None and len(bbox) != len(score):
        raise ValueError('The length of score must be same as that of bbox')

    n_inst = len(bbox)
    if instance_colors is None:
        instance_colors = voc_colormap(list(range(1, n_inst + 1)))
    instance_colors = np.array(instance_colors)

    _, H, W = mask.shape
    canvas_img = np.zeros((H, W, 4), dtype=np.uint8)
    for i, (bb, msk) in enumerate(zip(bbox, mask)):
        # The length of `colors` can be smaller than the number of instances
        # if a non-default `colors` is used.
        color = instance_colors[i % len(instance_colors)]
        rgba = np.append(color, alpha * 255)
        bb = np.round(bb).astype(np.int32)
        y_min, x_min, y_max, x_max = bb
        if y_max > y_min and x_max > x_min:
            canvas_img[msk] = rgba

        caption = []
        if label is not None and label_names is not None:
            lb = label[i]
            if not (0 <= lb < len(label_names)):
                raise ValueError('No corresponding name is given')
            caption.append(label_names[lb])
        if score is not None:
            sc = score[i]
            caption.append('{:.2f}'.format(sc))

        if len(caption) > 0:
            ax.text((x_max + x_min) / 2, y_min,
                    ': '.join(caption),
                    style='italic',
                    bbox={'facecolor': color / 255, 'alpha': alpha},
                    fontsize=8, color='white')

    ax.imshow(canvas_img)
    return ax


import random

class Round_info:
    def __init__(self, game_room):
        self.deck = self.shuffle_deck()
        self.hand = {}
        self.support_card = self.deck.pop()
        self.survivors = self.judge_survivors(game_room)
        self.first_player = self.set_first_player(game_room)
        self.turn = self.first_player
        self.temp_card = None
        self.caller = []
        self.main_channel = game_room.main_channel
        self.members = game_room.members
        self.pot = 0

    def shuffle_deck(self):
        deck = list(range(1,16))
        random.shuffle(deck)
        return deck

    def judge_survivors(self, game_room):
        survivors = []
        for player in game_room.members:
            if game_room.chips[player] > 0:
                survivors.append(player)
        return survivors

    def deal_cards(self):
        for survivor in self.survivors:
            self.hand[survivor] = self.deck.pop()

    def set_first_player(self, game_room):
        first_player = game_room.members[game_room.index_of_first_player]
        game_room.index_of_first_player = (game_room.index_of_first_player + 1) % len(game_room.members)
        while game_room.members[game_room.index_of_first_player] not in self.survivors:
            game_room.index_of_first_player = (game_room.index_of_first_player + 1) % len(game_room.members)
        return first_player

    def next_turn(self):
        if self.turn in self.survivors:
            index = self.survivors.index(self.turn)
            self.turn = self.survivors[(index + 1) % len(self.survivors)]
        else:
            index = self.members.index(self.turn)
            self.turn = self.members[(index + 1) % len(self.members)]
            while self.turn not in self.survivors:
                index = (index + 1) % len(self.members)
                self.turn = self.members[(index + 1) % len(self.members)]


""" Utility functions for data manipulation """
import pandas as pd
import numpy as np
from functools import reduce
import datetime
from sklearn.metrics.pairwise import cosine_similarity
import scipy.stats

def space_stripper(df):
	df_obj = df.select_dtypes(['object'])
	df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())
	return df

def get_status(hco_id):
	'''
	: param hco_id: a pandas series of hospital id
	'''
	x = hco_id.apply(lambda x: 1 if isinstance(x, str) else 0)
	return x

def get_df_subset(data, to_slice, slicer_list):
	sub = data[data[to_slice].isin(slicer_list)].reset_index(drop = True)
	return sub

def classify_user(sessions, complete_registration):
	'''
	rule-based classification of all users
	:param sessions: count of visits made by any user w/o full registration info
	:param complete_registration: boolean indicator for whether a user has fully completed registration
	'''
	if (sessions <= 2 and complete_registration == 1):
		# 已注册，活跃不到两次
		category = 'B'
	elif (sessions > 2 and complete_registration == 1):
		# 已注册，活跃多次
		category = 'D'
	elif (sessions <= 2 and complete_registration == 0):
		# 未注册，活跃多次
		category = 'A'
	else:
		# 未注册，活跃多次
		category = 'C'

	return pd.Series(category)

def get_reddit(user_df, user_type, user_identifier, log_data, content_identifier):
	'''
	: for a subset type of user, return the list of articles one read and a dataframe of contents that he had read
	'''
	user_sublist = user_df[user_df['type'] == user_type][user_identifier].unique().tolist()
	user_sublist_reddit = log_data[log_data[user_identifier].isin(user_sublist)][content_identifier].unique().tolist()
	user_sublist_log = log_data[log_data[user_identifier].isin(user_sublist)]

	return user_sublist, user_sublist_reddit, user_sublist_log

def get_rec_pool(user_sublist, reddit, df, id_):
	'''
	'''
	x1 = df[0][df[0][id_[0]].isin(user_sublist)][id_[1]].unique()
	x2 = df[1][df[1][id_[1]].isin(x1)][id_[2]].unique()
	x3 = df[2][df[2][id_[2]].isin(x2)][id_[3]].unique()
	x4 = df[3][df[3][id_[3]].isin(x3)][id_[4]].unique()
	y = list(set(x4) - set(reddit))
	return y

def remove_outlier(data, m = 5):
	'''
	: param duration: a pandas series of seconds spent on a unique article
	'''
	return (data[abs(data - np.mean(data)) < m*np.std(data)])

def get_user_label_matrix(log_data, label_matrix, identifier, behavior_measure):
	'''
	: output user-content label matrix with an extra param column of attention score
	'''
	x = log_data.merge(label_matrix, how = 'left')
	attention_base = x.groupby(identifier, as_index = False)[behavior_measure].transform(lambda x: x/x.max())['duration'].values # convert the single-col df to an aaray for binning
	attention_bin = np.digitize(attention_base, np.linspace(0, 1, 5))
	x['attention_bin'] = attention_bin.astype(int)

	return x

def get_label_score(user_label_matrix, identifier, list_labels, user_sublist):
	'''
	: output user-user similarity matrix
	'''
	user_label_matrix[user_label_matrix == 0] = np.nan
	score = user_label_matrix.groupby(identifier)[list_labels].mean().reset_index()
	score = score.fillna(0)
	sim = cosine_similarity(score[list_labels])
	sim = pd.DataFrame(sim, columns = user_sublist, index = user_sublist)

	return sim

def get_k_neighbors(sim_matrix, k):
	'''
	: for each of the user on our to-be_nudged list, output top K neighbors who behave alike
	'''
	x = sim_matrix.apply(lambda x: pd.Series(x.nlargest(k+1).index))
	x = x.loc[1:, :] # exclude the user himself

	return x

def output_rec_pool(user_sublist, knn_sublist, log_data, user_identifier, content_identifier, global_buzz):
	'''
	: for each of the user on our to-be_nudged list, output top K neighbors who behave alike
	'''
	rec_pool = []
	for i in range(len(user_sublist)):
		x = user_sublist[i]
		reddit = log_data[log_data[user_identifier] == x][content_identifier]
		x_knn = knn_sublist[x] # retrieve knn for user i
		rec_from_knn = log_data[log_data[user_identifier].isin(x_knn)][content_identifier]
		rec_set = list(set(rec_from_knn) - set(reddit))
		rec_set_sort = [i for i in global_buzz if i in rec_set]
		rec_pool.append(rec_set_sort)

	return rec_pool

def output_rec_list(list_user, nested_list_content):
	'''
	: param user_id: a list of users to receive a list of recommended goodies
	: param list_rec: a list of goodies to the target user
	'''
	if len(list_user) > 0:
		x = list(map(lambda x, y: [x] + y, list_user, nested_list_content))
	else:
		x = [] # return an empty list of recommendations when there's no user falling into the class
	return x

def output_rec_dict(list_user, nested_list_content):
	'''
	: param user_id: a list of users to receive a list of recommended goodies
	: param list_rec: a list of goodies to the target user
	'''
	if len(list_user) > 0:
		x = list(map(lambda x, y: {x:y}, list_user, nested_list_content))
	else:
		x = [] # return an empty list of recommendations when there's no user falling into the class
	return x

def output_rec_global(list_user, global_buzz):
	'''
	: param user_id: a list of users to receive a list of recommended goodies (global popular ones)
	'''
	output_dict = []
	for i in range(len(list_user)):
		try:
			x = {list_user[i]: global_buzz}
			output_dict.append(x)
		except:
			pass

	return output_dict

def get_pivoted(data, index_, col_, value_, na_replacer = 0):
	'''
	: param: data to be transposed (2-dimensional)
	: param index_: index string
	: param col_: column string
	: value_: value to be used
	: na_replacer: na value to be replaced by --
	'''
	x = data.pivot(index = index_, columns = col_, values = value_).reset_index()
	x = x.fillna(0) # replace NaN with 0
	# 当前所有挂靠了内容的标签array
	y = x.columns[1:]
	# replace weight with 1: weight是文本分类标签的预测概率，不作内容推荐计算用
	for i in range(len(y)):
		x[y[i]] = x[y[i]].apply(lambda x: 1 if x > 0 else 0)

	return x

def get_chainsmoker(df, num_cols, threshold):
	'''
	Data traverse
	'''
	y = df[num_cols].apply(lambda x: x > threshold)
	z = y.apply(lambda x: list(num_cols[x.values]), axis = 1)

	return z

def output_dict_lab_con(content_label_mapping):
	'''
	根据content-label主档，返回两个dict，一个以标签id为index，另一个以内容id为index
	'''
	con_lab_wide = get_pivoted(content_label_mapping, 'article_id', 'label_id', 'weight')
	labs = con_lab_wide.columns[1:]
	lab_con_wide = get_pivoted(content_label_mapping, 'label_id', 'article_id', 'weight')
	cons = lab_con_wide.columns[1:]
	list_lab = get_chainsmoker(con_lab_wide, labs, 0)
	list_con = get_chainsmoker(lab_con_wide, cons, 0)
	dict_lab = dict(zip(cons, list_lab))
	dict_con = dict(zip(labs, list_con))
	return dict_lab, dict_con, labs, cons, lab_con_wide, con_lab_wide


class Solution:
    def XXX(self, root: TreeNode) -> int:
        if not root:
            return 0
        queue = deque([(root, 1)])
        while queue:
            node, height = queue.popleft()
            if not node.left and not node.right:
                return height
            if node.left:
                queue.append((node.left, height+1))
            if node.right:
                queue.append((node.right, height+1))


# nlantau, 2021-12-30
"""
Write a function howSum(targetSum, numbers) that takes in a
targetSum and an array of numbers as arguments

The function should return an array containing any combination
of elements that add up to exactly the targetSum. If there is no
combination that adds up to the targetSum, then return null

If there are multiple combinations possible, you may return any
single one
"""

def howSumRecursive(targetSum, numbers):              # 7, [4,2,3]
    if targetSum == 0: return []
    if targetSum < 0: return None

    for num in numbers:                               # 4 in [4,2,3]               # 3 in [4,2,3]
        remainder = targetSum - num                   # 3 = 7 - 4                  # 0 = 3 - 3
        remainder_result = howSumRecursive(remainder, numbers) # rr = howSum(3, [4,2,3])    # [] = howSum(0, [4,2,3])
        if remainder_result != None:
            return [*remainder_result, num]
    return None

def howSum(targetSum, numbers, memo={}):
    if targetSum in memo: return memo[targetSum]
    if targetSum == 0: return []
    if targetSum < 0: return None

    for num in numbers:
        remainder = targetSum - num
        remainder_result = howSum(remainder, numbers, memo)
        if remainder_result != None:
            memo[targetSum] = [*remainder_result, num]
            return memo[targetSum]
    memo[targetSum] = None
    return None

print(howSumRecursive(7, [2,3,4]))
print(howSumRecursive(7, [5,3,4,7]))
print(howSumRecursive(7, [5,4,1]))
print(howSumRecursive(300, [5,3,4,7]))

print(howSum(7, [5,3,4,7]))
print(howSum(7, [5,4,1]))
print(howSum(300, [5,3,4,7]))

"""
Write a function canSum(targetSum, numbers) that takes in a
tagetSum and an array of numbers as argument.

The function should return a boolean indicating whether or not it
is possible to generate the targetSum using numbers from the array

Constraints:
You may use an element of the array as many times as needed.
You may assume that all input numbers are non-nogative.
"""

def canSum(targetSum, numbers, memo={}):
    if targetSum in memo: return memo[targetSum]
    if targetSum == 0: return True
    if targetSum < 0: return False

    for num in numbers:
        remainder = targetSum - num
        if canSum(remainder, numbers, memo):
            memo[targetSum] = True
            return True
    memo[targetSum] = False
    return False

print(canSum(7, [5,3,4,7]))
print(canSum(300, [5,3,4,7]))


#########################################################################
# k-nearest neighbour technique for classifying breast cancer.          #
#                                                                       #
# Author: Jonathan Harper                                               #
#########################################################################

import numpy as np
import helper_functions as func

# Maximum number of closest-proximity neighbours to consider
MAX_NUM_NEIGHBOURS = 3
# This represents the percentage split of the data into training/testing. 0.7 represents a 70:30 split of training and
# testing data
TRAINING_SPLIT = 0.8

def load_data():
    """
    Loads the data and splits it into training_data and unseen_data (for testing)
    :return training_data: The data which is used to train the model (the data we 'know')
    :return unseen_data: The data which hasn't been seen by the model (we're predicting the classification)
    """
    _, _, _, data = func.read_csv_and_prep()

    # Splitting the dataframe up into train/test sets (and randomly selecting values for it)
    from sklearn.model_selection import train_test_split
    training_data, unseen_data = train_test_split(data, test_size=1-TRAINING_SPLIT)

    return training_data, unseen_data

def get_neighbours(training_data, unseen_data_row):
    """
    Finding the closest MAX_NUM_NEIGHBOURS from the unseen_data_row point

    :param training_data: The 'known' and existing data
    :param unseen_data_row: The unseen data point that we are attempting to predict classification for
    :return: the MAX_NUM_NEIGHBOURS closest neighbours
    """
    from copy import deepcopy
    training_with_distances = deepcopy(training_data)

    # Working out the euclidean distances between the unseen data point and all of the existing training data points
    training_with_distances['distance'] = training_with_distances[func.FEATURES].\
        sub(np.array(unseen_data_row)).pow(2).sum(1).pow(0.5)

    # Sorting the dataframe based on the distances in ascending order
    training_with_distances.sort_values(by='distance', inplace=True)
    # Selecting the closest MAX_NUM_NEIGHBOURS
    neighbours = training_with_distances.head(n=MAX_NUM_NEIGHBOURS)

    return neighbours

def predict_classification(neighbours):
    """
    Given the closest neighbours selected, pick the majority classification for the unseen data point
    :param neighbours: The closest MAX_NUM_NEIGHBOURS neighbours in proximity
    :return: The predicted classification (str)
    """
    # Counting the number of instances of each classification within the dataframe
    number_of_class_instances = neighbours.groupby(['diagnosis'], sort=False).size().reset_index(name='count')
    # Sort by descending
    number_of_class_instances.sort_values(by='count', inplace=True, ascending=False)
    # Returns most frequent classification
    predicted_classification = number_of_class_instances.head(n=1).values.tolist()[0][0]
    return predicted_classification

if __name__ == '__main__':
    data_training, data_unseen = load_data()

    print('training_data length: {}'.format(len(data_training.index)))
    print('unseen_data length: {}'.format(len(data_unseen.index)))

    # The number of correct predictions
    num_correct = 0

    for index, row in data_unseen.iterrows():
        # Gets the neighbours for that particular unseen record
        records_neighbours = get_neighbours(data_training, row.tolist()[:-1])
        classification_prediction = predict_classification(records_neighbours)
        actual_classification = row.tolist()[0]
        # If predicted classification is the same as the actual
        if actual_classification == classification_prediction:
            num_correct += 1

    accuracy = num_correct / len(data_unseen.index)
    print("Accuracy: {}".format(accuracy))


import simplejson as json
from flask import Response, url_for
from flask import render_template, request, current_app
from flask_babel import gettext
from flask_security import login_required
from pgadmin.browser.server_groups.servers.utils import parse_priv_to_db
from pgadmin.utils import PgAdminModule
from pgadmin.utils.ajax import make_response as ajax_response, \
    make_json_response, internal_server_error
from pgadmin.utils.driver import get_driver

from config import PG_DEFAULT_DRIVER

try:
    from urllib import unquote
except:
    from urllib.parse import unquote
from pgadmin.utils.ajax import precondition_required
from functools import wraps
from pgadmin.utils.preferences import Preferences

# set template path for sql scripts
MODULE_NAME = 'grant_wizard'
server_info = {}

class GrantWizardModule(PgAdminModule):
    """
    class GrantWizardModule(Object):

        It is a wizard which inherits PgAdminModule
        class and define methods to load its own
        javascript file.

    LABEL = gettext('Browser')
    """

    def get_own_stylesheets(self):
        """
        Returns:
            list: the stylesheets used by this module.
        """
        stylesheets = [
            url_for('browser.static', filename='css/wizard.css'),
            url_for('grant_wizard.static', filename='css/grant_wizard.css')
        ]
        return stylesheets

    def get_own_javascripts(self):
        """"
        Returns:
            list: js files used by this module
        """
        scripts = []
        scripts.append({
            'name': 'pgadmin.tools.grant_wizard',
            'path': url_for('grant_wizard.index') + 'grant_wizard',
            'when': None
        })
        scripts.append({
            'name': 'pgadmin.browser.wizard',
            'path': url_for('browser.static', filename='js/wizard'),
            'when': None
        })
        return scripts

    def show_system_objects(self):
        """
        return system preference objects
        """
        return self.pref_show_system_objects

    def register_preferences(self):
        """
        Get show_system_objects preference
        """
        self.browser_preference = Preferences.module('browser')
        self.pref_show_system_objects = self.browser_preference.preference(
            'show_system_objects'
        )

# Create blueprint for GrantWizardModule class
blueprint = GrantWizardModule(
    MODULE_NAME, __name__, static_url_path='')

def check_precondition(f):
    """
    This function will behave as a decorator which will checks
    database connection before running view, it will also attaches
    manager,conn & template_path properties to instance of the method.

    Assumptions:
        This function will always be used as decorator of a class method.
    """

    @wraps(f)
    def wrap(*args, **kwargs):
        # Here args[0] will hold self & kwargs will hold gid,sid,did

        server_info.clear()
        server_info['manager'] = get_driver(
            PG_DEFAULT_DRIVER).connection_manager(
            kwargs['sid']
        )
        server_info['conn'] = server_info['manager'].connection(
            did=kwargs['did']
        )
        # If DB not connected then return error to browser
        if not server_info['conn'].connected():
            return precondition_required(
                gettext("Connection to the server has been lost!")
            )

        # Set template path for sql scripts
        server_info['server_type'] = server_info['manager'].server_type
        server_info['version'] = server_info['manager'].version
        if server_info['server_type'] == 'pg':
            server_info['template_path'] = 'grant_wizard/pg/9.1_plus'
        elif server_info['server_type'] == 'ppas':
            server_info['template_path'] = 'grant_wizard/ppas/9.1_plus'

        return f(*args, **kwargs)

    return wrap

@blueprint.route("/")
@login_required
def index():
    pass

@blueprint.route("/grant_wizard.js")
@login_required
def script():
    """render own javascript"""
    return Response(response=render_template(
        "grant_wizard/js/grant_wizard.js", _=gettext),
        status=200,
        mimetype="application/javascript")

@blueprint.route(
    '/acl/<int:gid>/<int:sid>/<int:did>/', methods=('GET', 'POST'))
@login_required
@check_precondition
def acl_list(gid, sid, did):
    """render list of acls"""
    server_prop = server_info
    return Response(response=render_template(
        server_prop['template_path'] + "/acl.json", _=gettext),
        status=200,
        mimetype="application/json")

@blueprint.route(
    '/properties/<int:gid>/<int:sid>/<int:did>'
    '/<int:node_id>/<node_type>/',
    methods=('GET', 'POST'))
@login_required
@check_precondition
def properties(gid, sid, did, node_id, node_type):
    """It fetches the properties of object types
       and render into selection page of wizard
    """

    # unquote encoded url parameter
    node_type = unquote(node_type)

    server_prop = server_info

    res_data = []
    manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
    conn = manager.connection(did=did)

    node_types = []
    show_sysobj = blueprint.show_system_objects().get()
    if node_type == 'database':

        # Fetch list of schemas
        # Get sys_obj_values and get list of schemas
        ntype = 'schema'
        SQL = render_template("/".join(
            [server_prop['template_path'], '/sql/get_schemas.sql']),
            show_sysobj=show_sysobj)
        status, res = conn.execute_dict(SQL)

        if not status:
            return internal_server_error(errormsg=res)
        node_types = res['rows']
    else:
        SQL = render_template("/".join(
            [server_prop['template_path'], '/sql/get_schemas.sql']),
            nspid=node_id, show_sysobj=False)
        status, res = conn.execute_dict(SQL)

        if not status:
            return internal_server_error(errormsg=res)
        node_types = res['rows']
        ntype = node_type

    for row in node_types:
        if 'oid' in row:
            node_id = row['oid']

        # Fetch functions against schema
        if ntype in ['schema', 'function']:
            SQL = render_template("/".join(
                [server_prop['template_path'], '/sql/function.sql']),
                node_id=node_id, type='function')

            status, res = conn.execute_dict(SQL)

            if not status:
                return internal_server_error(errormsg=res)

            res_data.extend(res['rows'])

        # Fetch procedures only if server type is ppas
        if (len(server_prop) > 0 and
                    server_prop['server_type'] == 'ppas' and
                    ntype in ['schema', 'procedure']):
            SQL = render_template("/".join(
                [server_prop['template_path'], '/sql/function.sql']),
                node_id=node_id, type='procedure')

            status, res = conn.execute_dict(SQL)

            if not status:
                return internal_server_error(errormsg=res)

            res_data.extend(res['rows'])

        # Fetch trigger functions
        if ntype in ['schema', 'trigger_function']:
            SQL = render_template("/".join(
                [server_prop['template_path'], '/sql/function.sql']),
                node_id=node_id, type='trigger_function')
            status, res = conn.execute_dict(SQL)

            if not status:
                return internal_server_error(errormsg=res)

            res_data.extend(res['rows'])

        # Fetch Sequences against schema
        if ntype in ['schema', 'sequence']:
            SQL = render_template("/".join(
                [server_prop['template_path'], '/sql/sequence.sql']),
                node_id=node_id)

            status, res = conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)
            res_data.extend(res['rows'])

        # Fetch Tables against schema
        if ntype in ['schema', 'table']:
            SQL = render_template("/".join(
                [server_prop['template_path'], '/sql/table.sql']),
                node_id=node_id)

            status, res = conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)

            res_data.extend(res['rows'])

        # Fetch Views against schema
        if ntype in ['schema', 'view']:
            SQL = render_template("/".join(
                [server_prop['template_path'], '/sql/view.sql']),
                node_id=node_id, node_type='v')

            status, res = conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)

            res_data.extend(res['rows'])

        # Fetch Materialzed Views against schema
        if ntype in ['schema', 'mview']:
            SQL = render_template("/".join(
                [server_prop['template_path'], '/sql/view.sql']),
                node_id=node_id, node_type='m')

            status, res = conn.execute_dict(SQL)
            if not status:
                return internal_server_error(errormsg=res)

            res_data.extend(res['rows'])

    return ajax_response(
        response=res_data,
        status=200
    )

@blueprint.route(
    '/msql/<int:gid>/<int:sid>/<int:did>/',
    methods=('GET', 'POST'))
@login_required
@check_precondition
def msql(gid, sid, did):
    """
    This function will return modified SQL
    """

    server_prop = server_info
    data = {}
    for k, v in request.args.items():
        try:
            data[k] = json.loads(v)
        except ValueError:
            data[k] = v

    # Form db connection
    manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
    conn = manager.connection(did=did)

    acls = []
    try:
        acls = render_template(
            "/".join([server_prop['template_path'], '/acl.json'])
        )
        acls = json.loads(acls)
    except Exception as e:
        current_app.logger.exception(e)

    try:

        # Parse privileges
        data['priv'] = {}
        if 'acl' in data:
            # Get function acls
            data['priv']['function'] = parse_priv_to_db(
                data['acl'],
                acls['function']['acl'])

            data['priv']['sequence'] = parse_priv_to_db(
                data['acl'],
                acls['sequence']['acl'])

            data['priv']['table'] = parse_priv_to_db(
                data['acl'],
                acls['table']['acl'])

        # Pass database objects and get SQL for privileges
        SQL_data = ''
        data_func = {}
        data_func['objects'] = data['objects']
        data_func['priv'] = data['priv']['function']
        SQL = render_template(
            "/".join([server_prop['template_path'],
                      '/sql/grant_function.sql']),
            data=data_func, conn=conn)
        if SQL and SQL.strip('\n') != '':
            SQL_data += SQL

        data_seq = {}
        data_seq['objects'] = data['objects']
        data_seq['priv'] = data['priv']['sequence']
        SQL = render_template(
            "/".join([server_prop['template_path'],
                      '/sql/grant_sequence.sql']),
            data=data_seq, conn=conn)
        if SQL and SQL.strip('\n') != '':
            SQL_data += SQL

        data_table = {}
        data_table['objects'] = data['objects']
        data_table['priv'] = data['priv']['table']
        SQL = render_template(
            "/".join([server_prop['template_path'], '/sql/grant_table.sql']),
            data=data_table, conn=conn)
        if SQL and SQL.strip('\n') != '':
            SQL_data += SQL

        res = {'data': SQL_data}

        return ajax_response(
            response=res,
            status=200
        )

    except Exception as e:
        return make_json_response(
            status=410,
            success=0,
            errormsg=e.message
        )

@blueprint.route(
    '/save/<int:gid>/<int:sid>/<int:did>/',
    methods=('GET', 'POST'))
@login_required
@check_precondition
def save(gid, sid, did):
    """
    This function will apply the privileges to the selected
    Database Objects
    """
    server_prop = server_info
    data = request.form if request.form else json.loads(request.data.decode())

    # Form db connection and we use conn to execute sql
    manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
    conn = manager.connection(did=did)

    acls = []
    try:
        acls = render_template(
            "/".join([server_prop['template_path'], 'acl.json']),
        )
        acls = json.loads(acls)
    except Exception as e:
        current_app.logger.exception(e)

    try:

        # Parse privileges
        data['priv'] = {}
        if 'acl' in data:
            # Get function acls
            data['priv']['function'] = parse_priv_to_db(
                data['acl'],
                acls['function']['acl'])

            data['priv']['sequence'] = parse_priv_to_db(
                data['acl'],
                acls['sequence']['acl'])

            data['priv']['table'] = parse_priv_to_db(
                data['acl'],
                acls['table']['acl'])

        # Pass database objects and get SQL for privileges
        # Pass database objects and get SQL for privileges
        SQL_data = ''
        data_func = {}
        data_func['objects'] = data['objects']
        data_func['priv'] = data['priv']['function']
        SQL = render_template(
            "/".join([server_prop['template_path'],
                      '/sql/grant_function.sql']),
            data=data_func, conn=conn)
        if SQL and SQL.strip('\n') != '':
            SQL_data += SQL

        data_seq = {}
        data_seq['objects'] = data['objects']
        data_seq['priv'] = data['priv']['sequence']
        SQL = render_template(
            "/".join([server_prop['template_path'],
                      '/sql/grant_sequence.sql']),
            data=data_seq, conn=conn)
        if SQL and SQL.strip('\n') != '':
            SQL_data += SQL

        data_table = {}
        data_table['objects'] = data['objects']
        data_table['priv'] = data['priv']['table']
        SQL = render_template(
            "/".join([server_prop['template_path'], '/sql/grant_table.sql']),
            data=data_table, conn=conn)
        if SQL and SQL.strip('\n') != '':
            SQL_data += SQL

        status, res = conn.execute_dict(SQL_data)
        if not status:
            return internal_server_error(errormsg=res)

        return make_json_response(
            success=1,
            info="Privileges applied"
        )

    except Exception as e:
        return internal_server_error(errormsg=e.message)


from django.db import models
from mongoengine import *
from mongoengine import connect
from django.core.paginator import Paginator
connect('djweb', host='127.0.0.1', port=27017)

# Create your models here.

class ArticleInfo(Document):
    des = StringField()
    title = StringField()
    score = StringField()
    tags = ListField(StringField())
    meta = {'collection' : 'djinfo1'}

for i in ArticleInfo.objects[:4]: # equal to limit(1)
    print(i.title, i.des, i.score, i.tags)

print("################################")
iter = 'sdfjowejqwjrkwj;efkjdskjf;sj'
paginator = Paginator(iter, 4) # can only display 4 items per page
page1 = paginator.page(1)
page2 = paginator.page(2)
print(page1.object_list)
print(page2.object_list)
print(page2.paginator.num_pages)


# Function: utils functions

import torch
from torch import nn
import math

def time_embedding(timesteps, dim, max_period=10000):
    """
    Create sinusoidal timestep embeddings.
    :param timesteps: a 1-D Tensor of N indices, one per batch element.
                      These may be fractional.
    :param dim: the dimension of the output.
    :param max_period: controls the minimum frequency of the embeddings.
    :return: an [batch_size x dim] Tensor of positional embeddings.
    """

    half = dim // 2
    freqs = torch.exp(
        -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half
    ).to(device=timesteps.device)
    args = timesteps[:, None].float() * freqs[None]
    embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
    if dim % 2:
        embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
    return embedding

class Downsample(nn.Module):
    def __init__(self, channels):
        super().__init__()
        self.op = nn.Conv2d(channels, channels, kernel_size=3, stride=2, padding=1)

    def forward(self, x):
        return self.op(x)

class Upsample(nn.Module):
    def __init__(self, channels):
        super().__init__()
        self.op = nn.ConvTranspose2d(in_channels=channels, out_channels=channels, kernel_size=3, stride=2, padding=1,
                                     output_padding=1)

    def forward(self, x):
        return self.op(x)


# Test cloud photos

import pytest

import osxphotos

PHOTOS_DB_CLOUD = "./tests/Test-Cloud-10.15.1.photoslibrary/database/photos.db"
PHOTOS_DB_NOT_CLOUD = "./tests/Test-10.15.1.photoslibrary/database/photos.db"

UUID_DICT = {
    "incloud": "37210110-E940-4227-92D3-45C40F68EB0A",
    "not_incloud": "63048B89-158C-4BA7-9687-4ABF394DCD9C",
    "cloudasset": "D11D25FF-5F31-47D2-ABA9-58418878DC15",
    "not_cloudasset": "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4",
}

@pytest.fixture(scope="module")
def photosdb():
    return osxphotos.PhotosDB(dbfile=PHOTOS_DB_CLOUD)

def test_incloud(photosdb):
    photos = photosdb.photos(uuid=[UUID_DICT["incloud"]])

    assert photos[0].incloud

def test_not_incloud(photosdb):
    photos = photosdb.photos(uuid=[UUID_DICT["not_incloud"]])

    assert not photos[0].incloud

def test_cloudasset_1(photosdb):
    photos = photosdb.photos(uuid=[UUID_DICT["cloudasset"]])

    assert photos[0].iscloudasset

def test_cloudasset_2(photosdb):
    photos = photosdb.photos(uuid=[UUID_DICT["not_incloud"]])

    # not_incloud is still a cloud asset
    assert photos[0].iscloudasset

def test_cloudasset_3():
    import osxphotos

    photosdb = osxphotos.PhotosDB(PHOTOS_DB_NOT_CLOUD)
    photos = photosdb.photos(uuid=[UUID_DICT["not_cloudasset"]])

    assert not photos[0].iscloudasset


import math

import cv2
import time
import numpy
import numpy as np

import HandsTracking as ht

from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume

videocap=cv2.VideoCapture(0)

prevtime=0

detector=ht.HandDetection()

devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
    IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
#volume.GetMute()
#volume.GetMasterVolumeLevel()
volrange=volume.GetVolumeRange()  #-65 to 0

minvol=volrange[0]
maxvol=volrange[1]

while True:
    test, imgframe=videocap.read()
    img=imgframe
    #img=detector.Hands(imgframe)
    lmlist=detector.Location(img,draw=False)
    if len(lmlist)>0:
        #print(lmlist[4],lmlist[8])
        x1,y1=lmlist[4][0],lmlist[4][1]
        x2, y2 = lmlist[8][0], lmlist[8][1]
        cv2.rectangle(img,(x1-5,y1-5),(x1+5,y1+5),cv2.COLOR_YUV420sp2GRAY,10)
        cv2.rectangle(img, (x2 - 5, y2 - 5), (x2 + 5, y2 + 5), cv2.COLOR_YUV420sp2GRAY, 10)
        cv2.line(img,(x1,y1),(x2,y2),(202,122,0),3)
        cx,cy=(x1+x2)//2,(y1+y2)//2
        cv2.circle(img, (cx, cy), 10, (33, 112, 234), cv2.FILLED)

        l=math.hypot(x1-x2,y1-y2)
        #print(l)

        # Length range 40-290
        vol=np.interp(l,[30,270],[minvol,maxvol])
        volume.SetMasterVolumeLevel(vol, None)
        print(vol)

        if l<50:
            cv2.circle(img, (cx, cy), 10, (0, 255, 0), cv2.FILLED)

    img=cv2.resize(img,(800,500))
    cv2.imshow("Img", img)
    cv2.waitKey(1)


import os
import time
from selenium import webdriver
import requests
from bs4 import BeautifulSoup
import credential as c
from selenium.webdriver.common.keys import Keys
import pandas as pd
import numpy as np
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.support.ui import Select
import pandas as pd
import numpy as np

list_of_profs = ["Ford, Kevin B.",
"Tyson, Jeremy T.",
"Hirani, Anil N.",
"Katz, Sheldon H.",
"Albin, Pierre",
"Dunfield, Nathan M.",
"Kostochka, Alexandr V.",
"Kedem, Rinat",
"Song, Renming",
"Dodd, Christopher",
"Duursma, Iwan Maynard",
"McCarthy, Randy",
"Rezk, Charles W.",
"Fernandes, Rui Loja",
"Mineyev, Igor",
"Dutta, Sankar Prasad",
"Yong, Alexander T. F.",
"Tolman, Susan",
"Erdoğan, Mehmet Burak",
"Junge, Marius",
"Hur, Vera Mikyoung",
"Stojanoska, Vesna",
"Ahlgren, Scott D.",
"Bradlow, Steven Benjamin",
"Rapti, Zoi",
"Sowers, Richard B.",
"Balogh, József",
"Kutzarova, Denka N.",
"Zaharescu, Alexandru",
"La Nave, Gabriele",
"Ando, Matthew",
"Berwick-Evans, Daniel",
"DeVille, R. E. Lee",
"Boca, Florin-Petre",
"Thorner, Jesse",
"Zharnitsky, Vadim",
"Lerman, Eugene M.",
"Reznick, Bruce",
"Dey, Partha Sarathi",
"Hinkkanen, Aimo",
"Nikolaev, Igor G.",
"Pascaleff, James Thomas",
"Bronski, Jared C.",
"Feng, Runhuan",
"Haboush, William J.",
"Baryshnikov, Yuliy M.",
"Kirr, Eduard",
"Oikhberg, Timur",
"Leditzky, Felix",
"Kirkpatrick, Kay Lene",
"Jing, Xiaochen",
"Tzirakis, Nikolaos",
"Kerman, Ely",
"Di Francesco, Philippe",
"Laugesen, Richard Snyder",
"Heller, Jeremiah Ben",
"Guzman, Rosemary K."]

# setup
option = webdriver.ChromeOptions()
toolsURL = "https://mathscinet-ams-org.proxy2.library.illinois.edu/mathscinet/index.html"
option.add_argument("headless")
base_path = os.path.dirname(os.path.abspath(__file__))
drive_path = os.path.abspath(base_path + "/chromedriver 2")
driver = webdriver.Chrome(drive_path)
driver.get(toolsURL)
time.sleep(0.2)

# login
driver.find_element_by_xpath("//*[@id='userNameInput']").click()
time.sleep(0.2)
driver.find_element_by_id("userNameInput").send_keys("devhp2@illinois.edu")
time.sleep(0.2)
driver.find_element_by_xpath("//*[@id='nextButton']").click()
driver.find_element_by_id("passwordInput").send_keys("20Pr#tgn720Pr#t1gn7")
time.sleep(0.2) # wait 0.2 seconds, waiting for the program to get everything
driver.find_element_by_xpath("//*[@id='submitButton']").click()
time.sleep(0.2)
try:
    element = WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.NAME, "s4"))
)
except:
    driver.quit()

time.sleep(0.3)

#check if there is next paper
def check_exists_by_partial_link_text():
    try:
        driver.find_element_partial_link_text("Next")
    except:
        return False
    return True

#check if there is reference list for each author
def check_exists_by_class_name():
    try:
        driver.find_element_by_class_name("reflist")
    except:
        return False
    return True

profdict = {}

for proffessor in list_of_profs:
    #enter information (professor name and starting year)
    time.sleep(0.4)
    driver.find_element_by_css_selector("input[type='radio'][value='pubyear']").click()
    time.sleep(0.4)
    select = Select(driver.find_element_by_id('yrop'))
    time.sleep(0.4)
    select.select_by_visible_text('>')
    time.sleep(0.4)
    driver.find_element_by_id("yearValue").send_keys("2010")
    time.sleep(0.4)
    driver.find_element_by_name("s4").send_keys(proffessor)
    time.sleep(0.4)
    driver.find_element_by_name("Submit").click()
    time.sleep(0.4)
    driver.find_element_by_class_name("mrnum").click()

    # get all references for all paper for one author
    listreferences = []
    time.sleep(0.2)
    if (check_exists_by_class_name()):
        soup = BeautifulSoup(driver.page_source, "html.parser")
        spans = soup.find_all('a', href = True)
        for word in spans:
            if (word.get_text()[0:2] == "MR" or word.get_text()[0:2] == "ar"):
                listreferences.append(word.get_text())

    #keep on adding references until there is no next paper
    while (True):
        time.sleep(0.2)
        try:
            driver.find_element_by_partial_link_text("Next").click()
            time.sleep(0.2)
            if (check_exists_by_class_name()):
                time.sleep(0.4)
                soup = BeautifulSoup(driver.page_source, "html.parser")
                time.sleep(0.2)
                spans = soup.find_all('a', href = True)
                time.sleep(0.2)
                for word in spans:
                    if (word.get_text()[0:2] == "MR" or word.get_text()[0:2] == "ar"):
                        listreferences.append(word.get_text())
                time.sleep(0.4)
        except:
            break
    #dictionary with key professor and value of all of their references
    profdict[proffessor] = listreferences
    time.sleep(0.4)

    #go back to home
    driver.find_element_by_link_text("Home").click()
    time.sleep(0.4)

df = pd.read_csv("namesofprofessors.csv")
faculty = df['professornames'].tolist()

#returns length of the intersection of two reference lists of two authors
def common_reference(author1, author2):
    listOne = profdict.get(list_of_profs[faculty.index(author1)])
    listTwo = profdict.get(list_of_profs[faculty.index(author2)])

    lengthNumber = len(list(set(listOne).intersection(set(listTwo))))
    return lengthNumber

matrix = np.zeros((len(faculty), len(faculty)))

for i in range(len(faculty)):
    for j in range(len(faculty)):
        matrix[i][j] = common_reference(faculty[i], faculty[j])

#convert matrix to csv file
pd.DataFrame(matrix).to_csv("common_references.csv")

print(len(list_of_profs))
print(len(faculty))


# encoding=utf-8
"""
Switching between 2 tasks.
Using wait & notify.
"""

import os
import time
import threading
from threading import Condition

class XiaoMing(threading.Thread):
    def __init__(self, condition):
        super().__init__(name='小明')
        self.condition = condition
        self.inner_count = 0  # 内部计数

    def run(self):
        global count, total_count

        with self.condition:
            while count < total_count:
                # ---------- Do something...
                count += 1
                self.inner_count += 1
                print('{:s} | global count: {:d}, inner count: {:d}'
                      .format(self.name, count, self.inner_count))
                # ----------

                self.condition.notify()
                self.condition.wait()

class XiaoHong(threading.Thread):
    def __init__(self, condition):
        super().__init__(name='小红')
        self.condition = condition
        self.inner_count = 0  # 内部计数

    def run(self):
        global count, total_count

        with self.condition:

            while count < total_count:
                self.condition.wait()

                # ---------- Do something...
                count += 1
                self.inner_count += 1
                print('{:s} | global count: {:d}, inner_count: {:d}'
                      .format(self.name, count, self.inner_count))
                # ----------

                self.condition.notify()

def TestTaskSwitch():
    condition = threading.Condition()

    global count, total_count
    count, total_count = 0, 100

    XM = XiaoMing(condition)
    XH = XiaoHong(condition)

    XH.start()
    XM.start()

    XH.join()
    XM.join()

if __name__ == '__main__':
    TestTaskSwitch()
    print('Test done.')