import json

from alipay.aop.api.constant.ParamConstants import *
from alipay.aop.api.domain.BankcardExtInfo import BankcardExtInfo

class Participant(object):

    def __init__(self):
        self._bankcard_ext_info = None
        self._ext_info = None
        self._identity = None
        self._identity_type = None
        self._merchant_user_info = None
        self._name = None

    @property
    def bankcard_ext_info(self):
        return self._bankcard_ext_info

    @bankcard_ext_info.setter
    def bankcard_ext_info(self, value):
        if isinstance(value, BankcardExtInfo):
            self._bankcard_ext_info = value
        else:
            self._bankcard_ext_info = BankcardExtInfo.from_alipay_dict(value)
    @property
    def ext_info(self):
        return self._ext_info

    @ext_info.setter
    def ext_info(self, value):
        self._ext_info = value
    @property
    def identity(self):
        return self._identity

    @identity.setter
    def identity(self, value):
        self._identity = value
    @property
    def identity_type(self):
        return self._identity_type

    @identity_type.setter
    def identity_type(self, value):
        self._identity_type = value
    @property
    def merchant_user_info(self):
        return self._merchant_user_info

    @merchant_user_info.setter
    def merchant_user_info(self, value):
        self._merchant_user_info = value
    @property
    def name(self):

    @name.setter
    def name(self, value):
        self._name = value

    def to_alipay_dict(self):
        params = dict()
        if self.bankcard_ext_info:
            if hasattr(self.bankcard_ext_info, 'to_alipay_dict'):
                params['bankcard_ext_info'] = self.bankcard_ext_info.to_alipay_dict()
            else:
                params['bankcard_ext_info'] = self.bankcard_ext_info
        if self.ext_info:
            if hasattr(self.ext_info, 'to_alipay_dict'):
                params['ext_info'] = self.ext_info.to_alipay_dict()
            else:
                params['ext_info'] = self.ext_info
        if self.identity:
            if hasattr(self.identity, 'to_alipay_dict'):
                params['identity'] = self.identity.to_alipay_dict()
            else:
                params['identity'] = self.identity
        if self.identity_type:
            if hasattr(self.identity_type, 'to_alipay_dict'):
                params['identity_type'] = self.identity_type.to_alipay_dict()
            else:
                params['identity_type'] = self.identity_type
        if self.merchant_user_info:
            if hasattr(self.merchant_user_info, 'to_alipay_dict'):
                params['merchant_user_info'] = self.merchant_user_info.to_alipay_dict()
            else:
                params['merchant_user_info'] = self.merchant_user_info
        if self.name:
            if hasattr(self.name, 'to_alipay_dict'):
                params['name'] = self.name.to_alipay_dict()
            else:
                params['name'] = self.name
        return params

    @staticmethod
    def from_alipay_dict(d):
        if not d:
            return None
        o = Participant()
        if 'bankcard_ext_info' in d:
            o.bankcard_ext_info = d['bankcard_ext_info']
        if 'ext_info' in d:
            o.ext_info = d['ext_info']
        if 'identity' in d:
            o.identity = d['identity']
        if 'identity_type' in d:
            o.identity_type = d['identity_type']
        if 'merchant_user_info' in d:
            o.merchant_user_info = d['merchant_user_info']
        if 'name' in d:
            o.name = d['name']
        return o


params = dict()
        if self.bankcard_ext_info:
            if hasattr(self.bankcard_ext_info, 'to_alipay_dict'):
                params['bankcard_ext_info'] = self.bankcard_ext_info.to_alipay_dict()
            else:
                params['bankcard_ext_info'] = self.bankcard_ext_info
        if self.ext_info:
            if hasattr(self.ext_info, 'to_alipay_dict'):
                params['ext_info'] = self.ext_info.to_alipay_dict()
            else:
                params['ext_info'] = self.ext_info

import json

from alipay.aop.api.constant.ParamConstants import *
from alipay.aop.api.domain.BankcardExtInfo import BankcardExtInfo

