import pygame as pg
import pygplus as pgp

import asyncio

import os; os.chdir(os.path.dirname(__file__))

class Engine:
    def __init__(self, width, height, title="Pygame game", icon_path=None, icon_size=32):
        pg.init()

        pgp.init_nodes(engine=self)
        self.screen_width = width
        self.screen_height = height
        self.screen = pg.display.set_mode((self.screen_width, self.screen_height), vsync=False)
        pg.display.set_caption(title)
        if icon_path:
            icon = pg.transform.scale(pg.image.load(icon_path).convert_alpha(), (icon_size, icon_size))
            pg.display.set_icon(icon)
        self.clock = pg.time.Clock()

        self.debug_font = pg.font.SysFont("calibri", size=32)
        self.enable_debug_text = True
        self.reset_debug_text()

        self.dt = pgp.TARGET_DT
        self.fps = 0
        self.updates_per_frame = 0

        self.running = True

    def reset(self):
        pass

    def handle_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.quit()

    def quit(self):
        self.running = False

    def draw(self):
        self.draw_background()

    def draw_background(self):
        self.screen.fill((119, 196, 236))

    def debug_text(self, item, value, round_floats=True):
        if isinstance(value, float) and round_floats:
            text = f"{item}: {round(value, 2)}"
        else:
            text = f"{item}: {value}"
        surface = self.debug_font.render(text, True, (255, 255, 255))
        rect = surface.get_rect()
        rect.bottomleft = (10, self.debug_text_y)
        self.screen.blit(surface, rect)
        self.debug_text_y -= self.debug_font.get_height() + 5

    def reset_debug_text(self):
        self.debug_text_y = self.screen_height - 4

    def gameloop(self):
        self.reset()
        self.running = True
        while self.running:
            if pgp.FIXED_TIMESTEP_SETTINGS["enable"]:
                if pgp.FIXED_TIMESTEP_SETTINGS["busy_loop"]:
                    self.dt = self.clock.tick_busy_loop(pgp.MAX_FPS)/1000
                else:
                    self.dt = self.clock.tick(pgp.MAX_FPS)/1000
                if self.dt == 0:
                    self.fps = "infinite"
                else:
                    self.fps = 1/self.dt

                self.accumulator += self.dt
                self.updates_per_frame = 0
                while self.accumulator >= pgp.TARGET_DT:
                    self.handle_events()
                    self.update()
                    self.accumulator -= pgp.TARGET_DT
                    self.updates_per_frame += 1

                self.draw()
                pg.display.flip()
            else:
                raise NotImplementedError("Not finished yet. Just use fixed timestep for now.")
                self.dt = self.clock.tick(pgp.MAX_FPS)/1000
                if self.dt == 0:
                    self.fps = "infinite"
                else:
                    self.fps = 1/self.dt
                self.handle_events()
                self.update()
                self.draw()
                pg.display.flip()

        pg.quit()

    def update(self):
        pass


from tqdm import tqdm

import os
import argparse
from parseAnnotatedXML import *
import turicreate as tc
from tqdm import tqdm
import numpy as np

try:
    import xml.etree.cElementTree as et
except ImportError:
    import xml.etree.ElementTree as et

class EvaluationSFrame(object):
	def getSFrame(xml_file, image_folder):
		IMAGE = ('.ras', '.xwd', '.bmp', '.jpe', '.jpg', '.jpeg', '.xpm', '.ief', '.pbm', '.tif', '.gif', '.ppm', '.xbm', '.tiff', '.rgb', '.pgm', '.png', '.pnm')
		xml_tree = et.parse(xml_file)

		data = {
			'image' : [],
			'annotations': []
		}

		for elem in tqdm(xml_tree.iter()):
			if elem.tag == "image":
				annotation = []
				for child in elem.iter():
					if child.tag == "box":
						xtl = float(child.get('xtl'))
						ytl = float(child.get('ytl'))
						width = float(child.get('xbr')) - float(child.get('xtl'))
						height = float(child.get('ybr')) - float(child.get('ytl'))
						initBBox = (xtl, ytl, width, height)
						annotation.append(XMLParser.getTCAnnotationFromBB(initBBox, child.get('label'), None))
				image = tc.Image(os.path.join(image_folder, elem.get("name")))
				data['annotations'].append(annotation)
				data['image'].append(image)
		# print(data)
		return tc.SFrame(data)

if __name__ == "__main__":
	parser = argparse.ArgumentParser(description='Creates an sframe of evaluation set')
	parser.add_argument('--image_folder', required = True,
	                    help='path to folder of all images')
	parser.add_argument('--xml_file', required = True, help = 'path to xml file')
	# parser.add_argument('--mask', required = False, help = 'path to folder of all xml annotations')

	args = parser.parse_args()

	sf = EvaluationSFrame.getSFrame(args.xml_file, args.image_folder)
	print("total number of images in sframe: " + str(len(sf)))
	# sf.print_rows(num_rows= len(sf))
	sf.save(str(len(sf)) + "evaluationSet.sframe")


import os
import re

f=open('Result.xls','r')
o=open('Result_new.xls','w+') #Rename this file to  Result.xls,then update is done

#hash for updating
ca={'ERP009131':'Canada'}			#No Country info,now update
twins={'ERP010700':'United Kindoms(twins)'}	#No Country info,now update
sweden={'ERP002469':'Sweden'}  #some from other countries ,but live in Sweden for a long time,so seem as Sweden
#ERP005989:some is baby _B,_4M_12M, for these samples,country info set as Denmark(baby)
area={}
disease={}
while True:
	count=1
	line=f.readline()
	line=line.strip()
	if not line:break
	ele=line.split('\t')
	es=[]
	for e in ele:
		e=e.strip()
		es.append(e)
	if es[3] in ca:
		es[22]=ca[es[3]]
	elif es[3] in twins:
		es[22]=twins[es[3]]
	elif es[3] in sweden:
		es[22]=sweden[es[3]]
	elif re.search('_12M',es[1]) or re.search('_4M',es[1]) or re.search('_B',es[1]):
		es[22]='Denmark(baby)'
	for c in es:
		if count==1:
			o.write(c)
			count+=1
			continue
		o.write('\t'+c)
	o.write('\n')


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/1/21 15:45
# @Author  : 叶永彬
# @File    : test_buyMonthTicket.py

import unittest
from Pages.payMonthTicket_page import PayMonthTicketPage
from Pages.payCharges_page import ChargesPage
import allure
from interface.pomp import Pomp
from Config.Config import Config
from common.baseCommon import getFunName

@allure.feature("购买月票模块")
class TestMonthTicket(unittest.TestCase):

	@classmethod
	def setUpClass(cls):
		cls.A = ChargesPage()
		cls.M = PayMonthTicketPage()

	@classmethod
	def tearDownClass(cls):
		Pomp().refund_monthTicket(carNum=Config().common_carNum)
		pass

	@getFunName
	@allure.story("购买月票")
	def test_buy_monthTicket(self):
		"""
		用例描述：购买月票
		"""
		result =self.M.buy_monthTicket("自动化测试停车场")
		assert result == True

	@getFunName
	@allure.story("访客授权一次")
	def test_visitor_authorization_once(self):
		"""
		用例描述：访客授权一次
		"""
		self.carCode = self.A.create_carNum()
		result = self.M.visitor_authorization(self.carCode,time = "once")
		assert result == "授权一次"
		self.M.del_visitorCar()

	@getFunName
	@allure.story("访客授权永久")
	def test_visitor_authorization_forever(self):
		"""
		用例描述：访客授权永久
		"""
		self.carCode = self.A.create_carNum()
		result = self.M.visitor_authorization(self.carCode,time = "forever")
		assert result == "不限次数"
		self.M.del_visitorCar()

	@getFunName
	@allure.story("点击月票详情")
	def test_monthTicket_detail(self):
		"""
		用例描述：点击月票详情
		"""
		result = self.M.check_details()
		assert result == "自动化测试停车场"
		ChargesPage().back(1)

	@getFunName
	@allure.story("月票续约")
	def test_mothTicket_renew(self):
		"""
		用例描述：月票续约
		"""
		result = self.M.renew_monthTicket()
		assert result == True


from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django.conf import settings

from push_notifications.models import APNSDevice, GCMDevice
from push_notifications.admin import DeviceAdmin

# Register your models here.
class CustomDeviceAdmin(DeviceAdmin):
    list_display = ('user', 'registration_id', 'active', 'date_created')
    fields = ('name', 'active', 'user', 'registration_id', 'date_created')
    readonly_fields = ('date_created',)
    search_fields = ('registration_id', 'user__email')
    actions = ('send_message', 'send_message_sound_badge', 'send_bulk_message',
               'prune_devices', 'enable', 'disable')

    def video_for_device(self, device):
        """
        get any video for the user associated with a device

        Returns:
            Video object instance or none
        """
        videos = device.user.videos.all().order_by('-created_at')
        return videos[0] if len(videos) > 0 else None

    def send_message(self, request, queryset):
        for device in queryset:
            try:
                video = self.video_for_device(device)
                extra = {} # must be an empty dictionary but not None
                if video:
                    extra[settings.PUSH_VIDEO_HASH_KEY_KEY] = video.hash_key
                if device.user:
                    extra[settings.PUSH_VIDEO_USER_PHONE_NUMBER_KEY] = (
                        device.user.phone_number.as_e164)
                    extra[settings.PUSH_VIDEO_USER_FULL_NAME_KEY] = (
                        device.user.full_name)

                extra[settings.PUSH_VIDEO_MESSAGE_KEY ] = (
                    'This is what it looks like when a chicken crosses the '
                    'road and clucks at the same time. Ideally this message '
                    'would be somewhat long')

                device.send_message("Test single notification", extra=extra)
            except Exception as e:
                pass
    send_message.short_description = _("Send test message")

    def send_message_sound_badge(self, request, queryset):
        for device in queryset:
            try:
                video = self.video_for_device(device)
                extra = {} # must be an empty dictionary but not None
                if video:
                    extra[settings.PUSH_VIDEO_HASH_KEY_KEY] = video.hash_key
                if device.user:
                    extra[settings.PUSH_VIDEO_USER_PHONE_NUMBER_KEY] = (
                        device.user.phone_number.as_e164)
                    extra[settings.PUSH_VIDEO_USER_FULL_NAME_KEY] = (
                        device.user.full_name)

                extra[settings.PUSH_VIDEO_MESSAGE_KEY ] = 'just a message!!'

                device.send_message(
                    "Test single notification with sound and badge",
                    sound="default", badge=1, extra=extra)
            except Exception as e:
                pass
    send_message_sound_badge.short_description = (
        "Send test message with sound and badge")

# unregister default ModelAdmins
admin.site.unregister(APNSDevice)
admin.site.unregister(GCMDevice)

# register custom ModelAdmins
admin.site.register(APNSDevice, CustomDeviceAdmin)


def HF(n):
	for i in range(1,int(n/2)+1):
		if n%i==0:
			hf=i
	return hf

n=int(input("enter no:-"))
print("hf of given no:-",HF(n))


from collections import OrderedDict, namedtuple
from dataclasses import dataclass, fields
from typing import Dict, List, Tuple

import numpy as np
import torch

from modelscope.utils.constant import Tasks

class OutputKeys(object):
    LOSS = 'loss'
    LOGITS = 'logits'
    SCORES = 'scores'
    SCORE = 'score'
    LABEL = 'label'
    LABELS = 'labels'
    INPUT_IDS = 'input_ids'
    LABEL_POS = 'label_pos'
    POSES = 'poses'
    CAPTION = 'caption'
    BOXES = 'boxes'
    KEYPOINTS = 'keypoints'
    MASKS = 'masks'
    DEPTHS = 'depths'
    DEPTHS_COLOR = 'depths_color'
    LAYOUT = 'layout'
    TEXT = 'text'
    POLYGONS = 'polygons'
    OUTPUT = 'output'
    OUTPUT_IMG = 'output_img'
    OUTPUT_IMGS = 'output_imgs'
    OUTPUT_VIDEO = 'output_video'
    OUTPUT_PCM = 'output_pcm'
    OUTPUT_PCM_LIST = 'output_pcm_list'
    OUTPUT_WAV = 'output_wav'
    OUTPUT_OBJ = 'output_obj'
    OUTPUT_MESH = 'output_mesh'
    IMG_EMBEDDING = 'img_embedding'
    SPK_EMBEDDING = 'spk_embedding'
    SPO_LIST = 'spo_list'
    TEXT_EMBEDDING = 'text_embedding'
    TRANSLATION = 'translation'
    RESPONSE = 'response'
    PREDICTION = 'prediction'
    PREDICTIONS = 'predictions'
    PROBABILITIES = 'probabilities'
    DIALOG_STATES = 'dialog_states'
    VIDEO_EMBEDDING = 'video_embedding'
    PHRASE_PROTOTYPE = 'phrase_prototype'
    OBJECT_PROTOTYPE = 'object_prototype'
    SENTENCE_PROTOTYPE = 'sentence_prototype'
    EVENT_PROTOTYPE = 'event_prototype'
    TEXTVIDEO_SIM = 'textvideo_sim'
    UUID = 'uuid'
    WORD = 'word'
    KWS_LIST = 'kws_list'
    SQL_STRING = 'sql_string'
    SQL_QUERY = 'sql_query'
    HISTORY = 'history'
    QUERY_RESULT = 'query_result'
    TIMESTAMPS = 'timestamps'
    SHOT_NUM = 'shot_num'
    SCENE_NUM = 'scene_num'
    SCENE_META_LIST = 'scene_meta_list'
    SHOT_META_LIST = 'shot_meta_list'
    MATCHES = 'matches'
    PCD12 = 'pcd12'
    PCD12_ALIGN = 'pcd12_align'
    TBOUNDS = 'tbounds'

