def args_to_dict(values=None, **kwargs):
    """convert args to a dict

    Allows developers to pass field values to fields either
    as a dict or as a set of keyword arguments, whichever
    makes the most sense for their code.

    This is currently only used for clean() but could potentially
    be used in a number of other places in this modudle where the
    same pattern shows up.  Erring on the side of caution for now.

    >>> args_to_dict()
    {}

    >>> args_to_dict({})
    {}

    >>> args_to_dict({'name': 'Pat'})
    {'name': 'Pat'}

    >>> from zoom.utils import pp
    >>> pp(args_to_dict(**{'name': 'Pat', 'age': 10}))
    {
      "age": 10,
      "name": "Pat"
    }

    >>> try:
    ...    args_to_dict({'name': 'Pat'}, 'bad value', age=10)
    ... except TypeError as e:
    ...    expected = 'args_to_dict() takes' in str(e)
    >>> expected
    True

    """
    return values or kwargs


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 require(name, field, data_type):
    """Require that the named `field` has the right `data_type`"""
    if not isinstance(field, data_type):
        msg = '{0} must have {1}, got: {2}'.format(name, data_type, field)
        raise AssertionError(msg)


def bfgs(f, x, bounds, max_iter=500, args=None):
    """
    Local optimizer that minimizes a function ``f`` using the constrained
    quasi-Newton method of Broyden, Fletcher, Goldfarb, and Shanno provided by
    SciPy [1,2,3].

    Arguments:

    ``f``
        A function to minimize. The function ``f(x)`` must be callable with
        ``x`` a sequence of ``m`` coordinates and should return a single scalar
        value.
    ``x``
        An initial guess for the ``x`` with the lowest ``f(x)``.
    ``bounds``
        A sequence of tuples ``(xmin, xmax)`` with the boundaries for each
        dimension of ``x``.
    ``max_iter``
        The maximum number of iterations to perform.
    ``args``
        An optional tuple containing extra arguments to ``f``. If ``args`` is
        specified, ``f`` will be called as ``f(x, *args)``.

    The method returns a tuple ``(xopt, fopt)`` where ``xopt`` is the best
    position found and ``fopt = f(xopt)``.

    References:

    [1] http://scipy.org

    [2] A Limited Memory Algorithm for Bound Constrained Optimization. Byrd,
    R H and P Lu and J. Nocedal (1995) SIAM Journal on Scientific and
    Statistical Computing 16 (5): 1190-1208.

    [3] L-BFGS-B: Algorithm 778: L-BFGS-B, FORTRAN routines for large scale
    bound constrained optimization. Zhu, C and R H Byrd and J Nocedal (1997)
    ACM Transactions on Mathematical Software 23 (4): 550-560.

    *Note: This method requires SciPy to be installed.*
    """
    from scipy.optimize import minimize
    if not callable(f):
        raise ValueError('The argument `f` must be a callable function.')
    if args is None:
        args = ()
    elif type(args) != tuple:
        raise ValueError('The argument `args` must be either None or a tuple.')
    max_iter = int(max_iter)
    if max_iter < 1:
        raise ValueError('Maximum number of iterations must be at least 1.')
    res = minimize(f, x, bounds=bounds, args=args, method='L-BFGS-B',
        options={'maxiter': max_iter, 'disp': False})
    return res.x, res.fun


def evalUnits(unitStr):
    """
    Evaluate a unit string into ([numerators,...], [denominators,...])
    Examples:
        N m/s^2   =>  ([N, m], [s, s])
        A*s / V   =>  ([A, s], [V,])
    """
    pass


def should_build_with_cython(previous_cython_version, is_release):
    """
    Returns the previously used Cython version (or 'unknown' if not
    previously built) if Cython should be used to build extension modules from
    pyx files.
    """
    have_cython = False
    try:
        from Cython import __version__ as cython_version
        have_cython = True
    except ImportError:
        pass
    if have_cython and (not is_release or previous_cython_version == 'unknown'
        ):
        return cython_version
    else:
        return False


def verify_all(local_save_folder=local_save_folder):
    """Loops over every file in the folder and determines if it's a valid MIMIC III file"""
    pass


def num_cycles(perm):
    """Returns the number of cycles in the permutation.

    >>> Permutation(53814276).num_cycles()
    3
    """
    return len(perm.cycle_decomp())


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

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

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


def __enter__():
    """Marks the instance as active.

        Should return self.
        """


def __next__(zelf):
    """ yield next value. """
    for k in dir(zelf):
        yield k


def mtf_ts_to_dataframe(tan, sag, freqs, field=0, focus=0):
    """Create a Pandas dataframe from tangential and sagittal MTF data.

    Parameters
    ----------
    tan : `numpy.ndarray`
        vector of tangential MTF data
    sag : `numpy.ndarray`
        vector of sagittal MTF data
    freqs : iterable
        vector of spatial frequencies for the data
    field : `float`
        relative field associated with the data
    focus : `float`
        focus offset (um) associated with the data

    Returns
    -------
    pandas dataframe.

    """
    import pandas as pd
    rows = []
    for f, t, s in zip(freqs, tan, sag):
        base_dict = {'Field': field, 'Focus': focus, 'Freq': f}
        rows.append({**base_dict, **{'Azimuth': 'Tan', 'MTF': t}})
        rows.append({**base_dict, **{'Azimuth': 'Sag', 'MTF': s}})
    return pd.DataFrame(data=rows)


def _map_participants(participant_data):
    """Map participant IDs to names."""
    participants = {}
    for participant_wrapper in participant_data:
        participant = participant_wrapper['participant']
        if len(participant['group_player_ids']) == 1:
            pid = participant['group_player_ids'][0]
            participants[pid] = participant['name']
        pid = participant['id']
        participants[pid] = participant['name']
    return participants


def pop(key, default=None):
    """remove specified key and return the corresponding value
        *args may contain a single default value, or may not be supplied.
        If key is not found, default is returned if given, otherwise
        KeyError is raised"""


ttwidgets//ttwidgets - Copy (2).pyfile:/ttwidgets - Copy (2).py:function:unmap/unmap

def unmap(widget):
    """Unmap a mapped WIDGET."""
    result = False
    if widget and widget.winfo_exists() and widget.winfo_ismapped():
        result = True
        geom_mgr = widget.winfo_manager()
        if geom_mgr == 'grid':
            widget.grid_forget()
        elif geom_mgr == 'pack':
            widget.pack_forget()
        elif geom_mgr == 'place':
            widget.place_forget()
        else:
            result = False
    return result


def normalize_sequence(value, rank):
    """For scalar input, duplicate it into a sequence of rank length. For
    sequence input, check for correct length.
    """
    try:
        lst = list(value)
    except TypeError:
        lst = [value] * rank
    if len(lst) != rank:
        raise ValueError('Invalid sequence length.')
    return lst


def rep0(s):
    """REGEX: build repeat 0 or more."""
    return s + '*'


def psi_Na_Cl_H2AsO4_M83(T, P):
    """c-a-a': sodium chloride dihydrogen-arsenate [M83]."""
    psi = 0
    valid = T == 298.15
    return psi, valid


def extrapolate_windspeed(hgt, shr, ref_windspeed, ref_hgt):
    """Extrapolate windspeed

    Extrapolate windspeed using the wind profile power law [1]_.

    Parameters
    ----------
    hgt : float
        Target height
    shr : float
        Shear
    ref_windspeed : float
        Reference wind speed
    ref_hgt : float
        Reference height

    Returns
    -------
    float
        Wind speed at target height

    References
    ----------

    .. [1] https://en.wikipedia.org/wiki/Wind_profile_power_law
    """
    return ref_windspeed * pow(hgt / ref_hgt, shr)


def critical_frequency(subsystem_plate, subsystem_cavity):
    """
    Critical frequency.

    .. math:: f_c = \\frac{ c_0^2 \\sqrt{3}  } {\\ pi c_L h}

    .. math:: f_c = \\frac{f c_0^2}{c_B^2}

    See Craik, table 3.3, page 51.
    """
    return subsystem_plate.frequency.center * (subsystem_cavity.
        soundspeed_group / subsystem_plate.component.subsystem_bend.
        soundspeed_phase) ** 2.0


def py_default(type_name):
    """Get the Python default value for a given model type.

        >>> py_default('string')
        ''string''
        >>> py_default('list')
        '[...]'
        >>> py_default('unknown')
        '...'

    :rtype: string
    """
    return {'double': '123.0', 'long': '123', 'integer': '123', 'string':
        "'string'", 'blob': "b'bytes'", 'boolean': 'True|False', 'list':
        '[...]', 'map': '{...}', 'structure': '{...}', 'timestamp':
        'datetime(2015, 1, 1)'}.get(type_name, '...')


def modify_db_snapshot_attribute(DBSnapshotIdentifier=None, AttributeName=
    None, ValuesToAdd=None, ValuesToRemove=None):
    """
    Adds an attribute and values to, or removes an attribute and values from, a manual DB snapshot.
    To share a manual DB snapshot with other AWS accounts, specify restore as the AttributeName and use the ValuesToAdd parameter to add a list of IDs of the AWS accounts that are authorized to restore the manual DB snapshot. Uses the value all to make the manual DB snapshot public, which means it can be copied or restored by all AWS accounts. Do not add the all value for any manual DB snapshots that contain private information that you don't want available to all AWS accounts. If the manual DB snapshot is encrypted, it can be shared, but only by specifying a list of authorized AWS account IDs for the ValuesToAdd parameter. You can't use all as a value for that parameter in this case.
    To view which AWS accounts have access to copy or restore a manual DB snapshot, or whether a manual DB snapshot public or private, use the  DescribeDBSnapshotAttributes API action.
    See also: AWS API Documentation

    Examples
    This example adds the specified attribute for the specified DB snapshot.
    Expected Output:

    :example: response = client.modify_db_snapshot_attribute(
        DBSnapshotIdentifier='string',
        AttributeName='string',
        ValuesToAdd=[
            'string',
        ],
        ValuesToRemove=[
            'string',
        ]
    )

    :type DBSnapshotIdentifier: string
    :param DBSnapshotIdentifier: [REQUIRED]
            The identifier for the DB snapshot to modify the attributes for.

    :type AttributeName: string
    :param AttributeName: [REQUIRED]
            The name of the DB snapshot attribute to modify.
            To manage authorization for other AWS accounts to copy or restore a manual DB snapshot, set this value to restore .

    :type ValuesToAdd: list
    :param ValuesToAdd: A list of DB snapshot attributes to add to the attribute specified by AttributeName .
            To authorize other AWS accounts to copy or restore a manual snapshot, set this list to include one or more AWS account IDs, or all to make the manual DB snapshot restorable by any AWS account. Do not add the all value for any manual DB snapshots that contain private information that you don't want available to all AWS accounts.
            (string) --

    :type ValuesToRemove: list
    :param ValuesToRemove: A list of DB snapshot attributes to remove from the attribute specified by AttributeName .
            To remove authorization for other AWS accounts to copy or restore a manual snapshot, set this list to include one or more AWS account identifiers, or all to remove authorization for any AWS account to copy or restore the DB snapshot. If you specify all , an AWS account whose account ID is explicitly added to the restore attribute can still copy or restore the manual DB snapshot.
            (string) --

    :rtype: dict
    :return: {
        'DBSnapshotAttributesResult': {
            'DBSnapshotIdentifier': 'string',
            'DBSnapshotAttributes': [
                {
                    'AttributeName': 'string',
                    'AttributeValues': [
                        'string',
                    ]
                },
            ]
        }
    }

    :returns:
    (string) --

    """
    pass