class Participant(object):

    def __init__(self):
        self._bankcard_ext_info = None
        self._ext_info = None
        self._identity = None
        self._identity_type = None
        self._merchant_user_info = None
        self._name = None

    @property
    def bankcard_ext_info(self):
        return self._bankcard_ext_info

    @bankcard_ext_info.setter
    def bankcard_ext_info(self, value):
        if isinstance(value, BankcardExtInfo):
            self._bankcard_ext_info = value
        else:
            self._bankcard_ext_info = BankcardExtInfo.from_alipay_dict(value)
    @property
    def ext_info(self):
        return self._ext_info

    @ext_info.setter
    def ext_info(self, value):
        self._ext_info = value
    @property
    def identity(self):
        return self._identity

    @identity.setter
    def identity(self, value):
        self._identity = value
    @property
    def identity_type(self):
        return self._identity_type

    @identity_type.setter
    def identity_type(self, value):
        self._identity_type = value
    @property
    def merchant_user_info(self):
        return self._merchant_user_info

    @merchant_user_info.setter
    def merchant_user_info(self, value):
        self._merchant_user_info = value
    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    def to_alipay_dict(self):

        if self.identity:
            if hasattr(self.identity, 'to_alipay_dict'):
                params['identity'] = self.identity.to_alipay_dict()
            else:
                params['identity'] = self.identity
        if self.identity_type:
            if hasattr(self.identity_type, 'to_alipay_dict'):
                params['identity_type'] = self.identity_type.to_alipay_dict()
            else:
                params['identity_type'] = self.identity_type
        if self.merchant_user_info:
            if hasattr(self.merchant_user_info, 'to_alipay_dict'):
                params['merchant_user_info'] = self.merchant_user_info.to_alipay_dict()
            else:
                params['merchant_user_info'] = self.merchant_user_info
        if self.name:
            if hasattr(self.name, 'to_alipay_dict'):
                params['name'] = self.name.to_alipay_dict()
            else:
                params['name'] = self.name
        return params

    @staticmethod
    def from_alipay_dict(d):
        if not d:
            return None
        o = Participant()
        if 'bankcard_ext_info' in d:
            o.bankcard_ext_info = d['bankcard_ext_info']
        if 'ext_info' in d:
            o.ext_info = d['ext_info']
        if 'identity' in d:
            o.identity = d['identity']
        if 'identity_type' in d:
            o.identity_type = d['identity_type']
        if 'merchant_user_info' in d:
            o.merchant_user_info = d['merchant_user_info']
        if 'name' in d:
            o.name = d['name']
        return o


if self.identity:
            if hasattr(self.identity, 'to_alipay_dict'):
                params['identity'] = self.identity.to_alipay_dict()
            else:
                params['identity'] = self.identity
        if self.identity_type:
            if hasattr(self.identity_type, 'to_alipay_dict'):
                params['identity_type'] = self.identity_type.to_alipay_dict()
            else:
                params['identity_type'] = self.identity_type

import json

from alipay.aop.api.constant.ParamConstants import *
from alipay.aop.api.domain.BankcardExtInfo import BankcardExtInfo

class Participant(object):

    def __init__(self):
        self._bankcard_ext_info = None
        self._ext_info = None
        self._identity = None
        self._identity_type = None
        self._merchant_user_info = None
        self._name = None

    @property
    def bankcard_ext_info(self):
        return self._bankcard_ext_info

    @bankcard_ext_info.setter
    def bankcard_ext_info(self, value):
        if isinstance(value, BankcardExtInfo):
            self._bankcard_ext_info = value
        else:
            self._bankcard_ext_info = BankcardExtInfo.from_alipay_dict(value)
    @property
    def ext_info(self):
        return self._ext_info

    @ext_info.setter
    def ext_info(self, value):
        self._ext_info = value
    @property
    def identity(self):
        return self._identity

    @identity.setter
    def identity(self, value):
        self._identity = value
    @property
    def identity_type(self):
        return self._identity_type

    @identity_type.setter
    def identity_type(self, value):
        self._identity_type = value
    @property
    def merchant_user_info(self):
        return self._merchant_user_info

    @merchant_user_info.setter
    def merchant_user_info(self, value):
        self._merchant_user_info = value
    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    def to_alipay_dict(self):
        params = dict()
        if self.bankcard_ext_info:
            if hasattr(self.bankcard_ext_info, 'to_alipay_dict'):
                params['bankcard_ext_info'] = self.bankcard_ext_info.to_alipay_dict()
            else:
                params['bankcard_ext_info'] = self.bankcard_ext_info
        if self.ext_info:
            if hasattr(self.ext_info, 'to_alipay_dict'):
                params['ext_info'] = self.ext_info.to_alipay_dict()
            else:
                params['ext_info'] = self.ext_info

        if self.merchant_user_info:
            if hasattr(self.merchant_user_info, 'to_alipay_dict'):
                params['merchant_user_info'] = self.merchant_user_info.to_alipay_dict()
            else:
                params['merchant_user_info'] = self.merchant_user_info
        if self.name:
            if hasattr(self.name, 'to_alipay_dict'):
                params['name'] = self.name.to_alipay_dict()
            else:
                params['name'] = self.name
        return params

    @staticmethod
    def from_alipay_dict(d):
        if not d:
            return None
        o = Participant()
        if 'bankcard_ext_info' in d:
            o.bankcard_ext_info = d['bankcard_ext_info']
        if 'ext_info' in d:
            o.ext_info = d['ext_info']
        if 'identity' in d:
            o.identity = d['identity']
        if 'identity_type' in d:
            o.identity_type = d['identity_type']
        if 'merchant_user_info' in d:
            o.merchant_user_info = d['merchant_user_info']
        if 'name' in d:
            o.name = d['name']
        return o


