def expose_values(labels, values, use_repr=False, to_stdout=True):
    """
    Given a (zippable) list or one string for each of args labels and values,
    prints or returns them for nice interactive data manipulation/debugging.

    Args:
        labels: string or list of strings
                just used to identify values
        values: expressions
        use_repr: boolean; if True, will apply repr() to each value
        to_stdout: boolean; if True, prints result; if False, returns list
                   of 2-tuples

    Returns:
        list of 2-tuples or None, according to ``to_stdout``.

    :todo: is use_repr ever useful?
    """
    if type(labels) != list:
        labels = [labels]
        values = [values]
    assert len(labels) == len(values)
    result = []
    for label, value in zip(labels, values):
        if use_repr:
            result.append((label, repr(value)))
        else:
            result.append((label, value))
    if to_stdout:
        for item in result:
            print('{}: {}'.format(item[0], item[1]))
    else:
        return result


def yield_all(fun, arr):
    """Yield all subitems of all item"""
    for items in arr:
        for val in fun(items):
            yield val


def _is_iter(val):
    """Checks if value is a list or tuple"""
    return isinstance(val, tuple) or isinstance(val, list)


def render_edit(data):
    """
        Get the HTML field for editing. This can be None, and the field will not be rendered on editing row
        """


@staticmethod
def visit_Constant(_):
    """ Return no dependencies on others functions. """
    return [frozenset()]


def getOS():
    """Returns operating system"""
    import platform
    return platform.system()


def volumetric_heat_capacity(se_top=1.0, porosity=0.4):
    """
    Computes the volumetric heat capacity of the soil

    .. math ::
        \\rho c_{p}=10e^{6}\\left[\\left(1-\\phi\\right)^{2}+
        2.5\\phi+4.2\\phi S_{e,top}\\right]

    Parameters
    ----------
    se_top : float
        effective saturation of the topsoil
        :math:`S_{e,top}`
        [-]
    porosity : float
        porosity of the soil
        :math:`\\phi`
        [-]

    Returns
    -------
    vhc : float
        volumetric heat capacity
        :math:`\\rho c_{p}`
        [J m-3 K-1]

    Examples
    --------
    >>> import ETLook.radiation as rad
    >>> rad.volumetric_heat_capacity(se_top=0.4, porosity = 0.5)
    23400000.0
    """
    return ((1 - porosity) ** 2 + 2.5 * porosity + 4.2 * porosity * se_top
        ) * 10 ** 6


def delete_flavor(nova, flavor):
    """
    Deletes a flavor
    :param nova: the Nova client
    :param flavor: the SNAPS flavor domain object
    """
    nova.flavors.delete(flavor.id)


def get_file_list(resource, datum_kwarg_gen, get_spec_handler):
    """
    Given a resource and an iterable of datum kwargs, get a list of
    associated files.

    DO NOT USE FOR COPYING OR MOVING. This is for debugging only.
    See the methods for moving and copying on the Registry object.
    """
    handler = get_spec_handler(resource['uid'])
    return handler.get_file_list(datum_kwarg_gen)


@classmethod
def rhombohedral(cls, a, alpha, lattice_type='P'):
    """Factory for hexagonal lattices

        :param a: unit cell length
        :param alpha: unit cell angle
        """
    a = float(a)
    alpha = float(a)
    self = cls(a, a, a, alpha, alpha, alpha, lattice='rhombohedral',
        lattice_type=lattice_type)
    return self


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

        :param MemberChangeStatusType val:
        :rtype: EventType
        """
    return cls('member_change_status', val)


def rinse(boto_response):
    """ Remove ResponseMetadata block from Boto / AWS API respone. """
    boto_response.pop('ResponseMetadata', None)
    return boto_response


def manifest_rc(name, type='dll'):
    """Return the rc file used to generate the res file which will be embedded
    as manifest for given manifest file name, of given type ('dll' or
    'exe').

    Parameters
    ----------
    name : str
            name of the manifest file to embed
    type : str {'dll', 'exe'}
            type of the binary which will embed the manifest

    """
    if type == 'dll':
        rctype = 2
    elif type == 'exe':
        rctype = 1
    else:
        raise ValueError('Type %s not supported' % type)
    return '#include "winuser.h"\n%d RT_MANIFEST %s' % (rctype, name)


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


@staticmethod
def display_time(seconds, precision=3):
    """
        method to display time in human readable format
        :param seconds: Number of seconds
        :param precision: Decimal precision
        :return: String
        """
    intervals = [('weeks', 604800), ('days', 86400), ('hours', 3600), (
        'minutes', 60), ('seconds', 1)]
    result = list()
    dtype = type(seconds).__name__
    if dtype != 'int' or dtype != 'long' or dtype != 'float':
        try:
            seconds = float(seconds)
        except (TypeError, ValueError, NameError):
            print('Type not coercible to Float')
    for name, count in intervals:
        if name != 'seconds':
            value = seconds // count
            if value:
                seconds -= value * count
                if value == 1:
                    name = name.rstrip('s')
                value = str(int(value))
                result.append('{v} {n}'.format(v=value, n=name))
        else:
            value = '{:.{p}f}'.format(seconds, p=precision)
            result.append('{v} {n}'.format(v=value, n=name))
    return ' '.join(result)


def getPrice():
    """ The lowest available price
        """


def images_separate(length: int=1):
    """On image sequence strips, it returns a strip for each image

    :param length: Length, Length of each frame
    :type length: int
    """
    pass


@staticmethod
def lat_lon_builder(lat=0, lon=0):
    """ Builds lat and lon query.
        :param lat:
            The latitude. Default is 0
        :type lat:
            float
        :param lon:
            The The longitude. Default is 0
        :type lon:
            float
        :returns:
            String
        """
    return (
        'upperLeftCornerLatitude:[%s+TO+1000]+AND+lowerRightCornerLatitude:[-1000+TO+%s]+AND+lowerLeftCornerLongitude:[-1000+TO+%s]+AND+upperRightCornerLongitude:[%s+TO+1000]'
         % (lat, lat, lon, lon))


def xy_to_rc(arr2d, x, y):
    """Returns the rc coordinates

    :param arr2d: an numpy array
    :param r: row coordinate
    :param c: column coordinates
    :returns: (x,y) coordinates
    """
    return arr2d.shape[0] - 1 - y, x


def merge_endpoints(defaults, additions):
    """
    Given an existing set of endpoint data, this will deep-update it with
    any similarly structured data in the additions.

    :param defaults: The existing endpoints data
    :type defaults: dict

    :param defaults: The additional endpoints data
    :type defaults: dict

    :returns: The modified endpoints data
    :rtype: dict
    """
    for service, region_info in additions.items():
        defaults.setdefault(service, {})
        defaults[service].update(region_info)
    return defaults


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the Nest binary sensors.

    No longer used.
    """


@classmethod
def get_add_form(cls, component, **kwargs):
    """Return configuration form for adding new addon."""
    if cls.settings_form is None:
        return None
    storage = cls.create_object(component)
    instance = cls(storage)
    return cls.settings_form(instance, **kwargs)


def keyframe_insert():
    """Insert a keyframe to selected tracks at current frame

    """
    pass


def set_logging_options(loggingOptionsPayload=None):
    """
    Sets the logging options.
    See also: AWS API Documentation

    :example: response = client.set_logging_options(
        loggingOptionsPayload={
            'roleArn': 'string',
            'logLevel': 'DEBUG'|'INFO'|'ERROR'|'WARN'|'DISABLED'
        }
    )

    :type loggingOptionsPayload: dict
    :param loggingOptionsPayload: [REQUIRED]
            The logging options payload.
            roleArn (string) -- [REQUIRED]The ARN of the IAM role that grants access.
            logLevel (string) --The logging level.

    """
    pass


@staticmethod
def _get_sample_name(path):
    """
        Returns the sample name given the path to the sample file
        :param path: path to the sample file
        :return: name of the sample
        """
    sp = path.split('/')
    file_name = sp[-1]
    return file_name.split('.')[0]


@classmethod
def validate_invoice(cls, invoice):
    """
        Valida que los campos de la factura cumplan con los requisitos de la AFIP
        :param invoice: Factura a validar, objeto ExportationElectronicInvoice
        """
    cls._validate_document_date(invoice)
    cls._validate_document_code(invoice)
    cls._validate_existent_permission(invoice)
    cls._validate_document_language(invoice)
    cls._validate_exportation_type(invoice)
    cls._validate_amount(invoice)


def is_abstract_model(model):
    """
    Given a model class, returns a boolean True if it is abstract and False if it is not.
    """
    return hasattr(model, '_meta') and hasattr(model._meta, 'abstract'
        ) and model._meta.abstract


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 intget(integer, default=None):
    """
    Returns `integer` as an int or `default` if it can't.

        >>> intget('3')
        3
        >>> intget('3a')
        >>> intget('3a', 0)
        0
    """
    try:
        return int(integer)
    except (TypeError, ValueError):
        return default


