import asyncio
import logging
import traceback

import sentry_sdk
from aiogram import Bot
from aiogram import types
from aiogram.contrib.fsm_storage.redis import RedisStorage2
from aiogram.dispatcher import Dispatcher
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.types import ContentType
from aiogram.utils.executor import Executor
from helpers import log_button_click
from sentry_sdk import capture_exception
from sentry_sdk import capture_message
from telegram_bot.constants import START_COMMAND
from telegram_bot.constants import AdminConsts
from telegram_bot.constants import ButtonNames as BN
from telegram_bot.constants import DialogConsts
from telegram_bot.constants import Messages
from telegram_bot.db import setup_db
from telegram_bot.exceptions import ApplicationLogicException
from telegram_bot.filters import AdminFilter
from telegram_bot.helpers import PersonInfoToChannelResender
from telegram_bot.helpers import StoryToChannelResender
from telegram_bot.helpers import answer_with_actions_keyboard
from telegram_bot.helpers import check_return_or_start_cmd
from telegram_bot.helpers import create_person_info_from_message
from telegram_bot.helpers import get_obj_id_from_callback_data
from telegram_bot.helpers import is_dialog_finished
from telegram_bot.keyboards import CANCEL_DIALOG_KEYBOARD
from telegram_bot.keyboards import RETURN_KEYBOARD
from telegram_bot.keyboards import STOP_DIALOG_SEARCH_KEYBOARD
from telegram_bot.keyboards import get_person_info_keyboard_markup
from telegram_bot.keyboards import get_story_keyboard_markup
from telegram_bot.models import AnonymousDialog
from telegram_bot.models import PersonInformation
from telegram_bot.models import Story
from telegram_bot.settings import ADMIN_OBJS_COUNT_SETTING
from telegram_bot.settings import REDIS_STORAGE_PARAMS
from telegram_bot.settings import SENTRY_URL
from telegram_bot.settings import TOKEN
from telegram_bot.states import ProjectStates

if SENTRY_URL:
    sentry_sdk.init(
        SENTRY_URL,

        # Set traces_sample_rate to 1.0 to capture 100%
        # of transactions for performance monitoring.
        # We recommend adjusting this value in production.
        traces_sample_rate=1.0
    )

bot = Bot(token=TOKEN)
dp = Dispatcher(bot, storage=RedisStorage2(**REDIS_STORAGE_PARAMS))
dp.filters_factory.bind(AdminFilter)
runner = Executor(dp)
# Включаем логирование, чтобы не пропустить важные сообщения
logging.basicConfig(level=logging.INFO)

async def answer(message, text, photo_file_id=None, **kwargs):
    """Ответ на сообщение с текстом/изображением и доп. параметрами"""
    if photo_file_id:
        await message.answer_photo(photo_file_id, text, **kwargs)
    else:
        await message.answer(text, **kwargs)

@dp.message_handler(commands=[START_COMMAND])
@log_button_click
async def process_start_command(message: types.Message):
    """Выдает стартовое сообщение."""
    await message.answer(Messages.START)
    await answer_with_actions_keyboard(message, Messages.CHOOSE_ACTION)

@dp.message_handler(Text(BN.values[BN.SEND_INFORMATION_FORM]))
@log_button_click
async def send_information_form(message: types.Message):
    """Обработчик нажатия на кнопку отправки анкеты сообщений."""
    await message.answer(
        Messages.SEND_INFORMATION_FORM, parse_mode="Markdown")
    await message.answer(
        Messages.INFORMATION_FORM_TEMPLATE, reply_markup=RETURN_KEYBOARD)
    await ProjectStates.send_information_form.set()

# TODO: может сделать всплывающую форму с разными полями (?)
#  как у бота @DurgerKingBot (да, название именно такое:))
@dp.message_handler(state=ProjectStates.send_information_form,
                    content_types=[ContentType.ANY])
async def send_information_form_saving(
        message: types.Message, state: FSMContext):
    """Сохранение анкеты."""

    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    await create_person_info_from_message(message)

    await answer_with_actions_keyboard(
        message, Messages.INFORMATION_FORM_PROCESSED)
    await state.finish()

@dp.message_handler(Text(BN.values[BN.SEND_STORY]))
@log_button_click
async def send_story(message: types.Message):
    """Обработчик нажатия на кнопку отправки интересной истории."""
    await message.answer(Messages.SEND_STORY, reply_markup=RETURN_KEYBOARD)
    await ProjectStates.send_story.set()

@dp.message_handler(state=ProjectStates.send_story)
async def story_saving(
        message: types.Message, state: FSMContext):
    """Сохранение истории."""
    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    await Story.create(text=message.text, user_id=message.from_user.id)

    await answer_with_actions_keyboard(message, Messages.STORY_PROCESSED)
    await state.finish()

@dp.message_handler(Text(AdminConsts.GET_STORIES), is_admin=True)
async def get_user_stories(message: types.Message, state: FSMContext):
    """Получение админом историй."""

    user_stories = await Story.filter(
        is_published=False
    ).limit(ADMIN_OBJS_COUNT_SETTING)

    if not user_stories:
        raise ApplicationLogicException(AdminConsts.STORIES_IS_EMPTY)

    for story in user_stories:
        await message.answer(
            story.text, reply_markup=get_story_keyboard_markup(story.id))

@dp.callback_query_handler(
    lambda c: AdminConsts.DELETE_STORY_CODE in c.data)
async def delete_story(callback_query: types.CallbackQuery):
    """Удаление истории вместе с сообщением."""
    story_id = get_obj_id_from_callback_data(callback_query.data)
    await Story.filter(id=story_id).delete()

    if callback_query.message:
        await callback_query.message.delete()

@dp.callback_query_handler(
    lambda c: AdminConsts.APPROVE_STORY_CODE in c.data)
async def process_story_approve(callback_query: types.CallbackQuery):
    """Авто-пересылка истории в канал"""
    story_id = get_obj_id_from_callback_data(callback_query.data)
    await StoryToChannelResender(story_id, callback_query.message).send()

@dp.callback_query_handler(
    lambda c: AdminConsts.NEED_TO_EDIT_STORY_CODE in c.data)
async def need_to_edit_story(callback_query: types.CallbackQuery,
                             state: FSMContext):
    """Отправка истории на редактирование вместе с сообщением от админа."""
    story_id = get_obj_id_from_callback_data(callback_query.data)
    await state.set_data({'user_story_id': story_id})

    await callback_query.message.answer(
        AdminConsts.NEED_TO_EDIT_TO_ADMIN, reply_markup=RETURN_KEYBOARD)

    await ProjectStates.need_to_edit_story.set()

@dp.message_handler(state=ProjectStates.need_to_edit_story)
async def need_to_edit_story_send_msg(
        message: types.Message, state: FSMContext):
    """Отправка истории на редактирование вместе с сообщением от админа."""

    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    state_data = await state.get_data()
    user_story_id = state_data.get('user_story_id', None)
    if user_story_id:
        story = await Story.filter(id=user_story_id).first()

        await bot.send_message(
            story.user_id,
            f'{AdminConsts.ADMIN_ANSWER}\n{Messages.STORY_NEED_TO_EDIT}',
            parse_mode="Markdown"
        )
        await bot.send_message(story.user_id, story.text)
        await bot.send_message(
            story.user_id, f'{AdminConsts.ADMIN_ANSWER}\n{message.text}',
            parse_mode="Markdown"
        )
        await answer_with_actions_keyboard(
            message, AdminConsts.ADMIN_MSG_SENDED)
    else:
        raise ApplicationLogicException('История не найдена!')
    await state.finish()

@dp.message_handler(Text(
    AdminConsts.GET_PERSON_INFO), is_admin=True)
async def get_user_info_forms(message: types.Message, state: FSMContext):
    """Получение админом анкет."""

    persons_information = await PersonInformation.filter(
        is_published=False
    ).limit(ADMIN_OBJS_COUNT_SETTING)

    if not persons_information:
        raise ApplicationLogicException(AdminConsts.PERSON_INFOS_IS_EMPTY)

    for person_info in persons_information:
        await answer(
            message, person_info.text, person_info.image_file_id,
            reply_markup=get_person_info_keyboard_markup(person_info.id)
        )

@dp.callback_query_handler(
    lambda c: AdminConsts.DELETE_PERSON_INFO_CODE in c.data)
async def delete_person_info(callback_query: types.CallbackQuery):
    """Удаление анкеты вместе с сообщением."""
    info_id = get_obj_id_from_callback_data(callback_query.data)
    await PersonInformation.filter(id=info_id).delete()

    if callback_query.message:
        await callback_query.message.delete()