OutputTypes = {
    OutputKeys.LOSS: float,  # checked
    OutputKeys.LOGITS: np.ndarray,  # checked.
    OutputKeys.SCORES: List[float],  # checked
    OutputKeys.SCORE: float,  # checked
    OutputKeys.LABEL: str,  # checked
    OutputKeys.LABELS: List[str],  # checked
    OutputKeys.INPUT_IDS: np.ndarray,  # checked
    OutputKeys.LABEL_POS: np.ndarray,  # checked
    OutputKeys.POSES:
    List[np.ndarray],  # [Tuple(np.ndarray, np.ndarray)]  # checked doubtful
    OutputKeys.CAPTION: str,
    OutputKeys.BOXES: np.ndarray,  # checked
    OutputKeys.KEYPOINTS: np.ndarray,  # checked
    OutputKeys.MASKS: np.ndarray,  # checked
    OutputKeys.DEPTHS: List[np.ndarray],  # checked
    OutputKeys.DEPTHS_COLOR: List[np.ndarray],  # checked
    OutputKeys.LAYOUT: np.ndarray,  # checked
    OutputKeys.TEXT: str,  # checked
    OutputKeys.POLYGONS: np.array,  # checked
    OutputKeys.OUTPUT: Dict,
    OutputKeys.OUTPUT_IMG: 'image',  # checked
    OutputKeys.OUTPUT_IMGS: List[np.ndarray],  # checked
    OutputKeys.OUTPUT_VIDEO: 'bytes',
    OutputKeys.OUTPUT_PCM: 'pcm',
    OutputKeys.OUTPUT_PCM_LIST: List[np.ndarray],
    OutputKeys.OUTPUT_WAV: 'pcm',
    OutputKeys.OUTPUT_OBJ: Dict,
    OutputKeys.OUTPUT_MESH: np.ndarray,
    OutputKeys.IMG_EMBEDDING: np.ndarray,
    OutputKeys.SPK_EMBEDDING: np.ndarray,
    OutputKeys.SPO_LIST: List[float],
    OutputKeys.TEXT_EMBEDDING: np.ndarray,
    OutputKeys.TRANSLATION: str,
    OutputKeys.RESPONSE: Dict,
    OutputKeys.PREDICTION: np.ndarray,  # checked
    OutputKeys.PREDICTIONS: List[np.ndarray],
    OutputKeys.PROBABILITIES: np.ndarray,
    OutputKeys.DIALOG_STATES: object,
    OutputKeys.VIDEO_EMBEDDING: np.ndarray,
    OutputKeys.PHRASE_PROTOTYPE: np.ndarray,
    OutputKeys.OBJECT_PROTOTYPE: np.ndarray,
    OutputKeys.SENTENCE_PROTOTYPE: np.ndarray,
    OutputKeys.EVENT_PROTOTYPE: np.ndarray,
    OutputKeys.TEXTVIDEO_SIM: np.ndarray,
    OutputKeys.UUID: str,
    OutputKeys.WORD: str,
    OutputKeys.KWS_LIST: List[str],
    OutputKeys.SQL_STRING: str,  # checked
    OutputKeys.SQL_QUERY: str,  # checked
    OutputKeys.HISTORY: Dict,  # checked
    OutputKeys.QUERY_RESULT: Dict,  # checked
    OutputKeys.TIMESTAMPS: str,
    OutputKeys.SHOT_NUM: int,
    OutputKeys.SCENE_NUM: int,
    OutputKeys.SCENE_META_LIST: List[int],
    OutputKeys.SHOT_META_LIST: List[int],
    OutputKeys.MATCHES: List[np.ndarray],
    OutputKeys.PCD12: np.ndarray,
    OutputKeys.PCD12_ALIGN: np.ndarray,
    OutputKeys.TBOUNDS: Dict,
}

OutputTypeSchema = {
    OutputKeys.LOSS: {
        'type': 'number'
    },  # checked
    OutputKeys.LOGITS: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked.
    OutputKeys.SCORES: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.SCORE: {
        'type': 'number'
    },  # checked
    OutputKeys.LABEL: {
        'type': 'string'
    },  # checked
    OutputKeys.LABELS: {
        'type': 'array',
        'items': {
            'type': 'string'
        }
    },  # checked
    OutputKeys.INPUT_IDS: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.LABEL_POS: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.POSES: {
        'type': 'array',
        'items': {
            'type': 'array',
            'items': {
                'type': 'number'
            }
        }
    },  # [Tuple(np.ndarray, np.ndarray)]  # checked doubtful
    OutputKeys.CAPTION: {
        'type': 'string'
    },
    OutputKeys.BOXES: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.KEYPOINTS: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.MASKS: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.DEPTHS: {
        'type': 'array',
        'items': {
            'type': 'array',
            'items': {
                'type': 'number'
            }
        }
    },  # checked
    OutputKeys.DEPTHS_COLOR: {
        'type': 'array',
        'items': {
            'type': 'array',
            'items': {
                'type': 'number'
            }
        }
    },  # checked
    OutputKeys.LAYOUT: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.TEXT: {
        'type': 'string'
    },  # checked
    OutputKeys.POLYGONS: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.OUTPUT: {
        'type': 'object'
    },
    OutputKeys.OUTPUT_IMG: {
        'type': 'string',
        'description': 'The base64 encoded image.',
    },  # checked
    OutputKeys.OUTPUT_IMGS: {
        'type': 'array',
        'items': {
            'type': 'string',
            'description': 'The base64 encoded image.',
        }
    },  # checked
    OutputKeys.OUTPUT_VIDEO: {
        'type': 'string',
        'description': 'The base64 encoded video.',
    },
    OutputKeys.OUTPUT_PCM: {
        'type': 'string',
        'description': 'The base64 encoded PCM.',
    },
    OutputKeys.OUTPUT_PCM_LIST: {
        'type': 'array',
        'items': {
            'type': 'string',
            'description': 'The base64 encoded PCM.',
        }
    },
    OutputKeys.OUTPUT_WAV: {
        'type': 'string',
        'description': 'The base64 encoded WAV.',
    },
    OutputKeys.OUTPUT_OBJ: {
        'type': 'object'
    },
    OutputKeys.OUTPUT_MESH: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.IMG_EMBEDDING: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.SPK_EMBEDDING: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.SPO_LIST: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.TEXT_EMBEDDING: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.TRANSLATION: {
        'type': 'string'
    },
    OutputKeys.RESPONSE: {
        'type': 'object'
    },
    OutputKeys.PREDICTION: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },  # checked
    OutputKeys.PREDICTIONS: {
        'type': 'array',
        'items': {
            'type': 'array',
            'items': {
                'type': 'number'
            }
        }
    },
    OutputKeys.PROBABILITIES: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.DIALOG_STATES: {
        'type': 'object'
    },
    OutputKeys.VIDEO_EMBEDDING: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.PHRASE_PROTOTYPE: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.OBJECT_PROTOTYPE: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.TEXTVIDEO_SIM: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.UUID: {
        'type': 'string'
    },
    OutputKeys.WORD: {
        'type': 'string'
    },
    OutputKeys.KWS_LIST: {
        'type': 'array',
        'items': {
            'type': 'string'
        }
    },
    OutputKeys.SQL_STRING: {
        'type': 'string'
    },  # checked
    OutputKeys.SQL_QUERY: {
        'type': 'string'
    },  # checked
    OutputKeys.HISTORY: {
        'type': 'object'
    },  # checked
    OutputKeys.QUERY_RESULT: {
        'type': 'object'
    },  # checked
    OutputKeys.TIMESTAMPS: {
        'type': 'string'
    },
    OutputKeys.SHOT_NUM: {
        'type': 'integer'
    },
    OutputKeys.SCENE_NUM: {
        'type': 'integer'
    },
    OutputKeys.SCENE_META_LIST: {
        'type': 'array',
        'items': {
            'type': 'integer'
        }
    },
    OutputKeys.SHOT_META_LIST: {
        'type': 'array',
        'items': {
            'type': 'integer'
        }
    },
    OutputKeys.MATCHES: {
        'type': 'array',
        'items': {
            'type': 'array',
            'items': {
                'type': 'number'
            }
        }
    },
    OutputKeys.PCD12: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.PCD12_ALIGN: {
        'type': 'array',
        'items': {
            'type': 'number'
        }
    },
    OutputKeys.TBOUNDS: {
        'type': 'object'
    },
}

