import pyglet

import assets
import animation

ui_batch = pyglet.graphics.Batch()
gameover_batch = pyglet.graphics.Batch()

loading_bar_background = [pyglet.shapes.Rectangle(18, 483, 154, 19, (255, 255, 255), ui_batch),
                          pyglet.shapes.Rectangle(728, 483, 154, 19, (255, 255, 255), ui_batch)]
loading_bar_background[0].opacity, loading_bar_background[1].opacity=150, 150
loading_bar = [pyglet.shapes.Rectangle(20, 485, 150, 15, (0, 128, 255), ui_batch),
               pyglet.shapes.Rectangle(730, 485, 150, 15, (0, 128, 255), ui_batch)]

health_bar_background = [pyglet.shapes.Rectangle(18, 258, 19, 184, (0, 0, 0), ui_batch),
                         pyglet.shapes.Rectangle(863, 258, 19, 184, (0, 0, 0), ui_batch)]
health_bar_background[0].opacity, health_bar_background[1].opacity = 150, 150
health_bar = [pyglet.shapes.Rectangle(20, 260, 15, 180, (0, 150, 0), ui_batch),
              pyglet.shapes.Rectangle(865, 260, 15, 180, (0, 150, 0), ui_batch)]

coin_icon = [pyglet.sprite.Sprite(img=animation.coin, x=180, y=480, batch=ui_batch),
             pyglet.sprite.Sprite(img=animation.coin, x=540, y=480, batch=ui_batch)]
coin_icon[0].scale, coin_icon[1].scale = 0.8, 0.8

p1_coin_label = pyglet.text.Label(text= '16000', font_size=13, color=(0, 0, 0, 255), x=205, y=485, batch=ui_batch)
p2_coin_label = pyglet.text.Label(text= '16000', font_size=13, color=(0, 0, 0, 255), x=565, y=485, batch=ui_batch)

level_icon = [pyglet.sprite.Sprite(img=assets.castle, x=270, y=480, batch=ui_batch),
              pyglet.sprite.Sprite(img=assets.castle, x=630, y=480, batch=ui_batch)]
level_icon[0].scale, level_icon[1].scale = 0.9, 0.9

p1_level_label = pyglet.text.Label(text= 'Level: ' + str(1), font_size=13, color=(0, 0, 0, 255), x=295, y=485, batch=ui_batch)
p2_level_label = pyglet.text.Label(text= 'Level: ' + str(1), font_size=13, color=(0, 0, 0, 255), x=655, y=485, batch=ui_batch)

winner_label = pyglet.text.Label(font_size=26, color=(255, 255, 255, 255), x=205, y=210, batch=gameover_batch)
winner_sprite = pyglet.sprite.Sprite(img=assets.gameover[0], x=98, y=300, batch=gameover_batch)
close_window_label = pyglet.text.Label(text="- Press spacebar to close window -",
                    font_size=16, color=(0, 0, 0, 255), x=270, y=30, batch=gameover_batch)

button_icons = [pyglet.sprite.Sprite(img=assets.knight_button, x=20, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.king_button, x=80, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.wizard_button, x=140, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.dragon_button, x=200, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.level_button, x=260, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.meteor_button, x=320, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.knight_button, x=540, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.king_button, x=600, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.wizard_button, x=660, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.dragon_button, x=720, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.level_button, x=780, y=530, batch=ui_batch),
                pyglet.sprite.Sprite(img=assets.meteor_button, x=840, y=530, batch=ui_batch)]

def create_buttons(player_index):
        buttons = []
        if player_index == 0:
            x = 20
        else:
            x = 540

        for i in range(6):
            button = pyglet.shapes.Rectangle(x + i * 60, 530, 40, 40, (255, 255, 255), ui_batch)
            button.opacity = 150
            buttons.append(button)

        return buttons

def scale_button(button, player_index, button_number):
    button.width += 10
    button.height += 10
    button.x -= 3
    button.y -= 3

    n = player_index * 6 + button_number
    button_icons[n].x -= 3
    button_icons[n].y -= 3
    button_icons[n].scale = 1.2

def unscale_button(button, player_index, button_number):
    button.width -= 10
    button.height -= 10
    button.x += 3
    button.y += 3

    n = player_index * 6 + button_number
    button_icons[n].x += 3
    button_icons[n].y += 3
    button_icons[n].scale = 1

def create_button_labels(player_index):
    labels = []
    prices = ['30$', '220$', '400$', '700$', '3000$', '1200$']

    if player_index == 0:
        keys = ['q', 'w', 'e', 'r', 'a', 's']
        m = 20
    else:
        keys = ['u', 'i', 'o', 'p', 'k', 'l']
        m = 540

    n = 0
    for i in keys:
        label = pyglet.text.Label(text=i, font_size=12, color=(0, 0, 0, 255),
                x=m + 15 + n * 60, y=582, batch=ui_batch)
        labels.append(label)
        n += 1

    n = 0
    for j in prices:
        label = pyglet.text.Label(text=j, font_size=10, color=(0, 0, 0, 255),
                x=m + n * 60, y=514, batch=ui_batch)
        labels.append(label)
        n += 1

    return labels

def update_coin_label(coins, player_index):
    if player_index == 0:
        p1_coin_label.text = str(coins)
    else:
        p2_coin_label.text = str(coins)

def update_level_label(level, player_index):
    if player_index == 0:
        p1_level_label.text = 'Level: ' + str(level)
    else:
        p2_level_label.text = 'Level: ' + str(level)

def create_winner_label(loser_index):
    if loser_index == 0:
        winner_label.text = 'Congratulations! Player 2 wins!'
        winner_sprite.image = assets.gameover[1]
    elif loser_index == 1:
        winner_label.text = 'Congratulations! Player 1 wins!'
        winner_sprite.image = assets.gameover[0]


import json
import logging
import random
import string
import sys
import torch
import experiment_utils as utils
from happytransformer import HappyBERT

sys.path.append('../')
from dataset_creation import pre_processing_utils as proc

def run_pipeline(model, fictitious_entities, sentences, config, number_of_entity_trials, logger):
    dataset = proc.prepare_masked_instances(sentences=sentences,
                                            config=config,
                                            fictitious_entities=fictitious_entities,
                                            num_entity_trials=number_of_entity_trials)

    logger.info("finished creating dataset")

    perf = utils.happy_transformer_masked_word_prediction(masked_examples=dataset,
                                                          model=model,
                                                          top_n=100,
                                                          logger=logger)

    logger.info("finished evaluating dataset")

    output_df = utils.convert_bi_statistic_results_into_df(perf)

    return output_df

def main():
    random.seed(1012)
    logging.basicConfig(format = '%(asctime)s - %(levelname)s - %(name)s -   %(message)s',
                        datefmt = '%m/%d/%Y %H:%M:%S',
                        level = logging.INFO)
    logger = logging.getLogger(__name__)
    chars = string.ascii_lowercase
    number_of_entity_trials = 10

    bert_base_cased = HappyBERT("bert-base-cased")

    fictitious_entities = proc.generate_pairs_of_random_strings(number_of_pairs=100,
                                                                min_length=3,
                                                                max_length=12,
                                                                character_set=chars)

    with open("../data/truism_data/physical_data_sentences_2.json", "r") as f:
        physical_sents = json.load(f)

    with open("../data/truism_data/physical_data_2.json", "r") as f:
        physical_config = json.load(f)

    logger.info("finished reading in physical data")

    output_df = run_pipeline(model=bert_base_cased,
                             fictitious_entities=fictitious_entities,
                             sentences=physical_sents,
                             config=physical_config,
                             number_of_entity_trials=number_of_entity_trials,
                             logger=logger)

    output_df.to_csv("../data/masked_word_result_data/bert/bert_physical_perf_{}.csv".format(number_of_entity_trials),
                     index=False)

    logger.info("finished saving physical results")

    with open("../data/truism_data/material_data_sentences_2.json", "r") as f:
        material_sents = json.load(f)

    with open("../data/truism_data/material_data_2.json", "r") as f:
        material_config = json.load(f)

    logger.info("finished reading in material data")

    output_df = run_pipeline(model=bert_base_cased,
                             fictitious_entities=fictitious_entities,
                             sentences=material_sents,
                             config=material_config,
                             number_of_entity_trials=number_of_entity_trials,
                             logger=logger)

    output_df.to_csv("../data/masked_word_result_data/bert/bert_material_perf_{}.csv".format(number_of_entity_trials),
                     index=False)

    logger.info("finished saving material results")

    with open("../data/truism_data/social_data_sentences_2.json", "r") as f:
        social_sents = json.load(f)

    with open("../data/truism_data/social_data_2.json", "r") as f:
        social_config = json.load(f)

    logger.info("finished reading in social data")

    output_df = run_pipeline(model=bert_base_cased,
                             fictitious_entities=fictitious_entities,
                             sentences=social_sents,
                             config=social_config,
                             number_of_entity_trials=number_of_entity_trials,
                             logger=logger)

    output_df.to_csv("../data/masked_word_result_data/bert/bert_social_perf_{}.csv".format(number_of_entity_trials),
                     index=False)

    logger.info("finished saving social results")

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
#
import datetime
import uuid

from wechat.wrapper import WeChatHandler
from wechat.models import *
from codex.baseerror import *
from django.db import transaction
from django.utils import timezone

__author__ = "Epsirom"

class ErrorHandler(WeChatHandler):

    def check(self):
        return True

    def handle(self):
        return self.reply_text('对不起，服务器现在有点忙，暂时不能给您答复 T T')

class DefaultHandler(WeChatHandler):

    def check(self):
        return True

    def handle(self):
        return self.reply_text('对不起，没有找到您需要的信息:(')

class HelpOrSubscribeHandler(WeChatHandler):

    def check(self):
        return self.is_text('帮助', 'help') or self.is_event('scan', 'subscribe') or \
               self.is_event_click(self.view.event_keys['help'])

    def handle(self):
        return self.reply_single_news({
            'Title': self.get_message('help_title'),
            'Description': self.get_message('help_description'),
            'Url': self.url_help(),
        })

class UnbindOrUnsubscribeHandler(WeChatHandler):

    def check(self):
        return self.is_text('解绑') or self.is_event('unsubscribe')

    def handle(self):
        self.user.student_id = ''
        self.user.save()
        return self.reply_text(self.get_message('unbind_account'))

class BindAccountHandler(WeChatHandler):

    def check(self):
        return self.is_text('绑定') or self.is_event_click(self.view.event_keys['account_bind'])

    def handle(self):
        return self.reply_text(self.get_message('bind_account'))

class BookEmptyHandler(WeChatHandler):

    def check(self):
        return self.is_event_click(self.view.event_keys['book_empty'])

    def handle(self):
        return self.reply_text(self.get_message('book_empty'))

# new added handlers
class BookWhatHandler(WeChatHandler):

    def check (self):
        return self.is_text('抢啥') or self.is_event_click(self.view.event_keys['book_what'])

    def handle(self):
        current_time = timezone.now()
        published_acts = Activity.objects.filter(status=Activity.STATUS_PUBLISHED, book_end__gte=current_time)
        if len(published_acts) == 0:
            return self.reply_text('对不起，当前没有活动推荐:(')
        response_news = []
        for act in published_acts:
            response_news.append({
                'Title': act.name,
                'Description': act.description,
                'Url': self.url_activity(act.id),
            })
        return self.reply_news(response_news)