def GetGPXtreeItemId(G2frame, parentId, itemText):
    """Find the tree item that matches the text in itemText starting with parentId

    :param wx.Frame G2frame: Data tree frame object
    :param wx.TreeItemId parentId: tree item to start search with
    :param str itemText: text for tree item
    """
    item, cookie = G2frame.GPXtree.GetFirstChild(parentId)
    while item:
        if G2frame.GPXtree.GetItemText(item) == itemText:
            return item
        item, cookie = G2frame.GPXtree.GetNextChild(parentId, cookie)
    return 0


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

        :param UploadSessionFinishBatchResult val:
        :rtype: UploadSessionFinishBatchLaunch
        """
    return cls('complete', val)


def adjusttokenpos(t, ofs):
    """Adjust start/end column of the given token"""
    return t._replace(start=(t.start[0], t.start[1] + ofs), end=(t.end[0],
        t.end[1] + ofs))


@staticmethod
def out_quint(progress):
    """.. image:: images/anim_out_quint.png
        """
    p = progress - 1.0
    return p * p * p * p * p + 1.0


def generic_find_uq_constraint_name(table, columns, insp):
    """Utility to find a unique constraint name in alembic migrations"""
    for uq in insp.get_unique_constraints(table):
        if columns == set(uq['column_names']):
            return uq['name']


@classmethod
def is_datasource_for(cls, **kwargs):
    """
        Determines if header corresponds to an NOAA predict indices
        `~sunpy.timeseries.TimeSeries`.
        """
    if kwargs.get('source', ''):
        return kwargs.get('source', '').lower().startswith(cls._source)


def linear(target, m, b, prop):
    """
    Calculates a property as a linear function of a given property

    Parameters
    ----------
    target : OpenPNM Object
        The object for which these values are being calculated.  This
        controls the length of the calculated array, and also provides
        access to other necessary thermofluid properties.

    m, b : floats
        Slope and intercept of the linear corelation

    prop : string
        The dictionary key containing the independent variable or phase
        property to be used in the correlation.

    Returns
    -------
    value : NumPy ndarray
        Array containing ``m * target[prop] + b``.

    """
    x = target[prop]
    value = m * x + b
    return value


def peep_(*args):
    """Examine local data.
    peep_()     # examine all variables in the scope (locals cover globals)
    peep_('x')  # examine x (name will be known as it is explicitely given)
    """
    from peepshow.core import peep as core
    from peepshow.utils import python as utils
    from peepshow.core.trans import GloLoc, Given
    if len(args) > 1:
        raise TypeError('Too many arguments.')
    expr = args[0]
    env = utils.caller_gloloc()
    if args:
        if not isinstance(expr, str):
            raise TypeError('Expression must be a string or None.')
        try:
            target = eval(expr, {}, env.initial)
        except:
            raise SyntaxError('Invalid expression.')
        target = Given(target, expr)
    else:
        target = GloLoc(env.initial)
    last_target = core.peep(target, env)


def check_bool(result, func, cargs):
    """Returns the boolean evaluation of the value."""
    if bool(result):
        return True
    else:
        return False


def prod(seq):
    """Product of a sequence of numbers.

    Parameters
    ----------
    seq : sequence
        A sequence of numbers.

    Returns
    -------
    float or int
        Product of numbers.

    Notes
    -----
    This is defined as:

    .. math::

        \\prod_{i=1}^n x_i
    """
    mult = 1
    for x in seq:
        mult *= x
    return mult


@staticmethod
def _get_example_from_basic_type(type):
    """Get example from the given type.

        Args:
            type: the type you want an example of.

        Returns:
            An array with two example values of the given type.
        """
    if type == 'integer':
        return [42, 24]
    elif type == 'number':
        return [5.5, 5.5]
    elif type == 'string':
        return ['string', 'string2']
    elif type == 'datetime':
        return ['2015-08-28T09:02:57.481Z', '2015-08-28T09:02:57.481Z']
    elif type == 'boolean':
        return [False, True]
    elif type == 'null':
        return ['null', 'null']


def get_unapproved_version():
    """Get the id of the unapproved version.
        """


@classmethod
def get_known_classes(cls):
    """Get protected member"""
    return cls._known_classes


def check_action(res):
    """
    Check the action status and raise expection if it failed

    Parameters
    ----------
    res : CASResults
        The results from the action

    Raises
    ------
    RuntimeError
        If the action failed

    Returns
    -------
    :class:`CASResults`

    """
    if res.severity > 1:
        raise RuntimeError(res.status)
    return res


def write_selected_sln_setting(cmake_file, settings,
    sln_setting_2_project_setting, sln_setting, has_property_value,
    command_indent, sln_conf, config_expressions,
    max_config_condition_width, **kwargs):
    """ Routine that writes main info of setting block """
    begin_text = kwargs['begin_text']
    property_name = kwargs['property_name']
    indent = kwargs['indent']
    write_setting_property_func = kwargs['write_setting_property_func']
    mapped_setting = settings[sln_setting_2_project_setting[sln_setting]]
    if property_name in mapped_setting:
        if mapped_setting[property_name]:
            if not has_property_value:
                begin_text = begin_text.replace('\n', '\n' + indent +
                    command_indent)
                if begin_text:
                    cmake_file.write('{}{}\n'.format(indent +
                        command_indent, begin_text))
                has_property_value = True
            config_condition_expr = None
            if sln_conf is not None:
                config_condition_expr = '$<CONFIG:{}>'.format(sln_conf)
                config_expressions.append(config_condition_expr)
            write_setting_property_func(cmake_file, indent + command_indent,
                config_condition_expr, mapped_setting[property_name],
                max_config_condition_width, **kwargs)
    return has_property_value


def decode_bin_angle(bin_angle, mode=None):
    """Decode BIN angle.

    See 4.2 p.23

    Parameters
    ----------
    bin_angle : array-like
    mode : int
        number of bytes

    Returns
    -------
    out : array-like
        decoded angle
    """
    return 360.0 * bin_angle / 2 ** (mode * 8)


def loss(y_pred, y_true, metric):
    """Compute loss function between prediction and ground truth.

    Loss function given by a Riemannian metric,
    expressed as the squared geodesic distance between the prediction
    and the ground truth.

    Parameters
    ----------
    y_pred
    y_true
    metric

    Returns
    -------
    loss

    """
    sq_dist = metric.squared_dist(y_pred, y_true)
    return sq_dist


def merge_two_dicts(x, y):
    """
    Given two dicts, merge them into a new dict as a shallow copy
    """
    z = x.copy()
    z.update(y)
    return z


def cigar_conversion(cigar):
    """Convert character or integer to corresponding integer or character for the SAM/BAM formatting
    :param cigar: character or int to get corresponding CIGAR equivalent
    """
    assert type(cigar) is str or type(cigar
        ) is int, 'Cigar character must be int or str'
    chars = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X']
    if type(cigar) is str:
        assert cigar in chars, 'Character is not a cigar string character'
        return chars.index(cigar)
    else:
        assert 0 <= cigar <= 8, 'Integer must be between 0 and 8'
        return chars[cigar]


def licenses_mapper(license, licenses):
    """
    Return declared_licenses list based on the `license` and
    `licenses` values found in a package.
    """
    declared_licenses = []
    if license:
        declared_licenses.append(str(license).strip())
    if licenses:
        for lic in licenses:
            if lic and lic.strip():
                declared_licenses.append(lic.strip())
    return declared_licenses


def hide_index_html_from(path):
    """Remove ``index.html`` suffix as well as trailing slashes (if
    any).
    """
    if not path.endswith('index.html'):
        return path
    return path[:-10].rstrip('/')


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


def get_corr_hex(num):
    """
    Gets correspondence between a number
    and an hexadecimal string

    Parameters
    -------------
    num
        Number

    Returns
    -------------
    hex_string
        Hexadecimal string
    """
    if num < 10:
        return str(int(num))
    elif num < 11:
        return 'A'
    elif num < 12:
        return 'B'
    elif num < 13:
        return 'C'
    elif num < 14:
        return 'D'
    elif num < 15:
        return 'E'
    elif num < 16:
        return 'F'


@staticmethod
def _start_repl(api):
    """
        Starts the REPL.
        """
    banner = (
        """IOTA API client for {uri} ({testnet}) initialized as variable `api`.