@dp.callback_query_handler(
    lambda c: AdminConsts.APPROVE_PERSON_INFO_CODE in c.data)
async def process_person_info_approve(callback_query: types.CallbackQuery):
    """Авто-пересылка анкеты в канал"""
    person_info_id = get_obj_id_from_callback_data(callback_query.data)
    await PersonInfoToChannelResender(
        person_info_id, callback_query.message).send()

@dp.callback_query_handler(
    lambda c: AdminConsts.NEED_TO_EDIT_PERSON_INFO_CODE in c.data)
async def need_to_edit_person_info(callback_query: types.CallbackQuery,
                                   state: FSMContext):
    """Отправка анкеты на редактирование вместе с сообщением от админа."""
    person_info_id = get_obj_id_from_callback_data(callback_query.data)
    await state.set_data({'user_person_info_id': person_info_id})

    await callback_query.message.answer(
        AdminConsts.NEED_TO_EDIT_TO_ADMIN, reply_markup=RETURN_KEYBOARD)

    await ProjectStates.need_to_edit_person_info.set()

@dp.message_handler(state=ProjectStates.need_to_edit_person_info)
async def need_to_edit_person_info_send_msg(
        message: types.Message, state: FSMContext):
    """Отправка анкеты на редактирование вместе с сообщением от админа."""

    return_or_start_cmd = await check_return_or_start_cmd(message, state)
    if return_or_start_cmd:
        return

    state_data = await state.get_data()
    user_person_info_id = state_data.get('user_person_info_id', None)
    if user_person_info_id:
        person_info = await PersonInformation.filter(
            id=user_person_info_id).first()

        await bot.send_message(
            person_info.user_id,
            f'{AdminConsts.ADMIN_ANSWER}\n{Messages.INFO_NEED_TO_EDIT}',
            parse_mode="Markdown"
        )
        await bot.send_photo(
            person_info.user_id, person_info.image_file_id, person_info.text)
        await bot.send_message(
            person_info.user_id,
            f'{AdminConsts.ADMIN_ANSWER}\n{message.text}',
            parse_mode="Markdown"
        )
        await answer_with_actions_keyboard(
            message, AdminConsts.ADMIN_MSG_SENDED)
    else:
        raise ApplicationLogicException('Анкета не найдена!')
    await state.finish()

############### Dialog part ###############

@dp.message_handler(Text(BN.values[BN.START_ANONYMOUS_DIALOG]))
@log_button_click
async def start_anon_dialog_search(message: types.Message, state: FSMContext):
    """Обработчик нажатия на кнопку поиск собеседника для диалога."""
    current_user_id = message.from_user.id

    dialog_partner = await AnonymousDialog.filter(
        to_user_id__isnull=True).exclude(user_id=current_user_id).first()
    dialog_partner_id = getattr(dialog_partner, 'user_id', None)

    if dialog_partner_id:
        await state.finish()

        partner_dialog_state = Dispatcher.get_current().current_state(
            chat=dialog_partner_id, user=dialog_partner_id)
        if partner_dialog_state:
            await partner_dialog_state.finish()

        await ProjectStates.anon_dialog_state.set()
        await ProjectStates.anon_dialog_state.set(
            chat_id=dialog_partner_id,
            user_id=dialog_partner_id,
            # Для юзера, которому устанавливаем состояние диалога, так же
            # прокидываем id пользователя с которым он общается.
            data={'dialog_partner_id': current_user_id}
        )

        await state.set_data({'dialog_partner_id': dialog_partner_id})

        dialog_partner.to_user_id = current_user_id
        await dialog_partner.save()

        await message.answer(
            DialogConsts.PARTNER_FOUNDED, reply_markup=CANCEL_DIALOG_KEYBOARD)

        await bot.send_message(
            dialog_partner_id, DialogConsts.PARTNER_FOUNDED,
            reply_markup=CANCEL_DIALOG_KEYBOARD
        )
    else:
        await ProjectStates.search_anon_dialog_state.set()
        await message.answer(
            DialogConsts.SEARCH_STARTED_BUTTON,
            reply_markup=STOP_DIALOG_SEARCH_KEYBOARD, parse_mode="Markdown"
        )

        current_user_is_searching = await AnonymousDialog.filter(
            to_user_id__isnull=True,
            user_id=current_user_id
        ).exists()
        if not current_user_is_searching:
            await AnonymousDialog.create(user_id=current_user_id)

@dp.message_handler(state=ProjectStates.search_anon_dialog_state)
async def dialog_search(
        message: types.Message, state: FSMContext):
    """Обработчик сообщений для состояния поиска диалога."""
    state_data = await state.get_data()
    dialog_partner_id = state_data.get('dialog_partner_id', None)

    dialog_finished = await is_dialog_finished(
        message, state, dialog_partner_id)
    if dialog_finished:
        return
    await message.answer(DialogConsts.STILL_SEARCHING)

@dp.message_handler(state=ProjectStates.anon_dialog_state)
async def anon_dialog(
        message: types.Message, state: FSMContext):
    """Обработчик пересылки сообщений в диалоге."""
    state_data = await state.get_data()
    dialog_partner_id = state_data.get('dialog_partner_id', None)

    dialog_finished = await is_dialog_finished(
        message, state, dialog_partner_id)
    if dialog_finished:
        return

    if dialog_partner_id:
        await bot.send_message(dialog_partner_id, message.text)

############### End dialog part ###############

@dp.message_handler(Text(AdminConsts.SEND_SENTRY_ERROR_CMD))
async def send_test_sentry_error(message: types.Message):
    """Обработчик отправки тестового сообщения в Sentry."""
    capture_message('Тестовое сообщение в Sentry')
    await answer_with_actions_keyboard(
        message, 'Тестовое сообщение в Sentry отправлено!')

@dp.message_handler(content_types=[ContentType.ANY])
async def unknown_message_handler(message: types.Message):
    """Обработчик неизвестных сообщений."""
    await message.answer(Messages.UNKNOWN_MESSAGE)
    state = dp.current_state()
    await check_return_or_start_cmd(message, state)

@dp.errors_handler(exception=Exception)
async def message_not_modified_handler(update, error):
    """Обработка ошибок.

    В случае ApplicationLogicException, просто выводится сообщение из текста
    ошибки.
    В случае другой ошибки, выводится сообщение о непредвиденной ошибке,
    очищается контекст, и происходит выход на главный экран.
    """
    message = update.message or update.callback_query.message
    if isinstance(error, ApplicationLogicException):
        await message.answer(str(error))
    else:
        await answer_with_actions_keyboard(message, Messages.ERROR)
        state = dp.current_state()
        await state.finish()
        # TODO: добавить логирование
        # Отправка ошибки в Sentry
        if SENTRY_URL:
            capture_exception(error)
        traceback.print_exc()

    return True

if __name__ == '__main__':
    setup_db(runner)
    loop = asyncio.get_event_loop()
    runner.start_polling(dp)


from collections import deque
# bfs를 하기 위한 첫 번째

def BFS(i,j):
    queue = deque() # 큐를 deque()으로 만들어준다.
    queue.append((i,j)) # 들어가는 자리를
    d=[(-1,0),(0,-1),(1,0),(0,1)] # 좌표를 상하좌우로 델타탐색 한다.
    cnt=1 # 들어갈 때 cnt 하나 해준다.

    while queue: # 큐가 빌 때 까지 해준다.
        y,x = queue.popleft() # 맨 왼쪽 값 뽑고 리스트에서 삭제
        for dy,dx in d : # for _ in range(4) 델타 탐색 상하좌우 하는 느낌으로
            Y,X = y+dy, x+dx # 델타 탐색 해주고,
            if (0<= Y < M) and (0 <= X < N) and graph[Y][X] == 0: # 범위 안에 있거나, 가보지 않았으면
                graph[Y][X] = 1 # 1 넣어주고
                queue.append((Y,X)) # 해당 좌표 넣어주고
                cnt +=1 # 1 더해주고..

    return cnt # 끝나면 count한 값

M,N,K = map(int,input().split())
graph = [[0]*N for _ in range(M)]

for _ in range(K):
    x1,y1,x2,y2 = map(int,input().split())
    for i in range(y1,y2):
        for j in range(x1,x2):
            graph[i][j] = 1

result = []
for i in range(M):
    for j in range(N):
        if graph[i][j] == 0: # 공백이면,
            graph[i][j] = 1 # 1을 칠해주고
            result.append(BFS(i,j)) # bfs 돌아준다.

print(len(result))
print(*sorted(result))


"""Create the application's database.

Run this once after installing the application::

    python -m pygall.scripts.setup development.ini [-d|--drop]
"""
import logging
import sys
import os