class BookingActivityHandler(WeChatHandler):

    def check (self):
        if self.is_msg_type('text'):
            return self.input['Content'].startswith('抢票 ')
        elif self.is_msg_type('event'):
            return (self.input['Event'] == 'CLICK') and (self.input['EventKey'].startswith(self.view.event_keys['book_header']))
        return False

    def handle(self):
        with transaction.atomic():
            # 测试是否存在此用户
            try:
                user = User.objects.select_for_update().get(open_id=self.user.open_id) # 悲观锁
            except User.DoesNotExist:
                raise BaseError(-1, 'User does not exist.')

            # 测试用户是否绑定
            if not user.student_id:
                return self.reply_text(self.get_message('bind_account'))

            # 处理文本信息的情况
            if self.is_msg_type('text'):
                act_key = self.input['Content'][len("抢票 "):]
                acts = Activity.objects.select_for_update().filter(key=act_key)
            # 处理点击事件的情况
            else:
                act_id = int(self.input['EventKey'].split('_')[-1])
                acts = Activity.objects.select_for_update().filter(id=act_id)

            # 检查活动
            if len(acts) == 0:
                return self.reply_text("【 抢票失败 】 对不起，这儿没有对应的活动:(")
            act = acts[0]
            if act.status != Activity.STATUS_PUBLISHED:
                return self.reply_text("【 抢票失败 】 对不起，这儿没有对应的活动:(")
            current_timestamp = timezone.now().timestamp()
            book_start_timestamp = act.book_start.timestamp()
            book_end_timestamp = act.book_end.timestamp()
            if current_timestamp < book_start_timestamp or book_end_timestamp < current_timestamp:
                return self.reply_text("【 抢票失败 】 对不起，现在不是抢票时间:(")
            if act.remain_tickets <= 0:
                return self.reply_text("【 抢票失败 】 对不起，已经没有余票了:(")

            # 检查重复抢票的情况
            tickets_valid_in_the_same_activity = Ticket.objects.select_for_update().filter(
                student_id = user.student_id,
                activity = act,
                status = Ticket.STATUS_VALID
            )
            if len(tickets_valid_in_the_same_activity) > 0:
                return self.reply_text("【 抢票失败 】 请不要重复抢票")

            tickets_used_in_the_same_activity = Ticket.objects.select_for_update().filter(
                student_id = user.student_id,
                activity = act,
                status = Ticket.STATUS_USED
            )
            if len(tickets_used_in_the_same_activity) > 0:
                return self.reply_text("【 抢票失败 】 请不要重复抢票")

            # 票充足，处理活动表格、电子票表格，失败、成功都则返回对应信息
            act.remain_tickets = act.remain_tickets - 1
            ticket_unique_id = str(uuid.uuid1()) + str(user.student_id)
            if len(ticket_unique_id) > 64:
                ticket_unique_id = ticket_unique_id[:64]
            Ticket.objects.create(
                student_id = user.student_id,
                unique_id = ticket_unique_id,
                activity = act,
                status = Ticket.STATUS_VALID
            )

            act.save()
            return self.reply_single_news({
                'Title': "【 抢票成功 】 " + act.name,
                'Description': act.description,
                'Url': self.url_activity(act.id),
            })

class QueryTicketHandler(WeChatHandler):
    def check(self):
        return self.is_text('查票') or self.is_event_click(self.view.event_keys['get_ticket'])

    def handle(self):
        # 测试是否存在此用户
        try:
            user = User.objects.get(open_id=self.user.open_id)
        except User.DoesNotExist:
            raise BaseError(-1, 'User does not exist.')

        # 测试用户是否绑定
        if not user.student_id:
            return self.reply_text(self.get_message('bind_account'))

        tickets = Ticket.objects.filter(student_id=self.user.student_id, status=Ticket.STATUS_VALID)
        if len(tickets) == 0:
            return self.reply_text("您现在还没有票嗷:)")
        return_info = []
        for ticket in tickets:
            return_info.append({
                'Title': ticket.activity.name,
                'Description': "",
                'Url': self.url_ticket(self.user.open_id, ticket.unique_id),
            })
        return self.reply_news(return_info)

class ExtractTicketHandler(WeChatHandler):
    def check(self):
        if self.is_msg_type('text'):
            return self.input['Content'].startswith('取票 ')
        return False

    def handle(self):
        # 测试是否存在此用户
        try:
            user = User.objects.get(open_id=self.user.open_id)
        except User.DoesNotExist:
            raise BaseError(-1, 'User does not exist.')

        # 测试用户是否绑定
        if not user.student_id:
            return self.reply_text(self.get_message('bind_account'))

        # 检测活动名的合法性
        act_key = self.input['Content'][len('取票 '):]
        acts = Activity.objects.filter(key=act_key, status=Activity.STATUS_PUBLISHED)
        if len(acts) == 0:
            return self.reply_text('【 取票失败 】 活动不存在哦~')
        act = acts[0]

        # 检测是否有未使用的对应活动的票
        tickets = Ticket.objects.filter(student_id=user.student_id, activity=act, status=Ticket.STATUS_VALID)
        if len(tickets) == 0:
            return self.reply_text('【 取票失败 】 您没有此活动中未使用的票嗷！')

        # 检测活动是否开始
        ticket = tickets[0]
        current_timestamp = timezone.now().timestamp()
        start_timestamp = act.start_time.timestamp()
        end_timestamp = act.end_time.timestamp()
        # 开始还是结束后不能取票嘛？
        if current_timestamp > end_timestamp:
            return self.reply_text('【 取票失败 】 活动已经结束！')

        # 取票，不变更数据库
        return self.reply_single_news({
            'Title': "【 取票成功 】 " + act.name,
            'Description': act.description,
            'Url': self.url_activity(act.key),
        })

class RefundTicketHandler(WeChatHandler):
    def check(self):
        if self.is_msg_type('text'):
            return self.input['Content'].startswith('退票 ')
        return False

    def handle(self):
        with transaction.atomic():
            # 测试是否存在此用户
            try:
                user = User.objects.select_for_update().get(open_id=self.user.open_id)
            except User.DoesNotExist:
                raise BaseError(-1, 'User does not exist.')

            # 测试用户是否绑定
            if not user.student_id:
                return self.reply_text(self.get_message('bind_account'))

            # 检测活动名的合法性
            act_key = self.input['Content'][len('退票 '):]
            acts = Activity.objects.select_for_update().filter(key=act_key, status=Activity.STATUS_PUBLISHED)
            if len(acts) == 0:
                return self.reply_text('【 退票失败 】 活动不存在哦~')
            act = acts[0]

            # 检测是否有未使用的对应活动的票
            tickets = Ticket.objects.select_for_update().filter(student_id=user.student_id, activity=act, status=Ticket.STATUS_VALID)
            if len(tickets) == 0:
                return self.reply_text('【 退票失败 】 您没有此活动中未使用的票嗷！')

            # 检测活动是否开始
            ticket = tickets[0]
            current_timestamp = timezone.now().timestamp()
            start_timestamp = act.start_time.timestamp()
            end_timestamp = act.end_time.timestamp()
            # 开始还是结束后不能退票嘛？
            if current_timestamp > end_timestamp:
                return self.reply_text('【 退票失败 】 活动已经结束！')

            # 退票
            ticket.status = Ticket.STATUS_CANCELLED
            ticket.save()
            act.remain_tickets += 1
            act.save()
            return self.reply_single_news({
                'Title': "【 退票成功 】 " + act.name,
                'Description': act.description,
                'Url': self.url_activity(act.key),
            })


from ChebyshevObject import *

class ChebyshevObject2D(ChebyshevObject):

    def __init__(self, sites, oriFun=None, aniFun=None, extent=1, withMP=True, tag=''):
        super().__init__(sites, oriFun, aniFun, extent, withMP, tag, 2)

    def logMeta(self):
        self.log.logThis('#/Cell', ['Min', 'Max', 'Med'], ','.join(['% 4s'] * 3))
        numNeighbors = list(map(len, self.cellAdjacency))
        numParts = list(map(len, self.cellVertexSets))
        numVerts = list(map(len, map(np.concatenate, self.cellVertexSets)))
        for nVals, tag in zip([numNeighbors, numParts, numVerts], ['Adj.', 'Parts', 'Verts']):
            self.log.logThis(tag, [min(nVals), max(nVals), np.median(nVals)], ','.join(['% 4d'] * 3))

    def getSitesSectorGeometry(self, sIdx, di, sJdx, dj):
        return [self.cellSectors[sIdx][di].vertices, self.cellSectors[sJdx][dj].vertices]

    def processDissolvedSectors(self, dData):
        self.cellVertexSets, self.cellPlaneKeys = list(zip(*dData))

    def plot(self, withSites=True, withCentroids=True, withAdjacency=True, withBBs=True, fileName=''):
        if mplMissing:
            warnings.warn('matplotlib missing.')
            return

        fig = plt.figure('Voronoi Plot')
        ax = fig.add_axes([0, 0, 1, 1])

        legendElements = []

        for sIdx in self.sIdxs:
            for cellVerts in self.cellVertexSets[sIdx]:
                ax.fill(cellVerts[:, 0], cellVerts[:, 1], color=self.colors[sIdx] / 255)

        if withAdjacency:
            adjacencyPlot = ax.plot(self.sites[self.cellAdjacencyEdges, 0].T, self.sites[self.cellAdjacencyEdges, 1].T, color='white', linewidth=1, label='Adjacency')
            legendElements.append(adjacencyPlot[0])

        if withSites:
            dirVecs = np.tile([edgeNormals[:4]], [self.numSites, 1, 1]) * self.lambdas.reshape(-1, 4, 1)
            oriPts = self.sites.reshape(-1, 1, 2) + innerNxM(dirVecs, self.Ms) * self.cellScale / 5
            sitesPlot = ax.plot(np.vstack(oriPts[:, [[0, 2], [1, 3]], 0]).T, np.vstack(oriPts[:, [[0, 2], [1, 3]], 1]).T, color='black')
            legendElements.append(ax.scatter([], [], marker='+', color='black', label='Sites'))

        if withCentroids:
            centroidsPlot = ax.scatter(self.cellCentroids[:, 0], self.cellCentroids[:, 1], color='yellow', s=15, label='$L_2$ Centroids')
            legendElements.append(centroidsPlot)

        if withBBs:
            bbCentersPlot = ax.scatter(self.cellBBcenters[:, 0], self.cellBBcenters[:, 1], color='green', s=15, label='$L_\infty$ BB Centers')
            legendElements.append(bbCentersPlot)
            for sIdx in self.sIdxs:
                ax.plot(self.cellBBs[sIdx][[0, 1, 2, 3, 0], 0], self.cellBBs[sIdx][[0, 1, 2, 3, 0], 1], color=self.colors[sIdx] / 255, linewidth=1)

        ax.set_aspect('equal', 'box')
        fig.legend(handles=legendElements, facecolor='gray')
        plt.axis(False)
        if fileName:
            plt.savefig(resDir + fileName)
        plt.show()

    def exportToObj(self, fileName='', withSites=True, withCentroids=True, withAdjacency=True, withBBs=True, numIter=None):
        llPrefix = '' if numIter is None else 'lr%04d_'%numIter
        fileName = fileName if fileName else self.tag + '.obj'

        numVerts = 0
        verts = []
        cells = []
        for sIdx in self.sIdxs:
            for cellVerts in self.cellVertexSets[sIdx]:
                cells.append(np.arange(len(cellVerts)) + numVerts)
                verts.append(cellVerts)
                numVerts += len(cellVerts)

        vertices = [padHor(np.vstack(verts))]
        faces = [cells]
        edges = [[]]
        tags = [llPrefix + 'cells']

        if withSites:
            vertices.append(padHor(self.sites))
            faces.append([])
            edges.append([])
            tags.append(llPrefix + 'sites')

        if withCentroids:
            vertices.append(padHor(self.cellCentroids))
            faces.append([])
            edges.append([])
            tags.append(llPrefix + 'centroids')

        if withAdjacency:
            vertices.append(padHor(self.sites))
            faces.append([])
            edges.append(self.cellAdjacencyEdges)
            tags.append(llPrefix + 'adjacency')

        if withBBs:
            bbVerts = []
            bbEdges = []
            for sIdx in self.sIdxs:
                bbVerts.append(np.vstack([self.cellBBs[sIdx], self.cellBBcenters[sIdx]]))
                bbEdges.append(np.int32([[0, 1], [1, 2], [2, 3], [3, 0]]) + sIdx * 5)

            vertices.append(padHor(np.vstack(bbVerts)))
            faces.append([])
            edges.append(np.vstack(bbEdges))
            tags.append(llPrefix + 'BBs')

        writeObjFile(resDir + llPrefix + fileName, vertices, faces, edges, subTags=tags)

    def exportToSvg(self, fileName='infinityVoronoi.svg', size=512, withSites=True):
        theDom = minidom.parseString('<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"%d\" width=\"%d\"></svg>'%(size, size))
        for sIdx in self.sIdxs:
            g = theDom.createElement('g')
            g.setAttribute('style', 'fill:%s;'%rgb2hex(self.colors[sIdx]))
            theDom.childNodes[0].appendChild(g)
            for cellVerts in self.cellVertexSets[sIdx]:
                p = theDom.createElement('path')
                verts = (cellVerts * [1, -1] + 1) / 2 * size
                p.setAttribute('d', 'M' + (('L%.6f %.6f ' * len(verts))%tuple(verts.ravel()))[1:] + 'Z')
                g.appendChild(p)

        if withSites:
            g = theDom.createElement('g')
            g.setAttribute('style', 'stroke:#000;stroke-width:2px;stroke-linecap:round;')
            theDom.childNodes[0].appendChild(g)
            for sIdx in self.sIdxs:
                aniVecs = edgeNormals[:4] * self.lambdas[sIdx].reshape(-1, 1)
                aniOriVecs = self.sites[sIdx] + np.dot(aniVecs, self.Ms[sIdx].T) * self.cellScale / 5
                aniOriPts = (aniOriVecs * [1, -1] + 1) / 2 * size

                p = theDom.createElement('path')
                p.setAttribute('d', 'M%.6f %.6f L%.6f %.6f'%(aniOriPts[0, 0], aniOriPts[0, 1], aniOriPts[2, 0], aniOriPts[2, 1]))
                g.appendChild(p)

                p = theDom.createElement('path')
                p.setAttribute('d', 'M%.6f %.6f L%.6f %.6f'%(aniOriPts[1, 0], aniOriPts[1, 1], aniOriPts[3, 0], aniOriPts[3, 1]))
                g.appendChild(p)

        fh = open(resDir + fileName, 'w')
        fh.write(theDom.toprettyxml())
        fh.close()

