def _checksubrepostate(pushop):
    """Ensure all outgoing referenced subrepo revisions are present locally"""
    for n in pushop.outgoing.missing:
        ctx = pushop.repo[n]
        if b'.hgsub' in ctx.manifest() and b'.hgsubstate' in ctx.files():
            for subpath in sorted(ctx.substate):
                sub = ctx.sub(subpath)
                sub.verify(onpush=True)


def laplace_noise_scale(k, num_attributes, num_tuples, epsilon):
    """
    Laplace scale for noisy conditional distribution.
    """
    return 2 * (num_attributes - k) / (num_tuples * epsilon)


def remove_sensitive_data(data):
    """
    Removes token or WSkey from url and token from a request header.
    WSkey has always 80 characters.

    Args:
        obj: str or dict,   response or request url, or request.header attribute
    """
    if type(data) == str:
        start_pos = data.index('wskey=')
        data = f'{data[:start_pos + 6]}WSKEY-HERE{data[start_pos + 86:]}'
    elif type(data) == dict:
        try:
            data['Authorization'] = 'AUTH-HERE'
        except IndexError:
            pass
    return data


def cmp(a, b):
    """Old Python 2 function"""
    return (a > b) - (a < b)


def calc_target_joint_dimension_from_link_list(link_list):
    """Calculate Total Degrees of Freedom from link list

    Parameters
    ----------
    link_list : list[skrobot.model.Link]

    Returns
    -------
    n : int
        total Degrees of Freedom
    """
    n = 0
    for link in link_list:
        if hasattr(link, 'joint'):
            n += link.joint.joint_dof
    return n


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


@classmethod
def process(cls, config_interp, logger=None):
    """Parse the interp field of the config dict.

        :param config_interp:   The configuration dict for the interp field.
        :param logger:          A logger object for logging debug info. [default: None]

        :returns: an Interp instance
        """
    import piff
    if 'type' not in config_interp:
        raise ValueError("config['interp'] has no type field")
    interp_class = getattr(piff, config_interp['type'])
    kwargs = interp_class.parseKwargs(config_interp, logger)
    interp = interp_class(**kwargs)
    return interp


def _should_run_cmake(commands, cmake_with_sdist):
    """Return True if at least one command requiring ``cmake`` to run
    is found in ``commands``."""
    for expected_command in ['build', 'build_ext', 'develop', 'install',
        'install_lib', 'bdist', 'bdist_dumb', 'bdist_egg', 'bdist_rpm',
        'bdist_wininst', 'bdist_wheel', 'test']:
        if expected_command in commands:
            return True
    if 'sdist' in commands and cmake_with_sdist:
        return True
    return False


def consentToProcessing(request):
    """Mark the current user as having agreed to the processing explicitly"""
    NotImplemented


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 average_islands_scale():
    """Average the size of separate UV islands, based on their area in 3D space

    """
    pass


@classmethod
def from_param(cls, seq):
    """  Allow implicit conversions """
    return seq if isinstance(seq, cls) else cls(seq)


def all_equal(list_=None):
    """
    Check whether all elements of a list are equal.

    Parameters
    ----------
    list_ : :class:`list`
        List whose elements should be checked for being equal

    Returns
    -------
    result : :class:`boolean`

    """
    return list_.count(list_[0]) == len(list_)


def _delete_from_list(list, item):
    """
    Deletes a requested item from a list. If the item does not exist in the
    list, a ValueError is raised

    Parameters
    ----------
    list : ``list``
        The list from which an item will be deleted
    item : ``object``
        The object to delete from the list
    """
    list.pop(list.index(item))


def time_iso_format(value):
    """
    Serialise a datetime.time to ISO string format.
    """
    return value.isoformat()


def __getitem__(index):
    """Return the value at the given index.

        An :class:`IndexError` is raised if the index cannot be found.
        """


def temperature_processor(ds):
    """
    Process ERA5-Land temperatures.

    Combine time and step dimensions into a singular timestep dimension. Convert
    Kelvin to Fahrenheit.
    """
    ds = (ds - 273.15) * (9.0 / 5.0) + 32.0
    ds = ds.stack(timestep=('time', 'step'))
    ds = ds.assign_coords(timestep=ds.timestep.time + ds.timestep.step)
    return ds


def __version__():
    """return package version"""
    return '0.2.10'


def gear_for_speed_profiles(gs, curr_speed, current_gear, gear_cnt,
    clutch_duration=5):
    """
    Return the gear that must be used and the clutch condition

    :param gs:
    :param curr_speed:
    :param current_gear:
    :param gear_cnt:
    :param clutch_duration: in sim step
    :return:
    """
    upshift_offs = 0.0
    downshift_off = 0.1
    gear_limits = [0]
    gear_limits.extend(gs)
    gear_limits.append(200)
    if gear_limits[current_gear - 1] - gear_limits[current_gear - 1
        ] * downshift_off <= curr_speed < gear_limits[current_gear
        ] + gear_limits[current_gear] * upshift_offs:
        if gear_cnt == 0:
            return current_gear, gear_cnt
        else:
            gear_cnt -= 1
            return current_gear, gear_cnt
    else:
        iter = 1
        gear_search = 1
        while iter == 1:
            if gear_limits[gear_search - 1] <= curr_speed < gear_limits[
                gear_search]:
                gear_cnt = clutch_duration
                current_gear = gear_search
                iter = 0
            else:
                gear_search += 1
        return current_gear, gear_cnt


def expand_slice(s, a, b, start=0, stop=None):
    """Expand a slice on the start/stop limits"""
    n1 = max(s.start - a, start)
    n2 = s.stop + b
    if stop is not None:
        n2 = min(n2, stop)
    return slice(n1, n2, 1)


def get_template_len(template_file):
    """
        return a dict of each seq's len based on the faidx
    """
    template_len_for = {}
    with open(template_file + '.fai') as f:
        for line in f:
            id, length = line.split('\t')[0:2]
            template_len_for[id] = int(length)
    return template_len_for


def nibbles(byte):
    """
    @returns (high nibble, low nibble)
    """
    return byte >> 4, byte & 15


def disable_session_expiry_refresh(f):
    """
	Security policy dictates that the user's session should time out after a set duration.
	The user's session is automatically refreshed (that is, the expiration date
	of their session is moved forward to 30 minutes after the request time) whenever
	the user performs an action. Pages such as the Calendar, Tool Control, and Status Dashboard
	all have polling AJAX requests to update information on the page. These regular polling
	requests should not refresh the session (because it does not indicate the user took
	an action). Place this decorator on any view that is regularly polled so that the
	user's session is not refreshed.
	"""
    f.disable_session_expiry_refresh = True
    return f


@staticmethod
def _format_result(result):
    """ Format the command result for the backend
        """
    if result is None:
        return {'status': False, 'output': 'None returned'}
    elif result is True:
        return {'status': True}
    else:
        return {'status': True, 'output': result}


@staticmethod
def p_compu_method_optional_list(p):
    """compu_method_optional_list : compu_method_optional
                                      | compu_method_optional compu_method_optional_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def simplified_pos(pos, tagset=None, default=''):
    """
    Return a simplified POS tag for a full POS tag `pos` belonging to a tagset `tagset`. By default the WordNet
    tagset is assumed.
    Does the following conversion by default:

    - all N... (noun) tags to 'N'
    - all V... (verb) tags to 'V'
    - all ADJ... (adjective) tags to 'ADJ'
    - all ADV... (adverb) tags to 'ADV'
    - all other to `default`

    Does the following conversion by with ``tagset=='penn'``:

    - all N... (noun) tags to 'N'
    - all V... (verb) tags to 'V'
    - all JJ... (adjective) tags to 'ADJ'
    - all RB... (adverb) tags to 'ADV'
    - all other to `default`

    :param pos: a POS tag
    :param tagset: the tagset used for `pos`
    :param default: default return value when tag could not be simplified
    :return: simplified tag
    """
    if tagset == 'penn':
        if pos.startswith('N') or pos.startswith('V'):
            return pos[0]
        elif pos.startswith('JJ'):
            return 'ADJ'
        elif pos.startswith('RB'):
            return 'ADV'
        else:
            return default
    elif pos.startswith('N') or pos.startswith('V'):
        return pos[0]
    elif pos.startswith('ADJ') or pos.startswith('ADV'):
        return pos[:3]
    else:
        return default


@staticmethod
def reset(sample_idx):
    """Reset layer variables."""
    pass


def get_time_parts_from_string(time_string):
    """Extract and return hh, mm, ss from a string of form hh:mm or hh:mm:ss.

    hh refers to two-digit hour, mm : two-digit minute, ss : two-digit second
    """
    hour = int(time_string[0:2])
    minute = int(time_string[3:5])
    second = int(time_string[6:8]) if len(time_string.strip()) == 7 else 0
    return hour, minute, second


def face_select_hide(unselected: bool=False):
    """Hide selected faces

    :param unselected: Unselected, Hide unselected rather than selected objects
    :type unselected: bool
    """
    pass


def _check_bool(name, value):
    """Check for boolean value."""
    if value.lower() in ('yes', 'on', 'true'):
        return True
    elif value.lower() in ('no', 'off', 'false'):
        return False
    elif value.isdigit():
        return bool(int(value))
    raise ValueError('{name}: ambiguous boolean value: {value}'.format(name
        =name, value=value))


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


def max(cube1, cube2):
    """Return max value between two cubes
    """
    return (cube1 > cube2) * cube1 + (cube1 <= cube2) * cube2


def register_gitlab_instance(shortname, url):
    """Register a gitlab instance.

    :param shortname: Short name (e.g. "gitlab")
    :param url: URL to the gitlab instance
    """
    from breezy.bugtracker import tracker_registry, ProjectIntegerBugTracker
    tracker_registry.register(shortname, ProjectIntegerBugTracker(shortname,
        url + '/{project}/issues/{id}'))


def verbosity_to_polyjit_log_level(verbosity: int):
    """Transfers the verbosity level to a useable polyjit format."""
    polyjit_log_levels = {(0): 'off', (1): 'error', (2): 'warn', (3):
        'info', (4): 'debug', (5): 'trace', (6): 'trace'}
    return polyjit_log_levels[verbosity]


def no_namedtuple_attrib_docstring(app, what, name, obj, options, lines):
    """
    `namedtuples` are awesome.  Unfortunately, if you find yourself with a large
    one and you use Sphinx for documentation you're going to find yourself with
    a gigantic part of your documentation documenting members as 'Alias for
    field...'  This function overrides that behavior.

    :param app:
    :param what:
    :param name:
    :param obj:
    :param options:
    :param lines: the lines that may contain Alias for field number'
    :return:

    .. seealso::

         https://chrisdown.name/2015/09/20/removing-namedtuple-docstrings-from-sphinx.html
    """
    is_namedtuple_docstring = len(lines) > 0 and lines[0].startswith(
        'Alias for field number')
    if is_namedtuple_docstring:
        del lines[:]


def insert_ordered(value, array):
    """
    This will insert the value into the array, keeping it sorted, and returning the
    index where it was inserted
    """
    index = 0
    for n in range(0, len(array)):
        if value >= array[n]:
            index = n + 1
    array.insert(index, value)
    return index


@classmethod
def add_parser(cls, subparser):
    """Create parser for command line."""
    parser = super().add_parser(subparser)
    parser.add_argument('--bare', action='store_true', help=
        'Print only version')
    return parser


def project_opened(project):
    """This function is called after opening the project"""


def dms2deg(x):
    """Transform *degrees:arcminutes:arcseconds* strings to degrees.

    Parameters
    ----------
    x : str
        The input angle written in the form, degrees:arcminutes:arcseconds

    Returns
    -------
    out : float
        The input angle as a number of degrees.

    """
    from astropy.coordinates import Angle
    ac = Angle(x, unit='degree')
    deg = float(ac.to_string(unit='degree', decimal=True))
    return deg


def suck_out_editions(reporters):
    """Builds a dictionary mapping edition keys to their root name.

    The dictionary takes the form of:
        {
         "A.":   "A.",
         "A.2d": "A.",
         "A.3d": "A.",
         "A.D.": "A.D.",
         ...
        }

    In other words, this lets you go from an edition match to its parent key.
    """
    editions_out = {}
    for reporter_key, data_list in reporters.items():
        for data in data_list:
            for edition_key, edition_value in data['editions'].items():
                try:
                    editions_out[edition_key]
                except KeyError:
                    editions_out[edition_key] = reporter_key
    return editions_out


@classmethod
def url_from_title(cls, title, lang='en'):
    """The Wikipedia URL for a given page title."""
    return 'http://{}/wiki/{}'.format(cls.hostname_from_lang(lang), title)


@classmethod
def should_check_origin(cls, handler):
    """Should the Handler check for CORS origin validation?

        Origin check should be skipped for token-authenticated requests.

        Returns:
        - True, if Handler must check for valid CORS origin.
        - False, if Handler should skip origin check since requests are token-authenticated.
        """
    return not cls.is_token_authenticated(handler)


def dict_diff(first, second):
    """ Return a dict of keys that differ with another config object.  If a value is
        not found in one fo the configs, it will be represented by KEYNOTFOUND.
        @param first:   Fist dictionary to diff.
        @param second:  Second dicationary to diff.
        @return diff:   Dict of Key => (first.val, second.val)
    """
    KEYNOTFOUND = '<KEYNOTFOUND>'
    diff = {}
    for key in first.keys():
        if key not in second:
            diff[key] = first[key], KEYNOTFOUND
        elif first[key] != second[key]:
            diff[key] = first[key], second[key]
    for key in second.keys():
        if key not in first:
            diff[key] = KEYNOTFOUND, second[key]
    return diff


@classmethod
def _make_transaction_id(cls, *args):
    """construct the transaction id using the default parts and any args"""
    return '.'.join(map(str, filter(None, cls._get_transaction_id_parts() +
        list(args))))


def _get_wf_name(bold_fname):
    """
    Derive the workflow name for supplied BOLD file.

    >>> _get_wf_name('/completely/made/up/path/sub-01_task-nback_bold.nii.gz')
    'func_preproc_task_nback_wf'
    >>> _get_wf_name('/completely/made/up/path/sub-01_task-nback_run-01_echo-1_bold.nii.gz')
    'func_preproc_task_nback_run_01_echo_1_wf'

    """
    from nipype.utils.filemanip import split_filename
    fname = split_filename(bold_fname)[1]
    fname_nosub = '_'.join(fname.split('_')[1:])
    name = 'func_preproc_' + fname_nosub.replace('.', '_').replace(' ', ''
        ).replace('-', '_').replace('_bold', '_wf')
    return name


def _enable_plugin(env, module):
    """Enable the given plugin module if it wasn't disabled explicitly."""
    if env.is_component_enabled(module) is None:
        env.enable_component(module)


