def xor_string_value(first_string, second_string):
    """
    Runs the xor bitwise operation over all the items
    of both strings, retrieving the result.

    :type first_string: String
    :param first_string: The first string to the xor operation.
    :type second_string: String
    :param second_string: The second string to the xor operation.
    :rtype: String
    :return: The "string" result of the xor operation.
    """
    first_string_length = len(first_string)
    second_string_length = len(second_string)
    if not first_string_length == second_string_length:
        raise ValueError('Arguments to xor string must have the same length')
    result_character_list = []
    for first_character, second_character in zip(first_string, second_string):
        result_character = chr(ord(first_character) ^ ord(second_character))
        result_character_list.append(result_character)
    xor_result = ''.join(result_character_list)
    return xor_result


@staticmethod
def parse_encap(encap):
    """
        Parses the encap_type and encap_id from a json encap string
        Examples: vlan-515 / vxlan-5000

        :param encap: String containing the json encap format
        :returns: encap_type, encap_id
        """
    encap_type, encap_id = encap.split('-')
    return encap_type, encap_id


def get_env(path):
    """Get any environment variables"""
    if path:
        return {'PYTHONPATH': path}
    else:
        return {}


@staticmethod
def type_cast(item: str) ->str:
    """Cast dummy: does nothing."""
    return item