from pyramid.paster import get_app
import transaction

from pygall import models

def main():
    if len(sys.argv) < 2:
        sys.exit("Usage: python -m pygall.scripts.setup INI_FILE#section [-d|--drop]")
    args = sys.argv[1].split('#')
    ini_file = args[0]
    section = args[1] if len(args)>1 else 'PyGall'
    logging.config.fileConfig(ini_file)
    log = logging.getLogger(__name__)
    app = get_app(ini_file, section)
    settings = app.registry.settings

    if len(sys.argv) > 2 and sys.argv[2] in ['-d', '--drop']:
        log.info("Dropping tables")
        models.Base.metadata.drop_all()
    # Abort if any tables exist to prevent accidental overwriting
    for table in models.Base.metadata.sorted_tables:
        log.debug("checking if table '%s' exists", table.name)
        if table.exists():
            raise RuntimeError("database table '%s' exists" % table.name)

    log.info("Creating tables")
    models.Base.metadata.create_all()

    log.info("Inserting data")
    sess = models.DBSession()
    # insert data here #
    transaction.commit()

    log.info("Generating auth.cfg file")
    with open(settings['auth_cfg'], 'w') as f:
        f.write("# This file contains the credentials of users allowed to\n" \
                "# access to the PyGall photo gallery.\n" \
                "# Currently pygall contains only one group: 'admin'.\n" \
                "# The format of each line should look like:\n" \
                "# 'username:password[:group]'\n" \
                "admin:N5rIuAWOHGycs:admin\n" \
                "guest:Z7TjkT9L.lUAM\n")

if __name__ == "__main__":
    main()


from fluent import FnLEFluent
from opt.function import CollisionFn
from utils import *
from openravepy import *
import ctrajoptpy
import numpy as np
import time

# If True, verify that caching produces equivalent results to
# computation. If False, actually do caching (return cached value).
CACHING_DEBUG = False

class NotObstructs(FnLEFluent):
    # def __init__(self, env, hl_action, robot, priority, traj, obj, obj_loc, dsafe=0.05):
    def __init__(self, env, hl_action, robot, priority, traj, obj, obj_loc=None, dsafe=0.05):
        self.env = env
        self.plotting_env = hl_action.hl_plan.env
        self.hl_action = hl_action
        self.traj = traj
        self.obj = obj
        self.obj_loc = obj_loc
        self.robot = robot
        self.priority = priority
        self.name = "NotObstructs"
        self.K = self.hl_action.K
        self.T = self.hl_action.T
        self.cc = ctrajoptpy.GetCollisionChecker(env)
        self.dsafe = dsafe
        self.cache = {}
        self.allow_early_converge = True

    def pre(self):
        traj = self.traj

        g = lambda x: self.collisions(x) # function inequality constraint g(x) <= 0
        obj_loc_list = []
        if self.obj_loc is not None:
            obj_loc_list = [self.obj_loc for i in range(self.T)]
        self.fn = CollisionFn([self.traj] + obj_loc_list, g)

    # TODO: compute collisions properly
    # @profile
    def collisions(self, traj):
        flattened = tuple(traj.round(5).flatten())
        v_check, j_check = None, None
        if flattened in self.cache:
            if CACHING_DEBUG:
                v_check, j_check = self.cache[flattened]
            else:
                return self.cache[flattened]

        env = self.env
        T = self.T
        K = self.K

        # ensure that there's gradient information outside dsafe
        self.cc.SetContactDistance(self.dsafe + .1)

        handles = []

        if self.obj_loc is not None:
            val = np.zeros((2*self.T, 1))
            jac = np.zeros((2*self.T, traj.size))
        else:
            val = np.zeros((self.T, 1))
            jac = np.zeros((self.T, traj.size))
        # if self.obj_loc is not None:
        #     self.obj.set_pose(env, self.obj_loc.set_value())

        if self.priority == 1:
            lst = [0, T-1]
        elif self.priority == 2:
            # since priority 1 was already run, don't need to recheck end states
            lst = range(1, T-1)
        else:
            raise NotImplementedError
        for t in lst:
            # xt = self.traj.set_value()[K*t:K*(t+1)]
            # xt = traj[:,t:t+1]
            xt = traj[K*t:K*(t+1)]
            self.robot.set_pose(env, xt)
            ot = None
            if self.obj_loc is not None:
                ot = traj[K*(t+T):K*(t+1+T)]
                self.obj.set_pose(env, ot)
            collisions = self.cc.BodyVsAll(self.robot.get_env_body(env))

            col_val, robot_jac, obj_jac = self.calc_grad_and_val(xt, ot, collisions)
            if robot_jac is not None:
                val[t], jac[t, K*t:K*(t+1)] = col_val, robot_jac
                if self.obj_loc is not None:
                    val[t+T], jac[t+T, K*(t+T):K*(t+1+T)] = col_val, obj_jac
                    # cross terms
                    jac[t, K*(t+T):K*(t+1+T)] = obj_jac
                    jac[t+T, K*t:K*(t+1)] = robot_jac

        self.plotting_env.UpdatePublishedBodies()
        handles = []

        if CACHING_DEBUG:
            assert v_check is None or np.allclose(v_check, val, atol=1e-4)
            assert j_check is None or np.allclose(j_check, jac, atol=1e-4)
        self.cache[flattened] = (val, jac)
        return (val, jac)

    # @profile
    def calc_grad_and_val(self, xt, ot, collisions):
        val = -1*float("inf")
        robot_grad = None
        obj_grad = None
        for c in collisions:
            linkA = c.GetLinkAParentName()
            linkB = c.GetLinkBParentName()

            if linkA == self.robot.name and linkB == self.obj.name:
                ptRobot = c.GetPtA()
                ptObj = c.GetPtB()
            elif linkB == self.robot.name and linkA == self.obj.name:
                ptRobot = c.GetPtB()
                ptObj = c.GetPtA()
            else:
                continue

            ptRobot[2] = 1.01
            ptObj[2] = 1.01

            distance = c.GetDistance()
            normal = c.GetNormal()

            # plotting
            self.plot_collision(ptRobot, ptObj, distance)

            # if there are multiple collisions, use the one with the greatest penetration distance
            if self.dsafe - distance > val:
                val = self.dsafe - distance

                robot_grad = np.dot(-1 * normal[0:2], self.calc_jacobian(np.transpose(ptObj), xt))
                if ot is not None:
                    obj_grad = np.dot(normal[0:2], self.calc_jacobian(np.transpose(ptRobot), ot))

        return val, robot_grad, obj_grad

    def plot_collision(self, ptA, ptB, distance):
        handles = []
        if not np.allclose(ptA, ptB, atol=1e-3):
            if distance < 0:
                handles.append(self.plotting_env.drawarrow(p1=ptA, p2=ptB, linewidth=.01,color=(1,0,0)))
            else:
                handles.append(self.plotting_env.drawarrow(p1=ptA, p2=ptB, linewidth=.01,color=(0,0,0)))
        self.hl_action.add_plot_handles(handles)

    def calc_jacobian(self, pt, x0):
        jac = np.zeros((2,3))
        r = pt[0:2] - x0[0:2, 0]
        jac[0,0] = 1
        jac[1,1] = 1
        jac[0,2] = -r[1]
        jac[1,2] = r[0]
        # return np.matrix(jac)
        return jac

    def params_to_resample(self):
        # resample ObjLoc, Start Robot Pose, and End Robot Pose
        return filter(lambda p: p is not None and p.is_resampled, [self.obj_loc, self.hl_action.start, self.hl_action.end])


from collections import deque
from trees import build_binary_tree, is_leaf_node

def find_path(root, sequence):
    """
    Given a binary tree and a number sequence, find if the sequence is present as a
    root-to-leaf path in the given tree.
    """
    seq_q = deque(sequence)

    def helper(root, seq):
        if root.val is None:
            return
        if is_leaf_node(root) and len(seq) == 1 and seq[0] == root.val:
            return True
        msd = seq.popleft()
        if msd == root.val:
            leftret = helper(root.left, seq)
            seq.appendleft(msd)
            rightret = helper(root.right, seq)
            return leftret or rightret
        else:
            return False

    return helper(root, seq_q)

if __name__ == '__main__':
    root = build_binary_tree([1, 0, 1, None, 1, 6, 5])
    print(find_path(root, [1, 1, 6]))


###### ESSE SCRIPT ESTA OBSOLETO, CONTINUA AQUI PARA REGISTRAR AS TENTATIVAS DE DIVERSAS TECNICAS ######

###### ESSE SCRIPT TAMBEM CONTEM O CODIGO PARA GERAR AS IMAGENS #######
#TODO: Integrar codigo que gera as imagens ao script principal