if self.merchant_user_info:
            if hasattr(self.merchant_user_info, 'to_alipay_dict'):
                params['merchant_user_info'] = self.merchant_user_info.to_alipay_dict()
            else:
                params['merchant_user_info'] = self.merchant_user_info
        if self.name:
            if hasattr(self.name, 'to_alipay_dict'):
                params['name'] = self.name.to_alipay_dict()
            else:
                params['name'] = self.name
        return params

import json

from alipay.aop.api.constant.ParamConstants import *
from alipay.aop.api.domain.BankcardExtInfo import BankcardExtInfo

class Participant(object):

    def __init__(self):
        self._bankcard_ext_info = None
        self._ext_info = None
        self._identity = None
        self._identity_type = None
        self._merchant_user_info = None
        self._name = None

    @property
    def bankcard_ext_info(self):
        return self._bankcard_ext_info

    @bankcard_ext_info.setter
    def bankcard_ext_info(self, value):
        if isinstance(value, BankcardExtInfo):
            self._bankcard_ext_info = value
        else:
            self._bankcard_ext_info = BankcardExtInfo.from_alipay_dict(value)
    @property
    def ext_info(self):
        return self._ext_info

    @ext_info.setter
    def ext_info(self, value):
        self._ext_info = value
    @property
    def identity(self):
        return self._identity

    @identity.setter
    def identity(self, value):
        self._identity = value
    @property
    def identity_type(self):
        return self._identity_type

    @identity_type.setter
    def identity_type(self, value):
        self._identity_type = value
    @property
    def merchant_user_info(self):
        return self._merchant_user_info

    @merchant_user_info.setter
    def merchant_user_info(self, value):
        self._merchant_user_info = value
    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    def to_alipay_dict(self):
        params = dict()
        if self.bankcard_ext_info:
            if hasattr(self.bankcard_ext_info, 'to_alipay_dict'):
                params['bankcard_ext_info'] = self.bankcard_ext_info.to_alipay_dict()
            else:
                params['bankcard_ext_info'] = self.bankcard_ext_info
        if self.ext_info:
            if hasattr(self.ext_info, 'to_alipay_dict'):
                params['ext_info'] = self.ext_info.to_alipay_dict()
            else:
                params['ext_info'] = self.ext_info
        if self.identity:
            if hasattr(self.identity, 'to_alipay_dict'):
                params['identity'] = self.identity.to_alipay_dict()
            else:
                params['identity'] = self.identity
        if self.identity_type:
            if hasattr(self.identity_type, 'to_alipay_dict'):
                params['identity_type'] = self.identity_type.to_alipay_dict()
            else:
                params['identity_type'] = self.identity_type

    @staticmethod
    def from_alipay_dict(d):
        if not d:
            return None
        o = Participant()
        if 'bankcard_ext_info' in d:
            o.bankcard_ext_info = d['bankcard_ext_info']
        if 'ext_info' in d:
            o.ext_info = d['ext_info']
        if 'identity' in d:
            o.identity = d['identity']
        if 'identity_type' in d:
            o.identity_type = d['identity_type']
        if 'merchant_user_info' in d:
            o.merchant_user_info = d['merchant_user_info']
        if 'name' in d:
            o.name = d['name']
        return o


import json

from alipay.aop.api.constant.ParamConstants import *
from alipay.aop.api.domain.BankcardExtInfo import BankcardExtInfo

