@classmethod
def coerce(cls, o):
    """This method serves as a processor for filling values.

        When you are filling values inside widgets and views, I bet you will quickly realize that
        filling basic values like strings or numbers is not enough. This method allows a potential
        fillable implement :py:meth:`as_fill_value` to return a basic value that represents the
        object in the UI

        Args:
            o: Object to be filled in the :py:class:`widgetastic.widget.View` or
                :py:class:`widgetastic.widget.Widget`

        Returns:
            Whatever is supposed to be filled in the widget.
        """
    if isinstance(o, cls):
        return o.as_fill_value()
    else:
        return o


def set_optionparser(option_class, optionparser_class):
    """Set the default Option and OptionParser class"""
    global OPTION_CLASS
    global OPTIONPARSER_CLASS
    OPTION_CLASS = option_class
    OPTIONPARSER_CLASS = optionparser_class


@staticmethod
def bg(value: int) ->str:
    """
        Returns the background escape code for a 256 color id.
        See https://jonasjacek.github.io/colors/ for full list.
        """
    return f'\x1b[48;5;{value}m'


def stop_discovery(browser):
    """Stop the chromecast discovery thread."""
    browser.zc.close()


@classmethod
def _order(cls, x):
    """Return an integer value for character x"""
    if x.isdigit():
        return int(x) + 1
    if x.isalpha():
        return ord(x)
    return ord(x) + 256


def native_pathsep(path):
    """Replace the path separator with the systems native os.sep.

    """
    pass


def _p100(part, total, prec=1):
    """Return percentage as string.
    """
    r = float(total)
    if r:
        r = part * 100.0 / r
        return '%.*f%%' % (prec, r)
    return 'n/a'


def read_igor_D_gene_parameters(params_file_name):
    """Load genD from file.

    genD is a list of genomic D information. Each element is a list of the name
    of the D allele and the germline sequence.

    Parameters
    ----------
    params_file_name : str
        File name for a IGOR parameter file.

    Returns
    -------
    genD : list
        List of genomic D information.

    """
    params_file = open(params_file_name, 'r')
    D_gene_info = {}
    in_D_gene_sec = False
    for line in params_file:
        if line.startswith('#GeneChoice;D_gene;'):
            in_D_gene_sec = True
        elif in_D_gene_sec:
            if line[0] == '%':
                split_line = line[1:].split(';')
                D_gene_info[split_line[0]] = [split_line[1], int(split_line[2])
                    ]
            else:
                break
    params_file.close()
    genD = [[]] * len(D_gene_info.keys())
    for D_gene in D_gene_info.keys():
        genD[D_gene_info[D_gene][1]] = [D_gene, D_gene_info[D_gene][0]]
    return genD


def intersection(list_1: list, list_2: list) ->list:
    """llogic.intersection(list_1, list_2)

    Returns the intersection of two lists (omitting repetitions). The order
    of the elements of the output depends on the order they are found in the
    first list. Usage:

    >>> alist = [1, 2, 3, 4, 5]
    >>> blist = [7, 6, 5, 4, 3]
    >>> llogic.intersection(alist, blist)
    [3, 4, 5]

    >>> alist = [1, 2, 3, 3, 4, 4, 5, 5, 5]
    >>> blist = [3, 3, 4, 5, 5, 6]
    >>> llogic.intersection(alist, blist)
    [3, 4, 5]

    Note that llogic.intersection does not flatten the lists so nested lists
    are of type list:

    >>> alist = [3, 4, [1, [5, 2]]]
    >>> blist = [1, 2, 3, 4, 5]
    >>> llogic.intersection(alist, blist)
    [3, 4]

    The lists can contain any datatype:

    >>> alist = [1, 2.3, 'foo', (3, 7)]
    >>> blist = ['foo', 7+3j, (3, 7)]
    >>> llogic.intersection(alist, blist)
    ['foo', (3, 7)]

    If either list is empty then the result is an empty list:

    >>> alist = [1, 2, 3, 4, 5]
    >>> blist = []
    >>> llogic.intersection(alist, blist)
    []
    """
    if not isinstance(list_1, list):
        raise TypeError("'list_1' must be 'list'")
    if not isinstance(list_2, list):
        raise TypeError("'list_2' must be 'list'")
    output_list = []
    for item in list_1:
        if item in list_2 and item not in output_list:
            output_list.append(item)
    return output_list


def __access_member_by_string(x, member):
    """
    Return the result of x.#member or x.#member()
    where member is the name of the function/variable.

    :param x: Element to operate on
    :param member: Function or value member
    :return:
    """
    action = getattr(x, member)
    if callable(action):
        return action()
    else:
        return action


def fileDescriptorReceived(descriptor):
    """
        Called when a file descriptor is received over the connection.

        @param descriptor: The descriptor which was received.
        @type descriptor: C{int}

        @return: L{None}
        """


@classmethod
def get(cls, context, uuid):
    """Find a DB ControlpathID and return an Obj ControlpathID."""
    db_cp = cls.dbapi.control_path_get_by_uuid(context, uuid)
    obj_cp = cls._from_db_object(cls(context), db_cp)
    return obj_cp


def line_joiner(line_iterator):
    """    Given a readline function, return lines, but handle line continuations
    ('\\
'). When lines are joined, the same number of blank lines is output
    so that the line counter for the consumer stays correct.
    """
    while True:
        joined_line = '\\\n'
        joined_lines = 0
        while joined_line[-2:] == '\\\n':
            joined_line = joined_line[:-2]
            line = next(line_iterator)
            if not line:
                break
            joined_line += line.rstrip() + '\n'
            joined_lines += 1
        while joined_lines > 1:
            yield '\n'
            joined_lines -= 1
        if not joined_line:
            break
        yield joined_line