# %%imports & func
import os
import pandas as pd
import re
import spacy
import numpy as np
import matplotlib.pyplot as plt

from collections import Counter
from nltk.corpus import stopwords
from nltk.stem.snowball import SnowballStemmer
from sklearn.feature_extraction.text import CountVectorizer
from skmultilearn.problem_transform import BinaryRelevance, LabelPowerset
from sklearn.model_selection import KFold
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.metrics import hamming_loss, accuracy_score
import seaborn as sns

def clean_text(msg):
    msg = msg.lower()
    msg = re.sub("[^a-zA-Z]", " ", msg)
    msg = " ".join(msg.split())
    return msg

def stemming(msg):
    msg = clean_text(msg)
    stemmer = SnowballStemmer(language="english")
    wordlist = [
        stemmer.stem(word)
        for word in msg.split()
        if word not in set(stopwords.words("english"))
    ]
    msg = " ".join(wordlist)
    return msg

def lemmatization(msg):
    msg = clean_text(msg)
    doc = nlp(msg)
    tokenlist = [
        token.lemma_ for token in doc if str(token) not in set(nlp.Defaults.stop_words)
    ]
    msg = " ".join(tokenlist)
    return msg

def word_freq(wordlist, n):
    big_sen = ""

    for sen in wordlist:
        big_sen += sen

    return Counter(big_sen.split()).most_common(n)

STOPWORDS = [
    "a",
    "e",
    "n",
    "s",
    "m",
    "o",
    "br",
    "ls",
    "www",
    "com",
    "fot",
    "cs",
    "hayasa",
    "apollo",
]

# %%Parameters part 1
norm = lemmatization  # stemming, lemmatization
stopwords_cond = True  # True, False

# %%Adding stopwords
nlp = spacy.load("en_core_web_sm")

if stopwords_cond:
    for word in nlp.Defaults.stop_words:
        lex = nlp.vocab[word]
        lex.is_stop = True

    stopwords.words("english").extend(STOPWORDS)

    nlp.Defaults.stop_words |= set(STOPWORDS)

# %%Loading dataset
dataset = pd.read_excel("Datasets/Dataset OneHot.xlsx")
labels_dataframe = dataset.iloc[:, 1:]

# %%Visualizing classes
sns.set()
sns.set_style("darkgrid")
plt.subplots(figsize=(10, 9))

sum_msgs = labels_dataframe.sum(axis=0).sort_values(ascending=False)

ax = sns.barplot(y=labels_dataframe.columns.values, x=sum_msgs, color="#B1587E")

for i, val in enumerate(sum_msgs):
    ax.text(val + 30, i, val, color="black", va="center", fontsize=10)

plt.ylabel("Ato de Fala", fontsize=13)
plt.xlabel("Contagem", fontsize=13)
plt.title("Contagem de mensagens por Ato de Fala", fontsize=16)

plt.savefig("cont msgs.png", dpi=300)

# %%Visualizing classes
sns.set_style("white")

count_lbl = (
    pd.DataFrame(labels_dataframe.sum(axis=1).sort_values(ascending=False))
    .reset_index()
    .groupby(0)
    .count()
    .reset_index()
    .rename(columns={0: "num_lbl", "index": "count"})
)

plt.subplots(figsize=(10, 9))
ax = sns.barplot(x=count_lbl["num_lbl"], y=count_lbl["count"], color="#833788")

for i, num_lbl, count in count_lbl.itertuples():
    ax.text(i, count + 30, count, color="black", ha="center", fontsize=11)

plt.xlabel("Quantidade de labels na mensagem", fontsize=13)
plt.ylabel("Número de mensagens", fontsize=13)
plt.title("Número de mensagens por quantidade de labels", fontsize=16)

# plt.savefig('count lbl.png', dpi=300)
# %%Visualizing classes
sns.set_style("ticks")

len_msgs = [len(msg) for msg in dataset["msgContent"]]

plt.subplots(figsize=(10, 9))
sns.distplot(len_msgs, hist=False, color="black")
plt.xlabel("Tamanho da mensagem (quantidade de caracteres)", fontsize=13)
plt.title("Histograma de frequencia do tamanho das mensagens", fontsize=16)

plt.savefig("hist_freq.png", dpi=300)
# %%Visualizing classes

len_msgs = [len(msg) for msg in dataset["msgContent"] if len(msg) <= 500]

plt.subplots(figsize=(10, 9))
sns.distplot(len_msgs, bins=20, kde=False, hist_kws=dict(alpha=1), color="#635751")
plt.xlabel("Tamanho da mensagem (quantidade de caracteres)", fontsize=13)
plt.title(
    "Histograma do tamanho das mensagens com tamanho menor ou igual a 500", fontsize=16
)

plt.savefig("hist_tam_msgs.png", dpi=300)
# %%Corpus creation
corpus = [norm(msg) for msg in list(dataset["msgContent"])]

# %%Parameters part 2
method = BinaryRelevance  # BinaryRelevance, LabelPowerset
classifier = LogisticRegression  # LogisticRegression, SVC, GaussianNB
max_iterations = 40
max_ft = 2000
k = 5

# %%Creating model & splitting dataset

# Creating the Bag of Words model
cv = CountVectorizer(max_features=max_ft)
X = cv.fit_transform(corpus)

y = labels_dataframe.values

acc_array = []
hamm_loss_array = []

# Splitting the dataset into training and test sets
kf = KFold(n_splits=k)

for train_index, test_index in kf.split(X):
    X_train, X_test, y_train, y_test = (
        X[train_index],
        X[test_index],
        y[train_index],
        y[test_index],
    )

    cf = method(classifier(max_iter=max_iterations, random_state=42))
    cf.fit(X_train, y_train)
    y_pred = cf.predict(X_test)

    acc_array.append(accuracy_score(y_test, y_pred))
    hamm_loss_array.append(hamming_loss(y_test, y_pred))

acc = np.mean(acc_array)
hamm_loss = np.mean(hamm_loss_array)

# -------

my_msg = dataset.iloc[4562]["msgContent"]

my_msg_clean = clean_text(my_msg)
my_msg_stem = stemming(my_msg)
my_msg_lemma = lemmatization(my_msg)

wordlist = [
    word for word in my_msg_clean.split() if word not in set(stopwords.words("english"))
]

msg_stpwd = " ".join(wordlist)

doc = nlp(msg_stpwd)
tokenlist = [token.lemma_ for token in doc]
msg_lem = " ".join(tokenlist)

my_msg = list([my_msg])
my_X = cv.transform(my_msg)

my_pred = cf.predict(my_X)

my_pred = my_pred.todense()

# Printing used parameters
print("\n\033[4mParameters:\033[0m\n")
print(f"Normalization: {norm.__name__}")
print(f"\nMethod: {method.__name__}")
print(f"Classifier: {classifier.__name__}")
print(f"Max iterations: {max_iterations}")
print(f"Max features: {max_ft}")
print(f"k: {k}")

# Printing results
print("\n\033[4mMetrics:\033[0m\n")
print(f"Accuracy: {acc:.2%}")
print(f"Hamming Loss: {hamm_loss:.2%}")


from django.urls import path
from .views import *

urlpatterns = [
    path('', qna_board, name="qna_board"),
    path('<str:id>', qna_detail, name="qna_detail"),
    path('qna_new/', qna_new, name="qna_new"),
    path('qna_create/', qna_create, name="qna_create"),
    path('qna_edit/<str:id>', qna_edit, name="qna_edit"),
    path('qna_update/<str:id>', qna_update, name="qna_update"),
    path('qna_delete/<str:id>', qna_delete, name="qna_delete"),
    path('comment_new/<str:post_id>', comment_new, name='comment_new'),
    path('update/comment_new/<str:comment_id>', comment_update, name='comment_update'),
    path('delete/comment_new/<str:comment_id>', comment_delete, name='comment_delete'),
]


import numpy as np
import pandas as pd
from sklearn import metrics
import datetime

stim_path = 'organized/stim_times/stimTimes_835HLS1left_0.csv'
#file_path = 'organized/835HLS1right_1/dff_835HLS1right_1.csv'

df = pd.read_csv('scaled_835leftHLS1_sensory0.csv')
#df2 = df.copy(deep=True)

print(df.head())
print(df.dtypes)

###Initialize Variables

dFF = 'dFF'
time = 'Time'
zdFF = 'zDFF'

