def set_app_id(appid):
    """
    Set application ID on windows.

    This is needed so that madgui windows will have their own taskbar group
    and not be counted as generic "python" applications.

    See: https://stackoverflow.com/a/1552105/650222
    """
    try:
        from ctypes import windll
    except ImportError:
        return
    windll.shell32.SetCurrentProcessExplicitAppUserModelID(appid)


def p_expr_NOT(p):
    """expr : NOT expr %prec UNOT"""
    p[0] = 'NOT', p[2]


def fetchclimate(context):
    """
    Dependencies for fetchclimate gizmo.
    """
    return ('tethys_gizmos/vendor/farbtastic/farbtastic.css',
        'tethys_gizmos/vendor/bootstrap_datepicker/css/datepicker3.css',
        'tethys_gizmos/css/fetchclimate/fetchclimate.css',
        'tethys_gizmos/css/fetchclimate/fetchclimate_map.css',
        'tethys_gizmos/css/fetchclimate/fetchclimate_plot.css',
        'tethys_gizmos/vendor/bootstrap_datepicker/js/bootstrap_datepicker.js',
        'tethys_gizmos/js/fetchclimate/fetchclimate_main.js',
        'tethys_gizmos/js/fetchclimate/fetchclimate_date.js',
        'tethys_gizmos/js/fetchclimate/fetchclimate_map.js',
        'tethys_gizmos/vendor/highcharts/js/highcharts.js',
        'tethys_gizmos/vendor/highcharts/js/highcharts-more.js',
        'tethys_gizmos/js/fetchclimate/fetchclimate_plot.js',
        'tethys_gizmos/js/fetchclimate/fetchclimate_data.js')


@staticmethod
def _interleave_datasets(data):
    """
        interleave a list of lists with equal dimensions
        """
    idata = []
    for y in range(len(data[0])):
        for x in range(len(data)):
            idata.append(data[x][y])
    return idata


def rotation_clear(clear_delta: bool=False):
    """Clear the object’s rotation

    :param clear_delta: Clear Delta, Clear delta rotation in addition to clearing the normal rotation transform
    :type clear_delta: bool
    """
    pass


def option_symbol(name):
    """Given OCC standardized option name, return option ticker"""
    return name[:-15]


def binary_encoder_decoder(obj):
    """
    Assumes value is already in binary format, so passes unchanged.
    """
    return obj


def repack_fileheader(dic):
    """
    Repack blockheader dic bit flag parameters into status and mode.
    """
    dic['status'] = dic['S_DATA'] * 1 + dic['S_SPEC'] * 2 + dic['S_32'
        ] * 4 + dic['S_FLOAT'] * 8 + dic['S_COMPLEX'] * 16 + dic[
        'S_HYPERCOMPLEX'] * 32 + dic['S_ACQPAR'] * 128 + dic['S_SECND'
        ] * 256 + dic['S_TRANSF'] * 512 + dic['S_NP'] * 2048 + dic['S_NF'
        ] * 4096 + dic['S_NI'] * 8192 + dic['S_NI2'] * 16384
    return dic


@classmethod
def tile(cls, op):
    """
        Use LU decomposition to compute inverse of matrix.
        Given a square matrix A:
        P, L, U = lu(A)
        b_eye is an identity matrix with the same shape as matrix A, then,
        (P * L * U) * A_inv = b_eye
        L * (U * A_inv) = P.T * b_eye
        use `solve_triangular` twice to compute the inverse of matrix A.
        """
    from .lu import lu
    from ..datasource import eye
    from ..base.transpose import TensorTranspose
    from .tensordot import tensordot
    from .solve_triangular import solve_triangular
    in_tensor = op.input
    is_sparse = in_tensor.is_sparse()
    b_eye = eye(in_tensor.shape[0], chunk_size=in_tensor.nsplits, sparse=
        is_sparse)
    b_eye._inplace_tile()
    p, l, u = lu(in_tensor)
    p._inplace_tile()
    p_transpose = TensorTranspose(dtype=p.dtype, sparse=p.op.sparse, axes=
        list(range(in_tensor.ndim))[::-1]).new_tensor([p], p.shape)
    p_transpose._inplace_tile()
    b = tensordot(p_transpose, b_eye, axes=((p_transpose.ndim - 1,), (b_eye
        .ndim - 2,)))
    b._inplace_tile()
    uy = solve_triangular(l, b, lower=True, sparse=op.sparse)
    uy._inplace_tile()
    a_inv = solve_triangular(u, uy, sparse=op.sparse)
    a_inv._inplace_tile()
    return [a_inv]


def create_blank_udic(ndim):
    """
    Create a blank universal dictionary for a spectrum of dimension ndim.
    """
    udic = dict()
    udic['ndim'] = ndim
    for i in range(ndim):
        d = dict()
        d['sw'] = 999.99
        d['complex'] = True
        d['obs'] = 999.99
        d['car'] = 999.99
        d['size'] = 1
        d['label'] = ['X', 'Y', 'Z', 'A'][i]
        if i == ndim - 1:
            d['encoding'] = 'direct'
        else:
            d['encoding'] = 'states'
        d['time'] = True
        d['freq'] = False
        udic[i] = d
    return udic


def tuple_similarity(t1, t2, var_attr, cat_sim, num_dis_norm, agg_col):
    """Compute the similarity between two tuples t1 and t2 on their attributes var_attr

    Args:
        t1, t2: two tuples
        var_attr: variable attributes
        cat_sim: the similarity measure for categorical attributes
        num_dis_norm: normalization terms for numerical attributes
        agg_col: the column of aggregated value
    Returns:
        the Gower similarity between t1 and t2
    """
    sim = 0.0
    cnt = 0
    for col in var_attr:
        if t1[col] is None or t2[col] is None:
            continue
        if cat_sim.is_categorical(col):
            s = cat_sim.compute_similarity(col, t1[col], t2[col], agg_col)
            sim += s
        elif col != agg_col and col != 'index':
            temp = abs(t1[col] - t2[col]) / num_dis_norm[col]['range']
            sim += 1 - temp
        cnt += 1
    return sim / cnt


def document_to_dict(instance, fields=None, exclude=None):
    """
    Returns a dict containing the data in ``instance`` suitable for passing as
    a Form's ``initial`` keyword argument.

    ``fields`` is an optional list of field names. If provided, only the named
    fields will be included in the returned dict.

    ``exclude`` is an optional list of field names. If provided, the named
    fields will be excluded from the returned dict, even if they are listed in
    the ``fields`` argument.
    """
    data = {}
    for f in instance._fields.values():
        if fields and f.name not in fields:
            continue
        if exclude and f.name in exclude:
            continue
        data[f.name] = getattr(instance, f.name, '')
    return data


def regress_to_class(current_timestamp: int, one_timestamp: int,
    anticipation_time_window: float) ->float:
    """
    This function checks every timestamp against the timestamp of a class occurrence, and assigns a weight on it.
    Linear interpolation of the label column is what this function does, providing us with a "ramp" instead of having a
    step transition from 0 to 1.
    Parameters
    ----------
    current_timestamp: ``int``, required
        The timestamp of the current row
    one_timestamp: ``int``, required,
        The timestamp to the `1` in the label class that we want to check the current timestamps against.
    anticipation_time_window: ``float``, required
        This parameter determines how "wide" our ramps should be.

    Returns
    ----------
    The output of this method is a float which represents the value of the ramp.
    """
    anticipation_time_window = float(anticipation_time_window)
    if (current_timestamp <= one_timestamp and current_timestamp >=
        one_timestamp - anticipation_time_window):
        return (anticipation_time_window - one_timestamp + current_timestamp
            ) / anticipation_time_window


def nbconvert(code):
    """Create Jupyter Notebook code

    Return dict in ipynb format
    Arguments:
    code -- code string separated by \\n
    """
    cells = []
    for cell in code.split('\n# <codecell>\n'):
        cells.append({'cell_type': 'code', 'execution_count': None,
            'metadata': {'collapsed': True}, 'outputs': [], 'source': [cell]})
    result = {'cells': cells, 'nbformat': 4, 'nbformat_minor': 0,
        'metadata': {'kernelspec': {'display_name': 'Python 2', 'language':
        'python', 'name': 'python2'}, 'language_info': {'codemirror_mode':
        {'name': 'ipython', 'version': 2}, 'file_extension': '.py',
        'mimetype': 'text/x-python', 'name': 'python', 'nbconvert_exporter':
        'python', 'pygments_lexer': 'ipython2', 'version': '2.7.6'}}}
    return result


def pandoc_cmd(book):
    """Create the command to convert the files (listed in `book`)
    into a pdf. This is wrapped with echos that the build has started and
    is complete."""
    with open(book + '.txt') as f:
        return (
            'echo "Starting build of {book}.pdf" && pandoc {files} -f markdown-smart --table-of-contents --top-level-division=chapter -o {book}.pdf && echo "  {book}.pdf created."'
            .format(book=book, files=f.read().replace('\n', ' ')))


def shorten_ref(ref, add_to_ref):
    """Shorten references."""
    link = ':ref:{}'.format(ref.split(':ref:')[1].split(':')[0])
    linkr = link.split('<')[1].split('>')[0]
    short = '.. |{}_{}| replace:: {}'.format(add_to_ref, linkr.split('-')[-
        1], link)
    print(short.split('|')[1])
    return short


def convert_truelike_to_bool(input_item, convert_float=False,
    convert_nontrue=True):
    """Converts true-like values ("true", 1, True", "WAHR", etc) to python boolean True.

    Parameters
    ----------
    input_item : string or int
        Item to be converted to bool (e.g. "true", 1, "WAHR" or the equivalent in several languagues)
    convert_float: bool
        Convert floats to bool.
        If True, "1.0" will be converted to True
    convert_nontrue : bool
        If True, the output for input_item not recognised as "True" will be False.
        If True, the output for input_item not recognised as "True" will be the original input_item.

    Returns
    -------
    return_value : True, or input_item
        If input_item is True-like, returns python bool True. Otherwise, returns the input_item.

    Usage
    -----
    # convert a single value or string
    convert_truelike_to_bool("true")
    # convert a column in a pandas DataFrame
    df["column_name"] = df["column_name"].apply(convert_truelike_to_bool)
    """
    list_True_items = [True, 'True', 'true', 'TRUE', 'T', 't', 'wahr',
        'WAHR', 'prawdziwy', 'verdadeiro', 'sann', 'istinit', 'veritable',
        'Pravda', 'sandt', 'vrai', 'igaz', 'veru', 'verdadero', 'sant',
        'gwir', 'PRAWDZIWY', 'VERDADEIRO', 'SANN', 'ISTINIT', 'VERITABLE',
        'PRAVDA', 'SANDT', 'VRAI', 'IGAZ', 'VERU', 'VERDADERO', 'SANT',
        'GWIR', 'bloody oath', 'BLOODY OATH', 'nu', 'NU', 'damn right',
        'DAMN RIGHT']
    if convert_float:
        list_True_items += [1.0, '1.0']
    input_item_is_true = input_item in list_True_items
    if convert_nontrue:
        nontrue_return_value = False
    else:
        nontrue_return_value = input_item
    return_value = (input_item_is_true if input_item_is_true == True else
        nontrue_return_value)
    return return_value


def _try_n_times(fn, n, *args, **kargs):
    """ Try a function N times """
    attempts = 0
    while attempts < n:
        try:
            return fn(*args, **kargs)
        except Exception:
            attempts += 1
    return fn(*args, **kargs)