TASK_OUTPUTS = {
    Tasks.task_template:
    [OutputKeys.BOXES, OutputKeys.OUTPUT_IMG, OutputKeys.TEXT_EMBEDDING],
    # ============ vision tasks ===================

    # ocr detection result for single sample
    # {
    #   "polygons": np.array with shape [num_text, 8], each polygon is
    #       [x1, y1, x2, y2, x3, y3, x4, y4]
    # }
    Tasks.ocr_detection: [OutputKeys.POLYGONS],
    Tasks.table_recognition: [OutputKeys.POLYGONS],
    Tasks.lineless_table_recognition: [OutputKeys.POLYGONS, OutputKeys.BOXES],
    Tasks.license_plate_detection: [OutputKeys.POLYGONS, OutputKeys.TEXT],
    Tasks.card_detection_correction: [
        OutputKeys.POLYGONS, OutputKeys.SCORES, OutputKeys.OUTPUT_IMGS,
        OutputKeys.LABELS, OutputKeys.LAYOUT
    ],

    # ocr recognition result for single sample
    # {
    #    "text": "电子元器件提供BOM配单"
    # }
    Tasks.ocr_recognition: [OutputKeys.TEXT],
    Tasks.sudoku: [OutputKeys.TEXT],
    Tasks.text2sql: [OutputKeys.TEXT],

    # document vl embedding for single sample
    # {
    #    "img_embedding": np.array with shape [M, D],
    #    "text_embedding": np.array with shape [N, D]
    # }
    Tasks.document_vl_embedding:
    [OutputKeys.IMG_EMBEDDING, OutputKeys.TEXT_EMBEDDING],

    # face 2d keypoint result for single sample
    #   {
    #       "keypoints": [
    #           [[x, y]*106],
    #           [[x, y]*106],
    #           [[x, y]*106],
    #       ],
    #       "poses": [
    #            [pitch, roll, yaw],
    #            [pitch, roll, yaw],
    #            [pitch, roll, yaw],
    #        ],
    #        "boxes": [
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #       ]
    #   }
    Tasks.face_2d_keypoints:
    [OutputKeys.KEYPOINTS, OutputKeys.POSES, OutputKeys.BOXES],

    # face detection result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "boxes": [
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #       ],
    #       "keypoints": [
    #           [x1, y1, x2, y2, x3, y3, x4, y4, x5, y5],
    #           [x1, y1, x2, y2, x3, y3, x4, y4, x5, y5],
    #           [x1, y1, x2, y2, x3, y3, x4, y4, x5, y5],
    #           [x1, y1, x2, y2, x3, y3, x4, y4, x5, y5],
    #       ],
    #   }
    Tasks.face_detection:
    [OutputKeys.SCORES, OutputKeys.BOXES, OutputKeys.KEYPOINTS],

    # card detection result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "boxes": [
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #       ],
    #       "keypoints": [
    #           [x1, y1, x2, y2, x3, y3, x4, y4],
    #           [x1, y1, x2, y2, x3, y3, x4, y4],
    #           [x1, y1, x2, y2, x3, y3, x4, y4],
    #           [x1, y1, x2, y2, x3, y3, x4, y4],
    #       ],
    #   }
    Tasks.card_detection:
    [OutputKeys.SCORES, OutputKeys.BOXES, OutputKeys.KEYPOINTS],

    # content check result for single sample
    #   {
    #       "scores": [0.9] # non sexy probability
    #   }
    Tasks.content_check: [OutputKeys.SCORES],

    # image driving perception result for single sample
    #   {
    #       "boxes": [
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #       ],
    #       "masks": [
    #            [np.array], # with fixed shape(h=720, w=1280, 3) containing only 0, 1
    #            [np.array], # with fixed shape(h=720, w=1280, 3) containing only 0, 1
    #       ]
    #   }
    Tasks.image_driving_perception: [OutputKeys.BOXES, OutputKeys.MASKS],

    # facial expression recognition result for single sample
    #   {
    #       "scores": [0.9]
    #       "boxes": [x1, y1, x2, y2]
    #   }
    Tasks.face_liveness: [OutputKeys.SCORES, OutputKeys.BOXES],

    # face quality assessment for single sample
    #   {
    #       "scores": [0.9]
    #       "boxes": [x1, y1, x2, y2]
    #   }
    Tasks.face_quality_assessment: [OutputKeys.SCORES, OutputKeys.BOXES],

    # facial expression recognition result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.02, 0.02, 0.02, 0.02, 0.02],
    #       "labels": ['Angry', 'Disgust', 'Fear', 'Happy', 'Sad', 'Surprise', 'Neutral']
    #   }
    Tasks.facial_expression_recognition:
    [OutputKeys.SCORES, OutputKeys.LABELS],
    Tasks.general_recognition: [OutputKeys.SCORES, OutputKeys.LABELS],

    # face processing base result for single img
    #   {
    #       "scores": [0.85]
    #       "boxes": [x1, y1, x2, y2]
    #       "keypoints": [x1, y1, x2, y2, x3, y3, x4, y4]
    #   }
    Tasks.face_processing_base: [
        OutputKeys.OUTPUT_IMG, OutputKeys.SCORES, OutputKeys.BOXES,
        OutputKeys.KEYPOINTS
    ],

    # face attribute recognition result for single sample
    #   {
    #       "scores": [[0.9, 0.1], [0.92, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01]
    #       "labels": [['Male', 'Female'], [0-2, 3-9, 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70+]]
    #   }
    Tasks.face_attribute_recognition: [OutputKeys.SCORES, OutputKeys.LABELS],

    # face recognition result for single sample
    #   {
    #       "img_embedding": np.array with shape [1, D],
    #   }
    Tasks.face_recognition: [OutputKeys.IMG_EMBEDDING],

    # human detection result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "labels": ["person", "person", "person", "person"],
    #       "boxes": [
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #       ],
    #   }
    #
    Tasks.human_detection:
    [OutputKeys.SCORES, OutputKeys.LABELS, OutputKeys.BOXES],

    # face generation result for single sample
    # {
    #   "output_img": np.array with shape(h, w, 3)
    # }
    Tasks.face_image_generation: [OutputKeys.OUTPUT_IMG],

    # image classification result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "labels": ["dog", "horse", "cow", "cat"],
    #   }
    Tasks.image_classification: [OutputKeys.SCORES, OutputKeys.LABELS],

    # object detection result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "labels": ["dog", "horse", "cow", "cat"],
    #       "boxes": [
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #       ],
    #   }
    Tasks.image_object_detection:
    [OutputKeys.SCORES, OutputKeys.LABELS, OutputKeys.BOXES],
    Tasks.domain_specific_object_detection:
    [OutputKeys.SCORES, OutputKeys.LABELS, OutputKeys.BOXES],
    Tasks.open_vocabulary_detection:
    [OutputKeys.SCORES, OutputKeys.LABELS, OutputKeys.BOXES],

    # video object detection result for single sample
    #   {

    #         "scores": [[0.8, 0.25, 0.05, 0.05], [0.9, 0.1, 0.05, 0.05]]
    #         "labels": [["person", "traffic light", "car", "bus"],
    #                     ["person", "traffic light", "car", "bus"]]
    #         "boxes":
    #          [
    #              [
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #              ],
    #              [
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #               ]
    #           ],

    #   }
    Tasks.video_object_detection:
    [OutputKeys.SCORES, OutputKeys.LABELS, OutputKeys.BOXES],

    # 3d object detection result for single sample
    # {
    #   "output_img": np.array with shape(h, w, 3)
    # }
    Tasks.object_detection_3d: [OutputKeys.OUTPUT_IMG],

    # instance segmentation result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05],
    #       "labels": ["dog", "horse", "cow", "cat"],
    #       "masks": [
    #           np.array # 2D array containing only 0, 1
    #       ]
    #   }
    Tasks.image_segmentation:
    [OutputKeys.SCORES, OutputKeys.LABELS, OutputKeys.MASKS],

    # video panoptic segmentation result for single sample
    #         "scores": [[0.8, 0.25, 0.05, 0.05], [0.9, 0.1, 0.05, 0.05]]
    #         "labels": [["person", "traffic light", "car", "bus"],
    #                     ["person", "traffic light", "car", "bus"]]
    #       "masks": [ #array containing only 0, 1
    #           [np.array, np.array, np.array, np.array],
    #           [np.array, np.array, np.array, np.array],
    #       ]
    #       "boxes":
    #          [
    #              [
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #              ],
    #              [
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #                [x1, y1, x2, y2],
    #               ]
    #           ],
    #       "uuid": [[0, 1, 2, 3],[0, 1, 2, 3]]
    #   }
    Tasks.video_panoptic_segmentation: [
        OutputKeys.SCORES, OutputKeys.LABELS, OutputKeys.MASKS,
        OutputKeys.BOXES, OutputKeys.UUID
    ],

    # semantic segmentation result for single sample
    #   {
    #       "masks": [np.array # 2D array with shape [height, width]]
    #   }
    Tasks.semantic_segmentation: [OutputKeys.MASKS],

    # image matting result for single sample
    # {
    #   "output_img": np.array with shape(h, w, 4)
    #                 for matting or (h, w, 3) for general purpose
    #                 , shape(h, w) for crowd counting
    # }
    Tasks.portrait_matting: [OutputKeys.OUTPUT_IMG],
    Tasks.universal_matting: [OutputKeys.OUTPUT_IMG],
    Tasks.image_deblurring: [OutputKeys.OUTPUT_IMG],
    Tasks.image_face_fusion: [OutputKeys.OUTPUT_IMG],

    # image_quality_assessment_mos result for a single image is a score in range [0, 1]
    # {0.5}
    Tasks.image_quality_assessment_mos: [OutputKeys.SCORE],

    # image editing task result for a single image
    # {"output_img": np.array with shape (h, w, 3)}
    Tasks.skin_retouching: [OutputKeys.OUTPUT_IMG],
    Tasks.image_super_resolution: [OutputKeys.OUTPUT_IMG],
    Tasks.image_super_resolution_pasd: [OutputKeys.OUTPUT_IMG],
    Tasks.image_colorization: [OutputKeys.OUTPUT_IMG],
    Tasks.image_color_enhancement: [OutputKeys.OUTPUT_IMG],
    Tasks.image_denoising: [OutputKeys.OUTPUT_IMG],
    Tasks.image_editing: [OutputKeys.OUTPUT_IMG],
    Tasks.image_portrait_enhancement: [OutputKeys.OUTPUT_IMG],
    Tasks.crowd_counting: [OutputKeys.SCORES, OutputKeys.OUTPUT_IMG],
    Tasks.image_inpainting: [OutputKeys.OUTPUT_IMG],
    Tasks.image_paintbyexample: [OutputKeys.OUTPUT_IMG],
    Tasks.controllable_image_generation: [OutputKeys.OUTPUT_IMG],

    # image generation task result for a single image
    # {"output_img": np.array with shape (h, w, 3)}
    Tasks.image_to_image_generation: [OutputKeys.OUTPUT_IMG],
    Tasks.image_to_image_translation: [OutputKeys.OUTPUT_IMG],
    Tasks.image_style_transfer: [OutputKeys.OUTPUT_IMG],
    Tasks.image_portrait_stylization: [OutputKeys.OUTPUT_IMG],
    Tasks.image_body_reshaping: [OutputKeys.OUTPUT_IMG],

    # video editing task result for a single video
    # {"output_video": "path_to_rendered_video"}
    Tasks.video_frame_interpolation: [OutputKeys.OUTPUT_VIDEO],
    Tasks.video_super_resolution: [OutputKeys.OUTPUT_VIDEO],
    Tasks.video_deinterlace: [OutputKeys.OUTPUT_VIDEO],
    Tasks.nerf_recon_acc: [OutputKeys.OUTPUT],
    Tasks.nerf_recon_vq_compression: [OutputKeys.OUTPUT],
    Tasks.surface_recon_common: [OutputKeys.OUTPUT],
    Tasks.video_colorization: [OutputKeys.OUTPUT_VIDEO],
    Tasks.image_control_3d_portrait: [OutputKeys.OUTPUT],

    # image quality assessment degradation result for single image
    # {
    #       "scores": [0.885272, 0.014790631, 0.014558001]
    #       "labels": ['噪声强度', '模糊程度', '压缩强度'],
    # }
    Tasks.image_quality_assessment_degradation: [
        OutputKeys.SCORES, OutputKeys.LABELS
    ],

    # live category recognition result for single video
    # {
    #       "scores": [0.885272, 0.014790631, 0.014558001]
    #       "labels": ['女装/女士精品>>棉衣/棉服', '女装/女士精品>>牛仔裤', '女装/女士精品>>裤子>>休闲裤'],
    # }
    Tasks.live_category: [OutputKeys.SCORES, OutputKeys.LABELS],

    # action recognition result for single video
    # {
    #   "output_label": "abseiling"
    # }
    Tasks.action_recognition: [OutputKeys.LABELS],

    # human body keypoints detection result for single sample
    # {
    #   "keypoints": [
    #               [[x, y]*15],
    #               [[x, y]*15],
    #               [[x, y]*15]
    #             ]
    #   "scores": [
    #               [[score]*15],
    #               [[score]*15],
    #               [[score]*15]
    #              ]
    #   "boxes": [
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #             ]
    # }
    Tasks.body_2d_keypoints: [
        OutputKeys.KEYPOINTS, OutputKeys.SCORES, OutputKeys.BOXES
    ],

    # 3D human body keypoints detection result for single sample
    # {
    #   "keypoints": [		    # 3d pose coordinate in camera coordinate
    #     	[[x, y, z]*17],	# joints of per image
    #     	[[x, y, z]*17],
    #     	...
    #     ],
    #   "timestamps": [     # timestamps of all frames
    #     "00:00:0.230",
    #     "00:00:0.560",
    #     "00:00:0.690",
    #   ],
    #   "output_video": "path_to_rendered_video" , this is optional
    # and is only available when the "render" option is enabled.
    # }
    Tasks.body_3d_keypoints: [
        OutputKeys.KEYPOINTS, OutputKeys.TIMESTAMPS, OutputKeys.OUTPUT_VIDEO
    ],

    # pedestrain attribute recognition result for single sample
    # {
    #   "boxes": [
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #             ]
    #   "labels": [
    #                    ['Female', 'AgeOver60', 'Front', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes',
    #                        'LongSleeve', 'Black', 'Trousers', 'Black' ],
    #                    ['Female', 'AgeOver60', 'Front', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes',
    #                        'LongSleeve', 'Black', 'Trousers', 'Black' ],
    #                    ['Female', 'AgeOver60', 'Front', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes',
    #                        'LongSleeve', 'Black', 'Trousers', 'Black' ],
    #           ]
    # }
    Tasks.pedestrian_attribute_recognition: [
        OutputKeys.BOXES, OutputKeys.LABELS
    ],

    # 3D face reconstruction result for single sample
    # {
    #     "output_obj": io.BytesIO,
    #     "output_img": np.array with shape(h, w, 3),
    #     "output": {
    #         "mesh": {
    #             "vertices": np.array with shape(n, 3),
    #             "faces": np.array with shape(n, 3),
    #             "faces_uv": np.array with shape(n, 3),
    #             "faces_normal": np.array with shape(n, 3),
    #             "UVs": np.array with shape(n, 2),
    #             "normals": np.array with shape(n, 3),
    #         },
    #         "vis_image": np.array with shape(h, w, 3),
    #         "frame_list", [np.array with shape(h, w, 3), ...],
    #     }
    # }
    Tasks.face_reconstruction: [OutputKeys.OUTPUT],
    Tasks.human3d_render: [OutputKeys.OUTPUT],
    Tasks.human3d_animation: [OutputKeys.OUTPUT],

    # 3D head reconstruction result for single sample
    # {
    #     "output_obj": io.BytesIO,
    #     "output_img": np.array with shape(h, w, 3),
    #     "output": {
    #         "mesh": {
    #             "vertices": np.array with shape(n, 3),
    #             "faces": np.array with shape(n, 3),
    #             "faces_uv": np.array with shape(n, 3),
    #             "faces_normal": np.array with shape(n, 3),
    #             "UVs": np.array with shape(n, 2),
    #             "normals": np.array with shape(n, 3),
    #         },
    #     }
    # }
    Tasks.head_reconstruction: [OutputKeys.OUTPUT],

    # text to head result for text input
    # {
    #     "output_obj": io.BytesIO,
    #     "output_img": np.array with shape(h, w, 3),
    #     "output": {
    #         "mesh": {
    #             "vertices": np.array with shape(n, 3),
    #             "faces": np.array with shape(n, 3),
    #             "faces_uv": np.array with shape(n, 3),
    #             "faces_normal": np.array with shape(n, 3),
    #             "UVs": np.array with shape(n, 2),
    #             "normals": np.array with shape(n, 3),
    #         },
    #     },
    #     "image": np.array with shape(h, w, 3),
    # }
    Tasks.text_to_head: [OutputKeys.OUTPUT],

    # 3D human reconstruction result for single sample
    # {
    #     "output": {
    #         "vertices": np.array with shape(n, 3),
    #         "faces": np.array with shape(n, 3),
    #         "colors": np.array with shape(n, 3),
    #     }
    # }
    Tasks.human_reconstruction: [OutputKeys.OUTPUT],

    # 3D text 2 texture generation result
    # {
    #     "output": {
    #         "Done"
    #     }
    # }
    Tasks.text_texture_generation: [OutputKeys.OUTPUT],

    # 2D hand keypoints result for single sample
    # {
    #     "keypoints": [
    #                     [[x, y, score] * 21],
    #                     [[x, y, score] * 21],
    #                     [[x, y, score] * 21],
    #                  ],
    #     "boxes": [
    #                 [x1, y1, x2, y2],
    #                 [x1, y1, x2, y2],
    #                 [x1, y1, x2, y2],
    #             ]
    # }
    Tasks.hand_2d_keypoints: [OutputKeys.KEYPOINTS, OutputKeys.BOXES],

    # video single object tracking result for single video
    # {
    #   "boxes": [
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #             ],
    #   "timestamps": ["hh:mm:ss", "hh:mm:ss", "hh:mm:ss"]
    # }
    Tasks.video_single_object_tracking: [
        OutputKeys.BOXES, OutputKeys.TIMESTAMPS
    ],

    # video multi object tracking result for single video
    # {
    #   "boxes": [
    #               [
    #                   [x1, y1, x2, y2],
    #                   [x1, y1, x2, y2],
    #                   ...
    #               ],
    #               [
    #                   [x1, y1, x2, y2],
    #                   [x1, y1, x2, y2],
    #                   ...
    #               ],
    #               [
    #                   [x1, y1, x2, y2]
    #                   ...
    #               ]
    #             ],
    #   "labels": [[obj_id0, obj_id1, ...], [obj_id1, obj_id2, ...], [obj_id3, ...]],
    #   "timestamps": ["hh:mm:ss", "hh:mm:ss", "hh:mm:ss"]
    # }
    Tasks.video_multi_object_tracking: [
        OutputKeys.BOXES, OutputKeys.LABELS, OutputKeys.TIMESTAMPS
    ],

    # live category recognition result for single video
    # {
    #       "scores": [0.885272, 0.014790631, 0.014558001],
    #       'labels': ['修身型棉衣', '高腰牛仔裤', '休闲连体裤']
    # }
    Tasks.live_category: [OutputKeys.SCORES, OutputKeys.LABELS],

    # video category recognition result for single video
    # {
    #       "scores": [0.7716429233551025],
    #       "labels": ['生活>>好物推荐']
    # }
    Tasks.video_category: [OutputKeys.SCORES, OutputKeys.LABELS],

    # image embedding result for a single image
    # {
    #   "image_bedding": np.array with shape [D]
    # }
    Tasks.product_retrieval_embedding: [OutputKeys.IMG_EMBEDDING],

    # video embedding result for single video
    # {
    #   "video_embedding": np.array with shape [D],
    # }
    Tasks.video_embedding: [OutputKeys.VIDEO_EMBEDDING],

    # phrase prototype result for single sentence
    # {
    #   "phrase_prototype": np.array with shape [K*D],
    # }
    # sentence prototype result for single sentence
    # {
    #   "sentence_prototype": np.array with shape [1*D],
    # }
    # object prototype result for single video
    # {
    #   "object_prototype": np.array with shape [N*K*D],
    # }
    # event prototype result for single video
    # {
    #   "event_prototype": np.array with shape [N*M*D],
    # }
    # text search video result for single sentence
    # {
    #   "textvideo_sim": np.array with shape [N*N],
    # }
    Tasks.text_video_retrieval: [
        OutputKeys.PHRASE_PROTOTYPE, OutputKeys.SENTENCE_PROTOTYPE,
        OutputKeys.OBJECT_PROTOTYPE, OutputKeys.EVENT_PROTOTYPE,
        OutputKeys.TEXTVIDEO_SIM
    ],

    # video stabilization task result for a single video
    # {"output_video": "path_to_rendered_video"}
    Tasks.video_stabilization: [OutputKeys.OUTPUT_VIDEO],

    # virtual_try_on result for a single sample
    # {
    #    "output_img": np.ndarray with shape [height, width, 3]
    # }
    Tasks.virtual_try_on: [OutputKeys.OUTPUT_IMG],
    # text driven segmentation result for single sample
    #   {
    #       "masks": [
    #           np.array # 2D array containing only 0, 255
    #       ]
    #   }
    Tasks.text_driven_segmentation: [OutputKeys.MASKS],
    # shop segmentation result for single sample
    #   {
    #       "masks": [
    #           np.array # 2D array containing only 0, 255
    #       ]
    #   }
    Tasks.shop_segmentation: [OutputKeys.MASKS],
    # movide scene segmentation result for a single video
    # {
    #        "shot_num":15,
    #        "shot_meta_list":
    #        [
    #           {
    #               "frame": [start_frame, end_frame],
    #               "timestamps": [start_timestamp, end_timestamp] # ['00:00:01.133', '00:00:02.245']
    #
    #           }
    #         ]
    #        "scene_num":3,
    #        "scene_meta_list":
    #        [
    #           {
    #               "shot": [0,1,2],
    #               "frame": [start_frame, end_frame],
    #               "timestamps": [start_timestamp, end_timestamp] # ['00:00:01.133', '00:00:02.245']
    #           }
    #        ]
    #
    # }
    Tasks.movie_scene_segmentation: [
        OutputKeys.SHOT_NUM, OutputKeys.SHOT_META_LIST, OutputKeys.SCENE_NUM,
        OutputKeys.SCENE_META_LIST
    ],

    # human whole body keypoints detection result for single sample
    # {
    #   "keypoints": [
    #               [[x, y]*133],
    #               [[x, y]*133],
    #               [[x, y]*133]
    #             ]
    #   "boxes": [
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #               [x1, y1, x2, y2],
    #             ]
    # }
    Tasks.human_wholebody_keypoint: [OutputKeys.KEYPOINTS, OutputKeys.BOXES],

    # video summarization result for a single video
    # {
    #        "output":
    #        [
    #           {
    #               "frame": [start_frame, end_frame]
    #               "timestamps": [start_time, end_time]
    #           },
    #           {
    #               "frame": [start_frame, end_frame]
    #               "timestamps": [start_time, end_time]
    #           }
    #        ]
    # }
    Tasks.video_summarization: [OutputKeys.OUTPUT],

    # referring video object segmentation result for a single video
    #   {
    #       "masks": [np.array # 3D array with shape [frame_num, height, width]]
    #       "timestamps": ["hh:mm:ss", "hh:mm:ss", "hh:mm:ss"]
    #       "output_video": "path_to_rendered_video" , this is optional
    # and is only available when the "render" option is enabled.
    #   }
    Tasks.referring_video_object_segmentation: [
        OutputKeys.MASKS, OutputKeys.TIMESTAMPS, OutputKeys.OUTPUT_VIDEO
    ],

    # video human matting result for a single video
    #   {
    #       "masks": [np.array # 2D array with shape [height, width]]
    #       "output_video": "path_to_matting_video"
    #   }
    Tasks.video_human_matting: [OutputKeys.MASKS, OutputKeys.OUTPUT_VIDEO],

    # ============ nlp tasks ===================

    # text classification result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "labels": ["happy", "sad", "calm", "angry"],
    #   }
    Tasks.text_classification: [OutputKeys.SCORES, OutputKeys.LABELS],

    # sentence similarity result for single sample
    #   {
    #       "scores": 0.9
    #       "labels": "1",
    #   }
    Tasks.sentence_similarity: [OutputKeys.SCORES, OutputKeys.LABELS],

    # nli result for single sample
    #   {
    #       "labels": ["happy", "sad", "calm", "angry"],
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #   }
    Tasks.nli: [OutputKeys.SCORES, OutputKeys.LABELS],

    # sentiment classification result for single sample
    # {
    #     'scores': [0.07183828949928284, 0.9281617403030396],
    #     'labels': ['1', '0']
    # }
    Tasks.sentiment_classification: [OutputKeys.SCORES, OutputKeys.LABELS],

    # zero-shot classification result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "labels": ["happy", "sad", "calm", "angry"],
    #   }
    Tasks.zero_shot_classification: [OutputKeys.SCORES, OutputKeys.LABELS],

    # relation extraction result for a single sample
    # {
    #     "uuid": "人生信息-1",
    #     "text": "《父老乡亲》是由是由由中国人民解放军海政文工团创作的军旅歌曲，石顺义作词，王锡仁作曲，范琳琳演唱",
    #     "spo_list": [{"subject": "石顺义", "predicate": "国籍", "object": "中国"}]
    # }
    Tasks.relation_extraction: [OutputKeys.SPO_LIST],

    # translation result for a source sentence
    #   {
    #       "translation": “北京是中国的首都”
    #   }
    Tasks.translation: [OutputKeys.TRANSLATION],

    # word segmentation result for single sample
    # {
    #   "output": ["今天", "天气", "不错", "，", "适合", "出去", "游玩"]
    # }
    # {
    #   'output': ['รถ', 'คัน', 'เก่า', 'ก็', 'ยัง', 'เก็บ', 'เอา']
    # }
    Tasks.word_segmentation: [OutputKeys.OUTPUT],

    # TODO @wenmeng.zwm support list of result check
    # named entity recognition result for single sample
    # {
    #   "output": [
    #     {"type": "LOC", "start": 2, "end": 5, "span": "温岭市"},
    #     {"type": "LOC", "start": 5, "end": 8, "span": "新河镇"}
    #   ]
    # }
    Tasks.named_entity_recognition: [OutputKeys.OUTPUT],
    Tasks.part_of_speech: [OutputKeys.OUTPUT],

    # text_error_correction result for a single sample
    # {
    #    "output": "我想吃苹果"
    # }
    Tasks.text_error_correction: [OutputKeys.OUTPUT],
    # word_alignment result for a single sample
    # {
    #    "output": "0-0 1-3 2-4 3-1 4-2 5-5"
    # }
    Tasks.word_alignment: [OutputKeys.OUTPUT],
    Tasks.sentence_embedding: [OutputKeys.TEXT_EMBEDDING, OutputKeys.SCORES],
    Tasks.text_ranking: [OutputKeys.SCORES],

    # text generation result for single sample
    # {
    #   "text": "this is the text generated by a model."
    # }
    Tasks.text_generation: [OutputKeys.TEXT],

    # chat task result for single sample
    # {
    #   "response": "this is the chat response generated by a model.",
    #   "history": [("hi", "nice to meet you"),("I felt happy, and you", "me too")]
    # }
    Tasks.chat: [OutputKeys.RESPONSE, OutputKeys.HISTORY],

    # fid dialogue result for single sample
    # {
    #   "text": "My name is Mike"
    # }
    Tasks.fid_dialogue: [OutputKeys.TEXT],

    # summarization result for single sample
    # {
    #   "text": "this is the text generated by a model."
    # }
    Tasks.text_summarization: [OutputKeys.TEXT],

    # text generation result for single sample
    # {
    #   "text": "北京"
    # }
    Tasks.text2text_generation: [OutputKeys.TEXT],

    # fill mask result for single sample
    # {
    #   "text": "this is the text which masks filled by model."
    # }
    Tasks.fill_mask: [OutputKeys.TEXT],

    # feature extraction result for single sample
    # {
    #   "text_embedding": [[
    #     [1.08599677e-04, 1.72710388e-05, 2.95618793e-05, 1.93638436e-04],
    #     [6.45841064e-05, 1.15997791e-04, 5.11605394e-05, 9.87020373e-01],
    #     [2.66957268e-05, 4.72324500e-05, 9.74208378e-05, 4.18022355e-05]
    #   ],
    #   [
    #     [2.97343540e-05, 5.81317654e-05, 5.44203431e-05, 6.28319322e-05],
    #     [8.24327726e-05, 4.66077945e-05, 5.32869453e-05, 4.16190960e-05],
    #     [3.61441926e-05, 3.38475402e-05, 3.44323053e-05, 5.70138109e-05]
    #   ]
    # ]
    # }
    Tasks.feature_extraction: [OutputKeys.TEXT_EMBEDDING],

    # (Deprecated) dialog intent prediction result for single sample
    # {'output': {'prediction': array([2.62349960e-03, 4.12110658e-03, 4.12748595e-05, 3.77560973e-05,
    #        1.08599677e-04, 1.72710388e-05, 2.95618793e-05, 1.93638436e-04,
    #        6.45841064e-05, 1.15997791e-04, 5.11605394e-05, 9.87020373e-01,
    #        2.66957268e-05, 4.72324500e-05, 9.74208378e-05, 4.18022355e-05,
    #        2.97343540e-05, 5.81317654e-05, 5.44203431e-05, 6.28319322e-05,
    #        7.34537680e-05, 6.61411541e-05, 3.62534920e-05, 8.58885178e-05,
    #        8.24327726e-05, 4.66077945e-05, 5.32869453e-05, 4.16190960e-05,
    #        5.97518992e-05, 3.92273068e-05, 3.44069012e-05, 9.92335918e-05,
    #        9.25978165e-05, 6.26462061e-05, 3.32317031e-05, 1.32061413e-03,
    #        2.01607945e-05, 3.36636294e-05, 3.99156743e-05, 5.84108493e-05,
    #        2.53432900e-05, 4.95731190e-04, 2.64443643e-05, 4.46992999e-05,
    #        2.42672231e-05, 4.75615161e-05, 2.66230145e-05, 4.00083954e-05,
    #        2.90536875e-04, 4.23891543e-05, 8.63691166e-05, 4.98188965e-05,
    #        3.47019341e-05, 4.52718523e-05, 4.20905781e-05, 5.50173208e-05,
    #        4.92360487e-05, 3.56021264e-05, 2.13957210e-05, 6.17428886e-05,
    #        1.43893281e-04, 7.32152112e-05, 2.91354867e-04, 2.46623786e-05,
    #        3.61441926e-05, 3.38475402e-05, 3.44323053e-05, 5.70138109e-05,
    #        4.31488479e-05, 4.94503947e-05, 4.30105974e-05, 1.00963116e-04,
    #        2.82062047e-05, 1.15582036e-04, 4.48261271e-05, 3.99339879e-05,
    #        7.27692823e-05], dtype=float32), 'label_pos': array([11]), 'label': 'lost_or_stolen_card'}}

    # (Deprecated) dialog modeling prediction result for single sample
    # {'output' : ['you', 'are', 'welcome', '.', 'have', 'a', 'great', 'day', '!']}

    # (Deprecated) dialog state tracking result for single sample
    # {
    #     "output":{
    #         "dialog_states": {
    #             "taxi-leaveAt": "none",
    #             "taxi-destination": "none",
    #             "taxi-departure": "none",
    #             "taxi-arriveBy": "none",
    #             "restaurant-book_people": "none",
    #             "restaurant-book_day": "none",
    #             "restaurant-book_time": "none",
    #             "restaurant-food": "none",
    #             "restaurant-pricerange": "none",
    #             "restaurant-name": "none",
    #             "restaurant-area": "none",
    #             "hotel-book_people": "none",
    #             "hotel-book_day": "none",
    #             "hotel-book_stay": "none",
    #             "hotel-name": "none",
    #             "hotel-area": "none",
    #             "hotel-parking": "none",
    #             "hotel-pricerange": "cheap",
    #             "hotel-stars": "none",
    #             "hotel-internet": "none",
    #             "hotel-type": "true",
    #             "attraction-type": "none",
    #             "attraction-name": "none",
    #             "attraction-area": "none",
    #             "train-book_people": "none",
    #             "train-leaveAt": "none",
    #             "train-destination": "none",
    #             "train-day": "none",
    #             "train-arriveBy": "none",
    #             "train-departure": "none"
    #         }
    #     }
    # }
    Tasks.task_oriented_conversation: [OutputKeys.OUTPUT],

    # table-question-answering result for single sample
    # {
    #   "sql": "SELECT shop.Name FROM shop."
    #   "sql_history": {sel: 0, agg: 0, conds: [[0, 0, 'val']]}
    # }
    Tasks.table_question_answering: [OutputKeys.OUTPUT],

    # ============ audio tasks ===================
    # asr result for single sample
    # { "text": "每一天都要快乐喔"}
    Tasks.auto_speech_recognition: [OutputKeys.TEXT],

    # itn result for single sample
    # {"text": "123"}
    Tasks.inverse_text_processing: [OutputKeys.TEXT],

    # speaker verification for single compare task
    # {'score': 84.2332}
    Tasks.speaker_verification: [OutputKeys.SCORES],
    # speaker diarization dialogue detection for binary results: dialogue or non_dialogue
    # {
    #   "scores": [0.98, 0.02],
    #   "labels": ["dialogue", "non_dialogue"],
    # }
    Tasks.speaker_diarization_dialogue_detection: [
        OutputKeys.SCORES, OutputKeys.LABELS
    ],
    Tasks.speech_language_recognition: [OutputKeys.TEXT],

    # punctuation result for single sample
    # { "text": "你好，明天！"}
    Tasks.punctuation: [OutputKeys.TEXT],

    # speaker diarization semantic speaker-turn detection
    # {
    #    "logits": [[0.7, 0.3], ..., [0.88, 0.12]],
    #    "text": "您好。您好，初次见面请多指教。",
    #    "prediction": [-100, -100, -100, 1, -100,..., -100, 0]
    # }
    Tasks.speaker_diarization_semantic_speaker_turn_detection: [
        OutputKeys.LOGITS, OutputKeys.TEXT, OutputKeys.PREDICTION
    ],

    # language model result for single sample
    # { "text": " hel@@ lo 大 家 好 呀 </s>
    #               p( hel@@ | <s> ) = 0.00057767 [ -7.45650959 ]
    #               p( lo | hel@@ ) = 0.99832278 [ -0.00167861 ]
    #               p( 大 | lo ) = 0.49116334 [ -0.71097857 ]
    #               p( 家 | 大 ) = 0.99691027 [ -0.00309453 ]
    #               p( 好 | 家 ) = 0.97999156 [ -0.02021134 ]
    #               p( 呀 | 好 ) = 0.00461205 [ -5.37908363 ]
    #               p( </s> | 呀 ) = 0.01524554 [ -4.18346834 ]
    #           logprob= -17.755 ppl= 12.6345
    # "}
    Tasks.language_score_prediction: [OutputKeys.TEXT],

    # speech timestamp result for single sample
    # {
    #   'text': '<sil> 0.000 0.376;一 0.376 0.556;个 0.556 0.796;东 0.796 0.976;
    #            太 0.976 1.136;平 1.136 1.256;洋 1.256 1.436;国 1.436 1.676;
    #            <sil> 1.676 1.676;家 1.676 1.916;<sil> 1.916 2.036;为 2.036 2.196;
    #            什 2.196 2.316;么 2.316 2.496;跑 2.496 2.676;到 2.676 2.856;
    #            西 2.856 3.036;太 3.036 3.196;平 3.196 3.376;洋 3.376 3.496;
    #            来 3.496 3.636;了 3.636 3.796;呢 3.796 4.148;<sil> 4.148 4.440;',
    #   'timestamp': [[0, 376], [376, 556], [556, 795], [795, 976],
    #                 [976, 1136], [1136, 1256], [1256, 1436], [1436, 1676],
    #                 [1676, 1676], [1676, 1916], [1916, 2036], [2036, 2196],
    #                 [2196, 2316], [2316, 2496], [2496, 2676], [2676, 2856],
    #                 [2856, 3036], [3036, 3196], [3196, 3376], [3376, 3496]]
    # }
    Tasks.speech_timestamp: [OutputKeys.TEXT],

    # audio processed for single file in PCM format
    # {
    #   "output_pcm": pcm encoded audio bytes
    # }
    Tasks.speech_signal_process: [OutputKeys.OUTPUT_PCM],
    Tasks.acoustic_echo_cancellation: [OutputKeys.OUTPUT_PCM],
    Tasks.acoustic_noise_suppression: [OutputKeys.OUTPUT_PCM],
    Tasks.speech_separation: [OutputKeys.OUTPUT_PCM_LIST],

    # text_to_speech result for a single sample
    # {
    #    "output_wav": {"input_label" : bytes}
    # }
    Tasks.text_to_speech: [OutputKeys.OUTPUT_WAV],

    # {
    #     "kws_list": [
    #         {
    #             'keyword': '',        # the keyword spotted
    #             'offset': 19.4,       # the keyword start time in second
    #             'length': 0.68,       # the keyword length in second
    #             'confidence': 0.85    # the possibility if it is the keyword
    #         },
    #         ...
    #     ]
    # }
    Tasks.keyword_spotting: [OutputKeys.KWS_LIST],

    # ============ multi-modal tasks ===================

    # image caption result for single sample
    # {
    #   "caption": "this is an image caption text."
    # }
    Tasks.image_captioning: [OutputKeys.CAPTION],

    # video caption result for single sample
    # {
    #   "caption": "this is an video caption text."
    # }
    Tasks.video_captioning: [OutputKeys.CAPTION],
    Tasks.ocr_recognition: [OutputKeys.TEXT],

    # visual grounding result for single sample
    # {
    #       "boxes": [
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #           [x1, y1, x2, y2],
    #       ],
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    # }
    Tasks.visual_grounding: [OutputKeys.BOXES, OutputKeys.SCORES],

    # text_to_image result for samples
    # {
    #    "output_imgs": np.ndarray list with shape [[height, width, 3], ...]
    # }
    Tasks.text_to_image_synthesis: [OutputKeys.OUTPUT_IMGS],

    # text_to_speech result for a single sample
    # {
    #    "output_wav": {"input_label" : bytes}
    # }
    Tasks.text_to_speech: [OutputKeys.OUTPUT_WAV],

    # multi-modal embedding result for single sample
    # {
    #   "img_embedding": np.array with shape [1, D],
    #   "text_embedding": np.array with shape [1, D]
    # }
    Tasks.multi_modal_embedding: [
        OutputKeys.IMG_EMBEDDING, OutputKeys.TEXT_EMBEDDING
    ],

    # generative multi-modal embedding result for single sample
    # {
    #   "img_embedding": np.array with shape [1, D],
    #   "text_embedding": np.array with shape [1, D],
    #   "caption": "this is an image caption text."
    # }
    Tasks.generative_multi_modal_embedding: [
        OutputKeys.IMG_EMBEDDING, OutputKeys.TEXT_EMBEDDING, OutputKeys.CAPTION
    ],

    # multi-modal similarity result for single sample
    # {
    #   "img_embedding": np.array with shape [1, D],
    #   "text_embedding": np.array with shape [1, D],
    #   "similarity": float
    # }
    Tasks.multi_modal_similarity: [
        OutputKeys.IMG_EMBEDDING, OutputKeys.TEXT_EMBEDDING, OutputKeys.SCORES
    ],

    # VQA result for a sample
    # {"text": "this is a text answser. "}
    Tasks.visual_question_answering: [OutputKeys.TEXT],

    # VideoQA result for a sample
    # {"text": "this is a text answser. "}
    Tasks.video_question_answering: [OutputKeys.TEXT],

    # Multimodal Dialogue result for a sample
    # {"text": "this is a text response. "}
    Tasks.multimodal_dialogue: [OutputKeys.TEXT],

    # auto_speech_recognition result for a single sample
    # {
    #    "text": "每天都要快乐喔"
    # }
    Tasks.auto_speech_recognition: [OutputKeys.TEXT],

    # {
    #       "scores": [0.9, 0.1, 0.1],
    #       "labels": ["entailment", "contradiction", "neutral"]
    # }
    Tasks.visual_entailment: [OutputKeys.SCORES, OutputKeys.LABELS],

    # {
    #     'labels': ['吸烟', '打电话', '吸烟'],
    #     'scores': [0.7527753114700317, 0.753358006477356, 0.6880350708961487],
    #     'boxes': [[547, 2, 1225, 719], [529, 8, 1255, 719], [584, 0, 1269, 719]],
    #     'timestamps': [1, 3, 5]
    # }
    Tasks.action_detection: [
        OutputKeys.TIMESTAMPS,
        OutputKeys.LABELS,
        OutputKeys.SCORES,
        OutputKeys.BOXES,
    ],

    # {
    #   'output': [
    #     [{'label': '6527856', 'score': 0.9942756295204163}, {'label': '1000012000', 'score': 0.0379515215754509},
    #      {'label': '13421097', 'score': 2.2825044965202324e-08}],
    #     [{'label': '1000012000', 'score': 0.910681426525116}, {'label': '6527856', 'score': 0.0005046309670433402},
    #      {'label': '13421097', 'score': 2.75914817393641e-06}],
    #     [{'label': '1000012000', 'score': 0.910681426525116}, {'label': '6527856', 'score': 0.0005046309670433402},
    #      {'label': '13421097', 'score': 2.75914817393641e-06}]]
    # }
    Tasks.faq_question_answering: [OutputKeys.OUTPUT],

    # image person reid result for single sample
    #   {
    #       "img_embedding": np.array with shape [1, D],
    #   }
    Tasks.image_reid_person: [OutputKeys.IMG_EMBEDDING],

    # {
    #     'output': ['Done' / 'Decode_Error']
    # }
    Tasks.video_inpainting: [OutputKeys.OUTPUT],

    # {
    #     'output': ['bixin']
    # }
    Tasks.hand_static: [OutputKeys.OUTPUT],

    # {    'labels': [2, 1, 0],
    #      'boxes':[[[78, 282, 240, 504], [127, 87, 332, 370], [0, 0, 367, 639]]
    #      'scores':[0.8202137351036072, 0.8987470269203186, 0.9679114818572998]
    # }
    Tasks.face_human_hand_detection: [
        OutputKeys.LABELS, OutputKeys.BOXES, OutputKeys.SCORES
    ],

    # {
    #   {'output': 'Happiness', 'boxes': (203, 104, 663, 564)}
    # }
    Tasks.face_emotion: [OutputKeys.OUTPUT, OutputKeys.BOXES],

    # {
    #     "masks": [
    #           np.array # 2D array containing only 0, 255
    #       ]
    # }
    Tasks.product_segmentation: [OutputKeys.MASKS],

    # image_skychange result for a single sample
    # {
    #    "output_img": np.ndarray with shape [height, width, 3]
    # }
    Tasks.image_skychange: [OutputKeys.OUTPUT_IMG],
    # {
    #     'score': [0.1, 0.2, 0.3, ...]
    # }
    Tasks.translation_evaluation: [OutputKeys.SCORE],

    # video object segmentation result for a single video
    #   {
    #       "masks": [np.array # 3D array with shape [frame_num, height, width]]
    #   }
    Tasks.video_object_segmentation: [OutputKeys.MASKS],

    # motion generation result for a single input
    #   {
    #       "keypoints": [np.array # 3D array with shape [frame_num, joint_num, 3]]
    #       "output_video": "path_to_rendered_video"
    #   }
    Tasks.motion_generation: [OutputKeys.KEYPOINTS, OutputKeys.OUTPUT_VIDEO],

    # bad image detecting for a single input
    #   {
    #       "scores": [0.8, 0.1, 0.1]
    #       "labels": ["正常", "花屏", "绿屏"],
    Tasks.bad_image_detecting: [OutputKeys.SCORES, OutputKeys.LABELS],

    # vision efficient tuning result for single sample
    #   {
    #       "scores": [0.9, 0.1, 0.05, 0.05]
    #       "labels": ["dog", "horse", "cow", "cat"],
    #   }
    Tasks.vision_efficient_tuning: [OutputKeys.SCORES, OutputKeys.LABELS],
    Tasks.document_grounded_dialog_generate: [OutputKeys.TEXT],
    Tasks.document_grounded_dialog_rerank: [OutputKeys.OUTPUT],
    Tasks.document_grounded_dialog_retrieval: [OutputKeys.OUTPUT],
    Tasks.video_temporal_grounding: [OutputKeys.SCORES, OutputKeys.TBOUNDS],
    Tasks.text_to_video_synthesis: [OutputKeys.OUTPUT_VIDEO],
    Tasks.text_to_360panorama_image: [OutputKeys.OUTPUT_IMG],

    # Tasks.image_try_on result for a single sample
    # {
    #    "output_img": np.ndarray with shape [height, width, 3]
    # }
    Tasks.image_try_on: [OutputKeys.OUTPUT_IMG],
    # Tasks.human_image_generation result for a single sample
    # {
    #    "output_img": np.ndarray with shape [height, width, 3]
    # }
    Tasks.human_image_generation: [OutputKeys.OUTPUT_IMG],
    # Tasks.image_view_transform result for a single sample
    # {
    #    "output_imgs": np.ndarray list with shape [[height, width, 3], ...]
    # }
    Tasks.image_view_transform: [OutputKeys.OUTPUT_IMGS],
}