### Get stimulation timepoints and sync them
stimsDF = pd.read_csv(stim_path, names=['file', 'index', 'timestamps', 'limb', 'stim_type'])
time_list = stimsDF['timestamps'].tolist()
stims = []
for t in range(len(time_list)):
    try:
        date_time = datetime.datetime.strptime(time_list[t], "%M:%S.%f")
    except:
        stims.append(float(time_list[t]))
        continue
    a_timedelta = date_time - datetime.datetime(1900, 1, 1)
    seconds = a_timedelta.total_seconds()
    stims.append(seconds)
print("Stims:", stims)

#get synced trial times
cal_start = 8.0644
vid_start = 5.647
trials = []
for count in range(len(stims)):
    trial= stims[count] - vid_start + cal_start
    trials.append(trial)

### Whole Trace calculations
median = round(float(np.median(df['dFF'])),4)
sd     = round(float(np.std(df['dFF'])),4)
mean   = round(float(np.mean(df['dFF'])),4)

prc50 = np.percentile(df['dFF'],50)
#print(prc50)

meanLT50 = np.mean(df['dFF'].loc[df['dFF'] <= prc50])
medLT50 = np.median(df['dFF'].loc[df['dFF'] <= prc50])
sdLT50 = np.std(df['dFF'].loc[df['dFF'] <= prc50])

thresholdMed = median + (2*sd)

### Calculate z-score dFF
df['zDFF'] = (df['dFF'] - meanLT50) / sdLT50
sdZDFF= np.std(df['zDFF'])

prc50Z = np.percentile(df['zDFF'],50)
sdLT50Z = np.std(df['zDFF'].loc[df['zDFF'] <= prc50Z])

### Calculate mean and standard deviation for the (X) seconds before stimulation
baselines = []
sds       = []
for stim in trials:
     begin = stim - 3.0
     end   = stim

     in_between = df['Time'].between(begin, end, inclusive=True)

     baselines.append(np.mean(df['dFF'].loc[in_between]))
     sds.append(np.std(df['dFF'].loc[in_between]))

### Calculate AUC while above threshold

##Find AUC
aucBeforeStim = []
aucAfterStim  = []
aucDuringPeak = []
aucDuringPeakZ = []
aucBeforeStimZ = []
aucDuringPeakMean =[]

durationsMed = []
durationsMean = []
durationsZ = []

# Get thresholds for latency of response

latencyMed = []
latencyMean = []
latencyZ = []

no_cross=0
for i in range(len(trials)-1):
    auc1start = trials[i] - 3
    auc1end   = trials[i]
    auc2start = trials[i]
    auc2end   = trials[i] + 5
    stim1 = trials[i]
    stim2 = trials[i+1]

    in_between1 = df['Time'].between(auc1start, auc1end, inclusive=True)
    in_between2 = df['Time'].between(auc2start, auc2end, inclusive=True)
    peak_indx = df.index[(df['Time'].between(stim1,stim2)) & (df['dFF'] >= medLT50)].tolist()
    peak_indxMean = df.index[(df['Time'].between(stim1,stim2)) & (df['dFF'] >= baselines[i])].tolist()
    peak_indxZ = df.index[(df['Time'].between(stim1,stim2)) & (df['zDFF'] >= 1.65)].tolist()
    try:
        peak_start = peak_indx[0]
        peak_end   = peak_indx[-1]
        peak_startMean= peak_indxMean[0]
        peak_endMean = peak_indxMean[-1]
        peak_startZ = peak_indxZ[0]
        peak_endZ   = peak_indxZ[-1]
    except:
        print(i)
        no_cross+=1
        continue

    ##Get duration while response was above threshold
    duration = df['Time'].iloc[peak_end] - df['Time'].iloc[peak_start]
    durationsMed.append(duration)
    duration2 = df['Time'].iloc[peak_endMean] - df['Time'].iloc[peak_startMean]
    durationsMean.append(duration2)
    duration3 = df['Time'].iloc[peak_endZ] - df['Time'].iloc[peak_startZ]
    durationsZ.append(duration3)

    ## Get latency of response

    #AUC 3 sec before Stim
    auc1 = metrics.auc(df['Time'].loc[in_between1], df['dFF'].loc[in_between1])
    aucBeforeStim.append(auc1)
    #AUC 5 sec after stim
    auc2 = metrics.auc(df['Time'].loc[in_between2], df['dFF'].loc[in_between2])
    aucAfterStim.append(auc2)
    #AUC during peak Median
    auc3= metrics.auc(df['Time'].iloc[peak_start:peak_end], df['dFF'].iloc[peak_start:peak_end])
    aucDuringPeak.append(auc3)
    #AUC during peak Mean
    auc4= metrics.auc(df['Time'].iloc[peak_startMean:peak_endMean], df['dFF'].iloc[peak_startMean:peak_endMean])
    aucDuringPeakMean.append(auc4)
    ##zDFF calculations
    auc5= metrics.auc(df['Time'].iloc[peak_startZ:peak_endZ], df['zDFF'].iloc[peak_startZ:peak_endZ])
    aucDuringPeakZ.append(auc5)
    auc6= auc1 = metrics.auc(df['Time'].loc[in_between1], df['zDFF'].loc[in_between1])
    aucBeforeStimZ.append(auc6)

# roundList = [baselines, durationsMed, aucBeforeStim, aucAfterStim, aucDuringPeak,
#             aucDuringPeakZ, aucBeforeStimZ]

# for variable in roundList:
#     variable = [round(num, 4) for num in variable]
#     print(variable)

### And make it pretty (Like Emily <3) :))

#Auc Rounds
baselines      = [round(num, 4) for num in baselines]
aucBeforeStim  = [round(num, 4) for num in aucBeforeStim]
aucAfterStim   = [round(num, 4) for num in aucAfterStim]
aucDuringPeak  = [round(num, 4) for num in aucDuringPeak]
aucDuringPeakZ = [round(num, 4) for num in aucDuringPeakZ]
aucBeforeStimZ = [round(num, 4) for num in aucBeforeStimZ]
aucDuringPeakMean = [round(num, 4) for num in aucDuringPeakMean]

#duration rounds
durationsMed   = [round(num, 4) for num in durationsMed]
durationsMean  =  [round(num, 4) for num in durationsMean]
durationsZ     = [round(num, 4) for num in durationsZ]

### OUTPUTS

print("Number of times didn't cross threshold:", no_cross)
print("\nAUC Before stim:", aucBeforeStim)
print("Mean AUC Before stim:",round(np.mean(aucBeforeStim),4))
print("AUC After stim:", aucAfterStim)
print("Mean AUC After stim:",round(np.mean(aucAfterStim),4))
print("AUC During Peak:", aucDuringPeak)
print("Mean AUC During Peak:", round(np.mean(aucDuringPeak),4))

#### Method 1 calculate AUC with threshold as median
print('\n---------"Method 1"---------\n')
print("Method 1: calculate AUC with threshold as median\n")
print("Median = whole trace without firing (dFF below 50 percentile)")
print("Median:",round(medLT50,4))
print("AUC Before stim:", aucBeforeStim)
print("Mean AUC Before stim:",round(np.mean(aucBeforeStim),4))
print("AUC During Peak:", aucDuringPeak)
print("Mean AUC During Peak:", round(np.mean(aucDuringPeak),4))
print("Duration of response:", durationsMed)
print("Mean of response duration:", round(np.mean(durationsMed),4))

print('\n---------"Method 2"---------\n')
print("Method 2: calculate AUC with threshold as mean 3 seconds before stim")
print("Baselines = mean 3 sec before stim\n")
print("Mean whole trace:", mean)
print("Mean whole trace below 50p:", round(meanLT50,4))
print("Baslines:", baselines)
print("Mean of all baselines", round(np.mean(baselines),4))
print("AUC During Peak:", aucDuringPeakMean)
print("Mean AUC During Peak:", round(np.mean(aucDuringPeakMean),4))
print("Duration of response:", durationsMean)
print("Mean of response duration:", round(np.mean(durationsMean),4))

print('\n---------"Method 3"---------\n')
print("Method 3: Do calculations based on z-scored dFF")
print("Threshold = 1.65 SD (SD = 1 in z-scored dFF\n")

print("SD LT50Z:", round(sdLT50Z,4))
print("AUC Before stim Z:", aucBeforeStimZ)
print("Mean AUC Before stim Z:",round(np.mean(aucBeforeStimZ),4))
print("AUC During Peak Z:", aucDuringPeakZ)
print("Mean AUC During Peak Z:", round(np.mean(aucDuringPeakZ),4))
print("Duration of response:", durationsZ)
print("Mean of response duration:", round(np.mean(durationsZ),4))

print('\n---------"Summary"---------\n')

print("Mean AUC:")
print("Method 1:", round(np.mean(aucDuringPeak),4))
print("Method 2:", round(np.mean(aucDuringPeakMean),4))
print("Method 3:", round(np.mean(aucDuringPeakZ),4))