def encode_entry(entry):
    """Convert from an entry to a JSON-representation."""
    return [entry.key, entry.settings, entry.constraints.to_json()]


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 convert2boolean(arg):
    """convert2boolean is used for environmental variables that must be
    returned as boolean"""
    if not isinstance(arg, bool):
        return arg.lower() in ('yes', 'true', 't', '1', 'y')
    return arg


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

        :param MemberSpaceLimitsChangeStatusDetails val:
        :rtype: EventDetails
        """
    return cls('member_space_limits_change_status_details', val)


def gen_img_code(github_url, alt, width=None, height=None):
    """
    Generate image markdown code with absolute URL link <deprecated>

    github_path: <username>/<repo>/<branch>/<folders>/<filename>
    """
    alt = alt.replace('\n', ' ')
    if height or width:
        width = 'width="{}"'.format(width) if width else ''
        height = 'height="{}"'.format(height) if height else ''
        return ''.format(github_url, alt,
            width, height)
    else:
        return '![{}]({})'.format(alt, github_url)


def time2tuple(timevalue):
    """Convert float time to ( seconds, millionths ) tuple"""
    return int(float(timevalue)), int((timevalue - int(timevalue)) * 1000000000
        )


@staticmethod
def should_wrap():
    """
        While returning the response the,
        kwikapi will wrap the response as -
        {success: value, result: value}
        This method, can used in above situation,
        if no wrapping is required,
        override this method in the protocol class.
        """
    return True


@classmethod
def from_csv(cls, s, columns=None, columns_row=True, **kwargs):
    """
        Load and decode CSV data from url, filepath or data-string.
        Decoder specific options can be passed using kwargs:
        https://docs.python.org/3/library/csv.html
        Return a new dict instance. A ValueError is raised in case of failure.
        """
    kwargs['columns'] = columns
    kwargs['columns_row'] = columns_row
    return cls(s, format='csv', **kwargs)


@classmethod
def register_type_pre_project_template(cls, project, template):
    """Hook to register custom resources before the project cloudformation
        stack is created.
        Note: This hook will be only executed once per resource type."""
    pass


def addTemplate(id, template):
    """ add the given ttw view template to the container
            and return it acquisition wrapped in the container """


def register_sentry(sentry_dsn):
    """Given a Raven client and an RQ worker, registers exception handlers
    with the worker so exceptions are logged to Sentry.
    """
    import sentry_sdk
    from sentry_sdk.integrations.rq import RqIntegration
    sentry_sdk.init(sentry_dsn, integrations=[RqIntegration()])


def create_pull_request(repo, branch_name, base=None, title=None):
    """Creates a pull request for the given branch"""
    base = base or 'master'
    title = title or 'Auto-Generated Pull Request'
    pull_request = repo.create_pull(title, base, branch_name)
    return pull_request


def marker_tag(marker):
    """ Create a marker tag for the given marker name. """
    return '_PELTAK-SCAFFOLD-{}_'.format(marker.upper())


def is_command(text):
    """
    Checks if `text` is a command. Telegram chat commands start with the '/' character.
    :param text: Text to check.
    :return: True if `text` is a command, else False.
    """
    return text.startswith('/')


@classmethod
def fromPageBotString(cls, pbs):
    """Construct a formatted cls.newString() from PageBotString instance.
        To be implemented by inheriting BabelString classes.
        """
    raise NotImplementedError


def __add__(form_fields):
    """Add two form fields collections (IFormFields)

        Return a new IFormFields that is the concatination of the two
        IFormFields.
        """


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


@classmethod
def compile(cls, pattern):
    """ Check whether we've parsed this pattern before, and if so,
            re-use the result """
    if pattern in cls._pattern_cache:
        return cls._pattern_cache[pattern]
    cp = cls._pattern_cache[pattern] = cls(pattern)
    return cp


@staticmethod
def __getSetDiscoModeForBridgeLampCmd(mode):
    """Give 'Set disco mode for bridge lamp' command

    Keyword arguments:
      mode -- (int) Disco mode between 1 and 9

    return: (bytearray) 'Set disco mode for bridge lamp' command
    """
    mode = int(mode)
    if mode < 1:
        mode = 1
    elif mode > 9:
        mode = 9
    mode &= 255
    return bytearray([49, 0, 0, 0, 4, mode, 0, 0, 0])


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


def describe_activity(activityArn=None):
    """
    Describes an activity.
    See also: AWS API Documentation

    :example: response = client.describe_activity(
        activityArn='string'
    )

    :type activityArn: string
    :param activityArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the activity to describe.

    :rtype: dict
    :return: {
        'activityArn': 'string',
        'name': 'string',
        'creationDate': datetime(2015, 1, 1)
    }

    """
    pass


def fib(n):
    """Fibonacci example function

    Args:
      n (int): integer

    Returns:
      int: n-th Fibonacci number
    """
    assert n > 0
    a, b = 1, 1
    for i in range(n - 1):
        a, b = b, a + b
    return a


def change_point_on_centroid(x, c, f, al):
    """Helper function for simplex optimization"""
    x_new = c + al * (x - c)
    return x_new, f(x_new)


def _format_error_line(error):
    """Formats the error line for human consumption"""
    return '{}:{}:{} -- {}: {}'.format(*error)


def is_valid_input(ext):
    """ Checks if input file format is compatible with Open Babel """
    formats = ['abinit', 'acesout', 'acr', 'adfout', 'alc', 'aoforce',
        'arc', 'axsf', 'bgf', 'box', 'bs', 'c09out', 'c3d2', 'caccrt',
        'can', 'car', 'castep', 'ccc', 'cdjson', 'cdx', 'cdxml', 'cif',
        'ck', 'cml', 'cmlr', 'CONFIG', 'CONTCAR', 'CONTFF', 'crk2d',
        'crk3d', 'ct', 'cub', 'cube', 'dallog', 'dalmol', 'dat', 'dmol',
        'dx', 'ent', 'exyz', 'fa', 'fasta', 'fch', 'fchk', 'fck', 'feat',
        'fhiaims', 'fract', 'fs', 'fsa', 'g03', 'g09', 'g92', 'g94', 'g98',
        'gal', 'gam', 'gamess', 'gamin', 'gamout', 'got', 'gpr', 'gro',
        'gukin', 'gukout', 'gzmat', 'hin', 'HISTORY', 'inchi', 'inp', 'ins',
        'jin', 'jout', 'log', 'lpmd', 'mcdl', 'mcif', 'MDFF', 'mdl', 'ml2',
        'mmcif', 'mmd', 'mmod', 'mol', 'mol2', 'mold', 'molden', 'molf',
        'moo', 'mop', 'mopcrt', 'mopin', 'mopout', 'mpc', 'mpo', 'mpqc',
        'mrv', 'msi', 'nwo', 'orca', 'out', 'outmol', 'output', 'pc',
        'pcjson', 'pcm', 'pdb', 'pdbqt', 'png', 'pos', 'POSCAR', 'POSFF',
        'pqr', 'pqs', 'prep', 'pwscf', 'qcout', 'res', 'rsmi', 'rxn', 'sd',
        'sdf', 'siesta', 'smi', 'smiles', 'smy', 'sy2', 't41', 'tdd',
        'text', 'therm', 'tmol', 'txt', 'txyz', 'unixyz', 'VASP', 'vmol',
        'xml', 'xsf', 'xtc', 'xyz', 'yob']
    return ext in formats


def hmsm_to_days(hour=0, _min=0, sec=0, micro=0):
    """Convert hours, minutes, seconds, and microseconds to fractional days.
    --------
    Examples
    --------
    >>> hmsm_to_days(hour=6)
    0.25
    --------
    :param hour: Hour number. Defaults to 0. (int)
    :param min: Minute: number. Defaults to 0. (int)
    :param sec: Second number. Defaults to 0. (int)
    :param micro: Microsecond number. Defaults to 0. (int)
    :returns: Fractional days. (float)
    """
    days = sec + micro / 1000000.0
    days = _min + days / 60.0
    days = hour + days / 60.0
    return days / 24.0


def process_bib_entry(cid, bibdatabase, bibnums, fallback_fmt=
    '[{author_abbrev}, {year}]'):
    """work out the best way to represent the bib entry """
    entry = bibdatabase[cid]
    if cid not in bibnums:
        bibnums[cid] = len(bibnums) + 1
    if 'doi' in entry:
        return '{text}'.format(doi=
            entry['doi'], text=bibnums[cid])
    elif 'url' in entry:
        return '{text}'.format(url=entry['url'], text=
            bibnums[cid])
    elif 'link' in entry:
        return '{text}'.format(url=entry['link'], text=
            bibnums[cid])
    else:
        return bibnums[cid]


def supplements(parms, countrate=None):
    u"""Supplementary parameters:
        [12]  n₁ = n*F₁     Particle number of species 1 (3D)
        [13]  n₂ = n*F₂     Particle number of species 2 (3D)
        [14]  n₃ = n*F₃     Particle number of species 3 (2D; F₃ = 1-F₁-F₂)
    """
    n = parms[0]
    F1 = parms[4]
    F2 = parms[5]
    Info = list()
    Info.append([u'n₁', n * F1])
    Info.append([u'n₂', n * F2])
    Info.append([u'n₃', n * (1 - F1 - F2)])
    if countrate is not None:
        cpp = countrate / n
        Info.append(['cpp [kHz]', cpp])
    return Info


def _pad_bytes(name, length):
    """
    Takes a char string and pads it wih null bytes until it's length chars
    """
    return name + '\x00' * (length - len(name))


@staticmethod
def isAvailable():
    """
        Method that should be overriden by child classes and return True
        if the given builder is available on the current environment
        """
    raise NotImplementedError


def add_polygon_filled(pic, point_list, col):
    """Draw an empty polygon of Color col with corners for every vertex
    in list point_list on Picture pic.

    Note:
    point_list is a list containing vertices xy coordinates
    (ex. [x1,y1,x2,y2,x3,y3]) It should contain at least
    three coordinate pairs."""
    pic.add_polygon_filled(col, point_list)


@classmethod
def GetAnalyzerNames(cls):
    """Retrieves the names of all loaded analyzers.

    Returns:
      list[str]: of analyzer names.
    """
    return cls._analyzer_classes.keys()


def center(text, width, fillchar=' '):
    """
    Creates a copy of ``text`` centered in a string of length ``width``.

    Padding is done using the specified ``fillchar`` (default is an ASCII space). The original
    string is returned if ``width`` is less than or equal to len(s).

    :param text: The string to center
    :type text:  ``str``

    :param width: The width of the stirng to produce
    :type width:  ``int``

    :param fillchar: The padding to expand the character to width
    :type fillchar:  ``str``

    :return: A copy of ``text`` centered in a string of length ``width``.
    :rtype: ``str``
    """
    assert isinstance(text, str), '%s is not a string' % text
    return text.center(width, fillchar)


def normalize_time(timestamp):
    """Normalize time in arbitrary timezone to UTC naive object."""
    offset = timestamp.utcoffset()
    if offset is None:
        return timestamp
    return timestamp.replace(tzinfo=None) - offset


def xstack_effect(opcode, opc, oparg=None, jump=None):
    """Compute the stack effect of opcode with argument oparg, using
    oppush and oppop tables in opc.

    If the code has a jump target and jump is True, stack_effect()
    will return the stack effect of jumping. If jump is False, it will
    return the stack effect of not jumping. And if jump is None
    (default), it will return the maximal stack effect of both cases.
    """
    pop, push = opc.oppop[opcode], opc.oppush[opcode]
    opname = opc.opname[opcode]
    if opname in ('BUILD_MAP',):
        if opc.version >= 3.5:
            return 1 - 2 * oparg
    elif opname in ('UNPACK_SEQUENCE', 'UNPACK_EX') and opc.version >= 3.0:
        return push + oparg
    elif opname in 'BUILD_SLICE' and opc.version <= 2.7:
        if oparg == 3:
            return -2
        else:
            return -1
        pass
    elif opname == 'MAKE_FUNCTION':
        if opc.version >= 3.5:
            if 0 <= oparg <= 10:
                if opc.version == 3.5:
                    return [-1, -2, -3, -3, -2, -3, -3, -4, -2, -3, -3, -4][
                        oparg]
                elif opc.version >= 3.6:
                    return [-1, -2, -2, -3, -2, -3, -3, -4, -2, -3, -3, -4][
                        oparg]
            else:
                return None
    elif opname == 'CALL_FUNCTION_EX':
        if opc.version >= 3.5:
            if 0 <= oparg <= 10:
                return [-1, -2, -1][oparg]
            else:
                return None
    if push >= 0 and pop >= 0:
        return push - pop
    elif pop < 0:
        if opcode in opc.VARGS_OPS:
            return push - oparg + (pop + 1)
        elif opcode in opc.NARGS_OPS:
            return -oparg + pop + push
    return -100


def remote_url():
    """Returns the Window URL through getFrameUrl method prefixed with
        base_url if it's selected by user.
        """
    pass


def validate_format(*_arg):
    """
    This method can be overridden with format validation logic.
    """
    return True


def bool_helper(bool_string):
    """
    Needed a helper that could take a string version of a bool and convert it to
    the actual bool value
    """
    if bool_string.lower() == 'true':
        return True
    else:
        return False


def getSimilarity(doc1, doc2):
    """Get similarity between two Spacy documents.
	Parameters :
	doc1 -- a Spacy document
	doc2 -- another Spacy document
	Return :
	similarity -- similarity between the documents
	"""
    return doc1.similarity(doc2)


def compare_checksums(remote_sums, local_sums):
    """ Compare the lists of the checksums from a remote and a local version of a dataset
        :argument remote_sums: list of remote checksums
        :argument local_sums: list of local checksums
        :return: result set
    """
    return set(remote_sums).symmetric_difference(local_sums)


def coherence_from_spectral(Sw):
    """Compute the spectral coherence between processes X and Y,
    given their spectral matrix S(w)

    Parameters
    ----------

    Sw : ndarray
      spectral matrix
    """
    Sxx = Sw[0, 0].real
    Syy = Sw[1, 1].real
    Sxy_mod_sq = (Sw[0, 1] * Sw[1, 0]).real
    Sxy_mod_sq /= Sxx
    Sxy_mod_sq /= Syy
    return Sxy_mod_sq


def primitive_nurbs_surface_sphere_add(radius: float=1.0, view_align: bool=
    False, enter_editmode: bool=False, location: float=(0.0, 0.0, 0.0),
    rotation: float=(0.0, 0.0, 0.0), layers: bool=(False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False, False)):
    """Construct a Nurbs surface Sphere

    :param radius: Radius
    :type radius: float
    :param view_align: Align to View, Align the new object to the view
    :type view_align: bool
    :param enter_editmode: Enter Editmode, Enter editmode when adding this object
    :type enter_editmode: bool
    :param location: Location, Location for the newly added object
    :type location: float
    :param rotation: Rotation, Rotation for the newly added object
    :type rotation: float
    :param layers: Layer
    :type layers: bool
    """
    pass


def nic_name_to_host(nic_name):
    """ helper function to translate the name of a network card into a valid host name"""
    from netifaces import ifaddresses, AF_INET
    host = ifaddresses(nic_name).setdefault(AF_INET, [{'addr': 'No IP addr'}])[
        0]['addr']
    return host


def findpath(imgpaths, filename):
    """
    find the filename in filepaths
    [[imagefolder][imagefile]]
    """
    diridx = 0
    while True:
        try:
            if filename + '.ppm' in imgpaths[diridx]:
                return imgpaths[diridx][0]
        except:
            return None
        diridx += 1


def app_model_label(model):
    """
    Stop those deprecation warnings
    """
    return model._meta.app_label, model._meta.model_name


def _resolve_action(field):
    """
    Resolve argparser action and type by Field type

    :param field: BaseType object
    :type field: model.BaseType

    :return: a tuple with string with argparser type and type, as format: (str, type)
    :rtype: (str, type)
    """
    type_maps = {'FloatField': ('store', float), 'StringField': ('store',
        str), 'SelectField': ('store', str), 'IntegerField': ('store', int),
        'BoolField': ('store_true', None), 'IncrementalIntegerField': (
        'count', None)}
    in_type = field.__class__.__name__
    results = type_maps[in_type]
    return results


@classmethod
def _new_rr(cls, rrs, name, cname, *values):
    """Add new record with multiple values."""
    change = rrs.add_change('CREATE', name, type=cname, ttl=cls.ttl)
    for v in values:
        change.add_value(v)


def read_section(config, spec, section, name, global_section='apps'):
    """read in a section to a list, and stop when we hit the next section
    """
    members = []
    while True:
        if len(spec) == 0:
            break
        next_line = spec[0]
        if next_line.upper().strip().startswith('%'):
            break
        else:
            new_member = spec.pop(0)
            if not new_member.strip().startswith('#'):
                if section in ['applabels', 'appfiles', 'appenv']:
                    new_member = new_member.strip()
                members.append(new_member)
    if len(members) > 0:
        if section is not None and name is not None:
            config[global_section][name][section] = members
        else:
            config[global_section] = members
    return config


def getid(obj):
    """Return id if argument is a Resource.

    Abstracts the common pattern of allowing both an object or an object's ID
    (UUID) as a parameter when dealing with relationships.
    """
    try:
        if obj.uuid:
            return obj.uuid
    except AttributeError:
        pass
    try:
        return obj.id
    except AttributeError:
        return obj


def relative_luminance(r, g, b):
    """ Converts linear RGB components to relative luminance.
		See: https://en.wikipedia.org/wiki/Relative_luminance
	"""
    return 0.2126 * r + 0.7152 * g + 0.0722 * b


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


def convert_shape_dict_to_array_shape(shape_dict, type='numpy'):
    """
    Converts a dict with "x", "y" (and optionally "z") attributes into
    a tuple that can be used to e.g. initialise a numpy array
    :param shape_dict: Dict with  "x", "y" (and optionally "z") attributes
    :param type: One of "numpy" or "fiji", to determine whether the "x" or the
    "y" attribute is the first dimension.
    :return: Tuple array shape
    """
    shape = []
    if type is 'numpy':
        shape.append(int(shape_dict['y']))
        shape.append(int(shape_dict['x']))
    elif type is 'fiji':
        shape.append(int(shape_dict['x']))
        shape.append(int(shape_dict['y']))
    else:
        raise NotImplementedError(
            "Type: {} not recognise, please specify 'numpy' or 'fiji'".
            format(type))
    if 'z' in shape_dict:
        shape.append(int(shape_dict['z']))
    return tuple(shape)


def transform_file_output(result):
    """ Transform to convert SDK file/dir list output to something that
    more clearly distinguishes between files and directories. """
    from collections import OrderedDict
    new_result = []
    iterable = result if isinstance(result, list) else result.get('items',
        result)
    for item in iterable:
        new_entry = OrderedDict()
        entity_type = item['type']
        is_dir = entity_type == 'dir'
        new_entry['Name'] = item['name'] + '/' if is_dir else item['name']
        new_entry['Content Length'] = ' ' if is_dir else item['properties'][
            'contentLength']
        new_entry['Type'] = item['type']
        new_entry['Last Modified'] = item['properties']['lastModified'] or ' '
        new_result.append(new_entry)
    return sorted(new_result, key=lambda k: k['Name'])


def duplicates_make_real(use_base_parent: bool=False, use_hierarchy: bool=False
    ):
    """Make dupli objects attached to this object real

    :param use_base_parent: Parent, Parent newly created objects to the original duplicator
    :type use_base_parent: bool
    :param use_hierarchy: Keep Hierarchy, Maintain parent child relationships
    :type use_hierarchy: bool
    """
    pass


def main(default=None):
    """Execute a command.

    It can be given as the first program argument or it's the `default`
    command is defined.

    """
    import sys
    from xotl.tools.cli import Command, HELP_NAME
    args = sys.argv[1:]
    if args and not args[0].startswith('-'):
        cmd_name = args[0]
        args = args[1:]
    else:
        cmd_name = default or Command.get_setting('default_command', None
            ) or HELP_NAME
    cmds = Command.registry
    cmd = cmds.get(cmd_name)
    if not cmd:
        print('Command "%s" not found!\n' % cmd_name)
        cmd = cmds.get(HELP_NAME)
        args = []
    sys.exit(cmd().run(args))


def message(name, default):
    """
        Return the message (from the `messages` attribute) that goes
        with `name`, or return default if `name` not found `default`.
        """


def _is_enabled():
    """
    Reason for returning true is explained in widi facade.
    /plyer/facades/wifi.py
    """
    return True


@classmethod
def create(cls, oid, name, len, type, category, delim, relid):
    """Create a type code for a PostgreSQL data type."""
    self = cls(name)
    self.oid = oid
    self.len = len
    self.type = type
    self.category = category
    self.delim = delim
    self.relid = relid
    return self


def _jaccard(a, b):
    """ Return the Jaccard similarity between two sets a and b. """
    return 1.0 * len(a & b) / len(a | b)


def listToString(s, add=''):
    """리스트 원소를 하나의 문자열로 만듭니다"""
    str = ''
    for ele in s:
        str += ele + add
    return str


def decode_utf8(input_iterator):
    """
    Generator that decodes a utf-8 encoded
    input line by line
    """
    for l in input_iterator:
        yield l if isinstance(l, str) else l.decode('utf-8')


def _import_module(name, package=None, warn=True, prefix='_py_', ignore='_'):
    """Try import all public attributes from module into global namespace.

    Existing attributes with name clashes are renamed with prefix.
    Attributes starting with underscore are ignored by default.

    Return True on successful import.

    """
    import warnings
    from importlib import import_module
    try:
        if not package:
            module = import_module(name)
        else:
            module = import_module('.' + name, package=package)
    except ImportError:
        if warn:
            warnings.warn('failed to import module %s' % name)
    else:
        for attr in dir(module):
            if ignore and attr.startswith(ignore):
                continue
            if prefix:
                if attr in globals():
                    globals()[prefix + attr] = globals()[attr]
                elif warn:
                    warnings.warn('no Python implementation of ' + attr)
            globals()[attr] = getattr(module, attr)
        return True


def semanage_port_get_ports(seport, setype, proto):
    """ Get the list of ports that have the specified type definition.

    :param seport: Instance of seobject.portRecords

    :type setype: str
    :param setype: SELinux type.

    :type proto: str
    :param proto: Protocol ('tcp' or 'udp')

    :rtype: list
    :return: List of ports that have the specified SELinux type.
    """
    records = seport.get_all_by_type()
    if (setype, proto) in records:
        return records[setype, proto]
    else:
        return []


def swapaxes(input, axis1, axis2):
    """Interchange the two given axes of a tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    axis1, axis2 : int
        The two axes.

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