class ModelOutputBase(list):

    def __post_init__(self):
        self.reconstruct()
        self.post_init = True

    def reconstruct(self):
        # Low performance, but low frequency.
        self.clear()
        for idx, key in enumerate(self.keys()):
            self.append(getattr(self, key))

    def __getitem__(self, item):
        if isinstance(item, str):
            if hasattr(self, item):
                return getattr(self, item)
        elif isinstance(item, (int, slice)):
            return super().__getitem__(item)
        raise IndexError(f'No Index {item} found in the dataclass.')

    def __setitem__(self, key, value):
        if isinstance(key, str):
            if key in [f.name for f in fields(self)]:
                if key not in self.keys():
                    super().__setattr__(key, value)
                    self.reconstruct()
                elif id(getattr(self, key)) != id(value):
                    super().__setattr__(key, value)
                    super().__setitem__(self.keys().index(key), value)
            else:
                super().__setattr__(key, value)
        elif isinstance(key, int):
            super().__setitem__(key, value)
            key_name = self.keys()[key]
            super().__setattr__(key_name, value)

    def __setattr__(self, key, value):
        if getattr(self, 'post_init', False):
            return self.__setitem__(key, value)
        else:
            return super().__setattr__(key, value)

    def keys(self):
        return [
            f.name for f in fields(self) if getattr(self, f.name) is not None
        ]

    def items(self):
        return self.to_dict().items()

    def to_dict(self):
        output = OrderedDict()
        for key in self.keys():
            output[key] = getattr(self, key)
        return output