def subtract(image1, image2, scale=1.0, offset=0):
    """
    Subtracts two images, dividing the result by scale and adding the offset.
    If omitted, scale defaults to 1.0, and offset to 0.0. At least one of the
    images must have mode "1".

    .. code-block:: python

        out = ((image1 - image2) / scale + offset)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_subtract(image2.im, scale, offset))


@classmethod
def all(cls):
    """
        List all subclasses
        """
    return cls.__subclasses__()


def is_file(path):
    """
    tests whether a canonical path refers to a file or a directory
    """
    return not path.endswith('/')


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def Mikhailov_Freire(Re):
    """Calculates drag coefficient of a smooth sphere using the method in
    [1]_ as described in [2]_.

    .. math::
        C_D = \\frac{3808[(1617933/2030) + (178861/1063)Re + (1219/1084)Re^2]}
        {681Re[(77531/422) + (13529/976)Re - (1/71154)Re^2]}

    Parameters
    ----------
    Re : float
        Reynolds number of the sphere, [-]

    Returns
    -------
    Cd : float
        Drag coefficient [-]

    Notes
    -----
    Range is Re <= 118300

    Examples
    --------
    >>> Mikhailov_Freire(200.)
    0.7514111388018659

    References
    ----------
    .. [1] Mikhailov, M. D., and A. P. Silva Freire. "The Drag Coefficient of
       a Sphere: An Approximation Using Shanks Transform." Powder Technology
       237 (March 2013): 432-35. doi:10.1016/j.powtec.2012.12.033.
    .. [2] Barati, Reza, Seyed Ali Akbar Salehi Neyshabouri, and Goodarz
       Ahmadi. "Development of Empirical Models with High Accuracy for
       Estimation of Drag Coefficient of Flow around a Smooth Sphere: An
       Evolutionary Approach." Powder Technology 257 (May 2014): 11-19.
       doi:10.1016/j.powtec.2014.02.045.
    """
    Cd = 3808.0 * (1617933.0 / 2030.0 + 178861.0 / 1063.0 * Re + 1219.0 /
        1084.0 * Re ** 2) / (681.0 * Re * (77531.0 / 422.0 + 13529.0 /
        976.0 * Re - 1.0 / 71154.0 * Re ** 2))
    return Cd


def normalize_headers(headers):
    """
    Create a dictionary of headers from:
       * A list of curl-style headers
       * None
       * a dictionary (return a *copy*).

    :param headers: List or dict of header (may also be None).
    :type headers: Iterable[string] | dict[string, string] | None
    :return: A dictionary of headers suitable for requests.
    :rtype: dict[string,string]
    """
    if headers is None:
        return {}
    elif isinstance(headers, dict):
        return headers.copy()
    else:
        result = {}
        for line in headers:
            key, sep, value = line.partition(':')
            if sep is None:
                raise Exception('Internal error - invalid header line (%s)' %
                    line)
            result[key.strip().lower()] = value.strip()
        return result


def _execute(job):
    """
    Cannot pickle method instances, so fake a function.
    Used by _process_jobs_locally
    """
    job.execute()
    return job.ret


def _clean_publisher(publisher):
    """Clean the Publisher field of some unnecessary annotations."""
    if ':' in publisher:
        publisher = publisher.split(':')[1]
    publisher = publisher.replace(' ; ', '; ').replace('/', '')
    return publisher.strip(':.,; ')


@classmethod
def _constructor(cls, mapping, configuration):
    """
        A standardized constructor used internally by Attr.

        mapping: A mapping of key-value pairs. It is HIGHLY recommended
            that you use this as the internal key-value pair mapping, as
            that will allow nested assignment (e.g., attr.foo.bar = baz)
        configuration: The return value of Attr._configuration
        """
    raise NotImplementedError('You need to implement this')


def __newobj_ex__(cls, args, kwargs):
    """Used by pickle protocol 4, instead of __newobj__ to allow classes with
    keyword-only arguments to be pickled correctly.
    """
    return cls.__new__(cls, *args, **kwargs)


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 escape_for_markdown(text: (str or None)) ->str:
    """
    Escapes text to use as plain text in a markdown document
    :param text: the original text
    :return: the escaped text
    """
    text = str(text)
    escaped = text.replace('*', '\\*').replace('_', '\\_')
    return escaped


def GetFFC5(ElSym):
    """Get 5 term form factor and Compton scattering data

    :param ElSym: str(1-2 character element symbol with proper case);
    :return El: dictionary with 5 term form factor & compton coefficients
    """
    import FormFactors as FF
    El = {}
    FF5 = FF.FFac5term[ElSym]
    El['fa'] = FF5[:5]
    El['fc'] = FF5[5]
    El['fb'] = FF5[6:]
    Cmp5 = FF.Compton[ElSym]
    El['cmpz'] = Cmp5[0]
    El['cmpa'] = Cmp5[1:6]
    El['cmpb'] = Cmp5[6:]
    return El


def _is_descriptor(obj):
    """Returns True if obj is a descriptor, False otherwise."""
    return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj,
        '__delete__')


def guess_contains_systemd(lines):
    """Tries to determine if a file includes systemd
    """
    for line in lines:
        if 'sd_bus_error_copy' in line:
            return 1
        if 'sd_bus_error_is_set' in line:
            return 1
        if 'sd_bus_error_add_map' in line:
            return 1
    return 0


def update_access(data, *access):
    """Merge access rights information.

    :params data: current JSON structure with metadata and potentially an
        `_access` key.
    :param *access: List of dictionaries to merge to the original data, each of
        them in the form `action: []`.
    """
    current_rules = data.get('_access', {})
    for a in access:
        for k, v in a.items():
            current_x_rules = set(current_rules.get(k, []))
            current_x_rules.update(v)
            current_rules[k] = list(current_x_rules)
    data['_access'] = current_rules


def _get_default_options():
    """
    Returns a dictionary with the available compiler options and the default values

    Returns:
        default_options (Dict)

    """
    return {'library_folders': [], 'verbose': False, 'check_balanced': True,
        'mtime_check': True, 'cache': False, 'codegen': False, 'expand_mx':
        False, 'unroll_loops': True, 'inline_functions': True,
        'expand_vectors': False, 'replace_parameter_expressions': False,
        'replace_constant_expressions': False,
        'eliminate_constant_assignments': False, 'replace_parameter_values':
        False, 'replace_constant_values': False,
        'eliminable_variable_expression': None,
        'factor_and_simplify_equations': False, 'detect_aliases': False,
        'reduce_affine_expression': False}


@classmethod
def parse(cls, fp):
    """
        >>> from io import BytesIO
        >>> fp = BytesIO(b'\\x00\\x11"3DUfw\\x88\\x99\\xaa\\xbb\\xcc\\xdd\\xee\\xff')
        >>> str(UniqueIdTextRecord.parse(fp))
        'urn:uuid:33221100-5544-7766-8899-aabbccddeeff'
        """
    u = fp.read(16)
    return cls(bytes_le=u)


def _show_legend(ax):
    """Utility function to show legend."""
    leg = ax.legend(loc=1, shadow=True, fancybox=True, labelspacing=0.2,
        borderpad=0.15)
    ltext = leg.get_texts()
    llines = leg.get_lines()
    frame = leg.get_frame()
    from matplotlib.artist import setp
    setp(ltext, fontsize='small')
    setp(llines, linewidth=1)


@staticmethod
def count_unzero_items(items_list):
    """Count nonzero items in list."""
    counter = 0
    for item in items_list:
        if items_list[item] != 0:
            counter += 1
    return counter


def newline_space_fix(text):
    """Replace "newline-space" with "newline".

    This function was particularly useful when converting between Google
    Sheets and .xlsx format.

    Args:
        text (str): The string to work with

    Returns:
        The text with the appropriate fix.
    """
    newline_space = '\n '
    fix = '\n'
    while newline_space in text:
        text = text.replace(newline_space, fix)
    return text


def distance(lat1, lon1, lat2, lon2, geoid):
    """
    Computes the distance between the points
    (lon1, lat1) and (lon2, lat2). This function
    used the :py:func:`mpl_toolkits.basemap.pyproj.Geod.inv`
    function.

    :param float lat1: latitude of the first point
    :param float lon1: longitude of the first point
    :param float lat2: latitude of the second point
    :param float lon2: longitude of the second point
    :param mpl_toolkits.basemap.pyproj.Geod geoid: :py:class:`mpl_toolkits.basemap.pyproj.Geod` object used to compute the distance
    :return: distance between the two points
    :rtype: float
    """
    output = geoid.inv(lon1, lat1, lon2, lat2)
    return output[-1]


def change_endianness(x):
    """ Changes the endianness (from BE to LE and vice versa) of a given value.

    :param x: Given value which endianness will be changed.
    :type x: hex str
    :return: The opposite endianness representation of the given value.
    :rtype: hex str
    """
    if len(x) % 2 == 1:
        x += '0'
    y = x.decode('hex')
    z = y[::-1]
    return z.encode('hex')


def slide(align: bool=False, select: bool=True):
    """Select and slide paint curve point

    :param align: Align Handles, Aligns opposite point handle during transform
    :type align: bool
    :param select: Select, Attempt to select a point handle before transform
    :type select: bool
    """
    pass


@classmethod
def stop(cls, force: bool=False) ->None:
    """
        Stop supervisor thread.

        Actual stop performed on force == True or if  number of stops == number of starts

        :param force: force stop regardless number of start.
        :return: None
        """
    with cls._lock:
        if not cls._supervisor_thread:
            return
        cls._start_count -= 1
        if cls._start_count <= 0 or force:
            cls._loop.call_soon_threadsafe(cls._stopped_future.set_result, True
                )
            cls._supervisor_thread.join()
            cls._supervisor_thread = None


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

    The ".dev0" means dirty.

    Exceptions:
    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 validate_config(config: dict):
    """Validate the maildaemon configuration."""
    for name, connection in config.get('connections', {}).items():
        assert isinstance(name, str), type(name)
        assert name, name
        assert 'protocol' in connection, connection
        assert isinstance(connection['protocol'], str), type(connection[
            'protocol'])
        assert connection['protocol'], connection
        assert 'domain' in connection, connection
        assert isinstance(connection['domain'], str), type(connection['domain']
            )
        assert connection['domain'], connection
        assert isinstance(connection.get('ssl', False), bool), type(connection
            ['ssl'])
        assert isinstance(connection.get('port', 1), int), type(connection[
            'port'])
        assert connection.get('port', 1) > 0, connection['port']
        assert isinstance(connection.get('login', 'test'), str), type(
            connection['login'])
        assert connection.get('login', 'test'), connection['login']
        assert isinstance(connection.get('password', 'test'), str), type(
            connection['password'])
        assert connection.get('password', 'test'), connection['password']
    for name, filter_ in config.get('filters', {}).items():
        for connection_name in filter_.get('connections', []):
            assert connection_name in config['connections']
        assert 'condition' in filter_, filter_
        assert isinstance(filter_['condition'], str), type(filter_['condition']
            )
        for action in filter_.get('actions', []):
            assert isinstance(action, str), type(action)


def _total_bogomips_windows():
    """Return sum of bogomips value for all CPUs."""
    return 5000


def _reverse_map(op_map):
    """
    Reverses the supplied fortran2psyir mapping to make a psyir2fortran
    mapping.

    :param op_map: mapping from string representation of operator to                    enumerated type.
    :type op_map: :py:class:`collections.OrderedDict`

    :returns: a mapping from PSyIR operation to the equivalent Fortran string.
    :rtype: dict with :py:class:`psyclone.psyGen.Operation.Operator` keys and
            str values.

    """
    mapping = {}
    for operator in op_map:
        mapping_key = op_map[operator]
        mapping_value = operator
        if mapping_key not in mapping:
            mapping[mapping_key] = mapping_value
    return mapping


def get_default_params(dim: int):
    """
        Returns the default parameters of the iL-SHADE Differential Evolution Algorithm
        :param dim: Size of the problem (or individual).
        :type dim: int
        :return: Dict with the default parameters of the iL-SHADE Differential
        Evolution Algorithm.
        :rtype dict
    """
    return {'population_size': 12 * dim, 'individual_size': dim,
        'memory_size': 6, 'max_evals': 10000 * dim, 'callback': None,
        'seed': None, 'opts': None}


def req_thickness(t_min, t_corr, f_tol):
    """
    Number [m], Number [m], Number [-] -> Number [m]

    Returns the required wall thickness based on the following mechanical
    allowances:
    - Corrosion allowance
    - Fabrication tolerance

    Exrapolated from Equation (4)
    """
    try:
        return (t_min + t_corr) / (1 - f_tol)
    except ZeroDivisionError:
        raise ZeroDivisionError('Divide by zero. Check fabrication tolerance.')


@classmethod
def iam(cls, account_name, api_key, **kwargs):
    """
        Create a Cloudant client that uses IAM authentication.

        :param account_name: Cloudant account name.
        :param api_key: IAM authentication API key.
        """
    return cls(None, api_key, account=account_name, auto_renew=kwargs.get(
        'auto_renew', True), use_iam=True, **kwargs)


def SessionKeyType():
    """
    Which crypto is used for session key.
    """
    return 'AES'


def tsplit(string, delimiters):
    """Behaves str.split but supports tuples of delimiters."""
    delimiters = tuple(delimiters)
    stack = [string]
    for delimiter in delimiters:
        for i, substring in enumerate(stack):
            substack = substring.split(delimiter)
            stack.pop(i)
            for j, _substring in enumerate(substack):
                stack.insert(i + j, _substring)
    return stack


@classmethod
def get_publish_date(cls, records, name):
    """
        Return publish date to render on view
        """
    res = {}
    for record in records:
        res[record.id] = str(record.published_on)
    return res


def node_attribute_xy(G, attribute, nodes=None):
    """Return iterator of node-attribute pairs for all edges in G.

    Parameters
    ----------
    G: NetworkX graph

    attribute: key
       The node attribute key.

    nodes: list or iterable (optional)
        Use only edges that are adjacency to specified nodes.
        The default is all nodes.

    Returns
    -------
    (x,y): 2-tuple
        Generates 2-tuple of (attribute,attribute) values.

    Examples
    --------
    >>> G = nx.DiGraph()
    >>> G.add_node(1,color='red')
    >>> G.add_node(2,color='blue')
    >>> G.add_edge(1,2)
    >>> list(nx.node_attribute_xy(G,'color'))
    [('red', 'blue')]

    Notes
    -----
    For undirected graphs each edge is produced twice, once for each edge
    representation (u,v) and (v,u), with the exception of self-loop edges
    which only appear once.
    """
    if nodes is None:
        nodes = set(G)
    else:
        nodes = set(nodes)
    node = G.node
    for u, nbrsdict in G.adjacency_iter():
        if u not in nodes:
            continue
        uattr = node[u].get(attribute, None)
        if G.is_multigraph():
            for v, keys in nbrsdict.items():
                vattr = node[v].get(attribute, None)
                for k, d in keys.items():
                    yield uattr, vattr
        else:
            for v, eattr in nbrsdict.items():
                vattr = node[v].get(attribute, None)
                yield uattr, vattr


def parse_adl_path(adl_path):
    """ Returns tuple (store_name, object_key) """
    path_parts = adl_path.replace('adl://', '').split('/')
    store_name = path_parts[0].replace('.azuredatalakestore.net', '')
    object_key = '/'.join(path_parts[1:])
    return store_name, object_key


@staticmethod
def reads(err_log):
    """
        Parse the outputs from bbmerge to extract the total number of reads, as well as the number of reads that
        could be paired
        :param err_log: bbmerge outputs the stats in the error file
        :return: num_reads, the total number of reads, paired_reads, number of paired readds
        """
    num_reads = 0
    paired_reads = 0
    with open(err_log, 'r') as error_log:
        for line in error_log:
            if 'Pairs:' in line:
                num_reads = line.split('\t')[-1].rstrip()
            elif 'Joined:' in line:
                paired_reads = line.split('\t')[-2].rstrip()
    return num_reads, paired_reads


def list_tables(ExclusiveStartTableName=None, Limit=None):
    """
    Returns an array of table names associated with the current account and endpoint. The output from ListTables is paginated, with each page returning a maximum of 100 table names.
    See also: AWS API Documentation

    Examples
    This example lists all of the tables associated with the current AWS account and endpoint.
    Expected Output:

    :example: response = client.list_tables(
        ExclusiveStartTableName='string',
        Limit=123
    )

    :type ExclusiveStartTableName: string
    :param ExclusiveStartTableName: The first table name that this operation will evaluate. Use the value that was returned for LastEvaluatedTableName in a previous operation, so that you can obtain the next page of results.

    :type Limit: integer
    :param Limit: A maximum number of table names to return. If this parameter is not specified, the limit is 100.

    :rtype: dict
    :return: {
        'TableNames': [
            'string',
        ],
        'LastEvaluatedTableName': 'string'
    }

    :returns:
    (string) --

    """
    pass


def remove_tail_id(ref, hyp):
    """Assumes that the ID is the final token of the string which is common
    in Sphinx but not in Kaldi."""
    ref_id = ref[-1]
    hyp_id = hyp[-1]
    if ref_id != hyp_id:
        print(
            """Reference and hypothesis IDs do not match! ref="{}" hyp="{}"