def describe_maintenance_window_execution_tasks(WindowExecutionId=None,
    Filters=None, MaxResults=None, NextToken=None):
    """
    For a given Maintenance Window execution, lists the tasks that were executed.
    See also: AWS API Documentation

    :example: response = client.describe_maintenance_window_execution_tasks(
        WindowExecutionId='string',
        Filters=[
            {
                'Key': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        MaxResults=123,
        NextToken='string'
    )

    :type WindowExecutionId: string
    :param WindowExecutionId: [REQUIRED]
            The ID of the Maintenance Window execution whose task executions should be retrieved.

    :type Filters: list
    :param Filters: Optional filters used to scope down the returned tasks. The supported filter key is STATUS with the corresponding values PENDING, IN_PROGRESS, SUCCESS, FAILED, TIMED_OUT, CANCELLING, and CANCELLED.
            (dict) --Filter used in the request.
            Key (string) --The name of the filter.
            Values (list) --The filter values.
            (string) --

    :type MaxResults: integer
    :param MaxResults: The maximum number of items to return for this call. The call also returns a token that you can specify in a subsequent call to get the next set of results.

    :type NextToken: string
    :param NextToken: The token for the next set of items to return. (You received this token from a previous call.)

    :rtype: dict
    :return: {
        'WindowExecutionTaskIdentities': [
            {
                'WindowExecutionId': 'string',
                'TaskExecutionId': 'string',
                'Status': 'PENDING'|'IN_PROGRESS'|'SUCCESS'|'FAILED'|'TIMED_OUT'|'CANCELLING'|'CANCELLED'|'SKIPPED_OVERLAPPING',
                'StatusDetails': 'string',
                'StartTime': datetime(2015, 1, 1),
                'EndTime': datetime(2015, 1, 1),
                'TaskArn': 'string',
                'TaskType': 'RUN_COMMAND'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


@classmethod
def isscalar(cls, dataset, dim):
    """
        Tests if dimension is scalar in each subpath.
        """
    if not dataset.data:
        return True
    ds = cls._inner_dataset_template(dataset)
    isscalar = []
    for d in dataset.data:
        ds.data = d
        isscalar.append(ds.interface.isscalar(ds, dim))
    return all(isscalar)


def ensure_in_a_virtual_environment():
    """
    Warn users if not in a virtual environment
    """
    import sys
    if hasattr(sys, 'real_prefix'):
        raise UserWarning(
            'aide_design should always be run in a virtual environment to ensurethat all dependencies are correctly installed. Please refer to thereadme for virtual environment setup instructions.'
            )


def format_time(t):
    """Format seconds into a human readable form."""
    m, s = divmod(t, 60)
    h, m = divmod(m, 60)
    d, h = divmod(h, 24)
    w, d = divmod(d, 7)
    if w:
        return '{0:2.0f}w{1:2.0f}d'.format(w, d)
    elif d:
        return '{0:2.0f}d{1:2.0f}h'.format(d, h)
    elif h:
        return '{0:2.0f}h{1:2.0f}m'.format(h, m)
    elif m:
        return '{0:2.0f}m{1:2.0f}s'.format(m, s)
    else:
        return '{0:5.0f}s'.format(s)


def traverse_using(iterator, obj, visitors):
    """visit the given expression structure using the given iterator of
    objects.

    :func:`.visitors.traverse_using` is usually called internally as the result
    of the :func:`.visitors.traverse` or :func:`.visitors.traverse_depthfirst`
    functions.

    :param iterator: an iterable or sequence which will yield
     :class:`_expression.ClauseElement`
     structures; the iterator is assumed to be the
     product of the :func:`.visitors.iterate` or
     :func:`.visitors.iterate_depthfirst` functions.

    :param obj: the :class:`_expression.ClauseElement`
     that was used as the target of the
     :func:`.iterate` or :func:`.iterate_depthfirst` function.

    :param visitors: dictionary of visit functions.  See :func:`.traverse`
     for details on this dictionary.

    .. seealso::

        :func:`.traverse`

        :func:`.traverse_depthfirst`

    """
    for target in iterator:
        meth = visitors.get(target.__visit_name__, None)
        if meth:
            meth(target)
    return obj


def humanize_time(secs):
    """convert second in to hh:mm:ss format
    """
    mins, secs = divmod(secs, 60)
    hours, mins = divmod(mins, 60)
    return '{:02d}:{:02d}:{:02d}'.format(int(hours), int(mins), int(secs))


def find_packages(top):
    """
    Find all of the packages.
    """
    import warnings
    warnings.warn('Deprecated, please use setuptools.find_packages',
        category=DeprecationWarning)
    from setuptools import find_packages as fp
    return fp(top)


def timeTime():
    """Return the date/time as a floating-point number in UTC, in
        the format used by the python time module.  Note that it is
        possible to create date/time values with DateTime that have no
        meaningful value to the time module."""


def provider_parser(subparser):
    """Configure provider parser for Henet."""
    subparser.description = """A provider for Hurricane Electric DNS.
        NOTE: THIS DOES NOT WORK WITH 2-FACTOR AUTHENTICATION.
              YOU MUST DISABLE IT IF YOU'D LIKE TO USE THIS PROVIDER.
        """
    subparser.add_argument('--auth-username', help=
        'specify username for authentication')
    subparser.add_argument('--auth-password', help=
        'specify password for authentication')


@classmethod
def stream_deserialize(cls, f, **kwargs):
    """Deserialize from a stream"""
    raise NotImplementedError


def is_job_array(job):
    """
    Check if the given job is an array.

    :param job: the job dictionary returned by AWS Batch api
    :return: true if the job is an array, false otherwise
    """
    return 'arrayProperties' in job and 'size' in job['arrayProperties']


@classmethod
def connect_nodes(cls, source=None, target=None, **kwargs):
    """ Connect source and target by creating an edge.
        `kwargs` are passed to the `cls` constructor.
        Only need to pass source, target or source_id, target_id """
    edge = cls(**kwargs)
    if source:
        edge.source = source
    if target:
        edge.target = target
    return edge


def formulafy(x):
    """
    Convert the input string x to a Latex representation of the chemical formula.
    e.g. ^13CH4 -> $^{13}CH_{4}$
    This can be used in matplotlib to display nicely a chemical formula.
    """
    import re
    return '$' + re.sub('([a-zA-Z])_?([0-9]+)', '\\1_{\\2}', re.sub(
        '\\^([0-9]+)', '^{\\1}', re.sub('([\\+-]+)$', '^{\\1}', x))) + '$'


def build_fun(bld):
    """
	Build function that is used for running configuration tests with ``conf.check()``
	"""
    if bld.kw['compile_filename']:
        node = bld.srcnode.make_node(bld.kw['compile_filename'])
        node.write(bld.kw['code'])
    o = bld(features=bld.kw['features'], source=bld.kw['compile_filename'],
        target='testprog')
    for k, v in bld.kw.items():
        setattr(o, k, v)
    if not bld.kw.get('quiet'):
        bld.conf.to_log('==>\n%s\n<==' % bld.kw['code'])


def registerCmd(cmd):
    """ registers cmd from tasks """
    print(f'registering {cmd}\r\n')


def write_file(filename, content, mode='w'):
    """write_file will open a file, "filename" and write content, "content"
       and properly close the file
    """
    with open(filename, mode) as filey:
        filey.writelines(content)
    return filename


@classmethod
def cubic(cls, a):
    """
        Initializes a Box in standard cubic setting using only cubic lattice
        parameters.

        a = b = c, alpha = beta = gamma = 90

        Parameters
        ----------
        - a : float
            The a lattice constant

        Returns
        -------
        atomman.Box
        """
    return cls(a=a, b=a, c=a, alpha=90, beta=90, gamma=90)


def file_replace(path, patterns):
    """
    Replace one or more patterns in a file.
    """
    content = open(path).read()
    if type(patterns[0]) == str:
        patterns = patterns,
    for pattern in patterns:
        content = content.replace(pattern[0], pattern[1])
    open(path, 'w').write(content)


def unique(seq):
    """Remove duplicate elements from seq. Assumes hashable elements."""
    return list(set(seq))


def _format_teams(teams):
    """Return a formatted string of the teams passed in"""
    result = ''
    for team in teams:
        result += team['name'] + '\n'
        if len(team['users']) > 1:
            for user in team['users']:
                result += '|    ' + user + '\n'
        result += '\n'
    return result.strip()


def apply_extras(value, extras):
    """Apply any additional functionalities after evaluation."""
    for extra in extras:
        if extra == 'len':
            value = len(value) if hasattr(value, 'len') or hasattr(value,
                '__len__') else 0
    return value


def getPropertyType(id):
    """Get the type of property 'id'.

        Returns None if no such property exists.
        """


def _append_params(oauth_params, params):
    """Append OAuth params to an existing set of parameters.

    Both params and oauth_params is must be lists of 2-tuples.

    Per `section 3.5.2`_ and `3.5.3`_ of the spec.

    .. _`section 3.5.2`: http://tools.ietf.org/html/rfc5849#section-3.5.2
    .. _`3.5.3`: http://tools.ietf.org/html/rfc5849#section-3.5.3

    """
    merged = list(params)
    merged.extend(oauth_params)
    merged.sort(key=lambda i: i[0].startswith('oauth_'))
    return merged


def warn(msg, category=UserWarning, stacklevel=2):
    """Generate a a warning with stacktrace.

    Parameters
    ----------
    msg : str
        The message of the warning.

    category : class
        The class of the warning to produce.

    stacklevel : int, optional
        How many steps above this function to "jump" in the stacktrace when
        displaying file and line number of the error message.
        Usually ``2``.

    """
    import warnings
    warnings.warn(msg, category=category, stacklevel=stacklevel)


def get_shell(name):
    """Absolute path to command

    :param str name: command
    :return: command args
    :rtype: list
    """
    if name.startswith('/'):
        return [name]
    return ['/usr/bin/env', name]


def chop(seq, count):
    """Returns an iterator that traverses the given sequence, returning tuples
    of count items at a time.  The final tuple is padded with Nones if there
    aren't enough items in the sequence.
    """
    buf = []
    for elt in seq:
        buf.append(elt)
        if len(buf) == count:
            yield tuple(buf)
            buf[:] = []
    if buf:
        yield tuple(buf) + (None,) * (count - len(buf))


def text_(s, encoding='latin-1', errors='strict'):
    """ If ``s`` is an instance of ``bytes``, return ``s.decode(encoding,
    errors)``, otherwise return ``s``"""
    if isinstance(s, bytes):
        return s.decode(encoding, errors)
    return s


def claim_delete(transport, request, queue_name, claim_id):
    """Deletes a Claim `claim_id`

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    """
    request.operation = 'claim_delete'
    request.params['queue_name'] = queue_name
    request.params['claim_id'] = claim_id
    transport.send(request)


def document_model_driven_signature(section, name, operation_model, include
    =None, exclude=None):
    """Documents the signature of a model-driven method

    :param section: The section to write the documentation to.

    :param name: The name of the method

    :param operation_model: The operation model for the method

    :type include: Dictionary where keys are parameter names and
        values are the shapes of the parameter names.
    :param include: The parameter shapes to include in the documentation.

    :type exclude: List of the names of the parameters to exclude.
    :param exclude: The names of the parameters to exclude from
        documentation.
    """
    params = {}
    if operation_model.input_shape:
        params = operation_model.input_shape.members
    parameter_names = list(params.keys())
    if include is not None:
        for member in include:
            parameter_names.append(member.name)
    if exclude is not None:
        for member in exclude:
            if member in parameter_names:
                parameter_names.remove(member)
    signature_params = ''
    if parameter_names:
        signature_params = '**kwargs'
    section.style.start_sphinx_py_method(name, signature_params)


@staticmethod
def _is_nmrstar(string):
    """Test if input string is in NMR-STAR format.

        :param string: Input string.
        :type string: :py:class:`str` or :py:class:`bytes`
        :return: Input string if in NMR-STAR format or False otherwise.
        :rtype: :py:class:`str` or :py:obj:`False`
        """
    if string[0:5] == u'data_' and u'save_' in string or string[0:5
        ] == b'data_' and b'save_' in string:
        return string
    return False


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def _linear_conversion(data, conversion):
    """ apply linear conversion to data

    Parameters
    ----------------
    data : numpy 1D array
        raw data to be converted to physical value
    conversion : mdfinfo3.info3 conversion block ('CCBlock') dict

    Returns
    -----------
    converted data to physical value
    """
    if conversion['P2'] == 1.0 and conversion['P1'] in (0.0, -0.0):
        return data
    else:
        return data * conversion['P2'] + conversion['P1']


def annotate(component, annotation, indicator) ->None:
    """
    Annotates ``component`` with ``indicator``.

    ..  container:: example

        Annotates first note in staff:

        >>> staff = abjad.Staff("c'4 d' e' f'")
        >>> abjad.annotate(staff[0], 'bow_direction', abjad.Down)
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \\new Staff
            {
                c'4
                d'4
                e'4
                f'4
            }

        >>> abjad.inspect(staff[0]).annotation('bow_direction')
        Down

        >>> abjad.inspect(staff[0]).annotation('bow_fraction') is None
        True

        >>> abjad.inspect(staff[0]).annotation('bow_fraction', 99)
        99

    Returns none.
    """
    from abjad.system.Wrapper import Wrapper
    import abjad
    if isinstance(annotation, abjad.Tag):
        message = 'use the tag=None keyword instead of annotate():\n'
        message += f'   {repr(annotation)}'
        raise Exception(message)
    assert isinstance(annotation, str), repr(annotation)
    Wrapper(annotation=annotation, component=component, indicator=indicator)


def _convert_code(code):
    """
    将聚宽形式的代码转化为 xalpha 形式

    :param code:
    :return:
    """
    no, mk = code.split('.')
    if mk == 'XSHG':
        return 'SH' + no
    elif mk == 'XSHE':
        return 'SZ' + no


def chute_find_field(chute, key, default=Exception):
    """
    Find a field in a chute definition loading from a paradrop.yaml file.
    """
    if key in chute:
        return chute[key]
    elif 'config' in chute and key in chute['config']:
        return chute['config'][key]
    elif isinstance(default, type):
        raise default('{} field not found in chute definition.'.format(key))
    else:
        return default


def calc_max_len(ser):
    """
    @doc: find the maximum length of a pandas Series of strings (for schema inference)
    @args: ser is a pandas Series of type 'O'
    @return: the maximum length of a string in ser
    """
    retser = ser.apply(lambda x: len(str(x)))
    ret = retser.max()
    return ret


def str_to_bytes(s):
    """convert string to byte unit. Case insensitive.

  >>> str_to_bytes('2GB')
    2147483648
  >>> str_to_bytes('1kb')
    1024
  """
    s = s.replace(' ', '')
    if s[-1].isalpha() and s[-2].isalpha():
        _unit = s[-2:].upper()
        _num = s[:-2]
    elif s[-1].isalpha():
        _unit = s[-1].upper()
        _num = s[:-1]
    else:
        return float(s)
    if not _unit in ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'):
        raise ValueError('invalid unit', _unit)
    carry = {'B': 1, 'KB': 1024, 'MB': 1024 ** 2, 'GB': 1024 ** 3, 'TB':
        1024 ** 4, 'PB': 1024 ** 5, 'EB': 1024 ** 6, 'ZB': 1024 ** 7, 'YB':
        1024 ** 8}
    return float(_num) * carry[_unit]


def reverse_dict(d):
    """ Reverses direction of dependence dict

    >>> d = {'a': (1, 2), 'b': (2, 3), 'c':()}
    >>> reverse_dict(d)
    {1: ('a',), 2: ('a', 'b'), 3: ('b',)}
    """
    result = {}
    for key in d:
        for val in d[key]:
            result[val] = result.get(val, tuple()) + (key,)
    return result


def make_time_unit_str(dtobj):
    """ Return a time unit string from a datetime object. """
    return 'seconds since ' + dtobj.strftime('%Y-%m-%dT%H:%M:%SZ')


@classmethod
def fromNamelistString(cls, string, context, template=None):
    """Loads the object from an FORTRAN namelist string.

        By default it assumes the derived class can be initialized from a string
        argument. If this is not the case, fromNamelistString should be implemented.
        """
    return cls(string)


def makeRoom(location='', *args):
    """
    Creates a tmp directory in the desired location
    Any extra argument is a nested directory
    """
    import os
    path = os.path.abspath(location)
    path = os.path.join(path, 'tmp')
    try:
        os.mkdir(path)
    except:
        pass
    for name in args:
        path = os.path.join(path, name)
        try:
            os.mkdir(path)
        except:
            pass
    return path


def update_subscriber(AccountId=None, BudgetName=None, Notification=None,
    OldSubscriber=None, NewSubscriber=None):
    """
    Update a subscriber
    See also: AWS API Documentation

    :example: response = client.update_subscriber(
        AccountId='string',
        BudgetName='string',
        Notification={
            'NotificationType': 'ACTUAL'|'FORECASTED',
            'ComparisonOperator': 'GREATER_THAN'|'LESS_THAN'|'EQUAL_TO',
            'Threshold': 123.0
        },
        OldSubscriber={
            'SubscriptionType': 'SNS'|'EMAIL',
            'Address': 'string'
        },
        NewSubscriber={
            'SubscriptionType': 'SNS'|'EMAIL',
            'Address': 'string'
        }
    )

    :type AccountId: string
    :param AccountId: [REQUIRED] Account Id of the customer. It should be a 12 digit number.

    :type BudgetName: string
    :param BudgetName: [REQUIRED] A string represents the budget name. No ':' character is allowed.

    :type Notification: dict
    :param Notification: [REQUIRED] Notification model. Each budget may contain multiple notifications with different settings.
            NotificationType (string) -- [REQUIRED] The type of a notification. It should be ACTUAL or FORECASTED.
            ComparisonOperator (string) -- [REQUIRED] The comparison operator of a notification. Currently we support less than, equal to and greater than.
            Threshold (float) -- [REQUIRED] The threshold of the a notification. It should be a number between 0 and 100.

    :type OldSubscriber: dict
    :param OldSubscriber: [REQUIRED] Subscriber model. Each notification may contain multiple subscribers with different addresses.
            SubscriptionType (string) -- [REQUIRED] The subscription type of the subscriber. It can be SMS or EMAIL.
            Address (string) -- [REQUIRED] A generic String.

    :type NewSubscriber: dict
    :param NewSubscriber: [REQUIRED] Subscriber model. Each notification may contain multiple subscribers with different addresses.
            SubscriptionType (string) -- [REQUIRED] The subscription type of the subscriber. It can be SMS or EMAIL.
            Address (string) -- [REQUIRED] A generic String.

    :rtype: dict
    :return: {}

    :returns:
    (dict) -- Response of UpdateSubscriber

    """
    pass


def insertbefore(newnode, refnode):
    """Insert newnode before refnode.

        ``__name__`` on newnode must be set.

        This function only supports adding of new nodes before the given
        refnode. If you want to move nodes you have to detach them from the
        tree first.
        """


def _check_resident_unhappy(resident, hospital):
    """ Determine whether a resident is unhappy because they are unmatched, or
    they prefer the hospital to their current match. """
    return resident.matching is None or resident.prefers(hospital, resident
        .matching)


def calc_av_over_3aa_window(df, data_col, new_col, n_aa=4):
    """ Function to average the properties of an amino acid (conservation, disruption, etc) across a window, consisting
    of three amino acids on the same side of an alpha helix (i, i-4, i+4)
    INPUTS:
    df: dataframe
    data_col: string showing the column name, which contains the data to be averaged
    new_col: string for the new column name, containing the average
    n_aa: number of amino acids separating the aa. Default = 4 (e.g. i, i-4, i+4)
    OUTPUTS:
    The original dataframe, with an extra column.
    """
    import numpy as np
    for aa_pos in df.index:
        disrupt_centre = df.loc[aa_pos, data_col]
        if aa_pos - n_aa in df.index:
            disrupt_left = df.loc[aa_pos - n_aa, data_col]
        else:
            disrupt_left = np.nan
        if aa_pos + n_aa in df.index:
            disrupt_right = df.loc[aa_pos + n_aa, data_col]
        else:
            disrupt_right = np.nan
        av_disrupt = np.nanmean([disrupt_centre, disrupt_left, disrupt_right])
        df.loc[aa_pos, new_col] = av_disrupt
    return df


@staticmethod
def line_list_to_string(line):
    """ Write a line in the CSV. """
    new_line = ''
    for i, cell in enumerate(line):
        cell = ' '.join(str(cell).split())
        new_line += cell.replace(',', ';')
        if i != len(line) - 1:
            new_line += ','
    return new_line


def get_stackless_package():
    """
    Compute the required Stackless-Python package.

    This method returns a string pair (name, version-specifier).
    If the package :mod:`stackless` is already available, the method
    returns (None,None).
    """
    from distutils.util import get_platform
    from distutils import log
    import sys
    try:
        import stackless
    except ImportError:
        pass
    else:
        log.info("Your Python version already provides the package 'stackless'"
            )
        return None, None
    reqVersionMin = '.'.join(map(str, sys.version_info[:3]))
    vi = list(sys.version_info[:3])
    vi[-1] += 1
    reqVersionMax = '.'.join(map(str, vi))
    reqVersion = '>=%s,<%s' % (reqVersionMin, reqVersionMax)
    ucs = 4 if sys.maxunicode >> 16 else 2
    platform = get_platform()
    if getattr(sys, 'pypy_version_info', None):
        raise RuntimeError('PyPy is not supported')
    elif platform.startswith('java'):
        raise NotImplementedError('Platform %s not yet supported' % (platform,)
            )
    installer = 'stackless_installer_C%d_%s' % (ucs, platform.replace('-', '_')
        )
    return installer, reqVersion


@staticmethod
def _get_parent_dn(dn):
    """
        Gets the dn of the parent object
        Meant to be overridden by inheriting classes.
        Raises exception if not overridden.

        :returns: string containing dn
        """
    if 'comp/' in dn:
        return dn.split('comp/prov-VMware/ctrlr-[DC1]-vcenter1/hv-')[0]
    else:
        return dn.split('topology/lsnode-')[0]


def add_keys(apps, schema_editor):
    """
    We can't import the Post model directly as it may be a newer
    version than this migration expects. We use the historical version.
    """
    Setting = apps.get_model('settings', 'Setting')
    key = ''
    try:
        key = 'IDENTIFIER'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title='کد منحصر بفرد سیستم', key=key, value=
            '', value_type='s', is_show=False, is_variable_in_home=False)


def jpxEncode(stream):
    """
        Method to encode streams using the JPEG2000 standard (NOT IMPLEMENTED YET)

        @param stream: A PDF stream
        @return: A tuple (status,statusContent), where statusContent is the encoded PDF stream in case status = 0 or an error in case status = -1
    """
    return -1, 'JpxEncode not supported yet'


@classmethod
def from_port_request(cls, context, port_uuid, port_resource_request):
    """Init the group from the resource request of a neutron port

        :param context: the request context
        :param port_uuid: the port requesting the resources
        :param port_resource_request: the resource_request attribute of the
                                      neutron port
        For example:

            port_resource_request = {
                "resources": {
                    "NET_BW_IGR_KILOBIT_PER_SEC": 1000,
                    "NET_BW_EGR_KILOBIT_PER_SEC": 1000},
                "required": ["CUSTOM_PHYSNET_2",
                             "CUSTOM_VNIC_TYPE_NORMAL"]
            }
        """
    obj = cls(context=context, use_same_provider=True, resources=
        port_resource_request['resources'], required_traits=set(
        port_resource_request.get('required', [])), requester_id=port_uuid)
    obj.obj_set_defaults()
    return obj


def enum_validation(property_schema, value):
    """Validate a non-collection property for value in an enumeration set.

    :param property_schema: The property schema to utilize for validation.
    :type property_schema: :class:`PropertySchema`
    :param value: The value of the property to be validated.
    :type value: object
    :return: True if the validation is successful, else False.
    :rtype: bool
    """
    if property_schema.enum:
        if not value in property_schema.enum:
            return False
    return True


def Ogive(df, no_nan=True):
    """
    Integrates the Ogive from Coespectra

    Parameters
    -----------
    df: dataframe
        cospectrum to be integrated
    """
    import scipy as sp
    import numpy as np
    import pandas as pd
    if no_nan:
        x = np.array(df.index)
        out = pd.DataFrame(index=x)
        for c in df.columns:
            y = np.array(df[c])
            og = sp.integrate.cumtrapz(y[::-1], x=x[::-1], initial=0)
            out.loc[:, (c)] = -og[::-1]
    else:
        dfs = []
        for c in df.columns:
            ser = df[c].dropna()
            x = np.array(ser.index)
            y = np.array(ser)
            og = sp.integrate.cumtrapz(y[::-1], x=x[::-1], initial=0)
            dfs.append(pd.DataFrame(data=-og[::-1], columns=[c], index=x))
        for d in dfs[1:]:
            dfs[0] = dfs[0].join(d, how='outer')
        out = dfs[0]
    out.index.name = df.index.name
    return out


@staticmethod
def attr():
    """
        Return the available attributes for a data_container type object.

        Returns
        -------
        out : dict
            Dictionary of available attributes (dictionary keys) with default
            values.
        """
    return {'func': None, 'is_set': False, 'param': None}


@classmethod
def from_timedelta(cls, delta):
    """
        Returns the closest pointwidth for the given timedelta without going over the
        specified duration. Because pointwidths are in powers of 2, be sure to check
        that the returned real duration is sufficient.
        """
    return cls.from_nanoseconds(delta.total_seconds() * 1000000000.0)


def getQueriables():
    """Return an iterable of objects that can be queried

        The returned obects should be two-tuples with:

        - A unicode id

          The id must uniquely identify the queriable object within
          the set of queriable objects. Furthermore, in subsequent
          calls, the same id should be used for a given queriable
          object.

        - A queriable object

          This is an object for which there is a view provided for
          searching for items.

        """


def _filter_by_extension(bundle, extension):
    """Return only files with the given extension"""
    for chunk in bundle:
        if chunk['name'].endswith('.{0}'.format(extension)):
            yield chunk


def toKilograms(x):
    """
    Converts x from Pounds to Kilograms
    :param x:
    :return: x / 2.205
    >>> toKilograms(1)
    0.453592
    """
    return x / 2.205


def endswith_lf(line):
    """Return True if line (a text or byte string) ends with '