from alphadb.utils.query.table import alter_table
from tests.test_utils.version_source import wrap_partial_in_altertable, wrap_version_list_in_base

def test_drop_column():
    test_data = wrap_partial_in_altertable({"dropcolumn": ["col1", "col2", "col3"]})

    assert alter_table(version_source=test_data, table_name="table", version="0.0.1") == " ALTER TABLE `table` DROP COLUMN `col1`, DROP COLUMN `col2`, DROP COLUMN `col3`;"

def test_drop_primary_key():
    test_data = wrap_version_list_in_base([
        {
            "_id": "0.0.1",
            "createtable": {
                "table": {
                    "primary_key": "col",
                    "col": {
                        "type": "INT",
                        "a_i": True
                    }
                }
            }
        },
        {
            "_id": "0.0.2",
            "altertable": {
                "table": {
                    "primary_key": None
                }
            }
        }
    ])

    assert alter_table(version_source=test_data, table_name="table", version="0.0.2") == " ALTER TABLE `table` MODIFY COLUMN `col` INT NOT NULL, DROP PRIMARY KEY;"


"""Preprocessing of skills file
"""
from skills_taxonomy.getters.esco_skills import get_skills

def preprocess_skills():
    """Preprocess skills by removing rows with descriptions
    containing two or fewer words and dropping unused columns

    Returns:
        df: processed skills
    """
    skills = get_skills()
    return (
        skills.assign(
            n_words_desc=skills["description"].apply(lambda x: len(x.split()))
        )
        .query("n_words_desc > 2")
        .reset_index(drop=True)
        .loc[:, ["preferredLabel", "altLabels", "description"]]
    )


