@classmethod
def values(cls):
    """Return a list of values that the enumeration can take."""
    return list(cls.itervalues())


def arccos(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise inverse cosine of the input array.

    The input should be in range `[-1, 1]`.
    The output is in the closed interval :math:`[0, \\pi]`

    .. math::
       arccos([-1, -.707, 0, .707, 1]) = [\\pi, 3\\pi/4, \\pi/2, \\pi/4, 0]

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

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

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

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

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


def stat_ahead_behind(git, local_ref, remote_ref):
    """
    Returns a tuple (ahead, behind) describing how far
    from the remote ref the local ref is.
    """
    behind = 0
    ahead = 0
    ret, out = git.call('rev-list', '--left-right', '%s..%s' % (remote_ref,
        local_ref), raises=False)
    if ret == 0:
        ahead = len(out.split())
    ret, out = git.call('rev-list', '--left-right', '%s..%s' % (local_ref,
        remote_ref), raises=False)
    if ret == 0:
        behind = len(out.split())
    return ahead, behind


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


def _get_import_path():
    """Get import path configured for the given Python interpreter."""
    import json
    import sys
    json.dump({'path': sys.path}, sys.stdout)
    sys.exit(0)


def transforms_clear():
    """Reset location, rotation, and scaling of selected bones to their default values

    """
    pass


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


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


def height_from_foot_width(segment_length):
    """
    Calculates body height based on the foot breadth

    args:
        segment_length (float): breadth of the foot

    Returns:
        float: total body height
    """
    if segment_length <= 0:
        raise ValueError('segment_length must be > 0')
    return segment_length / 0.055


def get_domain_ip(domain):
    """
    Get the IP for the domain.  Any IP that responded is good enough.
    """
    if domain.canonical.ip is not None:
        return domain.canonical.ip
    if domain.https.ip is not None:
        return domain.https.ip
    if domain.httpswww.ip is not None:
        return domain.httpswww.ip
    if domain.httpwww.ip is not None:
        return domain.httpwww.ip
    if domain.http.ip is not None:
        return domain.http.ip
    return None


def new_edge_weight(vertex, line):
    """
    Compute the weight of the splitted edge of geometry *line* and original
    vertex row *vertex*.

    Parameters
    ----------
    vertex: Series
        Row of the dataframe *vertices*.
    line: LineString
        One of the two geometries of the splitted edge.

    Returns
    -------
    float
        Weight of the new vertex.
    """
    return vertex['weight'] * line.length / vertex['geometry'].length


def create_path_return_clause(path_style='list', return_property='name'):
    """
    Create a Cypher query clause to return paths. If path_style is 'list' or 'string',
    then the return_property is extracted for each node along the path. If path_style
    is 'id_lists', then two lists (node_ids and rel_ids) are returned of neo4j databse ids.
    As formatting the output as a string is less efficient in terms of database
    hits, 'list' is the default style.

    Parameters
    ----------
    path_style : str
        the way the user wants the path returned. Currently supported options
        are 'list', 'string', and 'id_lists'
    return_property : str
        which node property to use to describe the path
    """
    if path_style == 'string':
        return (
            "substring(reduce(s = '', node IN nodes(path)| s + '–' + node.{property}), 1) AS path,"
            .format(property=return_property))
    elif path_style == 'list':
        return '[node in nodes(path) | node.{property}] AS path,'.format(
            property=return_property)
    elif path_style == 'id_lists':
        return """[node IN nodes(path) | id(node)] AS node_ids,
[rel IN relationships(path) | id(rel)] AS rel_ids,"""
    else:
        err_string = (
            "{style} is not a style currently implemented by create_path_return_clause. Valid styles are 'list', 'string', and 'id_lists'."
            .format(style=path_style))
        raise ValueError(err_string)


@classmethod
def fromkeys(cls, iterable, value=None):
    """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
        and values equal to v (which defaults to None).

        """
    d = cls()
    for key in iterable:
        d[key] = value
    return d


def portrait(pagesize):
    """
	Returns the given pagesize in portrait orientation

	:param pagesize:
	:type pagesize:

	:return:
	:rtype:
	"""
    a, b = pagesize
    if a >= b:
        return b, a
    else:
        return a, b


def arrow_out(value):
    """Convert an Arrow object to timestamp.

    :param Arrow value: The Arrow time or ``None``.
    :returns int: The timestamp, or ``None`` if the input is ``None``.
    """
    return value.timestamp if value else None


def get_slices_and_placeholder_nones(data_array, out_dims, direction_to_names):
    """
    Takes in a DataArray, a desired ordering of output directions, and
    a dictionary mapping those directions to a list of names corresponding to
    those directions. Returns a list with the same ordering as out_dims that
    contains slices for out_dims that have corresponding names (as many slices
    as names, and spanning the entire dimension named), and None for out_dims
    without corresponding names.

    This returned list can be used to create length-1 axes for the dimensions
    that currently have no corresponding names in data_array.
    """
    slices_or_none = []
    for direction in out_dims:
        if len(direction_to_names[direction]) == 0:
            slices_or_none.append(None)
        elif direction is not '*' and len(direction_to_names[direction]) > 1:
            raise ValueError(
                'DataArray has multiple dimensions for a single direction')
        else:
            for name in direction_to_names[direction]:
                slices_or_none.append(slice(0, len(data_array.coords[name])))
    return slices_or_none


def failure_message_from_response(response):
    """
    Given EMR response, returns a descriptive error message
    """
    fail_details = response['Step']['Status'].get('FailureDetails')
    if fail_details:
        return 'for reason {} with message {} and log file {}'.format(
            fail_details.get('Reason'), fail_details.get('Message'),
            fail_details.get('LogFile'))


@staticmethod
def ema(x, mu=None, alpha=0.3):
    """
        Exponential moving average: smoothing to give progressively lower
        weights to older values.

        Parameters
        ----------
        x  : float
            New value to include in EMA.
        mu  : float, optional
            Previous EMA value.
        alpha  : float, optional
            Smoothing factor in range [0, 1], [default: 0.3].
            Increase to give more weight to recent values.
            Ranges from 0 (yields mu) to 1 (yields x).
        """
    return x if mu is None else alpha * x + (1 - alpha) * mu


@classmethod
def from_xml_node(cls, xml_node):
    """
        Initialize the object from a XML node.
        :param xml_node: The XML node from which all necessary parameters will be parsed.
        :type xml_node: xml.etree.Element
        """
    raise NotImplementedError(
        'from_xml_node must be implemented by derived classes.')


def form_ext(form):
    """
    This will insert a form, in a bit more sophisticated way than {{ form }}.

    Required and optional fields are displayed differently. For details,
    see template file *goflow/apptools/edit_form.html*.

    parameter:

    form
        form variable

    Usage::

        {% form_ext form %}

    the current implementation is equivalent to::

        {% include "goflow/apptools/edit_form.html" %}
    """
    return {'form': form}


def dequote(s):
    """
    If a string has single or double quotes around it, remove them.
    Make sure the pair of quotes match.
    If a matching pair of quotes is not found, return the string unchanged.
    """
    if s[0] == s[-1] and s.startswith(("'", '"')):
        return s[1:-1]
    return s


def truncate(text, maxlen=128, suffix='...'):
    """Truncates text to a maximum number of characters."""
    if len(text) >= maxlen:
        return text[:maxlen].rsplit(' ', 1)[0] + suffix
    return text


def formula(foyer_fiscal, period, parameters):
    """
        Réductions pour personnes à charges
        """
    nb_pac = foyer_fiscal('nb_pac', period)
    nbH = foyer_fiscal('nbH', period)
    P = parameters(period).taxation_capital.isf_ifi.reduc_pac
    return P.reduc_enf_garde * nb_pac + P.reduc_enf_garde / 2 * nbH


@classmethod
def from_httplib(cls, message):
    """Read headers from a Python 2 httplib message object."""
    headers = []
    for line in message.headers:
        if line.startswith((' ', '\t')):
            key, value = headers[-1]
            headers[-1] = key, value + '\r\n' + line.rstrip()
            continue
        key, value = line.split(':', 1)
        headers.append((key, value.strip()))
    return cls(headers)


def yes_no_prompt(prompt):
    """Asks a yes/no question, and returns a boolean response."""
    selection = input('{} [y/n]: '.format(prompt))
    return bool(selection.lower() == 'y')


def paes_replacement(random, population, parents, offspring, args):
    """Replaces population using the Pareto Archived Evolution Strategy method.

    .. Arguments:
       random -- the random number generator object
       population -- the population of individuals
       parents -- the list of parent individuals
       offspring -- the list of offspring individuals
       args -- a dictionary of keyword arguments

    """
    archive = args['_ec'].archive
    archiver = args['_ec'].archiver
    survivors = []
    for p, o in zip(parents, offspring):
        if o == p:
            survivors.append(p)
        elif o in archive:
            survivors.append(p)
        elif o > p:
            archive = archiver(random, [o], archive, args)
            survivors.append(o)
        elif o >= p:
            for a in archive:
                if o > a or o < a:
                    break
            if o >= a:
                archive = archiver(random, [o], archive, args)
                if o > a or archiver.grid_population[o.grid_location
                    ] <= archiver.grid_population[p.grid_location]:
                    survivors.append(o)
                else:
                    survivors.append(p)
            else:
                survivors.append(p)
        else:
            survivors.append(p)
    return survivors


def date_to_str(value, fmt='%Y-%m-%d'):
    """ 日期类型转换为字符串。date to string.

    :type value: datetime.date
    :type fmt: str
    :rtype: str
    """
    return value.strftime(fmt)


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


def _get_ex_msg(obj):
    """ Get exception message """
    return obj.value.message if hasattr(obj, 'value') else obj.message


def editmode_toggle():
    """Enter/Exit edit mode for Grease Pencil strokes

    """
    pass


def _parse_link_header(headers):
    """Parses Github's link header for pagination.

    TODO eventually use a github client for this
    """
    links = {}
    if 'link' in headers:
        link_headers = headers['link'].split(', ')
        for link_header in link_headers:
            url, rel = link_header.split('; ')
            url = url[1:-1]
            rel = rel[5:-1]
            links[rel] = url
    return links


def intersect_point_tri_2d(pt: 'mathutils.Vector', tri_p1:
    'mathutils.Vector', tri_p2: 'mathutils.Vector', tri_p3: 'mathutils.Vector'
    ) ->int:
    """Takes 4 vectors (using only the x and y coordinates): one is the point and the next 3 define the triangle. Returns 1 if the point is within the triangle, otherwise 0.

    :param pt: Point
    :type pt: 'mathutils.Vector'
    :param tri_p1: First point of the triangle
    :type tri_p1: 'mathutils.Vector'
    :param tri_p2: Second point of the triangle
    :type tri_p2: 'mathutils.Vector'
    :param tri_p3: Third point of the triangle
    :type tri_p3: 'mathutils.Vector'
    """
    pass


def zero_mul_simp(l, index):
    """Used to combine two reduced words."""
    while index >= 0 and index < len(l) - 1 and l[index][0] == l[index + 1][0]:
        exp = l[index][1] + l[index + 1][1]
        base = l[index][0]
        l[index] = base, exp
        del l[index + 1]
        if l[index][1] == 0:
            del l[index]
            index -= 1


def kaiser_beta(a):
    """Compute the Kaiser parameter `beta`, given the attenuation `a`.

    Parameters
    ----------
    a : float
        The desired attenuation in the stopband and maximum ripple in
        the passband, in dB.  This should be a *positive* number.

    Returns
    -------
    beta : float
        The `beta` parameter to be used in the formula for a Kaiser window.

    References
    ----------
    Oppenheim, Schafer, "Discrete-Time Signal Processing", p.475-476.

    Examples
    --------
    Suppose we want to design a lowpass filter, with 65 dB attenuation
    in the stop band.  The Kaiser window parameter to be used in the
    window method is computed by `kaiser_beta(65)`:

    >>> from scipy.signal import kaiser_beta
    >>> kaiser_beta(65)
    6.20426

    """
    if a > 50:
        beta = 0.1102 * (a - 8.7)
    elif a > 21:
        beta = 0.5842 * (a - 21) ** 0.4 + 0.07886 * (a - 21)
    else:
        beta = 0.0
    return beta


def no_log_warn(logical_line):
    """Disallow 'LOG.warn('

    """
    if logical_line.startswith('LOG.warn('):
        yield 0, 'P301 Use LOG.warning() rather than LOG.warn()'


def write_data_list(list, filename, encoding):
    """리스트 데이터를 위한 쓰기 함수"""
    with open(filename, 'w', encoding=encoding) as f:
        for item in list:
            if len(item) == 1:
                f.write('%s\n' % item[0])
            elif len(item) == 2:
                f.write('%s\t%s\n' % (item[0], item[1]))
            elif len(item) == 3:
                f.write('%s\t%s\t%s\n' % (item[0], item[1], item[2]))
            elif len(item) == 4:
                f.write('%s\t%s\t%s\t%s\n' % (item[0], item[1], item[2],
                    item[3]))
            elif len(item) == 5:
                f.write('%s\t%s\t%s\t%s\t%s\n' % (item[0], item[1], item[2],
                    item[3], item[4]))
            elif len(item) == 6:
                f.write('%s\t%s\t%s\t%s\t%s\t%s\n' % (item[0], item[1],
                    item[2], item[3], item[4], item[5]))
            elif len(item) == 7:
                f.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (item[0], item[1],
                    item[2], item[3], item[4], item[5], item[6]))
            elif len(item) == 8:
                f.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (item[0], item
                    [1], item[2], item[3], item[4], item[5], item[6], item[7]))
            else:
                print('Error in write_data_list!!')
                print(len(item))