'."""
    return line.endswith('\n' if isinstance(line, str) else b'\n')


def interpolate_lagrange_2D(x, y, x_nodes, y_nodes, field_nodes):
    """Interpolate values using 2D Lagrangian polynomials

    The order of the polynomial interpolation in each direction depends on the
    number of field nodes passed to this function

    Parameters
    ----------
    x, y : (N,) array_like
        Coordinates used to interpolate
    x_nodes, y_nodes, field_nodes : array_like
        Nodal coordinates and field to be interpolated at corresponding nodes

    Returns
    -------
    field : (N,) array_like
        Interpolated field

    """
    field = 0
    for m, (xm, ym, theta) in enumerate(zip(x_nodes, y_nodes, field_nodes)):
        tmp = 1
        for k, xk in enumerate(x_nodes):
            if k != m and xm - xk != 0:
                tmp *= (x - xk) / (xm - xk)
        for p, yp in enumerate(y_nodes):
            if p != m and ym - yp != 0:
                tmp *= (y - yp) / (ym - yp)
        field += tmp * theta
    return field


def render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def abc_psd(nu, a, b, c):
    """Lorentzian model of a Power Spectral Density.

    Parameters
    ----------
    nu : `numpy.ndarray` or `float`
        spatial frequency
    a : `float`
        a coefficient
    b : `float`
        b coefficient
    c : `float`
        c coefficient

    Returns
    -------
    `numpy.ndarray`
        value of PSD model

    """
    return a / (1 + (nu / b) ** 2) ** (c / 2)


def convertToRowAndColumn(x, y, shape, xScale=None, yScale=None, safe=True):
    """
    Convert from plot coordinates to image row and column.
    """
    if xScale is None:
        c = x
    else:
        if x < xScale[0]:
            x = xScale[0]
        c = (x - xScale[0]) / xScale[1]
    if yScale is None:
        r = y
    else:
        if y < yScale[0]:
            y = yScale[0]
        r = (y - yScale[0]) / yScale[1]
    if safe:
        c = min(int(c), shape[1] - 1)
        r = min(int(r), shape[0] - 1)
    else:
        c = int(c)
        r = int(r)
    return r, c


@classmethod
def run_foreman_tasks_ui_investigate(cls, options=None):
    """Build foreman-maintain advanced procedure run
         foreman-tasks-ui-investigate"""
    cls.command_sub = 'foreman-tasks-ui-investigate'
    if options is None:
        options = {}
    result = cls._construct_command(options)
    return result


def merge_dicts(dicts):
    """
    Merge a list of dictionaries into one.
    Later entries override the earlier ones.
    """
    if len(dicts) == 0:
        return {}
    if len(dicts) == 1:
        return dicts[0]
    first, *rest = dicts
    result = dict(first)
    for other in rest:
        result.update(other)
    return result


def processAlternatePrefixes(argList):
    """Convert alternate prefixes to our normal form"""
    for l in range(0, len(argList)):
        name = argList[l]
        if name.find('enable-') >= 0:
            argList[l] = name.replace('enable-', 'with-')
            if name.find('=') == -1:
                argList[l] = argList[l] + '=1'
        if name.find('disable-') >= 0:
            argList[l] = name.replace('disable-', 'with-')
            if name.find('=') == -1:
                argList[l] = argList[l] + '=0'
            elif name.endswith('=1'):
                argList[l].replace('=1', '=0')
        if name.find('without-') >= 0:
            argList[l] = name.replace('without-', 'with-')
            if name.find('=') == -1:
                argList[l] = argList[l] + '=0'
            elif name.endswith('=1'):
                argList[l].replace('=1', '=0')
    return


def shift_series(s_x, s_y, shift):
    """Shift series to align
    :param s_x: First Series
    :type s_x: :mod:`pandas.Series`

    :param s_y: Second Series
    :type s_y: :mod:`pandas.Series`

    :param shift: The number of index
        positions to be shifted
    :type shift: int
    """
    if shift > 0:
        s_y = s_y.shift(shift)
    else:
        s_x = s_x.shift(-1 * shift)
    return s_x, s_y


@classmethod
def _create_join(cls, left, right, onclause=None, isouter=False, full=False):
    """Produce a :class:`.Join` object, given two :class:`.FromClause`
        expressions.

        E.g.::

            j = join(user_table, address_table,
                     user_table.c.id == address_table.c.user_id)
            stmt = select([user_table]).select_from(j)

        would emit SQL along the lines of::

            SELECT user.id, user.name FROM user
            JOIN address ON user.id = address.user_id

        Similar functionality is available given any
        :class:`.FromClause` object (e.g. such as a :class:`.Table`) using
        the :meth:`.FromClause.join` method.

        :param left: The left side of the join.

        :param right: the right side of the join; this is any
         :class:`.FromClause` object such as a :class:`.Table` object, and
         may also be a selectable-compatible object such as an ORM-mapped
         class.

        :param onclause: a SQL expression representing the ON clause of the
         join.  If left at ``None``, :meth:`.FromClause.join` will attempt to
         join the two tables based on a foreign key relationship.

        :param isouter: if True, render a LEFT OUTER JOIN, instead of JOIN.

        :param full: if True, render a FULL OUTER JOIN, instead of JOIN.

         .. versionadded:: 1.1

        .. seealso::

            :meth:`.FromClause.join` - method form, based on a given left side

            :class:`.Join` - the type of object produced

        """
    return cls(left, right, onclause, isouter, full)


