def source_desti_field_chk(base_field, base_field_type, field_name):
    """Prepare filters (kwargs{}) for django queryset
       where fields contain string are checked like
       exact | startswith | contains | endswith

    >>> source_desti_field_chk(21, '1', 'contact')
    {'contact__exact': 21}

    >>> source_desti_field_chk(21, '2', 'contact')
    {'contact__startswith': 21}

    >>> source_desti_field_chk(21, '3', 'contact')
    {'contact__contains': 21}

    >>> source_desti_field_chk(21, '4', 'contact')
    {'contact__endswith': 21}
    """
    kwargs = {}
    if base_field != '':
        if base_field_type == '1':
            kwargs[field_name + '__exact'] = base_field
        if base_field_type == '2':
            kwargs[field_name + '__startswith'] = base_field
        if base_field_type == '3':
            kwargs[field_name + '__contains'] = base_field
        if base_field_type == '4':
            kwargs[field_name + '__endswith'] = base_field
    return kwargs


@staticmethod
def makeURL(baseURL, **kwargs):
    """
        helper function for constructor
        generates URL querystring based on
        provided parameters and values
        """
    URL = baseURL
    if URL[-1] != '?':
        URL += '?'
    appendString = ''
    for kwarg in kwargs:
        appendString += '&'
        appendString += str(kwarg)
        appendString += '='
        appendString += str(kwargs[kwarg])
    URL += appendString[1:]
    return URL


def dBm2Watt(x):
    """
    converts from units of watts to dBm
    """
    return 10 ** (x / 10.0) / 1000.0


def join(separator, *args):
    """
    Similar to concatenate(), but takes an extra separator as first argument
    argument.

    Examples:
        >>> join(', ', 1, 2, 3)
        '1, 2, 3'
    """
    if not args:
        return ''
    if len(args) == 1:
        args = args[0]
    return str(separator).join(map(str, args))


def studyItemPixmapOk():
    """
    Get the reference pixmap for items of this module.
    """
    return 'ADAO_small_vert.png'


def driver_variables_paste(replace: bool=False):
    """Add copied driver variables to the active driver

    :param replace: Replace Existing, Replace existing driver variables, instead of just appending to the end of the existing list
    :type replace: bool
    """
    pass


def get_swarm_spans(coll):
    """
    Given a matplotlib Collection, will obtain the x and y spans
    for the collection. Will return None if this fails.
    """
    import numpy as np
    x, y = np.array(coll.get_offsets()).T
    try:
        return x.min(), x.max(), y.min(), y.max()
    except ValueError:
        return None


def is_unlinked_account(user):
    """
    Returns whether the provided user has authenticated via
    an InstitutionAccount not yet linked to a Uniauth profile.
    """
    return user.username and user.username.startswith('cas-')


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def __neg__(G):
    """
        The negation of the Nimber `G`. A Nimber is its own inverse.

        Returns
        -------
        G : Nimber
            The Nimber's inverse.
        """
    return G


def dict_of_str(json_dict):
    """Given a dictionary; return a new dictionary with all items as strings.

    Args:
        json_dict(dict): Input JSON dictionary.

    Returns:
        A Python dictionary with the contents of the JSON object as strings.
    """
    result = {}
    for key, value in json_dict.items():
        result[key] = '{}'.format(value)
    return result


def unauthenticated(func):
    """Adds 'unauthenticated' attribute to decorated function.

    Usage:

    >>> @unauthenticated
    ... def mymethod(f):
    ...     pass
    """
    func.unauthenticated = True
    return func


@classmethod
def from_exception(cls, exception):
    """Creates a failure object from a exception instance."""
    exc_info = type(exception), exception, getattr(exception,
        '__traceback__', None)
    return cls(exc_info=exc_info)


def format_bytes(size):
    """
    human readable bytes size
    :param size: integer
    :return: string
    """
    power = 2 ** 10
    n = 0
    power_labels = {(0): 'B', (1): 'kB', (2): 'MB', (3): 'GB', (4): 'TB'}
    while size > power:
        size /= power
        n += 1
    if n:
        formatted_size = f'{size:.2f}'
    else:
        formatted_size = size
    return f'{formatted_size}{power_labels[n]}'


def getTranslation(language='language'):
    """
        Return the object corresponding to a translated version or None if no
        translation exists.

        If called without arguments it returns the translation in the currently
        selected language. If the object is already in the selected language
        it returns self.
        """


@staticmethod
def isBaseElem(elem):
    """True if elem is a base element; i.e. can not be decomposed."""
    return True


def _create_function_from_code_obj(fcode, func_env, func_arg, func_clo, glbls):
    """
    Creates a function from a code object. Args:
    * fcode - the code object
    * func_env - string for the freevar placeholders
    * func_arg - string for the function args (e.g. "a, b, c, d=None")
    * func_clo - string for the closure args
    * glbls - the function globals
    """
    func_text = 'def g():\n%s\n  def f(%s):\n    return (%s)\n  return f' % (
        func_env, func_arg, func_clo)
    loc = {}
    exec(func_text, glbls, loc)
    f = loc['g']()
    f.__code__ = fcode
    f.__name__ = fcode.co_name
    return f


@staticmethod
def iterator(fn):
    """Tag the method as the collection remover.

        The iterator method is called with no arguments.  It is expected to
        return an iterator over all collection members::

            @collection.iterator
            def __iter__(self): ...

        """
    fn._sa_instrument_role = 'iterator'
    return fn


def get_identity_pool_roles(IdentityPoolId=None):
    """
    Gets the roles for an identity pool.
    You must use AWS Developer credentials to call this API.
    See also: AWS API Documentation

    :example: response = client.get_identity_pool_roles(
        IdentityPoolId='string'
    )

    :type IdentityPoolId: string
    :param IdentityPoolId: [REQUIRED]
            An identity pool ID in the format REGION:GUID.

    :rtype: dict
    :return: {
        'IdentityPoolId': 'string',
        'Roles': {
            'string': 'string'
        },
        'RoleMappings': {
            'string': {
                'Type': 'Token'|'Rules',
                'AmbiguousRoleResolution': 'AuthenticatedRole'|'Deny',
                'RulesConfiguration': {
                    'Rules': [
                        {
                            'Claim': 'string',
                            'MatchType': 'Equals'|'Contains'|'StartsWith'|'NotEqual',
                            'Value': 'string',
                            'RoleARN': 'string'
                        },
                    ]
                }
            }
        }
    }

    """
    pass


def get_command_class(command):
    """
    Called from runCLI() to select the command class for the selected command.

    :param command: The command to be implemented
    :return: The command class corresponding to the selected command
    """
    from scrapple.commands import genconfig, generate, run, web
    cmdClass = getattr(eval(command), command.title() + 'Command')
    return cmdClass


def p_host_block_decl(p):
    """ host_block_decl : HOST STRING BRACE_OPEN host_stmts BRACE_CLOSE"""
    p[0] = {p[1]: {p[2]: p[4]}}


def _summary(function):
    """
    Derive summary information from a function's docstring or name. The summary is
    the first sentence of the docstring, ending in a period, or if no dostring is
    present, the function's name capitalized.
    """
    if not function.__doc__:
        return f'{function.__name__.capitalize()}.'
    result = []
    for word in function.__doc__.split():
        result.append(word)
        if word.endswith('.'):
            break
    return ' '.join(result)


def validate(schema, data, owner=None):
    """Validate input data with input schema.

    :param Schema schema: schema able to validate input data.
    :param data: data to validate.
    :param Schema owner: input schema parent schema.
    :raises: Exception if the data is not validated.
    """
    schema._validate(data=data, owner=owner)


@classmethod
def fromElement(cls, elem):
    """
        Read properties from a MetaDataVersion element

        :param lxml.etree._Element elem: Source etree Element
        """
    self = cls()
    self.oid = elem.get('OID')
    self.name = elem.get('Name')
    return self


@staticmethod
def getSkimArguments():
    """
        _getSkimArguments_

        Skim arguments can be many of the same, it depends on the number
        of defined skims. However we need to keep the same definition of its arguments
        in a generic form. This method follows the same definition of getWorkloadCreateArgs in StdBase.
        """
    skimArgs = {'SkimName#N': {'default': None, 'type': str, 'optional':
        False, 'validate': None, 'null': False}, 'SkimInput#N': {'default':
        None, 'type': str, 'optional': False, 'validate': None, 'null':
        False}, 'Skim#NConfigCacheID': {'default': None, 'type': str,
        'optional': False, 'validate': None, 'null': False},
        'SkimTimePerEvent#N': {'default': None, 'type': float, 'optional':
        True, 'validate': lambda x: x > 0, 'null': False},
        'SkimSizePerEvent#N': {'default': None, 'type': float, 'optional':
        True, 'validate': lambda x: x > 0, 'null': False}, 'SkimMemory#N':
        {'default': None, 'type': float, 'optional': True, 'validate': lambda
        x: x > 0, 'null': False}, 'SkimSplittingAlgo#N': {'default': None,
        'type': str, 'optional': True, 'validate': None, 'null': False},
        'SkimEventsPerJob#N': {'default': None, 'type': int, 'optional':
        True, 'validate': lambda x: x > 0, 'null': False},
        'SkimLumisPerJob#N': {'default': 8, 'type': int, 'optional': True,
        'validate': lambda x: x > 0, 'null': False}, 'SkimFilesPerJob#N': {
        'default': 1, 'type': int, 'optional': True, 'validate': lambda x:
        x > 0, 'null': False}}
    return skimArgs


def b_validate(A='', fail_empty=True):
    """
    Validate that a given string contains only 0s and 1s.

    This will return True if the string is valid, otherwise it returns False.

    E.g. b_validate() returns False
         b_validate('') returns False
         b_validate('', fail_empty=False) returns True
         b_validate('01010101') returns True
         b_validate('010120101') returns False
         b_validate('0101 0101') returns False
    """
    t = True
    if t and not type(A) is str:
        t = False
    if t and fail_empty and not len(A) > 0:
        t = False
    if t:
        from re import compile as re_compile
        pattern = re_compile('[^01]')
        t = not bool(pattern.search(A))
        del re_compile, pattern
    return t


@staticmethod
def encode(_value):
    """Encode a DER null value"""
    return b''