class Participant(object):

    def __init__(self):
        self._bankcard_ext_info = None
        self._ext_info = None
        self._identity = None
        self._identity_type = None
        self._merchant_user

        self._name = None

    @property
    def bankcard_ext_info(self):
        return self._bankcard_ext_info

    @bankcard_ext_info.setter
    def bankcard_ext_info(self, value):
        if isinstance(value, BankcardExtInfo):
            self._bankcard_ext_info = value
        else:
            self._bankcard_ext_info = BankcardExtInfo.from_alipay_dict(value)
    @property
    def ext_info(self):
        return self._ext_info

    @ext_info.setter
    def ext_info(self, value):
        self._ext_info = value
    @property
    def identity(self):
        return self._identity

    @identity.setter
    def identity(self, value):
        self._identity = value
    @property
    def identity_type(self):
        return self._identity_type

    @identity_type.setter
    def identity_type(self, value):
        self._identity_type = value
    @property
    def merchant_user_info(self):
        return self._merchant_user_info

    @merchant_user_info.setter
    def merchant_user_info(self, value):
        self._merchant_user_info = value
    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    def to_alipay_dict(self):
        params = dict()
        if self.bankcard_ext_info:
            if hasattr(self.bankcard_ext_info, 'to_alipay_dict'):
                params['bankcard_ext_info'] = self.bankcard_ext_info.to_alipay_dict()
            else:
                params['bankcard_ext_info'] = self.bankcard_ext_info
        if self.ext_info:
            if hasattr(self.ext_info, 'to_alipay_dict'):
                params['ext_info'] = self.ext_info.to_alipay_dict()
            else:
                params['ext_info'] = self.ext_info
        if self.identity:
            if hasattr(self.identity, 'to_alipay_dict'):
                params['identity'] = self.identity.to_alipay_dict()
            else:
                params['identity'] = self.identity
        if self.identity_type:
            if hasattr(self.identity_type, 'to_alipay_dict'):
                params['identity_type'] = self.identity_type.to_alipay_dict()
            else:
                params['identity_type'] = self.identity_type
        if self.merchant_user_info:
            if hasattr(self.merchant_user_info, 'to_alipay_dict'):
                params['merchant_user_info'] = self.merchant_user_info.to_alipay_dict()
            else:
                params['merchant_user_info'] = self.merchant_user_info
        if self.name:
            if hasattr(self.name, 'to_alipay_dict'):
                params['name'] = self.name.to_alipay_dict()
            else:
                params['name'] = self.name
        return params

    @staticmethod
    def from_alipay_dict(d):
        if not d:
            return None
        o = Participant()
        if 'bankcard_ext_info' in d:
            o.bankcard_ext_info = d['bankcard_ext_info']
        if 'ext_info' in d:
            o.ext_info = d['ext_info']
        if 'identity' in d:
            o.identity = d['identity']
        if 'identity_type' in d:
            o.identity_type = d['identity_type']
        if 'merchant_user_info' in d:
            o.merchant_user_info = d['merchant_user_info']
        if 'name' in d:
            o.name = d['name']
        return o


if 'bankcard_ext_info' in d:
            o.bankcard_ext_info = d['bankcard_ext_info']

import json

from alipay.aop.api.constant.ParamConstants import *
from alipay.aop.api.domain.BankcardExtInfo import BankcardExtInfo

class Participant(object):

    def __init__(self):
        self._bankcard_ext_info = None
        self._ext_info = None
        self._identity = None
        self._identity_type = None
        self._merchant_user_info = None
        self._name = None

    @property
    def bankcard_ext_info(self):
        return self._bankcard_ext_info

    @bankcard_ext_info.setter
    def bankcard_ext_info(self, value):
        if isinstance(value, BankcardExtInfo):
            self._bankcard_ext_info = value
        else:
            self._bankcard_ext_info = BankcardExtInfo.from_alipay_dict(value)
    @property
    def ext_info(self):
        return self._ext_info

    @ext_info.setter
    def ext_info(self, value):
        self._ext_info = value
    @property
    def identity(self):
        return self._identity

    @identity.setter
    def identity(self, value):
        self._identity = value
    @property
    def identity_type(self):
        return self._identity_type

    @identity_type.setter
    def identity_type(self, value):
        self._identity_type = value
    @property
    def merchant_user_info(self):
        return self._merchant_user_info

    @merchant_user_info.setter
    def merchant_user_info(self, value):
        self._merchant_user_info = value
    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    def to_alipay_dict(self):
        params = dict()
        if self.bankcard_ext_info:
            if hasattr(self.bankcard_ext_info, 'to_alipay_dict'):
                params['bankcard_ext_info'] = self.bankcard_ext_info.to_alipay_dict()
            else:
                params['bankcard_ext_info'] = self.bankcard_ext_info
        if self.ext_info:
            if hasattr(self.ext_info, 'to_alipay_dict'):
                params['ext_info'] = self.ext_info.to_alipay_dict()
            else:
                params['ext_info'] = self.ext_info
        if self.identity:
            if hasattr(self.identity, 'to_alipay_dict'):
                params['identity'] = self.identity.to_alipay_dict()
            else:
                params['identity'] = self.identity
        if self.identity_type:
            if hasattr(self.identity_type, 'to_alipay_dict'):
                params['identity_type'] = self.identity_type.to_alipay_dict()
            else:
                params['identity_type'] = self.identity_type
        if self.merchant_user_info:
            if hasattr(self.merchant_user_info, 'to_alipay_dict'):
                params['merchant_user_info'] = self.merchant_user_info.to_alipay_dict()
            else:
                params['merchant_user_info'] = self.merchant_user_info
        if self.name:
            if hasattr(self.name, 'to_alipay_dict'):
                params['name'] = self.name.to_alipay_dict()
            else:
                params['name'] = self.name
        return params

    @staticmethod
    def from_alipay_dict(d):
        if not d:
            return None
        o = Participant()

        if 'ext_info' in d:
            o.ext_info = d['ext_info']
        if 'identity' in d:
            o.identity = d['identity']
        if 'identity_type' in d:
            o.identity_type = d['identity_type']
        if 'merchant_user_info' in d:
            o.merchant_user_info = d['merchant_user_info']
        if 'name' in d:
            o.name = d['name']
        return o