def validate_region_file(filename: str):
    """Checks if a file is a region file."""
    if filename[-4:].lower() != '.cnt' and filename[-4:].lower() != '.reg':
        raise ValueError('%s Failed validation: Not a region file' % filename)


def wanted(zelf, want):
    """ whether an object is desired. """
    for key, value in want.items():
        if key == 'format':
            continue
        if key not in zelf:
            continue
        if value.startswith('-'):
            continue
        if value not in str(zelf[key]):
            return False
    return True


@staticmethod
def _wrap_encode_items(items):
    """Return `items` encoded as bytes.

        Parameters
        ----------
        items : list of PDU items
            The items to encode.

        Returns
        -------
        bytes
            The encoded items.
        """
    bytestream = bytes()
    for item in items:
        bytestream += item.encode()
    return bytestream


def search_products_as_admin(AcceptLanguage=None, PortfolioId=None, Filters
    =None, SortBy=None, SortOrder=None, PageToken=None, PageSize=None,
    ProductSource=None):
    """
    Retrieves summary and status information about all products created within the caller's account. If a portfolio ID is provided, this operation retrieves information for only those products that are associated with the specified portfolio.
    See also: AWS API Documentation

    :example: response = client.search_products_as_admin(
        AcceptLanguage='string',
        PortfolioId='string',
        Filters={
            'string': [
                'string',
            ]
        },
        SortBy='Title'|'VersionCount'|'CreationDate',
        SortOrder='ASCENDING'|'DESCENDING',
        PageToken='string',
        PageSize=123,
        ProductSource='ACCOUNT'
    )

    :type AcceptLanguage: string
    :param AcceptLanguage: The language code to use for this operation. Supported language codes are as follows:
            'en' (English)
            'jp' (Japanese)
            'zh' (Chinese)
            If no code is specified, 'en' is used as the default.

    :type PortfolioId: string
    :param PortfolioId: The portfolio identifier.

    :type Filters: dict
    :param Filters: The list of filters with which to limit search results. If no search filters are specified, the output is all the products to which the administrator has access.
            (string) --
            (list) --
            (string) --

    :type SortBy: string
    :param SortBy: The sort field specifier. If no value is specified, results are not sorted.

    :type SortOrder: string
    :param SortOrder: The sort order specifier. If no value is specified, results are not sorted.

    :type PageToken: string
    :param PageToken: The page token of the first page retrieved. If null, this retrieves the first page of size PageSize .

    :type PageSize: integer
    :param PageSize: The maximum number of items to return in the results. If more results exist than fit in the specified PageSize , the value of NextPageToken in the response is non-null.

    :type ProductSource: string
    :param ProductSource: Access level of the source of the product.

    :rtype: dict
    :return: {
        'ProductViewDetails': [
            {
                'ProductViewSummary': {
                    'Id': 'string',
                    'ProductId': 'string',
                    'Name': 'string',
                    'Owner': 'string',
                    'ShortDescription': 'string',
                    'Type': 'CLOUD_FORMATION_TEMPLATE',
                    'Distributor': 'string',
                    'HasDefaultPath': True|False,
                    'SupportEmail': 'string',
                    'SupportDescription': 'string',
                    'SupportUrl': 'string'
                },
                'Status': 'AVAILABLE'|'CREATING'|'FAILED',
                'ProductARN': 'string',
                'CreatedTime': datetime(2015, 1, 1)
            },
        ],
        'NextPageToken': 'string'
    }

    """
    pass


@classmethod
def metadata(cls, val):
    """
        Create an instance of this class set to the ``metadata`` tag with value
        ``val``.

        :param Metadata val:
        :rtype: MetadataV2
        """
    return cls('metadata', val)


def _unquote(s):
    """Helper func that strips single and double quotes from inside strings"""
    return s.replace('"', '').replace("'", '')


def peek(parser, kind):
    """Determines if the next token is of a given kind"""
    return parser.token.kind == kind


def recommend_kernel_params(binsize):
    """
    Recommned kernel parameters for the
    standard convolution kernels, 'donut', etc
    same as in Rao et al 2014

    Parameters
    ----------
    binsize : integer
        binsize of the provided cooler

    Returns
    -------
    (w,p) : (integer, integer)
        tuple of the outer and inner kernel sizes
    """
    if binsize > 28000:
        raise ValueError(
            'Provided cooler has resolution {} bases, which is too coarse for analysis.'
            .format(binsize))
    elif binsize >= 18000:
        w, p = 3, 1
    elif binsize >= 8000:
        w, p = 5, 2
    elif binsize >= 4000:
        w, p = 7, 4
    else:
        raise ValueError(
            'Provided cooler has resolution {} bases, which is too fine for analysis.'
            .format(binsize))
    return w, p


@classmethod
def parse(cls, json):
    """Parse a json dict and return the correct subclass of :class:`ValidatorEffect`.

        It uses the 'effect' key to determine which :class:`ValidatorEffect` to instantiate.
        Please refer to :class:`enums.ValidatorEffectTypes` for the supported effects.

        :param json: dictionary containing the specific keys to parse into a :class:`ValidatorEffect`
        :type json: dict
        :returns: the instantiated subclass of :class:`ValidatorEffect`
        :rtype: :class:`ValidatorEffect` or subclass
        """
    effect = json.get('effect')
    if effect:
        from pykechain.models.validators import effects
        effect_implementation_classname = effect[0].upper() + effect[1:]
        if hasattr(effects, effect_implementation_classname):
            return getattr(effects, effect_implementation_classname)(json=json)
        else:
            raise Exception('unknown effect in json')
    raise Exception("Effect unknown, incorrect json: '{}'".format(json))


def parse_player_name(data: dict) ->str:
    """Parse the player name from the data payload."""
    return data['name']


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


def _record_running(job):
    """
    Record that a job is running
    """
    job.status = 'running'
    from autonomie_base.models.base import DBSESSION
    DBSESSION().merge(job)


def keys():
    """Return sequence of key elements."""


@classmethod
def from_config(cls, config):
    """Creates a layer from its config.

        This method is the reverse of `get_config`,
        capable of instantiating the same layer from the config
        dictionary. It does not handle layer connectivity
        (handled by Network), nor weights (handled by `set_weights`).

        # Arguments
            config: A Python dictionary, typically the
                output of get_config.

        # Returns
            A layer instance.
        """
    return cls(**config)


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


def _count_front(s: str) ->int:
    """Count the number of leading dashes on a string."""
    for position, element in enumerate(s):
        if element != '-':
            return position


@staticmethod
def _transform_member(member, feature_compatibility):
    """Transforms a member into an object that will

            be processed by the templating system
        """
    return {'id': member.id, 'address': member.ip_address, 'protocol_port':
        member.protocol_port, 'weight': member.weight, 'enabled': member.
        enabled, 'subnet_id': member.subnet_id, 'operating_status': member.
        operating_status, 'monitor_address': member.monitor_address,
        'monitor_port': member.monitor_port, 'backup': member.backup}


def parse_percent(percent_input: str) ->float:
    """Takes a percent string from the config and turns it into a float."""
    percent_input = percent_input.rstrip('%')
    try:
        return float(percent_input)
    except ValueError:
        raise ValueError("should be in format '0-x%'")


def getChildrenNodes():
    """
        Return a sequence of children nodes if the node is expanded.
        """


def test(predictions, labels, k=1):
    """
    Return precision and recall modeled after fasttext's test
    """
    precision = 0.0
    nexamples = 0
    nlabels = 0
    for prediction, labels in zip(predictions, labels):
        for p in prediction:
            if p in labels:
                precision += 1
        nexamples += 1
        nlabels += len(labels)
    return precision / (k * nexamples), precision / nlabels


def tanh_prime(weighted_sum, activations):
    """
    Returns the derivative of tanh w.r.t layer's weighted sum.
    """
    return 1 - activations ** 2


def get_lig_properties_elt(bs_elt):
    """
    lig_properties xml element
    """
    return next(bs_elt.iterchildren('lig_properties'))


def invert_dict(old_dict):
    """
        Helper function for assign_colors_to_clusters().
    """
    inv_dict = {}
    for k, v in old_dict.items():
        inv_dict[v] = inv_dict.get(v, [])
        inv_dict[v].append(k)
    return inv_dict


def select_from_key(key, d):
    """
    Return element of the dict to do the insertion on. If it is foo.1.bar, it
    will return d["foo"][1]. If it is only foo, it will return d directly.
    """
    path = key.split('.')[:-1]
    tmp_d = d
    for p in path:
        if isinstance(tmp_d, (list, tuple)):
            tmp_d = tmp_d[int(p)]
        else:
            tmp_d = tmp_d[p]
    return tmp_d


def has_migrations(engine):
    """Returns true if at least one data row can be migrated.

    There are rows left to migrate if meta_data column has
    {"backend": "...."}

    Note: This method can return a false positive if data migrations
    are running in the background as it's being called.
    """
    sql_query = (
        'select meta_data from image_locations where INSTR(meta_data, \'"backend":\') > 0'
        )
    if engine.name == 'postgresql':
        sql_query = (
            'select meta_data from image_locations where POSITION(\'"backend":\' IN meta_data) > 0'
            )
    with engine.connect() as con:
        metadata_backend = con.execute(sql_query)
        if metadata_backend.rowcount > 0:
            return True
    return False


def _io_in_adder(parser, config_dict, *args):
    """
    Add input options to the parser
    """
    in_arg_set = set(args)
    if 'io_in' in in_arg_set:
        group = parser.add_argument_group('Input Options')
        io_opt_list = ['csv', 'table', 'tsv', 'json', 'header', 'noheader']
        msg = 'Overwrite input column names with this list'
        group.add_argument('--names', nargs='+', type=str, dest='names',
            metavar='name', help=msg)
        default_for_input = [config_dict['io_input_type'], config_dict[
            'io_input_header']]
        msg = 'Must be one of {}'.format(repr(io_opt_list))
        group.add_argument('-i', '--input_options', nargs='+', type=str,
            dest='input_options', metavar='option', default=
            default_for_input, choices=io_opt_list, help=msg)


def get_anchor_name(name):
    """get anchor from a string"""
    if name.isdigit():
        return 'year' + name
    else:
        return name.lower().replace(' ', '-')


def print_last_lines(file, number):
    """prints last lines of a file"""
    print(f'<=== {file} ===>')
    with open(file, 'r') as infile:
        for line in infile.readlines()[number:]:
            print(line, end='')
        print()


def split_template_args(s, open_brace='<', close_brace='>', separator=','):
    """Takes a string with template specialization and returns a list
    of the argument values as strings."""
    targs = []
    ns = s.split(open_brace, 1)[-1].rsplit(close_brace, 1)[0].split(separator)
    count = 0
    targ_name = ''
    for n in ns:
        count += int(open_brace in n)
        count -= int(close_brace in n)
        targ_name += n
        if count == 0:
            targs.append(targ_name.strip())
            targ_name = ''
    return targs