def eq_27_axisymmetric_ceiling_jet_velocity(Q_dot_c_kW: float, z_H: float,
    z_0: float, r: float):
    """Equation 26 in Section 8.4.3.2 PD 7974-1:2019 calculates the temperature of ceiling jet above fire.

    :param Q_dot_c_kW: in kW, conductive heat release rate.
    :param z_H: in m, height of the ceiling above the fire source.
    :param z_0: height of the virtual source above the fuel surface.
    :param r: in m, radial distance from the ceiling impingement point.
    :return u_cj: in deg.C, temperature (above ambient temperature) of ceiling jet.

    NOTES
    The properties of the ceiling jet are dependent upon the surface roughness of the ceiling together with heat losses
    to it. Most of the methods available in [24] calculate the maximum temperature and velocity in the ceiling jet. If
    detectors or sprinkler heads are situated substantially lower than where the maximum temperature and velocity
    occur, then longer activation times should be expected.

    The ceiling jet formulae assume that the jet is moving through ambient air and is not submerged within a ceiling
    smoke layer. Existing correlations in 8.3.3 for the maximum temperature and velocity in the plume can be used when
    `r/(z_H-z_0)` are less than or equal to the limits given.

    REFERENCES
    [24] ALPERT R.L. Ceiling Jet Flows, SFPE Handbook of Fire Protection Engineering, Fifth Edition, 14, 429–454, 2016.
    """
    try:
        assert r / (z_H - z_0) > 0.246
    except AssertionError:
        errmsg = (
            f"Failed to assert `r / (z_H - z_0) = {r / (z_H - z_0)} > 0.246`. Inputs are outside of the Alpert's ceiling jet correlation limits."
            )
        raise ValueError(errmsg)
    aa = 0.2526
    bb = Q_dot_c_kW ** (1 / 3) / (z_H - z_0) ** (1 / 3)
    cc = (r / (z_H - z_0)) ** -1.0739
    u_cj = aa * bb * cc
    return u_cj


def change(seq, start, end, change):
    """Return the sequence with ``seq[start:end]`` replaced by ``change``"""
    return seq[:start] + change + seq[end:]


@classmethod
def debug(cls, name, message, *args):
    """
        Convenience function to log a message at the DEBUG level.

        :param name:    The name of the logger instance in the VSG namespace (VSG.<name>)
        :param message: A message format string.
        :param args:    The arguments that are are merged into msg using the string formatting operator.
        :..note:        The native logger's `kwargs` are not used in this function.
        """
    cls.getLogger(name).debug(message, *args)