import json

from alipay.aop.api.constant.ParamConstants import *
from alipay.aop.api.domain.BankcardExtInfo import BankcardExtInfo

class Participant(object):

    def __init__(self):
        self._bankcard_ext_info = None
        self._ext_info = None
        self._identity = None
        self._identity_type = None
        self._merchant_user_info = None
        self._name = None

    @property
    def bankcard_ext_info(self):
        return self._bankcard_ext_info

    @bankcard_ext_info.setter
    def bankcard_ext_info(self, value):
        if isinstance(value, BankcardExtInfo):
            self._bankcard_ext_info = value
        else:
            self._bankcard_ext_info = BankcardExtInfo.from_alipay_dict(value)
    @property
    def ext_info(self):
        return self._ext_info

    @ext_info.setter
    def ext_info(self, value):
        self._ext_info = value
    @property
    def identity(self):
        return self._identity

    @identity.setter
    def identity(self, value):
        self._identity = value
    @property
    def identity_type(self):
        return self._identity_type

    @identity_type.setter
    def identity_type(self, value):
        self._identity_type = value
    @property
    def merchant_user_info(self):
        return self._merchant_user_info

    @merchant_user_info.setter
    d

ef merchant_user_info(self, value):
        self._merchant_user_info = value
    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

    def to_alipay_dict(self):
        params = dict()
        if self.bankcard_ext_info:
            if hasattr(self.bankcard_ext_info, 'to_alipay_dict'):
                params['bankcard_ext_info'] = self.bankcard_ext_info.to_alipay_dict()
            else:
                params['bankcard_ext_info'] = self.bankcard_ext_info
        if self.ext_info:
            if hasattr(self.ext_info, 'to_alipay_dict'):
                params['ext_info'] = self.ext_info.to_alipay_dict()
            else:
                params['ext_info'] = self.ext_info
        if self.identity:
            if hasattr(self.identity, 'to_alipay_dict'):
                params['identity'] = self.identity.to_alipay_dict()
            else:
                params['identity'] = self.identity
        if self.identity_type:
            if hasattr(self.identity_type, 'to_alipay_dict'):
                params['identity_type'] = self.identity_type.to_alipay_dict()
            else:
                params['identity_type'] = self.identity_type
        if self.merchant_user_info:
            if hasattr(self.merchant_user_info, 'to_alipay_dict'):
                params['merchant_user_info'] = self.merchant_user_info.to_alipay_dict()
            else:
                params['merchant_user_info'] = self.merchant_user_info
        if self.name:
            if hasattr(self.name, 'to_alipay_dict'):
                params['name'] = self.name.to_alipay_dict()
            else:
                params['name'] = self.name
        return params

    @staticmethod
    def from_alipay_dict(d):
        if not d:
            return None
        o = Participant()
        if 'bankcard_ext_info' in d:
            o.bankcard_ext_info = d['bankcard_ext_info']
        if 'ext_info' in d:
            o.ext_info = d['ext_info']
        if 'identity' in d:
            o.identity = d['identity']
        if 'identity_type' in d:
            o.identity_type = d['identity_type']
        if 'merchant_user_info' in d:
            o.merchant_user_info = d['merchant_user_info']
        if 'name' in d:
            o.name = d['name']
        return o


from __future__ import unicode_literals

__version__ = '


def save_test_case(self, problem, base_dir):

import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")
        version = self._etree.attrib.get("version", "No Version")
        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")
        version = self._etree.attrib.get("version", "No Version")
        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")

import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):

        version = self._etree.attrib.get("version", "No Version")
        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


version = self._etree.attrib.get("version", "No Version")

import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")

        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")
        version = self._etree.attrib.get("version", "No Version")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")
        version = self._etree.attrib.get("version", "No Version")
        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return pro

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")