def _crystfel_format_vec(vec):
    """Convert an array of 3 numbers to CrystFEL format like "+1.0x -0.1y"
    """
    s = '{:+}x {:+}y'.format(*vec[:2])
    if vec[2] != 0:
        s += ' {:+}z'.format(vec[2])
    return s


def assert_parameters(N, k_over_2, beta):
    """Assert that `N` is integer, `k_over_2` is integer and `0 <= beta <= 1`"""
    assert k_over_2 == int(k_over_2)
    assert N == int(N)
    assert beta >= 0.0
    assert beta <= 1.0


def add_backup_arguments(parser):
    """Add CLI arguments required for this module.

    :param argparse.ArgumentParser parser: The argument parser

    """
    parser.add_argument('-b', '--s3-bucket', type=str, action='store', help
        =
        'The S3 bucket to upload the database backup to. Default: com-aweber-dba'
        , default='com-aweber-dba')


def bake_all(bake: bool=True):
    """Bake all physics

    :param bake: Bake
    :type bake: bool
    """
    pass


def escape_for_query(query_part: str) ->str:
    """Escapes all characters reserved by jriver in a natural string.

    Do not put a complete query in here - this method is used to escape
    reserved characters in a natural string that will be used as a query fragment.
    This is usually the content of a field (e.g. an album or artist name).
    """
    query_part = query_part.replace('"', '/"')
    query_part = query_part.replace('^', '/^')
    query_part = query_part.replace('[', '/[')
    query_part = query_part.replace(']', '/]')
    return query_part


def get_sprite_center(sprite):
    """
    Return the coordinates of the center of a sprite.

    :param sprite: A `Sprite` object.

    :return: A tuple `x, y` of the coordinates of the sprite's center
    """
    x1, y1 = sprite.top_left
    x2, y2 = sprite.bottom_right
    return (x1 + x2) // 2, (y2 + y1) // 2


@classmethod
def _convert_to_fill(cls, fill_dict):
    """
        Convert ``fill_dict`` to an openpyxl v2 Fill object
        Parameters
        ----------
        fill_dict : dict
            A dict with one or more of the following keys (or their synonyms),
                'fill_type' ('patternType', 'patterntype')
                'start_color' ('fgColor', 'fgcolor')
                'end_color' ('bgColor', 'bgcolor')
            or one or more of the following keys (or their synonyms).
                'type' ('fill_type')
                'degree'
                'left'
                'right'
                'top'
                'bottom'
                'stop'
        Returns
        -------
        fill : openpyxl.styles.Fill
        """
    from openpyxl.styles import PatternFill, GradientFill
    _pattern_fill_key_map = {'patternType': 'fill_type', 'patterntype':
        'fill_type', 'fgColor': 'start_color', 'fgcolor': 'start_color',
        'bgColor': 'end_color', 'bgcolor': 'end_color'}
    _gradient_fill_key_map = {'fill_type': 'type'}
    pfill_kwargs = {}
    gfill_kwargs = {}
    for k, v in fill_dict.items():
        pk = gk = None
        if k in _pattern_fill_key_map:
            pk = _pattern_fill_key_map[k]
        if k in _gradient_fill_key_map:
            gk = _gradient_fill_key_map[k]
        if pk in ['start_color', 'end_color']:
            v = cls._convert_to_color(v)
        if gk == 'stop':
            v = cls._convert_to_stop(v)
        if pk:
            pfill_kwargs[pk] = v
        elif gk:
            gfill_kwargs[gk] = v
        else:
            pfill_kwargs[k] = v
            gfill_kwargs[k] = v
    try:
        return PatternFill(**pfill_kwargs)
    except TypeError:
        return GradientFill(**gfill_kwargs)


def test():
    """test of the `purecma` module, called ``if __name__ == "__main__"``.

    Currently only based on `doctest`:

    >>> try: import cma.purecma as pcma
    ... except ImportError: import purecma as pcma
    >>> import random
    >>> random.seed(3)
    >>> xmin, es = pcma.fmin(pcma.ff.rosenbrock, 4 * [0.5], 0.5,
    ...                      verb_disp=0, verb_log=1)
    >>> print(es.counteval)
    1680
    >>> print(es.best.evals)
    1664
    >>> assert es.best.f < 1e-12
    >>> random.seed(5)
    >>> es = pcma.CMAES(4 * [0.5], 0.5)
    >>> es.params = pcma.CMAESParameters(es.params.dimension,
    ...                                  es.params.lam,
    ...                                  pcma.RecombinationWeights)
    >>> while not es.stop():
    ...     X = es.ask()
    ...     es.tell(X, [pcma.ff.rosenbrock(x) for x in X])
    >>> print("%s, %s" % (pcma.ff.rosenbrock(es.result[0]) < 1e-13,
    ...                   es.result[2] < 1600))
    True, True

    Large population size:

    >>> random.seed(4)
    >>> es = pcma.CMAES(3 * [1], 1)
    >>> es.params = pcma.CMAESParameters(es.params.dimension, 300,
    ...                                  pcma.RecombinationWeights)
    >>> es.logger = pcma.CMAESDataLogger()
    >>> try:
    ...    es = es.optimize(pcma.ff.elli, verb_disp=0)
    ... except AttributeError:  # OOOptimizer.optimize is not available
    ...     while not es.stop():
    ...         X = es.ask()
    ...         es.tell(X, [pcma.ff.elli(x) for x in X])
    >>> assert es.result[1] < 1e13
    >>> print(es.result[2])
    9300

    """
    import doctest
    print('launching doctest...')
    print(doctest.testmod(report=True, verbose=0))


@staticmethod
def defaultSymbol():
    """
        Returns the default symbol path for this cloud.

        :returns: symbol path (or resource).
        """
    return ':/symbols/cloud.svg'


def dpad_top_pressed(controller):
    """
    Callback function that is triggered, when the dpad top button was pressed

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


def is_int(string):
    """Check if a string is a digit.

    string : str
        Input string to check.

    Returns
    -------
    bool
        True on success, False on exception.
    """
    try:
        int(string)
        return True
    except Exception:
        return False


def process_result(result):
    """Do a simple evaluation of the score."""
    try:
        score = float(result[0].split('/')[0])
    except IndexError:
        return None, None
    try:
        delta = score - float(result[1].split('/')[0])
    except IndexError:
        delta = None
    return score, delta


@classmethod
def _get_separated_instrumentation_criteria(cls):
    """ Criteria where all elements are instrumented in different files
            :return: list of citeria
        """
    return []


@classmethod
def resolve_contents(cls, contents, env):
    """Resolve bundle names."""
    result = []
    for f in contents:
        try:
            result.append(env[f])
        except KeyError:
            result.append(f)
    return result


def af_to_genotypes(alt_af):
    """
    Returns the Hardy Weinberg equilibrium for a given alternate pooled allele frequency

    :param alt_af: [0, 1]
    :return: [homozygous Reference, heterozygous, homozygous Alternate]
    """
    return (1 - alt_af) ** 2, 2 * alt_af * (1 - alt_af), alt_af ** 2


def merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result


def parse_boolean(value, length, cursor):
    """Typecast the postgres boolean to a python boolean.

    Postgres returns the boolean as a string with 'true' or 'false'

    """
    return value[:1] == b't' if value is not None else None


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


def drop(lst, n):
    """
        Return a list that removes at most n elements from the beginning of the
        list.
        """
    for _ in range(n):
        try:
            lst = lst.tail
        except AttributeError:
            break
    return lst


def conditionWeights(lits, weights):
    """Modifies the weight of positive literal as per condition given by list lits"""
    for lit in lits:
        weights[int(lit)] = 1
        weights[-1 * int(lit)] = 0


def build_authenticate_header(realm=''):
    """Optional WWW-Authenticate header (401 error)"""
    return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}


def mask(in_file, mask_file, new_name):
    """
    Apply a binary mask to an image.

    Parameters
    ----------
    in_file : str
        Path to a NIfTI file to mask
    mask_file : str
        Path to a binary mask
    new_name : str
        Path/filename for the masked output image.

    Returns
    -------
    str
        Absolute path of the masked output image.

    Notes
    -----
    in_file and mask_file must be in the same
    image space and have the same dimensions.
    """
    import nibabel as nb
    import os
    in_nii = nb.load(in_file)
    mask_nii = nb.load(mask_file)
    data = in_nii.get_data()
    data[mask_nii.get_data() == 0] = 0
    new_nii = nb.Nifti1Image(data, in_nii.affine, in_nii.header)
    new_nii.to_filename(new_name)
    return os.path.abspath(new_name)


def list_to_string(list_of_strings):
    """
    Function that takes a list of string and converts it to a string.
    For example: ["apple", "banana", "cherry"] is changed to "apple; banana; cherry"
    """
    string = ''
    if list_of_strings is not None:
        for item in list_of_strings:
            if len(string) > 0:
                string += '; '
            string += item
    return string


def rawsize(rev):
    """Obtain the size of tracked data.

        Is equivalent to ``len(m.rawdata(node))``.

        TODO this method is only used by upgrade code and may be removed.
        """


def _retrieve_title() ->str:
    """ Gets title from the user's input """
    app_title = None
    while not app_title:
        app_title = input('Enter title: ').strip()
    return app_title


@staticmethod
def _write_imgdata(img, data, tr, x=0, y=0):
    """Write image data.

        Parameters
        ----------
        img : `PIL.Image.Image`
            Image.
        data : `iterable` of `int`
            Image data.
        tr : `markovchain.image.traversal.Traversal`
            Image traversal.
        x : `int`
            X offset.
        y : `int`
            Y offset.
        """
    for pixel, (x1, y1) in zip(data, tr):
        img.putpixel((x + x1, y + y1), pixel)
    return img


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.lightgbm.LightGBMRegressor'


def build_metadata_url(code):
    """Return a URL to search for a BCB time series metadata."""
    baseurl = 'https://dadosabertos.bcb.gov.br/api/3/action/package_search?'
    params = f'fq=codigo_sgs:{code}'
    return f'{baseurl}{params}'


@classmethod
def poisson_gt_one_more(cls, tau_1, tau_2, symbolic=False):
    """Asymptotic development of ``P(X_1 > X_2 + 1)``, where ``X_i ~ Poison(tau_i * n)``.

        Parameters
        ----------
        tau_1,tau_2 : Number
            The parameter of the Poisson distribution of ``X_i`` is ``tau_i * n``, where `n` tends to infinity.
        symbolic : bool
            Whether the computations are symbolic or numeric.

        Returns
        -------
        Asymptotic
            The asymptotic development of ``P(X_1 > X_2 + 1)``, where ``X_i ~ Poison(tau_i * n)``.

        Examples
        --------
            >>> from math import log
            >>> print(Asymptotic.poisson_gt_one_more(tau_1=0, tau_2=0))
            exp(- inf)
            >>> print(Asymptotic.poisson_gt_one_more(tau_1=0, tau_2=1/10))
            exp(- inf)
            >>> print(Asymptotic.poisson_gt_one_more(tau_1=1/10, tau_2=0))
            exp(o(1))
            >>> Asymptotic.poisson_gt_one_more(tau_1=9/10, tau_2=1/10).look_equal(
            ...     Asymptotic(mu=0, nu=0, xi=0))
            True
            >>> Asymptotic.poisson_gt_one_more(tau_1=3/10, tau_2=3/10).look_equal(
            ...     Asymptotic(mu=0, nu=0, xi=-log(2)))
            True
            >>> asymptotic = Asymptotic.poisson_gt_one_more(tau_1=1/10, tau_2=9/10)
            >>> asymptotic_eq = Asymptotic.poisson_eq(tau_1=1/10, tau_2=9/10)
            >>> asymptotic.look_equal(
            ...     Asymptotic(mu=asymptotic_eq.mu, nu=asymptotic_eq.nu, xi=asymptotic_eq.xi - log(6)))
            True
        """
    return cls.poisson_x1_ge_x2_plus_k(tau_1, tau_2, 2, symbolic=symbolic)