Type `help(api)` for list of API commands."""
        .format(testnet='testnet' if api.testnet else 'mainnet', uri=api.
        adapter.get_uri()))
    scope_vars = {'api': api}
    try:
        import IPython
    except ImportError:
        from code import InteractiveConsole
        InteractiveConsole(locals=scope_vars).interact(banner, '')
    else:
        print(banner)
        IPython.start_ipython(argv=[], user_ns=scope_vars)


def is_quoted(s):
    """ Returns True if the string begins and ends with quotes (single or double)

        :param s: a string
        :return: boolean
    """
    return s.startswith("'") and s.endswith("'") or s.startswith('"'
        ) and s.endswith('"')


def is_pure_ascii(value):
    """
    Determines whether the given string is a pure ascii
    string
    >>> utils.is_pure_ascii(u"Cаша")
        False
    >>> utils.is_pure_ascii(u"Alice")
        True
    >>> utils.is_pure_ascii("Alice")
        True
    """
    if value is None:
        return False
    if not isinstance(value, str):
        return False
    try:
        value.encode('ascii')
    except (UnicodeEncodeError, UnicodeDecodeError):
        return False
    return True


def excise(dict_, keypath):
    """
    Remove key pointed at by ``keypath`` from nested dict ``dict_``, if exists.

    .. versionadded:: 1.0
    """
    data = dict_
    keypath = list(keypath)
    leaf_key = keypath.pop()
    while keypath:
        key = keypath.pop(0)
        if key not in data:
            return
        data = data[key]
    if leaf_key in data:
        del data[leaf_key]


@staticmethod
def _source_s3():
    """Method to add s3 as source."""
    pass


def pylist(param):
    """
    Takes a comma separated string or list and renders a python list source code
    :param param:
    :return:
    """
    prefix = '["'
    suffix = '"]'
    if isinstance(param, str):
        param = param.split(' ')
    if isinstance(param, list):
        param = '","'.join(param)
    return prefix + param + suffix


def disable():
    """Disables v2 behaviors."""
    global _force_enable
    _force_enable = False


@staticmethod
def extrapolate(x0, t0, x1, t1, t):
    """
        Finds the value of `x` at `t` via linear extrapolation.
        """
    return x0 + (x1 - x0) * (t - t0) / (t1 - t0)


def setanchor(path):
    """Set anchor manually by given path.

        @param path: list representing the absolute node path.
        """


def sort(cmpfunc=None):
    """Stable sort *IN PLACE*; `cmpfunc(x, y)` -> -1, 0, 1"""


def platform_exe(name):
    """
	Append '.exe' if it's not already there.
	"""
    if name.endswith('.exe'):
        return name
    return name + '.exe'


def select_more():
    """Select connected parent/child objects

    """
    pass


def gr2R(g, r):
    """Use the Lupton 2005 transformations listed at
    http://classic.sdss.org/dr7/algorithms/sdssUBVRITransform.html
    to transform g,r passbands into R.

    Returns array of R and float estimate of systematic RMS error of transformation.
    """
    R = r - 0.1837 * (g - r) - 0.0971
    sigma = 0.0106
    return R, sigma


def make_vs_title(x: str, y: str):
    """Creates the axes title for a plot with the given x-axis variable and
    y-axis variable

    :param x: the name for the x-variable
    :type x: str
    :param y: the name for the y-variable
    :type y: str
    :return: The correct axes title
    :rtype: str
    """
    return f'{y} vs {x}'


def NotLeafNodeError(Error):
    """a leaf node is expected but we have a collection"""


def check_missing_data(df) ->bool:
    """
    Utility function that checks if the data has any missing values.

    Parameters
    ----------
    df : Dataframe
        Pandas Dataframe of data

    Returns
    -------
    bool
        True if data has missing values, False otherwise.
    """
    return df.isnull().values.any()


def demean(in_file, in_mask, only_mask=False, newpath=None):
    """Demean ``in_file`` within the mask defined by ``in_mask``"""
    import os
    import numpy as np
    import nibabel as nb
    from nipype.utils.filemanip import fname_presuffix
    out_file = fname_presuffix(in_file, suffix='_demeaned', newpath=os.getcwd()
        )
    nii = nb.load(in_file)
    msk = nb.load(in_mask).get_data()
    data = nii.get_data()
    if only_mask:
        data[msk > 0] -= np.median(data[msk > 0])
    else:
        data -= np.median(data[msk > 0])
    nb.Nifti1Image(data, nii.affine, nii.header).to_filename(out_file)
    return out_file


def filetypes():
    """Get supported text filetypes for system import."""
    return {'ini': 'Rian System Description', 'txt': 'Rian System Description'}


def gt_corners(gt, nx, ny):
    """Get corner coordinates based on input geotransform and raster dimensions
   """
    ul = [gt[0], gt[3]]
    ll = [gt[0], gt[3] + gt[5] * ny]
    ur = [gt[0] + gt[1] * nx, gt[3]]
    lr = [gt[0] + gt[1] * nx, gt[3] + gt[5] * ny]
    return ul, ll, ur, lr


def strtobool(val):
    """Convert a string representation of truth to true (1) or false (0).
    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
    'val' is anything else.
    """
    val = val.lower()
    if val in ('y', 'yes', 't', 'true', 'on', '1'):
        return 1
    elif val in ('n', 'no', 'f', 'false', 'off', '0'):
        return 0
    else:
        raise ValueError('invalid truth value %r' % (val,))


def lingres(xa, ya, w):
    """
	Return a, b for the relation y = a + b*x
	given data in xa, ya and weights in w
	"""
    sum = w.sum()
    sumX = (w * xa).sum()
    sumY = (w * ya).sum()
    sumX2 = (w * xa * xa).sum()
    sumY2 = (w * ya * ya).sum()
    sumXY = (w * xa * ya).sum()
    delta = sum * sumX2 - sumX * sumX
    a = (sumX2 * sumY - sumX * sumXY) / delta
    b = (sumXY * sum - sumX * sumY) / delta
    return a, b


def CarbfromfCO2HCO3(fCO2, HCO3, K0, K1, K2):
    """Calculate carbonate ion from CO2 fugacity and bicarbonate ion."""
    return HCO3 ** 2 * K2 / (K0 * fCO2 * K1)


def processauthors_removeparen(authors_string):
    """Remove parentheses

    See docstring of processauthors() for more information.

    >>> processauthors_removeparen("This (foo) string (bar) contains (baz) parenthesis")
    'This  string  contains  parenthesis'
    """
    opening = 0
    dest = ''
    for char in authors_string:
        if char == '(':
            opening += 1
        elif char == ')' and opening > 0:
            opening -= 1
        elif opening == 0:
            dest += char
    return dest


@classmethod
def decode_conjure_union_type(cls, obj, conjure_type):
    """Decodes json into a conjure union type.

        Args:
            obj: the json object to decode
            conjure_type: a class object which is the union type
                we're decoding into
        Returns:
            An instance of type conjure_type.
        """
    type_of_union = obj['type']
    for attr, conjure_field in conjure_type._options().items():
        if conjure_field.identifier == type_of_union:
            attribute = attr
            conjure_field_definition = conjure_field
            break
    else:
        raise ValueError('unknown union type {0} for {1}'.format(
            type_of_union, conjure_type))
    deserialized = {}
    if type_of_union not in obj or obj[type_of_union] is None:
        cls.check_null_field(obj, deserialized, conjure_field_definition)
    else:
        value = obj[type_of_union]
        field_type = conjure_field_definition.field_type
        deserialized[attribute] = cls.do_decode(value, field_type)
    return conjure_type(**deserialized)


def bC_H_HSO4_HMW84(T, P):
    """c-a: hydrogen bisulfate [HMW84]."""
    b0 = 0.2065
    b1 = 0.5556
    b2 = 0.0
    C0 = 0
    C1 = 0
    alph1 = 2
    alph2 = -9
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


def do_OP_PICK(vm):
    """
    >>> s = [b'a', b'b', b'c', b'd', b'']
    >>> do_OP_PICK(s, require_minimal=True)
    >>> print(s)
    [b'a', b'b', b'c', b'd', b'b']
    """
    v = vm.pop_nonnegative()
    vm.append(vm[-v - 1])


def _valid_version(data, info):
    """Return True if the version can be uploaded."""
    if data['version'] in info['releases'].keys():
        text = "# Package '%s' with version '%s' already exists."
        text = text % (data['name'], data['version'])
        print(text)
        return False
    return True


def handle_dbadmin_command(command, options, args):
    """Handle a dbadmin command

        :param command: the command string
        :param options: extra optparser options
        :param args: a list of C{args}
        """
    pass


@classmethod
def open(cls, path, mode):
    """
        Open a data file.  The base implementation of this function just
        opens and returns a standard python file object.

        Subclasses can override to either open files using different openers
        (like fitsio.FITS), or, for more specific data types, return an
        instance of the class itself to use as an intermediary for the file.

        """
    return open(path, mode)


def act_paso(símismo, paso):
    """
        Actualiza el paso actual del variable.

        Parameters
        ----------
        paso: int
            El nuevo paso en el ciclo actual.
        """
    símismo.paso = paso
    super().poner_val(símismo._matr_paso[paso])


@staticmethod
def _classification_function_one(att1, att2, att3):
    """ classification_function_one

        Decides the sample class label based on the sum of att1 and att2,
        and the threshold value of 9.

        Parameters
        ----------
        att1: float
            First numeric attribute.

        att2: float
            Second numeric attribute.

        att3: float
            Third numeric attribute.

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

        """
    return 0 if att1 + att2 <= 9 else 1


@classmethod
def _get_related_model_for_field(cls, field):
    """
        Get related model to which field has relationship to
        from property instance (e.g. ``ColumnProperty`` class or related)
        """
    return field._dependency_processor.mapper.class_


def check_hotshot(dump):
    """check to hotshot-profile datafile."""
    signature = 'hotshot-version'.encode()
    return True if dump.find(signature) > 0 else False


def is_vpc_peered():
    """
    Returns a Boolean value indicating whether your Lightsail VPC is peered.
    See also: AWS API Documentation

    :example: response = client.is_vpc_peered()

    :rtype: dict
    :return: {
        'isPeered': True|False
    }

    """
    pass


def iterSearchIndexes():
    """return iterator of all search indexes"""


@classmethod
def process(cls, *, context=None, parameter=None):
    """ Evaluate the CALL command. """
    context.callstack.append(parameter['location'])
    context.counter = context.labels[parameter['param']]


def description():
    """Description for command line interface"""
    return ''


def translate(x, y):
    """
    Generate an SVG transform statement representing a simple translation.
    """
    return 'translate(%i %i)' % (x, y)


def visiblename(name, all=None, obj=None):
    """Decide whether to show documentation on a variable."""
    if name in {'__author__', '__builtins__', '__cached__', '__credits__',
        '__date__', '__doc__', '__file__', '__spec__', '__loader__',
        '__module__', '__name__', '__package__', '__path__', '__qualname__',
        '__slots__', '__version__'}:
        return 0
    if name.startswith('__') and name.endswith('__'):
        return 1
    if name.startswith('_') and hasattr(obj, '_fields'):
        return True
    if all is not None:
        return name in all
    else:
        return not name.startswith('_')


def KK_RC19(w, Rs, R_values, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    return Rs + R_values[0] / (1 + w * 1.0j * t_values[0]) + R_values[1] / (
        1 + w * 1.0j * t_values[1]) + R_values[2] / (1 + w * 1.0j * t_values[2]
        ) + R_values[3] / (1 + w * 1.0j * t_values[3]) + R_values[4] / (1 +
        w * 1.0j * t_values[4]) + R_values[5] / (1 + w * 1.0j * t_values[5]
        ) + R_values[6] / (1 + w * 1.0j * t_values[6]) + R_values[7] / (1 +
        w * 1.0j * t_values[7]) + R_values[8] / (1 + w * 1.0j * t_values[8]
        ) + R_values[9] / (1 + w * 1.0j * t_values[9]) + R_values[10] / (1 +
        w * 1.0j * t_values[10]) + R_values[11] / (1 + w * 1.0j * t_values[11]
        ) + R_values[12] / (1 + w * 1.0j * t_values[12]) + R_values[13] / (
        1 + w * 1.0j * t_values[13]) + R_values[14] / (1 + w * 1.0j *
        t_values[14]) + R_values[15] / (1 + w * 1.0j * t_values[15]
        ) + R_values[16] / (1 + w * 1.0j * t_values[16]) + R_values[17] / (
        1 + w * 1.0j * t_values[17]) + R_values[18] / (1 + w * 1.0j *
        t_values[18])


def type_input(convert_type=str, message='', prompt='>', allow_empty=False):
    """指定した型に変換可能な文字列を受け取ります。
    Args:
        convert_type ([str or int or float or bool], optional): 型。指定しなければ文字列型。
        message (str, optional): 入力を受け取るときに表示する文字列。 指定しなければ空文字列になります。
        prompt (str, optional): 入力を受け取るときに表示するプロンプト文字列。 指定しなければ"> "です。
        allow_empty (bool, optional): 空文字列を受け取った場合、Noneを返します。 指定しなければFalseです。

    Returns:
        pass_type or None: 指定した型、または、None。
    """
    type_str = str(convert_type).split("'")[1]
    text = f'{message} ({type_str}){prompt}'.strip()
    while True:
        receive = input(text).strip()
        if receive == '':
            if allow_empty:
                return None
            else:
                continue
        try:
            if convert_type is bool:
                converted = receive.lower()
                if converted in ('true', 'false'):
                    return converted == 'true'
            else:
                converted = convert_type(receive)
                return converted
        except Exception:
            continue


def update_namespace_node(node, single):
    """Update node information"""
    node['count'] += single.count
    node['duration'] += single.duration
    node['info'].add_activation(single.activation)


def render(uid, view):
    """Render column with context by uid with view.
        """


def generate_paths(paths):
    """
    Iterates over `paths` (which may consist of files and/or directories)
    and return list of files.
    """
    import os
    import subprocess
    files = []
    for path in paths:
        if os.path.isdir(path):
            files += sorted(subprocess.check_output(['find', path, '-type',
                'f', '-readable', '-writable', '!', '-empty', '(', '-name',
                '*.conf', '-o', '-name', '*.txt', ')', '-print0'], stderr=
                subprocess.DEVNULL, universal_newlines=True).rstrip('\x00')
                .split('\x00'))
        else:
            files.append(path)
    return files


def home():
    """Get the home directory"""
    from os.path import expanduser
    return expanduser('~')


def export_rft(text, out_path):
    """
	Write the modified text to a file.
	"""
    with open(out_path, 'w') as outfile:
        outfile.write(text)
    print('Modified topoly file written to {}'.format(out_path))


@staticmethod
def apply_additional_json(txt):
    """
        Called post-init to apply the contents of additional_to_json().
        """


@classmethod
def sd_dict_to_syslog_str(cls, sd_dict):
    """ Converts structured data dictionary to a syslog str """
    syslog_sds = ''
    for sd_key, sd_val in list(sd_dict.items()):
        syslog_str = '[{sd_key}'.format(sd_key=sd_key)
        for sub_key, sub_val in list(sd_val.items()):
            syslog_str = '{orig} {key}="{value}"'.format(orig=syslog_str,
                key=sub_key, value=sub_val)
        syslog_str += ']'
        syslog_sds += syslog_str
    return syslog_sds


@classmethod
def all_statuses(cls):
    """
        Return all possible statuses for an order
        """
    return list(cls.pipeline.keys())


@classmethod
def create_from_connection_string(cls, connection_string):
    """
        Create a Provisioning Service Client from a connection string

        :param str connection_string: The connection string for the Device Provisioning Service
        :return: A new instance of :class:`ProvisioningServiceClient
         <provisioningserviceclient.ProvisioningServiceClient>`
        :rtype: :class:`ProvisioningServiceClient
         <provisioningserviceclient.ProvisioningServiceClient>`
        :raises: ValueError if connection string is invalid
        """
    cs_args = connection_string.split(cls._cs_delimiter)
    if len(cs_args) != 3:
        raise ValueError('Too many or too few values in the connection string')
    if len(cs_args) > len(set(cs_args)):
        raise ValueError('Duplicate label in connection string')
    for arg in cs_args:
        tokens = arg.split(cls._cs_val_separator, 1)
        if tokens[0] == cls._host_name_label:
            host_name = tokens[1]
        elif tokens[0] == cls._shared_access_key_name_label:
            shared_access_key_name = tokens[1]
        elif tokens[0] == cls._shared_access_key_label:
            shared_access_key = tokens[1]
        else:
            raise ValueError('Connection string contains incorrect values')
    return cls(host_name, shared_access_key_name, shared_access_key)


def gravity_fmg(force, mass):
    """Usage: Find gravity using force and mass """
    return force / mass


def get_fields(schema):
    """Return a dictionary containing all the Fields in a schema.
    """
    from guillotina.schema.interfaces import IField
    fields = {}
    for name in schema:
        attr = schema[name]
        if IField.providedBy(attr):
            fields[name] = attr
    return fields


def reset_customclassifiers():
    """
        reset_customclassifiers

        Reset all the custom classifiers

        @return: None
        """


@classmethod
def force_create(cls, **attributes):
    """
        Save a new model an return the instance. Allow mass assignment.

        :param attributes: The instance attributes
        :type attributes: dict

        :return: The new instance
        :rtype: Model
        """
    cls.unguard()
    model = cls.create(**attributes)
    cls.reguard()
    return model


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


@conf
def find_icpc(conf):
    """
	Finds the program icpc, and execute it to ensure it really is icpc
	"""
    cxx = conf.find_program('icpc', var='CXX')
    conf.get_cc_version(cxx, icc=True)
    conf.env.CXX_NAME = 'icc'


def update_window(p, args):
    """Adds new args to a window if they exist"""
    content = p['content']
    layout_update = args.get('layout', {})
    for layout_name, layout_val in layout_update.items():
        if layout_val is not None:
            content['layout'][layout_name] = layout_val
    opts = args.get('opts', {})
    for opt_name, opt_val in opts.items():
        if opt_val is not None:
            p[opt_name] = opt_val
    if 'legend' in opts:
        pdata = p['content']['data']
        for i, d in enumerate(pdata):
            d['name'] = opts['legend'][i]
    return p


def DestroyEnvironment():
    """ Destroys global environment state """
    global ENVIRONMENT_BOOTSTRAP_COMPLETE, ENV_STATE
    ENVIRONMENT_BOOTSTRAP_COMPLETE = False
    ENV_STATE = None


def _items(sobject):
    """
    Extract the I{items} from a suds object much like the
    items() method works on I{dict}.
    @param sobject: A suds object
    @type sobject: L{Object}
    @return: A list of items contained in I{sobject}.
    @rtype: [(key, value),...]
    """
    for item in sobject:
        yield item


def set_without_children(node):
    """Populate ending locations for nodes that are guaranteed to never have
    children. E.g. Const.

    These node's end_col_offset are currently assigned based on their
    computed string representation. This may differ from their actual
    source code representation, however (mainly whitespace).

    Precondition: `node` must not have a `last_child` (node).
    """
    if not hasattr(node, 'end_lineno'):
        node.end_lineno = node.fromlineno
    if not hasattr(node, 'end_col_offset'):
        node.end_col_offset = node.col_offset + len(node.as_string())
    return node


@staticmethod
def to_dict(source):
    """
        Converts to a dictionary data.
        """
    try:
        return float(source)
    except ValueError:
        return None


@classmethod
def get_node_by_id(cls, graph, node_id):
    """Get the node that correspond to the ID of a :param graph.

        :param graph: The graph of the node
        :param node_id: The unique ID that represent the node
        :return: the node
        """
    return graph.node[node_id]


def tamper(payload, **kwargs):
    """
    Slash escape single and double quotes (e.g. ' -> ')

    >>> tamper('1" AND SLEEP(5)#')
    '1\\\\" AND SLEEP(5)#'
    """
    return payload.replace("'", "\\'").replace('"', '\\"')


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


def _find_best(dblist, query, threshold_bp):
    """
    Search for the best containment, return precisely one match.
    """
    best_cont = 0.0
    best_match = None
    best_filename = None
    for obj, filename, filetype in dblist:
        for cont, match, fname in obj.gather(query, threshold_bp=threshold_bp):
            assert cont
            if cont == best_cont and match.name() < best_match.name(
                ) or cont > best_cont:
                best_cont = cont
                best_match = match
                best_filename = fname or filename
    if not best_match:
        return None, None, None
    return best_cont, best_match, best_filename


def get_vpmems(flavor):
    """Return vpmems related to input request.

    :param flavor: a flavor object to read extra specs from
    :returns: a vpmem label list
    """
    vpmems_info = flavor.get('extra_specs', {}).get('hw:pmem')
    if not vpmems_info:
        return []
    vpmem_labels = vpmems_info.split(',')
    formed_labels = []
    for label in vpmem_labels:
        formed_label = label.strip()
        if formed_label:
            formed_labels.append(formed_label)
    return formed_labels


def render_charfield(field, attrs):
    """
	Render the generic CharField.
	"""
    return field


def load_column_names(filename):
    """
    Read the first line of the file and extract column names from it.
    Returns a dictionary with two elements:
        colnames        A list of column names
        indices         A dictionary of column indices, indexed by name
    """
    f = open(filename, 'r')
    line = f.readline()
    f.close()
    names = line.replace('#', '').replace(' ', '').replace('\n', '').split(',')
    indices = {}
    for i in range(0, len(names)):
        indices[names[i]] = i
    return {'colnames': names, 'indices': indices}


def bottom(root_ideal, start_index):
    """ Given a row index ``start_index``, look at it's :meth:`down_path` and return the final index.

        EXAMPLES:

        The picture below represents the root ideal used in the examples, and the path drawn on the picture depicts the down path for index 0 specifically, demonstrating that ``bottom(0)`` should be 4:

        .. image:: _static/bottom.JPG
            :width: 180px
            :align: center
            :alt: The root ideal [(0,2), (0,3), (0,4), (1,3), (1,4), (2,4)]

        ::

            sage: ri = RootIdeals().init_from_partition([3, 2, 1], 5)
            sage: ri.bottom(0)
            4
            sage: ri.bottom(1)
            3
            sage: ri.bottom(2)
            4
            sage: ri.bottom(3)
            3
            sage: ri.bottom(4)
            4

        ..  SEEALSO::

            :meth:`down`, :meth:`up`, :meth:`down_path`, :meth:`up_path`, :meth:`top`
        """
    return root_ideal.down_path(start_index)[-1]


def rollback_quietly():
    """
        Rollback the connection and return a true value on success.

        When this completes, the connection will be in a neutral state,
        not idle in a transaction.

        If an error occurs during rollback, the connection is dropped
        and a false value is returned.
        """


@staticmethod
def current() ->int:
    """
        Get the current supplied by the battery.

        ----------
        Returns - Battery current (mA).
        """
    return 0


def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox']
    prefs['save_objectdb'] = True
    prefs['compress_objectdb'] = False
    prefs['automatic_soa'] = True
    prefs['soa_followed_calls'] = 0
    prefs['perform_doa'] = True
    prefs['validate_objectdb'] = True
    prefs['max_history_items'] = 32
    prefs['save_history'] = True
    prefs['compress_history'] = False
    prefs['indent_size'] = 4
    prefs['extension_modules'] = []
    prefs['import_dynload_stdmods'] = True
    prefs['ignore_syntax_errors'] = False
    prefs['ignore_bad_imports'] = False
    prefs['split_imports'] = False
    prefs['sort_imports_alphabetically'] = False


def cluster_alignment_errors(alignment):
    """Clusters alignments
    Takes an alignment created by min_edit_distance_align() and groups
    consecutive errors together. This is useful, because there are often
    many possible alignments, and so often we can't meaningfully distinguish
    between alignment errors at the character level, so it makes many-to-many
    mistakes more readable."""
    newalign = []
    mistakes = [], []
    for align_item in alignment:
        if align_item[0] == align_item[1]:
            if mistakes != ([], []):
                newalign.append((tuple(mistakes[0]), tuple(mistakes[1])))
                mistakes = [], []
            newalign.append((tuple([align_item[0]]), tuple([align_item[1]])))
        else:
            if align_item[0] != '':
                mistakes[0].append(align_item[0])
            if align_item[1] != '':
                mistakes[1].append(align_item[1])
    if mistakes != ([], []):
        newalign.append((tuple(mistakes[0]), tuple(mistakes[1])))
        mistakes = [], []
    return newalign


@classmethod
def run(cls, meta_path, regions_path, regions_label=None, force=False, fout
    =None):
    """ Run full classification

        Parameters
        ----------
        meta_path : str
            Path to meta CSV file containing lat/lon points
        regions_path : str
            Path to regions shapefile containing labeled geometries
        regions_label : str
            Attribute to use a label in the regions shapefile
        force : str
            Force outlier classification by finding nearest
        fout : str
            Output CSV file path for labeled meta CSV file

        Examples
        --------
        >>> meta_path = 'meta.csv'
        >>> regions_path = 'us_states.shp'
        >>> regions_label = 'NAME'
        >>> force = True
        >>> fout = 'new_meta.csv'
        >>>
        >>> RegionClassifier.run(meta_path=meta_path,
                                 regions_path=regions_path,
                                 regions_label=regions_label
                                 force=force, fout=fout)
        """
    classifier = cls(meta_path=meta_path, regions_path=regions_path,
        regions_label=regions_label)
    classification = classifier.classify(force=force)
    if fout:
        cls.output_to_csv(classification, fout)
    return classification


def d_y_diffr_dx(x, y):
    """
    derivative of d(y/r)/dx
    equivalent to second order derivatives dr_dxy

    :param x:
    :param y:
    :return:
    """
    return -x * y / (x ** 2 + y ** 2) ** (3 / 2.0)


def __len__():
    """Return number of terms."""


def area_dupli():
    """Duplicate selected area into new window

    """
    pass


def _get_bytearray_from_array(src: 'typing.Iterable[bytes]') ->bytearray:
    """Get bytearray from array of bytes blocks.

    :param src: source to process
    :type src: typing.List[bytes]
    :return: bytearray
    :rtype: bytearray
    """
    return bytearray(b''.join(src))


def arithmetic_mean(col):
    """ Arithmetic mean of `col`. """
    return sum(col) / len(col)


def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
    """Unsets a cookie by name, by default over all domains and paths.

    Wraps CookieJar.clear(), is O(n).
    """
    clearables = []
    for cookie in cookiejar:
        if cookie.name != name:
            continue
        if domain is not None and domain != cookie.domain:
            continue
        if path is not None and path != cookie.path:
            continue
        clearables.append((cookie.domain, cookie.path, cookie.name))
    for domain, path, name in clearables:
        cookiejar.clear(domain, path, name)


def lsim(sys, U=0.0, T=None, X0=0.0):
    """
    Simulate the output of a linear system.

    As a convenience for parameters `U`, `X0`:
    Numbers (scalars) are converted to constant arrays with the correct shape.
    The correct shape is inferred from arguments `sys` and `T`.

    Parameters
    ----------
    sys: LTI (StateSpace, or TransferFunction)
        LTI system to simulate

    U: array-like or number, optional
        Input array giving input at each time `T` (default = 0).

        If `U` is ``None`` or ``0``, a special algorithm is used. This special
        algorithm is faster than the general algorithm, which is used otherwise.

    T: array-like
        Time steps at which the input is defined, numbers must be (strictly
        monotonic) increasing.

    X0: array-like or number, optional
        Initial condition (default = 0).

    Returns
    -------
    yout: array
        Response of the system.
    T: array
        Time values of the output.
    xout: array
        Time evolution of the state vector.

    See Also
    --------
    step, initial, impulse

    Examples
    --------
    >>> yout, T, xout = lsim(sys, U, T, X0)
    """
    from ..timeresp import forced_response
    T, yout, xout = forced_response(sys, T, U, X0, transpose=True)
    return yout, T, xout


def _get_package_status(package):
    """Get the status for a package."""
    status = package['status_str'] or 'Unknown'
    stage = package['stage_str'] or 'Unknown'
    if stage == 'Fully Synchronised':
        return status
    return '%(status)s / %(stage)s' % {'status': status, 'stage': stage}


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


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


def unicode_storage(storage):
    """Convert all values in storage to unicode and assert that all keys
    can be converted

    >>> unicode_storage(Storage(a='b', b=1))
    Storage(a='b', b='1')
    """
    for key in storage:
        storage[key] = str(storage[key])
    return storage


def detect_regressions(steps, threshold=0):
    """Detect regressions in a (noisy) signal.

    A regression means an upward step in the signal.  The value
    'before' a regression is the value immediately preceding the
    upward step.  The value 'after' a regression is the minimum of
    values after the upward step.

    Parameters
    ----------
    steps : list of (left, right, value, min, error)
        List of steps computed by detect_steps, or equivalent
    threshold : float
        Relative threshold for reporting regressions. Filter out jumps
        whose relative size is smaller than threshold, if they are not
        necessary to explain the difference between the best and the latest
        values.

    Returns
    -------
    latest_value
        Latest value
    best_value
        Best value
    regression_pos : list of (before, after, value_before, value_after)
        List of positions between which the value increased. The first item
        corresponds to the last position at which the best value was obtained.

    """
    if not steps:
        return None, None, None
    regression_pos = []
    last_v = steps[-1][2]
    best_v = last_v
    best_err = steps[-1][4]
    prev_l = None
    for l, r, cur_v, cur_min, cur_err in reversed(steps):
        if best_v - cur_v > max(cur_err, best_err, threshold * cur_v):
            regression_pos.append((r - 1, prev_l, cur_v, best_v))
        prev_l = l
        if cur_v < best_v:
            best_v = cur_v
            best_err = cur_err
    regression_pos.reverse()
    if regression_pos:
        return last_v, best_v, regression_pos
    else:
        return None, None, None


def p_testlist_comp_star_2(p):
    """testlist_comp_star : testlist_comp_star COMMA test"""
    p[0] = p[1] + [p[3]]


def safe_get(d, key, def_val=None):
    """
    Helper function to fetch value from a dictionary

    * `d` - Dictionary to fetch value from
    * `key` - Key to lookup in dictionary
    * `def_val` - Default value to return if dict does not have a member with key
    """
    if key in d:
        return d[key]
    else:
        return def_val


def unescape(s, quote=False):
    """
    The opposite of the cgi.escape function.
    Replace escaped characters '&', '<' and '>' with the corresponding
    regular characters. If the optional flag quote is true, the escaped quotation
    mark character ('"') is also translated.
    """
    s = s.replace('<', '<')
    s = s.replace('>', '>')
    if quote:
        s = s.replace('"', '"')
    s = s.replace('&', '&')
    return s


def provides_facts():
    """
    Returns a dictionary keyed on the facts provided by this module. The value
    of each key is the doc string describing the fact.
    """
    return {'_is_linux':
        'A boolean indicating if the device is running linuxkernel.'}


@classmethod
def validate_security(cls, app, ssl_options=None):
    """Prevent warnings about security from base class"""
    return


def get_policy(policyName=None):
    """
    Gets information about the specified policy with the policy document of the default version.
    See also: AWS API Documentation

    :example: response = client.get_policy(
        policyName='string'
    )

    :type policyName: string
    :param policyName: [REQUIRED]
            The name of the policy.

    :rtype: dict
    :return: {
        'policyName': 'string',
        'policyArn': 'string',
        'policyDocument': 'string',
        'defaultVersionId': 'string'
    }

    """
    pass


def check_arcade_project(path):
    """
    Check if the current folder is an arcade project
    """
    pass


@classmethod
def get_cooling_agent(cls, ID):
    """Return cooling agent with given ID."""
    for agent in cls.cooling_agents:
        if agent.ID == ID:
            return agent
    raise KeyError(ID)


def is_vm(obj):
    """
    Checks if object is a vim.VirtualMachine.

    :param obj: The object to check
    :return: If the object is a VM
    :rtype: bool
    """
    return hasattr(obj, 'summary')


@classmethod
def _after_postgeneration(cls, instance, create, results=None):
    """Update the related page's languages (taken from DjangoCMS's create_page helper)."""
    super()._after_postgeneration(instance, create, results=results)
    page = instance.page
    if page:
        page_languages = page.get_languages()
        if instance.language not in page_languages:
            page.update_languages(page_languages + [instance.language])


def manage_acquiredPermissions(permissions=[]):
    """Change the permissions that acquire.
        """


def adapts(*interfaces):
    """Declare that a class adapts the given interfaces.

        This function can only be used in a class definition.

        (TODO, allow classes to be passed as well as interfaces.)
        """


def _on_message_simple(client, userdata, message):
    """Internal callback"""
    if userdata['msg_count'] == 0:
        return
    if message.retain and not userdata['retained']:
        return
    userdata['msg_count'] = userdata['msg_count'] - 1
    if userdata['messages'] is None and userdata['msg_count'] == 0:
        userdata['messages'] = message
        client.disconnect()
        return
    userdata['messages'].append(message)
    if userdata['msg_count'] == 0:
        client.disconnect()


def define(zelf, *args, **kwargs):
    """ set a attribute on this ding. """
    name = args[0]
    value = args[1]
    zelf[name] = value


def pcaTable(pca_evolution):
    """Make table with PCA formation mean and std"""
    pass


def no_prefix(name):
    """does the given constant have a ZMQ_ prefix?"""
    return name.startswith('E') and not name.startswith('EVENT')


def encode_boolean(obj):
    """lower the case to get a json/js boolean"""
    return str(obj).lower()


def stringLengthCompare(a, b):
    """
    _stringLengthCompare_

    Sort comparison function to sort strings by length from longest to shortest.
    """
    if len(a) > len(b):
        return -1
    if len(a) == len(b):
        return 0
    else:
        return 1


def _unsigned(number):
    """
    Converts the given number to unsigned assuming
    a 32 bit value.

    :type number: int
    :param number: The number to be converted to unsigned.
    :rtype: int
    :return: The given number converted to unsigned.
    """
    if number >= 0:
        return number
    return number + 4294967296


def childAborted(f):
    """Notify the Slicer that one of its child slicers (as produced by
        its .slice iterator) has caused an error. If the slicer got started,
        it has now emitted an ABORT token and terminated its token stream.
        If it did not get started (usually because the child object was
        unserializable), there has not yet been any trace of the object in
        the token stream.

        The corresponding Unslicer (receiving this token stream) will get an
        BananaFailure and is likely to ignore any remaining tokens from us,
        so it may be reasonable for the parent Slicer to give up as well.

        If the Slicer wishes to abandon their own sequence, it should simply
        return the failure object passed in. If it wants to absorb the
        error, it should return None."""


def get_weekday_info(vehicle_journey_element):
    """Parses weekday info from TransXChange VehicleJourney element"""
    j = vehicle_journey_element
    try:
        reg_weekdays = (j.OperatingProfile.RegularDayType.DaysOfWeek.
            get_elements())
        weekdays = []
        for elem in reg_weekdays:
            weekdays.append(elem._name)
        if len(weekdays) == 1:
            return weekdays[0]
        else:
            return '|'.join(weekdays)
    except:
        return None


def setBlacklistStatus(category, status):
    """Manage the blacklisting status of the given category.

        If status is None, the blacklist status will be obtained from a parent,
        defaulting to False. If status is False, the given portlet category
        will always be eligible for display. If status is True, the given
        portlet category will always be blocked.

        Thus, call setBlacklistStatus('user', True) to always black out 'user'
        portlets in this context, or setBlacklistStatus('user', False) to
        override any blacklisting done by a parent object. Calling
        setBlacklistStatus('user', None) will cause the status to be acquired
        from the parent instead (defaulting to no blacklisting).
        """


def raise_truthy(d, k, exception=None):
    """Raises exception if value is truthy.

    Parameters
    ----------
    d : dict
    k : str
    exception : Exception, optional

    Returns
    -------
    None

    Raises
    ------
    ValueError
        When dict value is truthy and a custom exception is not passed.

    """
    val = d.get(k)
    if val:
        raise (exception or ValueError(k))
    return val


def reformat_content_lines(content, fmt, header=None, footer=None):
    """Apply a (new-style) Python format expression to each line of a string
    content block.

    Also optionally add a header and/or footer to the content block.

    Parameters
    ----------
    fmt : `str`
        Python format statement that each line of the content is processed
        with. The default format argument is the original content line.
        For example, ``# {}`` turns the content into a Python comment.
    header : `str`, optional
        Text content that can be added above the original content.
    footer : `str`, optional
        Text content that can be added before the original content
    """
    content_lines = content.rstrip().split('\n')
    output_lines = []
    if header is not None:
        output_lines.append(header)
    for line in content_lines:
        output_lines.append(fmt.format(line).rstrip())
    if footer is not None:
        output_lines.append(footer)
    return '\n'.join(output_lines) + '\n'


def condense_border_none(css):
    """Condense border:none; to border:0;."""
    return css.replace('border:none;', 'border:0;')


def nice_keys(keywords):
    """
      joins coumpound keyphrases, if needed
    """
    for w in keywords:
        if isinstance(w, tuple):
            yield ' '.join(w)
        else:
            yield w


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

        :param FileRequestCloseType val:
        :rtype: EventType
        """
    return cls('file_request_close', val)