def extract_email_datas(email_container):
    """Function to extract email infos, return a dictionary with the name of the header like
    key and the mail like value"""
    email_info = {}
    email = email_container.find_element_by_tag_name('a').get_attribute('href')
    email = email.split(':')[1]
    email_info['Email'] = email
    return email_info


def pointerize(decl: str, name: str) ->str:
    """Given a C decl and its name, modify it to be a declaration to a pointer."""
    if '(' in decl:
        return decl.replace(name, '(*{})'.format(name))
    else:
        return decl.replace(name, '*{}'.format(name))


def capitalise(input_string: str) ->str:
    """Convert the first character of the string to uppercase."""
    return input_string[0].upper() + input_string[1:]


def pack_islands(rotate: bool=True, margin: float=0.001):
    """Transform all islands so that they fill up the UV space as much as possible

    :param rotate: Rotate, Rotate islands for best fit
    :type rotate: bool
    :param margin: Margin, Space between islands
    :type margin: float
    """
    pass


@classmethod
def get_mac_params(cls, mac_alg):
    """Get paramaters of the MAC algorithm used with this encryption"""
    return 0, 16, True


def checkEval(str1):
    """checks string for potentially malicious inputs for eval function"""
    str1 = str(str1)
    excludes = ['import', '__', 'os', 'sys', 'eval', 'exec', 'compile',
        'open', 'write', '\n', '\t']
    for i in range(len(excludes)):
        if excludes[i] in str1:
            return False
    return True