File lines in hyp file should match those in the ref file."""
            .format(ref_id, hyp_id))
        exit(-1)
    ref = ref[:-1]
    hyp = hyp[:-1]
    return ref, hyp


def select_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin: int=
    0, ymax: int=0, extend: bool=True):
    """Select all time markers using border selection

    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    """
    pass


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

        :param EmmRefreshAuthTokenType val:
        :rtype: EventType
        """
    return cls('emm_refresh_auth_token', val)


def read_param(filename):
    """
        Open the given file and retrieve all parameters written initially for apexAcquisition.method
        NC is written when no value for value is found

        structure : <param><name>C_MsmsE</name><value>0.0</value></param>

        read_param returns  values in a dictionnary
    """
    from xml.dom import minidom
    xmldoc = minidom.parse(filename)
    x = xmldoc.documentElement
    pp = {}
    children = x.childNodes
    for child in children:
        if child.nodeName == 'paramlist':
            params = child.childNodes
            for param in params:
                if param.nodeName == 'param':
                    if 'name' in param.attributes.keys():
                        k = param.attributes['name'].value
                    for element in param.childNodes:
                        if element.nodeName == 'name':
                            k = element.firstChild.toxml()
                        elif element.nodeName == 'value':
                            try:
                                v = element.firstChild.toxml()
                            except:
                                v = 'NC'
                    pp[k] = v
    return pp


def update_package_data(distribution):
    """update build_py options to get package_data changes"""
    build_py = distribution.get_command_obj('build_py')
    build_py.finalize_options()


def idmap_create(connection):
    """
	Create the _idmap_ table.  This table has columns "table_name",
	"old", and "new" mapping old IDs to new IDs for each table.  The
	(table_name, old) column pair is a primary key (is indexed and must
	contain unique entries).  The table is created as a temporary
	table, so it will be automatically dropped when the database
	connection is closed.

	This function is for internal use, it forms part of the code used
	to re-map row IDs when merging multiple documents.
	"""
    connection.cursor().execute(
        'CREATE TEMPORARY TABLE _idmap_ (table_name TEXT NOT NULL, old INTEGER NOT NULL, new INTEGER NOT NULL, PRIMARY KEY (table_name, old))'
        )


def print_matrix(x, y, A):
    """Print the matrix with the (0,0) entry in the top left
    corner. Will label the rows by the sequence and add in the
    0-row if appropriate."""
    if len(x) == len(A):
        print('%5s' % ' '),
    else:
        print('{} {}'.format(' ', '*')),
        y = '*' + y
    for c in x:
        print('{}'.format(c)),
    for j in range(len(A[0])):
        print('{}'.format(y[j])),
        for i in range(len(A)):
            print('{}'.format(A[i][j])),


def feec_element(family, n, r, k):
    """Finite element exterior calculus notation
    n = topological dimension of domain
    r = polynomial order
    k = form_degree"""
    _feec_elements = {'P- Lambda': ((('P', r), ('DP', r - 1)), (('P', r), (
        'RTE', r), ('DP', r - 1)), (('P', r), ('N1E', r), ('N1F', r), ('DP',
        r - 1))), 'P Lambda': ((('P', r), ('DP', r)), (('P', r), ('BDME', r
        ), ('DP', r)), (('P', r), ('N2E', r), ('N2F', r), ('DP', r))),
        'Q- Lambda': ((('Q', r), ('DQ', r - 1)), (('Q', r), ('RTCE', r), (
        'DQ', r - 1)), (('Q', r), ('NCE', r), ('NCF', r), ('DQ', r - 1))),
        'S Lambda': ((('S', r), ('DPC', r)), (('S', r), ('BDMCE', r), (
        'DPC', r)), (('S', r), ('AAE', r), ('AAF', r), ('DPC', r)))}
    _feec_elements['P-'] = _feec_elements['P- Lambda']
    _feec_elements['P'] = _feec_elements['P Lambda']
    _feec_elements['Q-'] = _feec_elements['Q- Lambda']
    _feec_elements['S'] = _feec_elements['S Lambda']
    family, r = _feec_elements[family][n - 1][k]
    return family, r


@staticmethod
def get_reactance(g, b):
    """g : conductance (S)
b : susceptance (S)
return reactance X (ohm) if not infinite"""
    if g == 0 and b == 0:
        return None
    return -b / (g * g + b * b)


def p_parameter(p):
    """parameter_list : parameter"""
    p[0] = p[1]


def _maybe_int(s):
    """Coerces to int if starts with a digit else return s"""
    if s and s[0] in '0123456789':
        return int(s)
    return s


def get_mobilenetv2_filename(key):
    """Rename tensor name to the corresponding Keras layer weight name.
    # Arguments
        key: tensor name in TF (determined by tf.variable_scope)
    """
    filename = str(key)
    filename = filename.replace('/', '_')
    filename = filename.replace('MobilenetV2_', '')
    filename = filename.replace('BatchNorm', 'BN')
    if 'Momentum' in filename:
        return None
    filename = filename.replace('_weights', '_kernel')
    filename = filename.replace('_biases', '_bias')
    return filename + '.npy'


def get_top_namespace(node):
    """Return the top namespace of the given node

    If the node has not namespace (only root), ":" is returned.
    Else the top namespace (after root) is returned

    :param node: the node to query
    :type node: str
    :returns: The top level namespace.
    :rtype: str
    :raises: None
    """
    name = node.rsplit('|', 1)[-1]
    name = name.lstrip(':')
    if ':' not in name:
        return ':'
    else:
        return name.partition(':')[0]


def is_uchar(uchar):
    """判断一个unicode是否是汉字"""
    return True if uchar >= u'一' and uchar <= u'龥' else False


def get_vbr_bitrate(mpeg_size, sample_count, sample_rate):
    """Get average bitrate of VBR file.

    :param mpeg_size: Size of MPEG in bytes.
    :type mpeg_size: number

    :param sample_count: Count of samples.
    :type sample_count: number

    :param sample_rate: Sample rate in Hz.
    :type sample_rate: number

    :return: Average bitrate in kilobits per second.
    :rtype: float

    """
    bytes_per_sample = float(mpeg_size) / float(sample_count)
    bytes_per_second = bytes_per_sample * float(sample_rate)
    bits_per_second = bytes_per_second * 8
    return bits_per_second / 1000


def join_host_port(host, port):
    """Joins a hostname and port together.

    This is a minimal implementation intended to cope with IPv6 literals. For
    example, _join_host_port('::1', 80) == '[::1]:80'.

    :Args:
        - host - A hostname.
        - port - An integer port.

    """
    if ':' in host and not host.startswith('['):
        return '[%s]:%d' % (host, port)
    return '%s:%d' % (host, port)


def modify(data):
    """Modifications based on data in the request"""


def t_begin_grammar(t):
    """_lr_productions\\ =\\ \\["""
    t.lexer.push_state('grammar')


def fractionalValue(value):
    """ Parse a string consisting of a float in the range [0..1] or a percentage
    as a float number in the range [0..1].
    """
    if value.endswith('%'):
        return float(value[:-1]) / 100.0
    else:
        return float(value)


def nearest(coordinate, coordinate_list, limit):
    """ returns a list of nearest coordinates from coordinate_list to coordinate
            including distance.
        """


def energy_photon(frequency, wavelength):
    """Usage: Calculate the energy of a photon using frequency and wavelength """
    equation = 6.62607004e-34 * 300000000.0 / wavelength


def combine_hex(data):
    """ Combine list of integer values to one big integer """
    output = 0
    for i, value in enumerate(reversed(data)):
        output |= value << i * 8
    return output


def iter_repl(seq, subseq, repl):
    """
    Replace sub-list `subseq` in `seq` with `repl`.
    """
    seq, subseq, repl = list(seq), list(subseq), list(repl)
    subseq_len = len(subseq)
    rem = seq[:]
    while rem:
        if rem[:subseq_len] == subseq:
            for c in repl:
                yield c
            rem = rem[subseq_len:]
        else:
            yield rem.pop(0)


def IndexInto(li, indices):
    """ Index into a list (or list of lists) using the indices given. If the
  indices are out of bounds, or are too many in number, return None, instead
  of throwing an error. 0 is a special case."""
    for i in indices:
        if type(li) != list and i == 0:
            return li
        if type(li) != list or i >= len(li):
            return None
        li = li[i]
    return li


def start_find():
    """Start searching text

    """
    pass


def convert_timezone(dt, tz_from, tz_to):
    """Convert dt from tz_from to tz_to"""
    return tz_from.localize(dt).astimezone(tz_to)


def dm_subset(dm_sq, idxs):
    """Get subset of distance matrix given list of indices

    Args:
        dm_sq (numpy.array): squareform distance matrix from pdist
        idxs (list of int): list of indices
    Returns:
        numpy.array: subset of `dm_sq` with `shape == (len(idxs), len(idxs))`
    """
    return dm_sq[idxs][:, (idxs)]


def defaultify(value, default):
    """Return `default` if `value` is `None`. Otherwise, return `value`"""
    if None == value:
        return default
    else:
        return value


def format_path(**kwargs):
    """Creates a path type string"""
    objects = []
    for key, value in kwargs.items():
        objects.append(value)
    return '/'.join(objects)