def _render_jinja2(recipe_dir):
    """Evaluate Conda recipe as a jinja template."""
    try:
        import jinja2
    except ImportError:
        raise Exception(
            'Failed to import jinja2 for evaluating Conda recipe templates.')
    loaders = [jinja2.FileSystemLoader(recipe_dir)]
    env = jinja2.Environment(loader=jinja2.ChoiceLoader(loaders))
    template = env.get_or_select_template('meta.yaml')
    return template.render(environment=env)


@classmethod
def _render_options(cls, options: dict, input_type: str, default: str,
    render_options: bool) ->str:
    """
        Returns a string to present to the user specifying the available
        options. 'options' must be normalized.
        """
    render = ''
    if render_options:
        if options and input_type in [cls.STR, cls.BOOL]:
            if input_type == cls.BOOL:
                if len(options) >= 2:
                    render += ' (%s/%s)' % (options['1'], options['2'])
                if default:
                    render += ' \\[%s\\]' % default
            else:
                render += ' default: %s\n' % default if default else '\n'
                for item, value in options.items():
                    render += '  %s) %s\n' % (item, value)
    return render


def narrow_row(x, start, stop):
    """Narrow down the tensor along the first dimension.

    Parameters
    ----------
    x : Tensor
        The input tensor.
    start : int
        The start index (inclusive).
    stop : int
        The stop index (exclusive).

    Returns
    -------
    Tensor
        The narrowed tensor

    Notes
    -----
    The returned tensor could be a view of the original tensor.
    """
    pass


