def attach_measure_thickness(api, window):
    """Attaches the measure Thickness computation to the target data item in the window."""
    target_data_item = window.target_data_item
    if target_data_item and target_data_item.display_xdata.is_data_1d:
        api.library.create_computation('nion.eels_analysis.measure_thickness',
            inputs={'src': target_data_item}, outputs={'thickness_interval':
            None})


def get_custom_db(firmware_version, _db):
    """Get db of device if yours doesn't exists."""
    if _db:
        if firmware_version in _db:
            return _db[firmware_version]
    return None


def set_latex_globally():
    """ Call this function to use latex synthax globally in matplotlip.
    Note that now every string used through matplotlib has to respect latex
    synthax.
    """
    from matplotlib import rcParams
    rcParams['text.usetex'] = True
    rcParams['text.latex.preamble'] = ['\\usepackage{amssymb}']


def _clean_up():
    """Clean up upon exit from the main processing loop.

        Called when the runner's main loop is stopped, this should perform any
        necessary resource deallocation.
        """


def uninstall(context):
    """Uninstall script"""
    if context.readDataFile('medialogcaptchawidget_uninstall.txt') is None:
        return


def fade_out_fx(channel, time):
    """ fade out sound in time """
    pass


def abs_sum(df_or_series):
    """type agnostic sum of absolute values"""
    return df_or_series.abs().sum()


def match_items(lines, content_old):
    """Create items for mangled lines.

    This function tries to match the lines in ``lines`` with the items (source
    file references and line numbers) in ``content_old``. The
    ``mangle_docstrings`` function changes the actual docstrings, but doesn't
    keep track of where each line came from. The manging does many operations
    on the original lines, which are hard to track afterwards.

    Many of the line changes come from deleting or inserting blank lines. This
    function tries to match lines by ignoring blank lines. All other changes
    (such as inserting figures or changes in the references) are completely
    ignored, so the generated line numbers will be off if ``mangle_docstrings``
    does anything non-trivial.

    This is a best-effort function and the real fix would be to make
    ``mangle_docstrings`` actually keep track of the ``items`` together with
    the ``lines``.

    Examples
    --------
    >>> lines = ['', 'A', '', 'B', '   ', '', 'C', 'D']
    >>> lines_old = ['a', '', '', 'b', '', 'c']
    >>> items_old = [('file1.py', 0), ('file1.py', 1), ('file1.py', 2),
    ...              ('file2.py', 0), ('file2.py', 1), ('file2.py', 2)]
    >>> content_old = ViewList(lines_old, items=items_old)
    >>> match_items(lines, content_old) # doctest: +NORMALIZE_WHITESPACE
    [('file1.py', 0), ('file1.py', 0), ('file2.py', 0), ('file2.py', 0),
     ('file2.py', 2), ('file2.py', 2), ('file2.py', 2), ('file2.py', 2)]
    >>> # first 2 ``lines`` are matched to 'a', second 2 to 'b', rest to 'c'
    >>> # actual content is completely ignored.

    Notes
    -----
    The algorithm tries to match any line in ``lines`` with one in
    ``lines_old``.  It skips over all empty lines in ``lines_old`` and assigns
    this line number to all lines in ``lines``, unless a non-empty line is
    found in ``lines`` in which case it goes to the next line in ``lines_old``.

    """
    items_new = []
    lines_old = content_old.data
    items_old = content_old.items
    j = 0
    for i, line in enumerate(lines):
        while j < len(lines_old) - 1 and not lines_old[j].strip():
            j += 1
        items_new.append(items_old[j])
        if line.strip() and j < len(lines_old) - 1:
            j += 1
    assert len(items_new) == len(lines)
    return items_new


def map_citem2line(line2citem):
    """Part of `Lighthouse plugin <https://github.com/gaasedelen/lighthouse>`_

    Creates a mapping of citem indexes to lines of code
    """
    citem2line = {}
    for line, citem_l in line2citem.items():
        for citem_idx in citem_l:
            citem2line[citem_idx] = line
    return citem2line


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

    The ".dev0" means dirty.

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


def get_attribute_at(config, target_path, key, default_value=None):
    """
    Return attribute value at a given path

    :param config:
    :param target_path:
    :param key:
    :param default_value:
    :return:
    """
    for target in target_path:
        config = config[target]
    return config[key] if key in config else default_value