print("\nMean durations:")
print("Method 1:", round(np.mean(durationsMed),4))
print("Method 2:", round(np.mean(durationsMean),4))
print("Method 3:", round(np.mean(durationsZ),4))

# dfexp.to_csv('thresh_outputTest.csv', index=False)

    # print(df['Time'].iloc[peak_start])
    # print(df['Time'].iloc[peak_end])


import logging
import logging.config
from pathlib import Path

from utils import read_json

def setup_logging(
    save_dir,
    root_dir="./",
    filename=None,
    log_config="logger/logger_config.json",
    default_level=logging.INFO,
):
    """
    setup logging configuration
    """
    log_config = Path(root_dir) / log_config
    if log_config.is_file():
        config = read_json(log_config)
        # modify logging paths based on run config
        for handler_k, handler_v in config["handlers"].items():
            if "filename" in handler_v:
                if filename is None or handler_k != "info_file_handler":
                    handler_v["filename"] = str(save_dir / handler_v["filename"])
                else:
                    handler_v["filename"] = str(save_dir / filename)

        logging.config.dictConfig(config)
    else:
        print(
            "warning: logging configuration file is not found in {}.".format(log_config)
        )
        logging.basicConfig(level=default_level)

LOG_LEVELS = {
    0: logging.WARNING,
    1: logging.INFO,
    2: logging.DEBUG,
}

def get_logger(name, verbosity=2):
    assert (
        verbosity in LOG_LEVELS
    ), "verbosity option {verbosity} is invalid. \
         Valid options are {LOG_LEVELS.keys()}."
    logger = logging.getLogger(name)
    logger.setLevel(LOG_LEVELS[verbosity])
    return logger


import shodan
from messages import *

class CalibreShodan:
    def __init__(self, shodan_key):
        self.api = shodan.Shodan(shodan_key)

    def find_calibre_hosts(self):
        hosts = []
        try:
            results = self.api.search('calibre')

            for result in results['matches']:
                hosts.append(f"{result['ip_str']}:{result['port']}")

        except shodan.APIError as e:
            print_error('Invalid api key')

        return hosts


import sys
input = sys.stdin.readline
from collections import deque

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def nor_bfs(x, y):
    queue = deque()
    queue.append((x, y))
    while queue:
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < n and nor_visited[nx][ny] == 0 and color[x][y] == color[nx][ny]:
                queue.append((nx, ny))
                nor_visited[nx][ny] = 1

def abnor_bfs(x, y):
    queue = deque()
    queue.append((x, y))
    while queue:
        x, y = queue.popleft()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx < n and 0 <= ny < n and abnor_visited[nx][ny] == 0 and abcolor[x][y] == abcolor[nx][ny]:
                queue.append((nx, ny))
                abnor_visited[nx][ny] = 1

n = int(input())

color = []
for _ in range(n):
    color.append(list(input().rstrip()))

abcolor = []
for i in range(n):
    tmp = ''.join(color[i])
    tmp2 = tmp.replace('R', 'G')
    abcolor.append(list(tmp2))

nor_visited = [[0] * n for _ in range(n)]
abnor_visited = [[0] * n for _ in range(n)]
nor = 0
abnor = 0
ans = []
for i in range(n):
    for j in range(n):
        if nor_visited[i][j] == 0:
            nor_bfs(i, j)
            nor += 1
ans.append(nor)
for i in range(n):
    for j in range(n):
        if abnor_visited[i][j] == 0:
            abnor_bfs(i, j)
            abnor += 1
ans.append(abnor)
print(*ans)


from app.core.deps import get_db, Permissions, get_current_active_superuser
from fastapi import APIRouter
from fastapi import Depends
from sqlalchemy.orm import Session
from app.roles.serializers.role import (
    RoleUpdateSerializer,
    RoleCreateSerializer,
    RoleInDBSerializer,
)
from typing import List
from app.roles.daos.role import role_dao
from app.core.logger import LoggingRoute
from app.roles.filters import RoleFilter
from app.roles.permissions import RolePermissions
from fastapi_sqlalchemy_filter import FilterDepends
from typing import Any
from app.users.models import User

router = APIRouter(route_class=LoggingRoute)

@router.post("/", response_model=RoleInDBSerializer)
async def create_role(
    role_in: RoleCreateSerializer,
    db: Session = Depends(get_db),
    _: User = Depends(get_current_active_superuser),
) -> Any:
    """Create user role"""
    return role_dao.get_or_create(db, obj_in=role_in)

@router.get("/", response_model=List[RoleInDBSerializer])
async def read_roles(
    role_filter: RoleFilter = FilterDepends(RoleFilter),
    db: Session = Depends(get_db),
    _: Permissions = Depends(Permissions(RolePermissions.role_list)),
) -> Any:
    """Read user roles"""
    role_filter_dict = role_filter.dict()

    if not any(role_filter_dict.values()):  # Returns True if all values are falsy/None
        return role_dao.get_all(db)

    return role_dao.search(db, role_filter)

@router.patch("/{role_id}", response_model=RoleInDBSerializer)
async def update_role(
    role_id: str,
    role_in: RoleUpdateSerializer,
    db: Session = Depends(get_db),
    _: Permissions = Depends(Permissions(RolePermissions.role_update)),
) -> Any:
    """Update role"""
    # Get the business_partner to be updated
    db_obj = role_dao.get_not_none(db, id=role_id)

    return role_dao.update(db, db_obj=db_obj, obj_in=role_in)


import numpy as np
import pandas as pd
from sklearn import neighbors, tree
from sklearn import cross_validation
from . import Preprocessing
# import Preprocessing as Preprocessing

def excKNN(k, train_data, train_labels, test_data, test_labels):
    errorCount = 0.0
    knnclf = neighbors.KNeighborsClassifier(k, weights='distance')
    knnclf.fit(train_data, train_labels)
    numTestVecs = test_data.shape[0]
    for i in range(numTestVecs):
        classifierResult = knnclf.predict(test_data[i,:].reshape(1,-1))
#         print("the classifier came back with: ", classifierResult ,", the real answer is: " , bank_test_labels_arr[i])
        if (classifierResult != test_labels[i]):
            errorCount += 1.0
    print("the total error rate is: %f",errorCount / float(numTestVecs))

def startClassifyKNN():
	dataSet = Preprocessing.getDataFromCSV()
	train_data, train_labels, train_ids, test_data, test_labels, test_ids = sep_train_test(dataSet)

	train_norm = Preprocessing.completePreprocessing(train_data,train_data)
	test_norm = Preprocessing.completePreprocessing(train_data, test_data)

	knnclf = neighbors.KNeighborsClassifier(5, weights='distance')
	knnclf.fit(train_norm, train_labels)
	trainScore = knnclf.score(train_norm, train_labels)
	testScore = knnclf.score(test_norm, test_labels)
	print(trainScore)
	print(testScore)

def startClassifyTree():
	dataSet = Preprocessing.getDataFromCSV()
	train_data, train_labels, train_ids, test_data, test_labels, test_ids = sep_train_test(dataSet)
	treeclf = tree.DecisionTreeClassifier(criterion='entropy')
	treeclf = treeclf.fit(np.array(train_data), np.array(train_labels))
	print(treeclf.score(train_data, train_labels))
	print(treeclf.score(test_data, test_labels))

def test(cv=30):
	dataSet = Preprocessing.getDataFromCSV()
	data_ = dataSet.iloc[:,1:-1]
	labels_ = dataSet.iloc[:,-1]
	ids_ = dataSet.iloc[:,0]

	data_norm = Preprocessing.completePreprocessing(data_,data_)

	knnclf = neighbors.KNeighborsClassifier(5, algorithm='brute')
	scores_KNN = cross_validation.cross_val_score(knnclf, data_norm, labels_, cv=cv)
	print("Overall Accuracy: %0.2f (+/- %0.2f)" % (scores_KNN.mean(), scores_KNN.std() * 2))

	treeclf = tree.DecisionTreeClassifier(criterion='entropy')
	scores_ = cross_validation.cross_val_score(treeclf, np.array(data_), np.array(labels_), cv=cv)
	print("Overall Accuracy: %0.2f (+/- %0.2f)" % (scores_.mean(), scores_.std() * 2))

def sep_train_test(dataSet, percent_test_cases=0.20):
	random_data_set = dataSet.reindex(np.random.permutation(dataSet.index))
	number_test_cases = int(random_data_set.shape[0]*percent_test_cases)

	test_data = random_data_set.iloc[:number_test_cases,1:-1]
	test_labels = random_data_set.iloc[:number_test_cases,-1]
	test_ids = random_data_set.iloc[:number_test_cases,0]

	train_data = random_data_set.iloc[number_test_cases:,1:-1]
	train_labels = random_data_set.iloc[number_test_cases:,-1]
	train_ids = random_data_set.iloc[number_test_cases:,0]

	return train_data, train_labels, train_ids, test_data, test_labels, test_ids