def move_workspace(old_path, new_path):
    """ Find data files in old workspace folder and move to new location """


def is_hater(weak_order):
    """Whether a weak order represents a "hater".

    Parameters
    ----------
    weak_order : str
        A weak order, e.g. ``'a>b~c'``, ``'a~b>c'``, etc.

    Returns
    -------
    bool
        True iff the weak order is of the form ``'a~b>c'``.

    Examples
    --------
        >>> is_hater('a~b>c')
        True
    """
    return weak_order[3] == '>'


def __sub__(other):
    """extent - set: given BTrees.IFBTree data structure, return difference"""


def index(a):
    """Same as a.__index__()."""
    return a.__index__()


def describe_delivery_channel_status(DeliveryChannelNames=None):
    """
    Returns the current status of the specified delivery channel. If a delivery channel is not specified, this action returns the current status of all delivery channels associated with the account.
    See also: AWS API Documentation

    :example: response = client.describe_delivery_channel_status(
        DeliveryChannelNames=[
            'string',
        ]
    )

    :type DeliveryChannelNames: list
    :param DeliveryChannelNames: A list of delivery channel names.
            (string) --

    :rtype: dict
    :return: {
        'DeliveryChannelsStatus': [
            {
                'name': 'string',
                'configSnapshotDeliveryInfo': {
                    'lastStatus': 'Success'|'Failure'|'Not_Applicable',
                    'lastErrorCode': 'string',
                    'lastErrorMessage': 'string',
                    'lastAttemptTime': datetime(2015, 1, 1),
                    'lastSuccessfulTime': datetime(2015, 1, 1),
                    'nextDeliveryTime': datetime(2015, 1, 1)
                },
                'configHistoryDeliveryInfo': {
                    'lastStatus': 'Success'|'Failure'|'Not_Applicable',
                    'lastErrorCode': 'string',
                    'lastErrorMessage': 'string',
                    'lastAttemptTime': datetime(2015, 1, 1),
                    'lastSuccessfulTime': datetime(2015, 1, 1),
                    'nextDeliveryTime': datetime(2015, 1, 1)
                },
                'configStreamDeliveryInfo': {
                    'lastStatus': 'Success'|'Failure'|'Not_Applicable',
                    'lastErrorCode': 'string',
                    'lastErrorMessage': 'string',
                    'lastStatusChangeTime': datetime(2015, 1, 1)
                }
            },
        ]
    }

    """
    pass