def plus_or_dot(pieces):
    """Return a + if we do not already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


def layer_duplicate():
    """Make a copy of the active Grease Pencil layer

    """
    pass


@classmethod
def _base_query_drop(cls, type: str, if_exists: bool=True, cascade: bool=False
    ) ->str:
    """Generates a DROP stub."""
    builder = ['DROP']
    builder.append(type)
    if if_exists:
        builder.append('IF EXISTS')
    builder.append(cls._name)
    if cascade:
        builder.append('CASCADE')
    return ' '.join(builder)


def constraint_remove():
    """Remove Rigid Body Constraint from Object

    """
    pass


def is_dict_type(value):
    """Treat any dict, MergeDict, MultiDict instance as dict type"""
    return isinstance(value, dict) or value.__class__.__name__ in ('MergeDict',
        'MultiDict')


@staticmethod
def format(cls, data):
    """Returns a string"""
    info = cls.get_element(data, 'Format')
    return info, info or 'null'


@classmethod
def set_delimiters(cls, line_delimiters=None, section_delimiters=None):
    """Set line/section delimiters.

        :returns: saved delimiter state suitable for
          :meth:`reset_delimiters`.

        :param line_delimiters: the line delimiters. If None, line
          delimiters are not changed.
        :param section_delimiters: the section delimiters. If None,
          `line_delimiters` is used.

        If both `line_delimiters` and `section_delimiters` are None,
        the delimiter state is returned without any modification to
        the current delimiters.

        >>> AdHoc.set_delimiters()
        (('@:', ':@'), ('@:', ':@'))

        >>> sv = AdHoc.inc_delimiters()
        >>> sv
        (('@:', ':@'), ('@:', ':@'))

        >>> AdHoc.set_delimiters()
        (('@@:', ':@@'), ('@@:', ':@@'))

        >>> AdHoc.reset_delimiters(sv)
        >>> AdHoc.set_delimiters()
        (('@:', ':@'), ('@:', ':@'))

        >>> AdHoc.set_delimiters(('<:', ':>'))
        (('@:', ':@'), ('@:', ':@'))

        >>> AdHoc.set_delimiters()
        (('<:', ':>'), ('<:', ':>'))

        >>> AdHoc.reset_delimiters(sv)
        >>> AdHoc.set_delimiters()
        (('@:', ':@'), ('@:', ':@'))

        """
    delimiter_state = cls.line_delimiters, cls.section_delimiters
    if line_delimiters is None:
        line_delimiters = delimiter_state[0]
        if section_delimiters is None:
            section_delimiters = delimiter_state[1]
    elif section_delimiters is None:
        section_delimiters = line_delimiters
    cls.line_delimiters, cls.section_delimiters = (line_delimiters,
        section_delimiters)
    return delimiter_state


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 store_multiple(option, opt, value, parser, *args, **kwargs):
    """
    Store multiple values in `parser.values`.  (Option callback.)

    Store `None` for each attribute named in `args`, and store the value for
    each key (attribute name) in `kwargs`.
    """
    for attribute in args:
        setattr(parser.values, attribute, None)
    for key, value in kwargs.items():
        setattr(parser.values, key, value)


def _variable_int(text: str) ->int:
    """Change variable text to index."""
    return int(text.split()[-1].replace('Point', ''))


def is_full_connection(domain):
    """
    Domain is "fully connected" if any https endpoint is fully connected.
    """
    https, httpswww = domain.https, domain.httpswww
    return https.https_full_connection or httpswww.https_full_connection


def describe_trusts(DirectoryId=None, TrustIds=None, NextToken=None, Limit=None
    ):
    """
    Obtains information about the trust relationships for this account.
    If no input parameters are provided, such as DirectoryId or TrustIds, this request describes all the trust relationships belonging to the account.
    See also: AWS API Documentation

    :example: response = client.describe_trusts(
        DirectoryId='string',
        TrustIds=[
            'string',
        ],
        NextToken='string',
        Limit=123
    )

    :type DirectoryId: string
    :param DirectoryId: The Directory ID of the AWS directory that is a part of the requested trust relationship.

    :type TrustIds: list
    :param TrustIds: A list of identifiers of the trust relationships for which to obtain the information. If this member is null, all trust relationships that belong to the current account are returned.
            An empty list results in an InvalidParameterException being thrown.
            (string) --

    :type NextToken: string
    :param NextToken: The DescribeTrustsResult.NextToken value from a previous call to DescribeTrusts . Pass null if this is the first call.

    :type Limit: integer
    :param Limit: The maximum number of objects to return.

    :rtype: dict
    :return: {
        'Trusts': [
            {
                'DirectoryId': 'string',
                'TrustId': 'string',
                'RemoteDomainName': 'string',
                'TrustType': 'Forest',
                'TrustDirection': 'One-Way: Outgoing'|'One-Way: Incoming'|'Two-Way',
                'TrustState': 'Creating'|'Created'|'Verifying'|'VerifyFailed'|'Verified'|'Deleting'|'Deleted'|'Failed',
                'CreatedDateTime': datetime(2015, 1, 1),
                'LastUpdatedDateTime': datetime(2015, 1, 1),
                'StateLastUpdatedDateTime': datetime(2015, 1, 1),
                'TrustStateReason': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def fahrToKelv(temp):
    """
    takes a temperature `temp` in fahrenheit and returns it in Kelvin
    """
    kelvin = 5.0 / 9.0 * (temp - 32.0) + 273.15
    return kelvin


def solve_linear(a, b, c):
    """
    Solve a*x + b*y = c.
    Solution (x0 + b*n, y0 + a*n).
    Return None or (x0, y0).
    """
    return None


def upgrade(account):
    """Transforms data from a v1 format to a v2 format"""
    environ = 'test'
    if 'prod' in account['tags']:
        environ = 'prod'
    owner = 'netflix'
    if not account['ours']:
        owner = 'third-party'
    services = []
    if account['metadata'].get('s3_name'):
        services.append(dict(name='s3', metadata=dict(name=account[
            'metadata']['s3_name']), status=[dict(region='all', enabled=True)])
            )
    if account['metadata'].get('cloudtrail_index'):
        services.append(dict(name='cloudtrail', metadata=dict(esIndex=
            account['metadata']['cloudtrail_index'], kibanaUrl=account[
            'metadata']['cloudtrail_kibana_url']), status=[dict(region=
            'all', enabled=True)]))
    if account.get('bastion'):
        services.append(dict(name='bastion', metadata=dict(hostname=account
            ['bastion']), status=[dict(region='all', enabled=True)]))
    for service in account['services'].keys():
        s = dict(name=service, status=[dict(region='all', enabled=account[
            'services'][service].get('enabled', True))])
        if service == 'spinnaker':
            s['metadata'] = {'name': account['services'][service]['name']}
        if service == 'lazyfalcon':
            if account['services'][service].get('owner'):
                s['metadata'] = {'owner': account['services'][service]['owner']
                    }
        if service == 'titus':
            s['metadata'] = {'stacks': account['services'][service]['stacks']}
        services.append(s)
    if account['metadata'].get('project_id'):
        item_id = account['metadata']['project_id']
    elif account['metadata'].get('account_number'):
        item_id = account['metadata']['account_number']
    else:
        raise Exception('No id found, are you sure this is in v1 swag format.')
    status = []
    if account['type'] == 'aws':
        status = [{'region': 'us-east-1', 'status': 'ready'}, {'region':
            'us-west-2', 'status': 'ready'}, {'region': 'eu-west-1',
            'status': 'ready'}, {'region': 'us-east-2', 'status':
            'in-active'}, {'region': 'us-west-1', 'status': 'in-active'}, {
            'region': 'ca-central-1', 'status': 'in-active'}, {'region':
            'ap-south-1', 'status': 'in-active'}, {'region':
            'ap-northeast-2', 'status': 'in-active'}, {'region':
            'ap-northeast-1', 'status': 'in-active'}, {'region':
            'ap-southeast-1', 'status': 'in-active'}, {'region':
            'ap-southeast-2', 'status': 'in-active'}, {'region':
            'eu-west-2', 'status': 'in-active'}, {'region': 'eu-central-1',
            'status': 'in-active'}, {'region': 'sa-east-1', 'status':
            'in-active'}]
    return dict(id=item_id, email=account['metadata'].get('email'), name=
        account['name'], contacts=account['owners'], provider=account[
        'type'], status=status, tags=list(set(account['tags'])),
        environment=environ, description=account['description'], sensitive=
        account['cmc_required'], owner=owner, aliases=account['alias'],
        services=services, account_status=account['account_status'])


def changekeys(map, keymap, replace=False):
    """
    Return a copy of map with the name of the keys changed according to the
    given keymap.

    Example:
        >>> changekeys({1: 2, 3: 4}, {1: 3, 3: 1})
        {3: 2, 1: 4}
    """
    return NotImplemented


def run_as_daemon(f, *args, **kwargs):
    """Run the given function as a daemonized process.

    :param f: The function to run
    """
    try:
        import daemon
        with daemon.DaemonContext():
            f(*args, **kwargs)
    except ImportError:
        print(
            'You must be on a UNIX platform to use this feature and musthave installed `python-daemon`'
            )


def drivers_delete_selected():
    """Delete drivers assigned to selected items

    """
    pass


def from_nibbles(bytes_, signed=False):
    """yield 4-bit nibble values in bytes_, low nibbles first

    (order example: nibbles(b'!Ce') yields the nibbles 1,2,3,4,5,6)

    bytes_: a bytes object OR a single int representing a single byte.
    signed: if True, nibbles are yielded as signed values,
        i.e. nibbles between [0x8 to 0xf] will yield respective values [-8 to -1]
    yields: integers in the range 0,15 for signed=False, -8,7 for signed=True
    """
    if not hasattr(bytes_, '__iter__'):
        bytes_ = bytes_,
    for b in bytes_:
        if signed:
            yield -(b & 8) + (b & 7)
            yield -(b >> 4 & 8) + (b >> 4 & 7)
        else:
            yield b & 15
            yield b >> 4 & 15


def _get_const_info(const_index, const_list):
    """Helper to get optional details about const references

       Returns the dereferenced constant and its repr if the constant
       list is defined.
       Otherwise returns the constant index and its repr().
    """
    argval = const_index
    if const_list is not None:
        argval = const_list[const_index]
    return argval, repr(argval)


def shape_to_strides(sh):
    """Return a tuple of strides given a shape tuple."""
    n = len(sh)
    if not n:
        return ()
    strides = [None] * n
    strides[n - 1] = 1
    for i in range(n - 1, 0, -1):
        strides[i - 1] = strides[i] * sh[i]
    return tuple(strides)


def delete_cached_file(cache, filename):
    """Delete cached file if present.

    :param cache: dictionary to hold opaque cache.
    :param filename: filename to delete
    """
    try:
        del cache[filename]
    except KeyError:
        pass


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def jbig2Decode(stream, parameters):
    """
        Method to decode streams using the JBIG2 standard (NOT IMPLEMENTED YET)

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


def copy():
    """Copy selected keyframes to the copy/paste buffer

    """
    pass


def compare_results(save, best_hsp, tmp_results, tmp_gene_split):
    """ Function for comparing hits and saving only the best hit """
    hit_id = best_hsp['hit_id']
    new_start_query = best_hsp['query_start']
    new_end_query = best_hsp['query_end']
    new_start_sbjct = int(best_hsp['sbjct_start'])
    new_end_sbjct = int(best_hsp['sbjct_end'])
    new_score = best_hsp['cal_score']
    new_db_hit = best_hsp['sbjct_header']
    new_contig = best_hsp['contig_name']
    new_HSP = best_hsp['HSP_length']
    for hit in list(tmp_results):
        hit_data = tmp_results[hit]
        old_start_query = hit_data['query_start']
        old_end_query = hit_data['query_end']
        old_start_sbjct = int(hit_data['sbjct_start'])
        old_end_sbjct = int(hit_data['sbjct_end'])
        old_score = hit_data['cal_score']
        old_db_hit = hit_data['sbjct_header']
        old_contig = hit_data['contig_name']
        old_HSP = hit_data['HSP_length']
        remove_old = 0
        if new_db_hit == old_db_hit:
            if (new_start_sbjct < old_start_sbjct or new_end_sbjct >
                old_end_sbjct):
                tmp_gene_split[old_db_hit][hit_id] = 1
                if not hit in tmp_gene_split[old_db_hit]:
                    tmp_gene_split[old_db_hit][hit] = 1
            elif new_score > old_score:
                remove_old = 1
                if (new_db_hit in tmp_gene_split and not hit_id in
                    tmp_gene_split[new_db_hit]):
                    tmp_gene_split[new_db_hit][hit_id] = 1
            else:
                save = 0
                if hit_id != hit:
                    if (new_db_hit in tmp_gene_split and hit_id in
                        tmp_gene_split[new_db_hit]):
                        del tmp_gene_split[new_db_hit][hit_id]
                break
        if new_contig == old_contig:
            if (old_start_query == new_start_query and old_end_query ==
                new_end_query):
                if best_hsp['perc_ident'] > hit_data['perc_ident']:
                    remove_old = 1
                    if (new_db_hit in tmp_gene_split and not hit_id in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                elif best_hsp['perc_ident'] == hit_data['perc_ident']:
                    if (new_db_hit in tmp_gene_split and not hit_id in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                else:
                    save = 0
                    if (new_db_hit in tmp_gene_split and hit_id in
                        tmp_gene_split[new_db_hit]):
                        del tmp_gene_split[new_db_hit][hit_id]
                    break
            elif max(old_end_query, new_end_query) - min(old_start_query,
                new_start_query) <= old_end_query - old_start_query + (
                new_end_query - new_start_query):
                if new_score > old_score:
                    remove_old = 1
                    if (new_db_hit in tmp_gene_split and not hit_id in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                elif new_score == old_score:
                    if int(best_hsp['perc_coverage']) == 100 and int(hit_data
                        ['perc_coverage']) == 100 and new_HSP > old_HSP:
                        remove_old = 1
                    if (new_db_hit in tmp_gene_split and not hit_id in
                        tmp_gene_split[new_db_hit]):
                        tmp_gene_split[new_db_hit][hit_id] = 1
                else:
                    if (new_db_hit in tmp_gene_split and hit_id in
                        tmp_gene_split[new_db_hit]):
                        del tmp_gene_split[new_db_hit][hit_id]
                    save = 0
                    break
        if remove_old == 1:
            del tmp_results[hit]
            if old_db_hit in tmp_gene_split and hit in tmp_gene_split[
                old_db_hit]:
                del tmp_gene_split[old_db_hit][hit]
    return save, tmp_gene_split, tmp_results


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


def data_to_result(header, data, data_present):
    """Moves the header and data (if present) into a common object."""
    result = {}
    if header['num_amplifier_channels'] > 0 and data_present:
        result['t_amplifier'] = data['t_amplifier']
    if header['num_aux_input_channels'] > 0 and data_present:
        result['t_aux_input'] = data['t_aux_input']
    if header['num_supply_voltage_channels'] > 0 and data_present:
        result['t_supply_voltage'] = data['t_supply_voltage']
    if header['num_board_adc_channels'] > 0 and data_present:
        result['t_board_adc'] = data['t_board_adc']
    if (header['num_board_dig_in_channels'] > 0 or header[
        'num_board_dig_out_channels'] > 0) and data_present:
        result['t_dig'] = data['t_dig']
    if header['num_temp_sensor_channels'] > 0 and data_present:
        result['t_temp_sensor'] = data['t_temp_sensor']
    if header['num_amplifier_channels'] > 0:
        result['spike_triggers'] = header['spike_triggers']
    result['notes'] = header['notes']
    result['frequency_parameters'] = header['frequency_parameters']
    if header['version']['major'] > 1:
        result['reference_channel'] = header['reference_channel']
    if header['num_amplifier_channels'] > 0:
        result['amplifier_channels'] = header['amplifier_channels']
        if data_present:
            result['amplifier_data'] = data['amplifier_data']
    if header['num_aux_input_channels'] > 0:
        result['aux_input_channels'] = header['aux_input_channels']
        if data_present:
            result['aux_input_data'] = data['aux_input_data']
    if header['num_supply_voltage_channels'] > 0:
        result['supply_voltage_channels'] = header['supply_voltage_channels']
        if data_present:
            result['supply_voltage_data'] = data['supply_voltage_data']
    if header['num_board_adc_channels'] > 0:
        result['board_adc_channels'] = header['board_adc_channels']
        if data_present:
            result['board_adc_data'] = data['board_adc_data']
    if header['num_board_dig_in_channels'] > 0:
        result['board_dig_in_channels'] = header['board_dig_in_channels']
        if data_present:
            result['board_dig_in_data'] = data['board_dig_in_data']
    if header['num_board_dig_out_channels'] > 0:
        result['board_dig_out_channels'] = header['board_dig_out_channels']
        if data_present:
            result['board_dig_out_data'] = data['board_dig_out_data']
    return result


def decrypt_RSA(key, package):
    """
    Decrypt RSA encrypted package with private key
    :param key: Private key
    :param package: Base64 encoded string to decrypt
    :return: String decrypted
    """
    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_OAEP
    from base64 import b64decode
    rsakey = RSA.importKey(key)
    rsakey = PKCS1_OAEP.new(rsakey)
    decrypted = rsakey.decrypt(b64decode(package))
    return decrypted.decode('unicode_escape')


def write_phones_txt(orig_lines, highest_numbered_symbol, nonterminals,
    filename):
    """Writes updated phones.txt to 'filename'.  'orig_lines' is the original lines
       in the phones.txt file as a list of strings (without the newlines);
       highest_numbered_symbol is the highest numbered symbol in the original
       phones.txt; nonterminals is a list of strings like '#nonterm:foo'."""
    with open(filename, 'wb') as f:
        for l in orig_lines:
            print(l, file=f)
        cur_symbol = highest_numbered_symbol + 1
        for n in (['#nonterm_bos', '#nonterm_begin', '#nonterm_end',
            '#nonterm_reenter'] + nonterminals):
            print('{0} {1}'.format(n, cur_symbol), file=f)
            cur_symbol = cur_symbol + 1


def poly(x_list, seed):
    """Return cordinates of a polynomial.

    This function returns the 2-D cordinates of a polynomial, and is used
    for interpolation problems.

    Parameters
    ----------
    x_list : list
        A list of numerics that defines the x values evaluated over.

    seed : array-like, shape = (parameters, 2)
        A numpy array of parameters generated by paddy.  Refer to
        :mod:`~paddy.Paddy_runner` for details regarding generation of the
        array.

    Returns
    -------
    output : list of floats
        A list of float values representing the y values of the input x.

    See Also
    --------
    :func:`eval_numeric`

    Notes
    -----
    The polynomial is defined as:

    .. math:: \\sum_{k=0}^{n}a_{k}x^k

    Where ``a`` represents the sequence of parameter values generated by
    paddy.  ``x`` is simply the `x` parameter of numeric values that the
    polynomial is evaluated over.

    """
    counter = 0
    output = []
    s_x = []
    while counter < len(x_list):
        k = 0
        xn_out = []
        while k < len(seed):
            temp_y = seed[k][0] * x_list[counter] ** k
            xn_out.append(temp_y)
            k = k + 1
        s_x.append(sum(xn_out))
        counter = counter + 1
    output = s_x
    return output


def splittime(seconds):
    """converts time given in seconds into a tuple: (hours, mins, secs)"""
    tmp = seconds
    hh = tmp / 3600
    tmp %= 3600
    mm = tmp / 60
    tmp %= 60
    ss = tmp
    return hh, mm, ss


@staticmethod
def user_parse(data):
    """Parse information from the provider."""
    _user = data.get('user_info', {})
    _id = _user.get('id') or _user.get('uid')
    yield 'id', _id
    yield 'locale', _user.get('default_lang')
    yield 'username', _user.get('display_name')
    first_name, _, last_name = _user.get('full_name', '').partition(' ')
    yield 'first_name', first_name
    yield 'last_name', last_name
    yield 'picture', 'http://avatars.plurk.com/{0}-big2.jpg'.format(_id)
    city, country = map(lambda s: s.strip(), _user.get('location', ',').
        split(','))
    yield 'city', city
    yield 'country', country


def to_dec_deg(dms):
    """Convert to decimal degrees."""
    if not dms:
        return 0.0
    deg, minutes = dms.split()
    side = minutes[-1]
    minutes = minutes[:2]
    float_deg = int(deg) + int(minutes) / 60.0
    return float_deg if side in ('N', 'E') else -float_deg


def isdatadescriptor(object):
    """Return true if the object is a data descriptor.

    Data descriptors have both a __get__ and a __set__ attribute.  Examples are
    properties (defined in Python) and getsets and members (defined in C).
    Typically, data descriptors will also have __name__ and __doc__ attributes
    (properties, getsets, and members have both of these attributes), but this
    is not guaranteed."""
    return hasattr(object, '__set__') and hasattr(object, '__get__')


def getCatalogs():
    """Returns a list of ICatalogs in the Datasource."""


def __delitem__(k):
    """ Delete an item from the dictionary which is passed to the
        renderer as the renderer globals dictionary."""


@classmethod
def post_init(cls, func):
    """A decorator for defining a routine to run after creation of a type object.

        An example use of this method would be to define a classmethod that gathers
        any defined methods or attributes after the base Python type construction (i.e. after
        :py:func:`type` has been called)
        """
    setattr(func, cls.__postinit, True)
    return classmethod(func)


def get_vert_ngrams_left(c):
    """Not implemented."""
    return


def get_user_permissions(username):
    """Return a list of permissions for the specified user.
        """


def show_code(func, get_txt=False):
    """show code of func or module"""
    import inspect
    txt = inspect.getsource(func)
    if not get_txt:
        print(txt)
    else:
        return txt


def indent(depth):
    """Returns an amount of indentation whitespace to the provided depth."""
    return '  ' * depth


def _link(token, result):
    """ A dummy function to link results together in a graph

    We use this to enforce an artificial sequential ordering on tasks that
    don't explicitly pass around a shared resource
    """
    return None


@classmethod
def export(cls, all_stages=True):
    """
        Export a dictionary representation of known stages
        (if all==True, the default) or just this stage (all==False).

        """


def list_zip(archive, compression, cmd, verbosity, interactive):
    """List a ZIP archive."""
    cmdlist = [cmd, '-l']
    if verbosity > 1:
        cmdlist.append('-v')
    cmdlist.extend(['--', archive])
    return cmdlist


def _exec(script, globals=None, locals=None):
    """
    Wrapper around the built-in function ``exec`` on Python versions 2.7.9 and
    higher 2.7.9, or a function calling the ``exec`` statement on earlier
    versions.
    """
    exec(script, globals, locals)


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 multiply(image1, image2):
    """
    Superimposes two images on top of each other.

    If you multiply an image with a solid black image, the result is black. If
    you multiply with a solid white image, the image is unaffected. At least
    one of the images must have mode "1".

    .. code-block:: python

        out = image1 * image2 / MAX

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_multiply(image2.im))


def with_metaclass(meta, *bases):
    """Create a base class with a metaclass."""
    return meta('NewBase', bases, {})


@classmethod
def _get_column_by_db_name(cls, name):
    """
        Returns the column, mapped by db_field name
        """
    return cls._columns.get(cls._db_map.get(name, name))


def view_all(include_handles: bool=True):
    """Reset viewable area to show full keyframe range

    :param include_handles: Include Handles, Include handles of keyframes when calculating extents
    :type include_handles: bool
    """
    pass


def get_function_name(wrapped, instance, args, kwargs):
    """Return the wrapped function's name."""
    return wrapped.__name__


@classmethod
def planar_sheet_2d(cls, identifier, nx, ny, distx, disty, noise=None):
    """Creates a planar sheet from an hexagonal grid of cells.

        Parameters
        ----------
        identifier : string
        nx, ny : int
          number of cells in the x and y axes
        distx, disty : float,
          the distances in x and y between the cells
        noise : float, default None
          position noise on the hexagonal grid

        Returns
        -------
        planar_sheet: a 2D :class:`Sheet` instance
          in the (x, y) plane

        """
    from scipy.spatial import Voronoi
    from ..config.geometry import planar_spec
    from ..generation import hexa_grid2d, from_2d_voronoi
    grid = hexa_grid2d(nx, ny, distx, disty, noise)
    datasets = from_2d_voronoi(Voronoi(grid))
    return cls(identifier, datasets, specs=planar_spec(), coords=['x', 'y'])


def portrayPDAgent(agent):
    """
    This function is registered with the visualization server to be called
    each tick to indicate how to draw the agent in its current state.
    :param agent:  the agent in the simulation
    :return: the portrayal dictionary
    """
    assert agent is not None
    return {'Shape': 'rect', 'w': 1, 'h': 1, 'Filled': 'true', 'Layer': 0,
        'x': agent.pos[0], 'y': agent.pos[1], 'Color': 'blue' if agent.
        isCooroperating else 'red'}


def _final_count(M, divisions=10):
    """Calculate final number of vertices where M control points are defined"""
    return (M - 1) // 2 * divisions - 1 + 1


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

        :param MemberChangeExternalIdType val:
        :rtype: EventType
        """
    return cls('member_change_external_id', val)


def control_group(action, action_space, control_group_act, control_group_id):
    """Act on a control group, selecting, setting, etc."""
    del action_space
    select = action.action_ui.control_group
    select.action = control_group_act
    select.control_group_index = control_group_id


def SizeBenefitAccHosp(t):
    """Accidental hospitalization benefit per policy"""
    return 0


@classmethod
def delete(cls, id, client=None):
    """You cannot delete a derived band.

        Raises
        ------
        NotImplementedError
            This method is not supported for DerivedBands.
        """
    raise NotImplementedError('Deleting DerivedBands is not permitted')


def deltam_f(mismatch):
    """Fractional mismatch between neighbouring tiles

    Parameters
    ----------
    mismatch: 'float'
        percentage of desired fractional mismatch

    Returns
    -------
    :type: 'float'
    """
    return 2 * (mismatch / 3.0) ** (1 / 2.0)


def day_of_month(datetimes):
    """Return the day of the month of given dates."""
    return (datetimes.astype('datetime64[D]', copy=False) - datetimes.
        astype('datetime64[M]', copy=False) + 1).astype(int)


def getLogin():
    """Return login name, or None if no login name found."""


def topsort(edge_dict, root=None):
    """
	List of nodes in topological sort order from edge dict
	where key = rv and value = list of rv's children
	"""
    queue = []
    if root is not None:
        queue = [root]
    else:
        for rv in edge_dict.keys():
            prior = True
            for p in edge_dict.keys():
                if rv in edge_dict[p]:
                    prior = False
            if prior == True:
                queue.append(rv)
    visited = []
    while queue:
        vertex = queue.pop(0)
        if vertex not in visited:
            visited.append(vertex)
            for nbr in edge_dict[vertex]:
                queue.append(nbr)
    return visited


def find_previous(element, l):
    """
    find previous element in a sorted list

    >>> find_previous(0, [0])
    0
    >>> find_previous(2, [1, 1, 3])
    1
    >>> find_previous(0, [1, 2])
    >>> find_previous(1.5, [1, 2])
    1
    >>> find_previous(3, [1, 2])
    2
    """
    length = len(l)
    for index, current in enumerate(l):
        if length - 1 == index:
            return current
        if index == 0:
            if element < current:
                return None
        if current <= element < l[index + 1]:
            return current


@staticmethod
def _show_previous_blank_lines(block):
    """
        Show the block previous blank lines
        """
    pblock = block.previous()
    while pblock.text().strip() == '' and pblock.blockNumber() >= 0:
        pblock.setVisible(True)
        pblock = pblock.previous()


def public_modules(path):
    """Yield all the paths to public modules in a given directory."""
    for entry in path.iterdir():
        if entry.name.startswith('_'):
            continue
        if entry.is_dir() or entry.is_file() and entry.suffix == '.py':
            yield entry


def add_button(figure):
    """Adds the pause-play button for animation"""
    figure['layout']['updatemenus'] = [{'buttons': [{'args': [None, {
        'frame': {'duration': 500, 'redraw': False}, 'fromcurrent': True,
        'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
        'label': 'Play', 'method': 'animate'}, {'args': [[None], {'frame':
        {'duration': 0, 'redraw': False}, 'mode': 'immediate', 'transition':
        {'duration': 0}}], 'label': 'Pause', 'method': 'animate'}],
        'direction': 'left', 'pad': {'r': 10, 't': 87}, 'showactive': False,
        'type': 'buttons', 'x': 0.1, 'xanchor': 'right', 'y': 0, 'yanchor':
        'top'}]


def match_texture_space():
    """Match texture space to object’s bounding box

    """
    pass


def linear_variogram_model(m, d):
    """Linear model, m is [slope, nugget]"""
    slope = float(m[0])
    nugget = float(m[1])
    return slope * d + nugget


def lookupMailGroup(name, timeout=None):
    """
        Perform an MG record lookup.

        @type name: C{str}
        @param name: DNS name to resolve.

        @type timeout: Sequence of C{int}
        @param timeout: Number of seconds after which to reissue the query.
            When the last timeout expires, the query is considered failed.

        @rtype: L{Deferred}
        @return: A L{Deferred} which fires with a three-tuple of lists of
            L{twisted.names.dns.RRHeader} instances.  The first element of the
            tuple gives answers.  The second element of the tuple gives
            authorities.  The third element of the tuple gives additional
            information.  The L{Deferred} may instead fail with one of the
            exceptions defined in L{twisted.names.error} or with
            C{NotImplementedError}.
        """


def __new__(cls, _str_: str, if_empty: str='', s: str=' or ', quote_args:
    bool=False) ->'AtRule':
    """Create the ``AtRule`` and save parameters.

        Parameters
        ----------
        _str_ : str
            The string of the current ``Var``

        For the other parameters, see the class docstring (``if_empty`` and ``quote_args`` have
        the same name as the arguments to ``__new__`, but ``separator`` comes from the ``s``
        argument.

        Returns
        -------
        AtRule
            The newly created AtRule.

        """
    obj = super().__new__(cls, _str_)
    obj.if_empty = if_empty
    obj.separator = s
    obj.quote_args = quote_args
    return obj


@staticmethod
def _intersection(i1, i2):
    """ Compute the intersection of *i1* and *i2*. """
    if i1.intersect(i2):
        return max((i1.inf, i2.inf)), min((i1.sup, i2.sup))
    else:
        return None, None


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 printVLines(ax, xCoords, width=0.05, color='gray', alpha=0.75, lStyle='--'
    ):
    """Adds vertical lines to the plot in the list of x-coordinates passed.
        Created as an auxiliary function to mark days at which events happen
        (threshold crossings).

    Parameters
    ----------
    ax : Matplotlib axes
        Can be obtained from a figure with: fig.get_axes()[0]
    xCoords : list
        A list containing the xCoordinates of all the lines to print.
    width : float
        Line width (weight).
    color : color
        Color id for the lines to be drawn.
    alpha : float
        Alpha to apply to the lines.
    lStyle : Matplotlib line-style
        Matplotlib dash-line style:
        https://matplotlib.org/gallery/lines_bars_and_markers/line_styles_reference.html

    Returns
    -------
    ax
        Returns the changed ax with the modification performed.

    """
    for vLine in xCoords:
        ax.axvline(x=vLine, linewidth=width, linestyle=lStyle, color=color,
            alpha=alpha)
    return ax


def stringify(val):
    """
    Accepts either str or bytes and returns a str
    """
    try:
        val = val.decode('utf-8')
    except (UnicodeDecodeError, AttributeError):
        pass
    return val


def iter_ima(cube, index=False):
    """An iterator over the images of successive spectral pixels in a Cube

    Each call to the iterator returns the image of the next spectral
    pixel of the cube. The first image to be returned, is the image of
    spectral pixel 0, followed, on the next call, by the image of
    spectral pixel 1 etc.

    The return value of iter_ima() is a python generator that can be
    used in loops, such as in the following example::

      from mpdaf.obj import iter_ima
      for im,channel in iter_ima(mycube, index=True):
          print("Total flux in channel %d = %g" % (channel, im.data.sum()))

    Parameters
    ----------
    cube : `~mpdaf.obj.Cube`
       The cube that contains the images to be returned.
    index : bool
       If False, return just an image at each iteration.
       If True, return both an image and the index of that image along
       the wavelength axis of the cube.

    Yields
    ------
    `mpdaf.obj.Image`

    """
    if index:
        for l in range(cube.shape[0]):
            yield cube[(l), :, :], l
    else:
        for l in range(cube.shape[0]):
            yield cube[(l), :, :]


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['type']
    if type == 'tech':
        return 'CreateTechSupportItemDetails'
    if type == 'limit':
        return 'CreateLimitItemDetails'
    else:
        return 'CreateItemDetails'


def _style_ticks(axis, color):
    """ Enable minor ticks, and color major + minor ticks"""
    axis.minorticks_on()
    ticks = axis.get_xticklines() + axis.xaxis.get_minorticklines(
        ) + axis.get_yticklines() + axis.yaxis.get_minorticklines()
    for tick in ticks:
        tick.set_color('#' + color + '3D')


def checkCompletedFor(user_id):
    """Check whether a user has completed the survey"""


def getFolder():
    """Convenience method that returns a suitable folder for storing
        IRulesets."""


@classmethod
def handle_error(cls, request, error_status):
    """
        Returns a response for the given request and error status
        :rtype: django.http.HttpResponse
        """
    raise NotImplementedError('Implement this method')


def remove_line_break(text):
    """Remove line breaks from text"""
    return text.replace('\n', '')


def _parse_fingerprint_awsconsole(line, host=None):
    """Parse SSH host fingerprint from AWS console output"""
    fingerprint = None
    if line.startswith('ec2:'):
        host = host
        fingerprint = line.split(': ', 2)[1]
    return host, fingerprint


def identity(arg=None, *args):
    """Return the first argument provided to it.

    Args:
        *args (mixed): Arguments.

    Returns:
        mixed: First argument or ``None``.

    Example:

        >>> identity(1)
        1
        >>> identity(1, 2, 3)
        1
        >>> identity() is None
        True

    .. versionadded:: 1.0.0
    """
    return arg


def rvs_from_distribution(*params, batch_size, distribution, size=None,
    random_state=None):
    """Transform the rvs method of a scipy like distribution to an operation in ELFI.

    Parameters
    ----------
    params :
        Parameters for the distribution
    batch_size : number of samples
    distribution : scipy-like distribution object
    size : tuple
        Size of a single datum from the distribution.
    random_state : RandomState object or None

    Returns
    -------
    random variates from the distribution

    Notes
    -----
    Used internally by the RandomVariable to wrap distributions for the framework.

    """
    if size is None:
        size = batch_size,
    else:
        size = (batch_size,) + size
    rvs = distribution.rvs(*params, size=size, random_state=random_state)
    return rvs


def get_flag_meanings(cls, flag_name):
    """ Returns flag category values and meanings given a flag_name, e.g. 'waveFlagPrimary' """
    return cls.get_var(flag_name).flag_meanings.split(' ')


def is_remote_list(values):
    """ check if this list corresponds to a backend formatted collection of
    dictionaries """
    for v in values:
        if not isinstance(v, dict):
            return False
        if '@type' not in v.keys():
            return False
    return True


@staticmethod
def __ensure_int_coordinates(*coordinates):
    """Casts point/rectangle coordinates to int.

        This is to ensure Py2 compatibility with scripts that have problems with floor division -> true division on Py3.
        If a single point is passed, returns a single point.  If more than one is passed, returns a list of points.

        :param coordinates: arbitrary number of coordinate pairs (x, y)
        :return: single point or list of points, depending on number of ``coordinates`` passed
        """
    res = []
    for coord in coordinates:
        new_coord = int(coord[0]), int(coord[1])
        res.append(new_coord)
    return res[0] if len(res) == 1 else res


def getProperties():
    """Returns a list of IProperty in the level."""


def provide_subscription_adapter(factory, adapts=None, provides=None):
    """Register a subscription adapter

        A subscription adapter is registered to provide an interface
        for some number of object types. If a factory implements only
        one interface, then the provides argument can be omitted and
        the provided interface will be used. (In this case, a provides
        argument can still be provided to provide a less specific
        interface.)

        If the factory has an adapts declaration, then the adapts
        argument can be omitted and the declaration will be used.  (An
        adapts argument can be provided to override the declaration.)

        CAUTION: This API should only be used from test or
        application-setup code. This API shouldn't be used by regular
        library modules, as component registration is a configuration
        activity.
        """


@classmethod
def add_common_opts(cls, parser):
    """Add options that are common for several plugins.
        """
    for opt in cls.common_opt_names:
        cls._parser_add_opt(parser, opt)


@staticmethod
def version_format_get():
    """This is the version number written as VERSION_FORMAT in the metastore"""
    return 1


def det(A=None, name=None, attr=None, out=None, **kwargs):
    """Compute the determinant of a matrix.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, *A* is a square matrix. We compute:

      *out* = *det(A)*

    If *n>2*, *det* is performed separately on the trailing two dimensions
    for all inputs (batch mode).

    .. note:: The operator supports float32 and float64 data types only.
    .. note:: There is no gradient backwarded when A is non-invertible (which is
              equivalent to det(A) = 0) because zero is rarely hit upon in float
              point computation and the Jacobi's formula on determinant gradient
              is not computationally efficient when A is non-invertible.

    Examples::

       Single matrix determinant
       A = [[1., 4.], [2., 3.]]
       det(A) = [-5.]

       Batch matrix determinant
       A = [[[1., 4.], [2., 3.]],
            [[2., 3.], [1., 4.]]]
       det(A) = [-5., 5.]

    Defined in src/operator/tensor/la_op.cc:L973

    Parameters
    ----------
    A : Symbol
        Tensor of square matrix

    name : string, optional.
        Name of the resulting symbol.

    Returns
    -------
    Symbol
        The result symbol.
    """
    return 0,


def _get_default_annual_spacing(nyears):
    """
    Returns a default spacing between consecutive ticks for annual data.
    """
    if nyears < 11:
        min_spacing, maj_spacing = 1, 1
    elif nyears < 20:
        min_spacing, maj_spacing = 1, 2
    elif nyears < 50:
        min_spacing, maj_spacing = 1, 5
    elif nyears < 100:
        min_spacing, maj_spacing = 5, 10
    elif nyears < 200:
        min_spacing, maj_spacing = 5, 25
    elif nyears < 600:
        min_spacing, maj_spacing = 10, 50
    else:
        factor = nyears // 1000 + 1
        min_spacing, maj_spacing = factor * 20, factor * 100
    return min_spacing, maj_spacing


def get_gene_symbol_of_transcript_id(transcripts_dict, transcript_id):
    """
    @description get the gene_symbol of a given transcript_id from the user gtf data
    @param transcripts_dict (dict)
    @param transcript_id (string)
    @return (None|string)
    """
    if transcript_id in transcripts_dict:
        t_list = transcripts_dict[transcript_id]
        if len(t_list) > 0:
            return t_list[0]['gene_symbol'].lower()
    return None


def check_host(host):
    """
    Returns SMTP host name and port
    """
    if 'gmail' in host:
        return 'smtp.gmail.com', 587
    elif 'yahoo' in host:
        return 'smtp.mail.yahoo.com', 465
    elif 'hotmail' in host or 'outlook' in host:
        return 'smtp.live.com', 25


def search_result_generator(page_generator):
    """
    Simple wrapper function to return a generator to iterate through item
    results on the search page
    """
    for page in page_generator:
        for res in page:
            yield res


def input_string(message):
    """Handle inputs if they are supposed to be strings"""
    while True:
        answer = input(message)
        if isinstance(answer, str):
            if answer.casefold() == 'none':
                return None
            else:
                return answer
        else:
            print('Please enter an integer')


def format_span_id(span_id):
    """Format the span id according to b3 specification."""
    return format(span_id, '016x')


@classmethod
def get_namedtuple_factory(cls, field_mappings, name='Record'):
    """Gets a method that will convert a dictionary to a namedtuple, as defined by
    get_namedtuple(field_mappings).
    """
    ntup = cls.get_namedtuple(field_mappings, name)
    return lambda data: ntup(**data)


def get_top_fitness(dirty_values):
    """Return top fitness value.

    Returns the top fitness values of a
    :class:`~paddy.Paddy_Runner.PFARunner`, solely, for each iteration as a
    list when passed a dictionary with the structure type of
    :attr:`~paddy.Paddy_Runner.PFARunner.top_values`.

    Parameters
    ----------
    dirty_values : dictionary
        A dictionary in the form of :attr:`~PFARunner.top_values`.

    Returns
    -------
    fitness_list : list of floats
        A list of the top fitness value evaluated for sowing during each
        itteration.

    See Also
    --------
    :meth:`paddy.Paddy_Runner.PFARunner.run_paddy`

    Notes
    -----
    The top value evaluated for sowing when using 'population' for
    the `paddy_type` parameter of a `PFARunner` instance might not be the
    value of a seed generated during that itteration.  See (need to find home for the full description of the PFA)

    """
    fitness_list = []
    for i in dirty_values:
        fitness_list.append(dirty_values[i]['fitness'])
    return fitness_list


@classmethod
def clear_update_fail_callback(cls):
    """Clear all callbacks"""
    cls._update_cache_fail_callback.clear()


def Dequiv(fsm, states, agents):
    """
    Return the set of fsm that equivalent to states w.r.t. distributed
    knowledge of agents.

    fsm -- a MAS representing the system
    states -- a BDD representing a set of states of fsm
    agents -- a set of agents names of fsm.
    """
    return fsm.equivalent_states(states, frozenset({agents}))


def shot_down_self(info):
    """
        Process 'user shot down himself' event.

        Input:
        `info`  # An object with information about event's time, user's
                # callsign and aircraft, position on map.
        """


def _combinations(instrumentString):
    """
    find all combinations of instrumentString.  Remove all punctuation.
    """
    sampleList = instrumentString.split()
    allComb = []
    for size in range(1, len(sampleList) + 1):
        for i in range(len(sampleList) - size + 1):
            allComb.append(' '.join(sampleList[i:i + size]))
    return allComb


def update(*args, **kwds):
    """od.update(E, **F) -> None.  Update od from dict/iterable E and F.

        If E is a dict instance, does:           for k in E: od[k] = E[k]
        If E has a .keys() method, does:         for k in E.keys(): od[k] = E[k]
        Or if E is an iterable of items, does:   for k, v in E: od[k] = v
        In either case, this is followed by:     for k, v in F.items(): od[k] = v

        """
    if len(args) > 2:
        raise TypeError(
            'update() takes at most 2 positional arguments (%d given)' % (
            len(args),))
    elif not args:
        raise TypeError('update() takes at least 1 argument (0 given)')
    self = args[0]
    other = ()
    if len(args) == 2:
        other = args[1]
    if isinstance(other, dict):
        for key in other:
            self[key] = other[key]
    elif hasattr(other, 'keys'):
        for key in other.keys():
            self[key] = other[key]
    else:
        for key, value in other:
            self[key] = value
    for key, value in kwds.items():
        self[key] = value


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


@staticmethod
def get_workers_on_a_node(num_workers, resources):
    """ Returns the number of workers that can be placed on each node"""
    num_nodes = len(resources.global_nodelist)
    workers_per_node = num_workers // num_nodes + (num_workers % num_nodes > 0)
    return workers_per_node


@staticmethod
def interfaces_roles_change_and_tree_was_active_and_transitions_to_unsure_and_best_upstream_neighbor_not_null(
    interface: 'TreeInterfaceUpstream') ->None:
    """
        Interfaces roles change (NonRoot->Root) AND
        Tree transitions from Active to Unsure state AND
        BestUpstreamNeighbor is not null (possible loop detected)
        """
    interface.logger.debug(
        'interfaces_roles_change_and_tree_was_active_and_transitions_to_unsure_and_best_upstream_neighbor_not_null'
        )
    interface.send_i_am_no_longer_upstream()
    interface.send_my_interest()


@staticmethod
def bytes2human(n, repr_format='{value:.3f} {symbol}'):
    """
        >>> bytes2human(10000)
        '9K'
        >>> bytes2human(100001221)
        '95M'
        """
    symbols = 'B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
    prefix = {}
    for i, s in enumerate(symbols[1:]):
        prefix[s] = 1 << (i + 1) * 10
    for symbol in reversed(symbols[1:]):
        if n >= prefix[symbol]:
            value = float(n) / prefix[symbol]
            return repr_format.format(value=value, symbol=symbol)
    return repr_format.format(symbol=symbols[0], value=n)


def click_button(driver, el):
    """
    Click a button using Javascript
    """
    driver.execute_script('arguments[0].click();', el)


@staticmethod
def edit(track):
    """Build a track edit event.

		Parameters:
			track (dict): A library track dict.

		Returns:
			dict: A mutation dict.
		"""
    return track


def isEnabled():
    """Returns the enable status.
        """


def _immediately_before(node, values, positions):
    """
    Returns the set of all nodes that are immediately after the given
    node.

    Tree node A immediately follows node B if the first terminal
    symbol (word) produced by A immediately follows the last
    terminal symbol produced by B.
    """
    i = node[positions['_n']] - 1
    try:
        return [values[i]]
    except:
        return list()


def get_readcap():
    """Return a readonly cap instance for this node. For immutable or
        readonly nodes, get_cap() and get_readcap() return the same thing."""


def get_instance_port_states(instanceName=None):
    """
    Returns the port states for a specific virtual private server, or instance .
    See also: AWS API Documentation

    :example: response = client.get_instance_port_states(
        instanceName='string'
    )

    :type instanceName: string
    :param instanceName: [REQUIRED]
            The name of the instance.

    :rtype: dict
    :return: {
        'portStates': [
            {
                'fromPort': 123,
                'toPort': 123,
                'protocol': 'tcp'|'all'|'udp',
                'state': 'open'|'closed'
            },
        ]
    }

    """
    pass


def compile_Livneh2013_locations(maptable):
    """
    Compile a list of file URLs for Livneh et al. 2013 (CIG)

    maptable: (dataframe) a dataframe that contains the FID, LAT, LONG_, and ELEV for each interpolated data file
    """
    locations = []
    for ind, row in maptable.iterrows():
        basename = '_'.join(['data', str(row['LAT']), str(row['LONG_'])])
        url = [
            'http://www.cses.washington.edu/rocinante/Livneh/Livneh_WWA_2013/forcs_dhsvm/'
            , basename]
        locations.append(''.join(url))
    return locations


@classmethod
def save(cls, weights: dict, path: str):
    """
        Save model state.

        :param weights: state
        :param path: state file path
        :return: None
        """
    from torch import save as torch_save
    torch_save(weights, path)


def translateNoteToByte(n):
    """
    takes a note.Note object and translates it to a single byte representation.

    currently returns the chr() for the note's midi number. or chr(127) for rests

    >>> n = note.Note('C4')
    >>> b = search.translateNoteToByte(n)
    >>> b
    '<'
    >>> ord(b)
    60
    >>> ord(b) == n.pitch.midi
    True

    Chords are currently just searched on the first Note (or treated as a Rest if None)
    """
    if n.isRest:
        return chr(127)
    elif n.isChord:
        if n.pitches:
            return chr(n.pitches[0].midi)
        else:
            return chr(127)
    else:
        return chr(n.pitch.midi)


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

        :param SfAllowNonMembersToViewSharedLinksType val:
        :rtype: EventType
        """
    return cls('sf_allow_non_members_to_view_shared_links', val)


def getMeasures(unique_name=None):
    """Returns a list of IMeasure in the catalog optionally
        matching the given name."""


def gamma_approx(mean, variance):
    """
    Returns alpha and beta of a gamma distribution for a given mean and variance
    """
    return mean ** 2 / variance, mean / variance


def ply_save_color_face(path, verts, faces, colors):
    """
  Save mesh into a .ply file with colored faces.

  Parameters
  ----------
  path : str
    Path to save the file.
  verts : np.ndarray, shape [v, 3]
    Mesh vertices.
  faces : np.ndarray, shape [f, 3]
    Mesh faces.
  colors : np.ndarray, shape [f, 3], dtype uint8
    RGB color for each face.
  """
    num_verts = verts.shape[0]
    num_faces = faces.shape[0]
    with open(path, 'wb') as f:
        f.write(b'ply\n')
        f.write(b'format ascii 1.0\n')
        f.write(b'element vertex %d\n' % num_verts)
        f.write(b'property float32 x\n')
        f.write(b'property float32 y\n')
        f.write(b'property float32 z\n')
        f.write(b'element face %d\n' % num_faces)
        f.write(b'property list uint8 int32 vertex_index\n')
        f.write(b'property uchar red\n')
        f.write(b'property uchar green\n')
        f.write(b'property uchar blue\n')
        f.write(b'end_header\n')
        for i in range(num_verts):
            v = verts[i]
            f.write(b'%f %f %f\n' % (v[0], v[1], v[2]))
        for i in range(num_faces):
            face = faces[i]
            c = colors[i]
            f.write(b'3 %d %d %d %d %d %d\n' % (face[0], face[1], face[2],
                c[0], c[1], c[2]))


def modinv(a, m):
    """Find the modular inverse of a, with modulus m."""
    x = 0
    lastx = 1
    y = 1
    lasty = 0
    b = m
    while b != 0:
        a, (q, b) = b, divmod(a, b)
        x, lastx = lastx - q * x, x
        y, lasty = lasty - q * y, y
    return lastx % m


def track_settings_to_track():
    """Copy tracking settings from active track to selected tracks

    """
    pass


def str_to_bytes(s):
    """
    Convert 0xHexString to bytes
    :param s: 0x hexstring
    :return:  byte sequence
    """
    try:
        return bytes.fromhex(s.replace('0x', ''))
    except (NameError, AttributeError):
        return s.decode('hex')


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 symbol_restore(symbol):
    """Restore symbol for XueQiu."""
    return f'{symbol[2:]}.{symbol[:2]}'


def get_issue_number_from_card_data(card_data: dict) ->int:
    """
    Returns the issue number from the given card data

    Can be None if the card is a note or some other non-issue card

    Args:
        card_data: the card data returned by the GH API

    Returns:
        Issue number or None
    """
    content_url = card_data.get('content_url')
    if not content_url:
        return
    issue_number = content_url.rsplit('/', 1)[-1]
    return int(issue_number)


def flatten(list):
    """For an iterable of sub-iterables, generate each member of each
    sub-iterable in turn, i.e. a flattened version of that super-iterable.

    Example: Turn [[a,b,c],[d,e,f]] into [a,b,c,d,e,f].
    """
    for sublist in list:
        for j in sublist:
            yield j


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 get_temperature_from_atm_table_filename(filename):
    """
    Get temperature from filename / directory name.

    :param filename: str;
    :return: float;
    """
    return float(str(filename).split('_')[1])


def match_request(req):
    """Return whether the handler wants to process the given request."""


def rotate():
    """Add a new secret to the ring, pushing out the oldest secret.
        """


def usage_percent(used, total, _round=None):
    """Calculate percentage usage of 'used' against 'total'."""
    try:
        ret = used / total * 100
    except ZeroDivisionError:
        ret = 0.0 if isinstance(used, float) or isinstance(total, float) else 0
    if _round is not None:
        return round(ret, _round)
    else:
        return ret


@staticmethod
def dmql(query):
    """Client supplied raw DMQL, ensure quote wrap."""
    if isinstance(query, dict):
        raise ValueError(
            'You supplied a dictionary to the dmql_query parameter, but a string is required. Did you mean to pass this to the search_filter parameter? '
            )
    if len(query) > 0 and query != '*' and query[0] != '(' and query[-1
        ] != ')':
        query = '({})'.format(query)
    return query


def entries_to_remove(entries, d):
    """
    Function to remove selected entries (key and respective values) from
    a given dict.
    Based on a reply from the user mattbornski [#]_ at stackoverflow.

    Parameters
    ----------
    entries : array
        Set of entried to be removed.
    d : dict
        Dictionary to apply the entried removal.

    References
    ----------
    ..  [#] mattbornski, 2012. http://stackoverflow.com/questions/8995611/removing-multiple-keys-from-a-dictionary-safely

    """
    for k in entries:
        d.pop(k, None)


def GetNumDensity(ElList, Vol):
    """needs a doc string"""
    sumNoAtoms = 0.0
    for El in ElList:
        sumNoAtoms += ElList[El]['FormulaNo']
    return sumNoAtoms / Vol


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_bool()
    return parameters


def get_files_changed(repository, review_id):
    """
    Get a list of files changed compared to the given review.
    Compares against current directory.

    :param repository: Git repository. Used to get remote.
      - By default uses first remote in list.
    :param review_id: Gerrit review ID.
    :return: List of file paths relative to current directory.
    """
    repository.git.fetch([next(iter(repository.remotes)), review_id])
    files_changed = repository.git.diff_tree(['--no-commit-id',
        '--name-only', '-r', 'FETCH_HEAD']).splitlines()
    print('Found {} files changed'.format(len(files_changed)))
    return files_changed


def device_from_request(request):
    """
    Determine's the device name from the request by first looking for an
    overridding cookie, and if not found then matching the user agent.
    Used at both the template level for choosing the template to load and
    also at the cache level as a cache key prefix.
    """
    from django.conf import settings
    try:
        for device, _ in settings.DEVICE_USER_AGENTS:
            if device == request.COOKIES['scoffold-device']:
                return device
    except KeyError:
        try:
            user_agent = request.META['HTTP_USER_AGENT'].lower()
        except KeyError:
            pass
        else:
            try:
                user_agent = user_agent.decode('utf-8')
            except (AttributeError, UnicodeDecodeError):
                pass
            for device, ua_strings in settings.DEVICE_USER_AGENTS:
                for ua_string in ua_strings:
                    if ua_string.lower() in user_agent:
                        return device
    return ''


def duplicate(image):
    """Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`.

    :rtype: :py:class:`~PIL.Image.Image`
    """
    return image.copy()


def p_expression_domain_literal_text(p):
    """domain_literal_text : domain_literal_text DTEXT
                           | domain_literal_text fwsp
                           | DTEXT
                           | fwsp"""
    p[0] = ''.join(p[1:])


def _check_magic(handle, bool_return=False):
    """Checks for lif file magic bytes (Private)."""
    if handle.read(4) == b'p\x00\x00\x00':
        return True
    elif not bool_return:
        raise ValueError(
            'This is probably not a LIF file. Expected LIF magic byte at ' +
            str(handle.tell()))
    else:
        return False


@staticmethod
def list_item(l, index, default=None):
    """Получить элемент массива, если такого элемента нет - вернёт default"""
    try:
        v = l[index]
    except IndexError:
        v = default
    return v


def _bregman_map(M, lambda_k, diff_d_k):
    """ Bregman map, according to [1], Eq. 2.9, with f(x) := -d(lambda), and M*psi(x,y) := M/2*||lambda-lambda_k||_2
    Old:
    lambda_bregman = lambda_k + float(1.0)/M*diff_d_k
    return self._project_on_dual_feasible_set(lambda_bregman)
    """
    return lambda_k + float(1.0) / M * diff_d_k


def is_package(name):
    """Check if string maps to a package installed via pip.

    name (unicode): Name of package.
    RETURNS (bool): True if installed package, False if not.
    """
    import pkg_resources
    name = name.lower()
    packages = pkg_resources.working_set.by_key.keys()
    for package in packages:
        if package.lower().replace('-', '_') == name:
            return True
    return False


def create_client_from_parsed_globals(session, service_name, parsed_globals,
    overrides=None):
    """Creates a service client, taking parsed_globals into account

    Any values specified in overrides will override the returned dict. Note
    that this override occurs after 'region' from parsed_globals has been
    translated into 'region_name' in the resulting dict.
    """
    client_args = {}
    if 'region' in parsed_globals:
        client_args['region_name'] = parsed_globals.region
    if 'endpoint_url' in parsed_globals:
        client_args['endpoint_url'] = parsed_globals.endpoint_url
    if 'verify_ssl' in parsed_globals:
        client_args['verify'] = parsed_globals.verify_ssl
    if overrides:
        client_args.update(overrides)
    return session.create_client(service_name, **client_args)


def oz_to_g(oz):
    """
    Convert ounces to grams
    """
    return oz * 28.34952


def solar_elevation_angle(solar_zenith_angle):
    """Returns Solar Angle in Degrees, with Solar Zenith Angle, solar_zenith_angle."""
    solar_elevation_angle = 90 - solar_zenith_angle
    return solar_elevation_angle


def om_icons():
    """ Exclamation icon if the site is not up to date """


def build_spellchcker():
    """Build the Solr spell-checker."""


def check_length(universe_dict):
    """Checks the name of all the DataFrames in the dictionary of time series.

    :param universe_dict:       The dictionary of time series
    :type  universe_dict:       dict
    """
    for df_name in universe_dict:
        print(len(universe_dict[df_name]))


def _safe_single_attr(x):
    """Handle cleaning of attributes after extraction:
      - '.'s to indicate None
      - tuples where we expect a single value
    """
    if x is None or x is '.':
        return None
    elif isinstance(x, (list, tuple)):
        return x[0]
    else:
        return x


def manage_getPermissionMapping():
    """Return the permission mapping for the object

        This is a list of dictionaries with:

          permission_name -- The name of the native object permission

          class_permission -- The class permission the permission is
             mapped to.
        """


def make_grid(freq, m, n):
    """Make the geodesic pattern grid"""
    grid = {}
    rng = 2 * freq // (m + n)
    for i in range(rng):
        for j in range(rng):
            x = i * -n + j * (m + n)
            y = i * (m + n) + j * -m
            if x >= 0 and y >= 0 and x + y <= freq:
                grid[i, j] = x, y
    return grid


def create_treelist(dataclass, uri):
    """ create a list of resources out of a tree

    This function is used for the COPY, MOVE and DELETE methods

    uri - the root of the subtree to flatten

    It will return the flattened tree as list

    """
    queue = [uri]
    list = [uri]
    while len(queue):
        element = queue[-1]
        if dataclass.is_collection(element):
            childs = dataclass.get_childs(element)
        else:
            childs = []
        if len(childs):
            list = list + childs
        del queue[-1]
        if len(childs):
            queue = queue + childs
    return list


def hyphenate_filter(s):
    """ Filter for lowercasing and hyphenating a string. """
    try:
        return s.lower().strip().replace(' ', '-')
    except ValueError:
        return s


def isobaric_expansion(V, dV_dT):
    """
    Calculate the isobaric coefficient of a thermal expansion, given its
    molar volume at a certain `T` and `P`, and its derivative of molar volume
    with respect to `T`.

    .. math::
        \\beta = \\frac{1}{V}\\left(\\frac{\\partial V}{\\partial T} \\right)_P

    Parameters
    ----------
    V : float
        Molar volume at `T` and `P`, [m^3/mol]
    dV_dT : float
        Derivative of molar volume with respect to `T`, [m^3/mol/K]

    Returns
    -------
    beta : float
        Isobaric coefficient of a thermal expansion, [1/K]

    Notes
    -----
    For an ideal gas, this expression simplified to:

    .. math::
        \\beta = \\frac{1}{T}

    Examples
    --------
    Calculated for hexane from the PR EOS at 299 K and 1 MPa (liquid):

    >>> isobaric_expansion(0.000130229900873546, 1.58875261849113e-7)
    0.0012199599384121608

    References
    ----------
    .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    """
    return dV_dT / V


def abortArgsNeeded(term, index, argsNeeded):
    """Issues the error message when an operator is provided with an insufficient
    number of arguments."""
    print('rpn:  error in arg ' + format(index) + ":  operator '" + term +
        "' requires " + format(argsNeeded) + ' argument', end='')
    print('s' if argsNeeded > 1 else '')


@staticmethod
def _global_parse_mode():
    """
        Detect global parse mode

        :return:
        """
    from aiogram import Bot
    bot = Bot.get_current()
    if bot is not None:
        return bot.parse_mode


def merge(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result


def check_field_applicability(tag):
    """
    Check the applicability of a 'field' for an object.
    """
    return not tag.field in tag.item_type.fields.all()


def getCurrentFolderUrl():
    """Returns the URL of the current folder as determined by
           self.getCurrentFolder(), used heavily in actions.
        """


@staticmethod
def _format_match(value) ->str:
    """
         Formatting value in the event of MATCHES operation
         encapsulating the value inside regex keyword
         :param value: str
         :return: str
         """
    return "'{}'".format(value)


@staticmethod
def dva2ret(xdva):
    """Convert degrees of visual angle (dva) to retinal eccentricity (um)

        Assumes that one degree of visual angle is equal to 280 um on the
        retina [Curcio1990]_.
        """
    return 280.0 * xdva


def service_retries():
    """A default number of tries to re-try an external service."""
    return range(30)


def type_object_attrgetter(obj, attr, *defargs):
    """
    This implements an improved attrgetter for type objects (i.e. classes)
    that can handle class attributes that are implemented as properties on
    a metaclass.

    Normally `getattr` on a class with a `property` (say, "foo"), would return
    the `property` object itself.  However, if the class has a metaclass which
    *also* defines a `property` named "foo", ``getattr(cls, 'foo')`` will find
    the "foo" property on the metaclass and resolve it.  For the purposes of
    autodoc we just want to document the "foo" property defined on the class,
    not on the metaclass.

    For example::

        >>> class Meta(type):
        ...     @property
        ...     def foo(cls):
        ...         return 'foo'
        ...
        >>> class MyClass(metaclass=Meta):
        ...     @property
        ...     def foo(self):
        ...         ""\"Docstring for MyClass.foo property.""\"
        ...         return 'myfoo'
        ...
        >>> getattr(MyClass, 'foo')
        'foo'
        >>> type_object_attrgetter(MyClass, 'foo')
        <property at 0x...>
        >>> type_object_attrgetter(MyClass, 'foo').__doc__
        'Docstring for MyClass.foo property.'

    The last line of the example shows the desired behavior for the purposes
    of autodoc.
    """
    for base in obj.__mro__:
        if attr in base.__dict__:
            if isinstance(base.__dict__[attr], property):
                return base.__dict__[attr]
            break
    return getattr(obj, attr, *defargs)


def setTracebackClearing(clear=True):
    """
    Enable or disable traceback clearing.
    By default, clearing is disabled and Python will indefinitely store unhandled exception stack traces.
    This function is provided since Python's default behavior can cause unexpected retention of
    large memory-consuming objects.
    """
    global clear_tracebacks
    clear_tracebacks = clear


def relabel_node(bg, old_name, new_name):
    """
    Change the name of a node.

    param old_name: The previous name of the node
    param new_name: The new name of the node
    """
    define = bg.defines[old_name]
    del bg.defines[old_name]
    bg.defines[new_name] = define
    edge = bg.edges[old_name]
    del bg.edges[old_name]
    bg.edges[new_name] = edge
    for k in bg.edges.keys():
        new_edges = set()
        for e in bg.edges[k]:
            if e == old_name:
                new_edges.add(new_name)
            else:
                new_edges.add(e)
        bg.edges[k] = new_edges


def unsqueeze(input, dim):
    """Add the given dimension of size 1.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    dim : int
        The dimension to be unsqueezed.

    Returns
    -------
    Tensor
        The result tensor.
    """
    pass


def get_coord(data_object, variable, data):
    """
    Find a specified coord

    :param data_object:
    :param variable:
    :param data:
    :return:
    """
    from iris.exceptions import CoordinateNotFoundError
    if variable in [data_object.name(), data_object.standard_name,
        data_object.long_name, 'default']:
        return data
    else:
        if variable.startswith('search:'):
            number_of_points = float(variable.split(':')[1])
            for coord in data_object.coords():
                if coord.shape[0] == number_of_points:
                    break
        else:
            try:
                coord = data_object.coord(variable)
            except CoordinateNotFoundError:
                return None
        return coord


def __delitem__(username):
    """Delete the conversation the inbox user has with the user
        `username`.
        """


def get_Callable_args_res(clb):
    """Python version independent function to obtain the parameters
    of a typing.Callable object. Returns as tuple: args, result.
    Tested with CPython 2.7, 3.5, 3.6 and Jython 2.7.1.
    """
    try:
        return clb.__args__, clb.__result__
    except AttributeError:
        return clb.__args__[:-1], clb.__args__[-1]


def hasBeenMoved(obj, source):
    """Returns True if the object has been moved away from ``source``.
        """


def authGSSServerCacheName(context):
    """
    Get the name of the credential cache created with
    L{authGSSServerStoreDelegate}.
    This method must only be called after L{authGSSServerStoreDelegate}.

    @param context: The context object returned from L{authGSSClientInit}.

    @return: A string containing the cache name.
    """


@staticmethod
def colorMsg(m='', c='red', flag=False, title=False, end='\n'):
    """Color text output"""
    sign = '30' if title else '1'
    colorCode = {'red': 31, 'green': 32, 'yellow': 33, 'blue': 34, 'pink':
        35, 'cblue': 36, 'white': 37}
    color = colorCode.get(c, 31) + (10 if title else 0)
    colorSign = '\x1b[' + sign + ';' + str(color) + 'm{0}\x1b[0m'
    msg = colorSign.format(m)
    if flag:
        return colorSign
    else:
        print(msg, end=end)
        return msg


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 get_mimetype_from_response(response, strip_params=False):
    """
    Get the mimetype from the HTTP response
    """
    mimetype = response.getheader('Content-type', None)
    if not mimetype:
        raise ValueError('No Content-Type header in response')
    if strip_params:
        return mimetype.split(';', 1)[0]
    else:
        return mimetype


def get_service_type(f):
    """Retrieves service type from function."""
    return getattr(f, 'service_type', None)


@staticmethod
def convert_duration_to_string(duration):
    """Convert a duration object to a duration string (in seconds).

        Args:
            duration (dict): Duration dictionary.

        Returns:
            str: Duration string.
        """
    duration_seconds = 0.0
    if 'seconds' in duration:
        duration_seconds += duration['seconds']
    if 'nanos' in duration:
        duration_seconds += duration['nanos'] * 10 ** -9
    if duration_seconds.is_integer():
        duration_str = int(duration_seconds)
    else:
        duration_str = '{:0.3f}'.format(duration_seconds)
    return str(duration_str) + 's'


def get_setting(varname):
    """ Returns the value of a configuration variable. """
    gl = globals()
    if varname not in gl.keys():
        raise ValueError('Unknown setting %s' % varname)
    return gl[varname]


def _update_lut(cmap, colors):
    """Change the LUT values in a matplotlib colormap in-place."""
    cmap._lut[:256] = colors
    cmap._set_extremes()


@staticmethod
def get_slice_wcs(wcs, slx=slice(480, 520), sly=slice(480, 520)):
    """Get slice of a WCS including higher orders like SIP and DET2IM

        The normal `~astropy.wcs.wcs.WCS` `slice` method doesn't apply the
        slice to all of the necessary keywords.  For example, SIP WCS also
        has a `CRPIX` reference pixel that needs to be offset along with
        the main `CRPIX`.

        Parameters
        ----------
        slx, sly : slice
            Slices in x and y dimensions to extract

        """
    NX = slx.stop - slx.start
    NY = sly.stop - sly.start
    slice_wcs = wcs.slice((sly, slx))
    slice_wcs.naxis1 = slice_wcs._naxis1 = NX
    slice_wcs.naxis2 = slice_wcs._naxis2 = NY
    if hasattr(slice_wcs, 'sip'):
        if slice_wcs.sip is not None:
            for c in [0, 1]:
                slice_wcs.sip.crpix[c] = slice_wcs.wcs.crpix[c]
    ACS_CRPIX = [4096 / 2, 2048 / 2]
    dx_crpix = slice_wcs.wcs.crpix[0] - ACS_CRPIX[0]
    dy_crpix = slice_wcs.wcs.crpix[1] - ACS_CRPIX[1]
    for ext in ['cpdis1', 'cpdis2', 'det2im1', 'det2im2']:
        if hasattr(slice_wcs, ext):
            wcs_ext = slice_wcs.__getattribute__(ext)
            if wcs_ext is not None:
                wcs_ext.crval[0] += dx_crpix
                wcs_ext.crval[1] += dy_crpix
                slice_wcs.__setattr__(ext, wcs_ext)
    return slice_wcs


def write_uint16(data, value, index):
    """ Write 16bit value into data string at index and return new string """
    data = data.decode('utf-8')
    return '{}{:02x}{:02x}{}'.format(data[:index * 4], value & 255, value >>
        8, data[index * 4 + 4:])


def filter_entity(entity_ref):
    """Filter out private items in an entity dict.

    :param entity_ref:  the entity dictionary. The 'dn' field will be removed.
        'dn' is used in LDAP, but should not be returned to the user.  This
        value may be modified.

    :returns: entity_ref

    """
    if entity_ref:
        entity_ref.pop('dn', None)
    return entity_ref


def _differences(weights):
    """Iterates over the input yielding differences between adjacent items."""
    previous_weight = None
    have_previous_weight = False
    for w in weights:
        if have_previous_weight:
            yield w - previous_weight
        previous_weight = w
        have_previous_weight = True


def best_type(dx, da, dc, ufflib, types):
    """Chooses the best UFF type according to neighborhood."""
    mincost = 1000.0
    mintyp = None
    for typ in types:
        xx, aa, cc = ufflib[typ]
        cost_x = (dx - xx) ** 2 / 2.5
        cost_a = (da - aa) ** 2 / 180.0
        cost_c = (dc - cc) ** 2 / 4.0
        cost = cost_x + cost_a + cost_c
        if cost < mincost:
            mintyp = typ
            mincost = cost
    return mintyp


def test_write_scale():
    """
Test the standard scaling policies of `write`.

Integer input data:

    >>> input = [[-2**8, 0, 2**8]]
    >>> stream = write(input)
    >>> output = read(stream, scale=False)
    >>> (output == input).all()
    True

    >>> stream = write(input, scale=False)
    >>> output = read(stream, scale=False)
    >>> (output == input).all()
    True

    >>> stream = write(input, scale=True)
    >>> output = read(stream, scale=False)
    >>> (output == [[-2**15, 0, 2**15 - 1]]).all()
    True

Floating-point input data:

    >>> input = [[-0.5, 0.0, 0.5]]
    >>> stream = write(input)
    >>> output = read(stream)
    >>> (output == input).all()
    True

    >>> stream = write(input, scale=True)
    >>> output = read(stream)
    >>> (output == [[-1.0, 0.0, 1.0 - 2**(-15)]]).all()
    True

    >>> input = np.arange(-2**15, 2**15).astype(np.float64)
    >>> stream = write(input, scale=False)
    >>> output = read(stream, scale=False)
    >>> (output == input).all()
    True
    """


def uint64_tag(name, value):
    """Create a DMAP tag with uint64 data."""
    return name.encode('utf-8') + b'\x00\x00\x00\x08' + value.to_bytes(8,
        byteorder='big')


def make_vertical_bar(percentage, width=1):
    """
    Draws a vertical bar made of unicode characters.

    :param value: A value between 0 and 100
    :param width: How many characters wide the bar should be.
    :returns: Bar as a String
    """
    bar = ' _▁▂▃▄▅▆▇█'
    percentage //= 10
    if percentage < 0:
        output = bar[0]
    elif percentage >= len(bar):
        output = bar[-1]
    else:
        output = bar[percentage]
    return output * width


def extract_default_resouces(args):
    """Helper function to extracts default resources from config file
    Args:
    args (object): Arguments object
    Returns:
    dict: Default section from config or None

    """
    res = list(filter(lambda x: x.get('default'), args.hosts_config))
    if res:
        return res[0]['default']['resources']
    return None


def load(create=False):
    """
        load data for a behavior
        """


def capword(s):
    """
    >>> capword('foo')
    'Foo'
    """
    return s[0].upper() + s[1:]


def inherit_doc(cls):
    """
    A decorator that makes a class inherit documentation from its parents.
    """
    for name, func in vars(cls).items():
        if name.startswith('_'):
            continue
        if not func.__doc__:
            for parent in cls.__bases__:
                parent_func = getattr(parent, name, None)
                if parent_func and getattr(parent_func, '__doc__', None):
                    func.__doc__ = parent_func.__doc__
                    break
    return cls