def decruft_url(url):
    """Attempt to remove extraneous characters from a given URL and return it."""
    url = url.split('?')[0].split('#')[0]
    return url


def merge_kwargs(defaults: dict, kwargs: dict):
    """
    Merge ``defaults`` into ``kwargs`` and return ``kwargs``.

    Intended usage is for setting defaults to ``**kwargs`` when the caller did not
    provide a given argument, but making sure not to overwrite the caller's explicit
    argument when specified.

    For example::

        >>> merge_kwargs({"a": 1, "b": 2}, {})
        {'a': 1, 'b': 2}
        >>> merge_kwargs({"a": 1, "b": 2}, {"a": 3})
        {'a': 3, 'b': 2}

    Entries in the ``defaults`` parameter only get included of **not** present in the
    ``kwargs`` argument.  This is to facilitate something like this::

        from ci_exec import merge_kwargs

        # The function we want to customize the defaults for.
        def func(alpha=1, beta=2):
            return alpha + beta

        # Example: default to alpha=2, leave beta alone.
        def custom(**kwargs):
            return func(**merge_kwargs({"alpha": 2}, kwargs))

        # custom()                == 4
        # custom(alpha=0)         == 2
        # custom(beta=0)          == 2
        # custom(alpha=0, beta=0) == 0

    Parameters
    ----------
    defaults : dict
        The dictionary of defaults to add to ``kwargs`` if not present.

    kwargs : dict
        The dictionary to merge ``defaults`` into.

    Return
    ------
    dict
        The ``kwargs`` dictionary, possibly with values from ``defaults`` injected.
    """
    for key, val in defaults.items():
        if key not in kwargs:
            kwargs[key] = val
    return kwargs


def init_http_logger(level=None):
    """initialize logging, otherwise you will not see anything from requests"""
    import logging
    import httplib
    logging.basicConfig()
    if level == 'debug':
        httplib.HTTPConnection.debuglevel = 1
        logging.getLogger().setLevel(logging.DEBUG)
        requests_log = logging.getLogger('requests.packages.urllib3')
        requests_log.setLevel(logging.DEBUG)
        requests_log.propagate = True


def _resolveLinkedAxis(axis):
    """Follow a chain of axis function dependencies."""
    loopcheck = set()
    while axis is not None and axis.isLinked():
        loopcheck.add(axis)
        axis = axis.getLinkedAxis()
        if axis in loopcheck:
            return None
    return axis


def align_fields(fields, titles, title2index):
    """ Make sure score fields for individual passage are aligned with summary result fields by inserting empties """
    ret = len(title2index) * ['']
    for field, title in zip(fields, titles):
        ret[title2index[title]] = field
    return ret


def is_dict(obj):
    """
    Checks if a given sequence is a dictionary.

    Parameters
    ----------
    obj : object
        The input argument.

    Returns
    -------
    test result : bool
        The test result of whether seq is a dictionary or not.

    >>> is_dict([1, 2, 3])
    False

    >>> is_dict((1, 2, 3))
    False

    >>> is_dict({'one': 1, 'two': 2, 'three': 3})
    True

    >>> is_dict('foobar')
    False
    """
    return isinstance(obj, dict)


def new_sgmt_from_points(p1=None, p2=None, p3=None):
    """Create sgmt from points.

    :param p1: survey origin, (ilno, xlno, crsx, crsy)
    :type p1: tuple
    :param p2: survey corner, (ilno, xlno, crsx, crsy)
    :type p2: tuple
    :param p3: survey corner, (ilno, xlno, crsx, crsy)
    :type p3: tuple
    :return: a survey object
    :rtype: :class:`~ezcad.gosurvey.survey.Survey`
    """
    if p1 is None:
        p1 = 1, 1, 0.0, 0.0
    if p2 is None:
        p2 = 1, 11, 0.0, 10.0
    if p3 is None:
        p3 = 11, 1, 10.0, 0.0
    dict_sgmt = {'P1_ILNO': p1[0], 'P1_XLNO': p1[1], 'P1_CRSX': p1[2],
        'P1_CRSY': p1[3], 'P2_ILNO': p2[0], 'P2_XLNO': p2[1], 'P2_CRSX': p2
        [2], 'P2_CRSY': p2[3], 'P3_ILNO': p3[0], 'P3_XLNO': p3[1],
        'P3_CRSX': p3[2], 'P3_CRSY': p3[3]}
    return dict_sgmt


def absolute_output_offsets_to_relative(off):
    """
    Relative offsets, prev + cur = next.
    Helps with varint encoding size.
    :param off:
    :return:
    """
    if len(off) == 0:
        return off
    res = sorted(off)
    for i in range(len(off) - 1, 0, -1):
        res[i] -= res[i - 1]
    return res


def _mangle_name(name):
    """Return mangled field name.

    Mangled field names have some name prefixes replaced with others (see
    mapping in code). This is to allow some field names with special chars in
    them to be defined via Schema class attributes.

    """
    mapping = dict(at='@', dash='-', dot='.', hash='#', plus='+', nil='')
    if '__' not in name:
        return name
    before, after = name.split('__', 1)
    if before not in mapping:
        return name
    return mapping[before] + after


@staticmethod
def dilution_space_plateau(doseweight, molmass, doseenrichment,
    plateauenrichment, background):
    """Calculate a dilution space using the plateau method.
           :param doseweight: weight of the does in grams
           :param molmass: moleular mass of the dose in grams/mol
           :param doseenrichment: enrichment of the dose in ppm
           :param plateauenrichment: enrichment of the plateau urine measurement as a ratio
           :param background: enrichment of the background urine measurement as a ratio
           :return: dilution space calculated by the plateau method in mol
        """
    return doseweight / molmass * (doseenrichment - plateauenrichment) / (
        plateauenrichment - background)


def user_is_valid(user):
    """
    User object validation
    """
    if user is None:
        return False
    if not user.get('id', 0):
        return False
    return True


@classmethod
def link(cls, other, share_redraw_state=True):
    """Create a new shape that shares its data with a source shape.

        Common values that are set in `other` will be set in this shape.

        :param other: Other shape to link this one to
        :param share_redraw_state: If True, share the redrawing state (for dynamic visualization backends) with `other`
        """
    result = cls.copy(other)
    result._attributes = other._attributes
    if share_redraw_state:
        result._dirty_attributes = other._dirty_attributes
    return result