def nice_years(l, dash='-', join=' '):
    """Convert a list of years into brief range like '1900-1901, 1921'."""
    if not l:
        return ''
    start = end = int(l[0])
    ranges = []
    for year in (l[1:] + [0]):
        year = int(year)
        if year == end + 1:
            end = year
            continue
        if start == end:
            ranges.append('%s' % start)
        else:
            ranges.append('%s%s%s' % (start, dash, end))
        start = end = year
    assert start == 0 and end == 0, (start, end)
    return join.join(ranges)


def _get_enzrnx_to_sequence_mapping(enzrxn_to_monomer, sequences):
    """Get mapping of enzyme reactions to sequences."""
    enzrxn_to_sequence = {}
    for enzrxn, monomers in enzrxn_to_monomer.items():
        for monomer in monomers:
            try:
                sequence = sequences[monomer]
                enzrxn_to_sequence.setdefault(enzrxn, dict())[monomer
                    ] = sequence
            except KeyError:
                pass
    return enzrxn_to_sequence


def _deactivate_multi_threading():
    """ disable multi threading (needed for to reset app environment in unit testing). """
    global _multi_threading_activated
    _multi_threading_activated = False


def provider_parser(subparser):
    """Generate a provider parser for Softlayer"""
    subparser.add_argument('--auth-username', help=
        'specify username for authentication')
    subparser.add_argument('--auth-api-key', help=
        'specify API private key for authentication')


def to_json(obj):
    """Utility method for converting an object to a json encoded string.

    Takes care of all the necessary setup.

    Args:
        obj (object): The object that should be encoded.

    Returns:
        str: The encoded version of the given object.
    """
    import jsonpickle
    jsonpickle.set_encoder_options('simplejson', sort_keys=True)
    return jsonpickle.encode(obj, unpicklable=False)


@classmethod
def rackdiag(cls, *args):
    """
        executes rackdiag with the given arguments
        :param args:
        :return:
        """
    return cls.execute('rackdiag', args)


@classmethod
def _from_et(cls, root, parent):
    """
        Create a :class:`Package` from a :code:`package` element.

        :param root: The element tree tree to parse.
        :param parent: :class:`EagleFilePart` that should hold the resulting :class:`EagleFilePart`
        :rtype: :class:`Package`
        """
    n = cls()
    n._init_from_et(root, parent)
    return n


def set_scene_frames():
    """Set scene’s start and end frame to match clip’s start frame and length

    """
    pass


def str_to_two_byte_iter(string):
    """
    Return a iter consisting of two byte chars from a string.
    """
    bstring = string.encode()
    bytes = bytearray()
    for char in bstring:
        bytes.append(char)
        bytes.append(0)
    return bytes


@classmethod
def _from_et(cls, root, parent):
    """
        Create a :class:`Circle` from a :code:`circle` element.

        :param root: The element tree tree to parse.
        :param parent: :class:`EagleFilePart` that should hold the resulting :class:`EagleFilePart`
        :rtype: :class:`Circle`
        """
    n = cls()
    n._init_from_et(root, parent)
    return n


@classmethod
def start_timing(cls, name):
    """ Start timer named *name*

            :param str name: name of timer to be started
        """
    cls.query_timers[name] = 0.0


def _overload_dummy(*args, **kwds):
    """Helper for @overload to raise when called."""
    raise NotImplementedError(
        'You should not call an overloaded function. A series of @overload-decorated functions outside a stub module should always be followed by an implementation that is not @overload-ed.'
        )


def is_redirect_or_down(endpoint):
    """
    Endpoint is a redirect or down if it is a redirect to an external site or it is down in any of 3 ways:
    it is not live, it is HTTPS and has a bad hostname in the cert, or it responds with a 4xx error code
    """
    return (endpoint.redirect_eventually_to_external or not endpoint.live or
        endpoint.protocol == 'https' and endpoint.https_bad_hostname or
        endpoint.status is not None and endpoint.status >= 400)


def duplicate(do_flip_names: bool=False):
    """Make copies of the selected bones within the same armature

    :param do_flip_names: Flip Names, Try to flip names of the bones, if possible, instead of adding a number extension
    :type do_flip_names: bool
    """
    pass


def iter_slices(string, slice_length):
    """Iterate over slices of a string."""
    pos = 0
    if slice_length is None or slice_length <= 0:
        slice_length = len(string)
    while pos < len(string):
        yield string[pos:pos + slice_length]
        pos += slice_length


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