def JNZ(cpu, target):
    """
        Jumps short if not zero.

        :param cpu: current CPU.
        :param target: destination operand.
        """
    cpu.JNE(target)


def abstract(entity):
    """Decorator @abstract for abstract methods or classes.

    An abstract class should not be directly instantiated, but needs
    to be sub-classed. An abstract method must be overridden in a
    derived class. For now this is only a way of visually showing this
    information in the code.

    """
    return entity


@classmethod
def from_hex(cls, value):
    """Initialize a new network from hexadecimal notation."""
    if len(value) == 8:
        return cls(int(value, 16))
    elif len(value) == 32:
        return cls(int(value, 16))
    else:
        raise ValueError('%r: invalid hexadecimal notation' % (value,))


def psi_H_Mg_HSO4_RC99(T, P):
    """c-c'-a: hydrogen magnesium bisulfate [RC99]."""
    psi = -0.027079
    valid = T == 298.15
    return psi, valid


def intToHexStr(i):
    """Converts int to hex

    :param i: Integer value to convert
    :type i: int

    :return: Hex string representing i
    """
    return hex(i)[2:]


@classmethod
def table_schema(cls):
    """
        gets the table schema that this entity represents in database.

        it might be `None` if schema has not been set for this entity.

        :rtype: str
        """
    schema = None
    if cls.__table_args__ is not None:
        schema = cls.__table_args__.get('schema', None)
    return schema


def list_deserialize(iodata):
    """Turn IOData instance back into a list"""
    return list(iodata.as_kwargs().values())