if __name__ == '__main__':

    n = 10
    e = 1.0
    sites = generateJitteredGridPoints(n, 2, e)

    def oriFun(xys):
        xs,ys = xys.T
        uvs = (xys + [0.5,0]) / np.sqrt((xs + 0.5)**2 + ys**2).reshape(-1,1)**3 + (xys - [0.5,0]) / np.sqrt((xs - 0.5)**2 + ys**2).reshape(-1,1)**3
        a = np.arctan2(uvs[:,0], uvs[:,1])
        m = np.abs(xs) < 0.5
        a[m] = np.cos(xs[m] * np.pi) * -np.sign(ys[m]) * np.sign(xs[m])
        return np.pi - a

    def aniFun(xys):
        xs,ys = xys.T
        s = np.min(np.abs(ys + [[0.5], [-0.5]] * np.sin(xs*np.pi)), axis=0)
        s[xs>0.5] = np.abs(0.5 - norm([0.5,0] - xys[xs>0.5]))
        s[xs<-0.5] = np.abs(0.5 - norm([-0.5,0] - xys[xs<-0.5]))
        return np.tile([2-s, np.ones(len(xys))], [2,1]).T

    cObj = ChebyshevObject2D(sites, oriFun, aniFun, e, withMP=True)
    if IN_IDLE:
        # compute the diagram once and plot it
        cObj.computeDiagram()
        cObj.plot()
    else:
        # run the relaxation (156 iterations) and save the demo image as SVG
        cObj.lloydRelax(0.001)
        cObj.exportToSvg()


from telethon import TelegramClient, sync, events
from telethon.tl.types import User
import logging
import app
import threading
from app import  queue, lock, event_to_async, event_to_flask, socketio, threads
from flask_socketio import emit
from datetime import datetime
from time import sleep

client = app.client

class dialog_():
	def __init__(self, dia_obj):
		self.obj = 	dia_obj
		self.id_ = dia_obj.id
		self.hash = dia_obj.entity.access_hash
		self.messages = []
		self.senders = []
		self.name = self.obj.name
		for message in client.iter_messages(self.obj, limit = 10):
			self.messages.append(message.message)
			if self.obj.id != client.get_me().id:
				if message.sender.last_name:
					self.senders.append(str(message.sender.first_name + ' ' + message.sender.last_name))
				else:
					self.senders.append(message.sender.first_name)
			else:
				user = client.get_me()
				if user.last_name:
					self.senders.append(user.first_name + ' ' + user.last_name)
				else:
					self.senders.append(user.first.name)

		self.messages.reverse()
		if self.obj.id != client.get_me().id:
			self.senders.reverse()

	def __repr__(self):
		return "id {} hash {} messages {} senders{}".format(self.id_, self.hash, self.messages, self.senders)

@client.on(events.NewMessage)
async def new_message_event(event):
	try:
		chat_user_id = event.message.to_id.user_id
		endpoint_id = None
		sender = await event.get_sender()
		if chat_user_id == dia[-1].id_:
			endpoint_id = sender.id
		else :
			endpoint_id = chat_user_id
	except:
		endpoint_id = -1
	for obj in dia:
		if obj.id_ == endpoint_id:
			obj.messages.append(event.message.message)
			msg = obj.messages[-1]
			name = obj.obj.name
			i = dia.index(obj) + 1
	try:
		print(msg)
	except:
		print('ошибка!!!')
	try:
		lock.acquire()
		queue.put((i,msg,name))
	except:
		pass
	finally:
		lock.release()
	event_to_flask.set()
	event_to_async.wait()
	event_to_async.clear()

def resender_kek(): #no use in this one. Gonna keep it as a fun feature
	#TODO integrate it in the working process
	#TODO create a client func to activate this one
	while True:
		sleep(5)
		d = datetime.now()
		socketio.emit('timer', {
		'data': str(d)
	}, namespace = '/main')

def resender():
	while True:
		event_to_flask.wait()
		event_to_flask.clear()
		try:
			lock.acquire()
			id_, msg, name  = queue.get()
		finally:
			lock.release()
		socketio.emit('get_new_message', {
		'id': str(id_),
		'message': str(msg),
		'name': name
	}, namespace = '/main')
		event_to_async.set()

def start(client):
	client.start()
	logging.basicConfig(level=logging.ERROR)
	dia = getting_data(client)
	print(dia[-1].messages)
	return dia

def getting_data(client):
	dialogs = client.get_dialogs()
	dia = []
	for ent in dialogs:
		try:
			if type(ent.entity) == User:
				#TODO get rid of botssssss (or better a special option for it ) or just mark them as bots
				if ent.id == client.get_me().id:
					myself = dialog_(dia_obj =ent)
				else:
					obj = dialog_(dia_obj = ent)
					dia.append(obj)
		except:
			pass
	dia.append(myself)
	return dia

dia = start(client)


import sys
import numpy as np
import random
from tqdm import tqdm_notebook

import pickle

def enumerate_grammar(t):
    grammar = set()
    if t.terminal:
        return(grammar)
    grammar.add(t.data)
    if t.left:
        grammar = grammar | enumerate_grammar(t.left)
    if t.right:
        grammar = grammar | enumerate_grammar(t.right)
    return(grammar)

def build_pcfg(training_trees, grammar, lexicon):
    grammar_pcfg = {k : dict() for k in grammar}
    lexicon_pcfg = {k : dict() for k in lexicon}
    # Fonction annexe pour parcourir les arbres
    def rec_on_tree(t):

        if t.terminal:
            return

        for u in [t.data]+t.units:
            if u in grammar_pcfg:
                next_seq = ""
                for c in t.get_children():
                    if c.terminal:
                        lexicon_pcfg[c.data.lower()][u] = lexicon_pcfg[c.data.lower()].get(u,0) + 1
                        continue
                    next_seq += c.data + "-"

                if len(next_seq) > 0:
                    grammar_pcfg[u][next_seq[:-1]] = grammar_pcfg[u].get(next_seq[:-1],0) + 1

        for c in t.get_children():
            rec_on_tree(c)

    for t in training_trees:
        rec_on_tree(t)

    for i in grammar_pcfg.keys():
        s = sum(grammar_pcfg[i].values())
        for j in grammar_pcfg[i].keys():
            grammar_pcfg[i][j] /= s

    for i in lexicon_pcfg.keys():
        s = sum(lexicon_pcfg[i].values())
        for j in lexicon_pcfg[i].keys():
            lexicon_pcfg[i][j] /= s
    return(grammar_pcfg,lexicon_pcfg)

def build_reverse_grammar_pcfg(grammar_pcfg):
    reverse_grammar_pcfg = dict()
    for k, children in grammar_pcfg.items():
        for child,p in children.items():
            if child not in reverse_grammar_pcfg:
                reverse_grammar_pcfg[child] = dict()
            reverse_grammar_pcfg[child][k] = p
    return(reverse_grammar_pcfg)

def save_pcfg(filename, grammar_pcfg, lexicon_pcfg):
    with open('%s_grammar.pickle'%filename, 'wb') as handle:
        pickle.dump(grammar_pcfg, handle, protocol=pickle.HIGHEST_PROTOCOL)
    with open('%s_lexicon.pickle'%filename, 'wb') as handle:
        pickle.dump(lexicon_pcfg, handle, protocol=pickle.HIGHEST_PROTOCOL)

def load_pcfg(filename):
    with open('%s_grammar.pickle'%filename, 'rb') as handle:
        grammar_pcfg = pickle.load(handle)
    with open('%s_lexicon.pickle'%filename, 'rb') as handle:
        lexicon_pcfg = pickle.load(handle)
    return grammar_pcfg, lexicon_pcfg


from django import forms
from .models import Post, Comment

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'content']

        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'content': forms.Textarea(attrs={'class': 'form-control'}),
        }

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('content', 'parent_comment',)
        widgets = {
            'content': forms.Textarea(attrs={'rows': 4}),
            'parent_comment': forms.HiddenInput(),
        }


import os
import pandas as pd
import numpy as np
import math
import random
from tqdm import tqdm
from gensim import corpora
from gensim.similarities import SparseMatrixSimilarity
from supervised_product_matching.model_preprocessing import remove_stop_words
from src.common import create_final_data

"""
Much of this algorithm is based on the paper Intermediate Training of BERT for Product Matching
which is by the people who made the WDC Product Corpus:
http://data.dws.informatik.uni-mannheim.de/largescaleproductcorpus/data/v2/papers/DI2KG2020_Peeters.pdf
"""

def combinations(total, choose):
    '''
    Simple function to compute combinations
    '''

    return int(math.factorial(total) / (math.factorial(choose) * math.factorial(total - choose)))

def chunk_data():
    '''
    Chunks the WDC Product Corpus into files of 100,000 rows each
    '''

    chunk_size = 100000
    batch = 1
    for chunk in pd.read_json('data/base/offers_corpus_english_v2.json.gz', lines=True, nrows= 100000000000000, chunksize=chunk_size):
        chunk.to_json('data/base/product_corpus/chunk' + str(batch) + '.json')
        batch += 1

def generate_computer_data():
    '''
    Gets the computer data from the WDC Product Corpus
    '''
    chunk_size = 100000
    computer_df = pd.DataFrame()
    for chunk in pd.read_json('data/base/offers_corpus_english_v2.json.gz', lines=True, nrows= 100000000000000, chunksize=chunk_size):
        computer_df = computer_df.append(chunk[chunk['category'].values == 'Computers_and_Accessories'])
    return computer_df

def extract_key_features(cluster):
    '''
    Simplies the DataFrames extracted from the WDC Product Corpus
    Only includes the ID, description, title, and title + description
    '''

    new_cluster = cluster.loc[:, ("id", "description", "title")]
    new_cluster["title"] = new_cluster["title"].map(lambda x: remove_stop_words(x))
    new_cluster["description"] = new_cluster["description"].map(lambda x: remove_stop_words(str(x)))
    new_cluster["titleDesc"] = new_cluster["title"].map(lambda x: x.split(" ")) + new_cluster["description"].map(lambda x: x.split(" ")).map(lambda x: x[0:6])
    return new_cluster

def get_valid_clusters(df):
    '''
    Returns the IDs of all the clusters that have more than 1 but less than 80 titles in them
    '''

    MAX_CLUSTER_SIZE = 80
    valid_clusters = (((df['cluster_id'].value_counts() > 1) &
                        (df['cluster_id'].value_counts() <= MAX_CLUSTER_SIZE)))

    valid_clusters = list(valid_clusters[valid_clusters == True].index)
    all_clusters = df[df['cluster_id'].isin(valid_clusters)]['cluster_id'].values
    return set(all_clusters)