@classmethod
def from_dict(cls, data):
    """
		Takes the dictionary--data--and
		returns a PawpyData instance.
		"""
    return cls(data['structure'], data['data'], dos=[data['energies'], data
        ['densities'], data['efermi']], vbm=data['vbm'], cbm=data['cbm'])


def _deserialize_object(value):
    """Return an original value.

    :return: object.
    """
    return value


@staticmethod
def get_text(source):
    """
    	Gets the text from a source.
	This may be a file or URL.
	"""
    if source.startswith('http'):
        import requests
        return requests.get(source).text
    with open(source, 'r') as file:
        return file.read()


def add_client_session(engine, session_id, client_id, sid, base_url, workspace
    ):
    """Add client session."""
    logger = engine.logger
    clients = engine.store.clients
    registered_sessions = engine.store.registered_sessions
    if client_id in clients:
        clients[client_id].append(sid)
        client_connected = True
    else:
        clients[client_id] = [sid]
        client_connected = False
    logger.info('Adding client session %s', sid)
    registered_sessions[sid] = {'client': client_id, 'session': session_id,
        'base_url': base_url, 'workspace': workspace}
    return client_connected


@classmethod
def from_kwargs(cls, **kwargs):
    """Initialise configuration from kwargs."""
    config = cls()
    for slot in cls.__slots__:
        if slot.startswith('_'):
            slot = slot[1:]
        setattr(config, slot, kwargs.pop(slot, cls.get_default(slot)))
    if kwargs:
        raise ValueError('Unrecognized option(s): {}'.format(kwargs.keys()))
    return config


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

        :param GroupUserManagementChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('group_user_management_change_policy_details', val)


def revsplit(rev):
    """Parse a revision string and return (uuid, path, revnum).
    >>> revsplit(b'svn:a2147622-4a9f-4db4-a8d3-13562ff547b2'
    ...          b'/proj%20B/mytrunk/mytrunk@1')
    ('a2147622-4a9f-4db4-a8d3-13562ff547b2', '/proj%20B/mytrunk/mytrunk', 1)
    >>> revsplit(b'svn:8af66a51-67f5-4354-b62c-98d67cc7be1d@1')
    ('', '', 1)
    >>> revsplit(b'@7')
    ('', '', 7)
    >>> revsplit(b'7')
    ('', '', 0)
    >>> revsplit(b'bad')
    ('', '', 0)
    """
    parts = rev.rsplit(b'@', 1)
    revnum = 0
    if len(parts) > 1:
        revnum = int(parts[1])
    parts = parts[0].split(b'/', 1)
    uuid = b''
    mod = b''
    if len(parts) > 1 and parts[0].startswith(b'svn:'):
        uuid = parts[0][4:]
        mod = b'/' + parts[1]
    return uuid, mod, revnum


def trim(text, tabwidth=4):
    """
    Trim text of common, leading whitespace.

    Based on the trim algorithm of PEP 257:
        http://www.python.org/dev/peps/pep-0257/
    """
    if not text:
        return ''
    lines = text.expandtabs(tabwidth).splitlines()
    maxindent = len(text)
    indent = maxindent
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    trimmed = [lines[0].strip()] + [line[indent:].rstrip() for line in
        lines[1:]]
    i = 0
    while i < len(trimmed) and not trimmed[i]:
        i += 1
    return '\n'.join(trimmed[i:])


def unique_value(domain):
    """Return if unique, the field and the value"""
    if isinstance(domain, list) and len(domain) == 1:
        domain, = domain
        name = domain[0]
        value = domain[2]
        count = 0
        if len(domain) == 4 and name[-3:] == '.id':
            count = 1
            model = domain[3]
            value = [model, value]
        if name.count('.') == count and domain[1] == '=':
            return True, domain[1], value
    return False, None, None


def add_mimetype(mimedb, mimetype, extension):
    """Add or replace a mimetype to be used with the given extension."""
    strict = extension in mimedb.types_map[True]
    mimedb.add_type(mimetype, extension, strict=strict)


def check_compute_distance(compute):
    """Check if compute distance/kernel function if a callable()"""
    if not callable(compute) and compute is not None:
        raise ValueError('The compute distance/kernel must be a function.')


def upload_file(client, bucket_name, file_name, path_to_blob=None):
    """ Uploads a file to a bucket, if the file is empty no uploads are created"""
    bucket = client.get_bucket(bucket_name)
    if path_to_blob is None:
        path_to_blob = file_name
    blob2 = bucket.blob(path_to_blob)
    blob2.upload_from_filename(filename=file_name)


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

        :param LookupError val:
        :rtype: SearchError
        """
    return cls('path', val)


def shouldSetupAPI():
    """
    Return whether the api needs to be compiled/pythonified
    """
    try:
        from api.colour import HueShifter
        from api.gui.gui import GUIState
        return False
    except ImportError:
        return True


@staticmethod
def set_region_whitelist(config_dict, regions):
    """set regions for config's region whitelist"""
    if regions:
        config_dict['region_whitelist'] = list(set(regions))
        print('Region whitelist set.')
    else:
        config_dict.pop('region_whitelist', None)
        print('Region whitelist cleared.')
    return config_dict


def nasnet_dual_path_scheme_ordinal(block, x, _):
    """
    NASNet specific scheme of dual path response for an ordinal block with dual inputs/outputs in a DualPathSequential
    block.

    Parameters:
    ----------
    block : Chain
        A block.
    x : Tensor
        Current processed tensor.

    Returns
    -------
    x_next : Tensor
        Next processed tensor.
    x : Tensor
        Current processed tensor.
    """
    return block(x), x


@classmethod
def _cmp_version_part(cls, version1, version2):
    """Compares two versions."""
    ver1_it = iter(version1)
    ver2_it = iter(version2)
    while True:
        v1 = next(ver1_it, None)
        v2 = next(ver2_it, None)
        if v1 is None or v2 is None:
            if v1 is not None:
                return 1
            if v2 is not None:
                return -1
            return 0
        if v1.isdigit() and v2.isdigit():
            a = int(v1)
            b = int(v2)
            if a < b:
                return -1
            if a > b:
                return 1
        else:
            r = cls._cmp_version_string(v1, v2)
            if r != 0:
                return r


@staticmethod
def _classification_function_eight(salary, commission, age, elevel, car,
    zipcode, hvalue, hyears, loan):
    """ classification_function_eight

        Parameters
        ----------
        salary: float
            Numeric feature: Salary.

        commission: float
            Numeric feature: Commission.

        age: int
            Numeric feature: Age.

        elevel: int
            Categorical feature: Education level.

        car: int
            Categorical feature: Car maker.

        zipcode; int
            Categorical feature: Zipcode.

        hvalue: flaot
            Numeric feature: Value of the house.

        hyears: float
            Numeric feature: Years house owned.

        loan: float
            Numeric feature: Total amount of loan.

        Returns
        -------
        int
            Returns the sample class label, either 0 or 1.

        """
    disposable = 2 * (salary + commission
        ) / 3 - 5000 * elevel - loan / 5 - 10000
    return 0 if disposable > 1 else 1


def get_int(byte_array, signed=True):
    """
    Gets the specified integer from its byte array.
    This should be used by this module alone, as it works with big endian.

    :param byte_array: the byte array representing th integer.
    :param signed: whether the number is signed or not.
    :return: the integer representing the given byte array.
    """
    return int.from_bytes(byte_array, byteorder='big', signed=signed)


def theta_K_Na_PK74(T, P):
    """c-c': potassium sodium [PK74]."""
    theta = -0.012
    valid = T == 298.15
    return theta, valid


def is_number_offset(c_offset):
    """
    Is the offset a number
    """
    return c_offset >= 102 and c_offset <= 111


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

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

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


def __new__(cls, *args, **kwargs):
    """ Create as a singleton. """
    if not hasattr(cls, 'instance'):
        cls.instance = object.__new__(cls)
    return cls.instance


def format_text(text):
    """Transform special chars in text to have only one line."""
    return text.replace('\n', '\\n').replace('\r', '\\r')


def Length(expr):
    """
    Returns number of elements in the expression just as sympy's len.

    Examples
    ========

    >>> from sympy.integrals.rubi.utility_function import Length
    >>> from sympy.abc import  x, a, b
    >>> from sympy import cos, sin
    >>> Length(a + b)
    2
    >>> Length(sin(a)*cos(a))
    2

    """
    if isinstance(expr, list):
        return len(expr)
    return len(expr.args)


def get_data_name(name):
    """
    convert DataNameFoo -> name_foo
    :param name: name of class in uppercase
    :return: name in lowercase
    """
    if name.find('Data') == 0:
        name = name[4:]
    name_ = ''
    for i, char in enumerate(name):
        if char.isupper() and i > 0:
            name_ += '_'
        name_ += char.lower()
    return name_


@staticmethod
def read(reader, _index):
    """
        Reads Zserio float32 type from the bit stream.

        :param reader: Bit stream from which to read.
        :param _index: Not used.
        """
    return reader.readFloat32()


def google_fixed_width_font(style):
    """check if the css of the current element defines a fixed width font"""
    font_family = ''
    if 'font-family' in style:
        font_family = style['font-family']
    if 'Courier New' == font_family or 'Consolas' == font_family:
        return True
    return False


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

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


def shorten_component_name(component):
    """Return canonical short version of the component name.

    Example: reana-workflow-controller -> r-w-controller

    :param component: standard component name
    :type component: str

    :return: short component name
    :rtype: str
    """
    short_name = ''
    parts = component.split('-')
    for part in parts[:-1]:
        short_name += part[0] + '-'
    short_name += parts[-1]
    return short_name


def strip(line):
    """Removes any `\\\\r` or `\\\\n` from line and remove trailing whitespaces

    Parameters
    ----------
    line: :obj:`str`

    Returns
    -------
    str
        the stripped line.

    """
    return line.replace('\r\n', '').strip()


def lambd_BOH3_K_FW86(T, P):
    """n-c: boric-acid potassium [FW86]."""
    lambd = -0.14
    valid = T == 298.15
    return lambd, valid


@staticmethod
def _lookup(record, index=None, default=None):
    """
        One-based lookup
        :param record: an object having a __getitem__ interface
        :param index: an integer, 0-based index
        :param default:
        :return:
        """
    if index is None:
        return default
    try:
        return record[index]
    except LookupError:
        return default


def convert_table(shell_output, delimiter='\t|\\s{2,}', output='dict'):
    """
        a method to convert a STDOUT shell table into a python data structure

    :param shell_output: string from STDOUT with headers
    :param delimiter: string with regex pattern delimiting headers
    :param output: string with type of structure to output (dict, list or csv)
    :return: list of dictionaries or list of lists or string with csv format
    """
    import re
    gap_pattern = re.compile(delimiter)
    output_lines = shell_output.splitlines()
    column_headers = gap_pattern.split(output_lines[0])
    blank_index = column_headers.index('')
    if blank_index > -1:
        column_headers.pop(blank_index)
    indices = []
    for i in range(len(column_headers)):
        if i + 1 < len(column_headers):
            indices.append((output_lines[0].find(column_headers[i]),
                output_lines[0].find(column_headers[i + 1])))
        else:
            indices.append((output_lines[0].find(column_headers[i]), -1))
    python_list = []
    csv_string = ''
    if output == 'dict':
        pass
    elif output == 'list':
        python_list.append(column_headers)
    elif output == 'csv':
        for i in range(len(column_headers)):
            if i:
                csv_string += ','
            csv_string += column_headers[i]
    else:
        raise ValueError(
            'output argument must be one of dict, list or csv values.')
    for i in range(1, len(output_lines)):
        if output == 'dict':
            row_details = {}
            for j in range(len(column_headers)):
                row_details[column_headers[j]] = output_lines[i][indices[j]
                    [0]:indices[j][1]].rstrip()
            python_list.append(row_details)
        elif output == 'list':
            row_list = []
            for j in range(len(column_headers)):
                row_list.append(output_lines[i][indices[j][0]:indices[j][1]]
                    ).rstrip()
            python_list.append(row_list)
        elif output == 'csv':
            csv_string += '\n'
            for j in range(len(column_headers)):
                if j:
                    csv_string += ','
                csv_string += output_lines[i][indices[j][0]:indices[j][1]
                    ].rstrip()
    if csv_string:
        return csv_string
    return python_list