categories = ['blues','classical','country','hiphop','jazz','metal','pop','punk','reggae','rnb','rock']

def transform_labels_to_numbers(labels_):
	i=0
	categ = np.zeros(shape=labels_.shape)
	for cat in categories:
		catTrues = labels_ == cat
		categ[np.array(catTrues == True)] = i
		i+=1
	return categ

def classify_KNN(k, cv=30):
	dataSet = Preprocessing.getDataFromCSV()
	data_ = dataSet.iloc[:,1:-1]
	labels_ = dataSet.iloc[:,-1]
	ids_ = dataSet.iloc[:,0]
	print("ESTA ACA")
	data_norm = Preprocessing.completePreprocessing(data_,data_)
	print("AVA VA A EHECUTAR ",data_norm.shape)
	knnclf = neighbors.KNeighborsClassifier(k, algorithm='auto')
	scores_KNN = cross_validation.cross_val_score(knnclf, data_norm, labels_, cv=cv)
	return "%0.2f (+/- %0.2f)" % (scores_KNN.mean(), scores_KNN.std() * 2)

def classify_Tree(cv=30):
	dataSet = Preprocessing.getDataFromCSV()
	data_ = dataSet.iloc[:,1:-1]
	labels_ = dataSet.iloc[:,-1]
	ids_ = dataSet.iloc[:,0]
	treeclf = tree.DecisionTreeClassifier(criterion='entropy')
	scores_ = cross_validation.cross_val_score(treeclf, np.array(data_), np.array(labels_), cv=cv)
	return "%0.2f (+/- %0.2f)" % (scores_.mean(), scores_.std() * 2)

def classify_song_tree(song):
	dataSet = Preprocessing.getDataFromCSV()
	data_ = dataSet.iloc[:,1:-1]
	labels_ = dataSet.iloc[:,-1]
	ids_ = dataSet.iloc[:,0]
	treeclf = tree.DecisionTreeClassifier(criterion='entropy')
	treeclf.fit(data_,labels_)
	category = treeclf.predict(song)
	return category[0]

# classify_KNN(3)
# startClassifyKNN()
# startClassifyTree()
# test()
# print(classify_KNN(20))


import random as rd
import datetime
import time

# PLAYER 1 ATTACKING PLAYER 2 (CHECK BEFOREHAND THEY HAVE ENOUGH LIFE)
def combat(player1, player2):
    if player1.cannot_attack == True or player2.immune == True or player2.sneak == True:
        print('Player 1 cannot attack, so no combat!')
        return None

    # If a player is frozen, then they automatically lose a life and are unfrozen
    if player2.cannot_attack == True:
            player2.hp -= 1
            player2.cannot_attack = False
            print('Player 2 was frozen!')
            return True
    player1_combat = rd.randint(1, 20)
    player2_combat = rd.randint(1, 20)
    player1_combat += player1.attack_bonus
    player2_combat += player2.defense_bonus
    if player1_combat > player2_combat:
        player2.hp -= 1
        print('Player 1 wins!')
        return True
    elif player2_combat > player1_combat:
        player1.hp -= 1
        print('Player 2 wins!')
        return False
    else:
        print("It's a tie!")
        return None
    return None

class Player:
    # Initialize the player

    def __init__(self):
        self.hp = 20
        self.inventory = []

        # Keep track of capabilites for fighting
        self.cannot_attack = False
        self.cannot_attack_time = None

        # To keep track of immune
        self.immune = False
        self.time_of_immune = None

        self.attack_bonus = 0
        self.defense_bonus = 0

class Wizard(Player):
    def __init__(self):
        Player.__init__(self)
        self.cast_freeze = False
        self.sneak = False
        self.cast_freeze_date = None

    def fireball(self, player2):
        self.attack_bonus += 2
        combat(self, player2)
        self.attack_bonus -= 2

    def freeze(self, player2):
        if not self.cast_freeze:
            player2.cannot_attack = True
            player2.cannot_attack_time = time.time()
            self.cast_freeze = True
            self.cast_freeze_date = datetime.datetime.now().date()
        else:
            print("You cannot cast that again for another day.")

    def check(self):
        if self.immune == True:
            # Measures in seconds
            if self.time_of_immune <= time.time() - 1800:
                self.immune = False
                self.time_of_immune = None

        if self.cannot_attack == True:
            # Measures in seconds
            if self.cannot_attack_time <= time.time() - 1800:
                self.cannot_attack = False
                self.cannot_attack_time = None

        if self.cast_freeze == True:
            if datetime.datetime.now().date() != self.case_freeze_date:
                self.cast_freeze = False
                self.cast_freeze_date = None

class Warrior(Player):
    def __init__(self):
        Player.__init__(self)
        self.defensive_maneuver = False
        self.defensive_maneuver_time = None
        self.cast_defensive_maneuver = False
        self.defensive_maneuver_cast_time = None
        self.sneak = False

    def rend(self, player2):
        self.attack_bonus += 2
        combat(self, player2)
        self.attack_bonus -= 2

    def defensive_manuever(self):
        if self.cast_defensive_maneuver == False:
            self.defense_bonus += 2
            self.defensive_maneuver = True
            self.cast_defensive_maneuver = True
            self.defensive_maneuver_time = time.time()
            self.defensive_maneuver_cast_time = datetime.datetime.now().date()
        else:
            print("You cannot cast that again for another day.")

    def check(self):
        if self.immune == True:
            # Measures in seconds
            if self.time_of_immune <= time.time() - 1800:
                self.immune = False
                self.time_of_immune = None

        if self.cannot_attack == True:
            # Measures in seconds
            if self.cannot_attack_time <= time.time() - 1800:
                self.cannot_attack = False
                self.cannot_attack_time = None

        if self.defensive_maneuver == True:
            if self.defensive_maneuver_time <= time.time() - 1800:
                self.defnesive_maneuver = False
                self.defensive_maneuver_time = None
                self.defense_bonus -= 2

        if self.cast_defensive_maneuver == True:
            if self.defensive_maneuver_cast_time != datetime.datetime.now().date():
                self.cast_defensive_maneuver = False
                self.defensive_maneuver_cast_time = False

class Rogue(Player):
    def __init__(self):
        Player.__init__(self)
        self.sneak = False
        self.sneak_time = None
        self.sneak_cast = False
        self.sneak_cast_time = None

    def backstab(self, player2):
        x = player2.defense_bonus
        player2.defense_bonus = 0
        combat(self, player2)
        player2.defense_bonus = x

    def sneak(self):
        if self.sneak_cast == False:
            self.sneak = True
            self.sneak_time = time.time()
            self.sneak_cast = True
            self.sneak_cast_time = datetime.datetime.now().date()
        else:
            print("You cannot cast that again for another day.")

    def check(self):
        if self.immune == True:
            # Measures in seconds
            if self.time_of_immune <= time.time() - 1800:
                self.immune = False
                self.time_of_immune = None

        if self.cannot_attack == True:
            # Measures in seconds
            if self.cannot_attack_time <= time.time() - 1800:
                self.cannot_attack = False
                self.cannot_attack_time = None

        if self.sneak == True:
            if self.sneak_time <= time.time() - 1800:
                self.sneak = False
                self.sneak_time = None

        if self.sneak_cast == True:
            if self.sneak_cast_time != datetime.datetime.now().date():
                self.sneak_cast = False
                self.sneak_cast_time = False

x = Warrior()
y = Wizard()
print(x.hp)
print(y.hp)
x.rend(y)
print(x.hp)
print(y.hp)
y.fireball(x)
print(x.hp)
print(y.hp)
y.freeze(x)
combat(y,x)
print(x.hp)
print(y.hp)


from data.data_manager import DataManager
import pandas as pd
from sqlalchemy import create_engine

# K线切分, 分为x,y; y= 1day reward 3day reward 5day reward;
# 特征抽取:
    #1、最简单对K线的Summery
# 计算不同特征的Reward, 存入数据库; feature, feature_type, stock_code,stock_name, trade_day, reward_1d,reward_3d,reward_5d,reward_10d
# 对所有特征进行统计分析得到解结论

dm = DataManager()
stock_basic = dm.get_stock_basic()

FE_TYPE_PCT_2 = "pct_2"
sql_engine = create_engine("mysql+mysqlconnector://root:k135792684@127.0.0.1:3306/quant?auth_plugin=mysql_native_password", echo=False)