import numpy as np
import pandas as pd
from openpyxl import Workbook, load_workbook
import xlsxwriter
import os
'''
# Assign directory
dir = '/Users/austinheuer/Desktop/LiST/LiST_tool/Folder'

# Iterate over files in folder
for filename in os.listdir(dir):
    if not filename.startswith('.'):
        filename = filename.lower()
        f = os.path.join(dir, filename)
        print(f)
'''

# Read in sheets from dataset
output = load_workbook("/Users/austinheuer/Desktop/LiST/LiST_tool/Folder/test1_output.xlsx")
births = pd.read_excel("/Users/austinheuer/Desktop/LiST/LiST_tool/Folder/test1_output.xlsx", sheet_name='1. Total Births', skiprows=0, header=1)
outcomes = pd.read_excel("/Users/austinheuer/Desktop/LiST/LiST_tool/Folder/test1_output.xlsx", sheet_name='2. Birth Outcomes (percent)', skiprows=0, header=1)
cov = pd.read_excel("/Users/austinheuer/Desktop/LiST/LiST_tool/Folder/test1_output.xlsx", sheet_name='1. Coverage of pregnancy interv', skiprows=0)
mn = pd.read_excel("/Users/austinheuer/Desktop/LiST/LiST_tool/Folder/test1_output.xlsx", sheet_name='2. Maternal nutrition', skiprows=0)

# Organize data
outcomes.columns = ["File name", "Country",	"ISO 3166-1 alpha-3", "Subnational region",	"Module",	"Indicator",	"Configuration", "2017", "2018", "2019",	"2020",	"2021",	"2022",	"2023",	"2024",	"2025",	"2026",	"2027",	"2028",	"2029",	"2030"]
outcomes = outcomes.sort_values(['Country', 'Configuration']) # order: LBW, PT-AGA, PT-SGA, Term-AGA, Term-SGA
outcomes = outcomes.reset_index(drop=True) # resets index to match the sorted dataframe
labs = ['Baseline', 'LiST 1', 'LiST 2']
years = ['2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030']
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

# Subset total births
tb_start = np.linspace(0, 3, 2).tolist()
tb_start = list(map(int, tb_start))
tb_end = np.linspace(3, 6, 2).tolist()
tb_end = list(map(int, tb_end))
birth_dfs = {}
for start, end in zip(tb_start, tb_end):
    country_name = births.iloc[start, 1]
    t_births = births.iloc[start:end, 7:]
    t_births.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    t_births = t_births.set_index('Projection')
    t_births.index.name = "Total number of births"
    birth_dfs[country_name] = t_births

# Subset LBW
lbw_start = np.linspace(0, 15, 2).tolist()
lbw_start = list(map(int, lbw_start))
lbw_end = np.linspace(3, 18, 2).tolist()
lbw_end = list(map(int, lbw_start))
lowbw = {}
numb_lbw = {}
ch_num_lbw = {}
for start, end in zip(lbw_start, lbw_end):
    country_name = outcomes.iloc[start, 1]
    lbw = outcomes.iloc[start:end, 7:]
    lbw.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    lbw = lbw.set_index('Projection')
    lbw.index.name = "% LBW births"
    lowbw[country_name] = lbw
    num_lbw = pd.DataFrame((lbw.values/100)*birth_dfs[country_name].values)
    num_lbw.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    num_lbw = num_lbw.set_index('Projection')
    num_lbw.columns = years
    num_lbw.index.name = "Number of LBW births"
    numb_lbw[country_name] = num_lbw
    c_num_lbw = pd.DataFrame(num_lbw.values - num_lbw.iloc[0].values, columns=num_lbw.columns)
    c_num_lbw.index.name = "Change in number of LBW births"
    ch_num_lbw[country_name] = c_num_lbw

# Subset PT-AGA
ptaga_start = np.linspace(3, 18, 2).tolist()
ptaga_start = list(map(int, ptaga_start))
ptaga_end = np.linspace(6, 21, 2).tolist()
ptaga_end = list(map(int, ptaga_end))
pret_aga = {}
numb_pret_aga = {}
ch_num_pret_aga = {}
for start, end in zip(ptaga_start, ptaga_end):
    country_name = outcomes.iloc[start, 1]
    pt_aga = outcomes.iloc[start:end, 7:]
    pt_aga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    pt_aga = pt_aga.set_index('Projection')
    pt_aga.index.name = "% Pre-term AGA births"
    pret_aga[country_name] = pt_aga
    num_pt_aga = pd.DataFrame((pt_aga.values/100)*birth_dfs[country_name].values)
    num_pt_aga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    num_pt_aga = num_pt_aga.set_index('Projection')
    num_pt_aga.columns = years
    num_pt_aga.index.name = "Number of Pre-term AGA births"
    numb_pret_aga[country_name] = num_pt_aga
    c_num_pt_aga = pd.DataFrame(num_pt_aga.values - num_pt_aga.iloc[0].values, columns=num_pt_aga.columns)
    c_num_pt_aga.index.name = "Change in number of Pre-term AGA births"
    ch_num_pret_aga[country_name] = c_num_pt_aga