def create_pos_from_cluster(data, cluster_id):
    '''
    Creates positive pairs from a cluster
    '''

    MAX_PAIRS = 16
    cluster = data.loc[data["cluster_id"].values == cluster_id]
    cluster = extract_key_features(cluster)
    max_combos = combinations(len(cluster), 2)

    dictionary = corpora.Dictionary(cluster["titleDesc"])
    cluster_dict = [dictionary.doc2bow(title) for title in cluster["title"].map(lambda x: x.split(" "))]
    sim_matrix = np.array(SparseMatrixSimilarity(cluster_dict, num_features=len(dictionary)))

    # Because the matrix is redundant (the rows and columns represent the same titles)
    # we set the bottom half of the similarities (including the diagonal) to 100
    # so that we don't have to worry about them when doing argmin()
    for row in range(sim_matrix.shape[0]):
        for column in range(sim_matrix.shape[1]):
            if (row >= column):
                sim_matrix[row][column] = 100

    # If the maximum amount of combinations we can make is less than our set max,
    # set the maximum to the max combos
    if max_combos < MAX_PAIRS:
        MAX_PAIRS = max_combos

    # Half of the pairs should be hard positives and the other half random
    hard_pos = MAX_PAIRS // 2
    random_pos = MAX_PAIRS - hard_pos

    pairs = []

    # Hard positives are those that are from the same cluster, but with the least similarity
    for x in range(hard_pos):
        # Keep getting the pairs with the lowest similarity score
        min_sim = np.unravel_index(sim_matrix.argmin(), sim_matrix.shape)
        pair = [cluster["title"].iloc[min_sim[0]], cluster["title"].iloc[min_sim[1]], 1]
        pairs.append(pair)
        sim_matrix[min_sim[0]][min_sim[1]] = 100

    # The amount of available pairs (given that some are gone from hard positive creation)
    avail_indices = np.argwhere(sim_matrix != 100)

    # Get random pairs within the same cluster
    for x in range(random_pos):
        ran_idx = random.sample(list(range(len(avail_indices))), 1)
        choice = avail_indices[ran_idx][0]
        pair = [cluster["title"].iloc[choice[0]],
                cluster["title"].iloc[choice[1]], 1]
        pairs.append(pair)
        avail_indices = np.delete(avail_indices, ran_idx, 0)

    return pd.DataFrame(pairs, columns=["title_one", "title_two", "label"])

def create_neg_from_cluster(data, cluster_id, all_clusters):
    '''
    Creates negative pairs from a cluster
    '''

    # Get the cluster
    cluster = data.loc[data["cluster_id"].values == cluster_id]
    cluster = extract_key_features(cluster)
    pairs = []
    hard_neg = len(cluster) // 2

    # Hard negatives are those that are from different clusters, but we get the pair with the highest similarity
    for row in range(hard_neg):
        # Keep choosing random titles until we get one that is not our own
        neg_cluster_id = cluster_id
        while neg_cluster_id == cluster_id:
            neg_cluster_id = random.choice(all_clusters)

        # Extract data about this cluster
        neg_cluster = data.loc[data["cluster_id"].values == neg_cluster_id].copy()
        neg_cluster = extract_key_features(neg_cluster)

        # Add the current title of the cluster to the beginning of this random cluster so that
        # the first row in the similarity matrix will refer to this title
        neg_cluster = pd.concat([pd.DataFrame([cluster.iloc[row].values], columns=["id", "description", "title", "titleDesc"]),
                                 neg_cluster])

        # Get the similarity between the title and the random cluster
        dictionary = corpora.Dictionary(neg_cluster["titleDesc"])
        neg_cluster_dict = [dictionary.doc2bow(title) for title in neg_cluster["title"].map(lambda x: x.split(" "))]
        sim_matrix = np.array(SparseMatrixSimilarity(neg_cluster_dict, num_features=len(dictionary)))

        # First row is the similarity between the current title and the rest of the random cluster
        # so get the max similarity of this (+1 is because we don't include the similarity with ourself)
        max_val = sim_matrix[0][1:].argmax() + 1

        # Add the pair
        pair = [cluster["title"].iloc[row], neg_cluster["title"].iloc[max_val], 0]
        pairs.append(pair)

    for row in range(hard_neg, len(cluster)):
        # Keep choosing random titles until we get one that is not our own
        neg_cluster_id = cluster_id
        while neg_cluster_id == cluster_id:
            neg_cluster_id = random.choice(all_clusters)

        # Randomly get a title from the random cluster
        neg_cluster = data.loc[data["cluster_id"].values == neg_cluster_id].copy()
        neg_cluster = extract_key_features(neg_cluster)
        neg_title = neg_cluster["title"].iloc[random.choice(list(range(len(neg_cluster))))]

        # Add the pair
        pair = [cluster["title"].iloc[row], neg_title, 0]
        pairs.append(pair)

    return pd.DataFrame(pairs, columns=["title_one", "title_two", "label"])

def create_computer_gs_data():
    file_path = 'data/train/wdc_computers.csv'
    if not os.path.exists(file_path):
        print('Generating Gold Standard Computer data (takes a long time) . . .')
        # Get the titles from the WDC Product Corpus
        if not os.path.exists('data/base/computer_wdc_whole_no_duplicates.csv'):
            computer_df = generate_computer_data()
            computer_df = computer_df.drop_duplicates('title')
            computer_df.to_csv('data/base/computer_wdc_whole_no_duplicates.csv')

        else:
            computer_df = pd.read_csv('data/base/computer_wdc_whole_no_duplicates.csv')

        # Get "good" clusters from the data
        valid_clusters = list(get_valid_clusters(computer_df))
        computer_train_wdc_pos = pd.DataFrame(columns=["title_one", "title_two", "label"])
        computer_train_wdc_neg = pd.DataFrame(columns=["title_one", "title_two", "label"])

        # Positive data creation
        print('    Generating postive example . . .')
        for cluster in tqdm(valid_clusters):
            computer_train_wdc_pos = computer_train_wdc_pos.append(create_pos_from_cluster(computer_df, cluster))

        # Negative data creation
        print('    Generating negative examples . . .')
        for cluster in tqdm(valid_clusters):
            computer_train_wdc_neg = computer_train_wdc_neg.append(create_neg_from_cluster(computer_df, cluster, valid_clusters))

        # Concatenate the data
        computer_train_wdc = create_final_data(computer_train_wdc_pos, computer_train_wdc_neg)
        computer_train_wdc.to_csv('data/train/wdc_computers.csv')

    else:
        print('Already have Gold Standard Computer Data. Moving on . . .')


import os
import paeiou

with open("pa_location.txt") as infile:
        pa_path = os.path.join(infile.readline(), "media/")

def main():
    paeiou.paeiou(
        mod_id = "com.pa.daedalus.dozer",
        paeiou_unit_path = "PAEIOU_units/",
        unit_add_list = "unit_add_list.txt",
        output_path = "",
        mod_prefix = "dozer",
        server = True,
        client = False,
        pa_path = pa_path
    )

if __name__ == '__main__':
    main()


import sys
from collections import deque

input = sys.stdin.readline

N = int(input())
buffer = deque()
full = 0
while True:
    packet = int(input())

    if packet == -1:
        break
    elif packet == 0:
        buffer.popleft()
        full -= 1
    else:
        if full >= N:
            continue
        else:
            buffer.append(packet)
            full += 1

if buffer:
    print(*buffer)
else:
    print("empty")


from abc import ABCMeta, abstractmethod
from skimage import measure
import torch
import torch.nn as nn
from mmcv.cnn import normal_init
from mmcv.runner import auto_fp16, force_fp32
import mmcv, cv2
from mmseg.core import build_pixel_sampler
from mmseg.ops import resize
from ..builder import build_loss
import numpy as np
import math, os
from torchvision.utils import make_grid

def calc_psnr(img1, img2):
    # img1 = img1[0].cpu().float().numpy()
    # img2 = img2[0].cpu().float().numpy()
    mse = np.mean((img1/1.0 - img2/1.0) ** 2)
    if mse == 0:
        return 100
    PIXEL_MAX = 255
    return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))

def tensor2img(tensor, rgb2bgr=True, out_type=np.uint8, min_max=(0, 1)):
    """Convert torch Tensors into image numpy arrays.

    After clamping to [min, max], values will be normalized to [0, 1].

    Args:
        tensor (Tensor or list[Tensor]): Accept shapes:
            1) 4D mini-batch Tensor of shape (B x 3/1 x H x W);
            2) 3D Tensor of shape (3/1 x H x W);
            3) 2D Tensor of shape (H x W).
            Tensor channel should be in RGB order.
        rgb2bgr (bool): Whether to change rgb to bgr.
        out_type (numpy type): output types. If ``np.uint8``, transform outputs
            to uint8 type with range [0, 255]; otherwise, float type with
            range [0, 1]. Default: ``np.uint8``.
        min_max (tuple[int]): min and max values for clamp.

    Returns:
        (Tensor or list): 3D ndarray of shape (H x W x C) OR 2D ndarray of
        shape (H x W). The channel order is BGR.
    """
    if not (torch.is_tensor(tensor) or (isinstance(tensor, list) and all(torch.is_tensor(t) for t in tensor))):
        raise TypeError(f'tensor or list of tensors expected, got {type(tensor)}')

    if torch.is_tensor(tensor):
        tensor = [tensor]
    result = []
    for _tensor in tensor:
        _tensor = _tensor.squeeze(0).float().detach().cpu().clamp_(*min_max)
        _tensor = (_tensor - min_max[0]) / (min_max[1] - min_max[0])

        n_dim = _tensor.dim()
        if n_dim == 4:
            img_np = make_grid(_tensor, nrow=int(math.sqrt(_tensor.size(0))), normalize=False).numpy()
            img_np = img_np.transpose(1, 2, 0)
            if rgb2bgr:
                img_np = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
        elif n_dim == 3:
            img_np = _tensor.numpy()
            img_np = img_np.transpose(1, 2, 0)
            if img_np.shape[2] == 1:  # gray image
                img_np = np.squeeze(img_np, axis=2)
            else:
                if rgb2bgr:
                    img_np = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
        elif n_dim == 2:
            img_np = _tensor.numpy()
        else:
            raise TypeError(f'Only support 4D, 3D or 2D tensor. But received with dimension: {n_dim}')
        if out_type == np.uint8:
            # Unlike MATLAB, numpy.unit8() WILL NOT round by default.
            img_np = (img_np * 255.0).round()
        img_np = img_np.astype(out_type)
        result.append(img_np)
    if len(result) == 1:
        result = result[0]
    return result

def numpy2imgs(numpy, mean=(0, 0, 0), std=(1, 1, 1), to_rgb=True):
    """Convert tensor to 3-channel images.

    Args:
        tensor (torch.Tensor): Tensor that contains multiple images, shape (
            N, C, H, W).
        mean (tuple[float], optional): Mean of images. Defaults to (0, 0, 0).
        std (tuple[float], optional): Standard deviation of images.
            Defaults to (1, 1, 1).
        to_rgb (bool, optional): Whether the tensor was converted to RGB
            format in the first place. If so, convert it back to BGR.
            Defaults to True.

    Returns:
        list[np.ndarray]: A list that contains multiple images.
    """

    if torch is None:
        raise RuntimeError('pytorch is not installed')
    # assert torch.is_tensor(numpy) and numpy.ndim == 3
    assert len(mean) == 3
    assert len(std) == 3
    mean = np.array(mean, dtype=np.float32)
    std = np.array(std, dtype=np.float32)
    imgs = []

    img = numpy.transpose(1, 2, 0)
    img = mmcv.imdenormalize(img, mean, std, to_bgr=to_rgb).astype(np.uint8)
    imgs.append(np.ascontiguousarray(img))
    return img

def save(output, gt, img_name):
    mean = [123.675, 116.28, 103.53]
    std = [58.395, 57.12, 57.375]
    out_dir = '../train_result/'
    if not os.path.exists(out_dir):
           os.mkdir(out_dir)

    dehaze = output['haze']
    # dehaze = tensor2img(dehaze[0,:,:,:])
    dehaze = numpy2imgs(dehaze[0,:,:,:].cpu().detach().numpy(), mean, std)
    # gt = tensor2img(gt[0,:,:,:])
    gt = numpy2imgs(gt[0,:,:,:].cpu().detach().numpy(), mean, std)
    outname = out_dir + img_name[40:]
    outdir = os.path.dirname(outname)
    if not os.path.exists(outdir):
        os.makedirs(outdir)
    cv2.imwrite("%s" % (outname),
                np.concatenate((dehaze, gt), axis=1))
    psnr = calc_psnr(quantize(dehaze), quantize(gt))
    ssim = measure.compare_ssim(dehaze, gt, data_range=255, multichannel=True)
    return psnr, ssim