def update_portfolio(AcceptLanguage=None, Id=None, DisplayName=None,
    Description=None, ProviderName=None, AddTags=None, RemoveTags=None):
    """
    Updates the specified portfolio's details. This operation will not work with a product that has been shared with you.
    See also: AWS API Documentation

    :example: response = client.update_portfolio(
        AcceptLanguage='string',
        Id='string',
        DisplayName='string',
        Description='string',
        ProviderName='string',
        AddTags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ],
        RemoveTags=[
            'string',
        ]
    )

    :type AcceptLanguage: string
    :param AcceptLanguage: The language code to use for this operation. Supported language codes are as follows:
            'en' (English)
            'jp' (Japanese)
            'zh' (Chinese)
            If no code is specified, 'en' is used as the default.

    :type Id: string
    :param Id: [REQUIRED]
            The identifier of the portfolio for the update request.

    :type DisplayName: string
    :param DisplayName: The name to use for display purposes.

    :type Description: string
    :param Description: The updated text description of the portfolio.

    :type ProviderName: string
    :param ProviderName: The updated name of the portfolio provider.

    :type AddTags: list
    :param AddTags: Tags to add to the existing list of tags associated with the portfolio.
            (dict) --Key/value pairs to associate with this provisioning. These tags are entirely discretionary and are propagated to the resources created in the provisioning.
            Key (string) -- [REQUIRED]The ProvisioningArtifactParameter.TagKey parameter from DescribeProvisioningParameters .
            Value (string) -- [REQUIRED]The esired value for this key.

    :type RemoveTags: list
    :param RemoveTags: Tags to remove from the existing list of tags associated with the portfolio.
            (string) --

    :rtype: dict
    :return: {
        'PortfolioDetail': {
            'Id': 'string',
            'ARN': 'string',
            'DisplayName': 'string',
            'Description': 'string',
            'CreatedTime': datetime(2015, 1, 1),
            'ProviderName': 'string'
        },
        'Tags': [
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    }

    """
    pass


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
        {
            "properties": {
                "description_analyzed": {
                  "type": "text",
                  "index": true
                }
           }
        } """
    return {'items': mapping}


@staticmethod
def _parse_layer(layer, return_wms_name=False):
    """ Helper function for parsing Geopedia layer name. If WMS name is required and wrong form is given it will
        return a string with 'ttl' at the beginning. (WMS name can also start with something else, e.g. only 't'
        instead 'ttl', therefore anything else is also allowed.) Otherwise it will parse it into a number.
        """
    if not isinstance(layer, (int, str)):
        raise ValueError(
            "Parameter 'layer' should be an integer or a string, but {} found"
            .format(type(layer)))
    if return_wms_name:
        if isinstance(layer, int) or layer.isdigit():
            return 'ttl{}'.format(layer)
        return layer
    if isinstance(layer, str):
        stripped_layer = layer.lstrip('tl')
        if not stripped_layer.isdigit():
            raise ValueError(
                "Parameter 'layer' has unsupported value {}, expected an integer"
                .format(layer))
        layer = stripped_layer
    return int(layer)


@classmethod
def _convert_to_protection(cls, protection_dict):
    """
        Convert ``protection_dict`` to an openpyxl v2 Protection object.
        Parameters
        ----------
        protection_dict : dict
            A dict with zero or more of the following keys.
                'locked'
                'hidden'
        Returns
        -------
        """
    from openpyxl.styles import Protection
    return Protection(**protection_dict)


def load_subs(hub):
    """
    Load up the needed subs
    """
    hub.pop.sub.add(dyne_name='artifact')
    hub.pop.sub.add(dyne_name='roster')
    hub.pop.sub.add(dyne_name='tunnel')
    hub.pop.sub.add(dyne_name='rend')


def _get_qpoint_pos(pos):
    """Return the coordinates of a QPointF object."""
    return pos.x(), pos.y()


def p_namespace(t):
    """namespace : NAMESPACE ID LBRACE specification RBRACE"""


def import_documentation_parts(restApiId=None, mode=None, failOnWarnings=
    None, body=None):
    """
    See also: AWS API Documentation

    :example: response = client.import_documentation_parts(
        restApiId='string',
        mode='merge'|'overwrite',
        failOnWarnings=True|False,
        body=b'bytes'|file
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            [Required] The identifier of an API of the to-be-imported documentation parts.

    :type mode: string
    :param mode: A query parameter to indicate whether to overwrite (OVERWRITE ) any existing DocumentationParts definition or to merge (MERGE ) the new definition into the existing one. The default value is MERGE .

    :type failOnWarnings: boolean
    :param failOnWarnings: A query parameter to specify whether to rollback the documentation importation (true ) or not (false ) when a warning is encountered. The default value is false .

    :type body: bytes or seekable file-like object
    :param body: [REQUIRED]
            [Required] Raw byte array representing the to-be-imported documentation parts. To import from a Swagger file, this is a JSON object.

    :rtype: dict
    :return: {
        'ids': [
            'string',
        ],
        'warnings': [
            'string',
        ]
    }

    :returns:
    (string) --

    """
    pass


def lazy_pool(pool, function, args, disable_return=True):
    """
    Run pool lazily, suitable when the argument is a generator.

    This function is designed to work mostly with generators So by default it returns None. The reason for this is
    because generator are usually used for very long iterables, and storing all returns would exhaust memory.

    Args:
        pool: Pool instance.
        function: Function to be executed in the pool.
        args: Function arguments list.
        disable_return: Whether to store and return or not. When the argument is a generator, it exhaust memory.

    Returns:
        the return of the function, or None when disable_return=True
    """
    result = pool.imap_unordered(function, args)
    i = 0
    return_list = []
    while True:
        try:
            row = result.next()
        except StopIteration:
            break
        if not disable_return:
            return_list.append(row)
        i += 1
        print(f'\r{i} loaded.')
    return return_list


def enchurch(n):
    """Encode Church numerals"""
    assert n >= 0
    return '(lambda f:(lambda x:{}(x){}))'.format('(f' * n, ')' * n)


def select_army(action, action_space, select_add):
    """Select the entire army."""
    del action_space
    action.action_ui.select_army.selection_add = select_add


def is_downloadable(url, formats):
    """Given one url and a list of formats,
    check whether the link leads to file we want to download."""
    return str(url).endswith(tuple(formats)) or str(url).endswith('gifv'
        ) and 'mp4' in tuple(formats)


def replace_with_separator(text, separator, regexs):
    """Get text with replaced separator if provided regular expressions were matched.

    Parameters
    ----------
    text : str
        Input text.
    separator : str
        The separator between words to be replaced.
    regexs : list of `_sre.SRE_Pattern`
        Regular expressions used in processing text.

    Returns
    -------
    str
        Text with replaced separators.

    """
    replacement = '\\1' + separator + '\\2'
    result = text
    for regex in regexs:
        result = regex.sub(replacement, result)
    return result


def data_ptr(array):
    """Given an Array, get a Buffer that starts at the right offset

    This fails unless ``array.offset`` is a multiple of
    ``queue.device.mem_base_addr_align``, which is rare, so this isn't really
    a good function.
    """
    if array.offset:
        return array.base_data.get_sub_region(array.offset, 1)
    else:
        return array.base_data


def linear(x, param):
    """Linear function.

    f = param[0] * x + param[1] .

    Parameters:
        x (np.ndarray):    Positions at which to evaluate function.
        param (np.ndarray):    Necessary parameters.

    Returns:
        (np.ndarray):    Values of function at x.

    """
    return param[0] * x + param[1]


@classmethod
def cls(cls, entity_name, key):
    """Returns the object class based on the entity_name.

        Parameters
        ----------
        entity_name: str
            The help scout object name. E.g.: conversation, mailbox.
        key: str
            The key under which the object's dictionary is contained in the
            API response.
            E.g.: conversations, mailboxes.

        Returns
        -------
        type: The object's class
        """
    if '/' in entity_name:
        parts = entity_name.rsplit('/')
        entity_name = parts[-2] if len(parts) % 2 == 0 else parts[-1]
    if '/' in key:
        parts = key.rsplit('/')
        key = parts[-2] if len(parts) % 2 == 0 else parts[-1]
    plural_letters = -2 if entity_name.endswith('es'
        ) else -1 if entity_name.endswith('s') else None
    class_name = entity_name.capitalize()[:plural_letters]
    existing_class = globals().get(class_name)
    if existing_class is not None:
        return existing_class
    globals()[class_name] = cls = type(class_name, (cls,), {'key': key})
    return cls


def query_ebv(ra, dec, size=2, thresh=0.25, verbose=False):
    """
    Take ra,dec and return the E(B-V) number
    URL query, see https://irsa.ipac.caltech.edu/applications/DUST
    """
    import urllib2
    import xmltodict
    url = 'https://irsa.ipac.caltech.edu/cgi-bin/DUST/nph-dust?'
    url += 'locstr=%.2f+%.2f+equ+j2000' % (ra, dec)
    if size < 2:
        size = 2
    if size > 37.5:
        size = 37.5
    url += '&regSize=%.2f' % size
    _file = urllib2.urlopen(url)
    data = _file.read()
    _file.close()
    _dict = xmltodict.parse(data)
    _ebv = _dict['results']['result'][0]['statistics']['meanValueSFD']
    ebvalue = float(_ebv.split('(mag)')[0])
    if ebvalue < thresh:
        if verbose:
            print('ra=%.2f dec=%.2f:\tebv=%.2f\tOK' % (ra, dec, float(_ebv.
                split('(mag)')[0])))
        return ebvalue
    else:
        if verbose:
            print('ra=%.2f dec=%.2f:\tebv=%.2f\tNo' % (ra, dec, float(_ebv.
                split('(mag)')[0])))
        return


def _set_lim(data=[], dmin=None, dmax=None, bins=2):
    """It sets the limits of the plot of a list of data depending on the number of bins of the plot and whatever or not the limits are explicitly provided. It is used by the 'set_xlim' and 'set_ylim' functions."""
    bins_offset = 0
    if dmin == None:
        bins_offset += 0.5
        if data == []:
            d_min = 0
        else:
            d_min = min(data)
    else:
        d_min = dmin
    if dmax == None:
        bins_offset += 0.5
        if data == []:
            d_max = 0
        else:
            d_max = max(data)
    else:
        d_max = dmax
    if bins == 1:
        bins_offset = 0.5
    if d_min == d_max:
        span = 0.1 * d_min
    else:
        span = (d_max - d_min) / (bins - bins_offset)
    minimum = d_min
    if dmin == None:
        minimum -= 0.5 * span
    maximum = d_max
    if dmax == None:
        maximum += 0.5 * span
    return minimum, maximum


@staticmethod
def _req_spec_msg_to_str(msg):
    """
        Inverse of :meth:`Python._req_spec_to_msg`.

        Parameters
        ----------
        msg : PythonRequirementEnvironmentBlob

        Returns
        -------
        req_spec : str

        """
    return '{}{}{}'.format(msg.library, msg.constraint, '{}.{}.{}{}'.format
        (msg.version.major, msg.version.minor, msg.version.patch, msg.
        version.suffix))


def coord_to_im(xyz, shape='square'):
    """Return image from xyz coordinates as an nxm matrix"""
    z = xyz[:, (2)]
    if shape == 'square':
        l = int(xyz.shape[0] ** 0.5)
        image = z.reshape(l, l).T
        return image
    y, x = shape
    image = z.reshape(y, x)
    return image


def human_filesize(number):
    """
    Human readable file size unit
    :param number: how many bytes
    :return: (num, unit)
    """
    units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
    for unit in units:
        if number < 10000 or unit == 'YB':
            return number, unit
        else:
            number = number / 1024.0


def _submit_args_to_dict(firmware='', profile=''):
    """Return kwargs for this arguments. Remove empty values"""
    kwargs = {}
    if firmware:
        kwargs['firmware'] = firmware
    if profile:
        kwargs['profile'] = profile
    return kwargs


def choose(question, choices):
    """Ask user to choose from a list of enumerated choices."""
    print('\n%s\n' % question)
    for number, choice in enumerate(choices, start=1):
        print('  %d) %s' % (number, str(choice)))
    user_choice = input('\n> ')
    return choices[int(user_choice) - 1]


def render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


def humanize_bytes(num, suffix='B', si_prefix=False, round_digits=2) ->str:
    """Return a human friendly byte representation.

    Modified from: https://stackoverflow.com/questions/1094841/1094933#1094933
    """
    div = 1000.0 if si_prefix else 1024.0
    unit_suffix = 'i' if si_prefix else ''
    for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']:
        if abs(num) < div:
            return f'{num:3.{round_digits}f} {unit}{unit_suffix}{suffix}'
        num /= div
    return f'{num:3.{round_digits}f} Y{unit_suffix}{suffix}'


def interval_set_to_string(intervals, separator=' '):
    """
    Convert interval set to strings:

    >>> interval_set_to_string([(1, 2), (5, 5), (10, 50)])
    '1-2 5 10-50'
    """
    res = ''
    for begin, end in intervals:
        if begin == end:
            res += separator + str(begin)
        else:
            res += separator + '{}-{}'.format(begin, end)
    return res.strip(separator)


def neg_edges(data):
    """
    Negate edge half (non-middle) of spectra.
    """
    data[(...), :int(data.shape[-1] * 1.0 / 4)] = -data[(...), :int(data.
        shape[-1] * 1.0 / 4)]
    data[(...), int(data.shape[-1] * 3.0 / 4):] = -data[(...), int(data.
        shape[-1] * 3.0 / 4):]
    return data


@staticmethod
def fromhex(obj: str) ->bytes:
    """Static method to create a bytes object from a string.

        Parameters
        ----------
        obj : str
            String object to be converted to bytes.

        Returns
        -------
        bytes
            The string object as bytes.
        """
    return bytes.fromhex(obj)


def shift(list, default):
    """
    Shift items off the front of the `list` until it is empty, then return
    `default`.
    """
    try:
        return list.pop(0)
    except IndexError:
        return default


@classmethod
def clear_global(cls):
    """
        Clear stored user agent string

        Returns:
            None

        """
    cls.user_agent = None


def add(alias):
    """Add the given address as an acceptable aliases for posting.

        :param alias: The email address to accept as a recipient for implicit
            destination posting purposes.  The alias is coerced to lower
            case.  If `alias` begins with a '^' character, it is interpreted
            as a regular expression, otherwise it must be an email address.
        :type alias: string
        :raises ValueError: when the alias neither starts with '^' nor has an
            '@' sign in it.
        """


def _format_rule_default_json(default):
    """Create a json node from policy.RuleDefault or policy.DocumentedRuleDefault.

    :param default: A policy.RuleDefault or policy.DocumentedRuleDefault object
    :returns: A string containing a json representation of the RuleDefault
    """
    return '"%(name)s": "%(check_str)s"' % {'name': default.name,
        'check_str': default.check_str}


def handle_create(namespace, repository):
    """handle create subcommand"""
    repository.create(namespace.name, namespace.description)


def Z_5_func(*, η_O, η_A, η_H, b_r, b_θ, b_φ, C):
    """
    Compute the value of the variable Z_5
    """
    return η_O + η_A * (1 - b_r ** 2) + C * (η_H * b_θ - η_A * b_r * b_φ)


def argsort(input, dim, descending):
    """Return the indices that would sort the input along the given dim.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    dim : int
        The dim to sort along.
    descending : bool
        Controls the sorting order (False: ascending, True: descending)

    Returns
    -------
    Tensor
        A framework-specific tensor.
    """


def auto_self_params(args: dict):
    """
    Typically call as the first line of __init__ with a parameter of locals().

    This will add all of the parameters of __init__ as attributes of self.
    The args parameter must be a dictionary which must include `self` which
    must be a  class object.  The built in locals gives this with all of the
    local names, including parameters, defined.
    """
    assert isinstance(args, dict), 'Must be called with dict as a parameter'
    theobj = args.pop('self', None)
    assert theobj is not None, "Class must specify 'self'"
    assert hasattr(theobj, '__class__') and hasattr(theobj, '__init__'
        ), 'Must be called in a class __init__ method'
    for key, val in args.items():
        setattr(theobj, key, val)


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


@staticmethod
def get_tags(instance):
    """
        Returns a dictionary of tags
        """
    return instance['tags']


def display_masses(corde, screen, pygame):
    """
    affichage de la corde à l'aide du module pyagame
    """
    y = screen.get_size()[1]
    color = 0, 0, 0
    for p in corde.list:
        pygame.draw.circle(screen, color, (int(p.x), int(y - p.y)), int(p.m +
            1))
    for i in range(0, len(corde.list) - 1):
        pygame.draw.line(screen, color, (int(corde.list[i].x), int(y -
            corde.list[i].y)), (int(corde.list[i + 1].x), int(y - corde.
            list[i + 1].y)))


def unwrap_pairwise(y):
    """given a y that may contain pairwise marginals, yield plain y."""
    if isinstance(y, tuple):
        return y[0]
    return y


def p_switch_case_list(p):
    """switch_case_list : LBRACE case_list RBRACE
                        | LBRACE SEMI case_list RBRACE"""
    if len(p) == 4:
        p[0] = p[2]
    else:
        p[0] = p[3]


def bake_from_cache():
    """Bake from cache

    """
    pass


def build_new_graph(figure, figure_structure, graph_position, graph_layout,
    dataframe):
    """Builds a new matplotlib graph in the provided matplotlib
    figure thanks to the provided parameters

    Input:
    ------
    figure : matplotlib object
    figure_structure : tuple of 2 integers
    graph_position : integer
    graph_layout : nested object
    dataframe : pandas data frame
    """
    subplot = figure.add_subplot(*figure_structure, graph_position)
    if 'x_label' in graph_layout:
        subplot.set_xlabel(graph_layout['x_label'])
    if 'y_label' in graph_layout:
        subplot.set_ylabel(graph_layout['y_label'])
    if 'title' in graph_layout:
        subplot.set_title(graph_layout['title'], fontweight='bold')
    if graph_layout['x_var'] in dataframe.keys():
        for curve_layout in graph_layout['curves']:
            if curve_layout['var'] in dataframe.keys():
                if 'legend' in curve_layout:
                    curve_legend = curve_layout['legend']
                else:
                    curve_legend = curve_layout['var']
                subplot.plot(dataframe[graph_layout['x_var']], dataframe[
                    curve_layout['var']], label=curve_legend)
    subplot.legend(loc='upper right')


def sample(size: int=1):
    """Use mouse to sample a color in current image

    :param size: Sample Size
    :type size: int
    """
    pass


def get_max_field_length(fields):
    """Get the length of the longest field in the dictionary ``fields``.

    :param dict fields: A dictionary to search for the longest field.
    """
    return max(map(len, fields))


def _text_file_with_path(sc, path):
    """Return an RDD that yields (path, line) for each line in the file.

    *path* must be a single path, not a comma-separated list of paths
    """
    from pyspark.sql import SparkSession
    from pyspark.sql import functions as F
    spark = SparkSession(sc)
    df = spark.read.text(path).select([F.input_file_name().alias(
        'input_file_name'), F.col('value')])
    return df.rdd.map(lambda row: (row.input_file_name, row.value if
        isinstance(row.value, bytes) else row.value.encode('utf_8')))


def _compute_ngrams_py(word, min_n, max_n):
    """Get the list of all possible ngrams for a given word.
    Parameters
    ----------
    word : str
        The word whose ngrams need to be computed.
    min_n : int
        Minimum character length of the ngrams.
    max_n : int
        Maximum character length of the ngrams.
    Returns
    -------
    list of str
        Sequence of character ngrams.
    """
    BOW, EOW = '<', '>'
    extended_word = BOW + word + EOW
    ngrams = []
    for ngram_length in range(min_n, min(len(extended_word), max_n) + 1):
        for i in range(0, len(extended_word) - ngram_length + 1):
            ngrams.append(extended_word[i:i + ngram_length])
    return ngrams


@classmethod
def translate(cls, val):
    """Translate each of the standard json/yaml types to appropiate objects."""
    if val is None:
        return cls.translate_none(val)
    elif isinstance(val, str):
        return cls.translate_str(val)
    elif isinstance(val, bool):
        return cls.translate_bool(val)
    elif isinstance(val, int):
        return cls.translate_int(val)
    elif isinstance(val, float):
        return cls.translate_float(val)
    elif isinstance(val, dict):
        return cls.translate_dict(val)
    elif isinstance(val, list):
        return cls.translate_list(val)
    return cls.translate_escaped_str(val)


def set_database_condition(query: str, database: str) ->str:
    """Replaces a placeholder in a query with a condition restricting results to a certain database"""
    if not database:
        modified_query = query.replace(':DB_CONDITION', 'TRUE')
    else:
        modified_query = query.replace(':DB_CONDITION', 'db.name = :database')
    return modified_query


def _par_fit(power_spectrum, fg):
    """Helper function for running in parallel."""
    fg._fit(power_spectrum=power_spectrum)
    return fg._get_results()


@classmethod
def paper_doc_deleted(cls, val):
    """
        Create an instance of this class set to the ``paper_doc_deleted`` tag
        with value ``val``.

        :param PaperDocDeletedType val:
        :rtype: EventType
        """
    return cls('paper_doc_deleted', val)


def number_to_string(number):
    """ Converts a number into a string.

    Assumes `number' is a `gmpy.mpz'. """
    tmp = number.binary()
    return tmp[:-1] if tmp[-1] == '\x00' else tmp


def get_met_ids(model):
    """
    This function returns a list of IDs of all metabolites in the model.

    Parameters
    ----------
    model : cobra.core.Model.Model
        A cobra model.

    Returns
    -------
    mets : list
        A list containing all IDs of metabolites in the model.
    """
    mets = []
    for met in model.metabolites:
        mets.append(met.id)
    mets = list(set(mets))
    return mets


@staticmethod
def _should_base64_encode(binary_types, request_mimetype):
    """
        Whether or not to encode the data from the request to Base64

        Parameters
        ----------
        binary_types list(basestring)
            Corresponds to self.binary_types (aka. what is parsed from SAM Template
        request_mimetype str
            Mimetype for the request

        Returns
        -------
            True if the data should be encoded to Base64 otherwise False

        """
    return request_mimetype in binary_types or '*/*' in binary_types


@classmethod
def _info(cls, vlan_id):
    """ Get information about a vlan."""
    return cls.call('hosting.vlan.info', vlan_id)


@staticmethod
def _obj_wrapper(func, x_meas, y_meas, kwargs, p):
    """
        Wrapper function that point to objective function.

        :param func: objective function.
        :param args: positional arguments to pass on to objective function
        :param kwargs: key arguments to pass on to objective function
        :param p: probe parameters used to calculate objective function
        :return: return the calculated objective function.
        """
    return func(p, x_meas, y_meas, **kwargs)


@classmethod
def success(cls, val):
    """
        Create an instance of this class set to the ``success`` tag with value
        ``val``.

        :param Metadata val:
        :rtype: RelocationBatchResultEntry
        """
    return cls('success', val)


def create_rectange_polygon(center: tuple, size_func, colour: str='#BE00FF',
    fill_opacity: float=1):
    """Creates a json describing a rectangle that is sent to Mapbox to be drawn on the request image."""
    size = size_func(center[2])
    tl = [center[1] - size, center[0] + size]
    tr = [center[1] + size, center[0] + size]
    br = [center[1] + size, center[0] - size]
    bl = [center[1] - size, center[0] - size]
    return {'type': 'Feature', 'geometry': {'type': 'Polygon',
        'coordinates': [[tl, tr, br, bl, tl]]}, 'properties': {'stroke':
        colour, 'fill': colour, 'fill-opacity': fill_opacity}}


@classmethod
def uninstall_all(cls, *bloksname):
    """ Search and call the uninstall method for all the uninstalled bloks

        .. warning::

            Use the ``desc order`` to uninstall because we can't uninstall
            a dependancies before

        :param bloksname: list of the blok name to uninstall
        """
    if not bloksname:
        return
    query = cls.query().filter(cls.name.in_(bloksname))
    query = query.order_by(cls.order.desc())
    bloks = query.all()
    if bloks:
        bloks.uninstall()


def list_to_csv(x):
    """Converts a list of str to a comma-separated string."""
    return ','.join(x)


def ringlen():
    """ -> the number of persistent objects in the ring.

        o Only includes items in the ring (no ghosts or p-classes).
        """


def _split_EP_days(hourly_series):
    """
    Splits the hourly series of EP simulations that simulate multiple days in different seasons into specific energyhub time series.
    """
    result1 = hourly_series.head(24)
    result1 = result1.reset_index()
    result2 = hourly_series.tail(24)
    result2 = result2.reset_index()
    return result1, result2


def _messageForError(status: int):
    """
    Return a description string for an HTTP error code
    """
    errors = {(500): 'Internal server error', (503):
        'Service temporarily unavailable', (598): 'Network read timeout error'}
    return errors[status]


def __init__(storage):
    """
        @param storage: Object providing L{IStorage}.
        """


def check(wants, has):
    """
    Check if a desired scope ``wants`` is part of an available scope ``has``.

    Returns ``False`` if not, return ``True`` if yes.

    :example:

    If a list of scopes such as

    ::

        READ = 1 << 1
        WRITE = 1 << 2
        READ_WRITE = READ | WRITE

        SCOPES = (
            (READ, 'read'),
            (WRITE, 'write'),
            (READ_WRITE, 'read+write'),
        )

    is defined, we can check if a given scope is part of another:

    ::

        >>> from provider import scope
        >>> scope.check(READ, READ)
        True
        >>> scope.check(WRITE, READ)
        False
        >>> scope.check(WRITE, WRITE)
        True
        >>> scope.check(READ, WRITE)
        False
        >>> scope.check(READ, READ_WRITE)
        True
        >>> scope.check(WRITE, READ_WRITE)
        True

    """
    if wants & has == 0:
        return False
    if wants & has < wants:
        return False
    return True


def readargs(pid):
    """
    This only works only on unixy systems
    """
    args = None
    try:
        with open(f'/proc/{pid}/cmdline', mode='rb') as fd:
            args = fd.read().decode().split('\x00')[:-1]
    except Exception:
        pass
    return args


@classmethod
def filtered_refgen(cls, name, description, refgen, gene_list):
    """
            Copies from a previous instance of refgen, making sure
            each gene is within gene list
        """
    self = cls.create(name, description, 'RefGen')
    for chrom in refgen.iter_chromosomes():
        self.add_chromosome(chrom)
    self.add_gene(gene_list, refgen=refgen)
    self._build_indices()
    return self


def res_get(res, *path, **kw):
    """
    Get a node's value and access the dict items beneath it.
    """
    val = res.get('value', None)
    if val is None:
        return None
    return val._get(*path, **kw)


def error2str(error):
    """Convert an error to string."""
    if isinstance(error, str):
        return error
    elif isinstance(error, BaseException):
        tname = type(error).__name__
        res = str(error)
        if tname in res:
            return res
        else:
            return ': '.join((tname, res)) if res else tname
    elif isinstance(error, type) and issubclass(error, BaseException):
        return error.__name__
    else:
        prefix = str('unknown error: ')
        cls = error if isinstance(error, type) else type(error)
        tname = cls.__name__
        if cls is error:
            res = tname
        else:
            res = str(error)
            if tname not in res:
                res = str('{}({})').format(tname, res) if res else tname
        return prefix + res


def next_power_of_2(n):
    """ Return next power of 2 greater than or equal to n """
    n -= 1
    shift = 1
    while n + 1 & n:
        n |= n >> shift
        shift *= 2
    return max(4, n + 1)


def track_copy_color():
    """Copy color to all selected tracks

    """
    pass


@staticmethod
def _content_length(line):
    """Extract the content length from an input line."""
    if line.startswith(b'Content-Length: '):
        _, value = line.split(b'Content-Length: ')
        value = value.strip()
        try:
            return int(value)
        except ValueError:
            raise ValueError('Invalid Content-Length header: {}'.format(value))
    return None


def select_all_toggle(invert: bool=False):
    """Toggle selection of all keyframes

    :param invert: Invert
    :type invert: bool
    """
    pass


def gradient_descent_with_momentum(loss_grad, theta, lr=0.001, momentum=0.9,
    maxsteps=100):
    """Gradient descent with momentum.

    Find an approximation of the vector theta that minimizes an
    objective function.

    Parameters
    ----------
    loss_grad : callable
        function computing the gradient of the objective.
    theta : ndarray, shape (n,)
        initial value.
    lr : float, optional
        learning rate.
    momentum : float, optional
        momentum term.
    maxsteps : int, optional
        maximum number of iterations.

    Returns
    -------
    ndarray, shape (n,)
        the final estimate found by the algorithm.

    """
    v = theta.copy()
    for _ in range(maxsteps):
        delta = momentum * v + loss_grad(theta)
        theta -= lr * delta
    return theta


def _f(tag):
    """Remove XML namespaces from text (as introduced by ElementTree)."""
    if tag.startswith('{'):
        return tag[tag.find('}') + 1:]
    else:
        return tag


def bitwise_and(first_value, second_value):
    """Perform a bitwise and operation."""
    return first_value & second_value


def smooth_actor(actor, factor=15):
    """
    Smooth an actor's mesh

    :param actor:
    :param factor:  (Default value = 15)

    """
    actor.smoothLaplacian(niter=factor)


def check_cprofile(dump):
    """check to cProfile module's data or profile module's data."""
    signature = 'sprof.Profiler'.encode()
    return True if dump.find(signature) > 0 else False


@classmethod
def getInstances(cls, objs):
    """Translate a list of objects into the list of corresponding
        instances.
        """
    return map(cls.getInstance, objs)


def calculate_amortization_amount(principal, interest_rate, period):
    """
    Calculates Amortization Amount per period

    :param principal: Principal amount
    :param interest_rate: Interest rate per period
    :param period: Total number of periods
    :return: Amortization amount per period
    """
    x = (1 + interest_rate) ** period
    return principal * (interest_rate * x) / (x - 1)


def __delitem__(key):
    """Delete object by key from cache.

        Always return None.
        """


def get_interface_type(interface):
    """Gets the type of interface
    """
    if interface.upper().startswith('GI'):
        return 'GigabitEthernet'
    elif interface.upper().startswith('FA'):
        return 'FastEthernet'
    elif interface.upper().startswith('FO'):
        return 'FortyGigE'
    elif interface.upper().startswith('ET'):
        return 'Ethernet'
    elif interface.upper().startswith('LO'):
        return 'Loopback'
    elif interface.upper().startswith('BE'):
        return 'Bundle-Ether'
    elif interface.upper().startswith('NV'):
        return 'nve'
    elif interface.upper().startswith('TWE'):
        return 'TwentyFiveGigE'
    elif interface.upper().startswith('HU'):
        return 'HundredGigE'
    elif interface.upper().startswith('PRE'):
        return 'preconfigure'
    else:
        return 'unknown'


def assert_bytes(*args):
    """
    porting helper, assert args type
    """
    try:
        for x in args:
            assert isinstance(x, (bytes, bytearray))
    except:
        print('assert bytes failed', list(map(type, args)))
        raise


def _get_var_parent(name):
    """Get parent of the variable given its name
    """
    if not name.startswith('$'):
        return name.split('.')[0]


def dim0(s):
    """Dimension of the slice list for dimension 0."""
    return s[0].stop - s[0].start


@classmethod
def query_by_group(cls, group):
    """Get all admins for a specific group."""
    return cls.query.filter_by(group=group)


@classmethod
def _cache_lookup(cls, id, **kwargs):
    """ Look up cached objects, return found instance and search key """
    if isinstance(id, int):
        return cls._cache[id], id
    if isinstance(id, dict):
        return cls._cache[id['plan_id']], id['plan_id']
    raise KeyError


def overwrite_toggle():
    """Toggle overwrite while typing

    """
    pass


def theta_Cl_SO4_MNTR08(T):
    """a-a': chloride sulfate [MNTR08]."""
    theta = -0.07122
    valid = T == 298.15
    return theta, valid


def resolve_frompath(pkgpath, relpath, level=0):
    """Resolves the path of the module referred to by 'from ..x import y'."""
    if level == 0:
        return relpath
    parts = pkgpath.split('.') + ['_']
    parts = parts[:-level] + (relpath.split('.') if relpath else [])
    return '.'.join(parts)


def _geojson_properties2karta(properties, n):
    """ Takes a dictionary (derived from a GeoJSON properties object) and
    divides it into singleton properties and *n*-degree data. """
    props = {}
    data = {}
    for key, value in properties.items():
        if isinstance(value, list) or isinstance(value, tuple):
            if len(value) == n:
                data[key] = value
            else:
                raise ValueError('properties must be singleton or per-vertex')
        else:
            props[key] = value
    return props, data


@staticmethod
def p_multiplexor_value_ranges(p):
    """multiplexor_value_ranges : value_range
                                    | value_range COMMA multiplexor_value_ranges"""
    try:
        p[0] = [p[1]] + p[3]
    except IndexError:
        p[0] = [p[1]]


def update_params(params, updates):
    """Merges updates into params"""
    params = params.copy() if isinstance(params, dict) else dict()
    params.update(updates)
    return params


def compare_hash(hash_a, hash_b):
    """
    Compares two hashes in constant time.
    """
    hash_a = hash_a if isinstance(hash_a, bytes) else hash_a.encode('utf-8')
    hash_b = hash_b if isinstance(hash_b, bytes) else hash_b.encode('utf-8')
    if len(hash_a) != len(hash_b):
        return False
    invalid_chars = 0
    for char_a, char_b in zip(hash_a, hash_b):
        if char_a != char_b:
            invalid_chars += 1
    return invalid_chars == 0


def iterable(obj):
    """Return true if the argument is iterable"""
    try:
        iter(obj)
    except TypeError:
        return False
    return True


@classmethod
def pipequeue(cls, *args, **kwargs):
    """
        This is a factory function which creates and initialises a
        Queue. Your code should call
        :py:meth:`close() <turberfield.utils.pipes.SimplePipeQueue.close>`
        on the queue when finished.
        """
    return cls(*args, **kwargs).__enter__()


@staticmethod
def ensure_piece(piece_path, piece_name, conn, cursor):
    """
        Ensure the given piece is included
            :param piece_path: Path to the piece
            :param piece_name: Name of the piece
            :param conn: Connection to sqlite instance
            :param cursor: Cursor to use
        """
    cursor.execute('SELECT id FROM pieces WHERE path=? AND name=? LIMIT 1',
        (piece_path, piece_name))
    results = cursor.fetchall()
    if results:
        return results[0][0]
    cursor.execute('INSERT INTO pieces (path, name) VALUES (?, ?)', (
        piece_path, piece_name))
    conn.commit()
    return cursor.lastrowid


def first(iterable, *args):
    """
    Return the first item from the iterable.

    >>> first(range(11))
    0
    >>> first([3,2,1])
    3
    >>> iter = range(11)
    >>> first(iter)
    0

    Raises StopIteration if no value is present.

    >>> first([])
    Traceback (most recent call last):
    ...
    StopIteration

    Pass a default to be used when iterable is empty.

    >>> first([], None)

    """
    iterable = iter(iterable)
    return next(iterable, *args)


def get_multi(keys):
    """ Return a mapping of values stored in the cache under 'keys'.
        """


def getdescfromdrev(drev):
    """get description (commit message) from "Differential Revision"

    This is similar to differential.getcommitmessage API. But we only care
    about limited fields: title, summary, test plan, and URL.
    """
    title = drev[b'title']
    summary = drev[b'summary'].rstrip()
    testplan = drev[b'testPlan'].rstrip()
    if testplan:
        testplan = b'Test Plan:\n%s' % testplan
    uri = b'Differential Revision: %s' % drev[b'uri']
    return b'\n\n'.join(filter(None, [title, summary, testplan, uri]))


def get_hex(fh, nbytes=1):
    """
    get nbyte bytes (1 by default)
    and display as hexidecimal
    """
    hstr = ''
    for i in range(nbytes):
        b = '%02X ' % ord(fh.read(1))
        hstr += b
    return hstr


@classmethod
def _to_str(cls, value):
    """Represents values either as string or None values as empty string.

        Args:
            value: a value

        """
    if value is None:
        return ''
    else:
        return str(value)


@classmethod
def get_storage_capabilities(cls):
    """Return a dictionary representing the performance capabilities.

        This is needed to evaluate the performance of each driver.
        """
    return cls.STORAGE_CAPABILITIES


def max_threshold(maxima, threshold):
    """Get the maxima with intensity above or equal to a threshold

    Parameters
    ----------
    maxima : pd.DataFrame
        Pandas DataFrame with the information of the maxima. Has to contain at least the column 'Intensity'.
    threshold : float
        Minimum value of the maxima to be returned.

    Returns
    -------
    pd.DataFrame
        The same Pandas DataFrame as the input ``maxima``, but containing only the maxima with an intensity equal
        or greater than ``threshold``.
    """
    return maxima[maxima['Intensity'] >= threshold]


def image_file_reader(*args, **kwargs):
    """Procedural interface for ImageFileReader"""
    import itk
    instance = itk.ImageFileReader.New(*args, **kwargs)
    return instance.__internal_call__()


@staticmethod
def replace_element(old_element, new_element_base_form):
    """Return a WordElement which base_form is the argument
        new_element_base_form. This element inherits its category and
        features from the argument old_element.

        Note: the old_element features do not override the new element
        ones, they can only complete them.

        """
    features = old_element.features.copy()
    element = old_element.lexicon.first(new_element_base_form, category=
        old_element.category)
    for feature, value in features.items():
        if feature not in element.features:
            element.features[feature] = value
    return element