def run_length_encode(in_array):
    """A function to run length decode an int array.

    :param in_array: the inptut array of integers
    :return the encoded integer array"""
    if len(in_array) == 0:
        return []
    curr_ans = in_array[0]
    out_array = [curr_ans]
    counter = 1
    for in_int in in_array[1:]:
        if in_int == curr_ans:
            counter += 1
        else:
            out_array.append(counter)
            out_array.append(in_int)
            curr_ans = in_int
            counter = 1
    out_array.append(counter)
    return out_array


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

        :param GroupDeleteDetails val:
        :rtype: EventDetails
        """
    return cls('group_delete_details', val)


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


def _get_data_for_html_display(obj):
    """Returns the data need to display the object in HTML.
    """
    return {'jstree_data': obj.to_jstree_dict(), 'previous': obj.
        get_previous_js_selectors(), 'html': obj.to_html(), 'elt_id': ':'.
        join(obj.prefixes)}


def rendered_columns(uid):
    """Render initial finder columns with object by uid as anchor.
        """


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


def aria_bool(value):
    """ aria2 rpc requires strings for some boolean arguments like 'continue'
	"""
    if value is None:
        return None
    elif value is True:
        return 'true'
    elif value is False:
        return 'false'
    else:
        raise ValueError(str(value))


def uniq(l):
    """Return list with consecutive duplicates removed."""
    result = l[:1]
    for item in l[1:]:
        if item != result[-1]:
            result.append(item)
    return result


def camelcase_to_underscores(argument):
    """ Converts a camelcase param like theNewAttribute to the equivalent
    python underscore variable like the_new_attribute"""
    result = ''
    prev_char_title = True
    if not argument:
        return argument
    for index, char in enumerate(argument):
        try:
            next_char_title = argument[index + 1].istitle()
        except IndexError:
            next_char_title = True
        upper_to_lower = char.istitle() and not next_char_title
        lower_to_upper = char.istitle() and not prev_char_title
        if index and (upper_to_lower or lower_to_upper):
            result += '_'
        prev_char_title = char.istitle()
        if not char.isspace():
            result += char.lower()
    return result


def alias(alias):
    """Select a single alias."""
    return {'alias': alias}


def flatten_request_header(header):
    """
    Transform a dict representing header parameters into a flat string of
    comma separated parameters suitable for inserting into the actual
    headers
    """
    flattened_header = ''
    if isinstance(header, dict):
        contents = []
        for content_key, content_val in header.items():
            contents.append('%s="%s"' % (content_key, content_val))
        flattened_header = ','.join(contents)
    else:
        flattened_header = str(header)
    return flattened_header


@staticmethod
def method():
    """method returns an associated ID for the Juju API call.
        """
    return 'addRelation'


@classmethod
def get_rawtx(cls, txid):
    """Gets rawtx by txid.

        :param txid: The transaction id in question.
        :type txid: ``str``
        :raises ConnectionError: If all API services fail.
        :rtype: ``str``
        """
    for api_call in cls.GET_RAWTX_MAIN:
        try:
            return api_call(txid)
        except cls.IGNORED_ERRORS:
            pass
    raise ConnectionError('All APIs are unreachable.')


def _explode_full_table_names(in_tables):
    """
    Takes a list of schema-qualified names and creates a schema-key, table_list-value dict
    :param in_tables: A list of schema-qualified table/view names
    :return:          schema-key, table_list-value dict
    """
    schema_to_table = dict()
    for t in set(in_tables):
        parts = t.split('.')
        schema = parts[0]
        table = parts[1]
        if schema in schema_to_table:
            schema_to_table[schema].append(table)
        else:
            schema_to_table[schema] = [table]
    return schema_to_table


def update_progress(name: str='Master', percent: float=None, message: str=None
    ) ->None:
    """
    * Allows the user to identify the prograss of the script

    * name: Is the of the progress bar master being the full script progress
    * percent: is a optional way to update progress.
    * message: is a optional way to update progress.
    """
    return


def calc_bpm(beat_interval, sampling_freq):
    """ Calculate instantaneous BPM from beat to beat interval

        Args:
            beat_interval: (int) number of samples in between each beat
                            (typically R-R Interval)
            sampling_freq: (float) sampling frequency in Hz

        Returns:
            bpm:  (float) beats per minute for time interval
    """
    return 60 * sampling_freq * (1 / beat_interval)


@classmethod
def _initialize(cls, port, secret):
    """
        Initialize BarrierTaskContext, other methods within BarrierTaskContext can only be called
        after BarrierTaskContext is initialized.
        """
    cls._port = port
    cls._secret = secret


def assert_code(response, status_code, msg_prefix=''):
    """Assert the response was returned with the given status code."""
    if msg_prefix:
        msg_prefix = '%s: ' % msg_prefix
    assert response.status_code == status_code, 'Response code was %d (expected %d)' % (
        response.status_code, status_code)


def cache_hostinfo(environ):
    """Processes the host information and stores a copy

    This work was previously done but wasn't stored in environ, nor is
    it guaranteed to be setup in the future (Routes 2 and beyond).

    cache_hostinfo processes environ keys that may be present to
    determine the proper host, protocol, and port information to use
    when generating routes.

    """
    hostinfo = {}
    if environ.get('HTTPS') or environ.get('wsgi.url_scheme'
        ) == 'https' or environ.get('HTTP_X_FORWARDED_PROTO') == 'https':
        hostinfo['protocol'] = 'https'
    else:
        hostinfo['protocol'] = 'http'
    if environ.get('HTTP_X_FORWARDED_HOST'):
        hostinfo['host'] = environ['HTTP_X_FORWARDED_HOST']
    elif environ.get('HTTP_HOST'):
        hostinfo['host'] = environ['HTTP_HOST']
    else:
        hostinfo['host'] = environ['SERVER_NAME']
        if environ.get('wsgi.url_scheme') == 'https':
            if environ['SERVER_PORT'] != '443':
                hostinfo['host'] += ':' + environ['SERVER_PORT']
        elif environ['SERVER_PORT'] != '80':
            hostinfo['host'] += ':' + environ['SERVER_PORT']
    environ['routes.cached_hostinfo'] = hostinfo
    return hostinfo


def _shape_to_size(shape):
    """
    Compute the size which corresponds to a shape
    """
    out = 1
    for item in shape:
        out *= item
    return out


@staticmethod
def set_connect_status(status):
    """
        Override the proton connection status.
        """
    global CONNECT_STATUS
    CONNECT_STATUS = status


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


def reload_experiment(api, exp_id, duration=None, start_time=None):
    """Reload given experiment, duration and start_time can be adapted.

    :param api: API Rest api object
    :param exp_id: experiment id
    :param duration: experiment duration in minutes. None for same duration.
    :param start_time: experiment start time timestamp.
        None for as soon as possible
    """
    exp_json = {}
    if duration is not None:
        exp_json['duration'] = str(duration)
    if start_time is not None:
        exp_json['reservation'] = str(start_time)
    return api.reload_experiment(exp_id, exp_json)


def format_arg_value(arg_val):
    """ Return a string representing a (name, value) pair.

    >>> format_arg_value(('x', (1, 2, 3)))
    'x=(1, 2, 3)'
    """
    arg, val = arg_val
    return '%s=%r' % (arg, val)


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

    The ".dev0" means dirty.

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


@classmethod
def main(cls, *args, **kwargs):
    """
        Run the program.
        """
    assert not (bool(args) and bool(kwargs))
    if args:
        return cls._run_args(args)
    elif kwargs:
        return cls._run_kwargs(kwargs)
    else:
        return cls._run_args(None)


def global_subplot_colorbar(p_obj, axs, fig, **kwargs):
    """Creates one colorbar for all subplots.

    Args:
        p_obj (obj): a single plot object, e.g. p_obj = plt.pcolormesh().
        axs (axes): collective axes object.
        fig (figure): figure object.
        **kwargs: arguments to be passed to plt.colorbar().

    Returns:
        Colorbar object and adds the colorbar to the side of the current fig.
        By passing `orientation='horizontal'`, it will be plotted at the
        bottom of the figure.
    """
    cb = fig.colorbar(p_obj, ax=axs.ravel().tolist(), **kwargs)
    return cb


def detach_thing_principal(thingName=None, principal=None):
    """
    Detaches the specified principal from the specified thing.
    See also: AWS API Documentation

    :example: response = client.detach_thing_principal(
        thingName='string',
        principal='string'
    )

    :type thingName: string
    :param thingName: [REQUIRED]
            The name of the thing.

    :type principal: string
    :param principal: [REQUIRED]
            If the principal is a certificate, this value must be ARN of the certificate. If the principal is an Amazon Cognito identity, this value must be the ID of the Amazon Cognito identity.

    :rtype: dict
    :return: {}

    """
    pass


def removeNullTerminator(bytestring):
    """Remove null terminator from bytestring."""
    bytesOut = bytestring.rstrip(b'\x00')
    return bytesOut


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 measureCanvas(nfigs, ncols_max=2, figinches=(6, 4)):
    """
    @params nfigs    : (int) Total number of figures.
    @params ncols_max: (int) The number of columns.
    @params figinches: (tuple) The figure size for 1 plot.
    """
    if nfigs >= ncols_max:
        ncols = ncols_max
        nrows = (nfigs - 1) // ncols_max + 1
    else:
        ncols = nfigs
        nrows = 1
    w, h = figinches
    figsize = w * ncols, h * nrows
    return ncols, nrows, figsize


def is_pendant(G, edge):
    """Checks if `edge` is pendant in the graph `G`"""
    if G.degree(edge[0]) == 1 or G.degree(edge[1]) == 1:
        return True
    else:
        return False


def get_active():
    """Return True if the upload is currently active, False if not."""


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


@classmethod
def raw_results_to_json(cls, raw_text, delim=','):
    """Converts raw BLAST text into a flatten dictionary.

        :param raw_text: raw text from BLAST results
        :type raw_text: basestring
        :param delim: delimiter for parsing
        :type delim: basestring
        :return: flattened dictionary
        :rtype: dict
        """
    if raw_text.strip() == '':
        return []
    meta = cls._extract_metadata(raw_text, delim)
    fields = meta['fields']
    if fields is None:
        return []
    alignment_rows = cls._get_alignment_rows(raw_text)
    match_dicts = cls._validate_matches(alignment_rows, tuple(fields))
    data = list(cls.__clean_json(match_dicts))
    return data


def get_bot_aliases(botName=None, nextToken=None, maxResults=None,
    nameContains=None):
    """
    Returns a list of aliases for a specified Amazon Lex bot.
    This operation requires permissions for the lex:GetBotAliases action.
    See also: AWS API Documentation

    :example: response = client.get_bot_aliases(
        botName='string',
        nextToken='string',
        maxResults=123,
        nameContains='string'
    )

    :type botName: string
    :param botName: [REQUIRED]
            The name of the bot.

    :type nextToken: string
    :param nextToken: A pagination token for fetching the next page of aliases. If the response to this call is truncated, Amazon Lex returns a pagination token in the response. To fetch the next page of aliases, specify the pagination token in the next request.

    :type maxResults: integer
    :param maxResults: The maximum number of aliases to return in the response. The default is 50. .

    :type nameContains: string
    :param nameContains: Substring to match in bot alias names. An alias will be returned if any part of its name matches the substring. For example, 'xyz' matches both 'xyzabc' and 'abcxyz.'

    :rtype: dict
    :return: {
        'BotAliases': [
            {
                'name': 'string',
                'description': 'string',
                'botVersion': 'string',
                'botName': 'string',
                'lastUpdatedDate': datetime(2015, 1, 1),
                'createdDate': datetime(2015, 1, 1),
                'checksum': 'string'
            },
        ],
        'nextToken': 'string'
    }

    """
    pass


@classmethod
def all(cls):
    """Return a list of all states."""
    return [cls.starting, cls.waiting, cls.processing, cls.finished, cls.
        error, cls.reapplying, cls.enrolling, cls.aborting]


def check_mouse_ax(event, self):
    """Grabs the mouse axes position

    Parameters
    ==========
    event (matplotlib event)
        the matpotlib event
    self (SXDMFrameset)
        the sxdmframeset

    Returns
    =======
    Nothing - just checks which axis the mouse is in
    """
    if event.inaxes == self.fluor_ax:
        self.viewer_currentax = self.fluor_ax
    elif event.inaxes == self.roi_ax:
        self.viewer_currentax = self.roi_ax


def eyedropper_colorramp():
    """Sample a color band

    """
    pass


def get_file_extension(filename):
    """ Return the extension if the filename has it. None if not.

    :param filename: The filename.
    :return: Extension or None.
    """
    filename_x = filename.split('.')
    if len(filename_x) > 1:
        if filename_x[-1].strip() is not '':
            return filename_x[-1]
    return None


def pytest_addoption(parser):
    """Add the --snail CLI option."""
    group = parser.getgroup('snail')
    group.addoption('--snail', action='store', type=float, default=5.0,
        metavar='DURATION', help=
        'tests running longer than this value will be marked')


def _make_logger_prefix(tag: str=None):
    """creates a function to add logger prefix"""
    return lambda text: '{}{}'.format(tag + ': ' if tag else '', text)


def change_record(temp, column, factorlist):
    """
    타자의 이닝별 기록을 숫자 코드로 변경하는 함수

    Args:
        temp(pandas DF): 타자기록이 저장된 데이터 프레임
        column(str): 열이름들 중 이닝
        factorlist(pandas DF): 타격 기록에 해당하는 숫자코드

    Returns:
        temp(pandas DF): 타자기록이 숫자코드로 변경된 데이터 프레임
    """
    for i in range(0, len(temp[[str(column)]])):
        if '/' in list(str(temp[str(column)].tolist()[i])):
            temp1 = factorlist.code[factorlist.factor_list == str(temp[str(
                column)].tolist()[i].split('/ ')[0].split('\\')[0])]
            temp2 = factorlist.code[factorlist.factor_list == str(temp[str(
                column)].tolist()[i].split('/ ')[1])]
            temp.loc[i, str(column)] = str(list(temp1)[0]) + str(list(temp2)[0]
                )
    return temp


@staticmethod
def mimetype():
    """Return most common media type for format."""
    return 'application/json'


@staticmethod
def _draw_outer_connector(context, width, height):
    """Draw the outer connector for container states

        Connector for container states can be connected from the inside and the outside. Thus the connector is split
        in two parts: A rectangle on the inside and an arrow on the outside. This method draws the outer arrow.

        :param context: Cairo context
        :param float port_size: The side length of the port
        """
    c = context
    arrow_height = height / 2.5
    gap = height / 6.0
    connector_height = (height - gap) / 2.0
    c.rel_move_to(-width / 2.0, -gap / 2.0)
    c.rel_line_to(width, 0)
    c.rel_line_to(0, -(connector_height - arrow_height))
    c.rel_line_to(-width / 2.0, -arrow_height)
    c.rel_line_to(-width / 2.0, arrow_height)
    c.close_path()


def declare_time(head):
    """Determine the maximum/minimum age of the files
       It does this through converting the specified
       age to days.
    """
    types = ['y', 'mon', 'w', 'd', 'h', 'min', 's']
    for item in types:
        if item in head[0]:
            if item == 'y':
                age = float(head[0][0:len(head) - 2]) * 365
            if item == 'mon':
                age = float(head[0][0:len(head) - 4]) * 30
            if item == 'w':
                age = float(head[0][0:len(head) - 2]) * 7
            if item == 'd':
                age = float(head[0][0:len(head) - 2])
            if item == 'h':
                age = float(head[0][0:len(head) - 2]) / 24
            if item == 'min':
                age = float(head[0][0:len(head) - 4]) / 24 / 60
            if item == 's':
                age = float(head[0][0:len(head) - 2]) / 24 / 60 / 60
    return age


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def min():
    """find minimum thing in incoming things using call as key function"""


def is_regressor(estimator):
    """
    Returns True if the given estimator is (probably) a regressor.

    Parameters
    ----------
    estimator : class or instance
        The object to test if it is a Scikit-Learn clusterer, especially a
        Scikit-Learn estimator or Yellowbrick visualizer

    See also
    --------
    is_regressor
        `sklearn.is_regressor() <https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/base.py#L531>`_
    """
    return getattr(estimator, '_estimator_type', None) == 'regressor'


def isDefaultPage(obj):
    """Finds out if the given obj is the default page for the
        adapted object.
        """


@classmethod
def cache_objects(cls, data, key=None):
    """ This classmethod allows to feed multiple objects into the
            cache is is mostly used for testing
        """
    return cls._import(data, key)


def _format_md_attr_list(item, linkify):
    """Create a Markdown attribute list for a heading."""
    return ' {{#{u} }}'.format(u=item.uid) if linkify else ''


def discard(evolver, key):
    """ Discard the element and returns a structure without the discarded elements """
    try:
        del evolver[key]
    except KeyError:
        pass


@classmethod
def lock(cls, pid, connection, session):
    """Explicitly lock the specified connection in the pool

        :param str pid: The pool id
        :type connection: psycopg2.extensions.connection
        :param connection: The connection to add to the pool
        :param queries.Session session: The session to hold the lock

        """
    with cls._lock:
        cls._ensure_pool_exists(pid)
        cls._pools[pid].lock(connection, session)


def _aespad(data):
    """ipmi demands a certain pad scheme, per table 13-20 AES-CBC encrypted

    payload fields.
    """
    currlen = len(data) + 1
    neededpad = currlen % 16
    if neededpad:
        neededpad = 16 - neededpad
    padval = 1
    pad = bytearray(neededpad)
    while padval <= neededpad:
        pad[padval - 1] = padval
        padval += 1
    pad.append(neededpad)
    return pad


def is_good_response(resp):
    """
    Returns True if the response seems to be HTML, False otherwise.
    """
    content_type = resp.headers['Content-Type'].lower()
    return (resp.status_code == 200 and content_type is not None and
        content_type.find('html') > -1)


def update_rho(rho, rnorm, snorm, iteration=None, mu=10, tau_inc=2, tau_dec=2):
    """See Boyd pag 20-21 for details.

    Parameters
    ----------
    rho : float
    """
    if rnorm > mu * snorm:
        return tau_inc * rho
    elif snorm > mu * rnorm:
        return rho / tau_dec
    return rho


def GetSGSpin(SGData, MSgSym):
    """get spin generators from magnetic space group symbol"""
    SpGrp = SGData['SpGrp']
    mSgSym = MSgSym + ' '
    Flds = SpGrp.split()
    iB = 0
    Spn = [1]
    if len(Flds) == 2:
        fld = Flds[1]
        iF = mSgSym[iB:].index(fld[0]) + iB
        jF = mSgSym[iF:].index(fld[-1]) + iF
        if '/' in mSgSym[iF:jF]:
            if "'" in mSgSym[iF:jF]:
                Spn.append(-1)
            else:
                Spn.append(1)
        if "'" == mSgSym[jF + 1]:
            Spn.append(-1)
        else:
            Spn.append(1)
    elif len(Flds) == 3:
        if SGData['SGPtGrp'] == '-3m':
            if not mSgSym.count("'"):
                Spn += [1, 1]
            elif mSgSym.count("'") == 2:
                Spn += [-1, 1]
            elif "3'" in mSgSym:
                Spn += [1, -1]
            else:
                Spn += [-1, -1]
        elif "'" in mSgSym:
            Spn.append(-1)
        else:
            Spn.append(1)
    else:
        for fld in Flds[1:]:
            iF = mSgSym[iB:].index(fld[0]) + iB
            jF = mSgSym[iF:].index(fld[-1]) + iF
            if "'" == mSgSym[jF + 1]:
                Spn.append(-1)
                iB = jF + 2
            else:
                Spn.append(1)
                iB = jF + 1
    Spn.append(1)
    return Spn


def purge(requestor, service, nodeIdentifier):
    """
        Called when a node purge request has been received.

        @param requestor: The entity the request originated from.
        @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param service: The entity the request was addressed to.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: The identifier of the node to be purged.
        @type nodeIdentifier: C{unicode}
        """


def get_all_ips(instance):
    """ Returns the public and private ip addresses of an GCP Compute instance
    """
    ip_list = []
    try:
        ip_list.append(instance['networkInterfaces'][0]['accessConfigs'][0]
            ['natIP'])
    except Exception as e:
        pass
    ip_list.append(instance['networkInterfaces'][0]['networkIP'])
    return ip_list


@staticmethod
def listify(s):
    """Convert unknown input to a list

        Parameters
        ----------
        s : str, int, float, list, tuple

        Returns
        -------
        list
           The input as list

        """
    if isinstance(s, list):
        return s
    elif isinstance(s, tuple):
        return list(s)
    else:
        return [s]


def __new__(cls, obj, *args, **kwargs):
    """
        creates an proxy instance referencing `obj`. (obj, *args, **kwargs) are
        passed to this class' __init__, so deriving classes can define an
        __init__ method of their own.
        note: _class_proxy_cache is unique per deriving class (each deriving
        class must hold its own cache)
        """
    try:
        cache = cls.__dict__['_class_proxy_cache']
    except KeyError:
        cls._class_proxy_cache = cache = {}
    try:
        theclass = cache[obj.__class__]
    except KeyError:
        cache[obj.__class__] = theclass = cls._create_class_proxy(obj.__class__
            )
    ins = object.__new__(theclass)
    theclass.__init__(ins, obj, *args, **kwargs)
    return ins


def regions2dict(regions):
    """
    Convert a 2d array into a dict
    """
    reg_dict = {}
    for chrid, start, end in regions:
        if chrid not in reg_dict:
            reg_dict[chrid] = []
        reg_dict[chrid].append([start, end])
    return reg_dict


def dic2blockheader(dic):
    """
    Convert a python dictionary into block header list.

    Does not repack status and mode from bit flags.
    """
    head = [0] * 9
    head[0] = dic['scale']
    head[1] = dic['status']
    head[2] = dic['index']
    head[3] = dic['mode']
    head[4] = dic['ctcount']
    head[5] = dic['lpval']
    head[6] = dic['rpval']
    head[7] = dic['lvl']
    head[8] = dic['tlt']
    return head


def rightmost(root):
    """
    Returns the rightmost leaf in this tree.

    :param root: The root node of the tree.
    :type root: d20.ast.ChildMixin
    :rtype: d20.ast.ChildMixin
    """
    right = root
    while right.children:
        right = right.children[-1]
    return right


def should_build_with_cython(package, release=None):
    """Returns the previously used Cython version (or 'unknown' if not
    previously built) if Cython should be used to build extension modules from
    pyx files.  If the ``release`` parameter is not specified an attempt is
    made to determine the release flag from `astropy.version`.
    """
    from ..setup_helpers import _module_state
    try:
        version_module = __import__(package + '.cython_version', fromlist=[
            'release', 'cython_version'])
    except ImportError:
        version_module = None
    if release is None and version_module is not None:
        try:
            release = version_module.release
        except AttributeError:
            pass
    try:
        cython_version = version_module.cython_version
    except AttributeError:
        cython_version = 'unknown'
    if _module_state['have_cython'] and (not release or cython_version ==
        'unknown'):
        return cython_version
    else:
        return False


def main():
    """
    main() function, not directly callable.
    :return:
    """
    print('Not directly executable')


def bytes_to_int(b: bytes) ->int:
    """Attempts to convert a bytes object of any length to an integer"""
    return int.from_bytes(b, 'little', signed=False)


def yn_choice(message, default='y'):
    """
    Querry the user if he or she wants to proceed.

    Parameters
    ----------
    message :
        Yes/No message presented to the user.
    default :
        Default action if no input is given

    Returns
    -------
    bool :
        `True` for yes, else `False`
    """
    choices = 'Y/n' if default.lower() in ('y', 'yes') else 'y/N'
    choice = input('%s (%s) ' % (message, choices))
    values = ('y', 'yes', '') if default == 'y' else ('y', 'yes')
    return choice.strip().lower() in values


def compare_list(list1, list2):
    """
    It will compare two python lists and return boolean result
    """
    if isinstance(list1, list) and isinstance(list2, list):
        if len(list2) != len(list1):
            return False
        for list2_item in list2:
            if list2_item not in list1:
                return False
        for list1_item in list1:
            if list1_item not in list2:
                return False
        return True
    raise Exception('Invalid Data provided')


def sequence(values):
    """
    Wrap a list of Python values as an Ibis sequence type

    Parameters
    ----------
    values : list
      Should all be None or the same type

    Returns
    -------
    seq : Sequence
    """
    import ibis.expr.operations as ops
    return ops.ValueList(values).to_expr()


def return_list_without_duplicates(lst):
    """
    Removes duplicates from a list and return the new ilst
    :param lst: list
    :return: list
    """
    new_list = list()
    for item in lst:
        if item not in new_list:
            new_list.append(item)
    return new_list


@staticmethod
def _from_db_object(x509keypair, db_x509keypair):
    """Converts a database entity to a formal object."""
    for field in x509keypair.fields:
        x509keypair[field] = db_x509keypair[field]
    x509keypair.obj_reset_changes()
    return x509keypair


def clean(values, strip=strip, empty=True):
    """
    Strip each value and yield if not empty.
    """
    for value in values:
        value = strip(value)
        if not value and empty:
            continue
        yield value


def create_urwid_mainloop():
    """Create the urwid main loop.
        """


@staticmethod
def resistance(genename, resistance_dict):
    """
        Determine the resistance class of the gene by searching the sets of genes included in every resistance FASTA
        file
        :param genename: Header string returned from analyses
        :param resistance_dict: Dictionary of resistance class: header
        :return: resistance class of the gene
        """
    resistance_list = list()
    for resistance_class, gene_set in resistance_dict.items():
        if genename in gene_set:
            resistance_list.append(resistance_class)
    resistance = ','.join(sorted(resistance_list))
    return resistance


def to_unicode(text, encoding=None, errors='strict'):
    """Return the unicode representation of a bytes object ``text``. If
    ``text`` is already an unicode object, return it as-is."""
    if isinstance(text, str):
        return text
    if not isinstance(text, (bytes, str)):
        raise TypeError(
            'to_unicode must receive a bytes or str object, got %s' % type(
            text).__name__)
    if encoding is None:
        encoding = 'utf-8'
    return text.decode(encoding, errors)


def minor_from_branch(ver):
    """Parse the minor version from the provided version (or 'branch').