import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")
        version = self._etree.attrib.get("version", "No Version")
        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":

                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))

import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:
            self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")
        version = self._etree.attrib.get("version", "No Version")
        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []

        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


import base64
import copy
import random
import string
import hashlib
import json
import os
import xml.etree.ElementTree as ET

class FPSParser(object):
    def __init__(self, fps_path=None, string_data=None):
        if fps_path:

 self._etree = ET.parse(fps_path).getroot()
        elif string_data:
            self._ertree = ET.fromstring(string_data).getroot()
        else:
            raise ValueError("You must tell me the file path or directly give me the data for the file")
        version = self._etree.attrib.get("version", "No Version")
        if version not in ["1.1", "1.2"]:
            raise ValueError("Unsupported version '" + version + "'")

    @property
    def etree(self):
        return self._etree

    def parse(self):
        ret = []
        for node in self._etree:
            if node.tag == "item":
                ret.append(self._parse_one_problem(node))
        return ret

    def _parse_one_problem(self, node):
        sample_start = True
        test_case_start = True
        problem = {"title": "No Title", "description": "No Description",
                   "input": "No Input Description",
                   "output": "No Output Description",
                   "memory_limit": {"unit": None, "value": None},
                   "time_limit": {"unit": None, "value": None},
                   "samples": [], "images": [], "append": [],
                   "template": [], "prepend": [], "test_cases": [],
                   "hint": None, "source": None, "spj": None, "solution": []}
        for item in node:
            tag = item.tag
            if tag in ["title", "description", "input", "output", "hint", "source"]:
                problem[item.tag] = item.text
            elif tag == "time_limit":
                unit = item.attrib.get("unit", "s")
                if unit not in ["s", "ms"]:
                    raise ValueError("Invalid time limit unit")
                problem["time_limit"]["unit"] = item.attrib.get("unit", "s")
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid time limit value")
                problem["time_limit"]["value"] = value
            elif tag == "memory_limit":
                unit = item.attrib.get("unit", "MB")
                if unit not in ["MB", "KB", "mb", "kb"]:
                    raise ValueError("Invalid memory limit unit")
                problem["memory_limit"]["unit"] = unit.upper()
                value = int(item.text)
                if value <= 0:
                    raise ValueError("Invalid memory limit value")
                problem["memory_limit"]["value"] = value
            elif tag in ["template", "append", "prepend", "solution"]:
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid " + tag + ", language name is missed")
                problem[tag].append({"language": lang, "code": item.text})
            elif tag == "spj":
                lang = item.attrib.get("language")
                if not lang:
                    raise ValueError("Invalid spj, language name if missed")
                problem["spj"] = {"language": lang, "code": item.text}
            elif tag == "img":
                problem["images"].append({"src": None, "blob": None})
                for child in item:
                    if child.tag == "src":
                        problem["images"][-1]["src"] = child.text
                    elif child.tag == "base64":
                        problem["images"][-1]["blob"] = base64.b64decode(child.text)
            elif tag == "sample_input":
                if not sample_start:
                    raise ValueError("Invalid xml, error 'sample_input' tag order")
                problem["samples"].append({"input": item.text, "output": None})
                sample_start = False
            elif tag == "sample_output":
                if sample_start:
                    raise ValueError("Invalid xml, error 'sample_output' tag order")
                problem["samples"][-1]["output"] = item.text
                sample_start = True
            elif tag == "test_input":
                if not test_case_start:
                    raise ValueError("Invalid xml, error 'test_input' tag order")
                problem["test_cases"].append({"input": item.text, "output": None})
                test_case_start = False
            elif tag == "test_output":
                if test_case_start:
                    raise ValueError("Invalid xml, error 'test_output' tag order")
                problem["test_cases"][-1]["output"] = item.text
                test_case_start = True

        return problem