@staticmethod
def rel_output(output_id, percent):
    """Generate a command to change the value of an output-port.

        :param    int    output_id:    Output id 0..3
        :param    int    percent:      Relative percentage -100..100
        :return:    The PCK command (without address header) as text
        :rtype:    str
        """
    if output_id < 0 or output_id > 3:
        raise ValueError('Invalid output_id.')
    percent_round = round(percent * 2)
    if percent_round % 2 == 0:
        pck = 'A{:d}{:s}{:03d}'.format(output_id + 1, 'AD' if percent >= 0 else
            'SB', abs(percent_round // 2))
    else:
        pck = 'O{:d}{:s}{:03d}'.format(output_id + 1, 'AD' if percent >= 0 else
            'SB', abs(percent_round))
        return pck


def _google_spreadsheet_url(key):
    """
    Returns full editing URL for a Google Spreadsheet given its key
    """
    return 'https://docs.google.com/spreadsheets/d/{key}/edit'.format(key=key)


@staticmethod
def _parse_instance_info(node):
    """Gets the instance specific Node deployment info.

        This method validates whether the 'instance_info' property of the
        supplied node contains the required or optional information properly
        for this driver to deploy images to the node.

        :param node: a target node of the deployment
        :returns:  the instance_info values of the node.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
    deploy_info = node.instance_info.copy()
    return deploy_info


@staticmethod
def _merge_with(node, delete_node):
    """Concat forms, merge feats, remove `delete_node`, and keep SpaceAfter of the right node.

        Should be called only on neighboring nodes.
        """
    if node.precedes(delete_node):
        node.form += delete_node.form
        node.misc['SpaceAfter'] = delete_node.misc['SpaceAfter']
    else:
        node.form = delete_node.form + node.form
    if node.parent == delete_node:
        node.parent = delete_node.parent
    for child in delete_node.children:
        child.parent = node
    delete_node.feats.update(node.feats)
    node.feats = delete_node.feats
    delete_node.remove()


def project_inv(pt, proj_axis, a, v):
    """Returns the vector w in the surface's plane such that project(w) equals x.

    See http://stackoverflow.com/a/39008641/1706564

    :param pt: A two-dimensional point.
    :param proj_axis: The axis to project into.
    :param a: Distance to the origin for the plane to project into.
    :param v: Normal vector of the plane to project into.
    :returns: The transformed point.

    """
    w = list(pt)
    w[proj_axis:proj_axis] = [0.0]
    c = a
    for i in range(3):
        c -= w[i] * v[i]
    c /= v[proj_axis]
    w[proj_axis] = c
    return tuple(w)


def mark_seam(clear: bool=False):
    """(Un)mark selected edges as a seam

    :param clear: Clear
    :type clear: bool
    """
    pass


def _convert_exception(exception):
    """Convert an Exception into a failure document for publishing."""
    return {'errmsg': str(exception), 'errtype': exception.__class__.__name__}


def wx_color_to_rgb(wx_color):
    """Convert a wxPython color to an RGB color."""
    return wx_color.red / 255, wx_color.green / 255, wx_color.blue / 255


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


def set_in(dct, keys, value):
    """Sets the value in dct at the nested path indicated by keys"""
    for key in keys[:-1]:
        if key not in dct:
            dct[key] = {}
        dct = dct[key]
    leaf_key = keys[-1]
    if leaf_key in dct and isinstance(dct[leaf_key], dict):
        raise Exception(
            f"Unable to set value because {'.'.join(keys)} is a configuration section."
            )
    else:
        dct[leaf_key] = value


@classmethod
def get_name(cls):
    """ Returns the name of the supplier.
        """
    return 'jsonl'


def _escape_xref(xref_match):
    """Escape things that need to be escaped if they're in a cross-reference.
    """
    xref = xref_match.group()
    xref = xref.replace('/', '%2F')
    xref = xref.replace('?', '%3F')
    xref = xref.replace('#', '%23')
    return xref


def check_for_bypass_url(raw_creds, nova_args):
    """
    Return a list of extra args that need to be passed on cmdline to nova.
    """
    if 'BYPASS_URL' in raw_creds.keys():
        bypass_args = ['--bypass-url', raw_creds['BYPASS_URL']]
        nova_args = bypass_args + nova_args
    return nova_args


def shifted_data_covariance(dataX, dataY):
    """Fixes catastrophic cancellation probelem"""
    n = len(dataX)
    if n < 2:
        return 0
    Kx = dataX[0]
    Ky = dataY[0]
    Ex = Ey = Exy = 0
    for iX, iY in zip(dataX, dataY):
        Ex += iX - Kx
        Ey += iY - Ky
        Exy += (iX - Kx) * (iY - Ky)
    return (Exy - Ex * Ey / n) / n


def modsplit(module):
    """Split module into submodules."""
    return tuple(module.split('.'))


@classmethod
def cyan(cls, string, auto=False):
    """Color-code entire string.

        :param str string: String to colorize.
        :param bool auto: Enable auto-color (dark/light terminal).

        :return: Class instance for colorized string.
        :rtype: Color
        """
    return cls.colorize('cyan', string, auto=auto)


@staticmethod
def user_parse(data):
    """Parse information from provider."""
    yield 'id', data.get('id')
    yield 'email', data.get('email')
    yield 'first_name', data.get('given_name')
    yield 'last_name', data.get('family_name')
    yield 'link', data.get('link')
    yield 'locale', data.get('locale')
    yield 'picture', data.get('picture')
    yield 'gender', data.get('gender')


@staticmethod
def get_node_text(node):
    """Get text from node's 'y:NodeLabel' parameter.
        Args:
            node (xml.element): Node to search within.
        Returns:
            If successfull, return text. Else, return None.
        """
    try:
        return node.getElementsByTagName('y:NodeLabel')[0].childNodes[0
            ].data.strip()
    except IndexError:
        return


def Check_Type(poly):
    """Ensures input for polymorphism type is an accepted value

    Parameters
    ----------
    poly : str
        A string representing the type of polymorphism. Either 'SNP' or 'INDEL'
    """
    if poly != 'SNP' and poly != 'INDEL':
        raise ValueError('--type takes only values SNP or INDEL')
    return


def object_data_add(context: 'bpy.types.Context', obdata: 'bpy.data',
    operator: 'bpy.types.Operator'=None, use_active_layer=True, name: str=None
    ) ->'bpy.types.ObjectBase':
    """Add an object using the view context and preference to to initialize the location, rotation and layer.

    :param context: The context to use.
    :type context: 'bpy.types.Context'
    :param obdata: the data used for the new object.
    :type obdata: 'bpy.data'
    :param operator: The operator, checked for location and rotation properties.
    :type operator: 'bpy.types.Operator'
    :param name: Optional name
    :type name: str
    :return:  the newly created object in the scene.
    """
    pass


def addmany(sequence):
    """Like "for item, score in sequence: self.add(item, score)".

        This is simply faster than calling add() len(seq) times.
        """


def move_to_layer(layers: bool=(False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False)):
    """Move the object to different layers

    :param layers: Layer
    :type layers: bool
    """
    pass


@staticmethod
def iter_params():
    """return (XOR key1, ADD key2)"""
    for xor_key in range(1, 256):
        for add_key in range(1, 256):
            yield xor_key, add_key


def __call__(environ, start_response):
    """Called by a WSGI server.

        The ``environ`` parameter is a dictionary object, containing CGI-style
        environment variables. This object must be a builtin Python dictionary
        (not a subclass, UserDict or other dictionary emulation), and the
        application is allowed to modify the dictionary in any way it
        desires. The dictionary must also include certain WSGI-required
        variables (described in a later section), and may also include
        server-specific extension variables, named according to a convention
        that will be described below.

        The ``start_response`` parameter is a callable accepting two required
        positional arguments, and one optional argument. For the sake of
        illustration, we have named these arguments ``status``,
        ``response_headers``, and ``exc_info``, but they are not required to
        have these names, and the application must invoke the
        ``start_response`` callable using positional arguments
        (e.g. ``start_response(status, response_headers)``).
        """


@staticmethod
def setup_subparser(parser, cmd=None):
    """
        Set up a subparser for 'install'
        """
    group = parser.add_argument_group('Install arguments' if cmd ==
        'install' else 'Update arguments')
    group.add_argument('packages', help=
        'List of packages to install/update', action='append', default=[],
        nargs='*', metavar='PACKAGES')
    group.add_argument('--print-tree', help='Print dependency tree', action
        ='store_true')
    group.add_argument('--no-deps', help=
        'Skip dependencies (may cause builds to fail!)', action='store_true')
    group.add_argument('--verify', help='Verify installs were successful',
        action='store_true')
    if cmd == 'install':
        group.add_argument('--static', help=
            'Build package(s) statically (implies source build)', action=
            'store_true')
        group.add_argument('--deps-only', help=
            'Only install the dependencies, not the requested packages',
            action='store_true')
        group.add_argument('-u', '--update', help=
            'If packages are already installed, update them instead.',
            action='store_true')
    elif cmd == 'update':
        group.add_argument('-a', '--all', help=
            'Update all packages installed to current prefix, including dependencies.'
            , action='store_true')


def m22feet2(area_m2):
    """Converts area value from meters squared to feet squared"""
    return area_m2 * 10.7639


def is_mutating(status):
    """Determines if the statement is mutating based on the status."""
    if not status:
        return False
    mutating = set(['insert', 'update', 'delete', 'alter', 'create', 'drop'])
    return status.split(None, 1)[0].lower() in mutating


def flux(data, segmap, source):
    """
    Total flux in segmap.

    Parameters
    ----------

    Returns
    -------

    """
    return {'flux': source.get_data(data=data, segmap=segmap).sum()}


def open_file_handles(backends, path, mode, schema, *, remote_operation=False):
    """Open backend accessor file handles for reading

    Parameters
    ----------
    backends : Set[str]
        if ``mode == 'r'`` then this should be the used backend format
        codes in the column. if ``mode == 'a'``, then this should be a
        list of the allowed backend format codes this schema can feasably
        write to.
    path : Path
        path to the hangar repository on disk
    mode : str
        one of ['r', 'a'] indicating read or write mode to open backends in.
    schema : ColumnDefinitionTypes
        schema spec so required values can be filled in to backend openers.

    Returns
    -------
    AccessorMapType
        dict mapping backend format codes to initialized instances of each
        read-only backend.
    """
    from ..backends import BACKEND_ACCESSOR_MAP
    fhandles = {}
    for be, accessor in BACKEND_ACCESSOR_MAP.items():
        if be in backends:
            if accessor is None:
                continue
            init_requires = schema._beopts.init_requires
            kwargs = {}
            for arg in init_requires:
                if arg == 'repo_path':
                    kwargs[arg] = path
                elif arg == 'schema_shape':
                    kwargs[arg] = schema.shape
                elif arg == 'schema_dtype':
                    kwargs[arg] = schema.dtype
            fhandles[be] = accessor(**kwargs)
            fhandles[be].open(mode=mode, remote_operation=remote_operation)
    if mode == 'a':
        if schema.backend in fhandles:
            fhandles[schema.backend].backend_opts = schema.backend_options
    return fhandles


def stripnull(string, null=b'\x00'):
    """Return string truncated at first null character.

    Clean NULL terminated C strings. For unicode strings use null='\\0'.

    >>> stripnull(b'string\\x00')
    b'string'
    >>> stripnull('string\\x00', null='\\0')
    'string'

    """
    i = string.find(null)
    return string if i < 0 else string[:i]


def _pre_mcs_init(cls):
    """
        Callback for BaseModelMetaclass subclasses to run code just before a
        concrete Model class gets registered with SQLAlchemy.

        This is intended to be used for advanced meta options implementations.
        """


def normalize_value(val, _min, _max):
    """
    Normalize value `val` to value from interval (0, 1) based on `_min` and `_max`.

    :param val: float;
    :param _min: float;
    :param _max: float;
    :return: float;
    """
    return (val - _min) / (_max - _min)


def hex_to_dec(x):
    """
    Convert hex to decimal
    """
    return int(x, 16)


@classmethod
def from_transport(cls, t, window_size=None, max_packet_size=None):
    """
        Create an SFTP client channel from an open `.Transport`.

        Setting the window and packet sizes might affect the transfer speed.
        The default settings in the `.Transport` class are the same as in
        OpenSSH and should work adequately for both files transfers and
        interactive sessions.

        :param .Transport t: an open `.Transport` which is already
            authenticated
        :param int window_size:
            optional window size for the `.SFTPClient` session.
        :param int max_packet_size:
            optional max packet size for the `.SFTPClient` session..

        :return:
            a new `.SFTPClient` object, referring to an sftp session (channel)
            across the transport

        .. versionchanged:: 1.15
            Added the ``window_size`` and ``max_packet_size`` arguments.
        """
    chan = t.open_session(window_size=window_size, max_packet_size=
        max_packet_size)
    if chan is None:
        return None
    chan.invoke_subsystem('sftp')
    return cls(chan)


def conv_select(bcm_save, bpp_save, final_kstar_1, final_kstar_2, method,
    conv_lims):
    """Select bcm data for special convergence cases

    Parameters
    ----------
    bcm_save : `pandas.DataFrame`
        bcm dataframe containing all saved bcm data

    bpp_save : `pandas.DataFrame`
        bpp dataframe containing all saved bpp data

    final_kstar_1 : `list`
        contains list of final primary kstars specified by user

    final_kstar_2 : `list`
        contains list of final primary kstars specified by user

    method : `str`
        stage in binary evolution to check convergence for
        only one method may be supplied and they are specified
        in the inifile

    conv_lims : `dict`
        dictionary where keys are convergence params and the
        values are lists containing a [lo, hi] value to filter the
        convergence param between
        any non-specified convergence params will not be filtered

    Returns
    -------
    conv_save : `pandas.DataFrame`
        filtered dataframe containing binaries that fulfill
        user-specified convergence criteria

    """
    _known_methods = ['formation', '1_SN', '2_SN', 'disruption',
        'final_state', 'XRB_form']
    if not method in _known_methods:
        raise ValueError(
            'You have supplied an unknown method to filter the bcm array for convergence. Known methods are {0}'
            .format(_known_methods))
    if method == 'formation':
        conv_save = bpp_save.loc[bpp_save.kstar_1.isin(final_kstar_1) &
            bpp_save.kstar_2.isin(final_kstar_2) & (bpp_save.sep > 0) &
            bpp_save.evol_type.isin([2.0, 4.0])]
        conv_save = conv_save.groupby('bin_num').first().reset_index()
    elif method == '1_SN':
        conv_sn_ind = bpp_save.loc[bpp_save.evol_type.isin([15.0, 16.0])
            ].bin_num
        conv_sn_ind = bpp_save.loc[bpp_save.bin_num.isin(conv_sn_ind) &
            bpp_save.kstar_1.isin(final_kstar_1) & bpp_save.kstar_2.isin(
            final_kstar_2) & (bpp_save.sep > 0)].bin_num
        conv_sn = bpp_save.loc[bpp_save.bin_num.isin(conv_sn_ind) &
            bpp_save.evol_type.isin([15.0, 16.0])]
        conv_save = conv_sn.groupby('bin_num').first().reset_index()
    elif method == '2_SN':
        conv_sn_ind = bpp_save.loc[bpp_save.evol_type.isin([15.0, 16.0])
            ].bin_num
        conv_sn_ind = bpp_save.loc[bpp_save.bin_num.isin(conv_sn_ind) &
            bpp_save.kstar_1.isin(final_kstar_1) & bpp_save.kstar_2.isin(
            final_kstar_2) & (bpp_save.sep > 0)].bin_num
        conv_sn = bpp_save.loc[bpp_save.bin_num.isin(conv_sn_ind) &
            bpp_save.evol_type.isin([15.0, 16.0])]
        conv_sn_2 = conv_sn.loc[conv_sn.groupby('bin_num').size() == 2]
        conv_save = conv_sn_2.groupby('bin_num').nth(1).reset_index()
    elif method == 'disruption':
        conv_ind = bpp_save.loc[bpp_save.kstar_1.isin(final_kstar_1) &
            bpp_save.kstar_2.isin(final_kstar_2)].bin_num.unique()
        conv_save = bpp_save.loc[bpp_save.bin_num.isin(conv_ind)]
        conv_save_reset = conv_save.reset_index()
        conv_save_reset_ind = conv_save_reset.loc[conv_save_reset.evol_type ==
            11.0].index
        conv_save = conv_save_reset.iloc[conv_save_reset_ind]
    elif method == 'final_state':
        conv_save = bcm_save
    elif method == 'XRB_form':
        conv_ind = bpp_save.loc[bpp_save.evol_type.isin([15.0, 16.0])
            ].bin_num.unique()
        conv_sn = bpp_save.loc[bpp_save.bin_num.isin(conv_ind)]
        conv_xrb = conv_sn.loc[conv_sn.kstar_1.isin(final_kstar_1) &
            conv_sn.kstar_2.isin(final_kstar_2) & (conv_sn.RROL_2 >= 1.0) &
            (conv_sn.sep > 0)]
        conv_save = conv_xrb.groupby('bin_num').first().reset_index()
    if conv_lims:
        for key in list(conv_lims.keys()):
            filter_lo = conv_lims[key][0]
            filter_hi = conv_lims[key][1]
            conv_save = conv_save.loc[conv_save[key] < filter_hi]
            conv_save = conv_save.loc[conv_save[key] > filter_lo]
    return conv_save


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 is_strobogrammatic2(num: str):
    """Another implementation."""
    return num == num[::-1].replace('6', '#').replace('9', '6').replace('#',
        '9')


def add_aws_creds(parser):
    """Adds AWS cred arguemnts"""
    parser.add_argument('--aws-secret-access-key', required=False, help=
        'AWS secret access key')
    parser.add_argument('--aws-access-key-id', required=False, help=
        'AWS access key id')


def get_similarity(d, val1, val2, mismatch_penalty=1):
    """
    Get similarity for partial matching.
    """
    dis = d.get(tuple((val2, val1)), -mismatch_penalty)
    return dis


def cmd(f):
    """
    Makes methods (on the classes: Project and Service) into CLI commands
    """
    f.cli_command = True
    return f


def mapbranch(branch, branchmap):
    """
    >>> bmap = {b'default': b'branch1'}
    >>> for i in [b'', None]:
    ...     mapbranch(i, bmap)
    'branch1'
    'branch1'
    >>> bmap = {b'None': b'branch2'}
    >>> for i in [b'', None]:
    ...     mapbranch(i, bmap)
    'branch2'
    'branch2'
    >>> bmap = {b'None': b'branch3', b'default': b'branch4'}
    >>> for i in [b'None', b'', None, b'default', b'branch5']:
    ...     mapbranch(i, bmap)
    'branch3'
    'branch4'
    'branch4'
    'branch4'
    'branch5'
    """
    branch = branchmap.get(branch or b'default', branch)
    if not branch:
        branch = branchmap.get(b'None', branch)
    return branch


def dpad_top_unheading(controller):
    """
    Callback function that is triggered, when the direction top was released

    :param controller:              the controller that triggered the action
    :type controller:               steuer.Controller
    """
    print('DIRECTION:' + str(controller.number) + ':' + controller.name +
        ':DPAD Top unheading')


@classmethod
def enable_dynamic_config(cls):
    """Enables dynamic config support of log levels.  Once this logger is installed as the logger it will not
        actually provide dynamic log level support until it is enabled in order to provide flexibility around when
        the required dependencies might be available since logging is such a low level thing that comes before all
        other services.
        """
    cls._enabled = True


def del_prefix(key):
    """
    Removes prefixes from the key
    """
    return key.split('||')[-1]


@classmethod
def __height(cls, header):
    """ provides height of tine property

        :param header: tine frameHeader
        :type header: :obj:`dict` <:obj:`str`, `any`>
        :returns: numpy dtype
        :rtype: :obj:`str`
        """
    height = 0
    if 'aoiHeight' in header and header['aoiHeight'] > 0:
        height = header['aoiHeight']
    elif 'sourceHeight' in header:
        height = header['sourceHeight']
    if not 0 < height <= 65535:
        raise ValueError('Invalid height: %s' % height)
    return height


@staticmethod
def add_session(fact, session, orm_classes):
    """Attach the session to the factory"""
    fact._meta.sqlalchemy_session = session
    fact._meta.sqlalchemy_session_persistence = 'flush'
    if isinstance(fact._meta.model, str):
        try:
            fact._meta.model = orm_classes[fact._meta.model]
        except KeyError:
            raise KeyError(
                'ORM Class not found matching %s. Check mapping.yml' % fact
                ._meta.model)
    return fact


def randomize_transform(random_seed: int=0, use_delta: bool=False, use_loc:
    bool=True, loc: float=(0.0, 0.0, 0.0), use_rot: bool=True, rot: float=(
    0.0, 0.0, 0.0), use_scale: bool=True, scale_even: bool=False, scale:
    float=(1.0, 1.0, 1.0)):
    """Randomize objects loc/rot/scale

    :param random_seed: Random Seed, Seed value for the random generator
    :type random_seed: int
    :param use_delta: Transform Delta, Randomize delta transform values instead of regular transform
    :type use_delta: bool
    :param use_loc: Randomize Location, Randomize the location values
    :type use_loc: bool
    :param loc: Location, Maximum distance the objects can spread over each axis
    :type loc: float
    :param use_rot: Randomize Rotation, Randomize the rotation values
    :type use_rot: bool
    :param rot: Rotation, Maximum rotation over each axis
    :type rot: float
    :param use_scale: Randomize Scale, Randomize the scale values
    :type use_scale: bool
    :param scale_even: Scale Even, Use the same scale value for all axis
    :type scale_even: bool
    :param scale: Scale, Maximum scale randomization over each axis
    :type scale: float
    """
    pass


def possible_start(ticket):
    """ Returns the possible start set on either the ticket, milestone or project
            or given by a dependency. Returns None if no start date was found.
        """


@staticmethod
def echo(session, *words):
    """
        Echoes the given words
        """
    session.write_line(' '.join(words))


@staticmethod
def _sort_by_timestamp(group_composite):
    """get timestamp which will be used to sort grouped data"""
    event_timestamp_string = group_composite[1]
    return event_timestamp_string


def write(fn, size):
    """Write a single file of `size` in bytes to path `fn`."""
    data = b'x' * int(size)
    with open(fn, 'wb') as fd:
        fd.write(data)


def getfunction(func):
    """
    Return the function associated with a class method.
    """
    return func