def _is_cmake_configure_argument(arg):
    """Return True if ``arg`` is a relevant argument to pass to cmake when configuring a project."""
    for cmake_arg in ('-C', '-D'):
        if arg.startswith(cmake_arg):
            return True
    return False


@staticmethod
def get_compatable_connection_types():
    """
        This is needed so the build system knows which
        connection types this connection is compatable.
        return::['str'] A list of the compatable socket types.
        """
    return []


def count_query_results(query, endpoint):
    """
    Returns the total number of results that query 'query' will generate
    WARNING: This is too expensive just for providing a number of result pages
             Providing a dummy count for now
    """
    return 1000


def view_all(use_all_regions: bool=False, center: bool=False):
    """View all objects in scene

    :param use_all_regions: All Regions, View selected for all regions
    :type use_all_regions: bool
    :param center: Center
    :type center: bool
    """
    pass


def set_default_parameters(param, default, **kwargs):
    """
    >>> param = {'width': '320', 'test': '1'}
    >>> default = {'width': '640', 'height': '360', 'test': '0', 'p': None}
    >>> set_default_parameters(param, default, test='2')
    >>> sorted(param.items())
    [('height', '360'), ('test', '2'), ('width', '320')]
    """
    for key, value in default.items():
        if param.get(key) is None:
            if value is not None:
                param[key] = value
    if kwargs:
        for key, value in kwargs.items():
            param[key] = value


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


@staticmethod
def _escape(value):
    """Escape a string (key or value) for InfluxDB's line protocol.

        :param str|int|float|bool value: The value to be escaped
        :rtype: str

        """
    value = str(value)
    for char, escaped in {' ': '\\ ', ',': '\\,', '"': '"'}.items():
        value = value.replace(char, escaped)
    return value


def env_match(language: str, env: str) ->bool:
    """检测language和env是否匹配.

    Args:
        language (str): language
        env (str): env

    Returns:
        bool: 是否匹配

    """
    if language == 'Python':
        if env not in ('env', 'conda'):
            return False
        else:
            return True
    elif language in ('Javascript',):
        if env not in ('node', 'frontend', 'webpack', 'vue', 'vue-electron',
            'vue-native', 'vue-nativescript'):
            return False
        else:
            return True
    elif language in ('Golang',):
        if env not in ('gomod',):
            return False
        else:
            return True
    else:
        raise AttributeError(f'unknown language {language}')


def unpad(bytestring, k=16):
    """
    Remove the PKCS#7 padding from a text bytestring.
    """
    val = bytestring[-1]
    if val > k:
        raise ValueError('Input is not padded or padding is corrupt')
    l = len(bytestring) - val
    return bytestring[:l]


@staticmethod
def flatten_mi_row_df(dfmi):
    """
        create flattend dataframe
        multi index row added as regular column
        """
    df = dfmi.reset_index()
    return df


def _import_string(names):
    """return a list of (name, asname) formatted as a string"""
    _names = []
    for name, asname in names:
        if asname is not None:
            _names.append('%s as %s' % (name, asname))
        else:
            _names.append(name)
    return ', '.join(_names)


@classmethod
def to_int(cls, bound_str):
    """
        Encode a string as an int for serialization.
        """
    return cls._bound_str_to_int_map[bound_str.upper()]


@staticmethod
def _check_triangles(triangles, point_length):
    """
        Verifies that the triangles are valid.

        Args:
            triangles (iterable): Array of the triangles
            point_length (int): Count of all points
        """
    if len(triangles) % 3 != 0:
        raise ValueError(
            '"triangles" must be a list of point indexes divisible by 3 defining each triangle.'
            )
    max_triangles = max(triangles)
    if max_triangles > point_length - 1:
        raise ValueError('point in triangles is out of range: {}'.format(
            max_triangles))
    min_triangles = min(triangles)
    if min_triangles < 0:
        raise ValueError('point in triangles is out of range: {}'.format(
            min_triangles))


def _mult_gf2(f1, f2):
    """Multiply two polynomials in GF(2)"""
    if f2 > f1:
        f1, f2 = f2, f1
    z = 0
    while f2:
        if f2 & 1:
            z ^= f1
        f1 <<= 1
        f2 >>= 1
    return z


@classmethod
def make(cls, baseCode, parameterNr=0):
    """baseCode -> The error code base.
		parameterNr -> The number of the parameter that caused
		the error. Starting at 1.
		"""
    return baseCode & 61695 | parameterNr << 8 & 3840


def make_grpc_unary_method(channel, service_name, method_descriptor,
    symbol_database_instance):
    """Make grp callable on the channel.

    Args:
        channel: grpc channel
        service_name: name of service
        method_descriptor: method descriptor
        symbol_database_instance: symbol db instance
    """
    input_prototype = symbol_database_instance.GetPrototype(method_descriptor
        .input_type)
    output_prototype = symbol_database_instance.GetPrototype(method_descriptor
        .output_type)
    method = channel.unary_unary('/{}/{}'.format(service_name,
        method_descriptor.name), request_serializer=input_prototype.
        SerializeToString, response_deserializer=output_prototype.FromString)
    return method


def type_to_string(arrow_type):
    """ Convert an Arrow type (possibly nested) in a string """
    pass


def describe_vpc_attribute(DryRun=None, VpcId=None, Attribute=None):
    """
    Describes the specified attribute of the specified VPC. You can specify only one attribute at a time.
    See also: AWS API Documentation

    Examples
    This example describes the enableDnsSupport attribute. This attribute indicates whether DNS resolution is enabled for the VPC. If this attribute is true, the Amazon DNS server resolves DNS hostnames for your instances to their corresponding IP addresses; otherwise, it does not.
    Expected Output:
    This example describes the enableDnsHostnames attribute. This attribute indicates whether the instances launched in the VPC get DNS hostnames. If this attribute is true, instances in the VPC get DNS hostnames; otherwise, they do not.
    Expected Output:

    :example: response = client.describe_vpc_attribute(
        DryRun=True|False,
        VpcId='string',
        Attribute='enableDnsSupport'|'enableDnsHostnames'
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type VpcId: string
    :param VpcId: [REQUIRED]
            The ID of the VPC.

    :type Attribute: string
    :param Attribute: [REQUIRED]
            The VPC attribute.

    :rtype: dict
    :return: {
        'VpcId': 'string',
        'EnableDnsSupport': {
            'Value': True|False
        },
        'EnableDnsHostnames': {
            'Value': True|False
        }
    }

    """
    pass


def is_dataframe(d):
    """
    is_dataframe(d) yields True if d is a pandas DataFrame object and False otherwise; if
      pandas cannot be loaded, this yields None.
    """
    try:
        import pandas
    except Exception:
        return None
    return isinstance(d, pandas.DataFrame)


@staticmethod
def try_parse(data):
    """Try to parse the given input text.

        Will return a list of parsed Inputs. The list might be empty (but not
        null).

        :param    data    str:    The input data received from LCN-PCHK

        :return:            The parsed Inputs (never null)
        :rtype:             List with instances of :class:`~pypck.input.Input`
        """
    raise NotImplementedError


def input_integers(message):
    """Handle inputs if they are supposed to be integers"""
    while True:
        answer = input(message)
        try:
            answer_int = int(answer)
            return answer_int
        except ValueError:
            if answer.casefold() == 'none':
                return None
            else:
                print('Please enter an integer')


def cache_request_user(user_cls, request, user_id):
    """ Helper function to cache currently logged in user.

    User is cached at `request._user`. Caching happens only only
    if user is not already cached or if cached user's pk does not
    match `user_id`.

    :param user_cls: User model class to use for user lookup.
    :param request: Pyramid Request instance.
    :user_id: Current user primary key field value.
    """
    pk_field = user_cls.pk_field()
    user = getattr(request, '_user', None)
    if user is None or getattr(user, pk_field, None) != user_id:
        request._user = user_cls.get_item(**{pk_field: user_id})


@classmethod
def label_home(cls, x, y):
    """Sets the origin for an entire label."""
    return cls(cls.LABEL_HOME, x, y)


@classmethod
def revoke(cls, user, database):
    """Query to revoke user access to a database."""
    return 'REVOKE ALL ON DATABASE "{database}" FROM "{user}"'.format(database
        =database, user=user)


def align(offset, alignment):
    """
    Return the offset aligned to the nearest greater given alignment
    Arguments:
    - `offset`: An integer
    - `alignment`: An integer
    """
    if offset % alignment == 0:
        return offset
    return offset + (alignment - offset % alignment)


def translate_condition_key_data_types(condition_str):
    """
    The docs use different type names, so this standardizes them.
    Example: The condition secretsmanager:RecoveryWindowInDays is listed as using a "Long"
    So return "Number"
    """
    if condition_str.lower() in ['arn', 'arn']:
        return 'Arn'
    elif condition_str.lower() in ['bool', 'boolean']:
        return 'Bool'
    elif condition_str.lower() in ['date']:
        return 'Date'
    elif condition_str.lower() in ['long', 'numeric']:
        return 'Number'
    elif condition_str.lower() in ['string', 'string', 'arrayofstring']:
        return 'String'
    elif condition_str.lower() in ['ip']:
        return 'Ip'
    else:
        raise Exception('Unknown data format: {}'.format(str))


def __getattribute__(name):
    """Return the value of the attribute with the specified name.

        If an attribute is not found or is None, the next higher up Locale
        object is consulted."""


def asunicode(s):
    """Force a string to be a unicode instance.

    :param s: any value
    :rtype: str

    If `s` is not already an unicode string, it is assumed it's
    an ``utf-8`` encoded string, a thus converted to unicode and
    returned. Otherwise `s` is returned as is::

      >>> assert asunicode(None) is None
      >>> assert not isinstance(asunicode(b'ascii'), bytes)
    """
    if s is None:
        return None
    elif isinstance(s, bytes):
        return s.decode('utf-8')
    else:
        return str(s)


def get_sample_rate(matData):
    """Returns the sample rate for the data."""
    if 'ActualRate' in matData.keys():
        sampleRate = matData['ActualRate']
    else:
        sampleRate = matData['sampleRate']
    return sampleRate


def unsafe(f):
    """Marks a function or method as unsafe.

    ::

        @unsafe
        def delete(self):
            pass
    """
    f.unsafe_callable = True
    return f


def InstallVirtualEnv():
    """Installs the virtualenv package if it is not already installed."""
    import pip
    pip.main(['install', 'virtualenv'])


@classmethod
def InitAnsiSequenceStreams(cls):
    """Initializes colorama"""
    if not cls.AreAnsiSequenceStreamsInitialized():
        import colorama
        colorama.init()
        cls._ansi_sequence_streams_initialized = True