def quantize(img, rgb_range=255):
    pixel_range = 255 / rgb_range
    return (img*pixel_range).clip(0, 255).round()/pixel_range

class BaseDecodeHead(nn.Module, metaclass=ABCMeta):
    """Base class for BaseDecodeHead.

    Args:
        in_channels (int|Sequence[int]): Input channels.
        channels (int): Channels after modules, before conv_seg.
        num_classes (int): Number of classes.
        dropout_ratio (float): Ratio of dropout layer. Default: 0.1.
        conv_cfg (dict|None): Config of conv layers. Default: None.
        norm_cfg (dict|None): Config of norm layers. Default: None.
        act_cfg (dict): Config of activation layers.
            Default: dict(type='ReLU')
        in_index (int|Sequence[int]): Input feature index. Default: -1
        input_transform (str|None): Transformation type of input features.
            Options: 'resize_concat', 'multiple_select', None.
            'resize_concat': Multiple feature maps will be resize to the
                same size as first one and than concat together.
                Usually used in FCN head of HRNet.
            'multiple_select': Multiple feature maps will be bundle into
                a list and passed into decode head.
            None: Only one select feature map is allowed.
            Default: None.
        loss_decode (dict): Config of decode loss.
            Default: dict(type='CrossEntropyLoss').
        ignore_index (int | None): The label index to be ignored. When using
            masked BCE loss, ignore_index should be set to None. Default: 255
        sampler (dict|None): The config of segmentation map sampler.
            Default: None.
        align_corners (bool): align_corners argument of F.interpolate.
            Default: False.
    """

    def __init__(self,
                 in_channels,
                 channels,
                 *,
                 num_classes,
                 dropout_ratio=0.1,
                 conv_cfg=None,
                 norm_cfg=None,
                 act_cfg=dict(type='ReLU'),
                 in_index=-1,
                 input_transform=None,
                 loss_dehaze=dict(type='L1_Loss', loss_weight=1.0),
                 loss_depth=dict(type='L1_Loss', loss_weight=1.0),
                 loss_feature=dict(type='L1_Loss', loss_weight=1.0),
                 loss_fuse=dict(type='L1_Loss', loss_weight=1.0),
                 loss_upsample=dict(type='L1_Loss', loss_weight=1.0),
                 loss_contrast=dict(type='L1_Loss', loss_weight=1.0),
                 decoder_params=None,
                 ignore_index=255,
                 sampler=None,
                 align_corners=False):
        super(BaseDecodeHead, self).__init__()
        self._init_inputs(in_channels, in_index, input_transform)
        self.channels = channels
        self.num_classes = num_classes
        self.dropout_ratio = dropout_ratio
        self.conv_cfg = conv_cfg
        self.norm_cfg = norm_cfg
        self.act_cfg = act_cfg
        self.in_index = in_index
        self.loss_dehaze = build_loss(loss_dehaze)
        self.loss_depth = build_loss(loss_depth)
        self.loss_feature = build_loss(loss_feature)
        self.ignore_index = ignore_index
        self.align_corners = align_corners

        if sampler is not None:
            self.sampler = build_pixel_sampler(sampler, context=self)
        else:
            self.sampler = None

        self.conv_seg = nn.Conv2d(channels, num_classes, kernel_size=1)
        if dropout_ratio > 0:
            self.dropout = nn.Dropout2d(dropout_ratio)
        else:
            self.dropout = None
        self.fp16_enabled = False

    def extra_repr(self):
        """Extra repr."""
        s = f'input_transform={self.input_transform}, ' \
            f'ignore_index={self.ignore_index}, ' \
            f'align_corners={self.align_corners}'
        return s

    def _init_inputs(self, in_channels, in_index, input_transform):
        """Check and initialize input transforms.

        The in_channels, in_index and input_transform must match.
        Specifically, when input_transform is None, only single feature map
        will be selected. So in_channels and in_index must be of type int.
        When input_transform

        Args:
            in_channels (int|Sequence[int]): Input channels.
            in_index (int|Sequence[int]): Input feature index.
            input_transform (str|None): Transformation type of input features.
                Options: 'resize_concat', 'multiple_select', None.
                'resize_concat': Multiple feature maps will be resize to the
                    same size as first one and than concat together.
                    Usually used in FCN head of HRNet.
                'multiple_select': Multiple feature maps will be bundle into
                    a list and passed into decode head.
                None: Only one select feature map is allowed.
        """

        if input_transform is not None:
            assert input_transform in ['resize_concat', 'multiple_select']
        self.input_transform = input_transform
        self.in_index = in_index
        if input_transform is not None:
            assert isinstance(in_channels, (list, tuple))
            assert isinstance(in_index, (list, tuple))
            assert len(in_channels) == len(in_index)
            if input_transform == 'resize_concat':
                self.in_channels = sum(in_channels)
            else:
                self.in_channels = in_channels
        else:
            assert isinstance(in_channels, int)
            assert isinstance(in_index, int)
            self.in_channels = in_channels

    def init_weights(self):
        """Initialize weights of classification layer."""
        normal_init(self.conv_seg, mean=0, std=0.01)

    def _transform_inputs(self, inputs):
        """Transform inputs for decoder.

        Args:
            inputs (list[Tensor]): List of multi-level img features.

        Returns:
            Tensor: The transformed inputs
        """

        if self.input_transform == 'resize_concat':
            inputs = [inputs[i] for i in self.in_index]
            upsampled_inputs = [
                resize(
                    input=x,
                    size=inputs[0].shape[2:],
                    mode='bilinear',
                    align_corners=self.align_corners) for x in inputs
            ]
            inputs = torch.cat(upsampled_inputs, dim=1)
        elif self.input_transform == 'multiple_select':
            inputs = [inputs[i] for i in self.in_index]
        else:
            inputs = inputs[self.in_index]

        return inputs

    @auto_fp16()
    @abstractmethod
    def forward(self, inputs):
        """Placeholder of forward function."""
        pass

    def forward_train(self, inputs, img_metas, gt, haze, train_cfg):
        """Forward function for training.
        Args:
            inputs (list[Tensor]): List of multi-level img features.
            img_metas (list[dict]): List of image info dict where each dict
                has: 'img_shape', 'scale_factor', 'flip', and may also contain
                'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'.
                For details on the values of these keys see
                `mmseg/datasets/pipelines/formatting.py:Collect`.
            gt_semantic_seg (Tensor): Semantic segmentation masks
                used if the architecture supports semantic segmentation task.
            train_cfg (dict): The training config.

        Returns:
            dict[str, Tensor]: a dictionary of loss components
        """
        seg_logits = self.forward(inputs, haze)
        save(seg_logits, gt, img_metas[0]['filename'])
        losses = self.losses(seg_logits, gt)
        return losses

    def forward_test(self, inputs, img, test_cfg):
        """Forward function for testing.

        Args:
            inputs (list[Tensor]): List of multi-level img features.
            img_metas (list[dict]): List of image info dict where each dict
                has: 'img_shape', 'scale_factor', 'flip', and may also contain
                'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'.
                For details on the values of these keys see
                `mmseg/datasets/pipelines/formatting.py:Collect`.
            test_cfg (dict): The testing config.

        Returns:
            Tensor: Output segmentation map.
        """
        return self.forward(inputs, img)

    def cls_seg(self, feat):
        """Classify each pixel."""
        if self.dropout is not None:
            feat = self.dropout(feat)
        output = self.conv_seg(feat)
        return output

    @force_fp32(apply_to=('seg_logit', ))
    def losses(self, predict, label):
        """Compute segmentation loss."""
        loss = dict()
        if 'haze' in predict:
            dehaze = predict['haze']
        if self.sampler is not None:
            weight = self.sampler.sample(dehaze, label)
        else:
            weight = None
        # label = label.squeeze(1)
        loss['loss_dehaze'] = self.loss_dehaze(
            dehaze,
            label,
            weight=weight)
        return loss


import pandas as pd
import re

final = pd.read_csv(r"C:\Data\PreppinData\2022W18 Input.csv")
final = final.melt(id_vars='Region', var_name='Cols', value_name='Amount')
final['Bike Type'] = final['Cols'].apply(lambda x: re.search('^([^_]+)(?=_)', x).group(1))
final['Measure'] = final['Cols'].apply(lambda x: re.search('(?<=_)([^_]+)$', x).group(1))
final['Month'] = final['Cols'].apply(lambda x: pd.to_datetime(re.sub('.*([A-Za-z]{3})_(\d+).*', '20\\2-\\1-01', x),
                                                              format='%Y-%b-%d').date())
final = final.drop('Cols', axis=1)
final = final.pivot_table(index=['Bike Type', 'Region', 'Month'], columns='Measure', values='Amount', aggfunc=sum).reset_index()
final = final[['Bike Type', 'Region', 'Month', 'Sales', 'Profit']]


# Create your tests here.
from multifiles_upload.models import Docket, FileUpload
from rest_framework import serializers

class FileUploadSerializer(serializers.ModelSerializer):
    class Meta:
        model = FileUpload
        fields = "__all__"

class DocketSerializer(serializers.ModelSerializer):
    files = serializers.ListField(
        child=serializers.FileField(), required=False
    )
    uploaded_items = FileUploadSerializer(read_only=True, many=True)

    class Meta:
        model = Docket
        fields = "__all__"

# class MultipleFileSerializer(serializers.Serializer):
#     files = serializers.ListField(
#         child=serializers.FileField()
#     )


from typing import Dict, Union

from pyjsg.jsglib import isinstance_
from rdflib import BNode, URIRef, Literal, Graph
from rdflib.namespace import NamespaceManager

from pyshex.shapemap_structure_and_language.p1_notation_and_terminology import Triple

class N3Mapper:
    def __init__(self, nsm: Union[Graph, NamespaceManager] = None) -> None:
        self._bnode_map: Dict[BNode, str] = {}
        self.namespace_manager = NamespaceManager(Graph()) if nsm is None \
            else nsm.namespace_manager if isinstance(nsm, Graph) else nsm
        self._cur_bnode_number = 0

    @property
    def _next_bnode(self) -> str:
        self._cur_bnode_number += 1
        return f'_:b{self._cur_bnode_number}'

    def n3(self, node: Union[URIRef, BNode, Literal, Triple, str]) -> str:
        if isinstance_(node, Triple):
            return f"{self.n3(node[0])} {self.n3(node[1])} {self.n3(node[2])} ."
        elif isinstance(node, BNode):
            if node not in self._bnode_map:
                self._bnode_map[node] = self._next_bnode
            return self._bnode_map[node]
        else:
            if not isinstance(node, (URIRef, Literal)):
                node = URIRef(str(node))
            return node.n3(self.namespace_manager)


import copy
class GameState:
    stack = []
    def __init__(self, board):
        self.board = board

    def addLast(self, last):
        GameState.stack.append(last)

    def deleteLast(self):
        if len(GameState.stack) != 0:
            last = GameState.stack.pop()
            self.board[last[0]][last[1]] = 0

    def getLegalActions(self, agent):
        """ Return an iterable representing the legal actions to take. """
        actions = []
        for i in range(0, 7):
            if self.board[i][-1] == 0:
                actions.append(i)
        return actions

    def generateSuccessor(self, agent, action):
        """ Generates the successor for the given action

        Keyword arguments:
        action -- The column in which to add the disk.

        """

        successor = GameState(self.board)
        rows = successor.board[action]
        for i, row in enumerate(rows):
            if row == 0:
                successor.board[action][i] = agent
                self.addLast((action, i))
                break
        return successor

    def mprint(self):
        height = len(self.board[0])
        width = len(self.board)
        for x in range(height - 1, -1, -1):
            for y in range(width):
                print (self.board[y][x], end=" ")
            print ("")
        print ("")