@property
def fraction(f):
    """
        Return the fraction as a float.

        Reading from left-to-right the bits in the fraction part, the
        equation is:
        bit_n * 2^-1 + bit_{n-1} * 2^-2 + bit_{n-2} * 2^-3 + ...
        """
    fraction = 0.0
    for bit, n in zip(f.fraction_bits, range(1, f.p)):
        if bit:
            fraction += 2 ** -n
    return fraction


def uniquify_list_of_strings(input_list):
    """
    Ensure that every string within input_list is unique.
    :param list input_list: List of strings
    :return: New list with unique names as needed.
    """
    output_list = list()
    for i, item in enumerate(input_list):
        tempList = input_list[:i] + input_list[i + 1:]
        if item not in tempList:
            output_list.append(item)
        else:
            output_list.append('{0}_{1}'.format(item, i))
    return output_list


@staticmethod
def context_merge_subject_and_session(context):
    """Merge session & subject labels"""
    merged = False
    if 'session' in context and 'label' in context['session']:
        context.setdefault('subject', {})['label'] = context['session']['label'
            ]
        merged = True
    if not merged and 'subject' in context and 'label' in context['subject']:
        context.setdefault('session', {})['label'] = context['subject']['label'
            ]
        merged = True
    return merged


def escape(string):
    """
    Replace special characters with their equivalent LaTeX macros.

    Args:
        string (str): The string to process.

    Returns:
        str: The string with special characters replaced with macros.
    """
    replacements = {'&': '\\&', '%': '\\%', '$': '\\$', '#': '\\#', '_':
        '\\_', '{': '\\{', '}': '\\}', '~': '\\textasciitilde{}', '^':
        '\\^{}', '\\': '\\textbackslash{}', '\n': '\\newline%\n', '-':
        '{-}', '\xa0': '~', '[': '{[}', ']': '{]}'}
    escaped = ''
    for char in string:
        escaped += replacements.get(char, char)
    return escaped


def prefixed_path_string(path, prefix=''):
    """Return the prefixed version of this string"""
    while path and path[0] == '.':
        path = path[1:]
    while path and path[-1] == '.':
        path = path[:-1]
    while prefix and prefix[0] == '.':
        prefix = prefix[1:]
    while prefix and prefix[-1] == '.':
        prefix = prefix[:-1]
    if not prefix:
        return path, path
    elif not path:
        return prefix, prefix
    else:
        res = '{0}.{1}'.format(prefix, path)
        return res, res


def select(iterable):
    """select an element of iterable. Returns None if there is no such element.

    This implementation just picks the first element.
    For many of the uses, which element is selected does not affect correctness,
    but may affect efficiency.
    """
    for e in iterable:
        return e


def set_verbosity(level):
    """Sets the modules message verbosity level for *all* messages printed.

    :arg level: a positive integer (>0); higher levels including more detail.
    """
    global verbosity
    verbosity = level


def right_rotate(x: int, amount: int, bits: int=32) ->int:
    """
    Performs a right-rotate.

    Parameters:
        x      (int): Integer to rotate.
        amount (int): Amount to rotate by.
        bits   (int): Bitspace to rotate over.

    Returns:
        int: Rotated integer.
    """
    mask = 2 ** bits - 1
    return (x >> amount | x << bits - amount) & mask