@staticmethod
def _parse_lsb_release_content(lines):
    """
        Parse the output of the lsb_release command.

        Parameters:

        * lines: Iterable through the lines of the lsb_release output.
                 Each line must be a unicode string or a UTF-8 encoded byte
                 string.

        Returns:
            A dictionary containing all information items.
        """
    props = {}
    for line in lines:
        line = line.decode('utf-8') if isinstance(line, bytes) else line
        kv = line.strip('\n').split(':', 1)
        if len(kv) != 2:
            continue
        k, v = kv
        props.update({k.replace(' ', '_').lower(): v.strip()})
    return props


def findTypeFromString(value: str):
    """
    Returns a fitting basic python data type of a string value, i.e.
    :param value: string
    :return: type out of [str, int or float]
    """
    for t in (int, float, str):
        try:
            _ = t(value)
        except ValueError:
            continue
        return t
    return str


def _GenerateCRCTable():
    """Generate a CRC-32 table.

        ZIP encryption uses the CRC32 one-byte primitive for scrambling some
        internal keys. We noticed that a direct implementation is faster than
        relying on binascii.crc32().
        """
    poly = 3988292384
    table = [0] * 256
    for i in range(256):
        crc = i
        for j in range(8):
            if crc & 1:
                crc = crc >> 1 & 2147483647 ^ poly
            else:
                crc = crc >> 1 & 2147483647
        table[i] = crc
    return table


@staticmethod
def get_progress_bar_class():
    """
        Return class of progress bar
        :return: class
        """
    from tpDccLib.abstract import progressbar
    return progressbar.AbstractProgressBar


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 initUser():
    """
    initUser initializes a user object containing tone data (from the
    Watson Tone Analyzer)
    @returns user json object with the emotion, writing and social tones.  The
    current tone identifies the tone for a specific conversation turn, and the
    history provides the conversation for all tones up to the current tone for a
    conversation instance with a user.
    """
    return {'user': {'tone': {'emotion': {'current': None}, 'writing': {
        'current': None}, 'social': {'current': None}}}}


def keying_set_path_add():
    """Add empty path to active Keying Set

    """
    pass


def modify_hsm(HsmArn=None, SubnetId=None, EniIp=None, IamRoleArn=None,
    ExternalId=None, SyslogIp=None):
    """
    Modifies an HSM.
    See also: AWS API Documentation

    :example: response = client.modify_hsm(
        HsmArn='string',
        SubnetId='string',
        EniIp='string',
        IamRoleArn='string',
        ExternalId='string',
        SyslogIp='string'
    )

    :type HsmArn: string
    :param HsmArn: [REQUIRED]
            The ARN of the HSM to modify.

    :type SubnetId: string
    :param SubnetId: The new identifier of the subnet that the HSM is in. The new subnet must be in the same Availability Zone as the current subnet.

    :type EniIp: string
    :param EniIp: The new IP address for the elastic network interface (ENI) attached to the HSM.
            If the HSM is moved to a different subnet, and an IP address is not specified, an IP address will be randomly chosen from the CIDR range of the new subnet.

    :type IamRoleArn: string
    :param IamRoleArn: The new IAM role ARN.

    :type ExternalId: string
    :param ExternalId: The new external ID.

    :type SyslogIp: string
    :param SyslogIp: The new IP address for the syslog monitoring server. The AWS CloudHSM service only supports one syslog monitoring server.

    :rtype: dict
    :return: {
        'HsmArn': 'string'
    }

    """
    pass


def get_options(args_list=None):
    """Create argparse structure and parse arguments"""
    import argparse
    parser = argparse.ArgumentParser(description=
        'A command line tool for creating tasks in JIRA.', formatter_class=
        argparse.RawDescriptionHelpFormatter, epilog=
        """Thank you for using Jira Bulk Loader.

Mailing list: <https://groups.google.com/d/forum/jura-bulk-loader>
Bug tracker: <https://github.com/oktopuz/jira-bulk-loader/issues>"""
        )
    parser.add_argument('template_file', help=
        'a file containing issues definition')
    parser.add_argument('--dry', dest='dry_run', action='store_true', help=
        'make a dry run. It checks everything but does not create issues',
        default=False)
    required = parser.add_argument_group('required arguments')
    required.add_argument('-H', '--host', required=True, help=
        'JIRA hostname with http:// or https://')
    required.add_argument('-U', '--user', required=True, help='your username')
    required.add_argument('-P', dest='password', required=True, help=
        "your password. You'll be prompted for it if not specified")
    jattrs = parser.add_argument_group('JIRA attributes')
    jattrs.add_argument('-W', '--project', help='project key')
    jattrs.add_argument('-R', '--priority', help=
        "default task priority. 'Medium' if not specified", default='Medium')
    jattrs.add_argument('-D', '--duedate', help=
        'default issue dueDate (YYYY-mm-DD)')
    return parser.parse_args(args_list)


def _object_to_FQCN(theobj):
    """Gets module path of object"""
    module = theobj.__class__.__module__
    if module is None or module == str.__class__.__module__:
        return theobj.__class__.__qualname__
    return module + '.' + theobj.__class__.__qualname__


def fpMul(_rm, a, b):
    """
    Returns the multiplication of two floating point numbers, `a` and `b`.
    """
    return a * b


def receive(data_length, es):
    """
    Receive data from evaluation server and remove useless characters.

    :param data_length: length of the data received
    :param es: evaluation server
    :return: data received
    """
    data_str = ''
    while True:
        data_tmp = es.recv(data_length).decode()
        stop = data_tmp.find('#')
        if stop > 0:
            data_tmp = data_tmp[0:stop]
            data_str += data_tmp
            break
        else:
            data_str += data_tmp
    if data_str[0] == '\n':
        data_str = data_str[1:]
    if data_str[-1] == '\n':
        data_str = data_str[:-1]
    return data_str


@classmethod
def load_from_dict(cls, d):
    """
        Overload this function in your subclass. It takes a dictionary and should return a constructed object.

        When overloading, you have to decorate this function with ``@classmethod``.

        Parameters
        ----------
        d : dict
            Dictionary representation of an instance of your class.

        Returns
        -------
        obj : object
            Returns an object that has been constructed based on the dictionary.
        """
    raise NotImplementedError(
        'Must override load_from_dict for Saveable interface')


@classmethod
def get_real_child_model(cls, data):
    """Returns the real base class specified by the discriminator"""
    discriminator_value = data[cls.json_discriminator_key]
    return cls.discriminator_value_class_map.get(discriminator_value)


def replace_dots_to_underscores_at_last(path):
    """
    Remove dot ('.') while a dot is treated as a special character in backends

    Args:
        path (str): A target path string

    Returns:
        str
    """
    if path == '':
        return path
    bits = path.split('/')
    bits[-1] = bits[-1].replace('.', '_')
    return '/'.join(bits)


def g11_alt(k, E, sig, band, gap):
    """
    Variation of :func: `g11 <arpys.2dfit.g11>` which takes precalculated
    values of `sig`, `band` and `gap`.

    *Parameters*
    ====  ======================================================================
    k     array of length 2; k vector (in-plane) at which to evaluate g11
    E     float; energy at which to evaluate g11
    sig   complex; value of the complex self-energy at E
    band  float; value of the bare band at this k
    gap   float; value of the gap at this k
    ====  ======================================================================
    """
    re_sig = sig.real
    e_diff = E - sig
    nominator = e_diff + band
    denominator = e_diff ** 2 - band ** 2 - gap * (1 - re_sig / E)
    return nominator / denominator


def exposure_index_values(H_a):
    """
    Computes the exposure index values :math:`I_{EI}` from given focal plane
    exposure :math:`H_a`.

    Parameters
    ----------
    H_a : array_like
        Focal plane exposure :math:`H_a`.

    Returns
    -------
    ndarray
        Exposure index values :math:`I_{EI}`.

    References
    ----------
    :cite:`ISO2006`

    Examples
    --------
    >>> exposure_index_values(0.1628937086212269)  # doctest: +ELLIPSIS
    61.3897251...
    """
    return 10 / H_a


@classmethod
def is_datasource_for(cls, data, header, **kwargs):
    """Determines if header corresponds to an RHESSI image"""
    return header.get('instrume') == 'RHESSI'


def view_zoom_border(xmin: int=0, xmax: int=0, ymin: int=0, ymax: int=0,
    wait_for_input: bool=True, zoom_out: bool=False):
    """Zoom in the view to the nearest item contained in the border

    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param wait_for_input: Wait for Input
    :type wait_for_input: bool
    :param zoom_out: Zoom Out
    :type zoom_out: bool
    """
    pass


def iterintersperse(iterable, separator):
    """Iteratively intersperse iterable."""
    iterable = iter(iterable)
    yield next(iterable)
    for item in iterable:
        yield separator
        yield item


def is_plant_uml(text, lang):
    """True if it is a plant uml diagram"""
    if lang:
        return lang.lower() in ['plantuml', 'uml']
    return text.lstrip().lower().startswith('@start')


def is_equivalent(step1, step2):
    """Compare steps, ignoring their priority."""
    return step1.get('interface') == step2.get('interface') and step1.get(
        'step') == step2.get('step')


def edge_collapse():
    """Collapse selected edges

    """
    pass


def find_header_line(data, header_keys):
    """
    Find the header line in row_based data_structure
    NOT IMPLEMENTED YET: Version 0.9 feature

    Parameters
    ----------
    data : list, pandas.DataFrame
    header_keys : str, list, set
        some key(s) to find in a row

    Returns
    -------
    int
        the header_line
    """
    raise NotImplemented


def radial_control(data_path_primary: str='', data_path_secondary: str='',
    use_secondary: str='', rotation_path: str='', color_path: str='',
    fill_color_path: str='', fill_color_override_path: str='',
    fill_color_override_test_path: str='', zoom_path: str='', image_id: str
    ='', secondary_tex: bool=False):
    """Set some size property (like e.g. brush size) with mouse wheel

    :param data_path_primary: Primary Data Path, Primary path of property to be set by the radial control
    :type data_path_primary: str
    :param data_path_secondary: Secondary Data Path, Secondary path of property to be set by the radial control
    :type data_path_secondary: str
    :param use_secondary: Use Secondary, Path of property to select between the primary and secondary data paths
    :type use_secondary: str
    :param rotation_path: Rotation Path, Path of property used to rotate the texture display
    :type rotation_path: str
    :param color_path: Color Path, Path of property used to set the color of the control
    :type color_path: str
    :param fill_color_path: Fill Color Path, Path of property used to set the fill color of the control
    :type fill_color_path: str
    :param fill_color_override_path: Fill Color Override Path
    :type fill_color_override_path: str
    :param fill_color_override_test_path: Fill Color Override Test
    :type fill_color_override_test_path: str
    :param zoom_path: Zoom Path, Path of property used to set the zoom level for the control
    :type zoom_path: str
    :param image_id: Image ID, Path of ID that is used to generate an image for the control
    :type image_id: str
    :param secondary_tex: Secondary Texture, Tweak brush secondary/mask texture
    :type secondary_tex: bool
    """
    pass