class MiniMax:
    def __init__(self, agent):
        self.agent = agent

    def maxValue(self, gameState, depth, agent, alpha, beta):
        if self.terminal(gameState, depth):
            ev = self.evaluate(gameState, depth)
            return ev

        maximum = float("-inf")
        nextAgent = self.getNextAgent(agent)

        for action in gameState.getLegalActions(agent):
            #print("Before:")
            #gameState.mprint()
            successor = gameState.generateSuccessor(agent, action)
            #print("Successor:")
            #successor.mprint()
            #gameState.mprint()
            value = self.minValue(successor, depth, nextAgent, alpha, beta)
            gameState.deleteLast()
            #print("After:")
            #gameState.mprint()

            if maximum < value:
                maximum = value
                maxAction = action

            if maximum > beta:
                return maximum

            alpha = max(alpha, maximum)

        if depth == 1:
            return maxAction
        else:
            return maximum

    def minValue(self, gameState, depth, agent, alpha, beta):
        if self.terminal(gameState,depth):
            return self.evaluate(gameState, depth)

        minimum = float("inf")
        nextAgent = self.getNextAgent(agent)

        for action in gameState.getLegalActions(agent):
            successor = gameState.generateSuccessor(agent, action)
            minimum = min(minimum, self.maxValue(successor, depth + 1, nextAgent, alpha, beta))
            gameState.deleteLast()
            if minimum < alpha:
                return minimum

            beta = min(beta, minimum)

        return minimum

    def getNextAgent(self, agent):
        """ Returns the agent representing the other player.

        ASSUMES: agent is either 1 or 2.
        """
        if agent == 1:
            return 2
        else:
            return 1

    def checkAnyT(self,board,player_number):
        width = len(board)
        height = len(board[0])
        for r in range(0,width):
            for c in range(0,height):
                if(board[r][c] == player_number):
                    if(checkWinBelow(board, width, height, c, r, player_number)
                    or checkWinAbove(board, width, height, c, r, player_number)
                    or checkLeft(board, width, height, c, r, player_number)
                    or checkRight(board, width, height, c, r, player_number)
                    or checkWinBottomRight(board, width, height, c, r, player_number)
                    or checkWinBottomLeft(board, width, height, c, r, player_number)
                    or checkWinTopLeft(board, width, height, c, r, player_number)
                    or checkWinTopRight(board, width, height, c, r, player_number)):
                        return True
        return False

    def evaluate(self, gameState, depth):
        """ Returns the 'score' for the given state """

        if self.checkAnyT(gameState.board,self.agent):
            print(str(1000-depth))
            gameState.mprint()
            return 1000-depth
        elif self.checkAnyT(gameState.board,self.getNextAgent(self.agent)):
            print(str(-100+depth))
            gameState.mprint()
            return -100+depth
        else:
            return 0

    def terminal(self, gameState, depth):
        return depth > 3 or not gameState.getLegalActions(self.agent) or self.checkAnyT(gameState.board,1) or self.checkAnyT(gameState.board,2)

def checkWinBelow(board, width, height,col, row, player_number):
    if(col+1 == height or row == 0 or row+1 == width): return False
    if(board[row-1][col+1] == player_number and board[row][col+1] == player_number and board[row+1][col+1] == player_number): return True
    return False

def checkWinAbove(board, width, height,col, row, player_number):
    if(col == 0 or row == 0 or row+1 == width): return False
    if(board[row-1][col-1] == player_number and board[row][col-1] == player_number and board[row+1][col-1] == player_number): return True
    return False

def checkLeft(board, width, height,col, row, player_number):
    if(row + 1 >= width or col + 1 >= height or col - 1 < 0 ): return False
    if(board[row+1][col-1] == board[row+1][col] == board[row+1][col+1] == player_number): return True
    return False

def checkRight(board, width, height,col, row, player_number):
    if(row - 1 < 0 or col + 1 >= height or col - 1 < 0 ): return False
    if(board[row-1][col-1] == board[row-1][col] == board[row-1][col+1] == player_number): return True
    return False

def checkWinBottomRight(board, width, height,col, row, player_number):
    if(row - 2 < 0 or col + 2 >= height): return False
    if(board[row-2][col] == player_number and board[row-1][col+1] == player_number and board[row][col+2] == player_number): return True
    return False

def checkWinBottomLeft(board, width, height,col, row, player_number):
    if(row + 2 >= width or col - 2 < 0): return False
    if(board[row+2][col] == player_number and board[row+1][col-1] == player_number and board[row][col-2] == player_number): return True
    return False

def checkWinTopLeft(board, width, height,col, row, player_number):
    if(row + 2 >= width or col - 2 < 0): return False
    if(board[row+2][col] == player_number and board[row+1][col-1] == player_number and board[row][col-2] == player_number): return True
    return False

def checkWinTopRight(board, width, height,col, row, player_number):
    if(row - 2 < 0 or col - 2 < 0): return False
    if(board[row-2][col] == player_number and board[row-1][col-1] == player_number and board[row][col-2] == player_number): return True
    return False


# from src.pylo import (
#     Prolog
# )
from pylo.language.lp import Constant, Variable, Functor, Structure, List, Predicate, Atom, Not, Clause, \
    c_var, c_pred, c_functor, c_const, c_symbol, Pair
from pylo.engines.prolog.prologsolver import Prolog
#from pylo.language.lp import Variable, Structure, List, Atom, Clause, c_var, c_pred, c_functor, c_const, c_symbol
import sys

#sys.path.append("../../build")
import os
wrap_path = os.path.abspath(os.path.dirname(__file__))
sys.path.append(wrap_path + "/../../../build")

import pyxsb
from typing import Union
from functools import reduce

def _is_list(term: str):
    return term.startswith('[')

def _is_structure(term: str):
    first_bracket = term.find('(')

    if first_bracket == -1:
        return False
    else:
        tmp = term[:first_bracket]
        return all([x.isalnum() for x in tmp]) and tmp[0].isalpha()

def _pyxsb_string_to_const_or_var(term: str):
    if term[0].islower():
        return c_const(term)
    elif term.isnumeric():
        if '.' in term:
            return float(term)
        else:
            return int(term)
    else:
        return c_var(term)

def _extract_arguments_from_compound(term: str):
    if _is_list(term):
        term = term[1:-1]  # remove '[' and ']'
    else:
        first_bracket = term.find('(')
        term = term[first_bracket+1:-1] # remove outer brackets

    args = []
    open_brackets = 0
    last_open_char = 0
    for i in range(len(term)):
        char = term[i]
        if term[i] in ['(', '[']:
            open_brackets += 1
        elif term[i] in [')', ']']:
            open_brackets -= 1
        elif term[i] == ',' and open_brackets == 0:
            args.append(term[last_open_char:i])
            last_open_char = i + 1
        elif i == len(term) - 1:
            args.append(term[last_open_char:])
        else:
            pass

    return args

def _pyxsb_string_to_structure(term: str):
    first_bracket = term.find('(')
    functor = term[:first_bracket]
    args = [_pyxsb_string_to_pylo(x) for x in _extract_arguments_from_compound(term)]
    functor = c_symbol(functor, arity=len(args))

    return Structure(functor, args)

def _pyxsb_string_to_list(term: str):
    args = [_pyxsb_string_to_pylo(x) for x in _extract_arguments_from_compound(term)]
    return List(args)

def _pyxsb_string_to_pylo(term: str):
    if _is_list(term):
        return _pyxsb_string_to_list(term)
    elif _is_structure(term):
        return _pyxsb_string_to_structure(term)
    else:
        return _pyxsb_string_to_const_or_var(term)

class XSBProlog(Prolog):

    def __init__(self, exec_path=None):
        if exec_path is None:
            exec_path = os.getenv('XSB_HOME', None)
            raise Exception(f"Cannot find XSB_HOME environment variable")
        pyxsb.pyxsb_init_string(exec_path)
        super().__init__()

    def release(self):
        if not self.is_released:
            pyxsb.pyxsb_close()
            self.is_released: bool = True

    def __del__(self):
        self.release()

    def consult(self, filename: str):
        return pyxsb.pyxsb_command_string(f"consult('{filename}').")

    def use_module(self, module: str, **kwargs):
        assert 'predicates' in kwargs, "XSB Prolog: need to specify which predicates to import from module"
        predicates = kwargs['predicates']
        command = f"use_module({module},[{','.join([x.get_name() + '/' + str(x.get_arity()) for x in predicates])}])."
        return pyxsb.pyxsb_command_string(command)

    def asserta(self, clause: Union[Clause, Atom]):
        if isinstance(clause, Atom):
            query = f"asserta({clause})."
            return pyxsb.pyxsb_command_string(query)
        else:
            query = f"asserta(({clause}))."
            return pyxsb.pyxsb_command_string(query)

    def assertz(self, clause: Union[Atom, Clause]):
        if isinstance(clause, Atom):
            query = f"assertz({clause})."
            return pyxsb.pyxsb_command_string(query)
        else:
            query = f"assertz(({clause}))."
            return pyxsb.pyxsb_command_string(query)

    def retract(self, clause: Union[Atom, Clause]):
        if isinstance(clause, Atom):
            return pyxsb.pyxsb_command_string(f"retract({clause}).")
        else:
            return pyxsb.pyxsb_command_string(f"retract(({clause})).")

    def has_solution(self, *query: Atom):
        #assert not all([x.is_ground() for x in query]), "XSB Prolog currently cannot query ground queries"
        string_repr = ','.join([str(x) for x in query])
        res = pyxsb.pyxsb_query_string(f"{string_repr}.")

        if res:
            pyxsb.pyxsb_close_query()

        return True if res else False

    def query(self, *query, **kwargs):
        if 'max_solutions' in kwargs:
            max_solutions = kwargs['max_solutions']
        else:
            max_solutions = -1

        if 'time_limit' in kwargs:
            time_limit = kwargs['time_limit']
        else:
            time_limit = None

        vars_of_interest = [[y for y in x.get_arguments() if isinstance(y, Variable)] for x in query]
        vars_of_interest = reduce(lambda x, y: x + y, vars_of_interest, [])
        vars_of_interest = reduce(lambda x, y: x + [y] if y not in x else x, vars_of_interest, [])

        string_repr = ','.join([str(x) for x in query])

        if time_limit:
            res = pyxsb.pyxsb_query_string(f"timed_call(({string_repr}),[max({time_limit},fail)]).")
        else:
            res = pyxsb.pyxsb_query_string(f"{string_repr}.")

        all_solutions = []
        while res and max_solutions != 0:
            vals = [x for x in res.strip().split(";")]
            var_assignments = [_pyxsb_string_to_pylo(x) for x in vals]
            all_solutions.append(dict([(v, s) for v, s in zip(vars_of_interest, var_assignments)]))

            res = pyxsb.pyxsb_next_string()
            max_solutions -= 1

        pyxsb.pyxsb_close_query()

        return all_solutions

    def register_foreign(self, pyfunction, arity):
        raise Exception("support for foreign predicates not supported yet")