def exp(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise exponential value of the input.

    .. math::
       exp(x) = e^x \\approx 2.718^x

    Example::

       exp([0, 1, 2]) = [1., 2.71828175, 7.38905621]

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

    Defined in src/operator/tensor/elemwise_unary_op_logexp.cc:L63

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

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

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


def default_validator(language, options):
    """Default validator."""
    return len(options) == 0


def parents(node):
    """Returns a 2-tuple of parent nodes for a revision.

        Values will be ``nullid`` if the parent is empty.
        """


def format_folia(lemma: str, pos_tag: str, word: str) ->str:
    """
    Lexical assignment of the lemma and postag.
    """
    return '[ @folia {0} {1} {2} ]'.format(lemma, pos_tag, word
        ) if word else ''


def shuffle():
    """randomly order incoming things"""


def writeConnectionLost():
    """
        Notification of the write connection being closed.

        This will never be called for TCP connections as TCP does not
        support notification of this type of half-close.
        """


def tell():
    """Return the current offset into the file, in bytes.
        """


def is_tensor(v):
    """
    Return if an object is a torch Tensor, without importing torch.
    """
    if type(v).__module__.startswith('torch'):
        import torch
        return torch.is_tensor(v)
    return False


def walk(start, ofn, cyc=None):
    """ Non recursive DFS to detect cycles

    :param start: start vertex in graph
    :param ofn: function to get the list of outgoing edges of a vertex
    :param cyc: list of existing cycles, cycles are represented in a list started with minimum vertex.
    :return: cycles
    :rtype: list of lists
    """
    ctx, stk = {}, [start]
    cyc = [] if cyc == None else cyc
    while len(stk):
        top = stk[-1]
        if top not in ctx:
            ctx.update({top: list(ofn(top))})
        if len(ctx[top]):
            n = ctx[top][0]
            if n in stk:
                nc = stk[stk.index(n):]
                ni = nc.index(min(nc))
                nc = nc[ni:] + nc[:ni] + [min(nc)]
                if nc not in cyc:
                    cyc.append(nc)
                ctx[top].pop(0)
            else:
                stk.append(n)
        else:
            ctx.pop(top)
            stk.pop()
            if len(stk):
                ctx[stk[-1]].remove(top)
    return cyc


def context_cycle_enum(data_path: str='', reverse: bool=False, wrap: bool=False
    ):
    """Toggle a context value

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param reverse: Reverse, Cycle backwards
    :type reverse: bool
    :param wrap: Wrap, Wrap back to the first/last values
    :type wrap: bool
    """
    pass


def serialize_class(cls):
    """ Serialize Python class """
    return '{}:{}'.format(cls.__module__, cls.__name__)


def get_optional_field_value(data, field_name, pk, fetch_model):
    """Gets the value of a model field if it exists either in serializer data or in the database.
    "Optional" means it's not an issue if the field value is not present.

    If there's no field in data, then model if fetched via function provided and looked up instead.
    Field can be missing in data in case of partial update (PATCH) or in case action allows that some other way.

    Parameters:

    - data #dict: The serializer's data to look up the field in first.
    - field_name #str: The name of the field to look up.
    - pk #object: The value of corresponding entity's PK to fetch model in case there's no field in data.
    - fetch_model #function: A function which is expected to return model instance if executed with its PK as argument.

    Returns: the value of the field if present else #None.
    """
    if field_name in data:
        return data.get(field_name)
    return None if pk is None else getattr(fetch_model(pk), field_name)


def distance(s1: str, s2: str) ->int:
    """
    Implementation of Damerau-Levenshtein distance with transposition (also
    sometimes calls unrestricted Damerau-Levenshtein distance).

    It is the minimum number of operations needed to transform one string into
    the other, where an operation is defined as an insertion, deletion, or
    substitution of a single character, or a transposition of two adjacent
    characters.
    """
    d: dict = {}
    for i in range(-1, len(s1) + 1):
        d[i, -1] = i + 1
    for j in range(-1, len(s2) + 1):
        d[-1, j] = j + 1
    for i, cs1 in enumerate(s1):
        for j, cs2 in enumerate(s2):
            cost = int(cs1 != cs2)
            d[i, j] = min(d[i - 1, j] + 1, d[i, j - 1] + 1, d[i - 1, j - 1] +
                cost)
            if not i or not j:
                continue
            if cs1 != cs2:
                continue
            d[i, j] = min(d[i, j], d[i - 2, j - 2] + cost)
    return d[len(s1) - 1, len(s2) - 1]


@staticmethod
def replace_text(filepath, to_replace, replacement):
    """
        Replaces a string in a given file with another string

        :param file: the file in which the string has to be replaced
        :param to_replace: the string to be replaced in the file
        :param replacement: the string which replaces 'to_replace' in the file
        """
    with open(filepath) as file:
        s = file.read()
    s = s.replace(to_replace, replacement)
    with open(filepath, 'w') as file:
        file.write(s)


@staticmethod
def p_a2ml_member_optional(p):
    """a2ml_member_optional : empty
                                | a2ml_member"""
    p[0] = p[1]


def _convert_unsqueeze(builder, node, graph, err):
    """
    convert to CoreML ExpandDim Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L4810
    """
    axes = node.attrs.get('axes')
    builder.add_expand_dims(name=node.name, input_name=node.inputs[0],
        output_name=node.outputs[0], axes=axes)


def worker_undo_cached_redis(caching_object):
    """Just a wrapper function to clean RQ's jobs' results."""
    return caching_object.delete()


def is_gziped(fp, **kwargs):
    """ Return True if the file is Gziped else False """
    return fp[-2:].lower() == 'gz'


def terminal_safe(s: str) ->str:
    """safely encode a string for printing to the terminal."""
    return s.encode('ascii', 'backslashreplace').decode('ascii')


def _infiniband_address_to_mac(address):
    """Convert InfiniBand address to MAC

    Convert InfiniBand address to MAC by Mellanox specific
    translation. The InfiniBand address is 59 characters
    composed from GID:GUID. The last 24 characters are the
    GUID. The InfiniBand MAC is upper 10 characters and lower
    9 characters from the GUID
    Example:
    address - a0:00:00:27:fe:80:00:00:00:00:00:00:7c:fe:90:03:00:29:26:52
    GUID - 7c:fe:90:03:00:29:26:52
    InfiniBand MAC - 7c:fe:90:29:26:52

    :param address: InfiniBand Address.
    :returns: InfiniBand MAC.
    """
    return address[36:-14] + address[51:]


def _list_estimators():
    """
    list available tpcf estimators.
    """
    estimators = ['Natural', 'Davis-Peebles', 'Hewett', 'Hamilton',
        'Landy-Szalay']
    return estimators


def resolve_variables(variables, context, provider):
    """Given a list of variables, resolve all of them.

    Args:
        variables (List[:class:`Variable`]): List of variables.
        context (:class:`runway.cfngin.context.Context`): CFNgin context.
        provider (:class:`runway.cfngin.providers.base.BaseProvider`): Subclass
            of the base provider.

    """
    for variable in variables:
        variable.resolve(context=context, provider=provider)


def move(cm, from_start, from_end, insert_pos):
    """
    Move rows from_start - from_end to insert_pos in-place.

    Parameters
    ----------
    cm : ndarray
    from_start : int
    from_end : int
    insert_pos : int

    Returns
    -------
    cm : ndarray

    Examples
    --------
    >>> cm = np.array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 0, 1], [2, 3, 4, 5]])
    >>> move(cm, 1, 2, 0)
    array([[5, 6, 4, 7],
           [9, 0, 8, 1],
           [1, 2, 0, 3],
           [3, 4, 2, 5]])
    """
    if not (insert_pos < from_start or insert_pos > from_end):
        raise ValueError(
            'insert_pos={} needs to be smaller than from_start={} or greater than from_end={}'
            .format(insert_pos, from_start, from_end))
    if insert_pos > from_end:
        p_new = list(range(from_end + 1, insert_pos + 1)) + list(range(
            from_start, from_end + 1))
    else:
        p_new = list(range(from_start, from_end + 1)) + list(range(
            insert_pos, from_start))
    p_old = sorted(p_new)
    cm[:, (p_old)] = cm[:, (p_new)]
    cm[(p_old), :] = cm[(p_new), :]
    return cm


@classmethod
def from_frame(cls, df):
    """Converts dataframe into an interable of objects."""
    for tup in df.itertuples():
        yield cls._to_obj(tup)


def fix_content_type(value, default=None):
    """Content-Type value may be badly broken"""
    if not value:
        return default or ('text', 'plain')
    values = value.lower().split('/')
    if len(values) >= 2:
        return values[:2]
    elif len(values) == 1:
        if values[0] == 'text':
            return 'text', 'plain'
        elif values[0] == 'html':
            return 'text', 'html'
        return 'application', 'octet-stream'


def xml_find_non_text_child(_node):
    """Finds the first child that is not of the Text node type."""
    nodelist = _node.childNodes
    for node in nodelist:
        if node.nodeType != node.TEXT_NODE:
            return node
    return None


def deep_getattr(obj, attr_string, default=None):
    """
    Returns the attribute of `obj` at the dotted path given by `attr_string`
    If no such attribute is reachable, returns `default`

    >>> deep_getattr(cass, 'cluster')
    <cassandra.cluster.Cluster object at 0xa20c350

    >>> deep_getattr(cass, 'cluster.metadata.partitioner')
    u'org.apache.cassandra.dht.Murmur3Partitioner'

    >>> deep_getattr(cass, 'i.dont.exist', default='default')
    'default'
    """
    attrs = attr_string.split('.')
    for attr in attrs:
        try:
            obj = getattr(obj, attr)
        except AttributeError:
            return default
    return obj


def evaluator_options_from_eval_config(eval_config):
    """Produces a dictionary of evaluation options for each eval metric.

  Args:
    eval_config: An `eval_pb2.EvalConfig`.

  Returns:
    evaluator_options: A dictionary of metric names (see
      EVAL_METRICS_CLASS_DICT) to `DetectionEvaluator` initialization
      keyword arguments. For example:
      evalator_options = {
        'coco_detection_metrics': {'include_metrics_per_category': True}
      }
  """
    eval_metric_fn_keys = eval_config.metrics_set
    evaluator_options = {}
    for eval_metric_fn_key in eval_metric_fn_keys:
        if eval_metric_fn_key in ('coco_detection_metrics', 'coco_mask_metrics'
            ):
            evaluator_options[eval_metric_fn_key] = {
                'include_metrics_per_category': eval_config.
                include_metrics_per_category}
        elif eval_metric_fn_key == 'precision_at_recall_detection_metrics':
            evaluator_options[eval_metric_fn_key] = {'recall_lower_bound':
                eval_config.recall_lower_bound, 'recall_upper_bound':
                eval_config.recall_upper_bound}
    return evaluator_options


def get_first_xpath(xpaths, doc):
    """Return the first element matched by the provided list of XPATH expressions"""
    for i in xpaths:
        res = i(doc)
        if res:
            return res[0]


@staticmethod
def consume_cartesian_product(items):
    """Force the generated to be consumed

        :argument items: Generator to consume
        :type items: iterable

        :returns: Consumed list
        :rtype: list

        >>> ArgumentsParser.consume_cartesian_product(iter([1]))
        [1]

        """
    return list(items)


def set_styles(styles):
    """Sets the customstyles.

        :param styles: The new, complete styles to set on the context.
        :type styles: dict
        """


def image(theWhere, theX, theY, theImage):
    """
	Display an image (np.ndarray).

	Parameters
	----------
	theWhere: np.ndarray
		image/frame where the provded image should be rendered.
	theX: int
		position X where the image should be placed.
	theY: int
		position Y where the image should be placed.
	theImage: np.ndarray
		image to be rendered in the specified destination.

	See Also
	----------
	button()
	iarea()
	"""
    print('This is wrapper function to help code autocompletion.')


def __new__(cls, content, depth=0, parent=None, *args, **kwargs):
    """ creates an object of str type to extend it """
    obj = super().__new__(cls, content, *args, **kwargs)
    obj.content = content
    obj.depth = depth
    obj.parent = parent
    return obj


@staticmethod
def metrics():
    """Evaluation metrics used for monitoring training."""
    import tensorflow as tf
    tfk = tf.keras
    return [tfk.metrics.BinaryAccuracy(), tfk.metrics.AUC()]


def name_key(tags):
    """ Convert way tags to name keys.

        Used by ParserOSM.parse().
    """
    if 'name' not in tags:
        return None
    if not tags['name']:
        return None
    return tags['name'],


def describe_default_cluster_parameters(ParameterGroupFamily=None,
    MaxRecords=None, Marker=None):
    """
    Returns a list of parameter settings for the specified parameter group family.
    For more information about parameters and parameter groups, go to Amazon Redshift Parameter Groups in the Amazon Redshift Cluster Management Guide .
    See also: AWS API Documentation

    :example: response = client.describe_default_cluster_parameters(
        ParameterGroupFamily='string',
        MaxRecords=123,
        Marker='string'
    )

    :type ParameterGroupFamily: string
    :param ParameterGroupFamily: [REQUIRED]
            The name of the cluster parameter group family.

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of response records to return in each call. If the number of remaining response records exceeds the specified MaxRecords value, a value is returned in a marker field of the response. You can retrieve the next set of records by retrying the command with the returned marker value.
            Default: 100
            Constraints: minimum 20, maximum 100.

    :type Marker: string
    :param Marker: An optional parameter that specifies the starting point to return a set of response records. When the results of a DescribeDefaultClusterParameters request exceed the value specified in MaxRecords , AWS returns a value in the Marker field of the response. You can retrieve the next set of response records by providing the returned marker value in the Marker parameter and retrying the request.

    :rtype: dict
    :return: {
        'DefaultClusterParameters': {
            'ParameterGroupFamily': 'string',
            'Marker': 'string',
            'Parameters': [
                {
                    'ParameterName': 'string',
                    'ParameterValue': 'string',
                    'Description': 'string',
                    'Source': 'string',
                    'DataType': 'string',
                    'AllowedValues': 'string',
                    'ApplyType': 'static'|'dynamic',
                    'IsModifiable': True|False,
                    'MinimumEngineVersion': 'string'
                },
            ]
        }
    }

    """
    pass


@classmethod
def set_timeout(cls, timeout):
    """
        Override the default timeout

        :Args:
            - timeout - timeout value for http requests in seconds
        """
    cls._timeout = timeout


def modify_db_cluster_parameter_group(DBClusterParameterGroupName=None,
    Parameters=None):
    """
    Modifies the parameters of a DB cluster parameter group. To modify more than one parameter, submit a list of the following: ParameterName , ParameterValue , and ApplyMethod . A maximum of 20 parameters can be modified in a single request.
    For more information on Amazon Aurora, see Aurora on Amazon RDS in the Amazon RDS User Guide.
    See also: AWS API Documentation

    Examples
    This example immediately changes the specified setting for the specified DB cluster parameter group.
    Expected Output:

    :example: response = client.modify_db_cluster_parameter_group(
        DBClusterParameterGroupName='string',
        Parameters=[
            {
                'ParameterName': 'string',
                'ParameterValue': 'string',
                'Description': 'string',
                'Source': 'string',
                'ApplyType': 'string',
                'DataType': 'string',
                'AllowedValues': 'string',
                'IsModifiable': True|False,
                'MinimumEngineVersion': 'string',
                'ApplyMethod': 'immediate'|'pending-reboot'
            },
        ]
    )

    :type DBClusterParameterGroupName: string
    :param DBClusterParameterGroupName: [REQUIRED]
            The name of the DB cluster parameter group to modify.

    :type Parameters: list
    :param Parameters: [REQUIRED]
            A list of parameters in the DB cluster parameter group to modify.
            (dict) --This data type is used as a request parameter in the ModifyDBParameterGroup and ResetDBParameterGroup actions.
            This data type is used as a response element in the DescribeEngineDefaultParameters and DescribeDBParameters actions.
            ParameterName (string) --Specifies the name of the parameter.
            ParameterValue (string) --Specifies the value of the parameter.
            Description (string) --Provides a description of the parameter.
            Source (string) --Indicates the source of the parameter value.
            ApplyType (string) --Specifies the engine specific parameters type.
            DataType (string) --Specifies the valid data type for the parameter.
            AllowedValues (string) --Specifies the valid range of values for the parameter.
            IsModifiable (boolean) --Indicates whether (true ) or not (false ) the parameter can be modified. Some parameters have security or operational implications that prevent them from being changed.
            MinimumEngineVersion (string) --The earliest engine version to which the parameter can apply.
            ApplyMethod (string) --Indicates when to apply parameter updates.

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

    :returns:
    Must be 1 to 255 alphanumeric characters
    First character must be a letter
    Cannot end with a hyphen or contain two consecutive hyphens

    """
    pass


def _is_bytes_like(obj):
    """
    Check whether obj behaves like a bytes object.
    """
    try:
        obj + b''
    except (TypeError, ValueError):
        return False
    return True


def time_convert(xdata):
    """ Convert time from MJD to UTC time

    Parameters
    ----------
    xdata : :obj:`xarray.DataArray`
        TIME column from the MS or table xarray dataset in MJD format.

    Returns
    -------
    newtime : :obj:`xarray.DataArray`
        TIME column in a more human readable UTC format. Stored as :obj:`numpy.datetime` type.

    """
    import pyrap.quanta as qa
    """
    The difference between MJD and unix time i.e. munix = MJD - unix_time
    so unix_time = MJD - munix
    munix = 3506716800.0 = (40857 * 86400)

    The value 40587 is the number of days between the MJD epoch (1858-11-17) and the Unix epoch (1970-01-01), and 86400 is the number of seconds in a day
    """
    init_time = xdata[0].data.compute()
    time_diff = xdata - xdata[0]
    init_time = qa.quantity(init_time, 's').to_unix_time()
    unix_time = time_diff + init_time
    unix_time = unix_time.astype('datetime64[s]')
    return unix_time


@classmethod
def succeed(cls, result):
    """
        Returns a Future for which the result has been set to the given result.
        Similar to Twisted's `Deferred.succeed()`.
        """
    f = cls()
    f.set_result(result)
    return f


@staticmethod
def calc_cidr_mask(mask):
    """
        Calculate the CIDR mask from the given full notation subnet mask.
        :param mask: full notation subnet mask (i.e. 255.255.255.0)
        :return: subnet mask in CIDR notation (i.e. /24)
        """
    mask_splitter = mask.split('.')
    cidr_mask = 0
    for i in range(0, len(mask_splitter)):
        mask_octet = format(int(str(bin(int(mask_splitter[i])))[2:], 2),
            '{fill}{width}b'.format(width=8, fill=0))
        cidr_mask += mask_octet.count('1')
    return cidr_mask


def set_watched(db, aid, ep_type, number):
    """Set episode as watched."""
    db.cursor().execute(
        """UPDATE episode SET user_watched=:watched
        WHERE aid=:aid AND type=:type AND number=:number"""
        , {'aid': aid, 'type': ep_type, 'number': number, 'watched': 1})


def quick_check_line_components(line_bin, dpi):
    """Quickly check whether the components of line_bin are
    reasonable.  Returns a value between 0 and 1; <0.5 means that
    there is probably something wrong."""
    return 1.0


def vcp(el_num: int) ->str:
    """Determine volume coverage pattern by number of scans."""
    if el_num == 5:
        task_name = 'VCP31'
    elif el_num == 9:
        task_name = 'VCP21'
    elif el_num == 14:
        task_name = 'VCP11'
    else:
        task_name = 'Unknown'
    return task_name


@NotImplementedError
def dfa_conformance_check(dfa):
    """ Checks if the dfa is conformant to the specifications.

    :param dict dfa:
    :return: *(Bool)*
    """
    return


def checkavailrawpc(context, am):
    """Returns a list of node objects representing available raw PCs at the
given aggregate."""
    avail = []
    ad = am.listresources(context)
    for node in ad.nodes:
        if node.exclusive and node.available:
            if 'raw-pc' in node.sliver_types:
                avail.append(node)
    return avail


@staticmethod
def _unpack_varint(bytes):
    """ Convert a varint to an integer.
        :param bytes: Bytes containing the varint.
        :return: integer
        """
    value = 0
    base = 1
    rd = 0
    for raw_byte in bytes:
        val_byte = ord(raw_byte) if type(raw_byte) != int else raw_byte
        rd += 1
        value += (val_byte & 127) * base
        if val_byte & 128:
            base *= 128
        else:
            break
    return value, rd


def insert_variation_impacts(session, metadata, buffer):
    """
    Populate the variant_impacts table with each variant in the buffer.
    """
    if len(buffer) == 0:
        return
    tbl = metadata.tables['variant_impacts']
    session.execute(tbl.insert(), buffer)
    session.commit()


def merge(a, b):
    """
    Merge all attributes and metadata from I{a} to I{b}.
    @param a: A I{source} object
    @type a: L{Object}
    @param b: A I{destination} object
    @type b: L{Object}
    """
    for item in a:
        setattr(b, item[0], item[1])
        b.__metadata__ = b.__metadata__
    return b


def _parse_data(data, data_args):
    """Parse different types of arguments"""
    data = data or {}
    if isinstance(data, dict):
        for k in data_args:
            data[k] = data_args[k]
    elif isinstance(data, list) and len(data_args.keys()) > 0:
        data.append(data_args)
    return data if len(data) > 0 else None


@classmethod
def has_global_scope(cls, scope):
    """
        Determine if a model has a global scope.

        :param scope: The scope to register
        :type scope: orator.orm.scopes.scope.Scope or str
        """
    return cls.get_global_scope(scope) is not None


def calculate_gear_box_speeds_in_v1(gear, final_drive_speed,
    gear_box_ratios, clutch):
    """
    Calculates Gear box speed vector [RPM].

    :param gears:
        Gear vector [-].
    :type gears: numpy.array

    :param gear_box_speeds_out:
        Wheel speed vector [RPM].
    :type gear_box_speeds_out: numpy.array

    :param gear_box_ratios:
        Gear box ratios [-].
    :type gear_box_ratios: dict

    :return:
        Gear box speed vector [RPM].
    :rtype: numpy.array
    """
    if clutch == 1:
        return 0
    return final_drive_speed * gear_box_ratios[gear - 1]


def __call__(cls, value, names=None, *, module=None, qualname=None, type=
    None, start=1):
    """Either returns an existing member, or creates a new enum class.

        This method is used both when an enum class is given a value to match
        to an enumeration member (i.e. Color(3)) and for the functional API
        (i.e. Color = Enum('Color', names='red green blue')).

        When used for the functional API:

        `value` will be the name of the new class.

        `names` should be either a string of white-space/comma delimited names
        (values will start at `start`), or an iterator/mapping of name, value pairs.

        `module` should be set to the module this class is being created in;
        if it is not set, an attempt to find that module will be made, but if
        it fails the class will not be picklable.

        `qualname` should be set to the actual location this class can be found
        at in its module; by default it is set to the global scope.  If this is
        not correct, unpickling will fail in some circumstances.

        `type`, if set, will be mixed in as the first base class.

        """
    if names is None:
        return cls.__new__(cls, value)
    return cls._create_(value, names, module=module, qualname=qualname,
        type=type, start=start)


def _validate_param_grid(param_grid):
    """Check if the parameter values are valid

    This basically does the same checks as in the constructor of the
    :class:`~.core.GenSVM` class, but for the entire parameter grid.

    """
    conditions = {'p': lambda x: 1.0 <= x <= 2.0, 'kappa': lambda x: x > -
        1.0, 'lmd': lambda x: x > 0, 'epsilon': lambda x: x > 0, 'gamma':
        lambda x: x != 0, 'weights': lambda x: x in ['unit', 'group']}
    for param in conditions:
        if param in param_grid:
            if not all(map(conditions[param], param_grid[param])):
                raise ValueError('Invalid value in grid for parameter: %s.' %
                    param)


def add_nodal_positions(graph, centroids):
    """Adds the x, y, z attributes to each node in graph."""
    for roi in centroids:
        graph.nodes[roi]['x'] = float(centroids[roi][0])
        graph.nodes[roi]['y'] = float(centroids[roi][1])
        graph.nodes[roi]['z'] = float(centroids[roi][2])
    return


def readfile(pathname):
    """retrun the data in the file"""
    fhandle = open(pathname, 'rb')
    data = fhandle.read()
    try:
        data = data.decode('ISO-8859-2')
    except AttributeError:
        pass
    fhandle.close()
    return data


def location_dict(lat=None, lon=None, height=None):
    """
    Create a location dict from the single values

    Args:
        lat, lon, height (float, optional) : the position

    Returns:
        dict : the location dict

    Raises:
        ValueError : if not enough values are specified
    """
    if lat is not None and lon is not None:
        if height is not None:
            return {'lat': lat, 'lng': lon, 'height': height}
        else:
            return {'lat': lat, 'lng': lon}
    else:
        raise ValueError("At least 'lat' and 'lon' need to be defined")


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

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


def google_map(context):
    """
    Dependencies for google_map gizmo.
    """
    return 'tethys_gizmos/js/tethys_map.js',


def pop():
    """Pop the next mesasge from the queue. The messages is a dict
        conaining a key 'name' with the spider name and other keys as spider
        attributes.

        This method can return a deferred. """


@staticmethod
def create_htmltable(command_output_array_table, first_row_html_header):
    """
           Add to output windows an HTML table with the command
        :param context:
        :param command_output:
        """
    str = '
\n'
    str += '
\n'
    if first_row_html_header:
        if len(command_output_array_table) > 0:
            for th in command_output_array_table[0]:
                str += '' + th + '	\n'
    str += '
\n'
    str += '
\n'
    for idx, row in enumerate(command_output_array_table):
        if not first_row_html_header or idx > 0:
            str += '
\n'
            for val in row:
                str += '' + val + '	\n'
            str += '
\n'
    str += '
\n
\n'
    return str


def _clean_with_no_strip(field, data):
    """Clean Django's CharField field without strip=True.

    :param field: Instance of the Charfield.
    :param data: The un-cleaned data from the form.
    :returns: Cleaned data.
    """
    field.strip = False
    return field.clean(data)


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 quoteStringArgument(argument):
    """
    Quote an argument to L{serverFromString} and L{clientFromString}.  Since
    arguments are separated with colons and colons are escaped with
    backslashes, some care is necessary if, for example, you have a pathname,
    you may be tempted to interpolate into a string like this::

        serverFromString("ssl:443:privateKey=%s" % (myPathName,))

    This may appear to work, but will have portability issues (Windows
    pathnames, for example).  Usually you should just construct the appropriate
    endpoint type rather than interpolating strings, which in this case would
    be L{SSL4ServerEndpoint}.  There are some use-cases where you may need to
    generate such a string, though; for example, a tool to manipulate a
    configuration file which has strports descriptions in it.  To be correct in
    those cases, do this instead::

        serverFromString("ssl:443:privateKey=%s" %
                         (quoteStringArgument(myPathName),))

    @param argument: The part of the endpoint description string you want to
        pass through.

    @type argument: C{str}

    @return: The quoted argument.

    @rtype: C{str}
    """
    return argument.replace('\\', '\\\\').replace(':', '\\:')


def chunks(seq, num):
    """splits the list seq in num (almost) equally sized chunks."""
    avg = len(seq) / float(num)
    out = []
    last = 0.0
    while last < len(seq):
        out.append(seq[int(last):int(last + avg)])
        last += avg
    return out


def onboot():
    """Chained call from :meth:`IWebApp.startapp`. Implementation
        can chain this onboot() call further down to other framwork /
        application plugins.

        While building a web application, this method can be used to configure
        url route-mapping by calling :meth:`add_view` or by parsing a mapper
        file. In any case, when this method returns, route-mapping must be
        compiled and cached for resolving request's view-callables.
        """


def addmargins(blocks):
    """Adds empty blocks for vertical spacing.

    This groups bullets, options, and definitions together with no vertical
    space between them, and adds an empty block between all other blocks.
    """
    i = 1
    while i < len(blocks):
        if blocks[i][b'type'] == blocks[i - 1][b'type'] and blocks[i][b'type'
            ] in (b'bullet', b'option', b'field'):
            i += 1
        elif not blocks[i - 1][b'lines']:
            i += 1
        else:
            blocks.insert(i, {b'lines': [b''], b'indent': 0, b'type':
                b'margin'})
            i += 2
    return blocks


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_admin(href):
    """Returns True if provided href has /api/admin into it.

    :param str href: href

    :return: True if admin else False

    :rtype: Boolean
    """
    if '/api/admin/extension/' in href:
        return False
    elif '/api/admin/' in href:
        return True
    else:
        return False


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


def normalize_date(date):
    """Removes non digits and joins numbers together

        Args:
            date:str
        Returns:
            returns str
        """
    whitelist = set('0123456789')
    normalized_date = ''.join(filter(whitelist.__contains__, date))
    return str(normalized_date)


@task
def get_tasks():
    """Get all paver-defined tasks."""
    from paver.tasks import environment
    for task in environment.get_tasks():
        print(task.shortname)


def sbolRule10102(sbol_obj, arg):
    """An SBOL document MUST declare the use of the following XML namespace:
    http://www.w3.org/1999/02/22-rdf-syntax-ns#."""
    raise NotImplementedError('Not yet implemented')


def object_load_bmesh(bm: 'bmesh.types.BMesh', scene: 'bpy.types.Scene',
    object: 'bpy.types.Object'):
    """Loads a bmesh into an object/mesh. This is a “private” bmop.

    :param bm: The bmesh to operate on.
    :type bm: 'bmesh.types.BMesh'
    :param scene: Undocumented.
    :type scene: 'bpy.types.Scene'
    :param object: Undocumented.
    :type object: 'bpy.types.Object'
    """
    pass


def _calc_mdd_4_drawback_analysis(pair, y):
    """
    此函数仅供 drawback_analysis 使用
    用于计算最大回撤使用
    :param pair:
    :param y:
    :return:
    """
    max_y_last = pair[0]
    max_y = max_y_last if max_y_last > y else y
    mdd_last = pair[1]
    keep_max = pair[2]
    dd = y / max_y - 1
    if keep_max:
        mdd = dd if dd < mdd_last else mdd_last
    else:
        mdd = dd
    return max_y, mdd, keep_max


def ajax_site_layout():
    """Get the path to the ajax site layout to use by default for the given
        content object.
        """


def ix_name(table_name, column_name):
    """Returns the name that will be used in the database for an index key, given:

       :arg table_name: The name of the table to which the index belongs.
       :arg column_name: The name of the column that is indexed.
    """
    return 'ix_%s_%s' % (table_name, column_name)


def deep_get(d, *keys, default=None):
    """ Recursive safe search in a dictionary of dictionaries.

    Args:
        d: the dictionary to work with
        *keys: the list of keys to work with
        default: the default value to return if the recursive search did not succeed

    Returns:
        The value wich was found recursively in d, or default if the search did not succeed

    Example:

        >>> d = {"user": {"id": 1, "login": "foo"}, "date": "2016-04-27"}
        >>> deep_get(d, "user", "login")
        "foo"
        >>> deep_get(d, "user")
        {"id": 1, "login": "foo"}
        >>> deep_get(d, "user", "name")
        None
        >>> deep_get(d, "user", "name", default="bar")
        "bar"
    """
    for key in keys:
        try:
            d = d[key]
        except (KeyError, IndexError, TypeError):
            return default
    return d


@staticmethod
def connection_status(handle_db_connection):
    """
        Check whether a connection to DB is open.

        :param handle_db_connection:
        :return: True if connection is open
        """
    if handle_db_connection:
        return True
    return False


def string_to_pretty_xml(input_string=None, encode='UTF-8'):
    """
        format string to xml
    :param input_string:
    :param encode:
    :return: formatting string
    """
    import xml.dom.minidom
    xml = xml.dom.minidom.parseString(input_string)
    return xml.toprettyxml()


def pad_encoded_str(encoded_string):
    """Return padded encoded string with zero
       to full byte if missing
    """
    extra_zero = 8 - len(encoded_string) % 8
    padded_encoded_string = '0' * extra_zero + encoded_string
    extra_zero_info = '{0:08b}'.format(extra_zero)
    padded_encoded_string = extra_zero_info + padded_encoded_string
    return padded_encoded_string


def d_r_dyy(x, y):
    """
    second derivative dr/dxdx
    :param x:
    :param y:
    :return:
    """
    return x ** 2 / (x ** 2 + y ** 2) ** (3.0 / 2)


def quitGame():
    """Exit the current game."""
    global quit
    quit = True


def check_fastq_line(fastq):
    """Check if fastq string has some necessary features of the fasta format.

    :param fastq: single string with a record of fastq """
    check = fastq.split('\n')
    assert len(check) == 4, 'Data is not fastq format: Not enough fields'
    assert check[0].startswith('@'
        ), 'Data is not fastq format: Does not start with @'
    assert len(check[1]) == len(check[3]
        ), 'Data is not fastq format: Sequence and quality scores do not match'
    assert check[2].startswith('+'
        ), 'Data is not fastq format: third line does not start with +'
    return True


def cosarctan(x):
    """Calculates the trigonometric function: Cos(Arctan(x)) by simplifying
    to (x^2+1)^-0.5. This function is meant to provide an improvement in
    speed over long iterations"""
    return (x ** 2 + 1) ** -0.5


def __contains__(month):
    """Return true if the given month is within the interval."""


@staticmethod
def printProcessedFile(filePath):
    """
        Prints out the file path, without interfering with the processing
        """
    print('---> ' + filePath)
    return True


def value_or(value, default):
    """Returns default if value is exactly None."""
    return value if value is not None else default


def home(routes, self):
    """Default home-page.

		Args:
			self (App): ProbeDesigner.App instance.
		"""
    d = self.vd.copy()
    d['title'] = 'Default Home-page'
    d['description'] = 'Nothing to say...'
    return d


def hot_cold_process(curr_yr, p_cold_rolling_steel, assumptions):
    """Calculate factor based on the fraction of hot
    and cold rolling processes in steel manufacturing.
    The fraction of either process is calculated based on
    the scenario input of the future share of cold rollling
    processes. A sigmoid diffusion towards this fucture defined
    fraction is implemented.

    Arguments
    ----------
    curr_yr : int
        Current year
    strategy_vars : dict
        Strategy variables
    assumptions : dict
        Assumptions including efficiencies of either process
        and the base year share

    Returns
    -------
    factor : float
        Factor to change energy demand
    """
    p_cold_rolling_by = assumptions.p_cold_rolling_steel_by
    p_hot_rolling_by = 1.0 - p_cold_rolling_by
    p_cold_rolling_cy = p_cold_rolling_steel[curr_yr]
    p_hot_rolling_cy = 1 - p_cold_rolling_cy
    eff_cold = assumptions.eff_cold_rolling_process
    eff_hot = assumptions.eff_hot_rolling_process
    p_by = p_cold_rolling_by * eff_cold + p_hot_rolling_by * eff_hot
    p_cy = p_cold_rolling_cy * eff_cold + p_hot_rolling_cy * eff_hot
    factor = p_cy / p_by
    return factor


def smart_urljoin(base, url):
    """urljoin, only an empty fragment from the relative(?) URL will be
    preserved.
    """
    from .compat.moves.urllib.parse import urljoin
    joined = urljoin(base, url)
    if url.endswith('#') and not joined.endswith('#'):
        joined += '#'
    return joined


@staticmethod
def _get_out_blocks(n_blocks):
    """
        Helper function that builds empty lists of lists to be filled as
        parameter of type COLLECTION_INOUT
        """
    return [[object() for _ in range(n_blocks[1])] for _ in range(n_blocks[0])]


@staticmethod
def get_codename():
    """Return the service_available name of the service.

        This name is used when setting service availability in
        set_availability method. If the method is not implemented, service
        availability is not set.
        """
    raise NotImplementedError


def _unsafe_dict_update(default_dict, override_dict):
    """
    Using defaults and an overriding dictionary, create a new dictionary.
    This new dictionary has the same values as the default dictionary and
    the same types. Thus, if there are values that are in the overriding
    dictionary, but not in the original, they will be ignored.

    Arguments
    ---------
    default_dict: dict
        Starting dictionary with defaults.
    override_dict: dict
        Dictionary with custom values (such as model parameters).

    Returns
    -------
    dict
        Merged dictionary.
    """
    new_dict = default_dict
    for key in override_dict:
        if key not in default_dict:
            print(f'Warning: key {key} is being ignored.')
    for key in new_dict:
        if key in override_dict:
            str_val = override_dict[key]
            if type(new_dict[key]) == bool:
                new_dict[key] = str_val in ['True', 'true', 'T', 't', True]
            else:
                try:
                    new_dict[key] = type(new_dict[key])(str_val)
                except TypeError:
                    raise TypeError(f'Error at {key}')
    return new_dict


def replace_rn(strobj):
    '\n    There are characters such as "\r" and "\n" that perform line breaks (or returns),\n    and these can create parsing dramas when reading/writing to disk.\n    This helper function mitigates this by replacing it with a benign alternative.\n    '
    return strobj.replace('\r', 'esc-r-').replace('\n', 'esc-n-')


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

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

    Return True on successful import.

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


@classmethod
def fail(cls, result):
    """
        Returns a Future for which the error has been set to the given result.
        Similar to Twisted's `Deferred.fail()`.
        """
    f = cls()
    f.set_exception(result)
    return f


def check_qids(qids):
    """Asserts that query ids are grouped into contiguous blocks.

    Note that query ids do not have to be sorted.

    Parameters
    ----------
    qids : array_like of shape = [n_samples]
        List of query ids.

    Returns
    -------
    int
        Number of unique query ids in `qids`.

    Raises
    ------
    ValueError
        If any two query ids are not in the same contiguous block.
        e.g. ``[1, 1, 3, 3, 2, 2, 3]``

    """
    seen_qids = set()
    prev_qid = None
    for qid in qids:
        assert qid is not None
        if qid != prev_qid:
            if qid in seen_qids:
                raise ValueError('Samples must be grouped by qid.')
            seen_qids.add(qid)
            prev_qid = qid
    return len(seen_qids)


def zone_target_temperature(zone):
    """
    Get target temperature for this zone
    """
    return zone['targettemperature']


def _setsockopt(sock, option, value):
    """
    This wraps setting socket options since python2 vs python3 handles strings differently
    and pyzmq requires a different call. See http://pyzmq.readthedocs.io/en/latest/unicode.html
    """
    try:
        sock.setsockopt(option, value)
    except TypeError:
        sock.setsockopt_string(option, value)


@classmethod
def match_project_from_project_name(cls, project_name):
    """Parses the project from a project resource.

        Args:
          project_name (string): A fully-qualified path representing a project
            resource.

        Returns:
          A string representing the project.
        """
    return cls._PROJECT_PATH_TEMPLATE.match(project_name).get('project')


def consulta():
    """Esta es la función Consulta"""
    print('Consultando')


@staticmethod
def _define_module_argument_spec():
    """
        Define the argument spec for the ansible module
        :return: argument spec dictionary
        """
    argument_spec = dict(server_id=dict(required=True), credentials=dict(
        default=False))
    return {'argument_spec': argument_spec}


def __compute_means__(v, M, C, i1, i2):
    """
    Computes the conditional means.

    :param v: The values conditioned on.
    :param M: Marginal means (vector).
    :param C: Covariance matrix.
    :param i1: Indices of unconditioned variables.
    :param i2: Indices of conditioned variables.
    :return: Conditional means.
    """
    return M[i1] + C.C12.dot(C.C22I).dot(v - M[i2])


def TrimReads(r1, r2, q1, q2, R1trimlength=None, R2trimlength=None):
    """Trims a pair of reads to a specified length by removing nucleotides from the 3' ends of the reads.

    *r1* and *r2* are strings representing a pair of sequencing reads.

    *q1* and *q2* are strings giving the Q-scores for the nucleotides in
    *r1* and *r2*; these Q-scores are assumed to be encoded as the ASCII code
    for the Q-score + 33.

    *R1trimlength* and *R2trimlength* are the lengths to which the *r1* and *r2* reads
    will be trimmed, as well as the corresponding Q-scores *q1* and *q2*. If no lengths are
    specified, the un-modified *r1*, *r2*, *q1*, and *q2* are returned.

    This function trims the *r1* and *r2* reads in a pair of reads. Nucleotides are trimmed
    away from the 3' end of each read to a specified length. The user-provided length includes
    the primer binding site and the barcode sequence at the 5' end of each read. The
    trimming is done from the 3' end of the read as Illumina Q-scores typically drop in this
    region resulting in less accurate sequence calls. This drop can be observed
    by running FastQC on the gzipped read files. In addition to trimming reads *r1* and
    *r2*, the corresponding Q-scores *q1* and *q2* for those reads are trimmed in the
    same manner.

    The return variable for this function is *(r1trim, r2trim, q1trim, q2trim)*, which
    are the trimmed sequencing reads and corresponding Q-scores.

    >>> r1 = 'GATTCTACATCCAAATGTGCACTGAACTTAAACTCAGTGATTATGAGGGGCGACTGATCCAGAACAGCTTAACAA'
    >>> r2 = 'TGTTAAGCTGTTCTGGATCAGTCGCCCCTCATAATCACTGAGTTTAAGTTCAGTGCACATTTGGATGTAGAATCT'
    >>> q1 = 'C9@ACCEFEGGG99-C9E<C9@E,,,CFFFC9CCC,,CA9EEEDD,,,,+66:FEECFFFCGCFE,@DFFFGGGG'
    >>> q2 = '6,A@,,6CFFGGGGCA,EC<,CFFCCCFFFFG9<EF9EE,,,<CC,,;EEFC9<,;,;,;CE,,,C8EE99,BC,'
    >>> TrimReads(r1, r2, q1, q2)
    ('GATTCTACATCCAAATGTGCACTGAACTTAAACTCAGTGATTATGAGGGGCGACTGATCCAGAACAGCTTAACAA', 'TGTTAAGCTGTTCTGGATCAGTCGCCCCTCATAATCACTGAGTTTAAGTTCAGTGCACATTTGGATGTAGAATCT', 'C9@ACCEFEGGG99-C9E<C9@E,,,CFFFC9CCC,,CA9EEEDD,,,,+66:FEECFFFCGCFE,@DFFFGGGG', '6,A@,,6CFFGGGGCA,EC<,CFFCCCFFFFG9<EF9EE,,,<CC,,;EEFC9<,;,;,;CE,,,C8EE99,BC,')
    >>> (R1trimlength, R2trimlength) = (100, 100)
    >>> TrimReads(r1, r2, q1, q2, R1trimlength, R2trimlength)
    ('GATTCTACATCCAAATGTGCACTGAACTTAAACTCAGTGATTATGAGGGGCGACTGATCCAGAACAGCTTAACAA', 'TGTTAAGCTGTTCTGGATCAGTCGCCCCTCATAATCACTGAGTTTAAGTTCAGTGCACATTTGGATGTAGAATCT', 'C9@ACCEFEGGG99-C9E<C9@E,,,CFFFC9CCC,,CA9EEEDD,,,,+66:FEECFFFCGCFE,@DFFFGGGG', '6,A@,,6CFFGGGGCA,EC<,CFFCCCFFFFG9<EF9EE,,,<CC,,;EEFC9<,;,;,;CE,,,C8EE99,BC,')
    >>> (R1trimlength, R2trimlength) = (5, 10)
    >>> TrimReads(r1, r2, q1, q2, R1trimlength, R2trimlength)
    ('GATTC', 'TGTTAAGCTG', 'C9@AC', '6,A@,,6CFF')
    """
    if R1trimlength is not None and R2trimlength is not None:
        assert R1trimlength > 0 and isinstance(R1trimlength, int
            ), 'r1 trimmed length must be positive integer: %s' % R1trimlength
        assert R2trimlength > 0 and isinstance(R2trimlength, int
            ), 'r2 trimmed length must be positive integer: %s' % R2trimlength
        assert '\n' not in r1, 'r1 string must not have new line character: %s' % r1
        assert '\n' not in r2, 'r2 string must not have new line character: %s' % r2
        assert len(r1) == len(q1
            ), 'r1 and q1 must be the same length: %s %s' % (r1, q1)
        assert len(r2) == len(q2
            ), 'r2 and q2 must be the same length: %s %s' % (r2, q2)
        r1trim = r1
        r2trim = r2
        q1trim = q1
        q2trim = q2
        if len(r1trim) > R1trimlength:
            r1trim = r1[:R1trimlength]
            q1trim = q1[:R1trimlength]
            assert len(r1trim
                ) == R1trimlength, 'r1 incorrect length: %s' % r1trim
            assert len(q1trim
                ) == R1trimlength, 'q1 incorrect length: %s' % q1trim
        if len(r2trim) > R2trimlength:
            r2trim = r2[:R2trimlength]
            q2trim = q2[:R2trimlength]
            assert len(r2trim
                ) == R2trimlength, 'r2 incorrect length: %s' % r2trim
            assert len(q2trim
                ) == R2trimlength, 'q2 incorrect length: %s' % q2trim
        return r1trim, r2trim, q1trim, q2trim
    else:
        return r1, r2, q1, q2


@classmethod
def generate_id(cls):
    """Return a unique ID for each date-picker input class."""
    cls._index += 1
    return 'fp_%s' % cls._index


def polygon_under_graph(xlist, ylist):
    """
    Construct the vertex list which defines the polygon filling the space under
    the (xlist, ylist) line graph.  Assumes the xs are in ascending order.
    """
    return [(xlist[0], 0.0), *zip(xlist, ylist), (xlist[-1], 0.0)]


def get_c_option_index(args):
    """
    Get index of "-c" argument and check if it's interpreter's option
    :param args: list of arguments
    :return: index of "-c" if it's an interpreter's option and -1 if it doesn't exist or program's option
    """
    try:
        ind_c = args.index('-c')
    except ValueError:
        return -1
    else:
        for i in range(1, ind_c):
            if not args[i].startswith('-'):
                return -1
        return ind_c


def _rssify_link(link):
    """return a link in a suitable format"""
    if type(link) is dict:
        return link['href']
    else:
        return link


def custom_indicator_class_factory(indicator_type, base_class, class_dict,
    value_fields):
    """Return internal methods for dynamically building Custom Indicator Class."""
    value_count = len(value_fields)

    def init_1(self, tcex, value1, xid, **kwargs):
        """Init method for Custom Indicator Types with one value"""
        summary = self.build_summary(value1)
        base_class.__init__(self, tcex, indicator_type, summary, xid, **kwargs)
        for k, v in class_dict.items():
            setattr(self, k, v)

    def init_2(self, tcex, value1, value2, xid, **kwargs):
        """Init method for Custom Indicator Types with two values."""
        summary = self.build_summary(value1, value2)
        base_class.__init__(self, tcex, indicator_type, summary, xid, **kwargs)
        for k, v in class_dict.items():
            setattr(self, k, v)

    def init_3(self, tcex, value1, value2, value3, xid, **kwargs):
        """Init method for Custom Indicator Types with three values."""
        summary = self.build_summary(value1, value2, value3)
        base_class.__init__(self, tcex, indicator_type, summary, xid, **kwargs)
        for k, v in class_dict.items():
            setattr(self, k, v)
    class_name = indicator_type.replace(' ', '')
    init_method = locals()[f'init_{value_count}']
    newclass = type(str(class_name), (base_class,), {'__init__': init_method})
    return newclass


def add_atom_data(data_api, data_setters, atom_names, element_names,
    atom_charges, group_atom_ind):
    """Add the atomic data to the DataTransferInterface.
    :param data_api the data api from where to get the data
    :param data_setters the class to push the data to
    :param atom_nams the list of atom names for the group
    :param element_names the list of element names for this group
    :param atom_charges the list formal atomic charges for this group
    :param group_atom_ind the index of this atom in the group"""
    atom_name = atom_names[group_atom_ind]
    element = element_names[group_atom_ind]
    charge = atom_charges[group_atom_ind]
    alternative_location_id = data_api.alt_loc_list[data_api.atom_counter]
    serial_number = data_api.atom_id_list[data_api.atom_counter]
    x = data_api.x_coord_list[data_api.atom_counter]
    y = data_api.y_coord_list[data_api.atom_counter]
    z = data_api.z_coord_list[data_api.atom_counter]
    occupancy = data_api.occupancy_list[data_api.atom_counter]
    temperature_factor = data_api.b_factor_list[data_api.atom_counter]
    data_setters.set_atom_info(atom_name, serial_number,
        alternative_location_id, x, y, z, occupancy, temperature_factor,
        element, charge)


def custom_bake_remap(scene):
    """
    Remap bake types into the new types and set the flags accordingly
    """
    bake_lookup = ('COMBINED', 'AO', 'SHADOW', 'NORMAL', 'UV', 'EMIT',
        'ENVIRONMENT', 'DIFFUSE_DIRECT', 'DIFFUSE_INDIRECT',
        'DIFFUSE_COLOR', 'GLOSSY_DIRECT', 'GLOSSY_INDIRECT', 'GLOSSY_COLOR',
        'TRANSMISSION_DIRECT', 'TRANSMISSION_INDIRECT',
        'TRANSMISSION_COLOR', 'SUBSURFACE_DIRECT', 'SUBSURFACE_INDIRECT',
        'SUBSURFACE_COLOR')
    diffuse_direct_idx = bake_lookup.index('DIFFUSE_DIRECT')
    cscene = scene.cycles
    bake_type_idx = cscene.get('bake_type')
    if bake_type_idx is None:
        cscene.bake_type = 'COMBINED'
        return
    if bake_type_idx < diffuse_direct_idx:
        return
    bake_type = bake_lookup[bake_type_idx]
    cscene.bake_type, end = bake_type.split('_')
    if end == 'DIRECT':
        scene.render.bake.use_pass_indirect = False
        scene.render.bake.use_pass_color = False
    elif end == 'INDIRECT':
        scene.render.bake.use_pass_direct = False
        scene.render.bake.use_pass_color = False
    elif end == 'COLOR':
        scene.render.bake.use_pass_direct = False
        scene.render.bake.use_pass_indirect = False


def rh_dodec_coord_test(x, y, z):
    """Test for coordinate in rhombic cuboctahedron grid"""
    return x % 2 + y % 2 + z % 2 == 0 or x % 2 + y % 2 + z % 2 == 3 and (x //
        2 + y // 2) % 2 == z // 2 % 2


def ensure_list_type(elem):
    """
    Transforms the argument elem into a list if it's not already its type.
    :param elem: Element to transform into a list.
    :return: A list containing the element, or the element if it is already a list.
    """
    if type(elem) != list:
        elem = [elem]
    return elem


def _standardize_page_based_counters(style, pseudo_type):
    """Drop 'pages' counter from style in @page and @margin context.

    Ensure `counter-increment: page` for @page context if not otherwise
    manipulated by the style.

    """
    page_counter_touched = False
    for propname in ('counter_reset', 'counter_increment'):
        if style[propname] == 'auto':
            style[propname] = ()
            continue
        justified_values = []
        for name, value in style[propname]:
            if name == 'page':
                page_counter_touched = True
            if name != 'pages':
                justified_values.append((name, value))
        style[propname] = tuple(justified_values)
    if pseudo_type is None and not page_counter_touched:
        style['counter_increment'] = (('page', 1),) + style['counter_increment'
            ]


def os_folder_is_path(path_or_stream):
    """
    Is given object `path_or_stream` a file path?
    :param path_or_stream: file path or stream, file/file-like object
    :return: True if `path_or_stream` is a file path
    """
    return isinstance(path_or_stream, str)


@staticmethod
def linkType():
    """
        Default link type to be used.

        :returns: string
        """
    return 'Ethernet'


def mos_repr_real(f: float) ->str:
    """ Get the Mosel source code representation of a float, without type or bound checking. """
    return repr(f)


@staticmethod
def verify_protocol(protocol):
    """Verify the protocol.

        :param protocol: 'I' or 'F' -- str
        :returns: boolean
        """
    return True if len(protocol) == 1 and ('I' in protocol or 'F' in protocol
        ) else False


def walk_up(arr, start_pos):
    """
    Performs a greedy search for a local maximum of :param:`arr` from the given :param:`start_pos`.
    """
    cur_pos = start_pos
    if arr[cur_pos - 1] > arr[cur_pos + 1]:
        while cur_pos >= 0:
            if arr[cur_pos - 1] > arr[cur_pos]:
                cur_pos -= 1
            else:
                break
    else:
        while cur_pos < len(arr):
            if arr[cur_pos + 1] > arr[cur_pos]:
                cur_pos += 1
            else:
                break
    return cur_pos


@staticmethod
def payload_for_create(email, phone_number, legal_name, **kwargs):
    """Build the API 'create user' payload from property values."""
    payload = {'logins': [{'email': email}], 'phone_numbers': [phone_number
        ], 'legal_names': [legal_name], 'extra': {'supp_id': kwargs.get(
        'supp_id'), 'note': kwargs.get('note'), 'is_business': kwargs.get(
        'is_business'), 'cip_tag': kwargs.get('cip_tag')}}
    if 'base_doc' in kwargs:
        payload['documents'] = [kwargs['base_doc']]
    if 'password' in kwargs:
        payload['logins'][0]['password'] = kwargs['password']
    return payload


@staticmethod
def constraint_normal_vector(n):
    """This should be equal to zero"""
    return n[0] ** 2 + n[1] ** 2 + n[2] ** 2 - 1


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

        :param SsoChangeLogoutUrlType val:
        :rtype: EventType
        """
    return cls('sso_change_logout_url', val)


def _writeEmptyAssignments(fullDir):
    """
	This script generates "empty" routes.czml and displayPaths.js files

	Parameters
	----------
	fullDir: string
		The directory of cesium, including the name of the instance.
	"""
    czmlFilePath = '%s/routes.czml' % fullDir
    f = open(czmlFilePath, 'w')
    czmlStr = '[ \n'
    czmlStr += '{ \n'
    czmlStr += '    "id": "document", \n'
    czmlStr += '    "version": "1.0" \n'
    czmlStr += '}\n'
    czmlStr += ']'
    f.write(czmlStr)
    f.close()
    jsFilePath = '%s/displayPaths.js' % fullDir
    f = open(jsFilePath, 'w')
    jsStr = (
        '// This .js file is auto-generated by `createCesium` from VeRoViz\n')
    jsStr += '// Display paths for cesium application\n\n'
    jsStr += 'function displayPaths() {\n'
    jsStr += '    // pass \n'
    jsStr += '}'
    f.write(jsStr)
    f.close()


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

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

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


def _get_localized_fn(path, root_dir):
    """
    Return absolute `path` relative to `root_dir`.

    When `path` == ``/home/xex/somefile.txt`` and `root_dir` == ``/home``,
    returned path will be ``/xex/somefile.txt``.

    Args:
        path (str): Absolute path beginning in `root_dir`.
        root_dir (str): Absolute path containing `path` argument.

    Returns:
        str: Local `path` when `root_dir` is considered as root of FS.
    """
    local_fn = path
    if path.startswith(root_dir):
        local_fn = path.replace(root_dir, '', 1)
    if not local_fn.startswith('/'):
        return '/' + local_fn
    return local_fn


@staticmethod
def array_dict_to_array(array_dict, key):
    """
        Get all values from a specific key in a dictionary array, and transform in a simple array

        :param array_dict: Array of dictionaries
        :param key: Interest key, based on this key that the values in array_dict will be extracted
        :return: Array, with values based on the key passed on
        """
    array = []
    for item in array_dict:
        array.append(item[key])
    return array


def rwmeth2filetype(rw_meth):
    """Get the alternate properties that corresponding to the old
    read_meth/write_meth keywords.

    Args:
        rw_meth (str): Read/write method name.

    Returns:
        dict: Property values equivalent to provided read/write method.

    """
    out = {}
    if rw_meth == 'all':
        out['filetype'] = 'binary'
    elif rw_meth == 'line':
        out['filetype'] = 'ascii'
    elif rw_meth == 'table_array':
        out['filetype'] = 'table'
        out['as_array'] = True
    else:
        out['filetype'] = rw_meth
    return out


def _binrange(start, stop):
    """returns a list of ints from start to stop in increments of one binary lshift"""
    out = list()
    out.append(start)
    if start == 0:
        start = 1
        out.append(start)
    while start < stop:
        start = start << 1
        out.append(start)
    return out


def _decode(b):
    """
    Internal decode function (see decode()).

    RETURN VALUE:
      A tuple (slen: int, s: bytes) where slen is the length of the data in bytes and s is the initial buffer with length and colon removed.

    THROWS:
      ValueError if the provided bytes object does not begin with a valid netstring
  """
    slen, s = b.split(b':', 1)
    slen = int(slen.decode('ascii'))
    if slen < 0 or s[slen] != b','[0]:
        raise ValueError
    return slen, s


def replace_missing_ambiguous(seq, missing_ambiguous_list):
    """Given sequence and list of missing or ambiguous characters,
    replace them in sequence with '-'.
    """
    for char in missing_ambiguous_list:
        seq = seq.replace(char, '-')
    return seq


def is_pipeline(obj):
    """Test if something is a Pipeline object. This is put here
    with a deferred import statement to avoid circular imports
    so the I/O don't need to import pipeline.py.

    This probably does not need to be deferred but doing it
    for safety sake.

    Parameters
    ----------
    obj : object
        An object to test to see if it's a Pipeline.

    Returns
    -------
    bool
        True if Pipeline
    """
    from .pipeline import Pipeline
    return isinstance(obj, Pipeline)


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 round_ste(data=None, name=None, attr=None, out=None, **kwargs):
    """Straight-through-estimator of `round()`.

    In forward pass, returns element-wise rounded value to the nearest integer of the input (same as `round()`).

    In backward pass, returns gradients of ``1`` everywhere (instead of ``0`` everywhere as in `round()`):
    :math:`\\frac{d}{dx}{round\\_ste(x)} = 1` vs. :math:`\\frac{d}{dx}{round(x)} = 0`.
    This is useful for quantized training.

    Reference: Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation.

    Example::
      x = round_ste([-1.5, 1.5, -1.9, 1.9, 2.7])
      x.backward()
      x = [-2.,  2., -2.,  2.,  3.]
      x.grad() = [1.,  1., 1.,  1.,  1.]

    The storage type of ``round_ste`` output depends upon the input storage type:
      - round_ste(default) = default
      - round_ste(row_sparse) = row_sparse
      - round_ste(csr) = csr

    Defined in src/operator/contrib/stes_op.cc:L55

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

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

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


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

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


def _applySpecialOrthoOptsCentre(centre, displayCtx, xax, yax, canvas):
    """Shared by the ``xcentre``, ``ycentre``, and ``zcentre`` functions.
    """
    xlo = displayCtx.bounds.getLo(xax)
    ylo = displayCtx.bounds.getLo(yax)
    xlen = displayCtx.bounds.getLen(xax)
    ylen = displayCtx.bounds.getLen(yax)
    xmid = xlo + 0.5 * xlen
    ymid = ylo + 0.5 * ylen
    x = xmid + 0.5 * xlen * centre[0]
    y = ymid + 0.5 * ylen * centre[1]
    canvas.centreDisplayAt(x, y)


def get_app_id_and_task_uuid_from_executor_id(executor_id):
    """Parse the paasta_native executor ID and return the (app id, task uuid)"""
    return executor_id.rsplit('.', 1)


def convert_by_vocab(vocab, items):
    """Converts a sequence of [tokens|ids] using the vocab."""
    output = []
    for item in items:
        output.append(vocab[item])
    return output


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['type']
    if type == 'ANY_OF':
        return 'AnyOfRouteAuthorizationPolicy'
    if type == 'ANONYMOUS':
        return 'AnonymousRouteAuthorizationPolicy'
    if type == 'AUTHENTICATION_ONLY':
        return 'AuthenticationOnlyRouteAuthorizationPolicy'
    else:
        return 'RouteAuthorizationPolicy'


def line(line, types, null_value=None, columns=None):
    """
	Parses a tsv line
	:param line: The line to parse
	:param types: fields types
	:param null_value: value to interpret as a None
	:param columns: which columns to return
	:return: selected columns
	"""
    assert columns is None or len(types) == len(columns)
    fields = line.rstrip('\n').split('\t')
    flen = len(fields)
    res = list()
    for i, vtype in enumerate(types):
        if columns is not None:
            index = columns[i]
        else:
            index = i
        if index < flen:
            field = fields[index]
        else:
            field = null_value
        if i < flen and (null_value is None or field != null_value):
            field = vtype(field)
        else:
            field = None
        res += [field]
    return tuple(res)


def get_surr_rows(row, endpoints, g):
    """return list (len=4) of the rows surrounding the current one on all sides
    IF the surrounding row is within the bounds of the grid."""
    y, z = row
    surr = []
    if y >= 1:
        surr.append(((y - 1, z), endpoints))
    if z >= 1:
        surr.append(((y, z - 1), endpoints))
    if g['ylo'] + (y + 1) * g['dy'] < g['yhi']:
        surr.append(((y + 1, z), endpoints))
    if g['zlo'] + (z + 1) * g['dz'] < g['zhi']:
        surr.append(((y, z + 1), endpoints))
    return surr


def extract_package_name(line):
    """Return package name in import statement."""
    assert '\\' not in line
    assert '(' not in line
    assert ')' not in line
    assert ';' not in line
    if line.lstrip().startswith(('import', 'from')):
        word = line.split()[1]
    else:
        return None
    package = word.split('.')[0]
    assert ' ' not in package
    return package


def last_char_to_vowel(word):
    """Intended for abbreviations, returns the vowel for illative etc based
    on how the last character is pronounced in Finnish."""
    assert isinstance(word, str)
    for last in reversed(word):
        last = last.lower()
        for ch, prev in (('e', 'eébcçdgptvwz'), ('o', 'ohk'), ('ä',
            'äflmnrsx'), ('i', 'ij'), ('u', 'uq'), ('y', 'yü')):
            if last in prev:
                return ch
    return 'e'


@classmethod
def add_options(cls, parser):
    """Add --author-re, --copyright-re, and --license-re options."""
    parser.add_option('--author-re', help=
        'regular expression(s) for valid :author: lines', parse_from_config
        =True)
    parser.add_option('--copyright-re', help=
        'regular expression(s) for valid :copyright: lines',
        parse_from_config=True)
    parser.add_option('--license-re', help=
        'regular expression(s) for valid :license: lines',
        parse_from_config=True)


def listAllowedVocabulary(schema, element, content=None, content_type=None):
    """ List allowed values for a given schema element and content object.

        o List possible keywords if both 'content' and 'content_type' are None.
        """


def env_partition(st, env):
    """Similar to str.partition, but rather than using a given separator,
    it partition the string across some LaTeX environment.

    >>> tex = r'''some text
    ... \\begin{foo}
    ...   foo env
    ... \\end{foo}
    ... ham!'''
    >>> pre, env, post = env_partition(tex, 'foo')
    >>> print(env)
    \\begin{foo}
      foo env
    \\end{foo}
    >>> pre + post
    'some text\\n\\nham!'
    """
    pre, begin, post = st.partition('\\begin{%s}' % env)
    envdata, end, post = post.partition('\\end{%s}' % env)
    return pre, begin + envdata + end, post


def get_corrected_measurement_id(args, n):
    """ Correct the provided measurement id, in case of multiple cloud-free periods. """
    if args.measurement_id is not None:
        order = int(args.measurement_id[-2:])
        new_no = order + n
        measurement_id = args.measurement_id[:-2] + str(new_no)
        measurement_no = args.measurement_number
    else:
        measurement_no = str(int(args.measurement_number) + n).zfill(2)
        measurement_id = None
    return measurement_id, measurement_no


def add_arg(f, *args, **kwargs):
    """Bind CLI arguments to a shell.py `do_foo` function."""
    if not hasattr(f, 'arguments'):
        f.arguments = []
    if (args, kwargs) not in f.arguments:
        f.arguments.insert(0, (args, kwargs))


def ImageCompress(image, scale):
    """ Reduces size of image by selecting every n'th point
    param: image array: original image
    param: scale int: intervsl between selected points
    returns: array: reduced size image
    """
    if scale == 1:
        return image
    else:
        return image[::scale, ::scale]


def add(principal_ids):
    """Share this lock with principal_ids.

        Adding principals that already are part of the lock can be ignored.

        If ended, raise EndedError.
        """


def extract_array(indices_center, halfsizes, inputarray2D):
    """
    extract a 2D slice array from inputarray2D

    aa= array([[ 0,  1,  2,  3,  4,  5,  6],
       [ 7,  8,  9, 10, 11, 12, 13],
       [14, 15, 16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25, 26, 27],
       [28, 29, 30, 31, 32, 33, 34],
       [35, 36, 37, 38, 39, 40, 41],
       [42, 43, 44, 45, 46, 47, 48],
       [49, 50, 51, 52, 53, 54, 55]])

    extract_array((3,4),(2,1),aa)

    array([[10, 11, 12],
       [17, 18, 19],
       [24, 25, 26],
       [31, 32, 33],
       [38, 39, 40]])
    """
    slowindex_center, fastindex_center = indices_center
    slowindex_halfsize, fastindex_halfsize = halfsizes
    nslow, nfast = inputarray2D.shape
    imax = min(slowindex_center + slowindex_halfsize, nslow - 1)[0]
    imin = max(slowindex_center - slowindex_halfsize, 0)[0]
    jmax = min(fastindex_center + fastindex_halfsize, nfast - 1)[0]
    jmin = max(fastindex_center - fastindex_halfsize, 0)[0]
    print('imin:imax + 1, jmin:jmax + 1', imin, imax + 1, jmin, jmax + 1)
    return inputarray2D[imin:imax + 1, jmin:jmax + 1]


def manhattan_distance(xy1, xy2):
    """"Returns the Manhattan distance between points xy1 and xy2 in R^2"""
    return abs(xy1[0] - xy2[0]) + abs(xy1[1] - xy2[1])


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

        :param GuestAdminChangeStatusDetails val:
        :rtype: EventDetails
        """
    return cls('guest_admin_change_status_details', val)