# Subset PT-SGA
ptsga_start = np.linspace(3, 18, 2).tolist()
ptsga_start = list(map(int, ptsga_start))
ptsga_end = np.linspace(6, 21, 2).tolist()
ptsga_end = list(map(int, ptsga_end))
pret_sga = {}
numb_pret_sga = {}
ch_num_pret_sga = {}
for start, end in zip(ptsga_start, ptsga_end):
    country_name = outcomes.iloc[start, 1]
    pt_sga = outcomes.iloc[start:end, 7:]
    pt_sga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    pt_sga = pt_sga.set_index('Projection')
    pt_sga.index.name = "% Pre-term SGA births"
    pret_sga[country_name] = pt_sga
    num_pt_sga = pd.DataFrame((pt_sga.values/100)*birth_dfs[country_name].values)
    num_pt_sga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    num_pt_sga = num_pt_sga.set_index('Projection')
    num_pt_sga.columns = years
    numb_pret_sga[country_name] = num_pt_sga
    num_pt_sga.index.name = "Number of Pre-term SGA births"
    c_num_pt_sga = pd.DataFrame(num_pt_sga.values - num_pt_sga.iloc[0].values, columns=num_pt_sga.columns)
    c_num_pt_sga.index.name = "Change in number of Pre-term SGA births"
    ch_num_pret_sga[country_name] = c_num_pt_sga

# Subset term-AGA
taga_start = np.linspace(9, 24, 2).tolist()
taga_start = list(map(int, taga_start))
taga_end = np.linspace(12, 27, 2).tolist()
taga_end = list(map(int, taga_end))
t_aga = {}
numb_t_aga = {}
ch_num_t_aga = {}
for start, end in zip(taga_start, taga_end):
    country_name = outcomes.iloc[start, 1]
    term_aga = outcomes.iloc[start:end, 7:]
    term_aga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    term_aga = term_aga.set_index('Projection')
    term_aga.index.name = "% Term AGA births"
    t_aga[country_name] = term_aga
    num_term_aga = pd.DataFrame((term_aga.values/100)*birth_dfs[country_name].values)
    num_term_aga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    num_term_aga = num_term_aga.set_index('Projection')
    num_term_aga.columns = years
    num_term_aga.index.name = "Number of Term AGA births"
    numb_t_aga[country_name] = num_term_aga
    c_num_term_aga = pd.DataFrame(num_term_aga.values - num_term_aga.iloc[0].values, columns=num_term_aga.columns)
    c_num_term_aga.index.name = "Change in number of Term AGA births"
    ch_num_t_aga[country_name] = c_num_term_aga

# Subset term-SGA
tsga_start = np.linspace(12, 27, 2).tolist()
tsga_start =list(map(int, tsga_start))
tsga_end = np.linspace(15, 30, 2).tolist()
tsga_end = list(map(int, tsga_end))
t_sga = {}
numb_t_sga = {}
ch_num_t_sga = {}
for start, end in zip(tsga_start, tsga_end):
    country_name = outcomes.iloc[start, 1]
    term_sga = outcomes.iloc[start:end, 7:]
    term_sga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    term_sga = term_sga.set_index('Projection')
    term_sga.index.name = "% Term SGA births"
    t_sga[country_name] = term_sga
    num_term_sga = pd.DataFrame((term_sga.values/100)*birth_dfs[country_name].values)
    num_term_sga.insert(loc=0, column='Projection', value=labs, allow_duplicates=True)
    num_term_sga = num_term_sga.set_index('Projection')
    num_term_sga.columns = years
    num_term_sga.index.name = "Number of Term SGA births"
    numb_t_sga[country_name] = num_term_sga
    c_num_term_sga = pd.DataFrame(num_term_sga.values - num_term_sga.iloc[0].values, columns=num_term_sga.columns)
    c_num_term_sga.index.name = "Change in number of Term SGA births"
    ch_num_t_sga[country_name] = c_num_term_sga

'''
# Put each dataframe into correct position on Summary sheet
writer = pd.ExcelWriter(f, engine='xlsxwriter')
workbook = writer.book
t_births.to_excel(writer, sheet_name='Summary', startrow=0, startcol=0)
num_pt_sga.to_excel(writer, sheet_name='Summary', startrow=6, startcol=0)
num_pt_aga.to_excel(writer, sheet_name='Summary', startrow=12, startcol=0)
num_term_sga.to_excel(writer, sheet_name='Summary', startrow=18, startcol=0)
num_term_aga.to_excel(writer, sheet_name='Summary', startrow=24, startcol=0)
num_lbw.to_excel(writer, sheet_name='Summary', startrow=30, startcol=0)
c_num_pt_sga.to_excel(writer, sheet_name='Summary', startrow=6, startcol=16)
c_num_pt_aga.to_excel(writer, sheet_name='Summary', startrow=12, startcol=16)
c_num_term_sga.to_excel(writer, sheet_name='Summary', startrow=18, startcol=16)
c_num_term_aga.to_excel(writer, sheet_name='Summary', startrow=24, startcol=16)
c_num_lbw.to_excel(writer, sheet_name='Summary', startrow=30, startcol=16)
pt_sga.to_excel(writer, sheet_name='Summary', startrow=6, startcol=32)
pt_aga.to_excel(writer, sheet_name='Summary', startrow=12, startcol=32)
term_sga.to_excel(writer, sheet_name='Summary', startrow=18, startcol=32)
term_aga.to_excel(writer, sheet_name='Summary', startrow=24, startcol=32)
lbw.to_excel(writer, sheet_name='Summary', startrow=30, startcol=32)
cov.to_excel(writer, sheet_name='Intervention Coverage', index=False)
mn.to_excel(writer, sheet_name='Interventions AF & efficacy', index=False)

writer.save()

'''


from utils.image import put_image
from os import path
from shutil import rmtree
from typing import List, Tuple
from utils.search import keywords_from_speciality, google_search, similar_image
from utils.types import *
from utils.cache import cache, account_cache
from utils.config import config
from utils.drive import get_file
from igramscraper.instagram import Instagram

MAX_FACE_MATCH_POINTS = 3

instagram_accs_sheet = get_file(config["INSTAGRAM_ACCOUNT_FILE"]["id"], config["INSTAGRAM_ACCOUNT_FILE"]["sheet"])
instagram_accs_data = instagram_accs_sheet.get_all_values()[1:]
instagram_accs = []

for index, acc in enumerate(instagram_accs_data):
    if acc[3] == "Active" and f"instagram_login:{acc[0]}:{acc[1]}" in account_cache:
        instagram_accs.append(account_cache[f"instagram_login:{acc[0]}:{acc[1]}"])
        continue
    if acc[3] in ["Active", ""]:
        instagram = Instagram()
        try:
            instagram.with_credentials(acc[0], acc[1])
            instagram.login(True)
        except Exception as e:
            print(f"[instagram] Login Error -> {acc[0]} : {e}")
            instagram_accs_sheet.update(f"D{index+2}", "Account Disabled")
            instagram_accs_sheet.format(
                f"D{index+2}",
                {"textFormat": {"bold": True, "foregroundColor": {"red": 1.0, "green": 0.0, "blue": 0.0}}},
            )
            continue
        instagram_accs.append([f"D{index+2}", instagram.user_session])
        instagram_accs_sheet.update(f"D{index+2}", "Active")
        instagram_accs_sheet.format(
            f"D{index+2}",
            {"textFormat": {"bold": True, "foregroundColor": {"red": 0.2039, "green": 0.6588, "blue": 0.3254}}},
        )
        account_cache[f"instagram_login:{acc[0]}:{acc[1]}"] = [f"D{index+2}", instagram.user_session]

if path.exists("./sessions"):
    rmtree("./sessions")

insta_index = 0

async def search(thread_id: int, doc_name: str, speciality: str, max_terms: int = 5) -> ModuleResults:
    doc_name = doc_name.lower()
    print(f"[{thread_id}][Instagram] Searching")
    search_hits: List[ModuleResult] = []
    search_results = instagram_search(doc_name)[:max_terms]
    doc_image_urls = google_search(doc_name, "images", 1)
    doc_image = doc_image_urls[0]["link"] if doc_image_urls else ""
    print(f"[{thread_id}][Instagram] People Search: {len(search_results)} result(s)")
    all_keywords: List[str] = []
    for keyword_set in keywords_from_speciality(speciality):
        all_keywords.extend(keyword_set["keywords"])
    for instagram_profile in search_results:
        total_keywords = len(all_keywords)
        face_match_points = 0
        result_content = instagram_profile[2].lower()
        if instagram_profile[1] and similar_image(doc_image, instagram_profile[1]):
            face_match_points = MAX_FACE_MATCH_POINTS
        print(f"[{thread_id}][Instagram] FACE MATCH: {face_match_points==MAX_FACE_MATCH_POINTS}")
        matched_keywords = []
        for keyword in all_keywords:
            if keyword.lower() in result_content:
                matched_keywords.append(keyword)
        confidence = round(
            ((len(matched_keywords) + face_match_points) / (total_keywords + MAX_FACE_MATCH_POINTS)) * 100, 2
        )
        if face_match_points > 0:
            matched_keywords.append("Face Match")
        if confidence > 0:
            search_hits.append(
                {
                    "link": f"https://www.instagram.com/{instagram_profile[0]}",
                    "confidence": confidence,
                    "keywords": matched_keywords,
                }
            )
    print(f"[{thread_id}][Instagram] Done")
    return {
        "source": "instagram",
        "results": sorted(search_hits, key=lambda x: x["confidence"], reverse=True)[:max_terms],
    }

def instagram_search(name, max_terms=5) -> List[Tuple[str, str, str]]:
    if f"instagram_search:{name}" in cache:
        return cache[f"instagram_search:{name}"][:max_terms]
    if config["DRY_RUN"]:
        return []
    global insta_index
    tries = 0
    while tries < len(instagram_accs):
        insta_index += 1
        insta_acc = insta_index % len(instagram_accs)
        tries += 1
        try:
            instagram_instance = Instagram()
            instagram_instance.user_session = instagram_accs[insta_acc][1]
            api_results = instagram_instance.search_accounts_by_username(name)
            results = []
            for acc in api_results[:max_terms]:
                profile_data = get_picture_bio(acc.username)
                results.append((acc.username, put_image(profile_data[0]), profile_data[1]))
            cache[f"instagram_search:{name}"] = results
            return results
        except Exception as e:
            print("[Instagram] Search Error: ", e)
    raise RuntimeError("[Instagram] Fatal Error Searching")

def get_picture_bio(username) -> Tuple[str, str]:
    print(f"[Instagram] Scraping {username}")
    if f"instagram_details:{username}" in cache:
        return cache[f"instagram_details:{username}"]
    bio = ""
    tries = 0
    global insta_index
    while tries < len(instagram_accs):
        insta_index += 1
        insta_acc = insta_index % len(instagram_accs)
        tries += 1
        try:
            instagram_instance = Instagram()
            instagram_instance.user_session = instagram_accs[insta_acc][1]
            profile_info = instagram_instance.get_account(username)
            bio = profile_info.biography
            picture = profile_info.get_profile_picture_url()
            cache[f"instagram_details:{username}"] = (str(picture), bio or "")
            return (str(picture), bio or "")
        except Exception:
            pass
    return ("", "")


import socket

target_host = '127.0.0.1'
target_port = 8000

try:

    # Create a socket object
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # Send some data
    client.sendto(b'asdfasdfa', (target_host, target_port))

    # Receive some data
    data, addr = str(client.recvfrom(4096))

    print(data)

except socket.timeout:
    print('Cannot connect to {0} on port {1}'.format(target_host, target_port))


import asana
from constants import ASANA_WORKSPACE, ASANA_PROJECT, PULL_REQUESTS_SECTION

def search_incomplete_tasks_by_name(client: asana.Client, query: str) -> list[dict]:
    print(f"Searching for tasks with query: {query}")
    return list(
        client.tasks.search_tasks_for_workspace(
            ASANA_WORKSPACE,
            {
                "completed": False,
                "text": query,
                "projects_any": ASANA_PROJECT,
                "sections_any": PULL_REQUESTS_SECTION,  # this will hopefully reduce incorrect matches
            },
        )
    )


"""Generic workflow engine views"""

from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.urlresolvers import reverse, reverse_lazy
from django.db import transaction
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.views import generic

from activflow.core.constants import WORKFLOW_APPS, REQUEST_IDENTIFIER
from activflow.core.helpers import (
    get_errors,
    get_model,
    get_model_instance,
    get_form_instance,
    get_request_params,
    flow_config
)

from activflow.core.mixins import AccessDeniedMixin
from activflow.core.models import get_workflows_requests, get_task

@login_required
def workflows(request):
    """Lists down registered workflows"""
    return render(request, 'index.html', {'workflows': WORKFLOW_APPS})

class WorkflowDetail(LoginRequiredMixin, generic.TemplateView):
    """Generic view to list worflow requests & tasks"""
    template_name = 'core/workflow.html'

    def get_context_data(self, **kwargs):
        """Retrieve context data<"""
        context = super(WorkflowDetail, self).get_context_data(**kwargs)
        app_title = get_request_params('app_name', **kwargs)
        config = flow_config(app_title)
        model = config.FLOW[config.INITIAL]['model']().title
        context['requests'] = get_workflows_requests(app_title)
        context['request_identifier'] = REQUEST_IDENTIFIER
        context['workflow_title'] = config.TITLE
        context['description'] = config.DESCRIPTION
        context['initial'] = model

        return context