def hash_iterable(it):
    """Perform a O(1) memory hash of an iterable of arbitrary length.

	hash(tuple(it)) creates a temporary tuple containing all values from it
	which could be a problem if it is large.

	See discussion at:
	https://groups.google.com/forum/#!msg/python-ideas/XcuC01a8SYs/e-doB9TbDwAJ
	"""
    hash_value = hash(type(it))
    for value in it:
        hash_value = hash((hash_value, value))
    return hash_value


def isfloat(value):
    """ Return True if all characters are part of a floating point value """
    try:
        float(value)
        return True
    except ValueError:
        return False


def transReadsIter(bamfile, trans, compatible=True, mis=0, sense=True,
    maxNH=None, minMapQ=None, secondary=False, paired=False, flank=0):
    """fetch reads from transcript exons
  """
    chr = bamfile.get_chrname(trans.chr)
    if chr is None:
        return
    if compatible:
        from . import interval
        transitv = interval.trans2interval(trans)
    if flank < 0:
        flank = 0
    used = {}
    for e in trans.exons:
        start, stop = e.start, e.stop
        if flank > 0:
            if start == trans.start:
                start -= flank
                if start < 1:
                    start = 1
            if stop == trans.stop:
                stop += flank
        rds = bamfile.fetch_reads(chr=chr, start=start, stop=stop, maxNH=
            maxNH, minMapQ=minMapQ, secondary=secondary, paired=paired)
        for read in rds:
            if (read.id, read.fragment_start) in used:
                continue
            if sense and read.strand != trans.strand:
                continue
            if read.fragment_start <= e.start or read.fragment_stop >= e.stop:
                used[read.id, read.fragment_start] = 1
            if compatible and not read.isCompatible(transitv=transitv, mis=mis
                ):
                continue
            yield read


def lastTransaction():
    """Return the id of the last committed transaction.

        If no transactions have been committed, return a string of 8
        null (0) characters.
        """


def _determine_levels(index):
    """Determine the correct levels argument to groupby.
    """
    if isinstance(index, (tuple, list)) and len(index) > 1:
        return list(range(len(index)))
    else:
        return 0


def broadcast_equal(lhs=None, rhs=None, name=None, attr=None, out=None, **
    kwargs):
    """Returns the result of element-wise **equal to** (==) comparison operation with broadcasting.

    Example::

       x = [[ 1.,  1.,  1.],
            [ 1.,  1.,  1.]]

       y = [[ 0.],
            [ 1.]]

       broadcast_equal(x, y) = [[ 0.,  0.,  0.],
                                [ 1.,  1.,  1.]]

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_logic.cc:L46

    Parameters
    ----------
    lhs : Symbol
        First input to the function
    rhs : Symbol
        Second input to the function

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

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


def Crop(*data, **kwargs):
    """

    .. note:: `Crop` is deprecated. Use `slice` instead.

    Crop the 2nd and 3rd dim of input data, with the corresponding size of h_w or
    with width and height of the second input symbol, i.e., with one input, we need h_w to
    specify the crop height and width, otherwise the second input symbol's size will be used

    Defined in src/operator/crop.cc:L50
    This function support variable length of positional input.

    Parameters
    ----------
    data : Symbol or Symbol[]
        Tensor or List of Tensors, the second input will be used as crop_like shape reference
    offset : Shape(tuple), optional, default=[0,0]
        crop offset coordinate: (y, x)
    h_w : Shape(tuple), optional, default=[0,0]
        crop height and width: (h, w)
    center_crop : boolean, optional, default=0
        If set to true, then it will use be the center_crop,or it will crop using the shape of crop_like

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

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


def iter_stable_unique(iterable):
    """Given a sequence, yield unique items while preserving ordering.

    For performance reasons, only use this if you really do need to preserve
    the ordering.
    """
    s = set()
    sadd = s.add
    sl = []
    slappend = sl.append
    iterable = iter(iterable)
    while True:
        try:
            for x in iterable:
                if x not in s:
                    yield x
                    sadd(x)
        except TypeError:
            if x not in sl:
                yield x
                slappend(x)
            continue
        break


def bits_count(int_tp):
    """counts all bits set to 1 in int_tp

    :Example:
        >>> bits_count(1234567)
        11
    """
    return bin(int_tp).count('1')


def cosh(data=None, out=None, name=None, **kwargs):
    """Returns the hyperbolic cosine  of the input array, computed element-wise.

    .. math::
       cosh(x) = 0.5\\times(exp(x) + exp(-x))

    The storage type of ``cosh`` output is always dense

    Defined in src/operator/tensor/elemwise_unary_op_trig.cc:L351

    Parameters
    ----------
    data : NDArray
        The input array.

    out : NDArray, optional
        The output NDArray to hold the result.

    Returns
    -------
    out : NDArray or list of NDArrays
        The output of this function.
    """
    return 0,


def rreplace(string, old, new, occurrence):
    """A version of the str.replace() method which works from the right.
    Taken from https://stackoverflow.com/questions/2556108/
    """
    elems = string.rsplit(old, occurrence)
    return new.join(elems)


@classmethod
def getattr(cls, obj, name, default=object):
    """
		Return the attribute ``name`` of the object :obj`obj` and honor
		``ul4getattr`` and ``ul4attrs``.
		"""
    ul4getattr = getattr(obj, 'ul4getattr', None)
    if ul4getattr is not None:
        try:
            return ul4getattr(name)
        except AttributeError:
            return cls.missing(obj, name, default)
    else:
        ul4attrs = getattr(obj, 'ul4attrs', None)
        if ul4attrs is not None and name in ul4attrs:
            return getattr(obj, name)
        elif name in cls.plainattrs:
            return getattr(obj, name)
        elif name in cls.wrappeddataattrs:
            return getattr(cls, name)(obj)
        elif name in cls.wrappedmethattrs:
            return cls.wrapmethod(obj, name)
        return cls.missing(obj, name, default)


def __setattr__(cls, name, value):
    """Block attempts to reassign Enum members.

        A simple assignment to the class namespace only changes one of the
        several possible ways to get an Enum member from the Enum class,
        resulting in an inconsistent Enumeration.

        """
    member_map = cls.__dict__.get('_member_map_', {})
    if name in member_map:
        raise AttributeError('Cannot reassign members.')
    super().__setattr__(name, value)