def perc_bounds(percent_filter):
    """
    Convert +/- percentage to decimals to be used to determine bounds.

    Parameters
    ----------
    percent_filter : float or tuple, default None
        Percentage or tuple of percentages used to filter around reporting
        irradiance in the irr_rc_balanced function.  Required argument when
        irr_bal is True.

    Returns
    -------
    tuple
        Decimal versions of the percent irradiance filter. 0.8 and 1.2 would be
        returned when passing 20 to the input.
    """
    if isinstance(percent_filter, tuple):
        perc_low = percent_filter[0] / 100
        perc_high = percent_filter[1] / 100
    else:
        perc_low = percent_filter / 100
        perc_high = percent_filter / 100
    low = 1 - perc_low
    high = 1 + perc_high
    return low, high


def generic_summary_provider(value_obj, internal_dict, class_synthetic_provider
    ):
    """
    Checks value type and returns summary.

    :param lldb.SBValue value_obj: LLDB object.
    :param dict internal_dict: Internal LLDB dictionary.
    :param class class_synthetic_provider: Synthetic provider class.
    :return: Value summary.
    :rtype: str
    """
    provider = class_synthetic_provider(value_obj, internal_dict)
    if provider is not None:
        return provider.summary()
    return 'Summary Unavailable'


def __identity(function):
    """
    identify function just returns the same function
    """
    return function


@classmethod
def _fromInputHandlerProxy(cls, input_handler_proxy):
    """
        Internal Constructor to wrap around JAVA Class InputHandler
        :param input_handler_proxy:
        :return:
        """
    instance = cls.__new__(cls)
    instance.input_handler_proxy = input_handler_proxy
    return instance


def is_sec_compressed(sec):
    """Return a boolean indicating if the sec represents a compressed public key."""
    return sec[:1] in (b'\x02', b'\x03')


def binary_to_bool_2(raw_input):
    """Map (0,1) to (True, False)"""
    mapping = {'0': True, '1': False}
    if raw_input in mapping.keys():
        return mapping[raw_input]
    else:
        return None


@classmethod
def supports_from_pcm(cls):
    """returns True if all necessary components are available
        to support the .from_pcm() classmethod"""
    return True


@staticmethod
def get_text_label_summary(provider):
    """
        Text label summary.

        :param UILabel.UILabelSyntheticProvider provider: UILabel provider
        :return: Text label summary.
        :rtype: str
        """
    value = provider.text_value
    if value is not None:
        return 'textLabel={}'.format(provider.text_value)
    return None


def _set_class_module(module_class):
    """Initialize the module."""
    global _CLASS_MODULE
    _CLASS_MODULE = module_class


def _primary_axes(coord):
    """gets the i,j,k axes from the ???"""
    coord_transform = coord.beta()
    ex = coord_transform[(0), :]
    ey = coord_transform[(1), :]
    ez = coord_transform[(2), :]
    return ex, ey, ez


def split_to_length(s, n):
    """
    Splits the given string s into a list of string, where each string has a maximal length n.

    :param s: The string to split
    :param n: The maximum length of each string in the result
    :return: A list of strings with maximum length n
    """
    result = []
    for i in range(0, len(s), n):
        result.append(s[i:i + n])
    return result


def print_keys(key_names, query_result):
    """
    Prints results and does not throw exception on queries
    like W1AW where fname key does not exist
    """
    info = ''
    for key_name in key_names:
        if key_name in query_result:
            info += query_result[key_name] + ' '
    print(info)


def crop_lt(x, crop_h, crop_w):
    """crop left top corner"""
    return x[:, :, 0:crop_h, 0:crop_w]


def pytest_assertion_pass(item, lineno, orig, expl):
    """
    **(Experimental)**

    .. versionadded:: 5.0

    Hook called whenever an assertion *passes*.

    Use this hook to do some processing after a passing assertion.
    The original assertion information is available in the `orig` string
    and the pytest introspected assertion information is available in the
    `expl` string.

    This hook must be explicitly enabled by the ``enable_assertion_pass_hook``
    ini-file option:

    .. code-block:: ini

        [pytest]
        enable_assertion_pass_hook=true

    You need to **clean the .pyc** files in your project directory and interpreter libraries
    when enabling this option, as assertions will require to be re-written.

    :param _pytest.nodes.Item item: pytest item object of current test
    :param int lineno: line number of the assert statement
    :param string orig: string with original assertion
    :param string expl: string with assert explanation

    .. note::

        This hook is **experimental**, so its parameters or even the hook itself might
        be changed/removed without warning in any future pytest release.

        If you find this hook useful, please share your feedback opening an issue.
    """


def extract_range(s):
    """ Extract range from string"""
    ranges = s.split(',')
    if len(ranges) > 1:
        return int(ranges[0]), int(ranges[1])
    else:
        return int(ranges[0]), None


def prefix_suffix_prep(string1, string2):
    """Calculates starting position and lengths of two strings such
    that common prefix and suffix substrings are excluded.
    Expects len(string1) <= len(string2)

    Parameters
    ----------
    string_1 : str
        Base string.
    string_2 : str
        The string to compare.

    Returns
    -------
    len1, len2, start : (int, int, int)
        `len1` and len2` are lengths of the part excluding common
        prefix and suffix, and `start` is the starting position.
    """
    len1 = len(string1)
    len2 = len(string2)
    while len1 != 0 and string1[len1 - 1] == string2[len2 - 1]:
        len1 -= 1
        len2 -= 1
    start = 0
    while start != len1 and string1[start] == string2[start]:
        start += 1
    if start != 0:
        len1 -= start
        len2 -= start
    return len1, len2, start


def set_tr_te(nifti_image, repetition_time, echo_time):
    """
    Set the tr and te in the nifti headers

    :param echo_time: echo time
    :param repetition_time: repetition time
    :param nifti_image: nifti image to set the info to
    """
    nifti_image.header.structarr['pixdim'][4] = repetition_time / 1000.0
    nifti_image.header.structarr['db_name'] = '?TR:%.3f TE:%d' % (
        repetition_time, echo_time)
    return nifti_image


def format_report_csv(report):
    """Format JSON validation report as CSV string

    :param report: JSON report output from validator
    :return: string representing csv formatted report
    """
    output = ''
    if report['validation_finished']:
        output = 'Validation=success\n'
    for warning in report['warnings']:
        output += str('{},{},{}\n').format(warning['code'], warning[
            'message'], warning['supplemental'])
    for error in report['errors']:
        output += str('{},{},{}\n').format(error['code'], error['message'],
            error['supplemental'])
    return output


def _check(info):
    """Validate a version info.

    :param info: could be a string, an integer, float, or any integer
           collection (only first three valid integers are used).

    :returns: a valid tuple or an error if invalid.

    """
    from collections import Iterable
    from distutils.version import LooseVersion, StrictVersion
    MAX_COUNT = 3
    if isinstance(info, (int, float)):
        aux = str(info)
    elif isinstance(info, Iterable) and not isinstance(info, str):
        aux = '.'.join(map(str, info))
    else:
        aux = info
    if isinstance(aux, str):
        try:
            essay = StrictVersion(aux)
        except (TypeError, ValueError):
            essay = LooseVersion(aux)
        res = essay.version[:MAX_COUNT]
        if any(res):
            return tuple(res)
        else:
            raise ValueError("invalid version value '{}'".format(info))
    else:
        msg = "Invalid type '{}' for version '{}'"
        raise TypeError(msg.format(type(info).__name__, info))


def adaptive_regularization_weights_from_pixel_signals(inner_coefficient,
    outer_coefficient, pixel_signals):
    """Compute the regularization weights, which are the effective regularization coefficient of every     pixel. They are computed using the (hyper) pixel-signal of each pixel.

    Two regularization coefficients are used, corresponding to the:

    1) (pixel_signals) - pixels with a high pixel-signal (i.e. where the signal is located in the pixelization).
    2) (1.0 - pixel_signals) - pixels with a low pixel-signal (i.e. where the signal is not located in the      pixelization).

    Parameters
    ----------
    coefficients : (float, float)
        The regularization coefficients which controls the degree of smoothing of the inversion reconstruction.
    pixel_signals : ndarray
        The estimated signal in every pixelization pixel, used to change the regularization weighting of high signal         and low signal pixelizations.
    """
    return (inner_coefficient * pixel_signals + outer_coefficient * (1.0 -
        pixel_signals)) ** 2.0


def escape(term):
    """
    escapes a term for use in ADQL
    """
    return str(term).replace("'", "''")


def check_version():
    """Checks version of Findex."""
    return


def get_after_slash(string):
    """
    Get the part of a string after the first slash
    :param str string: String to return the part after the first
    slash of
    :return str part_after_first_slash: Part of the string after
    the first slash
    """
    return '/'.join(string.split('/')[1:])


def select_mirror(only_active: bool=False, extend: bool=False):
    """Mirror the bone selection

    :param only_active: Active Only, Only operate on the active bone
    :type only_active: bool
    :param extend: Extend, Extend the selection
    :type extend: bool
    """
    pass


@classmethod
def get_command(cls, verb):
    """Get a command in this shell by its verb.

        :param str verb: The verb of the command to get
        :returns Command|None: The command with that verb or None

        """
    return cls._verbs.get(verb)


def casedict2xlsx():
    """
    Convert a full Cases.cases dict to Excel spreadsheets
    """


def _explode(lines, indent):
    """Split each line in `lines` at tabstops

    Tabstops at the beginning of each line are expanded to 2 spaces.

    Return list of rows (a row being a list of strings, i.e. cells)
    """
    exploded = []
    for line in lines:
        indentions = 0
        while line.startswith('\t'):
            indentions += 1
            line = line[1:]
        splitline = line.split('\t')
        for i in range(indentions):
            splitline.insert(0, ' ' * indent)
        exploded.append(splitline)
    return exploded


def test_extra():
    """Returns dict of extrapolation testing modules."""
    return {}


def split_group(source, pos, maxline):
    """ Split a group into two subgroups.  The
        first will be appended to the current
        line, the second will start the new line.

        Note that the first group must always
        contain at least one item.

        The original group may be destroyed.
    """
    first = []
    source.reverse()
    while source:
        tok = source.pop()
        first.append(tok)
        pos += len(tok)
        if source:
            tok = source[-1]
            allowed = maxline + 1 if tok.endswith(' ') else maxline - 4
            if pos + len(tok) > allowed:
                break
    source.reverse()
    return first, source


def setdefault(key, default=None):
    """D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"""