def step_regularity(autocorr_peak_values):
    """
    Calculate step and stride regularity from autocorrelation peak values.

    Step and stride regularity measures based on
    `Moe-Nilssen (2004) - Estimation of gait cycle characteristics by trunk
    accelerometry
    <http://www.jbiomech.com/article/S0021-9290(03)00233-1/abstract>`_.

    If calculating regularity from acceleration in the vertical axis, this
    function receives the detected peaks from the vertical axis
    autocorrelation.

    However, if calculating regularity from lateral axis
    acceleration, you should pass in *both* peaks and valleys from the
    autocorrelation of the lateral axis.

    **Step regularity:**

    Perfect step regularity will be 1.0 for vertical axis autocorrelation
    (the larger the better, capped at 1.0).

    For the lateral axis, perfect regularity is -1.0 (the smaller the
    better, capped at -1.0).

    **Stride regularity:**

    Perfect stride regularity will be 1.0 for vertical axis autocorrelation
    (the larger the better, capped at 1.0).

    Lateral axis sign and interpretation are the same as the vertical axis.

    Parameters
    ----------
    autocorr_peak_values : ndarray
        Values of the autocorrelation peaks/valleys detected by
        :func:`sensormotion.peak.find_peaks`. This should contain only peak
        values when looking at the vertical axis, and both peak and valley
        values when looking at the lateral axis.

    Returns
    -------
    step_reg : float
        Step regularity. Value is capped at 1.0 or -1.0 depending on the
        axis of interest.
    stride_reg : float
        Stride regularity. Capped at 1.0 for both vertical and lateral axes.
    """
    peaks_half = autocorr_peak_values[autocorr_peak_values.size // 2:]
    assert len(peaks_half
        ) >= 3, 'Not enough autocorrelation peaks detected. Plot the autocorrelation signal to visually inspect peaks'
    ac_lag0 = peaks_half[0]
    ac_d1 = peaks_half[1]
    ac_d2 = peaks_half[2]
    step_reg = ac_d1 / ac_lag0
    stride_reg = ac_d2 / ac_lag0
    return step_reg, stride_reg


def get_scaled_bounds(ax, position, *, distance=0.1, factor=200):
    """Get scaled bounds.

    Parameters
    ----------
    ax : Axes object
        Axes object.
    position : {'UL', 'LL', 'UR', 'LR'}
        Position.
    distance : number (optional)
        Distance. Default is 0.1.
    factor : number (optional)
        Factor. Default is 200.

    Returns
    -------
    ([h_scaled, v_scaled], [va, ha])
    """
    x0, y0, width, height = ax.bbox.bounds
    width_scaled = width / factor
    height_scaled = height / factor
    if position == 'UL':
        v_scaled = distance / width_scaled
        h_scaled = 1 - distance / height_scaled
        va = 'top'
        ha = 'left'
    elif position == 'LL':
        v_scaled = distance / width_scaled
        h_scaled = distance / height_scaled
        va = 'bottom'
        ha = 'left'
    elif position == 'UR':
        v_scaled = 1 - distance / width_scaled
        h_scaled = 1 - distance / height_scaled
        va = 'top'
        ha = 'right'
    elif position == 'LR':
        v_scaled = 1 - distance / width_scaled
        h_scaled = distance / height_scaled
        va = 'bottom'
        ha = 'right'
    else:
        print('corner not recognized')
        v_scaled = h_scaled = 1.0
        va = 'center'
        ha = 'center'
    return [h_scaled, v_scaled], [va, ha]


def psi_Mg_CO3_OH_HMW84(T, P):
    """c-a-a': magnesium carbonate hydroxide [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def storageinfo(exclusivefiles=False, sharedfiles=False, revisionscount=
    False, trackedsize=False, storedsize=False):
    """Obtain information about storage for this file's data.

        Returns a dict describing storage for this tracked path. The keys
        in the dict map to arguments of the same. The arguments are bools
        indicating whether to calculate and obtain that data.

        exclusivefiles
           Iterable of (vfs, path) describing files that are exclusively
           used to back storage for this tracked path.

        sharedfiles
           Iterable of (vfs, path) describing files that are used to back
           storage for this tracked path. Those files may also provide storage
           for other stored entities.

        revisionscount
           Number of revisions available for retrieval.

        trackedsize
           Total size in bytes of all tracked revisions. This is a sum of the
           length of the fulltext of all revisions.

        storedsize
           Total size in bytes used to store data for all tracked revisions.
           This is commonly less than ``trackedsize`` due to internal usage
           of deltas rather than fulltext revisions.

        Not all storage backends may support all queries are have a reasonable
        value to use. In that case, the value should be set to ``None`` and
        callers are expected to handle this special value.
        """


def get_rps(data_frame):
    """Calculate RPS for all requests

    Args:
        data_frame (DataFrame): data

    Returns:
        int: Requests per second
    """
    from_date = data_frame.iloc[0].time
    to_date = data_frame.iloc[-1].time
    duration = to_date - from_date
    if duration < 0:
        raise ValueError(
            'Incorrect time values from_date > to_data (%f > %f)' % (
            from_date, to_date))
    if duration == 0:
        duration = 1
    requests_count = data_frame.shape[0]
    return requests_count / duration


@classmethod
def update_user(cls, **kwargs):
    """ Update a user with the available parameters.

        >>> user = Retaincc.get_user(user_id='123')
        >>> user['name']
        u'Somebody'
        >>> user = Retaincc.update_user(user_id='123', name='Guido')
        >>> user['name']
        u'Guido'

        """
    return cls._do_call('PUT', cls.api_endpoint + 'users', params=kwargs)


def save_batch(schedule_queue, transaction_queue, batch):
    """
    Save a batch to file and split it into a queue for scheduling new processes, and a queue for adding transactions to the database

    :param schedule_queue: The input stream of new data for new processes
    :param transaction_queue: The input stream of transactions to be entered permanently in the database
    """
    batch.save()
    transaction_queue.put(batch)
    schedule_queue.put(batch)


def is_str_float(value: str) ->bool:
    """
    Check whether a string represents a number.

    Args:
        value (str): The string to check.

    Returns:
        bool: ``True`` if it does, ``False`` otherwise.
    """
    try:
        float(value)
        return True
    except ValueError:
        return False


def is_equal_or_child_uri(parentUri, childUri):
    """Return True, if childUri is a child of parentUri or maps to the same resource.

    Similar to <util.is_child_uri>_ ,  but this method also returns True, if parent
    equals child. ('/a/b' is considered identical with '/a/b/').
    """
    return parentUri and childUri and (childUri.rstrip('/') + '/').startswith(
        parentUri.rstrip('/') + '/')


def roundlist(inlist, digits):
    """
Goes through each element in a 1D or 2D inlist, and applies the following
function to all elements of float ... round(element,digits).

Usage:   roundlist(inlist,digits)
Returns: list with rounded floats
"""
    if type(inlist[0]) in [int, float]:
        inlist = [inlist]
    l = inlist * 1
    for i in range(len(l)):
        for j in range(len(l[i])):
            if isinstance(l[i][j], float):
                l[i][j] = round(l[i][j], digits)
    return l


def uninstall(context):
    """Uninstall script"""


def get_contig_name_to_splits_dict(splits_basic_info_dict,
    contigs_basic_info_dict):
    """
    Returns a dict for contig name to split name conversion.

    Here are the proper source of the input params:

        contigs_basic_info_dict = database.get_table_as_dict(t.contigs_info_table_name, string_the_key = True)
        splits_basic_info_dict  = database.get_table_as_dict(t.splits_info_table_name)
    """
    contig_name_to_splits_dict = {}
    for split_name in splits_basic_info_dict:
        parent = splits_basic_info_dict[split_name]['parent']
        if parent in contig_name_to_splits_dict:
            contig_name_to_splits_dict[parent].append(split_name)
        else:
            contig_name_to_splits_dict[parent] = [split_name]
    return contig_name_to_splits_dict


def human_readable_size(num, suffix='B'):
    """ FROM http://stackoverflow.com/a/1094933/1958900
    """
    for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
        if abs(num) < 1024.0:
            return '%3.1f%s%s' % (num, unit, suffix)
        num /= 1024.0
    return '%.1f%s%s' % (num, 'Yi', suffix)


def is_ip(value):
    """
    Check if a value is valid ip
    :param value:
    :return:
    """
    parts = value.split('.')
    if len(parts) != 4:
        return False
    for item in parts:
        if not 0 <= int(item) <= 255:
            return False
    return True


def update_item(db, klass, item_id, newvalues):
    """Update database item
       :argument: db database SQLalchemy connection session
       :argument: klass class representing table objects
       :argument: item_id the id for row to update
       :argument: newvalues a dictionary with the column keys, values to be updated
       :return nothing
    """
    db.query(klass).filter_by(id=item_id).update(newvalues)
    db.commit()
    return


def convertSkewToFfoPpb(skew):
    """
    Convert frequency skew to Fraction Frequency Offset (FFO) in ppb.
    """
    return (skew - 1) / 1e-09


def demo():
    """demo is used to demonstrate typical examples about this class."""
    demostr = """
import clubear as cb
import numpy as np
#clubear.csv is generated by cb.manager.demo()
pm=cb.pump('clubear.csv')  #read in the demodata for illustration
pm.drop=['brand','company','weight'] #drop some varialbe for illustration
pm.qlist=['age','height','logsales','price'] #define the quant variables
ck=cb.check(pm).table(tv=True); #levels of quali variables

tk=cb.tank(pm); #create a new tank to hold the pump work for prepressing
tk.app(np.log,'age','logage') #app np.log transformation to age
tk.app(lambda x: x**2,'height') #app a user defined func to height
tk.ady('gender',['Female']) #add dummy for gender
tk.ady('region',ck['region'][1]) #add dummy for region
ck=cb.check(tk).stats() #check the newly generated tank
"""
    print(demostr)


def info(__self, __message, *args, **kwargs):
    """Log ``message.format(*args, **kwargs)`` with severity ``'INFO'``."""
    __self._log('INFO', None, False, __self._options, __message, args, kwargs)


def _gcd(a, b):
    """Euclidean algorithm for calculating the GCD of two numbers a, b.
    This algoritm also works for real numbers:
    Find the greatest number h such that a and b are integer multiples of h.
    """
    while a > 1e-05:
        a, b = b % a, a
    return b


def rotate_z(vector, theta):
    """ Rotate a 3D vector about the +z axis
        Inputs:
            vector: 3d vector array
            theta [rad]: angle to rotate the vector about
        Returns: rotated vector
    """
    import numpy as np
    R = np.array([[np.cos(theta), -np.sin(theta), 0], [np.sin(theta), np.
        cos(theta), 0], [0, 0, 1]])
    if np.ndim(vector) == 1:
        out = np.zeros(3)
        out[0] = R[0, 0] * vector[0] + R[0, 1] * vector[1] + R[0, 2] * vector[2
            ]
        out[1] = R[1, 0] * vector[0] + R[1, 1] * vector[1] + R[1, 2] * vector[2
            ]
        out[2] = R[2, 0] * vector[0] + R[2, 1] * vector[1] + R[2, 2] * vector[2
            ]
    else:
        out = np.zeros((3, vector.shape[1]))
        out[0] = R[0, 0] * vector[(0), :] + R[0, 1] * vector[(1), :] + R[0, 2
            ] * vector[(2), :]
        out[1] = R[1, 0] * vector[(0), :] + R[1, 1] * vector[(1), :] + R[1, 2
            ] * vector[(2), :]
        out[2] = R[2, 0] * vector[(0), :] + R[2, 1] * vector[(1), :] + R[2, 2
            ] * vector[(2), :]
    return out


def format_install_url(app_id: str, location_id: str) ->str:
    """Return a web-based URL to auth and install a SmartApp."""
    return (
        f'https://account.smartthings.com/login?redirect=https%3A%2F%2Fstrongman-regional.api.smartthings.com%2F%3FappId%3D{app_id}%26locationId%3D{location_id}%26appType%3DENDPOINTAPP%26language%3Den%26clientOS%3Dweb%26theme%3Dsmartthings'
        )


def calc_theoretical_noise_threshold(imax, theoretical_noise_dr):
    """
    Calculates the theoretical noise threshold from the theoretical noise dynamic range
    imax (float): the maximum of the dirty image
    theoretical_noise_dr (float): the theoretical noise dynamic range
    returns (float): the theoretical noise threshold
    """
    theoretical_noise_threshold = imax / theoretical_noise_dr
    return theoretical_noise_threshold


def publish_public_ip_address(srv=None):
    """
    Custom function used as a periodic task for publishing your public ip address to the MQTT bus.
    Obtains service object.
    Returns None.
    """
    import socket
    import requests
    hostname = socket.gethostname()
    ip_address = requests.get('https://httpbin.org/ip').json().get('origin')
    if srv is not None:
        srv.logging.debug(
            'Publishing public ip address "{ip_address}" of host "{hostname}"'
            .format(**locals()))
        srv.mqttc.publish('test/ip/{hostname}'.format(**locals()), ip_address)


def as_tuple(obj):
    """ Given obj return a tuple """
    if not obj:
        return tuple()
    if isinstance(obj, (tuple, set, list)):
        return tuple(obj)
    if hasattr(obj, '__iter__') and not isinstance(obj, dict):
        return obj
    return obj,


def gen_task_name(fun, extension=None):
    """Generates task name."""


@staticmethod
def _show_opts():
    """Returns command options in a form that can be handled by the
        command parser."""
    opts = {'-h': {'type': bool, 'default': False}, '-l': {'type': str,
        'default': None}}
    return opts


def _find_shortest_indentation(lines):
    """Return most shortest indentation."""
    assert not isinstance(lines, str)
    indentation = None
    for line in lines:
        if line.strip():
            non_whitespace_index = len(line) - len(line.lstrip())
            _indent = line[:non_whitespace_index]
            if indentation is None or len(_indent) < len(indentation):
                indentation = _indent
    return indentation or ''


def eeff(e_1, nu_1, e_2, nu_2):
    """

    Calculate the effective (Young's) modulus of two contact bodies according
    to Hertzian contact theory.

    Parameters
    ----------
    e_1: ndarray, scalar
        The Young's modulus of contact body 1.
    nu_1: ndarray, scalar
        The Poisson ratio of contact body 1.
    e_2: ndarray, scalar
        The Young's modulus of contact body 2.
    nu_2: ndarray, scalar
        The Poisson ratio of contact body 1.

    Returns
    -------
    e_eff: scalar
        The effective modulus.

    """
    e_eff = 1 / ((1 - nu_1 ** 2) / (2 * e_1) + (1 - nu_2 ** 2) / (2 * e_2))
    return e_eff


def strip_dns_suffix(hostname):
    """
    Returns the first segment of a hostname (e.g. returns 'google' for the value 'google.com.au')
    Not intended to be used with hostnames beginning with www - will return 'www'
    """
    return hostname.split('.')[0] if '.' in hostname else hostname


def describe_elasticsearch_domains(DomainNames=None):
    """
    Returns domain configuration information about the specified Elasticsearch domains, including the domain ID, domain endpoint, and domain ARN.
    See also: AWS API Documentation

    :example: response = client.describe_elasticsearch_domains(
        DomainNames=[
            'string',
        ]
    )

    :type DomainNames: list
    :param DomainNames: [REQUIRED]
            The Elasticsearch domains for which you want information.
            (string) --The name of an Elasticsearch domain. Domain names are unique across the domains owned by an account within an AWS region. Domain names start with a letter or number and can contain the following characters: a-z (lowercase), 0-9, and - (hyphen).

    :rtype: dict
    :return: {
        'DomainStatusList': [
            {
                'DomainId': 'string',
                'DomainName': 'string',
                'ARN': 'string',
                'Created': True|False,
                'Deleted': True|False,
                'Endpoint': 'string',
                'Processing': True|False,
                'ElasticsearchVersion': 'string',
                'ElasticsearchClusterConfig': {
                    'InstanceType': 'm3.medium.elasticsearch'|'m3.large.elasticsearch'|'m3.xlarge.elasticsearch'|'m3.2xlarge.elasticsearch'|'m4.large.elasticsearch'|'m4.xlarge.elasticsearch'|'m4.2xlarge.elasticsearch'|'m4.4xlarge.elasticsearch'|'m4.10xlarge.elasticsearch'|'t2.micro.elasticsearch'|'t2.small.elasticsearch'|'t2.medium.elasticsearch'|'r3.large.elasticsearch'|'r3.xlarge.elasticsearch'|'r3.2xlarge.elasticsearch'|'r3.4xlarge.elasticsearch'|'r3.8xlarge.elasticsearch'|'i2.xlarge.elasticsearch'|'i2.2xlarge.elasticsearch'|'d2.xlarge.elasticsearch'|'d2.2xlarge.elasticsearch'|'d2.4xlarge.elasticsearch'|'d2.8xlarge.elasticsearch'|'c4.large.elasticsearch'|'c4.xlarge.elasticsearch'|'c4.2xlarge.elasticsearch'|'c4.4xlarge.elasticsearch'|'c4.8xlarge.elasticsearch'|'r4.large.elasticsearch'|'r4.xlarge.elasticsearch'|'r4.2xlarge.elasticsearch'|'r4.4xlarge.elasticsearch'|'r4.8xlarge.elasticsearch'|'r4.16xlarge.elasticsearch',
                    'InstanceCount': 123,
                    'DedicatedMasterEnabled': True|False,
                    'ZoneAwarenessEnabled': True|False,
                    'DedicatedMasterType': 'm3.medium.elasticsearch'|'m3.large.elasticsearch'|'m3.xlarge.elasticsearch'|'m3.2xlarge.elasticsearch'|'m4.large.elasticsearch'|'m4.xlarge.elasticsearch'|'m4.2xlarge.elasticsearch'|'m4.4xlarge.elasticsearch'|'m4.10xlarge.elasticsearch'|'t2.micro.elasticsearch'|'t2.small.elasticsearch'|'t2.medium.elasticsearch'|'r3.large.elasticsearch'|'r3.xlarge.elasticsearch'|'r3.2xlarge.elasticsearch'|'r3.4xlarge.elasticsearch'|'r3.8xlarge.elasticsearch'|'i2.xlarge.elasticsearch'|'i2.2xlarge.elasticsearch'|'d2.xlarge.elasticsearch'|'d2.2xlarge.elasticsearch'|'d2.4xlarge.elasticsearch'|'d2.8xlarge.elasticsearch'|'c4.large.elasticsearch'|'c4.xlarge.elasticsearch'|'c4.2xlarge.elasticsearch'|'c4.4xlarge.elasticsearch'|'c4.8xlarge.elasticsearch'|'r4.large.elasticsearch'|'r4.xlarge.elasticsearch'|'r4.2xlarge.elasticsearch'|'r4.4xlarge.elasticsearch'|'r4.8xlarge.elasticsearch'|'r4.16xlarge.elasticsearch',
                    'DedicatedMasterCount': 123
                },
                'EBSOptions': {
                    'EBSEnabled': True|False,
                    'VolumeType': 'standard'|'gp2'|'io1',
                    'VolumeSize': 123,
                    'Iops': 123
                },
                'AccessPolicies': 'string',
                'SnapshotOptions': {
                    'AutomatedSnapshotStartHour': 123
                },
                'AdvancedOptions': {
                    'string': 'string'
                }
            },
        ]
    }

    """
    pass


def choose_nameplate(nameplate):
    """
        Commit to a nameplate, allowing the word-completion phase to begin.

        This may only be called once.  Calling it a second time will raise
        ``AlreadyChoseNameplateError``.

        :param str nameplate: the complete nameplate, without a trailing
            hyphen

        :return: None
        """


def is_same(s, u, v):
    """Return if the sub-AST at u and v are the same."""
    if type(u) is not type(v):
        return False
    return u == v


@classmethod
def from_cube(cls, cube):
    """ convert from iris cube
        """
    from dimarray.convert.iris import as_dimarray
    return as_dimarray(cube, copy=True, cls=cls)


def is_ascii(str_data: str) ->bool:
    """Checks if string contains only ascii chars.

    Necessary because python 3.6 does not have a str.isascii() method.

    Parameters
    ----------
    str_data : str
        string to check if it contains only ascii characters

    Returns
    -------
    bool
        True if only ascii characters in the string, else False.
    """
    try:
        str_data.encode('ascii')
    except (UnicodeEncodeError, AttributeError):
        return False
    return True


def check_value(string, options, insensitive=True, label='option'):
    """
    Verifiy that string is within the allowed options.

    Raise a :py:exc:`ValueError` if not found.

    Parameters
    ----------
    string : str
        The string to verify.
    options : mapping[str, str] or iterable[str]
        A container that supports the ``in`` operator. If the container
        is a mapping that can be indexed by the input, the result is
        the "normalized" version of the string that will be returned.
    insensitive : bool
        Whether or not to do a case insensitive comparison (using
        :py:meth:`str.casefold`). If :py:obj:`True`, `options` is
        expected to contain casefolded items.
    label : str
        The label used to describe `string` if it is not found in
        `options`.

    Return
    ------
    check : str
        The input string if it is in `options`. If options is a
        mapping, the result will be ``options[string]`` instead. This
        allows normalization of the input so that multiple input options
        can represent the same output value.
    """
    check = string.casefold() if insensitive else string
    if check not in options:
        raise ValueError('No such {} "{}"'.format(label, string))
    try:
        return options[check]
    except TypeError:
        return check


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 thumbtag():
    """Generate image tag using the api of the ImageField
        """


def set_close_exec(fd):
    """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor."""
    raise NotImplementedError()


def enable_lazy():
    """Convenience function for configuring _() to use lazy gettext

    Call this at the start of execution to enable the gettextutils._
    function to use lazy gettext functionality. This is useful if
    your project is importing _ directly instead of using the
    gettextutils.install() way of importing the _ function.
    """
    global USE_LAZY
    USE_LAZY = True


@staticmethod
def _find_k8s_resources(k8s_namespace):
    """
        Virtual function. Find K8S

        :return: V1ConfigMap or V1Secret  -- K8S object
        """
    raise NotImplementedError('This function is not implemented in this class')


@classmethod
def get_namespace(cls):
    """Returns the namespace of the class. Defaults to the python module
        name."""
    return cls.__namespace__


def MPInt(value):
    """Encode a multiple precision integer value"""
    l = value.bit_length()
    l += l % 8 == 0 and value != 0 and value != -1 << l - 1
    l = (l + 7) // 8
    return l.to_bytes(4, 'big') + value.to_bytes(l, 'big', signed=True)


def unwrap(value):
    """ Unwrap a quoted string """
    return value[1:-1]


def n2s(n):
    """
    Number to string.
    """
    s = hex(n)[2:].rstrip('L')
    if len(s) % 2 != 0:
        s = '0' + s
    return s.decode('hex')


@classmethod
def input_labelled(cls, label):
    """Returns an XPath to find an HTML <input> referred to by a <label> that contains the text in `label`."""
    for_based_xpath = (
        '//input[@id=//label[normalize-space(node())=normalize-space("%s")]/@for]'
         % label)
    nested_xpath = (
        '//label[normalize-space()=normalize-space("%s")]//input' % label)
    return cls('%s|%s' % (for_based_xpath, nested_xpath))


def _display_interval(i):
    """Convert a time interval into a human-readable string.

    :param i: The interval to convert, in seconds.
    """
    sigils = ['d', 'h', 'm', 's']
    factors = [24 * 60 * 60, 60 * 60, 60, 1]
    remain = int(i)
    result = ''
    for fac, sig in zip(factors, sigils):
        if remain < fac:
            continue
        result += '{}{}'.format(remain // fac, sig)
        remain = remain % fac
    return result


def set_empty_crops(image, crop_t=None, crop_b=None, crop_l=None, crop_r=None):
    """
    Defines crop parameters based upon image size, effectively not cropping at all.

    :param image:
    :param crop_t:
    :param crop_b:
    :param crop_l:
    :param crop_r:
    :return:
    """
    return 0, image.shape[0], 0, image.shape[1]


def clear():
    """
        Clears the results
        """


def one_list_to_val(val):
    """
    Convert a single list element to val
    :param val:
    :return:
    """
    if isinstance(val, list) and len(val) == 1:
        result = val[0]
    else:
        result = val
    return result


def getTimeline(ifd):
    """Get the TIMELINE extension (if there is one) from the input file.

    Parameters
    ----------
    ifd: pyfits HDUList object
        The pyfits file handle for the input file.

    Returns
    -------
    pyfits BinTableHDU object, or None
        The TIMELINE extension from the input file, if there is one.
    """
    hdunum = 0
    for i in range(1, len(ifd)):
        hdu = ifd[i]
        extname = hdu.header.get('extname', 'MISSING')
        if extname.upper() == 'TIMELINE':
            hdunum = i
            break
    if hdunum < 1:
        timeline_hdu = None
    else:
        timeline_hdu = ifd[hdunum]
        if timeline_hdu.data is None:
            timeline_hdu = None
    return timeline_hdu


def _download_sxs_metadata(login, simulations):
    """Download metadata.json from Zenodo for each simulation, if needed"""
    import traceback
    from tqdm.autonotebook import tqdm
    for sxs_id in tqdm(simulations, dynamic_ncols=True):
        download_url = simulations[sxs_id].get('metadata_file_info', {}).get(
            'links', {}).get('download', '')
        if not download_url:
            continue
        try:
            metadata = login.session.get(download_url).json()
            simulations[sxs_id].pop('metadata_file_info', {})
            simulations[sxs_id].update(metadata)
        except KeyboardInterrupt:
            raise
        except:
            traceback.print_exc()


def duplicate_move(MASK_OT_duplicate=None, TRANSFORM_OT_translate=None):
    """Duplicate mask and move

    :param MASK_OT_duplicate: Duplicate Mask, Duplicate selected control points and segments between them
    :param TRANSFORM_OT_translate: Translate, Translate (move) selected items
    """
    pass


def bC_Na_HCO3_HMW84(T, P):
    """c-a: sodium bicarbonate [HMW84]."""
    b0 = 0.0277
    b1 = 0.0411
    b2 = 0.0
    C0 = 0
    C1 = 0
    alph1 = 2
    alph2 = -9
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


@staticmethod
def _scaper(input_string):
    """Adds the required scape characters to the format file.
        :param input_string: Value before scaping
        :type input_string: str
        :return: Scaped string
        """
    scaped_string = input_string.replace('"', '\\"').replace("'", "\\'"
        ).replace('\r', '\\r').replace('\n', '\\n')
    return scaped_string


@classmethod
def fromRequest(klass, request):
    """Constructor based on Request instance."""
    return klass.fromString(str(request.url))


def intfloat(x):
    """int . float (for convenience in command-line specification)"""
    return int(float(x))


def plot_district_heating_network(pipelines, plot, loc='upper center'):
    """
    Plot the geometries of the district heating network on the plot interface.

    Parameters
    ----------
    pipeplines: GeoDataFrame
        Geodataframe of the district heating network.
    plot: dhd.plot.Plot
        Plot interface of the considered city.
    loc: tuple, optional
        Location of the legend box. Default is *loc* = 'upper center'.
    """
    label = 'District Heating Network'
    kwargs = {'color': 'black', 'linewidth': 1.5}
    plot.add_geodataframe(pipelines, kwargs)
    plot.add_legend([kwargs['color']], [label], 'line', loc=loc)


def switchable(a_1, a_2):
    """
    decide if 2 actions can be swapped.
    two actions are independent if they are on opposite faces or on the same
    face but on different layers.
    :param a_1: first action
    :param a_2: second action
    :returns True if switchable, False otherwise
    """
    opposite_faces = a_1.face.value + a_2.face.value == 5
    same_face = a_1.face.value == a_2.face.value
    diff_layers = a_1.layer != a_2.layer
    if opposite_faces:
        return a_1.face.value > a_2.face.value
    elif same_face and diff_layers:
        return a_1.layer > a_2.layer
    else:
        return False


@classmethod
def without_pos(cls, *args, **kwargs):
    """
        Create an instance of the class itself without specifying
        ``start_pos`` and ``end_pos`` attributes.
        """
    return cls(None, None, *args, **kwargs)


def line(value: str, *args, **kwargs):
    """Wrapper in case I want to do something different later."""
    print(value, *args, **kwargs)


@classmethod
def FillUnitDatabaseWithPosc(cls, unit_database, fill_categories=True):
    """
        Fills a unit database with the posc values.

        :param UnitDatabase unit_database:
            The unit database to be filled.

        :param bool fill_categories:
            Indicates whether for each quantity type a category with the same name should be created.

        :rtype: UnitDatabase
        :returns:
            The unit database passed as a parameter.
        """
    from .posc import FillUnitDatabaseWithPosc
    unit_database.Clear()
    FillUnitDatabaseWithPosc(unit_database, fill_categories=fill_categories,
        override_categories=True)
    if fill_categories:
        for quantity_alias, quantity_type in cls._ADDITIONAL_CATEGORY_ALIASES.items(
            ):
            unit_database.AddCategory(quantity_alias, quantity_type)
    return unit_database


@staticmethod
def get_session():
    """Return a database session that can be used by the `QueryBuilder` to perform its query.

        If there is an exception within the context then the changes will be rolled back and the state will
        be as before entering.  Transactions can be nested.

        :return: an instance of :class:`sqlalchemy.orm.session.Session`
        """
    from aiida.backends.djsite import get_scoped_session
    return get_scoped_session()


def pytest_xdist_node_collection_finished(node, ids):
    """called by the master node when a node finishes collecting.
    """


def search(**query):
    """Search on the query provided.  Each query key is an index
        name, each query value is the value that the index expects as
        a query term."""


def raise_if_runroot_key_invalid(runroot_key):
    """
    Raise an ValueError exception in case the `runroot_key` contains forbidden
    characters.
    """
    for c in runroot_key:
        if c != '-' and not c.isalnum():
            raise ValueError(
                'Unexpected character \'%s\' in the runroot key "%s".' % (c,
                runroot_key))


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 validipport(port):
    """
    Returns True if `port` is a valid IPv4 port.

        >>> validipport('9000')
        True
        >>> validipport('foo')
        False
        >>> validipport('1000000')
        False
    """
    try:
        if not 0 <= int(port) <= 65535:
            return False
    except ValueError:
        return False
    return True


def install_conda_target(conda_target, conda_context, skip_environment=False):
    """
    Install specified target into a its own environment.

    Return the process exit code (i.e. 0 in case of success).
    """
    if not skip_environment:
        create_args = ['--name', conda_target.install_environment,
            conda_target.package_specifier]
        return conda_context.exec_create(create_args)
    else:
        return conda_context.exec_install([conda_target.package_specifier])


def find_dead_ends(graph, width):
    """Find dead ends in a graph."""
    dead_ends = []
    for node in graph.nodes():
        if graph.degree(node) == 1 and node[0] < width - 1:
            dead_ends.append(node)
    return dead_ends


def bytes_to_int_py2(byte_arr):
    """transform multi-byte values into integers, python2 version"""
    n = num = 0
    for b in byte_arr:
        num += ord(b) << n
        n += 8
    return num


@classmethod
def clear_expired(cls):
    """
        Remove expired sessions from the session store.

        If this operation isn't possible on a given backend, it should raise
        NotImplementedError. If it isn't necessary, because the backend has
        a built-in expiration mechanism, it should be a no-op.
        """
    raise NotImplementedError('This backend does not support clear_expired().')


@staticmethod
def _propagate_predecessors(graph, node):
    """Propagate through @node predecessors in @graph"""
    return graph.predecessors_iter(node)


def _get_fit_settings():
    """
     These are to rescale the mass ratio fit range
     from [-0.01, np.log(4+0.01)] to [-1, 1]. The chi fits are already in
     this range.

     Values defined here are model-specific. These values are for NRSur7dq4.
    """
    q_fit_offset = -0.9857019407834238
    q_fit_slope = 1.4298059216576398
    q_max_bfOrder = 3
    chi_max_bfOrder = 2
    return q_fit_offset, q_fit_slope, q_max_bfOrder, chi_max_bfOrder


def node_color_preset_add(name: str='', remove_name: bool=False,
    remove_active: bool=False):
    """Add or remove a Node Color Preset

    :param name: Name, Name of the preset, used to make the path name
    :type name: str
    :param remove_name: remove_name
    :type remove_name: bool
    :param remove_active: remove_active
    :type remove_active: bool
    """
    pass


def append_silence(snd, samp):
    """Append samp samples of silence onto Sound snd."""
    snd.append_silence(samp)


@staticmethod
def get_object(conn, binding_name, cls):
    """
        Get a reference to a remote object using CORBA
        """
    raise RuntimeError('NameService needs to be resolved first')


def ldap_str(buf: bytes) ->str:
    """
    Decode the byte-sequence in :buf: to str object
    """
    return buf.decode('utf-8')


def _dict_path(d, *steps):
    """Traverses throuth a dict of dicts.
    Returns always a list. If the object to return is not a list,
    it's encapsulated in one.
    If any of the path steps does not exist, an empty list is returned.
    """
    x = d
    for key in steps:
        try:
            x = x[key]
        except KeyError:
            return []
    if not isinstance(x, list):
        x = [x]
    return x


def replace_filter(text: str, pattern: dict) ->str:
    """replace_filter filtering text by pattern key to value
    slower than trans_filter
    just use text_filter
    """
    for pat, rep in pattern.items():
        text = text.replace(pat, rep)
    return text


def phs3mvasc(Vth, Zseq, Rf=0, Sbase=1):
    """
    Three-Phase MVA Short-Circuit Calculator

    Calculator to evaluate the Short-Circuit MVA of a three-phase fault given the system
    parameters of Vth, Zseq, and an optional Rf. Uses the formula as follows:

    .. math:: MVA_{sc} = \\frac{\\left|V_{th}^2\\right|}{|Z_1|} * Sbase

    Parameters
    ----------
    Vth:        complex
                The Thevenin-Equivalent-Voltage
    Zseq:       list of complex
                Tupple of sequence reactances as (Z0, Z1, Z2)
    Rf:         complex, optional
                The fault resistance, default=0
    Sbase:      real, optional
                The per-unit base for power. default=1

    Returns
    -------
    MVA:        real
                Three-Phase Short-Circuit MVA.
    """
    MVA = abs(Vth) ** 2 / abs(Zseq[1]) * Sbase
    if Sbase != 1:
        MVA = MVA * 1e-06
    return MVA


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

        :param UserSecondaryEmailsResult val:
        :rtype: UserAddResult
        """
    return cls('success', val)


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 create_axisdic(adic, tlen, dlen):
    """
    Make an Sparky axis dictionary from a universal axis dictionary.

    Parameters
    ----------
    adic : dict
        Axis dictionary from a universal dictionary.
    tlen : int
        Tile length of axis.
    dlen : int
        Data length of axis.

    Returns
    -------
    sdic : dict
        Sparky axis dictionary

    """
    dic = dict()
    dic['nucleus'] = adic['label']
    dic['spectral_shift'] = 0
    dic['npoints'] = int(dlen)
    dic['size'] = int(dlen)
    dic['bsize'] = int(tlen)
    dic['spectrometer_freq'] = float(adic['obs'])
    dic['spectral_width'] = float(adic['sw'])
    dic['xmtr_freq'] = float(adic['car']) / dic['spectrometer_freq']
    dic['zero_order'] = 0.0
    dic['first_order'] = 0.0
    dic['first_pt_scale'] = 0.0
    dic['extended'] = b'\x80'
    return dic


def get_schemas(dic):
    """Return a list of all subtypes of the Schema type to feed to __all__"""
    from pyson.schema.schema_class import Schema
    ret_lst = []
    for k, v in dic.items():
        if isinstance(v, type) and issubclass(v, Schema) and not k.startswith(
            '_'):
            ret_lst.append(k)
    return ret_lst


def getPrice():
    """ returns the total price of all products in the cart
        """


@classmethod
def find(cls, id, **params):
    """Get a single model by its id. See :method:`get`

        :param id: the model id
        :param params: extra parameters
        :return: the model
        """
    return cls.get(id, **params)


def fix(val):
    """strip off _: from nodeIDs... as they are not valid NCNames"""
    if val.startswith('_:'):
        return val[2:]
    else:
        return val


@classmethod
def _explain(cls):
    """copied from cpptraj doc
        """
    return """
        [shear] Base pair shear.
        [stretch] Base pair stretch.
        [stagger] Base pair stagger.
        [buckle] Base pair buckle.
        [prop] Base pair propeller.
        [open] Base pair opening.
        [hb] Number of hydrogen bonds between bases in base pair.
        [pucker] Base sugar pucker.
        [major] Rough estimate of major groove width, calculated between P atoms of each
        base.
        [minor] Rough estimate of minor groove width, calculated between O4 atoms of
        each base.
        [shift] Base pair step shift.
        [slide] Base pair step slide.
        [rise] Base pair step rise.
        [title] Base pair step tilt.
        [roll] Base pair step roll.
        [twist] Base pair step twist.
        [xdisp] Helical X displacement.
        [ydisp] Helical Y displacement.
        [hrise] Helical rise.
        [incl] Helical inclination.
        [tip] Helical tip.
        [htwist] Helical twist.
        """


def get_resource_config_history(resourceType=None, resourceId=None,
    laterTime=None, earlierTime=None, chronologicalOrder=None, limit=None,
    nextToken=None):
    """
    Returns a list of configuration items for the specified resource. The list contains details about each state of the resource during the specified time interval.
    The response is paginated, and by default, AWS Config returns a limit of 10 configuration items per page. You can customize this number with the limit parameter. The response includes a nextToken string, and to get the next page of results, run the request again and enter this string for the nextToken parameter.
    See also: AWS API Documentation

    :example: response = client.get_resource_config_history(
        resourceType='AWS::EC2::CustomerGateway'|'AWS::EC2::EIP'|'AWS::EC2::Host'|'AWS::EC2::Instance'|'AWS::EC2::InternetGateway'|'AWS::EC2::NetworkAcl'|'AWS::EC2::NetworkInterface'|'AWS::EC2::RouteTable'|'AWS::EC2::SecurityGroup'|'AWS::EC2::Subnet'|'AWS::CloudTrail::Trail'|'AWS::EC2::Volume'|'AWS::EC2::VPC'|'AWS::EC2::VPNConnection'|'AWS::EC2::VPNGateway'|'AWS::IAM::Group'|'AWS::IAM::Policy'|'AWS::IAM::Role'|'AWS::IAM::User'|'AWS::ACM::Certificate'|'AWS::RDS::DBInstance'|'AWS::RDS::DBSubnetGroup'|'AWS::RDS::DBSecurityGroup'|'AWS::RDS::DBSnapshot'|'AWS::RDS::EventSubscription'|'AWS::ElasticLoadBalancingV2::LoadBalancer'|'AWS::S3::Bucket'|'AWS::SSM::ManagedInstanceInventory'|'AWS::Redshift::Cluster'|'AWS::Redshift::ClusterSnapshot'|'AWS::Redshift::ClusterParameterGroup'|'AWS::Redshift::ClusterSecurityGroup'|'AWS::Redshift::ClusterSubnetGroup'|'AWS::Redshift::EventSubscription',
        resourceId='string',
        laterTime=datetime(2015, 1, 1),
        earlierTime=datetime(2015, 1, 1),
        chronologicalOrder='Reverse'|'Forward',
        limit=123,
        nextToken='string'
    )

    :type resourceType: string
    :param resourceType: [REQUIRED]
            The resource type.

    :type resourceId: string
    :param resourceId: [REQUIRED]
            The ID of the resource (for example., sg-xxxxxx ).

    :type laterTime: datetime
    :param laterTime: The time stamp that indicates a later time. If not specified, current time is taken.

    :type earlierTime: datetime
    :param earlierTime: The time stamp that indicates an earlier time. If not specified, the action returns paginated results that contain configuration items that start from when the first configuration item was recorded.

    :type chronologicalOrder: string
    :param chronologicalOrder: The chronological order for configuration items listed. By default the results are listed in reverse chronological order.

    :type limit: integer
    :param limit: The maximum number of configuration items returned on each page. The default is 10. You cannot specify a limit greater than 100. If you specify 0, AWS Config uses the default.

    :type nextToken: string
    :param nextToken: The nextToken string returned on a previous page that you use to get the next page of results in a paginated response.

    :rtype: dict
    :return: {
        'configurationItems': [
            {
                'version': 'string',
                'accountId': 'string',
                'configurationItemCaptureTime': datetime(2015, 1, 1),
                'configurationItemStatus': 'Ok'|'Failed'|'Discovered'|'Deleted',
                'configurationStateId': 'string',
                'configurationItemMD5Hash': 'string',
                'arn': 'string',
                'resourceType': 'AWS::EC2::CustomerGateway'|'AWS::EC2::EIP'|'AWS::EC2::Host'|'AWS::EC2::Instance'|'AWS::EC2::InternetGateway'|'AWS::EC2::NetworkAcl'|'AWS::EC2::NetworkInterface'|'AWS::EC2::RouteTable'|'AWS::EC2::SecurityGroup'|'AWS::EC2::Subnet'|'AWS::CloudTrail::Trail'|'AWS::EC2::Volume'|'AWS::EC2::VPC'|'AWS::EC2::VPNConnection'|'AWS::EC2::VPNGateway'|'AWS::IAM::Group'|'AWS::IAM::Policy'|'AWS::IAM::Role'|'AWS::IAM::User'|'AWS::ACM::Certificate'|'AWS::RDS::DBInstance'|'AWS::RDS::DBSubnetGroup'|'AWS::RDS::DBSecurityGroup'|'AWS::RDS::DBSnapshot'|'AWS::RDS::EventSubscription'|'AWS::ElasticLoadBalancingV2::LoadBalancer'|'AWS::S3::Bucket'|'AWS::SSM::ManagedInstanceInventory'|'AWS::Redshift::Cluster'|'AWS::Redshift::ClusterSnapshot'|'AWS::Redshift::ClusterParameterGroup'|'AWS::Redshift::ClusterSecurityGroup'|'AWS::Redshift::ClusterSubnetGroup'|'AWS::Redshift::EventSubscription',
                'resourceId': 'string',
                'resourceName': 'string',
                'awsRegion': 'string',
                'availabilityZone': 'string',
                'resourceCreationTime': datetime(2015, 1, 1),
                'tags': {
                    'string': 'string'
                },
                'relatedEvents': [
                    'string',
                ],
                'relationships': [
                    {
                        'resourceType': 'AWS::EC2::CustomerGateway'|'AWS::EC2::EIP'|'AWS::EC2::Host'|'AWS::EC2::Instance'|'AWS::EC2::InternetGateway'|'AWS::EC2::NetworkAcl'|'AWS::EC2::NetworkInterface'|'AWS::EC2::RouteTable'|'AWS::EC2::SecurityGroup'|'AWS::EC2::Subnet'|'AWS::CloudTrail::Trail'|'AWS::EC2::Volume'|'AWS::EC2::VPC'|'AWS::EC2::VPNConnection'|'AWS::EC2::VPNGateway'|'AWS::IAM::Group'|'AWS::IAM::Policy'|'AWS::IAM::Role'|'AWS::IAM::User'|'AWS::ACM::Certificate'|'AWS::RDS::DBInstance'|'AWS::RDS::DBSubnetGroup'|'AWS::RDS::DBSecurityGroup'|'AWS::RDS::DBSnapshot'|'AWS::RDS::EventSubscription'|'AWS::ElasticLoadBalancingV2::LoadBalancer'|'AWS::S3::Bucket'|'AWS::SSM::ManagedInstanceInventory'|'AWS::Redshift::Cluster'|'AWS::Redshift::ClusterSnapshot'|'AWS::Redshift::ClusterParameterGroup'|'AWS::Redshift::ClusterSecurityGroup'|'AWS::Redshift::ClusterSubnetGroup'|'AWS::Redshift::EventSubscription',
                        'resourceId': 'string',
                        'resourceName': 'string',
                        'relationshipName': 'string'
                    },
                ],
                'configuration': 'string',
                'supplementaryConfiguration': {
                    'string': 'string'
                }
            },
        ],
        'nextToken': 'string'
    }

    :returns:
    (string) --
    (string) --

    """
    pass


def get_title_editable():
    """Get the title of the editable version if possible.
        """


@staticmethod
def _find_memory(clc, module):
    """
        Find or validate the Memory value by calling the CLC API
        :param clc: clc-sdk instance to use
        :param module: module to validate
        :return: Int value for Memory
        """
    memory = module.params.get('memory')
    group_id = module.params.get('group_id')
    alias = module.params.get('alias')
    state = module.params.get('state')
    if not memory and state == 'present':
        group = clc.v2.Group(id=group_id, alias=alias)
        if group.Defaults('memory'):
            memory = group.Defaults('memory')
        else:
            module.fail_json(msg=str(
                "Can't determine a default memory value. Please provide a value for memory."
                ))
    return memory


def get_engine(cls, current_app):
    """Proxy for compatibility with flask-debugtoolbar
        """
    databases = getattr(current_app, 'databases', None)
    if not databases:
        return None
    return databases[0].engine


@staticmethod
def get_pids_by_process_name(process_name, process_list, case_sensitive=
    False, contains=False):
    """Get a list of PIDs for the given process name.

        Args:
            process_name (str): The name of process, i.e. 'calc.exe'.
            process_list (list): A list of processes obtained from
                get_processes().
            case_sensitive (bool, optional): Whether the process name
                comparison should be case-sensitive.
            contains (bool, optional): Allows partial matching. If True, a
                partial process_name may return results.

        Returns:
            list: A list of int PIDs on success.
        """
    pids = []
    for i in range(len(process_list)):
        if case_sensitive:
            if contains:
                if process_name in process_list[i][0]:
                    pids.append(process_list[i][1])
            elif process_list[i][0] == process_name:
                pids.append(process_list[i][1])
        elif contains:
            if process_name.lower() in process_list[i][0].lower():
                pids.append(process_list[i][1])
        elif process_list[i][0].lower() == process_name.lower():
            pids.append(process_list[i][1])
    if pids:
        return pids
    else:
        return


def schema_defines_array(schema):
    """
    Schemas of the type `array` translate to an `Array`. Incorrectly
    implemented schemas may also neglect this, however use of the attribute
    `items` is only valid in the context of an array--and therefore indicate
    the schema also defines an instance of `Array`.
    """
    return schema.type_ == 'array' or schema.items


def get_blrms(series, flow=4.0, fhigh=10.0, stride=1, whiten=True,
    fftlength=4, overlap=2, **kwargs):
    """Compute the whitened, band-limited RMS of a `TimeSeries`

    Parameters
    ----------
    series  : `~gwpy.timeseries.TimeSeries`
        the input `TimeSeries` data

    flow : `float`, optional
        lower limit (Hz) of the passband, default: 4.0

    fhigh : `float`, optional
        upper limit (Hz) of the passband, default: 10.0

    stride: `float`, optional
        RMS integration length (seconds), default: 1

    whiten : `bool`, optional
        boolean switch to enable (`True`) or disable (`False`)
        whitening of the input, default: `True`

    fftlength : `float`, optional
        FFT integration length (seconds), default: 4

    overlap : `float`, optional
        FFT overlap length (seconds), default: 2

    **kwargs : `dict`, optional
        additional keyword arguments to `TimeSeries.whiten`

    Returns
    -------
    wblrms : `~gwpy.timeseries.TimeSeries`
        whitened, band-limited RMS trends of the input `TimeSeries`

    See Also
    --------
    ~gwpy.timeseries.TimeSeries.whiten
        for the underlying whitening scheme
    ~gwpy.timeseries.TimeSeries.rms
        for the underlying root-mean-square (RMS) estimation method
    """
    if whiten:
        series = series.whiten(fftlength=fftlength, overlap=overlap, **kwargs)
    bpseries = series.bandpass(flow, fhigh)
    return bpseries.rms(stride)