def _dict(obj):
    """Work with obj.__dict__ or obj if it doesn't have one (it should be one).
    This lets us pass in regular objects or their dicts (like f_locals).
    """
    return getattr(obj, '__dict__', obj)


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

        :param str val:
        :rtype: AddSecondaryEmailResult
        """
    return cls('reached_limit', val)


def lod_remove(index: int=1):
    """Remove a level of detail from this object

    :param index: Index
    :type index: int
    """
    pass


def text_to_lowercase(text):
    """Set all letters to lowercase"""
    return text.lower()


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


def get_tables():
    """Returns a C{list} of domain classes

        This should return a C{list} of tuples, each one containing the
        domain path as the first item, and a list of classes as
        the second. e.g. A 'from a.b import C, D' should be
        translated into the C{tuple} ('a.b', ['C', 'D']).
        @note: this information is used for database synchronization

        :returns: a C{list} of C{tuple} containing domain info
        """
    pass


def remove_text_if_not_tick(tick_values, text_values):
    """
    removes text so that no text is in place where not ticks
    """
    for text_value in text_values:
        if tick_values.count(text_value) == 0:
            text_values.remove(text_value)


def select_linked_pick(deselect: bool=False):
    """(De)select all points linked to the curve under the mouse cursor

    :param deselect: Deselect
    :type deselect: bool
    """
    pass


def _velocity_factor(velocity_units_in, velocity_units_out):
    """helper method for convert_velocity"""
    factor = 1.0
    if velocity_units_in == 'm/s':
        factor /= 0.3048
    elif velocity_units_in == 'ft/s':
        pass
    elif velocity_units_in == 'in/s':
        factor /= 12.0
    elif velocity_units_in == 'knots':
        factor *= 1.68781
    else:
        msg = ('velocity_units_in=%r is not valid; use [ft/s, m/s, knots]' %
            velocity_units_in)
        raise RuntimeError(msg)
    if velocity_units_out == 'm/s':
        factor *= 0.3048
    elif velocity_units_out == 'ft/s':
        pass
    elif velocity_units_out == 'in/s':
        factor *= 12.0
    elif velocity_units_out == 'knots':
        factor /= 1.68781
    else:
        msg = (
            'velocity_units_out=%r is not valid; use [ft/s, m/s, in/s, knots]'
             % velocity_units_out)
        raise RuntimeError(msg)
    return factor


@staticmethod
def signers_init(n_signers):
    """Initialize the parties in the MuSig session and set their index number."""
    signers = []
    for i in range(n_signers):
        signers.append({'index': i, 'present': 0})
    return signers


def _has_instance(cls):
    """
        gets a value indicating that there is a registered instance.

        :rtype: bool
        """
    return str(cls) in cls._instances


@classmethod
def default_penalty(cls):
    """Implement :meth:`~.solver.Solver.default_penalty`."""
    return 1.0


def common_prefix_length(seq_a, seq_b):
    """
    Return the length of the common prefix between two sequences.

    Parameters
    ----------
    seq_a : iter
        An iterable holding the first sequence.
    seq_b : iter
        An iterable holding the second sequence.

    Returns
    -------
    length: int
        The length of the common prefix between `seq_a` and `seq_b`.

    Examples
    --------

    >>> import dafsa
    >>> dafsa.utils.common_prefix_length("abcde", "abcDE")
    3
    >>> dafsa.utils.common_prefix_length("abcde", "ABCDE")
    0
    """
    common_prefix_len = 0
    for i in range(min(len(seq_a), len(seq_b))):
        if seq_a[i] != seq_b[i]:
            break
        common_prefix_len += 1
    return common_prefix_len


def set_nvidia_environment_variables(environment, gpu_ids):
    """
    Updates a dictionary containing environment variables to setup Nvidia-GPUs.

    :param environment: The environment variables to update
    :param gpu_ids: A list of GPU ids
    """
    if gpu_ids:
        nvidia_visible_devices = ','.join(map(str, gpu_ids))
        environment['NVIDIA_VISIBLE_DEVICES'] = nvidia_visible_devices


def process_string_for_escapes(string_or_char_list, escape_char, open_group
    =None, close_group=None):
    """A utility routine which takes a string or character list with
    possibly-escaped elements as an argument and returns a list of two-tuples.

    The first element of a returned two-tuple is the actual character, and the
    second a boolean for whether or not it is escaped.

    If `open_group` and/or `close_group` is set to an opening or closing paren
    or bracket character the function returns a list of three-tuples, where the
    last element gives the level of parenthesis nesting, starting at zero and
    increasing.  An open and its corresponding close have the same level."""
    escaped = False
    tuple_list = []
    p_count = 0
    for elem in string_or_char_list:
        if elem == escape_char and not escaped:
            escaped = True
            continue
        if escaped:
            bool_val = True
            if open_group and elem == open_group:
                p_count += 1
        else:
            bool_val = False
        if open_group or close_group:
            tuple_list.append((elem, bool_val, p_count))
        else:
            tuple_list.append((elem, bool_val))
        if escaped:
            escaped = False
            if close_group and elem == close_group:
                p_count -= 1
    return tuple_list


def interleave(joiner, iterable):
    """
    Similar to `str.join` but for lists.

    >>> interleave([1], [2, 3, 4])
    [2, 1, 3, 1, 4]
    """
    try:
        yield next(iterable)
    except StopIteration:
        return
    for item in iterable:
        yield joiner
        yield item


def view_ndof():
    """Use a 3D mouse device to pan/zoom the view

    """
    pass


@staticmethod
def apache(connection, config):
    """
        1. Remove default nginx config file
        2. Create new config file
        3. Copy local config to remote config
        4. Setup new symbolic link
        """
    pass


def get_data():
    """
    Function for extracting a dictionary with the distances (pc) and apparent magnitudes of
    directly imaged planets and brown dwarfs.

    Returns
    -------
    dict
        Dictionary with the distances and apparent magnitudes of directly imaged companions.
        Distances are from GAIA DR2 unless indicated as comment.
    """
    data = {'beta Pic b': {'distance': (19.75, 0.13), 'app_mag': {
        'LCO/VisAO.Ys': (15.53, 0.34), 'Paranal/NACO.J': (14.11, 0.21),
        'Gemini/NICI.ED286': (13.18, 0.15), 'Paranal/NACO.H': (13.32, 0.14),
        'Paranal/NACO.Ks': (12.64, 0.11), 'Paranal/NACO.NB374': (11.25,
        0.23), 'Paranal/NACO.Lp': (11.3, 0.06), 'Paranal/NACO.NB405': (
        10.98, 0.05), 'Paranal/NACO.Mp': (11.1, 0.12)}}, 'HIP 65426 b': {
        'distance': (109.21, 0.75), 'app_mag': {
        'Paranal/SPHERE.IRDIS_D_H23_2': (17.94, 0.05),
        'Paranal/SPHERE.IRDIS_D_H23_3': (17.58, 0.06),
        'Paranal/SPHERE.IRDIS_D_K12_1': (17.01, 0.09),
        'Paranal/SPHERE.IRDIS_D_K12_2': (16.79, 0.09), 'Paranal/NACO.Lp': (
        15.33, 0.12), 'Paranal/NACO.NB405': (15.23, 0.22),
        'Paranal/NACO.Mp': (14.65, 0.29)}}, '51 Eri b': {'distance': (29.78,
        0.12), 'app_mag': {'MKO/NSFCam.J': (19.04, 0.4), 'MKO/NSFCam.H': (
        18.99, 0.21), 'MKO/NSFCam.K': (18.67, 0.19),
        'Paranal/SPHERE.IRDIS_D_H23_2': (18.41, 0.26),
        'Paranal/SPHERE.IRDIS_D_K12_1': (17.55, 0.14), 'Keck/NIRC2.Lp': (
        16.2, 0.11), 'Keck/NIRC2.Ms': (16.1, 0.5)}}, 'HR 8799 b': {
        'distance': (41.29, 0.15), 'app_mag': {'Subaru/CIAO.z': (21.22,
        0.29), 'Paranal/SPHERE.IRDIS_B_J': (19.78, 0.09), 'Keck/NIRC2.H': (
        18.05, 0.09), 'Paranal/SPHERE.IRDIS_D_H23_2': (18.08, 0.14),
        'Paranal/SPHERE.IRDIS_D_H23_3': (17.78, 0.1), 'Keck/NIRC2.Ks': (
        17.03, 0.08), 'Paranal/SPHERE.IRDIS_D_K12_1': (17.15, 0.06),
        'Paranal/SPHERE.IRDIS_D_K12_2': (16.97, 0.09), 'Paranal/NACO.Lp': (
        15.52, 0.1), 'Paranal/NACO.NB405': (14.82, 0.18), 'Keck/NIRC2.Ms':
        (16.05, 0.3)}}, 'HR 8799 c': {'distance': (41.29, 0.15), 'app_mag':
        {'Paranal/SPHERE.IRDIS_B_J': (18.6, 0.13), 'Keck/NIRC2.H': (17.06,
        0.13), 'Paranal/SPHERE.IRDIS_D_H23_2': (17.09, 0.12),
        'Paranal/SPHERE.IRDIS_D_H23_3': (16.78, 0.1), 'Keck/NIRC2.Ks': (
        16.11, 0.08), 'Paranal/SPHERE.IRDIS_D_K12_1': (16.19, 0.05),
        'Paranal/SPHERE.IRDIS_D_K12_2': (15.86, 0.07), 'Paranal/NACO.Lp': (
        14.65, 0.11), 'Paranal/NACO.NB405': (13.97, 0.11), 'Keck/NIRC2.Ms':
        (15.03, 0.14)}}, 'HR 8799 d': {'distance': (41.29, 0.15), 'app_mag':
        {'Paranal/SPHERE.IRDIS_B_J': (18.59, 0.37), 'Keck/NIRC2.H': (16.71,
        0.24), 'Paranal/SPHERE.IRDIS_D_H23_2': (17.02, 0.17),
        'Paranal/SPHERE.IRDIS_D_H23_3': (16.85, 0.16), 'Keck/NIRC2.Ks': (
        16.09, 0.12), 'Paranal/SPHERE.IRDIS_D_K12_1': (16.2, 0.07),
        'Paranal/SPHERE.IRDIS_D_K12_2': (15.84, 0.1), 'Paranal/NACO.Lp': (
        14.55, 0.14), 'Paranal/NACO.NB405': (13.87, 0.15), 'Keck/NIRC2.Ms':
        (14.65, 0.35)}}, 'HR 8799 e': {'distance': (41.29, 0.15), 'app_mag':
        {'Paranal/SPHERE.IRDIS_B_J': (18.4, 0.21),
        'Paranal/SPHERE.IRDIS_D_H23_2': (16.91, 0.2),
        'Paranal/SPHERE.IRDIS_D_H23_3': (16.68, 0.21), 'Keck/NIRC2.Ks': (
        15.91, 0.22), 'Paranal/SPHERE.IRDIS_D_K12_1': (16.12, 0.1),
        'Paranal/SPHERE.IRDIS_D_K12_2': (15.82, 0.11), 'Paranal/NACO.Lp': (
        14.49, 0.21), 'Paranal/NACO.NB405': (13.72, 0.2)}}, 'HD 95086 b': {
        'distance': (86.44, 0.24), 'app_mag': {'Gemini/GPI.H': (20.51, 0.25
        ), 'Gemini/GPI.K1': (18.99, 0.2), 'Paranal/NACO.Lp': (16.27, 0.19)}
        }, 'PDS 70 b': {'distance': (113.43, 0.52), 'app_mag': {
        'Paranal/SPHERE.IRDIS_D_H23_2': (17.94, 0.24),
        'Paranal/SPHERE.IRDIS_D_H23_3': (17.95, 0.17),
        'Paranal/SPHERE.IRDIS_D_K12_1': (16.65, 0.06),
        'Paranal/SPHERE.IRDIS_D_K12_2': (16.44, 0.05), 'Paranal/NACO.Lp': (
        14.08, 0.33), 'Paranal/NACO.NB405': (13.91, 0.34),
        'Paranal/NACO.Mp': (13.64, 0.22)}}, 'PDS 70 c': {'distance': (
        113.43, 0.52), 'app_mag': {'Paranal/NACO.NB405': (15.05, 0.59)}},
        '2M1207 b': {'distance': (64.42, 0.65), 'app_mag': {
        'HST/NICMOS1.F090M': (22.58, 0.35), 'HST/NICMOS1.F110M': (20.61,
        0.15), 'HST/NICMOS1.F145M': (19.05, 0.03), 'HST/NICMOS1.F160W': (
        18.27, 0.02), 'Paranal/NACO.J': (20.0, 0.2), 'Paranal/NACO.H': (
        18.09, 0.21), 'Paranal/NACO.Ks': (16.93, 0.11), 'Paranal/NACO.Lp':
        (15.28, 0.14)}}, 'AB Pic B': {'distance': (50.12, 0.07), 'app_mag':
        {'Paranal/NACO.J': (16.18, 0.1), 'Paranal/NACO.H': (14.69, 0.1),
        'Paranal/NACO.Ks': (14.14, 0.08)}}, 'HD 206893 B': {'distance': (
        40.81, 0.11), 'app_mag': {'Paranal/SPHERE.IRDIS_B_H': (16.79, 0.06),
        'Paranal/SPHERE.IRDIS_D_K12_1': (15.2, 0.1),
        'Paranal/SPHERE.IRDIS_D_K12_2': (14.88, 0.09), 'Paranal/NACO.Lp': (
        13.79, 0.31), 'Paranal/NACO.NB405': (13.16, 0.34),
        'Paranal/NACO.Mp': (12.77, 0.27)}}, 'GQ Lup B': {'distance': (
        151.82, 1.1), 'app_mag': {'HST/WFPC2.f606w': (19.19, 0.07),
        'HST/WFPC2.f814w': (17.67, 0.05), 'HST/NICMOS2.F171M': (13.84, 0.13
        ), 'HST/NICMOS2.F190N': (14.08, 0.2), 'HST/NICMOS2.F215N': (13.4,
        0.15), 'Subaru/CIAO.CH4s': (13.76, 0.26), 'Subaru/CIAO.K': (13.37,
        0.12), 'Subaru/CIAO.Lp': (12.44, 0.22)}}, 'PZ Tel B': {'distance':
        (47.13, 0.13), 'app_mag': {'Paranal/SPHERE.ZIMPOL_R_PRIM': (17.84,
        0.31), 'Paranal/SPHERE.ZIMPOL_I_PRIM': (15.16, 0.12),
        'Paranal/SPHERE.IRDIS_D_H23_2': (11.78, 0.19),
        'Paranal/SPHERE.IRDIS_D_H23_3': (11.65, 0.19),
        'Paranal/SPHERE.IRDIS_D_K12_1': (11.56, 0.09),
        'Paranal/SPHERE.IRDIS_D_K12_2': (11.29, 0.1), 'Paranal/NACO.J': (
        12.47, 0.2), 'Paranal/NACO.H': (11.93, 0.14), 'Paranal/NACO.Ks': (
        11.53, 0.07), 'Paranal/NACO.Lp': (11.04, 0.22),
        'Paranal/NACO.NB405': (10.94, 0.07), 'Paranal/NACO.Mp': (10.93,
        0.03), 'Gemini/NICI.ED286': (11.68, 0.14),
        'Gemini/NIRI.H2S1v2-1-G0220': (11.39, 0.14)}}, 'kappa And b': {
        'distance': (50.06, 0.87), 'app_mag': {'Subaru/CIAO.J': (15.86,
        0.21), 'Subaru/CIAO.H': (14.95, 0.13), 'Subaru/CIAO.Ks': (14.32,
        0.09), 'Keck/NIRC2.Lp': (13.12, 0.1), 'Keck/NIRC2.NB_4.05': (13.0,
        0.2), 'LBT/LMIRCam.M_77K': (13.3, 0.3)}}, 'ROXs 42 Bb': {'distance':
        (144.16, 1.54), 'app_mag': {'Keck/NIRC2.J': (16.91, 0.11),
        'Keck/NIRC2.H': (15.88, 0.05), 'Keck/NIRC2.Ks': (15.01, 0.06),
        'Keck/NIRC2.Lp': (13.97, 0.06), 'Keck/NIRC2.NB_4.05': (13.9, 0.08),
        'Keck/NIRC2.Ms': (14.01, 0.23)}}, 'GJ 504 b': {'distance': (17.54,
        0.08), 'app_mag': {'Paranal/SPHERE.IRDIS_D_Y23_2': (20.98, 0.2),
        'Paranal/SPHERE.IRDIS_D_Y23_3': (20.14, 0.09),
        'Paranal/SPHERE.IRDIS_D_J23_3': (19.01, 0.17),
        'Paranal/SPHERE.IRDIS_D_H23_2': (18.95, 0.3),
        'Paranal/SPHERE.IRDIS_D_H23_3': (21.81, 0.35),
        'Paranal/SPHERE.IRDIS_D_K12_1': (18.77, 0.2), 'Subaru/CIAO.J': (
        19.78, 0.1), 'Subaru/CIAO.H': (20.01, 0.14), 'Subaru/CIAO.Ks': (
        19.38, 0.11), 'Subaru/CIAO.CH4s': (19.58, 0.13), 'Subaru/IRCS.Lp':
        (16.7, 0.17)}}, 'GU Psc b': {'distance': (47.61, 0.16), 'app_mag':
        {'Gemini/GMOS-S.z': (21.75, 0.07), 'CFHT/Wircam.Y': (19.4, 0.05),
        'CFHT/Wircam.J': (18.12, 0.03), 'CFHT/Wircam.H': (17.7, 0.03),
        'CFHT/Wircam.Ks': (17.4, 0.03), 'WISE/WISE.W1': (17.17, 0.33),
        'WISE/WISE.W2': (15.41, 0.22)}}, '2M0103 ABb': {'distance': (47.2,
        3.1), 'app_mag': {'Paranal/NACO.J': (15.47, 0.3), 'Paranal/NACO.H':
        (14.27, 0.2), 'Paranal/NACO.Ks': (13.67, 0.2), 'Paranal/NACO.Lp': (
        12.67, 0.1)}}, '1RXS 1609 B': {'distance': (139.67, 1.33),
        'app_mag': {'Gemini/NIRI.J-G0202w': (17.9, 0.12),
        'Gemini/NIRI.H-G0203w': (16.87, 0.07), 'Gemini/NIRI.K-G0204w': (
        16.17, 0.18), 'Gemini/NIRI.Lprime-G0207w': (14.8, 0.3)}},
        'GSC 06214 B': {'distance': (108.84, 0.51), 'app_mag': {
        'MKO/NSFCam.J': (16.24, 0.04), 'MKO/NSFCam.H': (15.55, 0.04),
        'MKO/NSFCam.Kp': (14.95, 0.05), 'MKO/NSFCam.Lp': (13.75, 0.07),
        'LBT/LMIRCam.M_77K': (13.75, 0.3)}}, 'HD 72946 B': {'distance': (
        25.87, 0.03), 'app_mag': {'Paranal/SPHERE.IRDIS_D_H23_2': (14.56,
        0.07), 'Paranal/SPHERE.IRDIS_D_H23_3': (14.4, 0.07)}}}
    return data


def _preprocess_dims(dim):
    """Preprocesses dimensions to prep for stacking.

    Parameters
    ----------
    dim : str, list
        The dimension(s) to apply the function along.
    """
    if isinstance(dim, str):
        dim = [dim]
    axis = tuple(range(-1, -len(dim) - 1, -1))
    return dim, axis


def current_service(request):
    """Return the Cornice service matching the specified request.

    :returns: the service or None if unmatched.
    :rtype: cornice.Service
    """
    if request.matched_route:
        services = request.registry.cornice_services
        pattern = request.matched_route.pattern
        try:
            service = services[pattern]
        except KeyError:
            return None
        else:
            return service


def get_task_flow_id_pair(tb_client, project_id):
    """
    获取 teambition 交易管理项目的 状态列表 的 name id pair
    :param project_id: 项目 id
    :param tb_client:
    :return:
    """
    task_flows = tb_client.get_project_scenariofieldconfigs(project_id)
    name_id_pair = dict()
    id_name_pair = dict()
    name_kind_pair = dict()
    id_kind_pair = dict()
    for status in task_flows[0]['taskflowstatuses']:
        name_id_pair[status['name']] = status['_id']
        id_name_pair[status['_id']] = status['name']
        name_kind_pair[status['name']] = status['kind']
        id_kind_pair[status['_id']] = status['kind']
    scenario_field_config_id = task_flows[0]['_id']
    return {'scenario_field_config_id': scenario_field_config_id,
        'task_flow_id_pair': name_id_pair, 'id_task_flow_pair':
        id_name_pair, 'task_flow_kind_pair': name_kind_pair, 'id_kind_pair':
        id_kind_pair}


@classmethod
def parse_options(cls, options):
    """Extracts subdomain and endpoint values from the options dict and returns
           them along with a new dict without those values.
        """
    options = options.copy()
    subdomain = options.pop('subdomain', None)
    endpoint = options.pop('endpoint', None)
    return subdomain, endpoint, options


def commit():
    """Commit the transaction
        """


def get_results_for_storage_index(storage_index):
    """Retrive the ICheckAndRepairResults instance for the given (binary)
        storage index. Raises KeyError if there are no results for that
        storage index."""


def viewletmanager(manager):
    """Define on which viewlet manager a viewlet is registered.
        """


def get_row_history(row: 'md_table.Table'
    ) ->'typing.Dict[md_column.Column, typing.Dict[str, typing.Any]]':
    """
    Gets the history for the specified row.

    This returns a dict, indexed by Column, with values being another dict with `old` and `new` keys
    that represent the old and new values of the item.
    """
    d = {}
    for column in row.table.iter_columns():
        old_value = row.get_old_value(column)
        new_value = row.get_column_value(column, return_default=False)
        d[column] = {'old': old_value, 'new': new_value}
    return d


def tosym(name):
    """Replace unsupported characters in ASN.1 symbol names"""
    return str(name).replace(' ', '').replace('-', '_')


def chunks(l, n):
    """Yield successive n-sized chunks from l.
    Source: http://stackoverflow.com/a/312464
    """
    if n > 0:
        for i in range(0, len(l), n):
            yield l[i:i + n]
    else:
        yield l


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 CheckSpin(isym, SGData):
    """ Check for exceptions in spin rules
    """
    if SGData['SGPtGrp'] in ['222', 'mm2', '2mm', 'm2m']:
        if SGData['SGSpin'][1] * SGData['SGSpin'][2] * SGData['SGSpin'][3] < 0:
            SGData['SGSpin'][(isym + 1) % 3 + 1] *= -1
        if SGData['SpGrp'][0] == 'F' and isym > 2:
            SGData['SGSpin'][(isym + 1) % 3 + 3] == 1
    elif SGData['SGPtGrp'] == 'mmm':
        if SGData['SpGrp'][0] == 'F' and isym > 2:
            SGData['SGSpin'][(isym + 1) % 3 + 3] == 1


def is_odd(n):
    """Returns True if n is odd, and False if n is even.
    Assumes integer.
    """
    return bool(n & 1)


def monkey_patch_tiles(mpltiles):
    """Add some new tiles to the mplleaflet."""
    mpltiles['norgeskart_topo4'] = (
        'http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4&zoom={z}&x={x}&y={y}'
        , 'Kartverket')
    mpltiles['norgeskart_toporaster3'] = (
        'http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=toporaster3&zoom={z}&x={x}&y={y}'
        , 'Kartverket')


@staticmethod
def list_package_dependency_versions():
    """
        Lists package dependency versions.

        ..  container:: example

            >>> abjad_configuration = abjad.AbjadConfiguration()
            >>> abjad_configuration.list_package_dependency_versions() # doctest: +SKIP
            {'sphinx': '1.1.2', 'pytest': '2.1.2'}

        Returns dictionary.
        """
    dependencies = {}
    dependencies['configobj'] = None
    try:
        import configobj
        dependencies['configobj'] = configobj.__version__
    except (AttributeError, ImportError):
        pass
    dependencies['ply'] = None
    try:
        from ply import lex
        dependencies['ply'] = lex.__version__
    except ImportError:
        pass
    dependencies['pytest'] = None
    try:
        import pytest
        dependencies['pytest'] = pytest.__version__
    except ImportError:
        pass
    dependencies['sphinx'] = None
    try:
        import sphinx
        dependencies['sphinx'] = sphinx.__version__
    except ImportError:
        pass
    return dependencies


def namespaced(obj, tagname, namespace=None):
    """
    Utility to create a namespaced tag for an object
    """
    namespace = getattr(obj, 'namespace', None) or namespace
    if namespace is not None:
        tagname = '{%s}%s' % (namespace, tagname)
    return tagname


def get_pkg_version(pkg_name):
    """ Return package version for `pkg_name` if installed

    Returns
    -------
    pkg_version : str or None
        Return None if package not importable.  Return 'unknown' if standard
        ``__version__`` string not present. Otherwise return version string.
    """
    try:
        pkg = __import__(pkg_name)
    except ImportError:
        return None
    try:
        return pkg.__version__
    except AttributeError:
        return 'unknown'


def resolve(hub, rdats):
    """
    Given the dict of requisite data sets, determine if the defined
    requisites passed. This allows for requisites to be defined
    as requiring, all, some, one, or none of the required states to
    pass
    """
    errors = []
    for req, rlist in rdats.items():
        rmap = hub.idem.RMAP[req]
        resolver = rmap.get('resolver', 'all')
        errors.extend(getattr(hub, f'idem.resolver.{resolver}.check')(rlist))
    return errors


def _find_conda_env_paths_from_conda(mgr):
    """Returns a list of path as given by `conda env list --json`.

    Returns empty list, if conda couldn't be called.
    """
    if not mgr.use_conda_directly:
        return []
    mgr.log.debug('Looking for conda environments by calling conda directly...'
        )
    import subprocess
    import json
    try:
        p = subprocess.Popen(['conda', 'env', 'list', '--json'], stdin=
            subprocess.PIPE, stdout=subprocess.PIPE)
        comm = p.communicate()
        output = comm[0].decode()
        if p.returncode != 0 or len(output) == 0:
            mgr.log.error(
                "Couldn't call 'conda' to get the environments. Output:\n%s",
                str(comm))
            return []
    except FileNotFoundError:
        mgr.log.error("'conda' not found in path.")
        return []
    output = json.loads(output)
    envs = output['envs']
    return envs


def get_col_names_and_indices(sqlite_description, ignore_gt_cols=False):
    """Return a list of column namanes and a list of the row indices.
       Optionally exclude gt_* columns.
    """
    col_indices = []
    col_names = []
    for idx, col_tup in enumerate(sqlite_description):
        col_name = col_tup[0]
        if not ignore_gt_cols or ignore_gt_cols and not col_name.startswith(
            'gt'):
            col_indices.append(idx)
            col_names.append(col_name)
    return col_names, col_indices


def list_portfolios_for_product(AcceptLanguage=None, ProductId=None,
    PageToken=None, PageSize=None):
    """
    Lists all portfolios that the specified product is associated with.
    See also: AWS API Documentation

    :example: response = client.list_portfolios_for_product(
        AcceptLanguage='string',
        ProductId='string',
        PageToken='string',
        PageSize=123
    )

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

    :type ProductId: string
    :param ProductId: [REQUIRED]
            The product identifier.

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

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

    :rtype: dict
    :return: {
        'PortfolioDetails': [
            {
                'Id': 'string',
                'ARN': 'string',
                'DisplayName': 'string',
                'Description': 'string',
                'CreatedTime': datetime(2015, 1, 1),
                'ProviderName': 'string'
            },
        ],
        'NextPageToken': 'string'
    }

    """
    pass


@staticmethod
def initialize_values(repo_details: dict) ->None:
    """
        Initializes all values that might be needed in order to avoid exceptions.
        :param repo_details: details associated with the analyzed repository.
        :return:
        """
    if 'issue_durations' not in repo_details:
        repo_details['issue_durations'] = list()
    if 'open_pull_requests' not in repo_details:
        repo_details['open_pull_requests'] = 0
    if 'open_issues' not in repo_details:
        repo_details['open_issues'] = 0


def run(hub, low, running):
    """
    Return the sequence map that should be used to execute the lowstate
    The sequence needs to identify:
    1. recursive requisites
    2. what chunks are free to run
    3. Behavior augments for the next chunk to run
    """
    ret = {}
    for ind, chunk in enumerate(low):
        tag = hub.idem.tools.gen_tag(chunk)
        if tag in running:
            continue
        ret[ind] = {'chunk': chunk, 'reqrets': [], 'unmet': set(), 'tag': tag}
        for req, data in hub.idem.RMAP.items():
            if data.get('prereq'):
                continue
            if req in chunk:
                for rdef in chunk[req]:
                    if not isinstance(rdef, dict):
                        continue
                    state = next(iter(rdef))
                    name = rdef[state]
                    r_chunks = hub.idem.tools.get_chunks(low, state, name)
                    if not r_chunks:
                        ret[ind]['errors'].append(
                            f'Requisite {req} {state}:{name} not found')
                    for r_chunk in r_chunks:
                        r_tag = hub.idem.tools.gen_tag(r_chunk)
                        if r_tag in running:
                            reqret = {'req': req, 'name': name, 'state':
                                state, 'r_tag': r_tag, 'ret': running[r_tag
                                ], 'chunk': 'r_chunk'}
                            ret[ind]['reqrets'].append(reqret)
                        else:
                            ret[ind]['unmet'].add(r_tag)
    return ret


def SortFiles(items, sorteditems, filenames):
    """
    Sort files in alphabetical order.

    :param `sorteditems`: a list of :class:`Thumb` objects;
    :param `filenames`: a list of image filenames.
    """
    newfiles = []
    for item in sorteditems:
        newfiles.append(filenames[items.index(item)])
    return newfiles


def get_action_with_highest_probability(probabilities):
    """
    Choose the action which should be taken in the end
    :param probabilities:
    :return:
    """
    return [int(probabilities.argmax())]


def edge_split():
    """Split selected edges so that each neighbor face gets its own copy

    """
    pass


def _improve_answer_span(doc_tokens, input_start, input_end, tokenizer,
    orig_answer_text):
    """Returns tokenized answer spans that better match the annotated answer."""
    tok_answer_text = ' '.join(tokenizer.tokenize(orig_answer_text))
    for new_start in range(input_start, input_end + 1):
        for new_end in range(input_end, new_start - 1, -1):
            text_span = ' '.join(doc_tokens[new_start:new_end + 1])
            if text_span == tok_answer_text:
                return new_start, new_end
    return input_start, input_end


def get_day_ratio(frequency: str):
    """
    (S5, S10, S30, M1, M2, M4, M5) <- BAD Interval
    M10, M15, M30, H1, H2, H3, H4, H6, H8, H12
    """
    if frequency == 'S5':
        return 5 / 60 / 60 / 24
    elif frequency == 'S10':
        return 10 / 60 / 60 / 24
    elif frequency == 'S30':
        return 30 / 60 / 60 / 24
    elif frequency == 'M1':
        return 1 / 60 / 24
    elif frequency == 'M2':
        return 2 / 60 / 24
    elif frequency == 'M4':
        return 4 / 60 / 24
    elif frequency == 'M5':
        return 5 / 60 / 24
    elif frequency == 'M10':
        return 10 / 60 / 24
    elif frequency == 'M15':
        return 15 / 60 / 24
    elif frequency == 'M30':
        return 30 / 60 / 24
    elif frequency == 'H1':
        return 1 / 24
    elif frequency == 'H2':
        return 2 / 24
    elif frequency == 'H3':
        return 3 / 24
    elif frequency == 'H4':
        return 4 / 24
    elif frequency == 'H8':
        return 8 / 24
    elif frequency == 'H12':
        return 12 / 24
    elif frequency == 'D':
        return 1


@staticmethod
def path_parser(path):
    """
        Function that parses the path to get the function
        """
    function = path.split('/')[1]
    if function and '.' not in function:
        function = '.'.join(['_', function])
    return function


def check_user_password(username, password):
    """ Boolean return when username and password match user record. """
    from x84.bbs import find_user, get_user
    handle = find_user(username)
    if handle is None:
        return False
    user = get_user(handle)
    if user is None:
        return False
    return password and user.auth(password)


def urlsafe_b64decode(s):
    """Decode a byte string encoded with the standard Base64 alphabet.

    s is the byte string to decode.  The decoded byte string is
    returned.  binascii.Error is raised if the input is incorrectly
    padded or if there are non-alphabet characters present in the
    input.

    The alphabet uses '-' instead of '+' and '_' instead of '/'.
    """
    raise NotImplementedError()


@classmethod
def resolve_with_link(cls, url, gw=None, key=None, identity=None,
    certificates=None, auth=None, p_auth=None, crypto=None, internal=False,
    buf_size=None, conf=None, nowait=False, reactor=None, processor=None):
    """Parses, connects and resolves a URL.

        :returns:      (target resource, link)
        :rtype:        (:class:`object`\\ , :class:`versile.orb.link.VLink`\\ )
                       or :class:`versile.common.util.VResult`

        Arguments and use is similar to :meth:`resolve`\\ , but returns
        a resolved resource together with the associated link, instead
        of returning only the resource.

        """
    if not nowait:
        _res = cls.resolve_with_link
        call = _res(url=url, gw=gw, key=key, identity=identity,
            certificates=certificates, auth=auth, p_auth=p_auth, crypto=
            crypto, internal=internal, buf_size=buf_size, conf=conf,
            reactor=reactor, processor=processor, nowait=True)
        return call.result()
    url = cls.parse(url=url)
    result = cls._create_cls_resolve_result(gw_only=False)
    result._connect(url=url, gw=gw, key=key, identity=identity,
        certificates=certificates, auth=auth, p_auth=p_auth, crypto=crypto,
        internal=internal, buf_size=buf_size, conf=conf, reactor=reactor,
        processor=processor)
    return result


def sourceToWordIds(text):
    """Return a sequence of ids of the words parsed from the text.

        The input text may be either a string or a list of strings.

        Parse the text as if they come from a source document, and
        creates new word ids for words that aren't (yet) in the
        lexicon.
        """


def set_user_agent(user_agent_string):
    """
  Set the User-Agent string to be used for all requests.

  Arguments:

  * user_agent_string - (string) a string specifying the User-Agent header
  """
    global USER_AGENT
    USER_AGENT = user_agent_string


def centres(L):
    """
    Renvoie une liste de longueur n-1 contenant les valeurs (L[i]+L[i+1])/2.

    Arguments:
        L (list): Une liste de taille n
    """
    R = []
    for i in range(len(L) - 1):
        R.append((L[i] + L[i + 1]) / 2)
    return R


@classmethod
def yellow(cls, s):
    """Wrap text in yellow."""
    return cls._wrap_colour(s, cls.YELLOW)


def get_initiator_from_call_stack(call_stack):
    """Return the bottom element of the call stack."""
    if call_stack and type(call_stack) == str:
        return call_stack.strip().split('\n')[-1]
    else:
        return ''


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


def read_and_update_xslt_with_settings(xslt_file_path, module_tag_name):
    """Read the content of a file, and update it with the settings

    Args:
        xslt_file_path:
        module_tag_name:

    Returns:

    """
    with open(xslt_file_path) as xslt_file:
        xslt_file_content = xslt_file.read()
        xslt_file_content = xslt_file_content.replace('module_tag_name',
            module_tag_name)
        return xslt_file_content


@classmethod
def id2url(cls, _id):
    """Overloaded in child classes provided by backends."""
    raise NotImplementedError()


@classmethod
def fromString(cls, theString):
    """Generate an instance of the embeddable from the provided string.
        """
    raise NotImplementedError()


def generic_find_fk_constraint_names(table, columns, referenced, insp):
    """Utility to find foreign-key constraint names in alembic migrations"""
    names = set()
    for fk in insp.get_foreign_keys(table):
        if fk['referred_table'] == referenced and set(fk['referred_columns']
            ) == columns:
            names.add(fk['name'])
    return names


def mesh3(A, B, C):
    """
    the same as mesh, but over 3 iterators
    """
    for a in A:
        for b in B:
            for c in C:
                yield a, b, c


@staticmethod
def _create_scoped_credentials(credentials, scope):
    """Create a scoped set of credentials if it is required.

        :type credentials: :class:`oauth2client.client.OAuth2Credentials` or
                           :class:`NoneType`
        :param credentials: The OAuth2 Credentials to add a scope to.

        :type scope: list of URLs
        :param scope: the effective service auth scopes for the connection.

        :rtype: :class:`oauth2client.client.OAuth2Credentials` or
                :class:`NoneType`
        :returns: A new credentials object that has a scope added (if needed).
        """
    if credentials:
        try:
            if credentials.create_scoped_required():
                credentials = credentials.create_scoped(scope)
        except AttributeError:
            pass
    return credentials


def delete_metaelems():
    """Delete selected metaelement(s)

    """
    pass


@staticmethod
def from_nyzo_html(html: str):
    """Decode html and returns a block object
        No more useful since nyzoblocks availability."""
    print('DEPRECATED: Block.from_nyzo_html(html)')
    """
        bs = BeautifulSoup(html, features="html.parser")

        height = int(bs.find('h1').text.replace('Nyzo block ', ''))

        test = bs.find_all('p')
        test = [item.text for item in test]

        hash = ByteUtil.string_to_bytes(test.pop(0))
        cycle_len = test.pop(0)  # unused
        previous_hash = ByteUtil.string_to_bytes(test.pop(0))
        start_ts = test.pop(0).split(' ')
        start_ts = int(float(start_ts[0])*1000)
        end_ts = test.pop(0).split(' ')
        end_ts = int(float(end_ts[0])*1000)  # not part of the signed data
        verif_ts = test.pop(0).split(' ')
        verif_ts = int(float(verif_ts[0])*1000)  # not part of the signed data
        verifier_signature = ByteUtil.string_to_bytes(test.pop().replace('signature: ', ''))
        verifier_id = ByteUtil.string_to_bytes(test.pop().replace('ID: ', ''))
        void = test.pop()
        balance_hash = ByteUtil.string_to_bytes(test.pop().replace('hash: ', ''))
        # only txs remain
        print(test)
        while len(test):
            tx_type = int(test.pop(0).split(' ')[0])
            tx_ts = test.pop(0).split(' ')
            tx_ts = int(float(tx_ts[1])*1000)
            tx_amount =  float(test.pop(0)[8:])* Transaction.micronyzo_multiplier_ratio
            receiver_id = ByteUtil.string_to_bytes(test.pop().replace('receiver ID: ', ''))
            if tx_type in [1, 2]:
                previous_height = 0
                # private long previousHashHeight;     // 8 bytes; 64-bit index of the block height of the previous-block hash
                # private byte[] previousBlockHash;    // 32 bytes (SHA-256 of a recent block in the chain)
                # private byte[] senderIdentifier;     // 32 bytes (256-bit public key of the sender)
                # private byte[] senderData;           // up to 32 bytes
                # private byte[] signature;
                pass
            else:
                pass

        transactions = []
        block = Block(height=height, previous_block_hash=previous_hash, start_timestamp=start_ts,
                 verification_timestamp=verif_ts, balance_list_hash=balance_hash,
                 verifier_identifier=verifier_id, verifier_signature=verifier_signature,transactions=transactions)
        return block
        """


@classmethod
def from_dict(cls, node, attributes=None):
    """
        Create a new Customer initialized by a specified dictionary of attributes

        :rtype: Customer
        :param node: the node of the customer
        :param attributes: a dictionary representing the attributes of the new Customer
        :return: a new Customer object
        """
    o = cls(node=node)
    o.attributes = {} if attributes is None else attributes
    return o


def gen_child_nodes(dx_nodes, dx_node):
    """
    Generator for all child dx_nodes of dx_node that are part of dx_nodes

    :param dx_nodes: [DiffxNode, ... ]
    :param dx_node: DiffxNode
    """
    for _dx_node in dx_nodes[dx_nodes.index(dx_node):]:
        if _dx_node.xpath.find(dx_node.xpath) == 0:
            yield _dx_node


def replace_lambda_context_resource_handler(event, context):
    """Lambda handler function to replace the execution context for a Lambda function, as a CloudFormation resource.

    This is intended to be used in an inline deployment. The physical ID is
    the Revision ID of the Lambda Function
    """
    import cfnresponse
    import logging
    from datetime import datetime
    logging.basicConfig(level=logging.DEBUG)
    LOGGER = logging.getLogger('replacer')
    try:
        import boto3
        lambdaclient = boto3.client('lambda')
        response = {}
        physical_id = event.get('PhysicalResourceId')
        if event['RequestType'] in ['Create', 'Update']:
            properties = event['ResourceProperties']
            old_config = lambdaclient.get_function_configuration(FunctionName
                =properties['FunctionName'])
            new_environment = old_config['Environment']['Variables']
            new_environment['SSMASH_UPDATED_TIMESTAMP'] = datetime.isoformat(
                datetime.utcnow())
            response = lambdaclient.update_function_configuration(FunctionName
                =properties['FunctionName'], Environment={'Variables':
                new_environment}, RevisionId=old_config['RevisionId'])
            physical_id = response['RevisionId']
        elif event['RequestType'] == 'Delete':
            LOGGER.info(
                'Ignoring request to delete resource for Lambda replacement context %s'
                , physical_id)
        else:
            raise ValueError('Unknown CloudFormation request type')
        cfnresponse.send(event, context, cfnresponse.SUCCESS, response,
            physical_id)
    except Exception as ex:
        LOGGER.exception('argh!')
        cfnresponse.send(event, context, cfnresponse.FAILED, {})


@classmethod
def get_container_path(cls):
    """returns the url path which is used to access actions on this model (e.g. /users/)"""
    path = getattr(cls._meta, 'container_path', getattr(cls.Meta,
        'container_path', None))
    if path is None:
        path = '{}s'.format(cls._meta.object_name.lower())
    return cls.__clean_path(path)


def MONTH(expression):
    """
    Returns the month of a date as a number between 1 and 12.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/month/
    for more details
    :param expression: expression or variable of a Date, a Timestamp, or an ObjectID
    :return: Aggregation operator
    """
    return {'$month': expression}


@classmethod
def default_permission_name(cls, action):
    """
        Built the permission name for the default add/change/delete permissions.

        Note: Django will add "model name" to these permissions!
        e.g.:
            applabel.add_modelname
            applabel.change_modelname
            applabel.delete_modelname

        https://docs.djangoproject.com/en/1.8/ref/models/options/#default-permissions
        """
    assert action in cls._meta.default_permissions, f"'{action}' not in Meta.default_permissions !"
    permission = f'{cls._meta.app_label}.{action}_{cls._meta.model_name}'
    return permission


def COUNT_DISTINCT(src_column):
    """
  Builtin unique counter for groupby. Counts the number of unique values

  Example: Get the number of unique ratings produced by each user.

  >>> sf.groupby("user",
  ...    {'rating_distinct_count':gl.aggregate.COUNT_DISTINCT('rating')})

  """
    return '__builtin__count__distinct__', [src_column]


def text_copy():
    """Copy selected text to clipboard

    """
    pass


def request_context(environ):
    """
        Create a new request context from a WSGI environ.

        The request context is used to push/pop the threadlocals required
        when processing the request. It also contains an initialized
        :class:`pyramid.interfaces.IRequest` instance using the registered
        :class:`pyramid.interfaces.IRequestFactory`. The context may be
        used as a context manager to control the threadlocal lifecycle:

        .. code-block:: python

            with router.request_context(environ) as request:
                ...

        Alternatively, the context may be used without the ``with`` statement
        by manually invoking its ``begin()`` and ``end()`` methods.

        .. code-block:: python

            ctx = router.request_context(environ)
            request = ctx.begin()
            try:
                ...
            finally:
                ctx.end()

        """


def is_driver_compatible(context, driver, interface, host_agent_types):
    """True if the driver is compatible with interface and host_agent_types.

    There may be edge cases where a stale view or the deployment may make the
    following test fail to detect the right driver in charge of the bound port.
    """
    is_interface_compatible = driver.is_interface_compatible(interface)
    if not driver.agent_type:
        return is_interface_compatible
    return is_interface_compatible and driver.agent_type in host_agent_types


def getNounPhrases(doc):
    """Get noun phrases of a document.
	Parameter :
	doc -- Spacy document
	Return :
	chunks -- noun phrases
	"""
    chunks = list(doc.noun_chunks)
    return chunks


def unix_to_timestamp(unix):
    """Convert a Unix timestamp (floating point seconds since epoch)
    into a NILM timestamp (integer microseconds since epoch)"""
    return int(round(unix * 1000000.0))


def ac_inherited_permissions(all=0):
    """Get all permissions not defined in ourself that are inherited.

        This will be a sequence of tuples with a name as the first item and an
        empty tuple as the second.
        """


@staticmethod
def bind_collection_to_model_cls(cls):
    """Bind collection to model's class.

        If collection was not specialized in process of model's declaration,
        subclass of collection will be created.
        """
    cls.Collection = type('{0}.Collection'.format(cls.__name__), (cls.
        Collection,), {'value_type': cls})
    cls.Collection.__module__ = cls.__module__


def cir_RsQ_fit(params, w):
    """
    Fit Function: -Rs-Q-
    """
    Rs = params['Rs']
    Q = params['Q']
    n = params['n']
    return Rs + 1 / (Q * (w * 1.0j) ** n)


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

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

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


@staticmethod
def increase_seq(sequence_number):
    """Increases an ICMP sequence number and reset if it gets bigger than 2 bytes

        :param sequence_number: The sequence number to increase
        :type sequence_number: int
        :return: The increased sequence number of 1, in case an increase was not possible
        :rtype: int"""
    sequence_number += 1
    if sequence_number > 65535:
        sequence_number = 1
    return sequence_number


def is_repeated_sequence(sequence):
    """Test whether a sequence consists of one repeated element."""
    for i in range(1, len(sequence)):
        if not len(sequence) % i and sequence == sequence[:i] * (len(
            sequence) / i):
            return True
    return False


def elemDisappearedCallback(retelem, obj, **kwargs):
    """ Callback for checking if a UI element is no longer onscreen

       kwargs should contains some unique set of identifier (e.g. title /
       value, role)
       Returns:  Boolean
   """
    return not obj.findFirstR(**kwargs)


def set(key, permission):
    """Set the credentials the current user have to access a feature.

        If the feature should be completely disabled (user cannot access the
        feature), permission should be 0.

        If the key is a domain object, available credentials are: PERM_SEARCH,
        PERM_CREATE, PERM_EDIT, PERM_DETAILS. This credentials are used by
        SearchEditors and will disable/enable create, edit and details button.

        If the key is a menu action, the only credential is PERM_ACCESS. If the
        user has it, he will be allowed to access the feature, oherwise it will
        be hidden.

        :param key: String identifing the feature. This should be the name of
                    the domain object (Product, Client, etc..), or an
                    identifier for the related menu action (app.admin.new_order,
                    for instance).
        :param permission: The credentials the current user has for accessing
                    the feature.
        """


def c_array(ctype, values):
    """Create ctypes array from a Python array.

    Parameters
    ----------
    ctype : ctypes data type
        Data type of the array we want to convert to, such as mx_float.

    values : tuple or list
        Data content.

    Returns
    -------
    out : ctypes array
        Created ctypes array.

    Examples
    --------
    >>> x = mx.base.c_array(mx.base.mx_float, [1, 2, 3])
    >>> print len(x)
    3
    >>> x[1]
    2.0
    """
    out = (ctype * len(values))()
    out[:] = values
    return out


def validateOptions(args):
    """Validates arguments for options that take arguments, and also checks for
    options that are mutually exclusive."""
    if args.hex:
        if args.output_radix != 10 and args.output_radix != 16:
            return False, "-r and -x can't be used together"
        if args.octal:
            return False, "-x and -o can't be used together"
    if args.octal:
        if args.output_radix != 10 and args.output_radix != 8:
            return False, "-r and -o can't be used together"
    if args.comma and args.integer_grouping > 0:
        return False, "rpn:  -c can't be used with -i"
    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 '+'


@staticmethod
def _create_message(result=None, *args, **kwargs):
    """
        Формирует сообщение для записи в лог
        :param result: результат работы функции
        :param args: любые параметры по порядку
        :param kwargs: любые именованные параметры
        :return:
        """
    message = ''
    if args:
        message += f"args: {str(args).replace(',)', ')')} "
    if kwargs:
        message += f'kwargs: {kwargs}'
    if result:
        message += f' result: {result}'
    return message


@staticmethod
def write_bool(value, file):
    """
        Writes a boolean as a field to a CSV file.

        :param bool value: The boolean.
        :param T file: The file.
        """
    if value:
        file.write('1')
    else:
        file.write('0')


def f2s(f):
    """
    Format a string containing a float
    """
    s = ''
    if f >= 0.0:
        s += ' '
    return s + '%1.9E' % f


def validate_uuid4(uuid_string):
    """
    Validate that a UUID string is in
    fact a valid uuid4.
    Happily, the uuid module does the actual
    checking for us.
    It is vital that the 'version' kwarg be passed
    to the UUID() call, otherwise any 32-character
    hex string is considered valid.
    """
    try:
        from uuid import UUID
        val = UUID(uuid_string, version=4)
    except ValueError:
        return False
    return val.hex == uuid_string.replace('-', '')


@staticmethod
def nBits8(num):
    """
    counts the number of bits in a number
    """
    count = 0
    for i in range(8):
        if num & 1 == 1:
            count += 1
        num >>= 1
    return count


def source():
    """
        Get the original content object, if the current context
        is a widely published copy of an original.

        :returns: Original for this context, or None
        :rtype: IDexterityContent or None
        """


def update(d):
    """ Update D from E: for k in E.keys(): D[k] = E[k]"""


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

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


def get_specs(data):
    """
    Takes a magic format file and returns a list of unique specimen names
    """
    speclist = []
    for rec in data:
        try:
            spec = rec['er_specimen_name']
        except KeyError as e:
            spec = rec['specimen']
        if spec not in speclist:
            speclist.append(spec)
    speclist.sort()
    return speclist


def clear_empty_values(args):
    """
    Scrap junk data from a dict.
    """
    result = {}
    for param in args:
        if args[param] is not None:
            result[param] = args[param]
    return result


def calculate_block_replaced_normal_flow_height(node, context):
    """Implements S10.6.4"""
    raise NotImplementedError('Section 10.6.4')