class FPSHelper(object):
    def save_image(self, problem, base_dir, base_url):
        _problem = copy.deepcopy(problem)
        for img in _problem["images"]:
            name = "".join(random.choice(string.ascii_lowercase + string.digits) for _ in range(12))
            ext = os.path.splitext(img["src"])[1]
            file_name = name + ext
            with open(os.path.join(base_dir, file_name), "wb") as f:
                f.write(img["blob"])
            for item in ["description", "input", "output"]:
                _problem[item] = _problem[item].replace(img["src"], os.path.join(base_url, file_name))
        return _problem

    def save_test_case(self, problem, base_dir):
        spj = problem.get("spj", {})
        test_cases = {}
        for index, item in enumerate(problem["test_cases"]):
            input_content = item.get("input")
            output_content = item.get("output")
            if input_content:
                with open(os.path.join(base_dir, str(index + 1) + ".in"), "w", encoding="utf-8") as f:
                    f.write(input_content)
            if output_content:
                with open(os.path.join(base_dir, str(index + 1) + ".out"), "w", encoding="utf-8") as f:
                    f.write(output_content)
            if spj:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in"
                }
            else:
                one_info = {
                    "input_size": len(input_content),
                    "input_name": f"{index + 1}.in",
                    "output_size": len(output_content),
                    "output_name": f"{index + 1}.out",
                    "stripped_output_md5": hashlib.md5(output_content.rstrip().encode("utf-8")).hexdigest()
                }
            test_cases[index] = one_info
        info = {
            "spj": True if spj else False,
            "test_cases": test_cases
        }
        with open(os.path.join(base_dir, "info"), "w", encoding="utf-8") as f:
            f.write(json.dumps(info, indent=4))
        return info

if __name__ == "__main__":
    import pprint

    parser = FPSParser("fps.xml")
    helper = FPSHelper()
    problems = parser.parse()
    for index, problem in enumerate(problems):
        path = os.path.join("/tmp/", str(index + 1))
        os.mkdir(path)
        helper.save_test_case(problem, path)

        pprint.pprint(helper.save_image(problem, "/tmp", "/static/img"))


"""
"""
"""
API for Correlator Module
This module finds correlation between two time series.
"""

from luminol import exceptions, utils
from luminol.algorithms.correlator_algorithms.all import correlator_algorithms
from luminol.anomaly_detector import AnomalyDetector
from luminol.constants import *
from luminol.modules.time_series import TimeSeries

class Correlator(object):

  def __init__(self, time_series_a, time_series_b, time_period=None, use_anomaly_score=False, algorithm_name=None, algorithm_params=None):
    """
    Initializer
    :param time_series_a: a TimeSeries, a dictionary or a path to a csv file(str).
    :param time_series_b: a TimeSeries, a dictionary or a path to a csv file(str).
    :param time_period: a tuple (start, end) representing a data period for considering correlation.
    :param str algorithm_name: name of the algorithm to use.
    :param dict algorithm_params: additional params for the specific algorithm.
    """
    self.time_series_a = self._load(time_series_a)
    self.time_series_b = self._load(time_series_b)
    if use_anomaly_score:
      self.time_series_a = self._get_anomaly_scores(self.time_series_a)
      self.time_series_b = self._get_anomaly_scores(self.time_series_b)
    if time_period:
      start_p, end_p = time_period
      try:
        self.time_series_a = self.time_series_a.crop(start_p, end_p)
        self.time_series_b = self.time_series_b.crop(start_p, end_p)
      # No data points fall into the specific time range.
      except ValueError:
        raise exceptions.NotEnoughDataPoints
    self._sanity_check()
    self.algorithm_params = {'time_series_a': self.time_series_a, 'time_series_b': self.time_series_b}
    self._get_algorithm_and_params(algorithm_name, algorithm_params)
    self._correlate()

  def _get_anomaly_scores(self, time_series):
    """
    Get anomaly scores of a time series.
    :param TimeSeries time_series: a time_series.
    """
    return AnomalyDetector(time_series, score_only=True).get_all_scores()

  def _load(self, time_series):
    """
    Load time series into a TimeSeries object.
    :param timeseries: a TimeSeries, a dictionary or a path to a csv file(str).
    :return TimeSeries: a TimeSeries object.
    """
    if isinstance(time_series, TimeSeries):
      return time_series
    if isinstance(time_series, dict):
      return TimeSeries(time_series)
    return TimeSeries(utils.read_csv(time_series))

  def _get_algorithm_and_params(self, algorithm_name, algorithm_params):
    """
    Get the specific algorithm and merge the algorithm params.
    :param str algorithm: name of the algorithm to use.
    :param dict algorithm_params: additional params for the specific algorithm.
    """
    algorithm_name = algorithm_name or CORRELATOR_ALGORITHM
    try:
      self.algorithm = correlator_algorithms[algorithm_name]
    except KeyError:
      raise exceptions.AlgorithmNotFound('luminol.Correlator: ' + str(algorithm_name) + ' not found.')
    # Merge parameters.
    if algorithm_params:
      if not isinstance(algorithm_params, dict):
        raise exceptions.InvalidDataFormat('luminol.Correlator: algorithm_params passed is not a dictionary.')
      else:
        self.algorithm_params = dict(algorithm_params.items() + self.algorithm_params.items())

  def _sanity_check(self):
    """
    Check if the time series have more than two data points.
    """
    if len(self.time_series_a) < 2 or len(self.time_series_b) < 2:
      raise exceptions.NotEnoughDataPoints('luminol.Correlator: Too few data points!')

  def _correlate(self):
    """
    Run correlation algorithm.
    """
    a = self.algorithm(**self.algorithm_params)
    self.correlation_result = a.run()

  def get_correlation_result(self):
    """
    Get correlation result.
    :return CorrelationResult: a CorrelationResult object.
    """
    return self.correlation_result