For example, if --group=openshift-3.9 then runtime.group_config.branch
will have the value rhaos-3.9-rhel-7. When passed to this function the
return value would be the number 9, where in considering '3.9' then
'9' is the MINOR version.

I.e., this gives you the Y component if 3.9 => X.Y.

This behavior is HIGHLY dependent on the format of the input
argument. Hence, why this function indicates the results are based on
the 'branch' variable. Arbitrary input will fail. Use of this implies
you read the docs.
    """
    return ver.split('-')[1].split('.')[1]


def correlation_function(x, y):
    """
    Get correlation between 2 arrays.

    Parameters
    ----------
    x : ~pytil.numpy.ArrayLike[float]
    y : ~pytil.numpy.ArrayLike[float]

    Returns
    -------
    float
        Correlation between ``x`` and ``y``
    """
    raise Exception(
        'This is an abstract function intended to be referenced in documentation only, do not call it in code'
        )


def _syntaxerror_offset(value, lineoffset):
    """Adjust the line number in a SyntaxError exception."""
    if lineoffset:
        msg, (efname, elineno, eoffset, badline) = value.args
        value.args = msg, (efname, elineno + lineoffset, eoffset, badline)
        value.lineno = elineno + lineoffset


def fades_clear():
    """Removes fade animation from selected sequences

    """
    pass


def real_project_name(project_name):
    """
    Used to let Mezzanine run from its project template directory, in which
    case "{{ project_name }}" won't have been replaced by a real project name.
    """
    if project_name == '{{ project_name }}':
        return 'project_name'
    return project_name


def errno_from_exception(e):
    """Provides the errno from an Exception object.

    There are cases that the errno attribute was not set so we pull
    the errno out of the args but if someone instantiates an Exception
    without any args you will get a tuple error. So this function
    abstracts all that behavior to give you a safe way to get the
    errno.
    """
    if hasattr(e, 'errno'):
        return e.errno
    elif e.args:
        return e.args[0]
    else:
        return None


def add_gpencil():
    """Add brush for Grease Pencil

    """
    pass


def polynomial(name, *varlist, **kwargs):
    """
    Multivariate polynomial effect in the specified numeric variables

    Parameters
    ----------
    name : string
        specifies the name of the effect.
    *varlist : one or more strings
        specifies numeric variables for the multivariate polynomial
        effect.
        Default: []
    details : boolean, optional
        requests a table that shows additional details related to this
        effect.
        Default: False
    degree : int32, optional
        specifies the degree of the polynomial. The degree must be a
        positive integer.
        Default: 1
        Note: Value range is 0 <= n < 2147483647
    labelstyle : dict, optional
        specifies a list of options that control the terms in the
        polynomial are labeled.

        expand : boolean, optional
            when set to True, specifies that each variable with an
            exponent greater than 1 be written as products of that
            variable.
            Default: False
        exponent : string, optional
            specifies that each variable with an exponent greater than 1
            be written using exponential notation with the specified
            exponentiation string. By default, the symbol ^ is used as
            the exponentiation operator.
        includename : boolean, optional
            when set to True, specifies that the name of the effect
            followed by an underscore be used as a prefix for term
            labels.
            Default: False
        productsymbol : string, optional
            specifies that the supplied string be used as the product
            symbol.

    mdegree : int32, optional
        specifies the maximum degree of any variable in a term of the
        polynomial. This degree must be a positive integer. The default
        is the degree of the specified polynomial.
        Default: 1
        Note: Value range is 1 <= n < 2147483647
    noseparate : boolean, optional
        specifies that the polynomial be treated as a single effect with
        multiple degrees of freedom. The effect name that you specify is
        used as the constructed effect name, and the labels of the terms
        are used as labels of the corresponding parameters.
        Default: False
    standardize : dict, optional
        specifies a list of options that control how the variables
        forming the polynomial are standardized.

        method : string, optional
            specifies the method by which the variables that define the
            polynomial be standardized.
            Default: MRANGE
            Values: MOMENTS, MRANGE, WMOMENTS
        prefix : string, optional
            specifies the prefix that is appended to standardized
            variables when forming the term labels.
        options : string, optional
            controls whether the standardization is to center, scale, or
            both center and scale.
            Default: CENTERSCALE
            Values: CENTER, CENTERSCALE, NONE, SCALE

    Returns
    -------
    dict

    """
    dict(name=name, varlist=list(varlist), **kwargs)


def trim_beats(beats, min_beat_time=5.0):
    """Removes beats before min_beat_time.  A common preprocessing step.

    Parameters
    ----------
    beats : np.ndarray
        Array of beat times in seconds.
    min_beat_time : float
        Minimum beat time to allow
        (Default value = 5.)

    Returns
    -------
    beats_trimmed : np.ndarray
        Trimmed beat array.
    """
    return beats[beats >= min_beat_time]


def resolve_host(host, port=None):
    """
    Resolve host from given arguments
    :param host: string
    :param port: number
    :return:
    """
    if port and port != 80:
        host += ':' + str(port)
    if not host.startswith('http'):
        host = 'http://' + host
    return host


def describe_services(serviceCodeList=None, language=None):
    """
    Returns the current list of AWS services and a list of service categories that applies to each one. You then use service names and categories in your  CreateCase requests. Each AWS service has its own set of categories.
    The service codes and category codes correspond to the values that are displayed in the Service and Category drop-down lists on the AWS Support Center Create Case page. The values in those fields, however, do not necessarily match the service codes and categories returned by the DescribeServices request. Always use the service codes and categories obtained programmatically. This practice ensures that you always have the most recent set of service and category codes.
    See also: AWS API Documentation

    :example: response = client.describe_services(
        serviceCodeList=[
            'string',
        ],
        language='string'
    )

    :type serviceCodeList: list
    :param serviceCodeList: A JSON-formatted list of service codes available for AWS services.
            (string) --

    :type language: string
    :param language: The ISO 639-1 code for the language in which AWS provides support. AWS Support currently supports English ('en') and Japanese ('ja'). Language parameters must be passed explicitly for operations that take them.

    :rtype: dict
    :return: {
        'services': [
            {
                'code': 'string',
                'name': 'string',
                'categories': [
                    {
                        'code': 'string',
                        'name': 'string'
                    },
                ]
            },
        ]
    }

    """
    pass


def insert_output_start_stop_indicators(src):
    """
    Insert identifier strings so that output can be segregated from input.

    Parameters
    ----------
    src : str
        String containing input and output lines.

    Returns
    -------
    str
        String with output demarked.
    """
    lines = src.split('\n')
    print_producing = ['print(', '.setup(', '.run_model(', '.run_driver(',
        '.check_partials(', '.check_totals(', '.list_inputs(',
        '.list_outputs(', '.list_problem_vars(']
    newlines = []
    input_block_number = 0
    in_try = False
    in_continuation = False
    head_indent = ''
    for line in lines:
        newlines.append(line)
        if in_continuation:
            line = line.rstrip()
            if not (line.endswith(',') or line.endswith('\\') or line.
                endswith('(')):
                newlines.append('%sprint(">>>>>%d")' % (head_indent,
                    input_block_number))
                input_block_number += 1
                in_continuation = False
        if in_try:
            if 'except' in line:
                in_try = False
            continue
        if 'try:' in line:
            in_try = True
            continue
        if 'set_solver_print(' in line:
            continue
        for item in print_producing:
            if item in line:
                indent = ' ' * (len(line) - len(line.lstrip()))
                line = line.rstrip()
                if line.endswith(',') or line.endswith('\\') or line.endswith(
                    '('):
                    in_continuation = True
                    head_indent = indent
                    break
                newlines.append('%sprint(">>>>>%d")' % (indent,
                    input_block_number))
                input_block_number += 1
                break
    return '\n'.join(newlines)