def calc_mass_ratio_from_velrs(velr_1, velr_2):
    """Calculate ratio of stellar masses from observed radial velocities.
    Assumes circular orbit.

    Parameters
    ----------
    velr_1 : float
        Observed radial velocity of star 1. Unit is m/s.
    velr_2 : float
        Observed radial velocity of star 2. Unit is m/s.

    Returns
    -------
    mass_ratio : float
        Ratio of stellar masses for stars 1 and 2 as mass1 / mass2. Unitless.

    Notes
    -----
    m1 / m2 = a2 / a1, where a is semi-major axis of low-eccentricty orbit.
    v = 2*pi*a / P, where v is orbital velocity, P is orbital period.
      = vr / sin(i), where vr is observed radial orbital velocity, i is orbital inclination.
    => m1 / m2 = v2r / v1r
    From equation 7.5 in section 7.3 of [1]_.

    References
    ----------
    .. [1] Carroll and Ostlie, 2007, An Introduction to Modern Astrophysics

    """
    mass_ratio = velr_2 / velr_1
    return mass_ratio


def get_first_element_index(root, tag_name):
    """
    In order to use Element.insert() in a convenient way,
    this function will find the first child tag with tag_name
    and return its index position
    The index can then be used to insert an element before or after the
    found tag using Element.insert()
    """
    tag_index = 1
    for tag in root:
        if tag.tag == tag_name:
            return tag_index
        tag_index = tag_index + 1
    return None


def tup_divide(tuple):
    """
    definition: func(tuple(...)) {...}
    objective : divides the elements of the tuple from left to right
    """
    first_element = tuple[0]
    for i in range(1, len(tuple), 1):
        first_element /= tuple[i]
    return first_element


@classmethod
def is_installed(cls, language=None):
    """Determine if the necessary libraries are installed for this
        communication class.

        Args:
            language (str, optional): Specific language that should be checked
                for compatibility. Defaults to None and all languages supported
                on the current platform will be checked.

        Returns:
            bool: Is the comm installed.

        """
    return True


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 extract_first_value_in_quotes(line, quote_mark):
    """
    Extracts first value in quotes (single or double) from a string.
    Line is left-stripped from whitespaces before extraction.
    :param line: string
    :param quote_mark: type of quotation mark: ' or "
    :return: Dict: 'value': extracted value;
                    'remainder': the remainder after extraction
                    'error' empty string if success or 'syntax' otherwise;
    """
    line = line.lstrip()
    result = {'value': '', 'remainder': line, 'error': 'syntax'}
    if len(line) < 2:
        return result
    if line[0] != quote_mark:
        return result
    next_qm_pos = line.find(quote_mark, 1)
    if next_qm_pos == -1:
        return result
    result['value'] = line[1:next_qm_pos]
    result['remainder'] = line[next_qm_pos + 1:]
    result['error'] = ''
    return result


@classmethod
def set_credentials(cls, client_id, client_secret):
    """
        Class method for setting the Imgur API client ID and client secret
        """
    cls.client_id = client_id
    cls.client_secret = client_secret


def obj_box_coords_rescale(coords=None, shape=None):
    """Scale down a list of coordinates from pixel unit to the ratio of image size i.e. in the range of [0, 1].

    Parameters
    ------------
    coords : list of list of 4 ints or None
        For coordinates of more than one images .e.g.[[x, y, w, h], [x, y, w, h], ...].
    shape : list of 2 int or None
        【height, width].

    Returns
    -------
    list of list of 4 numbers
        A list of new bounding boxes.

    Examples
    ---------
    >>> coords = obj_box_coords_rescale(coords=[[30, 40, 50, 50], [10, 10, 20, 20]], shape=[100, 100])
    >>> print(coords)
      [[0.3, 0.4, 0.5, 0.5], [0.1, 0.1, 0.2, 0.2]]
    >>> coords = obj_box_coords_rescale(coords=[[30, 40, 50, 50]], shape=[50, 100])
    >>> print(coords)
      [[0.3, 0.8, 0.5, 1.0]]
    >>> coords = obj_box_coords_rescale(coords=[[30, 40, 50, 50]], shape=[100, 200])
    >>> print(coords)
      [[0.15, 0.4, 0.25, 0.5]]

    Returns
    -------
    list of 4 numbers
        New coordinates.

    """
    if coords is None:
        coords = []
    if shape is None:
        shape = [100, 200]
    imh, imw = shape[0], shape[1]
    imh = imh * 1.0
    imw = imw * 1.0
    coords_new = list()
    for coord in coords:
        if len(coord) != 4:
            raise AssertionError('coordinate should be 4 values : [x, y, w, h]'
                )
        x = coord[0] / imw
        y = coord[1] / imh
        w = coord[2] / imw
        h = coord[3] / imh
        coords_new.append([x, y, w, h])
    return coords_new


def one(iterable, too_short=None, too_long=None):
    """Return the first item from *iterable*, which is expected to contain only
    that item. Raise an exception if *iterable* is empty or has more than one
    item.

    :func:`one` is useful for ensuring that an iterable contains only one item.
    For example, it can be used to retrieve the result of a database query
    that is expected to return a single row.

    If *iterable* is empty, ``ValueError`` will be raised. You may specify a
    different exception with the *too_short* keyword:

        >>> it = []
        >>> one(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        ValueError: too many items in iterable (expected 1)'
        >>> too_short = IndexError('too few items')
        >>> one(it, too_short=too_short)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        IndexError: too few items

    Similarly, if *iterable* contains more than one item, ``ValueError`` will
    be raised. You may specify a different exception with the *too_long*
    keyword:

        >>> it = ['too', 'many']
        >>> one(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        ValueError: too many items in iterable (expected 1)'
        >>> too_long = RuntimeError
        >>> one(it, too_long=too_long)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        RuntimeError

    Note that :func:`one` attempts to advance *iterable* twice to ensure there
    is only one item. If there is more than one, both items will be discarded.
    See :func:`spy` or :func:`peekable` to check iterable contents less
    destructively.

    """
    it = iter(iterable)
    try:
        value = next(it)
    except StopIteration:
        raise (too_short or ValueError(
            'too few items in iterable (expected 1)'))
    try:
        next(it)
    except StopIteration:
        pass
    else:
        raise (too_long or ValueError(
            'too many items in iterable (expected 1)'))
    return value


@staticmethod
def _parse_saved_offsets(app_name, topic, saved_offset_spec):
    """get dict representing saved offsets."""
    offset_dict = {}
    for key, value in saved_offset_spec.items():
        if key.startswith('%s_%s' % (app_name, topic)):
            spec_app_name = value.get_app_name()
            spec_topic = value.get_topic()
            spec_partition = int(value.get_partition())
            spec_from_offset = value.get_from_offset()
            spec_until_offset = value.get_until_offset()
            key = '_'.join((spec_topic, str(spec_partition)))
            offset_dict[key] = (spec_app_name, spec_topic, spec_partition,
                spec_from_offset, spec_until_offset)
    return offset_dict


@classmethod
def read(cls, filename):
    """
        return file elements in a generator
        """
    assert False


@classmethod
def from_env(cls, task_name: str=None, default_save=None, reset_templates:
    bool=None, align_connectors: bool=None, default_save_intent: bool=None,
    default_intent_level: bool=None, order_next_available: bool=None,
    default_replace_intent: bool=None, **kwargs):
    """ Class Factory Method that builds the connector handlers taking the property contract path from
        the os.environ['AISTAC_PM_PATH'] or, if not found, uses the system default,
                    for Linux and IOS '/tmp/components/contracts
                    for Windows 'os.environ['AppData']\\components\\contracts'
        The following environment variables can be set:
        'AISTAC_PM_PATH': the property contract path, if not found, uses the system default
        'AISTAC_PM_TYPE': a file type for the property manager. If not found sets as 'json'
        'AISTAC_PM_MODULE': a default module package, if not set uses component default
        'AISTAC_PM_HANDLER': a default handler. if not set uses component default

        This method calls to the Factory Method 'from_uri(...)' returning the initialised class instance

         :param task_name: The reference name that uniquely identifies a task or subset of the property manager
         :param default_save: (optional) if the configuration should be persisted
         :param reset_templates: (optional) reset connector templates from environ variables. Default True
                                (see `report_environ()`)
         :param align_connectors: (optional) resets aligned connectors to the template. default Default True
         :param default_save_intent: (optional) The default action for saving intent in the property manager
         :param default_intent_level: (optional) the default level intent should be saved at
         :param order_next_available: (optional) if the default behaviour for the order should be next available order
         :param default_replace_intent: (optional) the default replace existing intent behaviour
         :param kwargs: to pass to the property ConnectorContract as its kwargs
         :return: the initialised class instance
         """
    task_name = task_name if isinstance(task_name, str) else 'base'
    return super().from_env(task_name=task_name, default_save=default_save,
        reset_templates=reset_templates, align_connectors=align_connectors,
        default_save_intent=default_save_intent, default_intent_level=
        default_intent_level, order_next_available=order_next_available,
        default_replace_intent=default_replace_intent)


def _swap(obj, i, j):
    """Swaps the elements at index `i` and index `j` in `obj`.

    If `obj` has a ``copy()`` method, ``obj[j]`` gets a copy of ``obj[i]``.

    """
    temp = obj[i]
    if hasattr(temp, 'copy'):
        temp = temp.copy()
    obj[i] = obj[j]
    obj[j] = temp
    return obj


def _get_edges_elist(line, attributes, separator, secondary, edges,
    di_attributes, di_convert):
    """
    Add edges and attributes to `edges` and `di_attributes` for the "neighbour"
    format.
    """
    data = line.split(separator)
    source, target = int(data[0]), int(data[1])
    edges.append((source, target))
    if len(data) == 3:
        attr_data = data[2].split(secondary)
        for name, val in zip(attributes, attr_data):
            di_attributes[name].append(di_convert[name](val))


def range_bind(min_value, max_value, value):
    """ binds number to a type and range """
    if value not in range(min_value, max_value + 1):
        value = min(value, max_value)
        value = max(min_value, value)
    return int(value)


def isascii(s):
    """Returns True if str s is entirely ASCII characters.

    (Compare to Python 3.7 `str.isascii()`.)
    """
    try:
        s.encode('ascii')
    except UnicodeEncodeError:
        return False
    return True


@classmethod
def getSymmetry(cls, scipionSym):
    """ Return the equivalent Chimera symmetry from Scipion one. """
    return cls._symmetryMap[scipionSym]


@staticmethod
def select_point(event, video_state=None, **_kwargs):
    """
            Should be implemented
            :param event:
            :param video_state:
        """
    return event, video_state