if __name__ == '__main__':
    def test1():
        pl = XSBProlog("/Users/seb/Documents/programs/XSB")

        p = c_pred("p", 2)
        f = c_functor("t", 3)
        f1 = p("a", "b")

        pl.assertz(f1)

        X = c_var("X")
        Y = c_var("Y")

        query = p(X, Y)

        r = pl.has_solution(query)
        print("has solution", r)

        rv = pl.query(query)
        print("all solutions", rv)

        f2 = p("a", "c")
        pl.assertz(f2)

        rv = pl.query(query)
        print("all solutions after adding f2", rv)

        func1 = f(1, 2, 3)
        f3 = p(func1, "b")
        pl.assertz(f3)

        rv = pl.query(query)
        print("all solutions after adding structure", rv)

        l = List([1, 2, 3, 4, 5])

        member = c_pred("member", 2)
        pl.use_module("lists", predicates=[member])

        query2 = member(X, l)

        rv = pl.query(query2)
        print("all solutions to list membership ", rv)

        r = c_pred("r", 2)
        f4 = r("a", l)
        f5 = r("a", "b")

        pl.asserta(f4)
        pl.asserta(f5)

        query3 = r(X, Y)

        rv = pl.query(query3)
        print("all solutions after adding list ", rv)

        q = c_pred("q", 2)
        cl = (q("X", "Y") <= r("X", "Y") & r("X", "Z"))

        pl.assertz(cl)
        query4 = q("X", "Y")
        rv = pl.query(query4)
        print("all solutions to q: ", rv)

        del pl

    def test2():
        pl = XSBProlog("/Users/seb/Documents/programs/XSB")

        person = c_pred("person", 1)
        friends = c_pred("friends", 2)
        stress = c_pred("stress", 1)
        influences = c_pred("influences", 2)
        smokes = c_pred("smokes", 1)
        asthma = c_pred("asthma", 1)

        pl.assertz(person("a"))
        pl.assertz(person("b"))
        pl.assertz(person("c"))
        pl.assertz(friends("a", "b"))
        pl.assertz(friends("a", "c"))

        pl.assertz(stress("X") <= person("X"))
        pl.assertz(influences("X", "Y") <= person("X") & person("Y"))
        pl.assertz(smokes("X") <= stress("X"))
        pl.assertz(smokes("X") <= friends("X", "Y") & influences("Y", "X") & smokes("Y"))
        pl.assertz(asthma("X") <= smokes("X"))

        query_p = person("X")
        tv = pl.query(query_p)
        print("all persons: ", tv)

        query_f = friends("X", "Y")
        tv = pl.query(query_f)
        print("all friends: ", tv)

        query_st = stress("Y")
        tv = pl.query(query_st)
        print("all stressed people: ", tv)

        tv = pl.query(influences("X", "Y"))
        print("all influences: ", tv)

        tv = pl.query(smokes("X"))
        print("all smokers: ", tv)

        tv = pl.query(asthma("X"))
        print("all asthma: ", tv)

        del pl

    def test3():
        pl = XSBProlog("/Users/seb/Documents/programs/XSB")

        bongard = c_pred('bongard', 2)
        circle = c_pred('circle', 2)
        inp = c_pred('in', 3)
        config = c_pred('config', 3)
        triangle = c_pred('triangle', 2)
        square = c_pred('square', 2)

        pl.assertz(bongard(2, "la"))
        pl.assertz(circle(2, "o3"))
        pl.assertz(config(2, "o1", "up"))
        pl.assertz(config(2, "o2", "up"))
        pl.assertz(config(2, "o5", "up"))
        pl.assertz(triangle(2, "o1"))
        pl.assertz(triangle(2, "o2"))
        pl.assertz(triangle(2, "o5"))
        pl.assertz(square(2, "o4"))
        pl.assertz(inp(2, "o4", "o5"))
        pl.assertz(inp(2, "o2", "o3"))

        A = c_var("A")
        B = c_var("B")
        C = c_var("C")
        D = c_var("D")

        #pl.assertz((bongard(A,"la") <= triangle(A,C) & inp(A, C, D)))

        res = pl.query(bongard(A, "la"), triangle(A,C), inp(A, C, D))

        print(res)

        del pl

    def test5():
        solver = XSBProlog("/Users/seb/Documents/programs/XSB")

        edge = c_pred("edge", 2)
        path = c_pred("path", 2)

        f1 = edge("v1", "v2")
        f2 = edge("v1", "v3")
        f3 = edge("v2", "v4")

        X = c_var("X")
        Y = c_var("Y")
        Z = c_var("Z")

        cl1 = (path("X", "Y") <= edge("X", "Y"))
        cl2 = (path("X", "Y") <= edge("X", "Z") & path("Z", "Y"))

        as1 = solver.assertz(f1)
        as2 = solver.assertz(f2)
        as3 = solver.assertz(f3)

        as4 = solver.assertz(cl1)
        solver.assertz(cl2)

        assert solver.has_solution(edge("X", "v2"))
        assert solver.has_solution(path("v1", "v4"))
        assert len(solver.query(path("v1", "X"), max_solutions=1)[0]) == 1
        assert len(solver.query(path(X, "v4"), max_solutions=1)[0]) == 1
        assert len(solver.query(path(X, Y), max_solutions=1)[0]) == 2

        assert len(solver.query(path("v1", X))) == 3
        assert len(solver.query(path(X, Y))) == 4

        solver.assertz(edge("v4", "v5"))
        assert len(solver.query(path(X, Y))) == 7

        print(solver.query(edge(X, Y), edge(Y, Z), edge(Z,"W")))

        del solver

    def test6():
        solver = XSBProlog("/Users/seb/Documents/programs/XSB")

        head = c_pred("head", 2)
        tail = c_pred("tail", 2)
        take_second = c_pred("take_second", 2)
        H = c_var("Head")
        T = c_var("Tail")
        X = c_var("X")
        Y = c_var("Y")

        hatm1 = head(Pair(H, T), H)
        tatm1 = tail(Pair(H, T), T)
        cl = (take_second(X,Y) <= tail(X, T) & head(T, Y))

        solver.assertz(hatm1)
        solver.assertz(tatm1)
        solver.assertz(cl)

        l = List([1, 2, 3, 4, 5])
        print(solver.query(take_second(l, X)))

        del solver

    def test7(limit=10):
        pl = XSBProlog("/Users/seb/Documents/programs/XSB")

        p = c_pred("p", 2)
        f = c_functor("t", 3)
        f1 = p("a", "b")

        pl.assertz(f1)

        X = c_var("X")
        Y = c_var("Y")

        query = p(X, Y)

        r = pl.has_solution(query)
        print("has solution", r)

        rv = pl.query(query, time_limit=limit)
        print("all solutions", rv)

        f2 = p("a", "c")
        pl.assertz(f2)

        rv = pl.query(query, time_limit=limit)
        print("all solutions after adding f2", rv)

        func1 = f(1, 2, 3)
        f3 = p(func1, "b")
        pl.assertz(f3)

        rv = pl.query(query, time_limit=limit)
        print("all solutions after adding structure", rv)

        l = List([1, 2, 3, 4, 5])

        member = c_pred("member", 2)
        pl.use_module("lists", predicates=[member])

        query2 = member(X, l)

        rv = pl.query(query2, time_limit=limit)
        print("all solutions to list membership ", rv)

        r = c_pred("r", 2)
        f4 = r("a", l)
        f5 = r("a", "b")

        pl.asserta(f4)
        pl.asserta(f5)

        query3 = r(X, Y)

        rv = pl.query(query3, time_limit=limit)
        print("all solutions after adding list ", rv)

        q = c_pred("q", 2)
        cl = (q("X", "Y") <= r("X", "Y") & r("X", "Z"))

        pl.assertz(cl)
        query4 = q("X", "Y")
        rv = pl.query(query4, time_limit=limit)
        print("all solutions to q: ", rv)

        del pl

    #test1()
    #test5()
    #test6()
    #test7(10)


from requests.api import options
from settings import moodle
import requests
import time
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta

def moodle_request(func):
    def inner(arg):
        req = func(arg)
        url = moodle["baseURL"] + moodle["userToken"] + \
            "&wsfunction=" + req["func"] + \
            moodle["defaultParams"]
        return requests.post(url=url, data=req["payload"]).json()
    return inner

@moodle_request
def get_users_by_email(email):
    func = "core_user_get_users_by_field"
    payload = {
        "field": "email",
        "values[0]": email
    }
    return {"payload": payload, "func": func}

@moodle_request
def get_courses_by_user_id(userid):
    func = "core_enrol_get_users_courses"
    payload = {
        "userid": userid
    }
    return {"payload": payload, "func": func}

def get_courses_by_user_email(email):
    users = get_users_by_email(email)
    if not users:
        return None
    return get_courses_by_user_id(users[0]["id"])

@moodle_request
def get_courses_events(courses):
    func = "core_calendar_get_calendar_events"
    courses_id = {}
    for course in courses:
        courses_id[f"events[courseids][{len(courses_id)}]"] = course["id"]

    today = datetime.now()

    this_month_start = datetime(year=today.year, month=today.month,
                                day=1, hour=0, second=0)

    next_month_end = this_month_start + relativedelta(months=2)

    this_month_start_unix = time.mktime(this_month_start.timetuple())
    next_month_end_unix = time.mktime(next_month_end.timetuple())

    payload = {
        "options[userevents]": 0,
        "options[timestart]": int(this_month_start_unix),
        "options[timeend]": int(next_month_end_unix)
    }
    return {"payload": {**courses_id, **payload}, "func": func}

# courses = get_courses_by_user_email("f.galletti@aluno.ifsp.edu.br")

# courses_name = []
# for course in courses:
#     courses_name.append(course["displayname"])

# nl = '\n'
# message = f"""Cursos:

# {nl.join(courses_name)}

# a
# """

# print(message)

# print(courses)
# print(get_courses_events(courses))

# print(int(time.time()))


for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))

    ans = a[0]
    cur = a[0]

    for i in range(1, n):
        cur = max(cur + a[i], a[i])
        ans = max(ans, cur)

    a = sorted(a, reverse=True)
    ans2 = a[0]
    for i in range(1, n):
        if a[i] > 0:
            ans2 += a[i]
    print(ans, ans2)

    """
    def MaxSub(A,N):
    max_ending_here = max_so_far = 0
    for x in A:
        max_ending_here = max(0, max_ending_here + x)
        max_so_far = max(max_so_far, max_ending_here)
    if ( max_so_far == 0 ):
        max_so_far = max(A)
    return str( max_so_far )

def MaxSubNonCont(A,N):
    tot = 0
    for x in A:
        if (x > 0):
            tot += x
    if (tot == 0):
        tot = max(A)
    return str( tot )

T = int(input())
for _ in range(T):
    N = int(input())
    A = [int(i) for i in input().split()]
    print( MaxSub(A,N) + " " + MaxSubNonCont(A,N) )

      """


from flask import Blueprint, Response,request
from database.models import User
from api.controllers import user as user_logic

user = Blueprint('user', __name__)

@user.route('/api/user/<chat_id>', methods=['GET'])
def get_user(chat_id):
    user = User.objects().get(chat_id=chat_id).to_json()
    return Response(user, mimetype="application/json", status=200)

@user.route('/api/user', methods=['POST'])
def create_user():
    body = request.get_json()
    user = User(**body).save()
    id = user.id
    return {'id': str(id)}, 200

@user.route('/api/user/<chat_id>', methods=['PATCH'])
def edit_user(chat_id):
   user = User.objects().get(chat_id=chat_id)
   body = request.get_json()
   user.update(**body)
   return Response(user.to_json(), mimetype="application/json", status=200)

@user.route('/api/user/<chat_id>', methods=['DELETE'])
def delete_user(chat_id):
    user_logic.delete_user(chat_id)
    return { "status": "ok"  }


import torch
from model import LSTMnet
from train import batch_scale, make_map
import matplotlib.pyplot as plt
from Dataloader import test_loader

def evaluate(model, test_loader, label_maps):
    # Nghiệm chứng và đánh giá
    test_features, test_labels = batch_scale(next(iter(test_loader)))

    val = model(test_features)
    _ , pred = torch.max(val.data, 1)
    acc = (100 * torch.sum(test_labels==pred) / len(test_labels))
    print(f'Accuracy of the network {acc} %')

    idx = 30
    val = model(test_features[:idx])
    _ , pred = torch.max(val.data, 1)

    fig = plt.figure(figsize=(15,15))
    for i in range(0,idx):
        img = test_features[i].squeeze()
        fig.add_subplot(5,6,i+1)
        plt.imshow(img,cmap='gray')
        plt.axis('off')
        plt.title(label_maps[int(pred[i])] + ' <-> ' + label_maps[int(test_labels[i])])
    plt.show()

if __name__ == '__main__':
    label_maps , class_num = make_map()
    input_dim = 28
    hidden_dim = 128
    layer_dim = 1
    output_dim = class_num
    model = LSTMnet(input_dim, hidden_dim, layer_dim, output_dim)
    model.load_state_dict(torch.load('Net.pth'))
    evaluate(model, test_loader, label_maps)


from elftools.elf.elffile import ELFFile
from binascii import hexlify

from unicorn import *
from unicorn.arm64_const import *

import struct
import re

global instructions_run, current_id
instructions_run = 0
current_id = 0
module_functions = []
module_names = []

SMASH_HASH_ADDR = 0x2b569a0
SMASH_REGISTERING_FUNCTION = 0x1913930
SMASH_REGISTER_FUNCTION = 0x2957450
SMASH_REGISTER_CATEGORY = 0x29570e0