def analysis():
    if_exists = "replace"
    for idx,itm in stock_basic.iterrows():
        if idx !=0:
            if_exists="append"
        print(idx,itm['ts_code'])
        res = analysis_stock(itm['ts_code'],start_date="20110201")
        res.to_sql(name="stock_analysis1", con=sql_engine, if_exists=if_exists)
        #df = dm.k_line_daily(code=itm['ts_code'])

#获取变化率
def change_rate(cur_price,pre_price,type="pct"):

    res = (cur_price/pre_price-1)*100
    if type == FE_TYPE_PCT_2:
        if res >=9.5:res = 9
        elif res>=5:res =5
        elif res>=3:res=3
        elif res>=1:res =1
        elif res>=0:res=0
        elif res>-1:res=-0
        elif res>-3:res=-1
        elif res>-5:res=-3
        elif res>-9.5:res=-5
        else: res=-9
    return round(res,2)

def fe_kline_base(open,close,high,low,pre_close):
    res = ''
    res += str(change_rate(open,pre_close,type=FE_TYPE_PCT_2))
    res += str(change_rate(close,pre_close,type=FE_TYPE_PCT_2))
    res += str(change_rate(high,pre_close,type=FE_TYPE_PCT_2))
    res += str(change_rate(low,pre_close,type=FE_TYPE_PCT_2))
    return res

def get_reward(df,close,cur_idx,reward_day):
    #row_size = df.shape[0]
    idx = cur_idx - reward_day #0是最近一天
    if idx<0:   #row_size-1:
        return 0
    else:
        #print(df.loc[idx])
        end_close = df.loc[idx]["close"]
        return change_rate(end_close,close)

def analysis_stock(code,start_date):
    df = dm.k_line_daily(code,start_date)
    #df = df.sort_values(by=["trade_date"],ascending=[True])
    res = pd.DataFrame()
    for idx, itm in df.iterrows():
        fe_kine_pct2 = fe_kline_base(itm["open"],itm["close"],itm["high"],itm["low"],itm["pre_close"])
        close =itm["close"]
        stock_code =itm["ts_code"]
        trade_date =itm["trade_date"]
        #print(idx)
        reward_1d = get_reward(df,close,idx,1)
        reward_3d = get_reward(df,close,idx,3)
        reward_5d = get_reward(df,close,idx,5)
        reward_10d = get_reward(df,close,idx,10)
        data={"stock_code":stock_code,"trade_date":trade_date,
                "feature":fe_kine_pct2,"feature_type":'pct_2',
                "reward_1d":reward_1d,"reward_3d":reward_3d,
                "reward_5d":reward_5d,"reward_10d":reward_10d}

        #feature, feature_type, stock_code,stock_name, trade_day, reward_1d,reward_3d,reward_5d,reward_10d
        #df1 = pd.DataFrame(data=[[itm["ts_code"],itm["trade_date"],fe_kine_pct2,'pct_2',reward_1d,reward_3d,reward_5d,reward_10d]],
        #                   columns=["stock_code","trade_date","feature","feature_type","reward_1d","reward_3d","reward_5d","reward_10d"],
        #                   index=[idx])
        res =res.append(data,ignore_index=True)
        #print(res)
        #print(idx,itm["trade_date"],fe_kine_pct2,reward_1d,reward_3d,reward_5d,reward_10d)
        #print(idx,itm["open"],itm["close"],itm["high"],itm["low"],itm["pre_close"])
        #print(changeprate(itm["open"],itm["pre_close"]),change_rate(itm["close"],itm["pre_close"]))

    return res

#analysis_stock("000565.SZ")

analysis()


import re
import json
from tqdm import tqdm

def get_cmg_from_output(filename, tempfile):
    outl = open(filename, 'r').read().split('<nl>')
    with open(tempfile) as f:
        temp = json.load(f)
    print(len(outl))

    if 'response_split' not in temp:
        print('Do not have response_split feild in temp file')
        return

    f = open(temp['response_split'], 'w')

    for idx, line in tqdm(enumerate(outl)):
        #set idx for debug time
        if idx > 100000:
            continue
        line = line.strip()
        try:
            line = line.split('Short commit message:')[1]
        except:
            print(line)
            line = ""
        line = line.strip()
        f.write(line + '\n')


from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy as _

from django.conf import settings

if "notification" in settings.INSTALLED_APPS:
    from notification import models as notification
else:
    notification = None

from newprojects.models import Project, ProjectMember
from newprojects.forms import ProjectForm, ProjectUpdateForm

TOPIC_COUNT_SQL = """
SELECT COUNT(*)
FROM topics_topic
WHERE
    topics_topic.object_id = newprojects_project.id AND
    topics_topic.content_type_id = %s
"""
MEMBER_COUNT_SQL = """
SELECT COUNT(*)
FROM newprojects_projectmember
WHERE newprojects_projectmember.project_id = newprojects_project.id
"""

@login_required
def create(request, form_class=ProjectForm, template_name="newprojects/create.html"):
    project_form = form_class(request.POST or None)

    if project_form.is_valid():
        project = project_form.save(commit=False)
        project.creator = request.user
        project.save()
        project_member = ProjectMember(project=project, user=request.user)
        project.members.add(project_member)
        project_member.save()
        if notification:
            # @@@ might be worth having a shortcut for sending to all users
            notification.send(User.objects.all(), "projects_new_project",
                {"project": project}, queue=True)
        return HttpResponseRedirect(project.get_absolute_url())

    return render_to_response(template_name, {
        "project_form": project_form,
    }, context_instance=RequestContext(request))

def projects(request, template_name="newprojects/projects.html"):

    projects = Project.objects.all()

    search_terms = request.GET.get('search', '')
    if search_terms:
        projects = (projects.filter(name__icontains=search_terms) |
            projects.filter(description__icontains=search_terms))

    content_type = ContentType.objects.get_for_model(Project)

    projects = projects.extra(select=SortedDict([
        ('member_count', MEMBER_COUNT_SQL),
        ('topic_count', TOPIC_COUNT_SQL),
    ]), select_params=(content_type.id,))

    return render_to_response(template_name, {
        'projects': projects,
        'search_terms': search_terms,
    }, context_instance=RequestContext(request))

def delete(request, group_slug=None, redirect_url=None):
    project = get_object_or_404(Project, slug=group_slug)
    if not redirect_url:
        redirect_url = reverse('project_list')

    # @@@ eventually, we'll remove restriction that project.creator can't leave project but we'll still require project.members.all().count() == 1
    if (request.user.is_authenticated() and request.method == "POST" and
            request.user == project.creator and project.members.all().count() == 1):
        project.delete()
        request.user.message_set.create(message=_("Project %(project_name)s deleted.") % {"project_name": project.name})
        # no notification required as the deleter must be the only member

    return HttpResponseRedirect(redirect_url)

@login_required
def your_projects(request, template_name="newprojects/your_projects.html"):
    return render_to_response(template_name, {
        "projects": Project.objects.filter(members=request.user).order_by("name"),
    }, context_instance=RequestContext(request))

def project(request, group_slug=None, form_class=ProjectUpdateForm,
        template_name="newprojects/project.html"):
    project = get_object_or_404(Project, slug=group_slug)

    project_form = form_class(request.POST or None, instance=project)

    if not request.user.is_authenticated():
        is_member = False
    else:
        is_member = project.user_is_member(request.user)

    action = request.POST.get('action')
    if action == 'update' and project_form.is_valid():
        project = project_form.save()
    elif action == 'join':
        # @@@ should move to a method on the Project model?
        if not is_member:
            project_member = ProjectMember(project=project, user=request.user)
            project.members.add(project_member)
            project_member.save()
            request.user.message_set.create(
                message=_("You have joined the project %(project_name)s") % {"project_name": project.name})
            if notification:
                notification.send([project.creator], "projects_created_new_member", {"user": request.user, "project": project})
                notification.send(project.member_users.all(), "projects_new_member", {"user": request.user, "project": project})
        else:
            request.user.message_set.create(
                message=_("You are already a member of project %(project_name)s") % {"project_name": project.name})
    elif action == 'leave':
        project.members.remove(request.user)
        request.user.message_set.create(message="You have left the project %(project_name)s" % {"project_name": project.name})
        if notification:
            pass # @@@ no notification on departure yet

    # TODO: Shouldn't have to do this in the view. Should write new "groupurl" templatetag :(
    new_topic_url = reverse('topic_list', kwargs=project.get_url_kwargs())

    return render_to_response(template_name, {
        "project_form": project_form,
        "project": project,
        "is_member": is_member,
        "new_topic_url": new_topic_url,
    }, context_instance=RequestContext(request))