class ViewActivity(AccessDeniedMixin, generic.DetailView):
    """Generic view to display activity details"""
    template_name = 'core/detail.html'

    def dispatch(self, request, *args, **kwargs):
        """Overriding dispatch on DetailView"""
        self.model = get_model(**kwargs)
        denied = self.check(request, **kwargs)
        return denied if denied else super(ViewActivity, self).dispatch(
            request, *args, **kwargs)

class RollBackActivity(LoginRequiredMixin, generic.View):
    """Rollbacks workflow task"""
    @transaction.atomic
    def post(self, request, **kwargs):
        """POST request handler for rollback"""
        app_title = get_request_params('app_name', **kwargs)
        identifier = get_request_params('pk', **kwargs)
        get_task(identifier).rollback()

        return HttpResponseRedirect(
            reverse('workflow-detail', args=[app_title]))

class DeleteActivity(LoginRequiredMixin, generic.DeleteView):
    """Deletes activity instance"""
    def dispatch(self, request, *args, **kwargs):
        """Overriding dispatch on DeleteView"""
        self.model = get_model(**kwargs)
        self.success_url = reverse_lazy(
            'workflow-detail', args=[get_request_params(
                'app_name', **kwargs)])

        return super(DeleteActivity, self).dispatch(
            request, *args, **kwargs)

class CreateActivity(AccessDeniedMixin, generic.View):
    """Generic view to initiate activity"""
    def get(self, request, **kwargs):
        """GET request handler for Create operation"""
        form = get_form_instance(**kwargs)
        context = {'form': form}

        denied = self.check(request, **kwargs)
        return denied if denied else render(
            request, 'core/create.html', context)

    @transaction.atomic
    def post(self, request, **kwargs):
        """POST request handler for Create operation"""
        model = get_model(**kwargs)
        form = get_form_instance(**kwargs)(request.POST)
        app_title = get_request_params('app_name', **kwargs)

        if form.is_valid():
            instance = model(**form.cleaned_data)

            if instance.is_initial:
                instance.initiate_request(request.user, app_title)
            else:
                instance.assign_task(
                    get_request_params('pk', **kwargs))
                instance.task.initiate()

            return HttpResponseRedirect(
                reverse('update', args=(
                    app_title, instance.title, instance.id)))
        else:
            context = {
                'form': form,
                'error_message': get_errors(form.errors)
            }

            return render(request, 'core/create.html', context)

class UpdateActivity(AccessDeniedMixin, generic.View):
    """Generic view to update activity"""
    def get(self, request, **kwargs):
        """GET request handler for Update operation"""
        instance = get_model_instance(**kwargs)
        form = get_form_instance(**kwargs)
        context = {
            'form': form(instance=instance),
            'object': instance,
            'next': instance.next_activity()
        }

        denied = self.check(request, **kwargs)
        return denied if denied else render(
            request, 'core/update.html', context)

    @transaction.atomic
    def post(self, request, **kwargs):
        """POST request handler for Update operation"""
        redirect_to_update = False
        instance = get_model_instance(**kwargs)
        app_title = get_request_params('app_name', **kwargs)
        form = get_form_instance(
            **kwargs)(request.POST, instance=instance)

        if form.is_valid():
            form.save()

            if 'save' in request.POST:
                redirect_to_update = True
                instance.update()
            elif 'finish' in request.POST:
                instance.finish()
            else:
                next_activity = request.POST['submit']
                if not instance.validate_rule(next_activity):
                    redirect_to_update = True
                else:
                    instance.task.submit(
                        app_title, self.request.user, next_activity)

            return HttpResponseRedirect(
                reverse('update', args=(
                    app_title, instance.title, instance.id))
            ) if redirect_to_update else HttpResponseRedirect(
                    reverse('workflow-detail', args=[app_title]))
        else:
            context = {
                'form': form,
                'object': instance,
                'next': instance.next_activity(),
                'error_message': get_errors(form.errors)
            }

            return render(request, 'core/update.html', context)


import csv

import cchardet

def autodetect_encoding(file_path):
    with open(file_path, "rb") as file:
        content = file.read()
    detection = cchardet.detect(content)
    if detection['confidence'] < 0.5:
        raise ValueError("Could not detect proper encoding")
    return detection['encoding']

def load_qif(file_path):
    encoding = autodetect_encoding(file_path)
    with open(file_path, "rt", encoding=encoding) as file:
        statement_content = file.read()
    return statement_content

def is_integrity_fine(file_path, config=None, encoding=None):
    if config and 'integrity' in config:
        line_index = config['integrity']['line_index']
        line_expected = config['integrity']['line_content']
        encoding = autodetect_encoding(file_path) if encoding is None else encoding
        with open(file_path, "rt", encoding=encoding) as dataset:
            lines = dataset.read().splitlines()
            line_actual = lines[line_index]
            return line_actual == line_expected
    return True

def load_csv_items(file_path, row_type, encoding=None, skip_headers=0, selected_columns=None, delim=';'):
    encoding = autodetect_encoding(file_path) if encoding is None else encoding
    items = []
    with open(file_path, "rt", encoding=encoding) as dataset:
        csv_reader = csv.reader(dataset, delimiter=delim)
        for i in range(skip_headers):
            next(csv_reader)
        for row_data in csv_reader:
            if selected_columns is not None:
                selected_data = [row_data[i] for i in selected_columns]
                item = row_type(*selected_data)
            else:
                item = row_type(*row_data)
            items += [item]
    return items


#!/usr/bin/env python
# coding: utf-8

# In[1]:

import numpy as np
import matplotlib.pyplot as plt
from numpy import log as ln
import random
from numpy import random
import math
from matplotlib.pyplot import plot,savefig
import sys
filePath = '../Utils/nup'
sys.path.append(filePath)
import os
from functions import relu,drelu,softmax,divi_,mini_batch_generate,sigmoid,dsigmoid,turn_2_zero,scale,tanh,dtanh
from optimizers import Adam
from model_save import model_save
from dataset import load
mnist=np.array(load.load_mnist(one_hot=True),dtype="object")
train_data0 = mnist[0][0][0:60000].T
train_label0 = mnist[0][1][0:60000].T
test_data0 = mnist[1][0][:10000].T
test_label0 = mnist[1][1][:10000].T

# In[17]:

def sig_mat(sig):
    lenth = len(sig)
    mat=np.zeros((lenth,lenth))
    for i in range(lenth):
        mat[i][i]=float(sig[i]*1)
    return mat
def clip_n(mat,bound):
    test = mat*1
    test[np.abs(mat)<bound] = 0
    return test

class NeuralNetwork:
    def __init__(self,sizes,p_m):
        self.num_layers = len(sizes)
        self.patterns = p_m
#         self.patterns = p*np.ones((self.num_layers-1,1))
        self.sizes = sizes
        self.Sigma =  [(np.ones((int(self.patterns[l]),1))) for l in range(self.num_layers-1)]
        self.xi1 = [(((1/(self.sizes[l]*ln(self.sizes[l])))**(1/6))*np.random.normal(0,1.0,size = (self.sizes[l+1],int(self.patterns[l])))) for l in range(self.num_layers-1)]
        self.xi2=[(((1/(self.sizes[l]*ln(self.sizes[l])))**(1/6))*np.random.normal(0,1.0,size = (int(self.patterns[l]),self.sizes[l]))) for l in range(self.num_layers-1)]
        self.w_sy = [np.dot(np.dot(self.xi1[l],sig_mat(self.Sigma[l])),self.xi2[l]) for l in range(self.num_layers-1)]
        self.Adam_s = Adam(self.Sigma*1)
        self.Adam_xi1 = Adam(self.xi1*1)
        self.Adam_xi2=Adam(self.xi2*1)
    def update(self):
        self.w_sy = [np.dot(np.dot(self.xi1[l],sig_mat(self.Sigma[l])),self.xi2[l]) for l in range(self.num_layers-1)]
    def feedforward(self,a1,activate,back=False):
        #x为输入的图片，尺寸为784*mini_batch_size
        a = a1*1
        zm=[]
        process=[a*1]
        for l in range(self.num_layers-1):#0,1,2
#             self.update()
            z = np.dot(self.w_sy[l],process[l])
            zm.append(z*1)
            if (l<(self.num_layers-2)):#l=0,1
                a = activate(z)
            if (l>=(self.num_layers-2)):
                a = softmax(z)
            process.append(a*1)

        if back == False:
            return process[-1]
        if back == True:
            return zm,process

    def evaluate(self, testdata1,activate,clip_now = 0):
        # 获得预测结果a:10*batch_size
        #testlabel:10*batch_size
        data1,label1 = mini_batch_generate(500,testdata1*1,test_label*1)
        accuracy=[]
        for j in range(data1.shape[0]):
            a=self.feedforward(data1[j],activate,back=False)
            max0=np.argmax(a,axis=0)
            max1=np.argmax(label1[j],axis=0)
            accuracy.append((np.sum((max0-max1) == 0))/(data1[j].shape[1]))
        return np.average(accuracy)

    def backprop(self,x,y,activate,dactivate,back=True):
        medicine=pow(10,-30)
        #x:输入：784*batch_size
        #y:输入标签：10*batch_size
        tri=[]
        self.update()
        zm,out=self.feedforward(x,activate,back=True)
        ## out is attached with sigmoid
        nabla_sig = [np.zeros(b_s.shape) for b_s in self.Sigma]
        nabla_xi1 = [np.zeros(b_s.shape) for b_s in self.xi1]
        nabla_xi2 = [np.zeros(b_s.shape) for b_s in self.xi2]
        for l in range(1, (self.num_layers)):
            self.update()
            if l==1:
                tri_=(out[-1]-y)
                tri.append(tri_)
            else:
                tri_=np.dot(self.w_sy[-l+1].T,tri[-1])*dactivate(zm[-l])
                tri.append(tri_)
#             nabla_sig[-l] = (np.sum((tri_@(np.dot(self.xi2[-l],out[-l-1]).T))*self.xi1[-l],axis=0)/(out[-l-1].shape[1])).reshape(len(self.Sigma[-l]),1)
            nabla_xi1[-l] = ((tri_@((self.xi2[-l]@out[-l-1]).T))*(self.Sigma[-l].T))/out[-l-1].shape[1]
            nabla_xi2[-l] = ((self.xi1[-l]*(self.Sigma[-l].T)).T)@(tri_@out[-l-1].T)/out[-l-1].shape[1]
        return nabla_sig,nabla_xi1,nabla_xi2

    def adam_update(self,lr,mini_batch_size,activate,dactivate,train_data_x,train_label_x):
        data_x=train_data_x*1
        label_x=train_label_x*1
        data,label = mini_batch_generate(mini_batch_size,data_x,label_x)
        for j in range(data.shape[0]):
            self.update()
            delta_nabla_sig,delta_nabla_xi1,delta_nabla_xi2= self.backprop(data[j],label[j],activate,dactivate,back=True)
            self.xi1 = (self.Adam_xi1.New_theta(self.xi1,delta_nabla_xi1,lr,1e-4))
            self.xi2 = (self.Adam_xi2.New_theta(self.xi2,delta_nabla_xi2,lr,1e-4))
#             self.Sigma = (self.Adam_s.New_theta(self.Sigma,delta_nabla_sig,lr,1e-4))
#             print('\r'+str(j)+'/'+str(int(data.shape[0])),end='')

    def SGD(self,mini_batch_size,epoch,lr0,activate,dactivate):
        acc1_=[]
        for i in range(epoch):
            train_labelt=train_label*1#改参数
            train_datat=train_data
            lr = divi_(lr0,i,30)
            print ("epoch %s training complete" % i)
            acc1 = self.evaluate(test_data,activate)
            print("the test Accuracy for task0 is:{} %".format((acc1)*100))
            self.adam_update(lr,mini_batch_size,activate,dactivate,train_datat,train_labelt)
            acc1_.append(acc1*100)
        return acc1_

# In[18]:

if __name__ == '__main__':
    import time
    for lr in [0.005]:
        for N in [50]:
            print("lr=",lr)
            print("N=", N)
            acc_p=[]
            for i in range(5):
                time1=time.time()
                net = NeuralNetwork([784,N,N,10],[50,50,50])
                acc1=net.SGD(100,150,lr,relu,drelu)
                acc_p.append(acc1*1)
                time2=time.time()
                print(time2-time1)
            print("accuracy = ",np.average(np.array(acc_p)[:,-1]))
#         model_save('nscaledata/model/new/7hidp'+str(p)+'hopsimple'+str(i+1)+'.pickle').model_s(net)
#     np.save('nscaledata/7hidbatch100simple_p='+str(p)+'data2',acc_p,allow_pickle=True)