"""
    Compare with a threshold to determine whether two timeseries correlate to each other.
    :return: a CorrelationResult object if two time series correlate otherwise false.
    """
    return self.correlation_result if self.correlation_result.coefficient >= threshold else False


"""
    Get anomaly scores of a time series.
    :param TimeSeries time_series: a time_series.
    """
    return AnomalyDetector(time_series, score_only=True).get_all_scores()

"""
"""
"""
API for Correlator Module
This module finds correlation between two time series.
"""

from luminol import exceptions, utils
from luminol.algorithms.correlator_algorithms.all import correlator_algorithms
from luminol.anomaly_detector import AnomalyDetector
from luminol.constants import *
from luminol.modules.time_series import TimeSeries

class Correlator(object):

  def __init__(self, time_series_a, time_series_b, time_period=None, use_anomaly_score=False, algorithm_name=None, algorithm_params=None):
    """
    Initializer
    :param time_series_a: a TimeSeries, a dictionary or a path to a csv file(str).
    :param time_series_b: a TimeSeries, a dictionary or a path to a csv file(str).
    :param time_period: a tuple (start, end) representing a data period for considering correlation.
    :param str algorithm_name: name of the algorithm to use.
    :param dict algorithm_params: additional params for the specific algorithm.
    """
    self.time_series_a = self._load(time_series_a)
    self.time_series_b = self._load(time_series_b)
    if use_anomaly_score:
      self.time_series_a = self._get_anomaly_scores(self.time_series_a)
      self.time_series_b = self._get_anomaly_scores(self.time_series_b)
    if time_period:
      start_p, end_p = time_period
      try:
        self.time_series_a = self.time_series_a.crop(start_p, end_p)
        self.time_series_b = self.time_series_b.crop(start_p, end_p)
      # No data points fall into the specific time range.
      except ValueError:
        raise exceptions.NotEnoughDataPoints
    self._sanity_check()
    self.algorithm_params = {'time_series_a': self.time_series_a, 'time_series_b': self.time_series_b}
    self._get_algorithm_and_params(algorithm_name, algorithm_params)
    self._correlate()

  def _get_anomaly_scores(self, time_series):

  def _load(self, time_series):
    """
    Load time series into a TimeSeries object.
    :param timeseries: a TimeSeries, a dictionary or a path to a csv file(str).
    :return TimeSeries: a TimeSeries object.
    """
    if isinstance(time_series, TimeSeries):
      return time_series
    if isinstance(time_series, dict):
      return TimeSeries(time_series)
    return TimeSeries(utils.read_csv(time_series))

  def _get_algorithm_and_params(self, algorithm_name, algorithm_params):
    """
    Get the specific algorithm and merge the algorithm params.
    :param str algorithm: name of the algorithm to use.
    :param dict algorithm_params: additional params for the specific algorithm.
    """
    algorithm_name = algorithm_name or CORRELATOR_ALGORITHM
    try:
      self.algorithm = correlator_algorithms[algorithm_name]
    except KeyError:
      raise exceptions.AlgorithmNotFound('luminol.Correlator: ' + str(algorithm_name) + ' not found.')
    # Merge parameters.
    if algorithm_params:
      if not isinstance(algorithm_params, dict):
        raise exceptions.InvalidDataFormat('luminol.Correlator: algorithm_params passed is not a dictionary.')
      else:
        self.algorithm_params = dict(algorithm_params.items() + self.algorithm_params.items())

  def _sanity_check(self):
    """
    Check if the time series have more than two data points.
    """
    if len(self.time_series_a) < 2 or len(self.time_series_b) < 2:
      raise exceptions.NotEnoughDataPoints('luminol.Correlator: Too few data points!')

  def _correlate(self):
    """
    Run correlation algorithm.
    """
    a = self.algorithm(**self.algorithm_params)
    self.correlation_result = a.run()

  def get_correlation_result(self):
    """
    Get correlation result.
    :return CorrelationResult: a CorrelationResult object.
    """
    return self.correlation_result

  def is_correlated(self, threshold=None):
    """
    Compare with a threshold to determine whether two timeseries correlate to each other.
    :return: a CorrelationResult object if two time series correlate otherwise false.
    """
    return self.correlation_result if self.correlation_result.coefficient >= threshold else False