def _load_namedtuple(name, fields):
    """
    Loads a class generated by namedtuple
    """
    from collections import namedtuple
    return namedtuple(name, fields)


@classmethod
def where(cls, **filters):
    """
        Shortcut for smart_query() method
        Example 1:
          Product.where(subject_ids__in=[1,2], grade_from_id=2).all()

        Example 2:
          filters = {'subject_ids__in': [1,2], 'grade_from_id': 2}
          Product.where(**filters).all()

        Example 3 (with joins):
          Post.where(public=True, user___name__startswith='Bi').all()
        """
    return cls.smart_query(filters)


def bytes2human(n, format='%(value).1f%(symbol)s'):
    """Used by various scripts. See:
    http://goo.gl/zeJZl

    >>> bytes2human(10000)
    '9.8K'
    >>> bytes2human(100001221)
    '95.4M'
    """
    symbols = 'B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
    prefix = {}
    for i, s in enumerate(symbols[1:]):
        prefix[s] = 1 << (i + 1) * 10
    for symbol in reversed(symbols[1:]):
        if n >= prefix[symbol]:
            value = float(n) / prefix[symbol]
            return format % locals()
    return format % dict(symbol=symbols[0], value=n)


def zero_variance_flagger_and_cutter(df, useful_cols, cutter=True):
    """
    Function flags features with only one value (zero variance), and, if specified, culls these from the input dataframe (inplace)

    Parameters
    ----------
    df : pandas.DataFrame
        Desired features
    useful_cols : pandas.DataFrame
        Lookup table detailing desired features
    cutter : bool
        If true [default], df is modified to remove features with only one value

    Returns
    -------
    zero_variance_features : list
        List of features with zero variance
    useful_cols : pandas.DataFrame
        Returned unchanged if `cutter` == False, else the clipped features are removed
    """
    zero_variance_features = []
    for feature_name, feature in df.iteritems():
        if len(feature.value_counts()) == 1:
            zero_variance_features.append(feature_name)
    if cutter == True:
        print(
            f'Following features dropped for having zero variance: {zero_variance_features}'
            )
        df.drop(zero_variance_features, axis=1, inplace=True)
        useful_cols = useful_cols.loc[(~useful_cols.feature.isin(
            zero_variance_features)), :]
    return zero_variance_features, useful_cols


def populate():
    """Populate the styles from the configuration files.

        This clears the current set of styles and resets them from those
        defined in the configuration files.
        """


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 close():
    """Close an open file handle."""