@staticmethod
def domain_check(checks):
    """
        list checks:  The list of domain checks to be pretty printed.
        """
    if 'resData' in checks:
        checks = checks['resData']
    count, total = 0, len(checks)
    output = '\n%i domain check(s):\n' % total
    for check in checks['domain']:
        count += 1
        output += '%s = %s' % (check['domain'], check['status'])
    return output


def runingest(sdms):
    """ Call archive tool or move data to trigger archiving of sdms.
    This function will ultimately be triggered by candidate portal.
    """
    NotImplementedError


def update_nested_dict(main_dict, new_dict):
    """Update nested dict (only level of nesting) with new values.

    Unlike dict.update, this assumes that the values of the parent dict are
    dicts, so you shouldn't replace the nested dict if it already exists.
    Instead you should update the sub-dict.
    """
    for name, rc_dict in new_dict.items():
        if name in main_dict:
            main_dict[name].update(rc_dict)
        else:
            main_dict[name] = rc_dict
    return main_dict


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

        :param NoPasswordLinkViewCreateReportType val:
        :rtype: EventType
        """
    return cls('no_password_link_view_create_report', val)


def close_file_handles(file_handles):
    """Close every opened file."""
    for file_cell_handles in file_handles.values():
        file_cell_handles['r1'].close()
        file_cell_handles['r2'].close()


def _path_to_inlet(bore_connectivity, bore_index):
    """
    Returns the path from a borehole to the bore field inlet.

    This function raises an error if the supplied borehole connectivity is
    invalid.

    Parameters
    ----------
    bore_connectivity : list
        Index of fluid inlet into each borehole. -1 corresponds to a borehole
        connected to the bore field inlet.
    bore_index : int
        Index of borehole to evaluate path.

    Returns
    -------
    path : list
        List of boreholes leading to the bore field inlet, starting from
        borehole bore_index

    """
    path = [bore_index]
    index_in = bore_connectivity[bore_index]
    while not index_in == -1:
        path.append(index_in)
        index_in = bore_connectivity[index_in]
    return path


def implicit_cast(t1, t2):
    """
    Checks whether two types can be implicitly casted
    to one of each other.
    Returns `None` if no implicit cast can be performed.
    """
    t1_t2 = t1.implicit_to(t2)
    if t1_t2 is not None:
        return t1_t2
    t2_t1 = t2.implicit_to(t1)
    if t2_t1 is not None:
        return t2_t1
    return None


def application_url():
    """Return the URL to the developer website."""
    return 'https://www.sympathyfordata.com/'


def filenum(increment: int=1):
    """Increment number in filename

    :param increment: Increment
    :type increment: int
    """
    pass


def tweets(url):
    """
    .. py:function:: tweets(url : string)

        Get the number of tweets containing the provided URL.

        This was deprecated as of November 20. 2015. See here:
        https://blog.twitter.com/2015/hard-decisions-for-a-sustainable-platform

        Hence, this function always returns (0,) until implemented otherwise.

        :param str url: The url to query Twitter for.
        :return: the number of tweets
        :rtype: Tuple
        :raises Exception: none.
        .. todo: Implement an own counter for URLs through the recommended
        "filter" Streaming-API.

        Old query:
        query = "http://urls.api.twitter.com/1/urls/count.json?url=%s" % (url)
    """
    return 0,


@classmethod
def blue(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0x3498db``."""
    return cls(3447003)


@classmethod
def get_table(cls, name):
    """Return the boto3 Table object for this model, create it if it doesn't exist

        The Table is stored on the class for each model, so it is shared between all instances of a given model.
        """
    try:
        return cls._table
    except AttributeError:
        pass
    cls._table = cls.get_resource().Table(name)
    return cls._table


def __add__(months):
    """Add a given number of months."""


def to_trc_v1_3(messages, bus):
    """`messages` should be a dict.  Keys are bus numbers and values are
    iterables of messages"""
    raise Exception('Not implemented')


def _unpack_obs_player(role, strategy, payoff, **_):
    """Unpack an observation player"""
    return role, strategy, payoff


def lr_schedule(epoch):
    """Learning Rate Schedule

    Learning rate is scheduled to be reduced after 10, 20, 30, 50 epochs.
    Called automatically every epoch as part of callbacks during training.

    # Arguments
        epoch (int): The number of epochs

    # Returns
        lr (float32): learning rate
    """
    lr = 0.001
    if epoch > 60:
        lr *= 0.0001
    elif epoch > 55:
        lr *= 0.001
    elif epoch > 40:
        lr *= 0.01
    elif epoch > 20:
        lr *= 0.1
    print('Learning rate: ', lr)
    return lr


def stepwise_selection(variables, train_model, score_model, direction=
    'both', verbose=True):
    """ Variable selection using forward and/or backward selection

    Input:
        variables: complete list of variables to consider in model building
        train_model: function that returns a fitted model for a given set of variables
        score_model: function that returns the score of a model; better models have lower scores
        direction: use it to limit stepwise selection to either 'forward' or 'backward'

    Returns:
        (best_model, best_variables)
    """
    FORWARD = 'forward'
    BACKWARD = 'backward'
    directions = [FORWARD, BACKWARD]
    if direction.lower() == FORWARD:
        directions = [FORWARD]
    if direction.lower() == BACKWARD:
        directions = [BACKWARD]
    best_variables = [] if 'forward' in directions else list(variables)
    best_model = train_model(best_variables)
    best_score = score_model(best_model, best_variables)
    if verbose:
        print('Variables: ' + ', '.join(variables))
        print('Start: score={:.2f}, constant'.format(best_score))
    while True:
        step = [(best_score, None, best_model, 'unchanged')]
        if FORWARD in directions:
            for variable in variables:
                if variable in best_variables:
                    continue
                step_var = list(best_variables)
                step_var.append(variable)
                step_model = train_model(step_var)
                step_score = score_model(step_model, step_var)
                step.append((step_score, variable, step_model, 'add'))
        if 'backward' in directions:
            for variable in best_variables:
                step_var = list(best_variables)
                step_var.remove(variable)
                step_model = train_model(step_var)
                step_score = score_model(step_model, step_var)
                step.append((step_score, variable, step_model, 'remove'))
        step.sort(key=lambda x: x[0])
        best_score, chosen_variable, best_model, direction = step[0]
        if verbose:
            print('Step: score={:.2f}, {} {}'.format(best_score, direction,
                chosen_variable))
        if chosen_variable is None:
            break
        if direction == 'add':
            best_variables.append(chosen_variable)
        else:
            best_variables.remove(chosen_variable)
    return best_model, best_variables


def get_image_dimensions(file_or_path, close=False):
    """
    Returns the (width, height) of an image, given an open file or a path.  Set
    'close' to True to close the file at the end if it is initially in an open
    state.
    """
    try:
        from PIL import ImageFile as PILImageFile
    except ImportError:
        import ImageFile as PILImageFile
    p = PILImageFile.Parser()
    if hasattr(file_or_path, 'read'):
        file = file_or_path
        file_pos = file.tell()
        file.seek(0)
    else:
        file = open(file_or_path, 'rb')
        close = True
    try:
        chunk_size = 1024
        while 1:
            data = file.read(chunk_size)
            if not data:
                break
            p.feed(data)
            if p.image:
                return p.image.size
            chunk_size = chunk_size * 2
        return None
    finally:
        if close:
            file.close()
        else:
            file.seek(file_pos)


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 poly_compare(poly1, poly2, area):
    """Calculate the ratio of overlap between two polygons and the given area

    :param poly1: polygon specified by its verticies
    :type poly1: list
    :param poly2: polygon specified by its verticies
    :type poly2: list
    :param area: the area to compare the overlap of poly1 and poly2
    :type area: float
    :return: the ratio of overlap of poly1 and poly2 to the area  e.g. overlap(poly1, poly2)/area
    :rtype: float
    """
    assert area > 0
    intersection_area = help.polygon_intersection_area([poly1, poly2])
    return intersection_area / area


def _determine_input_core_dims(dim, weights):
    """
    Determine input_core_dims based on type of dim and weights.

    Parameters
    ----------
    dim : str, list
        The dimension(s) to apply the correlation along.
    weights : xarray.Dataset or xarray.DataArray or None
        Weights matching dimensions of ``dim`` to apply during the function.

    Returns
    -------
    list of lists
        input_core_dims used for xr.apply_ufunc.
    """
    if not isinstance(dim, list):
        dim = [dim]
    if weights is None:
        input_core_dims = [dim, dim, [None]]
    else:
        input_core_dims = [dim, dim, dim]
    return input_core_dims


def from_csv(filen, index_col=None, header_row=None, **kwargs):
    """
    Loads an array of points from the given filename parsed
    as a csv.

    .. note:: This function requires pandas to be installed.

    .. note:: For data in a space-separated column format,
              pass the argument `sep=' '` to read in as a csv.

    Parameters
    ----------
    filen : str
        The (relative) filename to load from.
    index_col: int or None
        The column that indexes the rows, defaults to None
        meaning no such column is present.
    header_row: int or None
        The row with header information (i.e. column names), with
        all previous rows ignored. Defaults to None, which means
        no such header exists.

    **kwargs :
        Passed directly to pandas.DataFrame.from_csv.
    """
    import pandas as pn
    df = pn.DataFrame.from_csv(filen, index_col=index_col, header_row=
        header_row, **kwargs)
    return df.as_matrix()


def mpf_shift(s, n):
    """Quickly multiply the raw mpf s by 2**n without rounding."""
    sign, man, exp, bc = s
    if not man:
        return s
    return sign, man, exp + n, bc


def time_scale(time_scale):
    """Validate a macro temporal time scale."""
    if time_scale <= 0 or isinstance(time_scale, float):
        raise ValueError('time scale must be a positive integer')