#SMASH_REGISTER_MODULE = 0x29570e0
#SMASH_REGISTER_FUNCTION = 0x2957670
# FIGHTER_STATUS_DAMAGE_WORK_FLOAT_VECOR_CORRECT_STICK_X
#SMASH_STRING_OFFSET = 0x382c816
#SMASH_STRING_HASH = 0xA4D50A730E36970E
#SMASH_STRING_CRC = 0x1bc1d3d4

def uc_get_string(addr):
    s = ""
    c = uc.mem_read(addr, 1)
    while c != b'\x00':
        s += c.decode('latin8')
        addr += 1
        c = uc.mem_read(addr, 1)
    return s

def uc_write_u64(addr, num):
    uc.mem_write(addr, struct.pack("<Q", num))

def uc_read_u64(addr):
    return struct.unpack("<Q", uc.mem_read(addr, 8))[0]

def uc_return():
    lr = uc.reg_read(UC_ARM64_REG_LR)
    uc.reg_write(UC_ARM64_REG_PC, lr)

def register_module_replacement(uc):
    x0 = uc.reg_read(UC_ARM64_REG_X0)
    x1 = uc.reg_read(UC_ARM64_REG_X1)
    x2 = uc.reg_read(UC_ARM64_REG_X2)
    x3 = uc.reg_read(UC_ARM64_REG_X3)
    name = uc_get_string(x2)
    print(f"Module {name:30} {x3:08X}")
    module_names.append(name)
    module_functions.append([])
    uc_return()

def register_category_replacement(uc):
    x2 = uc.reg_read(UC_ARM64_REG_X2)
    name = uc_get_string(x2)
    module_functions.append(("CAT", name))
    #print(f"CATEGORY,{name}")
    uc_return()

def register_function_replacement(uc):
    x0 = uc.reg_read(UC_ARM64_REG_X0)
    x1 = uc.reg_read(UC_ARM64_REG_X1)
    x2 = uc.reg_read(UC_ARM64_REG_X2)
    name = uc_get_string(x1)
    module_functions.append(("CONST", x1, x2))
    #print(f"CONST,{name},0x{x2:08X}")
    uc_return()

def hook_code(uc, address, size, user_data):
    global instructions_run
    instructions_run += 1

    #if address == SMASH_REGISTER_MODULE:
    #    register_module_replacement(uc)
    if address == SMASH_REGISTER_FUNCTION:
        register_function_replacement(uc)
    if address == SMASH_REGISTER_CATEGORY:
        register_category_replacement(uc)
    return True

file_handle = open('./main_200.elf', 'rb')

elf = ELFFile(file_handle)
sections = list(elf.iter_sections())

uc = Uc(UC_ARCH_ARM64, UC_MODE_ARM)

uc.mem_map(0, 0x06704000)
# protect rodata just in case
uc.mem_protect(0x037b1000, 0x818000, UC_PROT_READ)

# Setup stack
uc.mem_map(0x0F000000, 0x01000000) # Stack
uc.reg_write(UC_ARM64_REG_SP, 0xFF00000) # Default stack pointer

for i, section in enumerate(sections):
    if section["sh_addr"] == 0 and section.name != ".text":
        continue
    print(f'LOAD {i:2} {section["sh_flags"] & 0x7:03b} {section["sh_addr"] + 0x100000:08X} {section["sh_addr"] + section.data_size + 0x100000:08X} {section.name}')
    uc.mem_write(section["sh_addr"] + 0x100000, section.data())

def empty_func(a,b,c,d):
    pass

# Map HOOK_CODE to an empty function, which fixes the fact unicorn's
# reg read's PC value doesn't update after the first jal cause reasons???
uc.hook_add(UC_HOOK_CODE, hook_code)

entry = SMASH_REGISTERING_FUNCTION

print(f"JUMP entry {entry:X}")
try:
    uc.emu_start(entry, 0x8009F6CC, timeout=2*UC_SECOND_SCALE)
except unicorn.UcError as e:
    #print(f"Result: {hex(uc.reg_read(UC_ARM64_REG_X0))}")
    print(f"Error: {e}")

from progress.bar import IncrementalBar as Bar

with open('consts.csv', 'w') as f:
    for row in Bar('Hashed %(index)d/%(max)d constants', suffix='%(percent).1f%% - %(eta)ds remaining', max=len(module_functions)).iter(module_functions):
        if row[0] == "CONST":
            _, name_addr, val = row
            name = uc_get_string(name_addr)
            try:
                uc.reg_write(UC_ARM64_REG_X0, name_addr)
                uc.reg_write(UC_ARM64_REG_X1, len(name))
                uc.reg_write(UC_ARM64_REG_LR, 0xDEADBEEFDEADBEEF)
                uc.emu_start(SMASH_HASH_ADDR, 0x8009F6CC, timeout=2*UC_SECOND_SCALE)
            except unicorn.UcError as e:
                # hopefully it succeeded enough to give us the hash
                hash = uc.reg_read(UC_ARM64_REG_X0)
                print(f"CONST,0x{hash:016X},\"{name}\",0x{val:X}", file=f)
        if row[0] == "CAT":
            print(f"CAT,{row[1]}", file=f)

print(f'Ran {instructions_run} instructions')
file_handle.close()


from pytube import YouTube
import os

link = str(input("Link: "))
yt = YouTube(link)

name = str(input("File Name: " ))

out_donwload = yt.streams.filter(only_audio=True).first().download()

print("Donwloading....")

file = out_donwload
base = os.path.splitext(file)[0]

if name == '':
    os.rename(out_donwload, base + '.mp3')
else:
    os.rename(out_donwload, name + '.mp3')

print("Finish")


def get_telemetry_data(df, telemetry_list,
                       pd, conn):  # Takes a File and a list of telemetry and return a dataframe of list of telemetry ,
    # ts and id

    # ts_kv_dict = pd.read_csv('ts_kv_d.csv', index_col=0)
    sql = '''select * from ts_kv_dictionary;'''
    ts_kv_dict = pd.read_sql_query(sql, conn)

    key = int(ts_kv_dict[ts_kv_dict['key'] == telemetry_list[0]]['key_id'])
    telemetry = df[df['key'] == key].dropna(axis=1)
    telemetry.drop(columns='key', inplace=True)
    telemetry.columns = ['entity_id', 'ts', telemetry_list[0]]

    for i in range(1, len(telemetry_list)):
        key = int(ts_kv_dict[ts_kv_dict['key'] == telemetry_list[i]]['key_id'])
        temp = df[df['key'] == key].dropna(axis=1)
        temp.drop(columns='key', inplace=True)
        temp.columns = ['entity_id', 'ts', telemetry_list[i]]
        telemetry = pd.merge(telemetry, temp, on=['entity_id', 'ts'], how='left')

    return telemetry


from telegram import (
    Update,
    InlineQueryResultArticle, InputTextMessageContent,
)
from telegram.ext import (
    ApplicationBuilder, CommandHandler, ContextTypes,
    InlineQueryHandler, MessageHandler, filters,
)

# Connect to our data (TODO: use an API-module)
import nlpcloud
from pandas import read_csv
from decouple import config

Party = read_csv('../data/Party.csv')

Vote = read_csv('../data/Vote.csv')
Vote.dropna(subset=['BusinessAuthor'], inplace=True)

# Private tokens for our demo (TODO: store in environment!)
API_KEY = config('NLP_CLOUD_API_KEY')
TELEGRAM_KEY = config('TELEGRAM_KEY')

# Quick test routine
async def hello(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.message.reply_text(f'Hello {update.effective_user.first_name}')

# Return a random party from our data
async def party(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    txt = Party.sample(n=1).get('PartyName').values[0]
    await update.message.reply_text(txt)

# Get votes by a politician
async def vote(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    qry = ' '.join(context.args).lower()
    if not qry:
        print("No query")
        return
    print('Vote', qry)
    votes = Vote[Vote['BusinessAuthor'].str.lower().str.contains(qry)]
    if votes.count()[0] > 0:
        t = '3 / ' + str(votes.count()[0])
        for index, row in votes.sample(n=3).iterrows():
            t = t + '\n'
            t = t + '- ' + row['BusinessTitle']
            if row['SessionName']:
                t = t + ' (' + row['SessionName'] + ')'
    else:
        t = 'No results'
    await update.message.reply_text(t)

# Say something smart
async def parl(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    qry = ' '.join(context.args)
    if not qry:
        print("No query")
        return
    print(qry)
    txt = nlpcli.chatbot(qry,
        context="""Dies ist eine Diskussion über Parlamentswahlen basierend auf den Daten von parlament.ch"""
    )['response']
    await update.message.reply_text(txt)

# Say something smarter
async def inline_parl(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    qry = update.inline_query.query
    if not qry:
        print("Blank query")
        return
    print(qry)
    txt = nlpcli.chatbot(qry,
        context="""Dies ist eine Diskussion über Parlamentswahlen basierend auf den Daten von parlament.ch"""
    )['response']
    results = [
        InlineQueryResultArticle(
            id='parl',
            title='PARL',
            description=txt,
            input_message_content=InputTextMessageContent(f'/parl {query}')
        )
    ]
    await context.bot.answer_inline_query(update.inline_query.id, results)

# Be confused
async def unknown(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=update.effective_chat.id, text="Sorry, I didn't understand that command.")

# Set up the app
app = ApplicationBuilder().token(TELEGRAM_KEY).build()

# Connect to NLP cloud
nlpcli = nlpcloud.Client("finetuned-gpt-neox-20b", API_KEY, gpu=True)

if __name__ == '__main__':

    # Add bot commands
    app.add_handler(CommandHandler("hello", hello))
    app.add_handler(CommandHandler("party", party))
    app.add_handler(CommandHandler("parl",  parl))
    app.add_handler(CommandHandler("vote",  vote))

    # Add inline support
    app.add_handler(InlineQueryHandler(inline_parl))

    # Finally add 404
    app.add_handler(MessageHandler(filters.COMMAND, unknown))

    # Start the loop
    print("Bot operational. Press Ctrl-C to exit ..")
    app.run_polling()

app.run_polling()


# define class for module plans
from .module import module
from .semester import semester

class ModsPlan:
    # define class of module plans

    def __init__(self,id,maxMcs):
        self.id = id
        self.sems = []
        self.sems.append(semester(1,20))
        for i in range(1,4):
            self.sems.append(semester(i+1,maxMcs))
        for i in range(4,8):
            self.sems.append(semester(i+1,20))

    def add_module(self,seq_num,mod:str):
        # add a module to a semester
        self.sems[seq_num].modules.append(mod)
        self.sems[seq_num].cur_mcs += module(mod).mcs

    def get_cur_mcs(self):
        # calculate cur mcs of plan
        plan_mcs = 0
        for sem in self.sems:
            plan_mcs += sem.cur_mcs
        return plan_mcs

    def ModsPlan_json(self):
        # response dict
        response = {
            'id':self.id,
            'sems':[sem.semester_json() for sem in self.sems]
        }
        return response


from setuptools import find_packages, setup

long_description = '''
pibake fetches and stores Raspberry PI Images to local cache, from
where you can burn it to a mounted SD card.
'''

setup(author='Thys Meintjes',
      author_email='sthysel@gmail.com',
      name='pibake',
      version='0.2.7',
      keywords='Raspberry PI Downloader',
      long_description=open('README.rst').read(),
      url='https://github.com/sthysel/pibake',
      download_url='https://github.com/sthysel/pibake/archive/v0.2.7.tar.gz',
      license="GPLv2",
      description='Fetches and Manages Raspberry PI Images',
      packages=find_packages(exclude=['tests*']),
      include_package_data=True,
      install_requires=[
          'click',
          'requests',
          'psutil',
          'pyxdg',
          'xdg',
      ],
      entry_points={'console_scripts': [
          'pibake=pibake.cli:cli',
      ]},
      classifiers=[
          'Development Status :: 5 - Production/Stable',
          'Programming Language :: Python :: 3.6',
          'Intended Audience :: Education',
          'Intended Audience :: End Users/Desktop',
          'Intended Audience :: Science/Research', 'Operating System :: Unix',
          'Topic :: Education', 'Topic :: Utilities'
      ])