@classmethod
def from_lsc(cls, data):
    """Parse text .lsc data into an object."""
    raise NotImplementedError


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

        :param DeviceUnlinkType val:
        :rtype: EventType
        """
    return cls('device_unlink', val)


def NewName(BaseName, NameList, ForceID=True):
    """
	Return a Name that is unique to the list, based on the pattern Base-Name + number
	"""
    NameList = list(NameList)
    NB = 0
    if NameList.count(BaseName) > 0 or ForceID == True:
        while NameList.count('{0}_{1}'.format(BaseName, NB)):
            NB += 1
        NameList.append('{0}_{1}'.format(BaseName, NB))
        return '{0}_{1}'.format(BaseName, NB)
    else:
        NameList.append(BaseName)
        return BaseName


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 pytest_benchmark_update_machine_info(config, machine_info):
    """
    If benchmarks are compared and machine_info is different then warnings will be shown.

    To add the current user to the commit info override the hook in your conftest.py like this:

    .. sourcecode:: python

        def pytest_benchmark_update_machine_info(config, machine_info):
            machine_info['user'] = getpass.getuser()
    """
    pass


def face_join(faces: 'bmesh.types.BMFace', remove: bool=True
    ) ->'bmesh.types.BMFace':
    """Joins a sequence of faces.

    :param faces: Sequence of faces.
    :type faces: 'bmesh.types.BMFace'
    :param remove: Remove the edges and vertices between the faces.
    :type remove: bool
    :return:  The newly created face or None on failure.
    """
    pass


@classmethod
def block_header(cls, block, height):
    """Return the AuxPow block header bytes"""
    deserializer = cls.DESERIALIZER(block)
    return deserializer.read_header(cls.BASIC_HEADER_SIZE)


@classmethod
def phi(cls, *baloon):
    """
        Return the angle of the piece of cake.
        b/l=R*phi/(R*Sin(phi)) -> Phi=arsinc(l/b)
        """
    return cls.arcsinc(baloon)


def _show_consistency(field, message, is_consistent):
    """
    If `is_consistent` is false,
    make `field` RED with tooltip caption `message`.
    Otherwise reset colour and tooltip caption of `field` to default values.
    """
    if is_consistent is True:
        field.setStyleSheet('')
        field.setToolTip('')
    else:
        field.setStyleSheet('QLineEdit { background-color : red;}')
        field.setToolTip(message)


def get_input(prompt, type, error_string, check_list=[], default='', **kwds):
    """
    Return user input after validating it.
    """
    input_validated = False
    if type == 'float':
        while not input_validated:
            input_data = eval(input(prompt))
            try:
                input_data = float(input_data)
                input_validated = True
            except ValueError:
                print(error_string)
    if type == 'float+':
        input_data = eval(input(prompt))
        try:
            input_data = float(input_data)
            if input_data < 0:
                print(error_string)
            else:
                input_validated = True
        except ValueError:
            print(error_string)
    elif type == 'float_or_blank':
        while not input_validated:
            input_data = eval(input(prompt))
            if input_data == '':
                input_data = default
                input_validated = True
            else:
                try:
                    input_data = float(input_data)
                    input_validated = True
                except ValueError:
                    print(error_string)
    elif type == 'float_str_or_blank':
        while not input_validated:
            input_data = eval(input(prompt))
            if input_data == '':
                input_data = default
                input_validated = True
            elif input_data in kwds['str_list']:
                input_validated = True
            else:
                try:
                    input_data = float(input_data)
                    input_validated = True
                except ValueError:
                    print(error_string)
    elif type == 'float+_or_blank':
        while not input_validated:
            input_data = eval(input(prompt))
            if input_data == '':
                input_data = default
                input_validated = True
                return input_data
            try:
                input_data = float(input_data)
                if input_data < 0:
                    print(error_string)
                else:
                    input_validated = True
            except ValueError:
                print(error_string)
    if type == 'int':
        while 1:
            input_data = eval(input(prompt))
            try:
                input_data = int(input_data)
                break
            except ValueError:
                print(error_string)
    if type == 'int_or_str':
        while 1:
            input_data = eval(input(prompt))
            if input_data in kwds['str_list']:
                break
            try:
                input_data = int(input_data)
                try:
                    if input_data < kwds['min']:
                        print(('You must enter an integer no less than',
                            kwds['min']))
                except KeyError:
                    pass
                try:
                    if input_data > kwds['max']:
                        print(('You must enter an integer less than', kwds[
                            'max']))
                except KeyError:
                    break
            except ValueError:
                print('You must enter an integer')
    elif type == 'list':
        while not input_validated:
            input_data = eval(input(prompt))
            if input_data == '':
                input_data = default
                input_validated = True
                return default
            if input_data in check_list:
                input_validated = True
            else:
                print(error_string)
    return input_data


def shortify(s, length=50):
    """
    Returns a shortified version of s
    """
    return '…' + s[-(length - 1):] if len(s) > length else s


def is_data_dependent(fmto, data):
    """Check whether a formatoption is data dependent

    Parameters
    ----------
    fmto: Formatoption
        The :class:`Formatoption` instance to check
    data: xarray.DataArray
        The data array to use if the :attr:`~Formatoption.data_dependent`
        attribute is a callable

    Returns
    -------
    bool
        True, if the formatoption depends on the data"""
    if callable(fmto.data_dependent):
        return fmto.data_dependent(data)
    return fmto.data_dependent


def read_all(*files):
    """Read file(s) and return the content

    Args:
        files (str): variable number of file names
    Returns:
        combined content as a string
    """
    output = []
    for f in files:
        with open(f, 'r') as IN:
            output.append(IN.read())
    return '\n'.join(output)


def cloneQuery(limit):
    """
        Create a similar-but-not-identical copy of this query with certain
        attributes changed.

        (Currently this only supports the manipulation of the "limit"
        parameter, but it is the intent that with a richer query-introspection
        interface, this signature could be expanded to support many different
        attributes.)

        @param limit: an integer, representing the maximum number of rows that
        this query should return.

        @return: an L{IQuery} provider with the new limit.
        """


@classmethod
def table_cell_with_text(cls, text):
    """Returns an XPath to find an HTML <tr> that contains a <td> / cell with text matching the text in `text`"""
    return cls('//tr/td[normalize-space(node())="%s"]' % text)


def select(b, t, f):
    """
    tf.where equivalent but use broadcasting
    :param b:
    :param t:
    :param f:
    :return:
    """
    b = b.to_float()
    value = b * t + (1.0 - b) * f
    return value


def set_quiet(is_quiet):
    """Sets whether the messaging system is running in quiet mode. Quiet mode
    only prints messages with explicit verbosity specified. If verbosity==None
    and quiet==True, any message with level >= 0 is printed.
    """
    global quiet
    quiet = is_quiet


@classmethod
def check_config(cls, cfg):
    """Check the consistency of a mapping object. """
    return cfg


def zoom(delta: int=0, mx: int=0, my: int=0):
    """Zoom in/out in the view

    :param delta: Delta
    :type delta: int
    :param mx: Zoom Position X
    :type mx: int
    :param my: Zoom Position Y
    :type my: int
    """
    pass


@staticmethod
def op(value, comparable):
    """Return whether `value` is contained in `comparable`."""
    try:
        return value in comparable
    except (TypeError, ValueError):
        return False


@classmethod
def name(cls):
    """Returns name of class"""
    return cls.NAME


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

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


def get_tokens(line):
    """
    Goes through each charachter in scrumpy file attempting to find tokens

    FIXME: if there is a numeric after a direction token this fails
    e.g. '->2 "PROTON"' fails but '-> 2 "PROTON"' works
    :param line_dt:
    :return:
    """
    line_dt = line.strip().split('#')[0]
    tokens = []
    quoted = False
    tk_str = ''
    line_dt = line_dt.replace('->', '-> ')
    line_dt = line_dt.replace('<-', '<- ')
    line_dt = line_dt.replace('<>', '<> ')
    for ch in line_dt:
        if ch in ['"', "'"]:
            if not quoted:
                quoted = True
                if len(tk_str) and ch != ' ':
                    tokens.append(tk_str)
                tk_str = ch
            elif tk_str[0] == ch:
                tk_str += ch
                tokens.append(tk_str)
                tk_str = ''
                quoted = False
            else:
                tk_str += ch
        elif ch in ['(', ')', ':', ',', ' '] and not quoted:
            if len(tk_str):
                tokens.append(tk_str)
            tk_str = ''
            if ch != ' ':
                tokens.append(ch)
        else:
            tk_str += ch
    if len(tk_str):
        tokens.append(tk_str)
    return tokens


@classmethod
def _transfer_coin(cls, context: 'IconScoreContext', params: dict) ->None:
    """Transfer coin between EOA and EOA based on protocol v2
        JSON-RPC syntax validation has already been complete

        :param context:
        :param params:
        :return:
        """
    from_: 'Address' = params['from']
    to: 'Address' = params['to']
    value: int = params.get('value', 0)
    context.engine.icx.transfer(context, from_, to, value)


def get_function_arguments(func):
    """Get arguments of function.

    :param func: function to parse arguments
    :return: list of arguments that predicate function expects
    """
    return list(func.__code__.co_varnames[:func.__code__.co_argcount])


@classmethod
def get_latest_tasks(cls, flow_name, run_id=None, steps=None, pathspecs=None):
    """
        Return a list of (step, task, attempt, metadata_blob) for a subset of
        the tasks (consider eventual consistency) for which the latest attempt
        is done for the input `flow_name, run_id`.
        We filter the list based on `steps` if non-None.
        Alternatively, `pathspecs` can contain the exact list of pathspec(s)
        (run_id/step_name/task_id) that should be filtered.
        Note: When `pathspecs` is specified, we expect strict consistency and
        not eventual consistency in contrast to other modes.
        """
    raise NotImplementedError()


@classmethod
def make_from_service_response(cls, resp, is_rest: bool=False) ->'Response':
    """
        Build resource from soap-service response
        :param resp:        service soap/rest response
        :param is_rest:     indicate rest request
        """
    code = None
    status = False
    message = None
    more_results = False
    request_id = None
    results = []
    if resp is None:
        return cls()
    if is_rest:
        code = resp.status_code
        status = True if code == 200 else False
        results = resp.json()
    else:
        code = resp[0]
        body = resp[1]
        if body and 'RequestID' in body:
            request_id = body['RequestID']
        if code == 200:
            status = True
            if 'OverallStatus' in body:
                message = body['OverallStatus']
                if body['OverallStatus'] == 'MoreDataAvailable':
                    more_results = True
                elif body['OverallStatus'] != 'OK':
                    status = False
            body_container_tag = None
            if 'Results' in body:
                body_container_tag = 'Results'
            elif 'ObjectDefinition' in body:
                body_container_tag = 'ObjectDefinition'
            if body_container_tag is not None:
                results = body[body_container_tag]
    inst = cls()
    inst.raw_response = resp
    inst.code = code
    inst.status = status
    inst.message = message
    inst.more_results = more_results
    inst.request_id = request_id
    inst.results = results
    inst.valid_response = True
    return inst


def remove_var_with_one_value(df):
    """
    Removes dataset's columns that only contain one unique value.

    Parameters
    ----------
    df: pd.DataFrame
        Dataframe to inspect

    Returns
    -------
    pd.DataFrame:
        Dataframe without columns with only one unique value
    """
    if len(df) <= 1:
        return df
    drop_cols = list()
    for var in df:
        if df[var].nunique() <= 1:
            drop_cols.append(var)
    return df.drop(columns=drop_cols)


def days_hours_minutes_seconds(value):
    """
    Returns a timedelta as days, hours, minutes, seconds
    """
    minutes, seconds = divmod(value.total_seconds(), 60)
    hours, minutes = divmod(minutes, 60)
    days, hours = divmod(hours, 24)
    return int(days), int(hours), int(minutes), int(seconds)


def quote(value):
    """Quote a string value."""
    res = ['"']
    for char in value:
        if char == '"':
            res.append('\\')
        res.append(char)
    res.append('"')
    return ''.join(res)


def prod_gc_skew(genes_dictionary, positions, window_size, sequence_length,
    sequence):
    """
    Produces a list of gc-skew and ta-skew values.

    :param genes_dictionary:    Dictionary with all genes from Prodigal
    :param positions:           Dictionary for positions in whole genome, in all_genes and in third_pos
    :param window_size:         Size of window for calculation
    :param sequence_length:     Length of chromosome
    :param sequence:            FASTA sequence of chromosome
    :return:                    Lists with gc- and ta-skews
    """
    ev_third = ['u'] * sequence_length
    rev = list(sequence.seq)
    gc_skew_list = [0.0] * sequence_length
    ta_skew_list = [0.0] * sequence_length
    for key in genes_dictionary:
        """If plus strand gene -- save every third nt to list"""
        if positions[key][3] == 1:
            for i in range(positions[key][0] + 2, positions[key][1], 3):
                ev_third[i] = sequence.seq[i - 1]
        """If minus strand gene -- reverse list and save every third nt"""
        if positions[key][3] == -1:
            rev[positions[key][0]:positions[key][1] + 1] = list(
                genes_dictionary[key].seq)
            for i in range(positions[key][0] + 2, positions[key][1], 3):
                ev_third[i] = rev[i]
        """Calculate the number of each nt per window for every 10th nt in the list"""
        for i in range(positions[key][0], positions[key][1] + 1, 10):
            if i - window_size // 2 < 0:
                rest = abs(i - window_size // 2)
                a = ev_third[sequence_length - 1 - rest:i + window_size // 2
                    ].count('A') + ev_third[sequence_length - 1 - rest:i +
                    window_size // 2].count('a') + ev_third[0:i +
                    window_size // 2].count('A') + ev_third[0:i +
                    window_size // 2].count('a')
                c = ev_third[sequence_length - 1 - rest:i + window_size // 2
                    ].count('C') + ev_third[sequence_length - 1 - rest:i +
                    window_size // 2].count('c') + ev_third[0:i +
                    window_size // 2].count('C') + ev_third[0:i +
                    window_size // 2].count('c')
                g = ev_third[sequence_length - 1 - rest:i + window_size // 2
                    ].count('G') + ev_third[sequence_length - 1 - rest:i +
                    window_size // 2].count('g') + ev_third[0:i +
                    window_size // 2].count('G') + ev_third[0:i +
                    window_size // 2].count('g')
                t = ev_third[sequence_length - 1 - rest:i + window_size // 2
                    ].count('T') + ev_third[sequence_length - 1 - rest:i +
                    window_size // 2].count('t') + ev_third[0:i +
                    window_size // 2].count('T') + ev_third[0:i +
                    window_size // 2].count('t')
            elif i + window_size // 2 > sequence_length - 1:
                rest = abs(sequence_length - window_size // 2)
                a = ev_third[i - window_size // 2:sequence_length - 1].count(
                    'A') + ev_third[i - window_size // 2:sequence_length - 1
                    ].count('a') + ev_third[0:rest].count('A') + ev_third[0
                    :rest].count('a')
                c = ev_third[i - window_size // 2:sequence_length - 1].count(
                    'C') + ev_third[i - window_size // 2:sequence_length - 1
                    ].count('c') + ev_third[0:rest].count('C') + ev_third[0
                    :rest].count('c')
                g = ev_third[i - window_size // 2:sequence_length - 1].count(
                    'G') + ev_third[i - window_size // 2:sequence_length - 1
                    ].count('g') + ev_third[0:rest].count('G') + ev_third[0
                    :rest].count('g')
                t = ev_third[i - window_size // 2:sequence_length - 1].count(
                    'T') + ev_third[i - window_size // 2:sequence_length - 1
                    ].count('t') + ev_third[0:rest].count('T') + ev_third[0
                    :rest].count('t')
            else:
                a = ev_third[i - window_size // 2:i + window_size // 2].count(
                    'A') + ev_third[i - window_size // 2:i + window_size // 2
                    ].count('a')
                c = ev_third[i - window_size // 2:i + window_size // 2].count(
                    'C') + ev_third[i - window_size // 2:i + window_size // 2
                    ].count('c')
                g = ev_third[i - window_size // 2:i + window_size // 2].count(
                    'G') + ev_third[i - window_size // 2:i + window_size // 2
                    ].count('g')
                t = ev_third[i - window_size // 2:i + window_size // 2].count(
                    'T') + ev_third[i - window_size // 2:i + window_size // 2
                    ].count('t')
            """If not division with zero -- calculate gc- and ta-skew and save to lists"""
            if g + c != 0.0:
                gc_skew_list[i] = positions[key][3] * ((g - c) / (g + c))
            if t + a != 0.0:
                ta_skew_list[i] = positions[key][3] * ((t - a) / (t + a))
    return gc_skew_list, ta_skew_list


def package_root(varmap):
    """Return correct directory for the root package.

    The "root" package is the one where modules which do not
    belong to a package are located (see the distutils docs).
    This function should not need to be called directly in
    your actual setup script, but it can be useful for testing.
    Note that it looks for a ``package_root`` setup var, which
    can be used as a shortcut if your "root" package is not in
    the standard place (which is your setup script directory),
    rather than having to declare a ``package_dir`` dictionary
    with a ``''`` key.
    """
    try:
        return varmap['package_dir']['']
    except KeyError:
        try:
            result = varmap['package_root']
        except KeyError:
            return '.'
        else:
            dirmap = varmap.setdefault('package_dir', {})
            if '' not in dirmap:
                dirmap[''] = result
            return result


def boundary(value, minvalue, maxvalue):
    """Limit a value between a minvalue and maxvalue."""
    return min(max(value, minvalue), maxvalue)


def line(x0, y0, x1, y1, color=None, width=None):
    """Return a line shape

    args:
        x0, y0, x1, y1: beginning and end of line
        color (str): a plotly color string
        width (int): line width
    """
    data = {'type': 'line', 'x0': x0, 'y0': y0, 'x1': x1, 'y1': y1, 'line': {}}
    if color:
        data['line']['color'] = color
    if width:
        data['line']['width'] = width
    return data


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

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

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


def storeConvert(unic, escapeSpace=True, escapeUnicode=True):
    """
    Converts unicodes to encoded \\uxxxx and escapes
    special characters with a preceding slash

    Note: the return is unicode type if the input is.

    @param  unic            input string
    @param  escapeSpace     True for key, False for value (true is OK)
    @param  escapeUnicode   (boolean)
    @return                 processed string
    """
    outBuffer = []
    for x in range(len(unic)):
        aChar = unic[x]
        if ord(aChar) > 61 and ord(aChar) < 127:
            if aChar == '\\':
                outBuffer.append('\\\\')
                continue
            outBuffer.append(aChar)
            continue
        if aChar == ' ':
            if x == 0 or escapeSpace:
                outBuffer.append('\\')
            outBuffer.append(' ')
        elif aChar == '\t':
            outBuffer.append('\\t')
        elif aChar == '\n':
            outBuffer.append('\\n')
        elif aChar == '\r':
            outBuffer.append('\\r')
        elif aChar == '\x0c':
            outBuffer.append('\\f')
        elif aChar == '=' or aChar == ':' or aChar == '#' or aChar == '!':
            outBuffer.append('\\' + aChar)
        elif (ord(aChar) < 32 or ord(aChar) > 126) and escapeUnicode:
            outBuffer.append('\\u%04x' % ord(aChar))
        else:
            outBuffer.append(aChar)
    return ''.join(outBuffer)


def get_ordered_unique(items):
    """
    Generates a unique list of items in same order they were received in.

    Args:
        items (list): List of items.

    Returns:
        list: Unique ordered list.
    """
    output = []
    temp = set()
    for item in items:
        if item not in temp:
            output.append(item)
            temp.add(item)
    return output


def has_dupes(sequence, target):
    """Given a sequence and search object, return True if there's more
    than one, False if zero or one of them.

    """
    c = 0
    for item in sequence:
        if item is target:
            c += 1
            if c > 1:
                return True
    return False


def parse_fmt(fmt):
    """given a fmt block BitstreamReader (without the 8 byte header)
    returns (channels, sample_rate, bits_per_sample, channel_mask)
    where channel_mask is a ChannelMask object and the rest are ints
    may raise ValueError if the fmt chunk is invalid
    or IOError if an error occurs parsing the chunk"""
    from audiotools import ChannelMask
    (compression, channels, sample_rate, bytes_per_second, block_align,
        bits_per_sample) = fmt.parse('16u 16u 32u 32u 16u 16u')
    if compression == 1:
        if channels == 1:
            channel_mask = ChannelMask.from_fields(front_center=True)
        elif channels == 2:
            channel_mask = ChannelMask.from_fields(front_left=True,
                front_right=True)
        elif channels == 3:
            channel_mask = ChannelMask.from_fields(front_left=True,
                front_right=True, front_center=True)
        elif channels == 4:
            channel_mask = ChannelMask.from_fields(front_left=True,
                front_right=True, back_left=True, back_right=True)
        elif channels == 5:
            channel_mask = ChannelMask.from_fields(front_left=True,
                front_right=True, back_left=True, back_right=True,
                front_center=True)
        elif channels == 6:
            channel_mask = ChannelMask.from_fields(front_left=True,
                front_right=True, back_left=True, back_right=True,
                front_center=True, low_frequency=True)
        else:
            channel_mask = ChannelMask(0)
        return channels, sample_rate, bits_per_sample, channel_mask
    elif compression == 65534:
        cb_size, valid_bits_per_sample, channel_mask, sub_format = fmt.parse(
            '16u 16u 32u 16b')
        if (sub_format != b'\x01\x00\x00\x00\x00\x00\x10\x00' +
            b'\x80\x00\x00\xaa\x008\x9bq'):
            raise ValueError('invalid WAVE sub-format')
        else:
            channel_mask = ChannelMask(channel_mask)
            return channels, sample_rate, bits_per_sample, channel_mask
    else:
        raise ValueError('unsupported WAVE compression')


def is_ecma_regex(regex):
    """Check if given regex is of type ECMA 262 or not.

    :rtype: bool

    """
    parts = regex.split('/')
    if len(parts) == 1:
        return False
    if len(parts) < 3:
        raise ValueError("Given regex isn't ECMA regex nor Python regex.")
    parts.pop()
    parts.append('')
    raw_regex = '/'.join(parts)
    if raw_regex.startswith('/') and raw_regex.endswith('/'):
        return True
    return False


def longest_common_subsequence(x, y):
    """Longest common subsequence

    Dynamic programming

    :param x:
    :param y: x, y are lists or strings
    :returns: longest common subsequence in form of a string
    :complexity: `O(|x|*|y|)`
    """
    n = len(x)
    m = len(y)
    A = [[(0) for j in range(m + 1)] for i in range(n + 1)]
    for i in range(n):
        for j in range(m):
            if x[i] == y[j]:
                A[i + 1][j + 1] = A[i][j] + 1
            else:
                A[i + 1][j + 1] = max(A[i][j + 1], A[i + 1][j])
    sol = []
    i, j = n, m
    while A[i][j] > 0:
        if A[i][j] == A[i - 1][j]:
            i -= 1
        elif A[i][j] == A[i][j - 1]:
            j -= 1
        else:
            i -= 1
            j -= 1
            sol.append(x[i])
    return ''.join(sol[::-1])


def update_size_constraint_set(SizeConstraintSetId=None, ChangeToken=None,
    Updates=None):
    """
    Inserts or deletes  SizeConstraint objects (filters) in a  SizeConstraintSet . For each SizeConstraint object, you specify the following values:
    For example, you can add a SizeConstraintSetUpdate object that matches web requests in which the length of the User-Agent header is greater than 100 bytes. You can then configure AWS WAF to block those requests.
    To create and configure a SizeConstraintSet , perform the following steps:
    For more information about how to use the AWS WAF API to allow or block HTTP requests, see the AWS WAF Developer Guide .
    See also: AWS API Documentation

    Examples
    The following example deletes a SizeConstraint object (filters) in a size constraint set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.
    Expected Output:

    :example: response = client.update_size_constraint_set(
        SizeConstraintSetId='string',
        ChangeToken='string',
        Updates=[
            {
                'Action': 'INSERT'|'DELETE',
                'SizeConstraint': {
                    'FieldToMatch': {
                        'Type': 'URI'|'QUERY_STRING'|'HEADER'|'METHOD'|'BODY',
                        'Data': 'string'
                    },
                    'TextTransformation': 'NONE'|'COMPRESS_WHITE_SPACE'|'HTML_ENTITY_DECODE'|'LOWERCASE'|'CMD_LINE'|'URL_DECODE',
                    'ComparisonOperator': 'EQ'|'NE'|'LE'|'LT'|'GE'|'GT',
                    'Size': 123
                }
            },
        ]
    )

    :type SizeConstraintSetId: string
    :param SizeConstraintSetId: [REQUIRED]
            The SizeConstraintSetId of the SizeConstraintSet that you want to update. SizeConstraintSetId is returned by CreateSizeConstraintSet and by ListSizeConstraintSets .

    :type ChangeToken: string
    :param ChangeToken: [REQUIRED]
            The value returned by the most recent call to GetChangeToken .

    :type Updates: list
    :param Updates: [REQUIRED]
            An array of SizeConstraintSetUpdate objects that you want to insert into or delete from a SizeConstraintSet . For more information, see the applicable data types:
            SizeConstraintSetUpdate : Contains Action and SizeConstraint
            SizeConstraint : Contains FieldToMatch , TextTransformation , ComparisonOperator , and Size
            FieldToMatch : Contains Data and Type
            (dict) --Specifies the part of a web request that you want to inspect the size of and indicates whether you want to add the specification to a SizeConstraintSet or delete it from a SizeConstraintSet .
            Action (string) -- [REQUIRED]Specify INSERT to add a SizeConstraintSetUpdate to a SizeConstraintSet . Use DELETE to remove a SizeConstraintSetUpdate from a SizeConstraintSet .
            SizeConstraint (dict) -- [REQUIRED]Specifies a constraint on the size of a part of the web request. AWS WAF uses the Size , ComparisonOperator , and FieldToMatch to build an expression in the form of 'Size ComparisonOperator size in bytes of FieldToMatch '. If that expression is true, the SizeConstraint is considered to match.
            FieldToMatch (dict) -- [REQUIRED]Specifies where in a web request to look for the size constraint.
            Type (string) -- [REQUIRED]The part of the web request that you want AWS WAF to search for a specified string. Parts of a request that you can search include the following:
            HEADER : A specified request header, for example, the value of the User-Agent or Referer header. If you choose HEADER for the type, specify the name of the header in Data .
            METHOD : The HTTP method, which indicated the type of operation that the request is asking the origin to perform. Amazon CloudFront supports the following methods: DELETE , GET , HEAD , OPTIONS , PATCH , POST , and PUT .
            QUERY_STRING : A query string, which is the part of a URL that appears after a ? character, if any.
            URI : The part of a web request that identifies a resource, for example, /images/daily-ad.jpg .
            BODY : The part of a request that contains any additional data that you want to send to your web server as the HTTP request body, such as data from a form. The request body immediately follows the request headers. Note that only the first 8192 bytes of the request body are forwarded to AWS WAF for inspection. To allow or block requests based on the length of the body, you can create a size constraint set. For more information, see CreateSizeConstraintSet .
            Data (string) --When the value of Type is HEADER , enter the name of the header that you want AWS WAF to search, for example, User-Agent or Referer . If the value of Type is any other value, omit Data .
            The name of the header is not case sensitive.
            TextTransformation (string) -- [REQUIRED]Text transformations eliminate some of the unusual formatting that attackers use in web requests in an effort to bypass AWS WAF. If you specify a transformation, AWS WAF performs the transformation on FieldToMatch before inspecting a request for a match.
            Note that if you choose BODY for the value of Type , you must choose NONE for TextTransformation because CloudFront forwards only the first 8192 bytes for inspection.
            NONE
            Specify NONE if you don't want to perform any text transformations.
            CMD_LINE
            When you're concerned that attackers are injecting an operating system command line command and using unusual formatting to disguise some or all of the command, use this option to perform the following transformations:
            Delete the following characters: ' ' ^
            Delete spaces before the following characters: / (
            Replace the following characters with a space: , ;
            Replace multiple spaces with one space
            Convert uppercase letters (A-Z) to lowercase (a-z)
            COMPRESS_WHITE_SPACE
            Use this option to replace the following characters with a space character (decimal 32):
            f, formfeed, decimal 12
            t, tab, decimal 9
            n, newline, decimal 10
            r, carriage return, decimal 13
            v, vertical tab, decimal 11
            non-breaking space, decimal 160
            COMPRESS_WHITE_SPACE also replaces multiple spaces with one space.HTML_ENTITY_DECODE
            Use this option to replace HTML-encoded characters with unencoded characters. HTML_ENTITY_DECODE performs the following operations:
            Replaces (ampersand)quot; with '
            Replaces (ampersand)nbsp; with a non-breaking space, decimal 160
            Replaces (ampersand)lt; with a 'less than' symbol
            Replaces (ampersand)gt; with ````
            Replaces characters that are represented in hexadecimal format, (ampersand)#xhhhh; , with the corresponding characters
            Replaces characters that are represented in decimal format, (ampersand)#nnnn; , with the corresponding characters
            LOWERCASE
            Use this option to convert uppercase letters (A-Z) to lowercase (a-z).
            URL_DECODE
            Use this option to decode a URL-encoded value.
            ComparisonOperator (string) -- [REQUIRED]The type of comparison you want AWS WAF to perform. AWS WAF uses this in combination with the provided Size and FieldToMatch to build an expression in the form of 'Size ComparisonOperator size in bytes of FieldToMatch '. If that expression is true, the SizeConstraint is considered to match.
            EQ : Used to test if the Size is equal to the size of the FieldToMatchNE : Used to test if the Size is not equal to the size of the FieldToMatch
            LE : Used to test if the Size is less than or equal to the size of the FieldToMatch
            LT : Used to test if the Size is strictly less than the size of the FieldToMatch
            GE : Used to test if the Size is greater than or equal to the size of the FieldToMatch
            GT : Used to test if the Size is strictly greater than the size of the FieldToMatch
            Size (integer) -- [REQUIRED]The size in bytes that you want AWS WAF to compare against the size of the specified FieldToMatch . AWS WAF uses this in combination with ComparisonOperator and FieldToMatch to build an expression in the form of 'Size ComparisonOperator size in bytes of FieldToMatch '. If that expression is true, the SizeConstraint is considered to match.
            Valid values for size are 0 - 21474836480 bytes (0 - 20 GB).
            If you specify URI for the value of Type , the / in the URI counts as one character. For example, the URI /logo.jpg is nine characters long.

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

    :returns:
    Create a SizeConstraintSet. For more information, see  CreateSizeConstraintSet .
    Use  GetChangeToken to get the change token that you provide in the ChangeToken parameter of an UpdateSizeConstraintSet request.
    Submit an UpdateSizeConstraintSet request to specify the part of the request that you want AWS WAF to inspect (for example, the header or the URI) and the value that you want AWS WAF to watch for.

    """
    pass


def extract_cab(archive, compression, cmd, verbosity, interactive, outdir):
    """Extract a CAB archive."""
    cmdlist = [cmd, '-d', outdir]
    if verbosity > 0:
        cmdlist.append('-v')
    cmdlist.append(archive)
    return cmdlist


def get_youtube_title(content, number=None):
    """ Get the YouTube video's title. """
    title = content.title
    if number:
        return '{0}. {1}'.format(number, title)
    else:
        return title


@classmethod
def from_npy(cls, filename):
    """
        Load a model from a ``.npy`` file
        """
    from pyRSD.rsd import load_model
    return load_model(filename)


@classmethod
def from_ephem(cls, attractor, ephem, epoch):
    """Create osculating orbit from ephemerides at a given epoch.

        This will assume that the `Ephem` coordinates
        are expressed with respect the given body.

        Parameters
        ----------
        ephem : ~poliastro.ephem.Ephem
            Ephemerides object to use.
        attractor : ~poliastro.bodies.Body
            Body to use as attractor.
        epoch : ~astropy.time.Time
            Epoch to retrieve the osculating orbit at.

        """
    return cls.from_vectors(attractor, *ephem.rv(epoch), epoch, ephem.plane)


def is_unknown(val: str) ->bool:
    """
    Returns True if val represents and unknown value
    """
    if not isinstance(val, str):
        raise TypeError
    if not val or val.upper() in ('UNKN',):
        return True
    for char in val:
        if char not in ('/', 'X', '.'):
            break
    else:
        return True
    return False


@classmethod
def __factory(cls, data):
    """
        This factory makes that any returned value is a measure
        instead of a float.
        """
    return cls(data)


def dump(cls, data, **kwargs):
    """
        Dump the contents of a python data structure to the expected format
        """
    raise NotImplementedError('override in subclass')


def select_more():
    """Select more strips adjacent to the current selection

    """
    pass


@classmethod
def __group_params(cls, sparam, mparam, sparam_name, mparam_name, default=
    None, allmstr=None):
    """Create list with either the singular or multiple valued parameter's value(s).

        This method allows only one or the other parameter to be defined, and returns a list
        containing whatever it finds. If neither parameter is defined, the specified default is
        instead returned.
        """
    if sparam is None and mparam is None:
        return default
    if sparam is not None:
        if mparam is not None:
            raise ValueError(
                f'{sparam_name} and {mparam_name} cannot both be defined')
        return [sparam]
    if allmstr is not None and mparam == allmstr:
        return mparam
    return list(mparam)


def compute_index_shape(v):
    """Compute the 'index shape' of v."""
    return v.ufl_index_dimensions


def __printBoard__(board):
    """
    Prints the board

    Parameters
    ----------
    board : list
        List of pieces at their locations
    """
    print(board[0] + ' | ' + board[1] + ' | ' + board[2])
    print('--+---+--')
    print(board[3] + ' | ' + board[4] + ' | ' + board[5])
    print('--+---+--')
    print(board[6] + ' | ' + board[7] + ' | ' + board[8])


def rem_quotes(txt):
    """ a little helper function to remove quotes from a string."""
    if txt is None:
        return txt
    elif txt[0] == "'" and txt[-1] == "'":
        return txt[1:-1]
    elif txt[0] == '"' and txt[-1] == '"':
        return txt[1:-1]
    else:
        return txt


@classmethod
def get_serializer_class(cls):
    """gets the serializer for the class

        :return: `rest_framework.serializers.Serializer`
        """
    from .serializers import ContentSerializer
    return ContentSerializer


def notifyOnDisconnect(callback, *args, **kwargs):
    """Register a callback to run when we lose this connection.

        The callback will be invoked with whatever extra arguments you
        provide to this function. For example::

         def my_callback(name, number):
             print name, number+4
         cookie = rref.notifyOnDisconnect(my_callback, 'bob', number=3)

        This function returns an opaque cookie. If you want to cancel the
        notification, pass this same cookie back to dontNotifyOnDisconnect::

         rref.dontNotifyOnDisconnect(cookie)

        Note that if the Tub is shutdown (via stopService), all
        notifyOnDisconnect handlers are cancelled.
        """


@staticmethod
def _basename(string):
    """
        Remove trailing numbers from a string.
        """
    if not isinstance(string, str):
        raise ValueError(
            '_basename received a non-string input! Got the following: {}'.
            format(string))
    if string == '':
        return string
    if not string[-1].isdigit():
        return string
    else:
        counter = 0
        for ss in string[::-1]:
            if ss.isdigit():
                counter += 1
            else:
                break
        return string[:-counter]


def get_domain_names(position=None, limit=None):
    """
    Represents a collection of  DomainName resources.
    See also: AWS API Documentation

    :example: response = client.get_domain_names(
        position='string',
        limit=123
    )

    :type position: string
    :param position: The current pagination position in the paged result set.

    :type limit: integer
    :param limit: The maximum number of returned results per page. The value is 25 by default and could be between 1 - 500.

    :rtype: dict
    :return: {
        'position': 'string',
        'items': [
            {
                'domainName': 'string',
                'certificateName': 'string',
                'certificateArn': 'string',
                'certificateUploadDate': datetime(2015, 1, 1),
                'distributionDomainName': 'string'
            },
        ]
    }

    """
    pass


def _is_sunder(name):
    """Returns True if a _sunder_ name, False otherwise."""
    return name[0] == name[-1] == '_' and name[1:2] != '_' and name[-2:-1
        ] != '_' and len(name) > 2


@classmethod
def escape_argument(cls, arg: bytes) ->bytes:
    """Escape special bytes in an argument"""
    if arg == b'':
        return b'\\@'
    else:
        return cls._ESCAPE_RE.sub(cls._escape_match, arg)


def view_persportho():
    """Switch the current view from perspective/orthographic projection

    """
    pass


@classmethod
def get_available_commands(cls):
    """
        Get a list of commands that we can execute.  By default, we have a
        fixed list that we make available in this directory, but the user can
        create her own plugins and store them at
        ~/.config/ripe-atlas-tools/commands/.  If we find any files there, we
        add them to the list here.
        """
    if not cls._commands:
        cls._load_commands()
    return sorted(cls._commands.keys())


def available_datasets():
    """
    List of available datasets
    """
    return ['Salary', 'Weather']


@staticmethod
def group_format(items, converter):
    """
        Return a list of numbered items transformed by a converter
        """
    strings = []
    indexed = []
    index = 1
    for item in items:
        name = converter(item)
        if name is not None:
            indexed.append(item)
            strings.append(f'#{index}: {converter(item)}')
            index += 1
    return indexed, '\n'.join(strings)


@classmethod
def to_year(cls, qo):
    """Return year corresponding to quarter ordinal `qo`."""
    y, q = divmod(qo, 4)
    return y


@classmethod
def float_nosign_exp(cls):
    """Regular expression to match an unsigned float with exponent."""
    return cls._construct_regex('({float_num}{exp}|[{numeric}])')


def psi_Mg_Na_SO4_PK74(T, P):
    """c-c'-a: magnesium sodium sulfate [PK74]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@classmethod
def get_transcript(cls, video_id, languages=('en',), proxies=None, cookies=None
    ):
    """
        Retrieves the transcript for a single video. This is just a shortcut for calling::

            YouTubeTranscriptApi.list_transcripts(video_id, proxies).find_transcript(languages).fetch()

        :param video_id: the youtube video id
        :type video_id: str
        :param languages: A list of language codes in a descending priority. For example, if this is set to ['de', 'en']
        it will first try to fetch the german transcript (de) and then fetch the english transcript (en) if it fails to
        do so.
        :type languages: list[str]
        :param proxies: a dictionary mapping of http and https proxies to be used for the network requests
        :type proxies: {'http': str, 'https': str} - http://docs.python-requests.org/en/master/user/advanced/#proxies
        :param cookies: a string of the path to a text file containing youtube authorization cookies
        :type cookies: str
        :return: a list of dictionaries containing the 'text', 'start' and 'duration' keys
        :rtype [{'text': str, 'start': float, 'end': float}]:
        """
    return cls.list_transcripts(video_id, proxies, cookies).find_transcript(
        languages).fetch()


def get_assign_groups(line, ops=ops):
    """ Split a line into groups by assignment (including
        augmented assignment)
    """
    group = []
    for item in line:
        group.append(item)
        if item in ops:
            yield group
            group = []
    yield group


def note_handler(data, bot, chats):
    """
    Defines the handler for a note (create or update) on commit, merge request, issue or snippet
    """
    message = 'New note on '
    if 'commit' in data:
        message += 'commit '
        info = '\nCommit : ' + data['commit']['url']
    elif 'merge_request' in data:
        message += 'merge request '
        info = '\nMerge request : ' + data['merge_request']['title']
    elif 'issue' in data:
        message += 'issue '
        info = '\nIssue : ' + data['issue']['title']
    else:
        message += 'snippet '
        ifno = '\nSnippet : ' + data['snippet']['title']
    message += 'on project ' + data['project']['name']
    message += info
    message += '\nNote : ' + data['object_attributes']['note']
    message += '\nURL : ' + data['object_attributes']['url']
    bot.send_message_to_list(chats, message)


@classmethod
def getSupportedSymbolNames(cls):
    """Returns the list of supported symbol human-readable names.

        :rtype: tuple of str
        """
    return tuple(cls._SUPPORTED_SYMBOLS.values())


def grouper(iterable, n):
    """
    grouper([0,1,2,3,4], 3) --> [(0,1,2), (3,4)]
    """
    for i in range(0, len(iterable), n):
        yield iterable[i:i + n]


def console_monitor(a, b):
    """
    Simple monitor function which can be used with :obj:`calculate_spectrum`.

    Prints in stdout 'a/b'.

    Args:
        a: An object representing the completed amount (e.g., a number representing a part...).
        b: An object representing the total amount (... of a number representing a total).

    """
    print('Calculation: ', a, '/', b)


def resolve_name(name):
    """Resolve a name like ``module.object`` to an object and return it.

    Raise `ImportError` if the module or name is not found.
    """
    parts = name.split('.')
    cursor = len(parts) - 1
    module_name = parts[:cursor]
    attr_name = parts[-1]
    while cursor > 0:
        try:
            ret = __import__('.'.join(module_name), fromlist=[attr_name])
            break
        except ImportError:
            if cursor == 0:
                raise
            cursor -= 1
            module_name = parts[:cursor]
            attr_name = parts[cursor]
            ret = ''
    for part in parts[cursor:]:
        try:
            ret = getattr(ret, part)
        except AttributeError:
            raise ImportError(name)
    return ret


def can_print(payment):
    """If it's possible to print this payment

        :param payment: the payment to print
        """


def _base_ordering(base, degree):
    """
    Order `\\{0, 1, ..., n-1\\}` so that base points come first and in order.

    Parameters
    ==========

    ``base`` - the base
    ``degree`` - the degree of the associated permutation group

    Returns
    =======

    A list ``base_ordering`` such that ``base_ordering[point]`` is the
    number of ``point`` in the ordering.

    Examples
    ========

    >>> S = SymmetricGroup(4)
    >>> S.schreier_sims()
    >>> _base_ordering(S.base, S.degree)
    [0, 1, 2, 3]

    Notes
    =====

    This is used in backtrack searches, when we define a relation `<<` on
    the underlying set for a permutation group of degree `n`,
    `\\{0, 1, ..., n-1\\}`, so that if `(b_1, b_2, ..., b_k)` is a base we
    have `b_i << b_j` whenever `i<j` and `b_i << a` for all
    `i\\in\\{1,2, ..., k\\}` and `a` is not in the base. The idea is developed
    and applied to backtracking algorithms in [1], pp.108-132. The points
    that are not in the base are taken in increasing order.

    References
    ==========

    * Holt, D., Eick, B., O'Brien, E.
      "Handbook of computational group theory"

    """
    base_len = len(base)
    ordering = [0] * degree
    for i in range(base_len):
        ordering[base[i]] = i
    current = base_len
    for i in range(degree):
        if i not in base:
            ordering[i] = current
            current += 1
    return ordering


def create_cache_parameter_group(CacheParameterGroupName=None,
    CacheParameterGroupFamily=None, Description=None):
    """
    Creates a new Amazon ElastiCache cache parameter group. An ElastiCache cache parameter group is a collection of parameters and their values that are applied to all of the nodes in any cache cluster or replication group using the CacheParameterGroup.
    A newly created CacheParameterGroup is an exact duplicate of the default parameter group for the CacheParameterGroupFamily. To customize the newly created CacheParameterGroup you can change the values of specific parameters. For more information, see:
    See also: AWS API Documentation

    :example: response = client.create_cache_parameter_group(
        CacheParameterGroupName='string',
        CacheParameterGroupFamily='string',
        Description='string'
    )

    :type CacheParameterGroupName: string
    :param CacheParameterGroupName: [REQUIRED]
            A user-specified name for the cache parameter group.

    :type CacheParameterGroupFamily: string
    :param CacheParameterGroupFamily: [REQUIRED]
            The name of the cache parameter group family that the cache parameter group can be used with.
            Valid values are: memcached1.4 | redis2.6 | redis2.8 | redis3.2

    :type Description: string
    :param Description: [REQUIRED]
            A user-specified description for the cache parameter group.

    :rtype: dict
    :return: {
        'CacheParameterGroup': {
            'CacheParameterGroupName': 'string',
            'CacheParameterGroupFamily': 'string',
            'Description': 'string'
        }
    }

    :returns:
    CacheParameterGroupName (string) -- [REQUIRED]
    A user-specified name for the cache parameter group.

    CacheParameterGroupFamily (string) -- [REQUIRED]
    The name of the cache parameter group family that the cache parameter group can be used with.
    Valid values are: memcached1.4 | redis2.6 | redis2.8 | redis3.2

    Description (string) -- [REQUIRED]
    A user-specified description for the cache parameter group.

    """
    pass


def interval(els):
    """Returns Friedmann (1985) CI, the distance between one
    element in a CC (normal_form cseg here), and a later element
    as signified by +, - and a number (without + here). For
    example, in cseg = [0, 2, 1], CI(0, 2) = 2, e CI(2, 1) = -1.

    >>> interval([4, 0])
    -4
    """
    el1, el2 = els
    return el2 - el1


def _parse_index_file(filename):
    """Parse index file."""
    index = []
    for line in open(filename):
        index.append(int(line.strip()))
    return index


@staticmethod
def side_effects(event: 'EventModel') ->None:
    """Side effects called during handling the event."""
    pass


@staticmethod
def _calc_parallel_connection(element_list, omega):
    """Parallel connection of walls according to VDI 6007

        Calculates the parallel connection of wall elements according to VDI
        6007, resulting in R1 and C1 (equation 23, 24).

        Parameters
        ----------
        element_list : list
            List of inner or outer walls
        omega : float
            VDI 6007 frequency

        Returns
        ----------
        r1 : float [K/W]
            VDI 6007 resistance for all inner or outer walls
        c1 : float [K/W]
            VDI 6007 capacity all for inner or outer walls
        """
    for wall_count in range(len(element_list) - 1):
        if wall_count == 0:
            r1 = (element_list[wall_count].r1 * element_list[wall_count].c1 **
                2 + element_list[wall_count + 1].r1 * element_list[
                wall_count + 1].c1 ** 2 + omega ** 2 * element_list[
                wall_count].r1 * element_list[wall_count + 1].r1 * (
                element_list[wall_count].r1 + element_list[wall_count + 1].
                r1) * element_list[wall_count].c1 ** 2 * element_list[
                wall_count + 1].c1 ** 2) / ((element_list[wall_count].c1 +
                element_list[wall_count + 1].c1) ** 2 + omega ** 2 * (
                element_list[wall_count].r1 + element_list[wall_count + 1].
                r1) ** 2 * element_list[wall_count].c1 ** 2 * element_list[
                wall_count + 1].c1 ** 2)
            c1 = ((element_list[wall_count].c1 + element_list[wall_count +
                1].c1) ** 2 + omega ** 2 * (element_list[wall_count].r1 +
                element_list[wall_count + 1].r1) ** 2 * element_list[
                wall_count].c1 ** 2 * element_list[wall_count + 1].c1 ** 2) / (
                element_list[wall_count].c1 + element_list[wall_count + 1].
                c1 + omega ** 2 * (element_list[wall_count].r1 ** 2 *
                element_list[wall_count].c1 + element_list[wall_count + 1].
                r1 ** 2 * element_list[wall_count + 1].c1) * element_list[
                wall_count].c1 * element_list[wall_count + 1].c1)
        else:
            r1x = r1
            c1x = c1
            r1 = (r1x * c1x ** 2 + element_list[wall_count + 1].r1 *
                element_list[wall_count + 1].c1 ** 2 + omega ** 2 * r1x *
                element_list[wall_count + 1].r1 * (r1x + element_list[
                wall_count + 1].r1) * c1x ** 2 * element_list[wall_count +
                1].c1 ** 2) / ((c1x + element_list[wall_count + 1].c1) ** 2 +
                omega ** 2 * (r1x + element_list[wall_count + 1].r1) ** 2 *
                c1x ** 2 * element_list[wall_count + 1].c1 ** 2)
            c1 = ((c1x + element_list[wall_count + 1].c1) ** 2 + omega ** 2 *
                (r1x + element_list[wall_count + 1].r1) ** 2 * c1x ** 2 *
                element_list[wall_count + 1].c1 ** 2) / (c1x + element_list
                [wall_count + 1].c1 + omega ** 2 * (r1x ** 2 * c1x +
                element_list[wall_count + 1].r1 ** 2 * element_list[
                wall_count + 1].c1) * c1x * element_list[wall_count + 1].c1)
    return r1, c1


def normals_make_consistent(inside: bool=False):
    """Make face and vertex normals point either outside or inside the mesh

    :param inside: Inside
    :type inside: bool
    """
    pass


@classmethod
def all(cls, name, range_key):
    """ Create an index that projects all attributes """
    return cls(cls.ALL, name, range_key)


def unescape(value, escape='\\'):
    """
    Unescapes the provided string value using the provided escape
    character as the reference for the unescape operation.

    This is considered to be a very expensive operation and so it
    should be used carefully.

    :type value: String
    :param value: The string value that is going to be unescape.
    :rtype: String
    :return: The final unescaped value.
    """
    result = []
    iterator = iter(value)
    for char in iterator:
        if char == escape:
            try:
                result.append(next(iterator))
            except StopIteration:
                result.append(escape)
        else:
            result.append(char)
    return ''.join(result)


def sortByMinima(requestContext, seriesList):
    """
    Takes one metric or a wildcard seriesList.

    Sorts the list of metrics by the lowest value across the time period
    specified.

    Example::

        &target=sortByMinima(server*.instance*.memory.free)

    """
    return list(sorted(seriesList, key=min))


def prepare_payload(module_id, activity_id, parsed):
    """Format the payload in order to send the declaration."""
    data = {'module': module_id, 'activity': activity_id}
    start_date = parsed.start_date
    end_date = parsed.end_date
    declaration = {'start': start_date, 'end': end_date, 'content': parsed.
        declaration.read()}
    data['declaration'] = declaration
    return data


def supscr(text=None):
    """
     | supscr - add superscript text formatting for ** and ^
     | This is an internal routine used in titles and colour bars
     | and not used by the user.
     | text=None - input text

     :Returns:
      Formatted text
     |
     |
     |
     |
     |
     |
     |
    """
    if text is None:
        errstr = '\n supscr error - supscr must have text input\n'
        raise Warning(errstr)
    tform = ''
    sup = 0
    for i in text:
        if i == '^':
            sup = 2
        if i == '*':
            sup = sup + 1
        if sup == 0:
            tform = tform + i
        if sup == 1:
            if i not in '*':
                tform = tform + '*' + i
                sup = 0
        if sup == 3:
            if i in '-0123456789':
                tform = tform + i
            else:
                tform = tform + '}$' + i
                sup = 0
        if sup == 2:
            tform = tform + '$^{'
            sup = 3
    if sup == 3:
        tform = tform + '}$'
    tform = tform.replace('m2', 'm$^{2}$')
    tform = tform.replace('m3', 'm$^{3}$')
    tform = tform.replace('m-2', 'm$^{-2}$')
    tform = tform.replace('m-3', 'm$^{-3}$')
    tform = tform.replace('s-1', 's$^{-1}$')
    tform = tform.replace('s-2', 's$^{-2}$')
    return tform


def describe_account_limits(Marker=None, PageSize=None):
    """
    Describes the current Elastic Load Balancing resource limits for your AWS account.
    For more information, see Limits for Your Application Load Balancer in the Application Load Balancer Guide .
    See also: AWS API Documentation

    :example: response = client.describe_account_limits(
        Marker='string',
        PageSize=123
    )

    :type Marker: string
    :param Marker: The marker for the next set of results. (You received this marker from a previous call.)

    :type PageSize: integer
    :param PageSize: The maximum number of results to return with this call.

    :rtype: dict
    :return: {
        'Limits': [
            {
                'Name': 'string',
                'Max': 'string'
            },
        ],
        'NextMarker': 'string'
    }

    :returns:
    application-load-balancers
    listeners-per-application-load-balancer
    rules-per-application-load-balancer
    target-groups
    targets-per-application-load-balancer

    """
    pass


def gen_un_ordered_list(list_items, bullet_char='*'):
    """Generates a bullet list.

    The bullet character can be provided.

    Args:
     list_items (list of strings): The items to be listed.
     bullet_char (char, optional): The bullet character '*'
       is default.

    Returns:
      string: The markdown formatted list.

    """
    md_str = ''
    for item in list_items:
        md_str += '{} {}\n'.format(bullet_char, item)
    return md_str


@classmethod
def current(cls):
    """Retrieve the active schema or the default."""
    current = cls.read_stack('schema')
    if current is None:
        return cls.default()
    return current


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 color_select(deselect: bool=False):
    """Select all Grease Pencil strokes using current color

    :param deselect: Deselect, Unselect strokes
    :type deselect: bool
    """
    pass


def _write_device(out, device):
    """Write a single device to file."""
    attributes = []
    if device.name is not None:
        attributes.append(f'name: {device.name}')
    if device.tracking_device_id is not None:
        attributes.append(f'tracking_device_id: {device.tracking_device_id}')
    if device.disabled:
        attributes.append('disabled: True')
    out.write(device.push_id)
    out.write(': {')
    if attributes:
        separator = ', '
        out.write(separator.join(attributes))
    out.write('}\n')


def _windows_shell_quote(s):
    """Return a Windows shell-escaped version of the string *s*

    Windows has potentially bizarre rules depending on where you look. When
    spawning a process via the Windows C runtime the rules are as follows:

    https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments

    To summarize the relevant bits:

    * Only space and tab are valid delimiters
    * Double quotes are the only valid quotes
    * Backslash is interpreted literally unless it is part of a chain that
      leads up to a double quote. Then the backslashes escape the backslashes,
      and if there is an odd number the final backslash escapes the quote.

    :param s: A string to escape
    :return: An escaped string
    """
    if not s:
        return '""'
    buff = []
    num_backspaces = 0
    for character in s:
        if character == '\\':
            num_backspaces += 1
        elif character == '"':
            if num_backspaces > 0:
                buff.append('\\' * (num_backspaces * 2))
                num_backspaces = 0
            buff.append('\\"')
        else:
            if num_backspaces > 0:
                buff.append('\\' * num_backspaces)
                num_backspaces = 0
            buff.append(character)
    if num_backspaces > 0:
        buff.append('\\' * num_backspaces)
    new_s = ''.join(buff)
    if ' ' in new_s or '\t' in new_s:
        return '"%s"' % new_s
    return new_s


@classmethod
def clean(cls):
    """
        Clean the class method name for tests
        :return: None
        """
    if id(cls) in cls.available_rpc_methods:
        del cls.available_rpc_methods[id(cls)]


def report_delete():
    """Delete selected reports

    """
    pass


def reify(to_reify):
    """ Reify the indicated objects.

        o If 'to_reify' is a string, treat it as an OID.

        o Otherwise, iterate over it as a sequence of OIDs.

        o For each OID, if present in 'data' and in GHOST state:

            o Call '_p_activate' on the object.

            o Add it to the ring.

        o If any OID is present but not in GHOST state, skip it.

        o Raise KeyErrory if any OID is not present.
        """


def enable_shared_function(value):
    """force and override settings, by setting the global use shared data
    attribute
    """
    global ENABLED
    ENABLED = bool(value)


def _add_time_variable(root, time, **kwds):
    """Add a time value to a NetCDF file.

    Append a new time value to the time variable of a NetCDF file. If there
    is not time variable, create one. The time variable is named, ``t``.

    Parameters
    ----------
    root : netcdf_file
        A NetCDF file.
    time : float
        The time.
    units : str, optional
        Time units.
    reference : str, optional
        Reference time.
    """
    units = kwds.get('units', 'days')
    reference = kwds.get('reference', '00:00:00 UTC')
    netcdf_vars = root.variables
    try:
        time_var = netcdf_vars['t']
    except KeyError:
        time_var = root.createVariable('t', 'f8', ('nt',))
        time_var.units = ' '.join([units, 'since', reference])
        time_var.long_name = 'time'
    try:
        n_times = len(time_var)
    except TypeError:
        n_times = len(time_var[:])
    if time is not None:
        time_var[n_times] = time
    else:
        time_var[n_times] = n_times


def _iszero(x):
    """Returns True if x is zero."""
    return x.is_zero


def isZ(pid):
    """Determine if the PID is that of a Z0"""
    return pid == 23


def DrudeSommerfeld(omega, omegap, gamma):
    """
	The Drude-Sommerfeld model of a metal dielectric.
	Applies when only free-electron contributions need
	to be considered.

	Returns
	----------

	eps:		Drude permittivity
	"""
    frac = omegap ** 2 / (omega ** 2 + 1.0j * gamma * omega)
    eps = 1 - frac
    return eps


def get_oid_desc_stm(oid_desc):
    """Format oid descriptions (int->value mappings) for neo4j """
    return ','.join(map(lambda k: '{}: "{}"'.format(oid_desc[k], k), oid_desc))


def assert_query_has_qmark(query: str, context: str='') ->None:
    """Throws Exception if the query does not contain any question marks."""
    if '?' in query:
        return
    message = ''
    if context:
        message = ' ' + context
    message = (message +
        "Query commands must contain question-marks. Sent query: '{0}'".
        format(query.strip('\n')))
    raise Exception(message)


def asn1_length(n):
    """Return a string representing a field length in ASN.1 format.

    @param n: integer field length
    @return: ASN.1 field length
    """
    assert n >= 0
    if n < 127:
        return bytearray([n])
    r = bytearray()
    while n > 0:
        r.insert(n & 255)
        n >>= 8
    return r