def chunker(reader, width):
    """Yield chunks from lines in reader with given width."""
    for line in reader:
        line = line[:-1]
        if line == '':
            yield ''
            continue
        for offset in range(0, len(line), width):
            yield line[offset:offset + width]


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

        :param str val:
        :rtype: UserSelectorArg
        """
    return cls('email', val)


def _get_row_col_map_2d(matrix, GCi, GCj, ifo):
    """helper for ``get_row_col_map``"""
    rows = {}
    rows_reversed = {}
    cols = {}
    cols_reversed = {}
    i = 0
    for nid, comp in GCi:
        gci = nid, comp
        if gci not in rows:
            rows[gci] = i
            rows_reversed[i] = gci
            i += 1
    if ifo == 6:
        for nid, comp in GCj:
            gcj = nid, comp
            if gcj not in rows:
                rows[gcj] = i
                rows_reversed[i] = gcj
                i += 1
        cols = rows
        cols_reversed = rows_reversed
    else:
        j = 0
        for nid, comp in GCj:
            gcj = nid, comp
            if gcj not in cols:
                cols[gcj] = j
                cols_reversed[j] = gcj
                j += 1
    return rows, cols, rows_reversed, cols_reversed


def quaternion_real(quaternion):
    """Return real part of quaternion.

    >>> quaternion_real([3, 0, 1, 2])
    3.0

    """
    return float(quaternion[0])


def inherited_states(deactivated=False):
    """ Returns a list of inherited :py:class:`IState` s
        """


def enumConfiglets(group=None):
    """ lists the Configlets of a group, returns them as dicts by
            calling .getAction() on each of them """


def override_remove_button(all: bool=True):
    """Remove an override operation

    :param all: All, Reset to default values all elements of the array
    :type all: bool
    """
    pass


def get_parent_pid(pid):
    """
    Returns the parent PID for the given process

    :note: This is currently Linux specific.

    :param pid: The PID of child process
    :returns: The parent PID
    :rtype: int
    """
    with open('/proc/%d/stat' % pid, 'rb') as proc_stat:
        parent_pid = proc_stat.read().split(b' ')[-49]
        return int(parent_pid)


def parse_value_or_iterable(arg):
    """
    If arg is a single value, return it as a string; if an iterable, return
    a ;-joined string of all values
    """
    if str(arg) == arg:
        return arg
    if type(arg) == int:
        return str(arg)
    return ';'.join(arg)


@staticmethod
def _get_flag_value(event):
    """Note, this may be able to be made more accurate,
            i.e. handle two modifier keys at once."""
    flags = event.modifierFlags()
    if flags == 256:
        value = 0
    else:
        value = 1
    return value


def split(path):
    """split(path) -> streamname, filename

    Separate the stream name and file name in a /-separated stream path and
    return a tuple (stream_name, file_name).  If no stream name is available,
    assume '.'.

    """
    try:
        stream_name, file_name = path.rsplit('/', 1)
    except ValueError:
        stream_name, file_name = '.', path
    return stream_name, file_name


def _get_subexons_to_rescue(subexon_table):
    """Return a DataFrame with the subexons to rescue."""
    return subexon_table.loc[subexon_table['Cluster'] < 0, [
        'SubexonIDCluster', 'Cluster', 'SubexonProteinSequence']
        ].drop_duplicates(subset='SubexonIDCluster').to_dict('records')


def get_byte_array(padded_encoded_string):
    """Convert padded encoded string into bytes"""
    byte_array = bytearray()
    length = len(padded_encoded_string)
    for i in range(0, length, 8):
        byte = padded_encoded_string[i:i + 8]
        byte_array.append(int(byte, 2))
    return byte_array


def delocalize_compressed_verts(comp_verts, local_nodes):
    """TODO: Update this function to also work on parsed vert data."""
    local_node_ct = len(local_nodes) * 3
    for i in range(28, len(comp_verts), 32):
        if comp_verts[i] < local_node_ct:
            comp_verts[i] = local_nodes[comp_verts[i] // 3] * 3
        i += 1
        if comp_verts[i] < local_node_ct:
            comp_verts[i] = local_nodes[comp_verts[i] // 3] * 3


def next_child_ordering(cnx, parent_eid, rtype):
    """Return value for the `ordering` attribute of a child freshly appended through
    `rtype` to parent entity with the given eid.
    """
    rql = 'Any MAX(O) WHERE X {rtype} P, P eid %(p)s, X ordering O'
    ordering = cnx.execute(rql.format(rtype=rtype), {'p': parent_eid})[0][0]
    return 1 if ordering is None else ordering + 1


@staticmethod
def get_or_new_from_json_dict_with_types(data, cls_map, type_key='type'):
    """Get `cls` object w/ deserialization from json by using type key hint if needed.

        If data is instance of one of cls, return data.
        Else if data is instance of dict, create instance from dict.
        Else, return None.

        :param data:
        :param cls_map:
        :param type_key:
        :rtype: object
        """
    if isinstance(data, tuple(cls_map.values())):
        return data
    elif isinstance(data, dict):
        type_val = data[type_key]
        if type_val in cls_map:
            return cls_map[type_val].new_from_json_dict(data)
    return None


@staticmethod
def get_size():
    """Returns the size of a byte (one byte)."""
    return 1


def rr_or(x, y, nx, ny):
    """Dimensionless production rate for a gene regulated by two
    repressors with OR logic in the absence of leakage.

    Parameters
    ----------
    x : float or NumPy array
        Concentration of first repressor.
    y : float or NumPy array
        Concentration of second repressor.
    nx : float
        Hill coefficient for first repressor.
    ny : float
        Hill coefficient for second repressor.

    Returns
    -------
    output : NumPy array or float
        (1 + x**nx + y**ny) / (1 + x**nx) / (1 + y**ny)
    """
    return (1 + x ** nx + y ** ny) / (1 + x ** nx) / (1 + y ** ny)


def remove_suffix(string):
    """Removes suffixes

          Args:
              string:str
          Returns:
              returns str
          """
    suffixes = ['Esq', 'Ii', 'Iii', 'Iiii', 'Iv', 'Jnr', 'Jr', 'Sr']
    string = string.replace(' ', '')
    string = string.replace('.', '')
    string = string.replace(',', '')
    for suffix in suffixes:
        if string.endswith(suffix):
            string = string[:-len(suffix)]
            return string
    return string


def contains_url(tweet):
    """Returns True is tweet has at least one 'urls' entity"""
    if 'entities' not in tweet:
        return False
    if 'urls' in tweet['entities'] and len(tweet['entities']['urls']) > 0:
        return True
    return False


def cHypot():
    """
    Return the kernel code for hypot, which computes the sqrt(x*x + y*y) without intermediate overflow.
    """
    R = """
    KERNEL void cHypot(GLOBAL_MEM float2 *x,
                                    GLOBAL_MEM const float2 *y)
    {
    const unsigned int gid =  get_global_id(0);
    float2 tmp_x;
    float2 tmp_y;
    tmp_x = x[gid];
    tmp_y = y[gid];
    tmp_x.x = hypot( tmp_x.x, tmp_x.y); // sqrt( tmp_x.x*tmp_x.x + tmp_x.y*tmp_x.y);
    tmp_y.x = hypot( tmp_y.x, tmp_y.y); // sqrt( tmp_y.x*tmp_y.x + tmp_y.y*tmp_y.y);

    x[gid].x = hypot(tmp_x.x, tmp_y.x);
    x[gid].y = 0.0;

    };
    """
    return R


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 midnight_datetime(dtime):
    """ Takes a datetime object and returns a datetime at midnight of the
        given day """
    midnightDt = dtime.replace(minute=0, hour=0, second=0, microsecond=0)
    return midnightDt


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

        :param alias: The email address to no longer accept as a recipient for
            implicit destination posting purposes.
        :type alias: string
        """


@staticmethod
def getConfig(conf, section, key):
    """
        获取指定section下面的key
        :param conf:
        :param section:
        :param key:
        :return:
        """
    return conf.get(section, key)


def make_generic_scoring_dict(match, mtype):
    """returns scoring dict for alignment

    Parameters
    ----------
    match : int
        value for a match, mismatches default to -1
    mtype
        MolType instance or string that can be used to get_moltype
    """
    from cogent3 import get_moltype
    mtype = get_moltype(mtype)
    S = {}
    for a in mtype:
        for b in mtype:
            if a == b:
                score = match
            else:
                score = -1
            S[a, b] = score
    return S


def get_event_source_mapping(UUID=None):
    """
    Returns configuration information for the specified event source mapping (see  CreateEventSourceMapping ).
    This operation requires permission for the lambda:GetEventSourceMapping action.
    See also: AWS API Documentation

    Examples
    This operation retrieves a Lambda function's event source mapping
    Expected Output:

    :example: response = client.get_event_source_mapping(
        UUID='string'
    )

    :type UUID: string
    :param UUID: [REQUIRED]
            The AWS Lambda assigned ID of the event source mapping.

    :rtype: dict
    :return: {
        'UUID': 'string',
        'BatchSize': 123,
        'EventSourceArn': 'string',
        'FunctionArn': 'string',
        'LastModified': datetime(2015, 1, 1),
        'LastProcessingResult': 'string',
        'State': 'string',
        'StateTransitionReason': 'string'
    }

    """
    pass


@staticmethod
def __ensure_int_values(*values):
    """Casts values to int.

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

        :param values: arbitrary number of values that can be cast to int
        :return: single value or list of values, depending on number of ``values`` passed
        """
    res = []
    for val in values:
        res.append(int(val))
    return res[0] if len(res) == 1 else res


def get_normalized_version_string(version_string):
    """takes in a version string and returns a normalized version that is compatible with inf and cat files"""
    while version_string.count('.') < 3:
        version_string += '.0'
    return version_string


def get_incompatible_reqs(dist, installed_dists):
    """Return all of the requirements of `dist` that are present in
    `installed_dists`, but have incompatible versions.

    """
    installed_dists_by_name = {}
    for installed_dist in installed_dists:
        installed_dists_by_name[installed_dist.project_name] = installed_dist
    for requirement in dist.requires():
        present_dist = installed_dists_by_name.get(requirement.project_name)
        if present_dist and present_dist not in requirement:
            yield requirement, present_dist


def verify(server_name):
    """
    Aim is to verify the release on this server (try to install it and run tests if relevant).

    :param server_name:
    :return:
    """
    raise NotImplementedError


def get_fields(header, name=None):
    """
    Return the set of all field names (a.k.a "data keys") in a header.

    Parameters
    ----------
    header : Header
    name : string, optional
        Get field from only one "event stream" with this name. If None
        (default) get fields from all event streams.

    Returns
    -------
    fields : set
    """
    fields = set()
    for descriptor in header['descriptors']:
        if name is not None and name != descriptor.get('name', 'primary'):
            continue
        for field in descriptor['data_keys'].keys():
            fields.add(field)
    return fields


def status(client, access_key, status=True):
    """Set security credentials status."""
    status = client.user.credentials.status(method='POST', accessKey=
        access_key, isActive=status)
    return status


def unpack(cls, string):
    """@brief Unpack the runlength encoded table data.

        Terence implemented packed table initializers, because Java has a
        size restriction on .class files and the lookup tables can grow
        pretty large. The generated JavaLexer.java of the Java.g example
        would be about 15MB with uncompressed array initializers.

        Python does not have any size restrictions, but the compilation of
        such large source files seems to be pretty memory hungry. The memory
        consumption of the python process grew to >1.5GB when importing a
        15MB lexer, eating all my swap space and I was to impacient to see,
        if it could finish at all. With packed initializers that are unpacked
        at import time of the lexer module, everything works like a charm.

        """
    ret = []
    for i in range(len(string) / 2):
        n, v = ord(string[i * 2]), ord(string[i * 2 + 1])
        if v == 65535:
            v = -1
        ret += [v] * n
    return ret