def parse_ipv6_literal_host(entity, default_port):
    """Validates an IPv6 literal host:port string.

    Returns a 2-tuple of IPv6 literal followed by port where
    port is default_port if it wasn't specified in entity.

    :Parameters:
        - `entity`: A string that represents an IPv6 literal enclosed
                    in braces (e.g. '[::1]' or '[::1]:27017').
        - `default_port`: The port number to use when one wasn't
                          specified in entity.
    """
    if entity.find(']') == -1:
        raise ValueError(
            "an IPv6 address literal must be enclosed in '[' and ']' according to RFC 2732."
            )
    i = entity.find(']:')
    if i == -1:
        return entity[1:-1], default_port
    return entity[1:i], entity[i + 2:]


def ends_paragraph(s):
    """Return True if s is a blank line."""
    return not s.strip()


def load_pydoc(finder, module):
    """The pydoc module will work without the Tkinter module so ignore the
       error if that module cannot be found."""
    module.IgnoreName('Tkinter')


def disable_silverlight():
    """
        disable_silverlight

        Disable SilverLight

        @return: None
        """


def seams_from_islands(mark_seams: bool=True, mark_sharp: bool=False):
    """Set mesh seams according to island setup in the UV editor

    :param mark_seams: Mark Seams, Mark boundary edges as seams
    :type mark_seams: bool
    :param mark_sharp: Mark Sharp, Mark boundary edges as sharp
    :type mark_sharp: bool
    """
    pass


def get_raw_base_qual(alignment: bytes, len_read_name: int,
    number_cigar_operations: int, len_sequence: int) ->bytes:
    """Extract the raw base qualities from a BAM alignment bytestring

    Parameters
    ----------
    alignment : bytes
        A byte string of a bam alignment entry in raw binary format

    len_read_name : int
        The length of the readname string
        eg from pylazybam.bam.get_len_read_name()

    number_cigar_operations : int
        The number of cigar operations
        eg from pylazybam.bam.get_number_cigar_operations()

    len_sequence : int
        The length of the sequence and quality score strings
        eg from pylazybam.bam.get_len_sequence

    Returns
    -------
    bytes
        The raw base qualities in BAM format as a binary bytestring

    """
    start = 36 + len_read_name + 4 * number_cigar_operations + (len_sequence +
        1) // 2
    end = start + len_sequence
    return alignment[start:end]


@staticmethod
def strip_textpad(text):
    """
        Attempt to intelligently strip excess whitespace from the output of a
        curses textpad.
        """
    if text is None:
        return text
    if '\n' not in text:
        return text.rstrip()
    stack, current_line = [], ''
    for line in text.split('\n'):
        if line.endswith('  ') or not line:
            stack.append(current_line + line.rstrip())
            current_line = ''
        else:
            current_line += line
    stack.append(current_line)
    for item in stack[::-1]:
        if not item:
            stack.pop()
        else:
            break
    out = '\n'.join(stack)
    return out


def normalize_line(line, newline):
    """Return line with fixed ending, if ending was present in line.

    Otherwise, does nothing.
    """
    stripped = line.rstrip('\n\r')
    if stripped != line:
        return stripped + newline
    return line


def _udot(u, t, coeff_rec_func, redshift_func, ion_func, bubble=True):
    """du/dt where u = x - f_* f_esc,gamma N_gamma F

    Parameters
    ----------

    u: integral of du/dt as defined below

    t: cosmic age in s

    redshift_func: function returning redshift given t

    ion_func: function returing ionized fraction neglecting recombinations

    coeff_rec_func: function returning clumping_factor alpha_B n_H_0 (1+z)^3

    bubble: If True, assume ionized gas is in fully-ionized bubbles
            and other gas is fully neutral. If False, asssume gas is
            uniformly fractionally ionized.

    Notes
    -----

    This is implemented as a reformulation of the normal ODE
    describing ionization and recombination (see, e.g. Bagla, Kulkarni
    & Padmanabhan (2009MNRAS.397..971B).

    The original ODE is:

    dx/dt = -alpha_B C n_H x + f_* f_esc,gamma N_gamma dF/dt

    If we let u = x - w, where w = f_* f_esc,gamma N_gamma F(t) then

    du/dt = dx/dt - dw/dt

    which gives

    du/dt = -alpha_B C n_H x = -alpha_B C n_H (u + w)

    We have an analytical expression for w, so we can numerically
    integrate the ODE to give us u(t) or x(t) = u(t) + w(t).

    """
    z = redshift_func(t)
    w = ion_func(z)
    crf = coeff_rec_func(z)
    x = u + w
    x = x * (x <= 1.0) + 1.0 * (x > 1.0)
    if bubble:
        udot = -1.0 * crf * x
    else:
        udot = -1.0 * crf * x ** 2
    if False:
        print('z=%.3f; t=%.1g; c=%.2g; udot=%.2g; w,x,u = %.2g, %.2g, %.2g' %
            (z, t, crf, udot, w, x, u))
    return udot


def next():
    """Return the next message.

        It should return a Deferred which will get fired when there is a new
        project that needs to run, or already fired if there was a project
        waiting to run already.

        The message is a dict containing (at least):
        * the name of the project to be run in the '_project' key
        * the name of the spider to be run in the '_spider' key
        * a unique identifier for this run in the `_job` key
        This message will be passed later to IEnvironment.get_environment().
        """


@staticmethod
def get_jenkins_plugin_name():
    """Gets the name of the Jenkins plugin associated with this PyJen plugin

        This static method is used by the PyJen plugin API to associate this
        class with a specific Jenkins plugin, as it is encoded in the config.xml

        :rtype: :class:`str`
        """
    return 'hudson.plugins.parameterizedtrigger.BuildTrigger'


def positive_int(string):
    """Type checker for positive integers
    """
    value = int(string)
    if value <= 0:
        raise ValueError('integer is not positive: {}'.format(value))
    return value


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

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

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

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


def divup(x: int, y: int) ->int:
    """Divide x by y and round the result upwards."""
    return (x + y - 1) // y


def set_client(client):
    """Store a client instance as singleton client

    Args:
        client (ozelot.client.Client): database client
    """
    global _client
    _client = client


def get_remoteadb_url(environment: str, enterprise_id: str, device_id: str,
    remoteadb_id: str=None) ->str:
    """
    Build and return remoteadb url for scapi endpoint
    :param environment:
    :param enterprise_id:
    :param device_id:
    :param remoteadb_id:
    :return:
    """
    host = f'https://{environment}-api.shoonyacloud.com'
    url = (
        f'{host}/api/v0/enterprise/{enterprise_id}/device/{device_id}/remoteadb/'
        )
    if remoteadb_id:
        url = f'{url}{remoteadb_id}'
    return url


def AND(*values):
    """Return a logical AND (conjunction) between all the values.

    Example
    -------
    To define symptomatic individuals as infected for at least 5 days::

      is_symptomatic:
        desc: 'test if individuals has symptoms'
        value: 'AND(is_I, duration_in_health_state >= 5)'

    Parameters
    ----------
    *values: list
        boolean values separated by commas

    Returns
    -------
    bool:
        True if **all** values are True, False otherwise.
    """
    return all(values)


def async_task(func):
    """
    Used as a convenience decorator to be able to declare async_tasks for a TaskSet
    inline in the class. Example::

        class ForumPage(TaskSet):
            @async_task
            def read_thread(self):
                pass
    """
    func.async_task = True
    return func


@classmethod
def module_repr(cls, module):
    """Return repr for the module.

        The method is deprecated.  The import machinery does the job itself.

        """
    return '<module {!r} (namespace)>'.format(module.__name__)


def should_build_with_cython(package, release=None):
    """Returns the previously used Cython version (or 'unknown' if not
    previously built) if Cython should be used to build extension modules from
    pyx files.  If the ``release`` parameter is not specified an attempt is
    made to determine the release flag from `astropy.version`.
    """
    try:
        version_module = __import__(package + '.cython_version', fromlist=[
            'release', 'cython_version'])
    except ImportError:
        version_module = None
    if release is None and version_module is not None:
        try:
            release = version_module.release
        except AttributeError:
            pass
    try:
        cython_version = version_module.cython_version
    except AttributeError:
        cython_version = 'unknown'
    have_cython = False
    try:
        import Cython
        have_cython = True
    except ImportError:
        pass
    if have_cython and (not release or cython_version == 'unknown'):
        return cython_version
    else:
        return False


def next_power_of_2(n):
    """
    Return next power of 2 greater than or equal to n
    """
    return 2 ** (n - 1).bit_length()


def d2cd(d, e):
    """Transform from *d* value to column *cd* count value, using the
    *e.css('cd')* (column depth) as column measure."""
    cd = e.css('cd', 0)
    if cd + e.gd:
        return (d + e.gd) / (cd + e.gd)
    return 0


def allow_inheritance(permission_id):
    """Unset inheritance for the permission.
        """


def _get_hg_status(output):
    """This function exists to enable mocking the `hg status` output in tests.
    """
    return output[0].decode('utf-8').splitlines()


def sum_of_intervals(intervals):
    """
    Returns (list of) sum of intervals. Intervals could be tuple of any
    orderable values (ex. integers, dates). If sets are overlapping, they are
    "merged" together and resulting interval is (min(start1, start2),
    max(end1, end2)).

    >>> sum_of_intervals([(1, 5), (4, 10), (7, 13), (15, 20), (21, 30)])
    [(1, 13), (15, 20), (21, 30)]
    """
    intervals_set = set()
    for v_start, v_end in intervals:
        intervals_set.add((v_start, True))
        intervals_set.add((v_end, False))
    intervals = list(intervals_set)
    intervals.sort(key=lambda a: a[0])
    current_start = None
    started = 0
    result = []
    for value, is_start in intervals:
        if is_start:
            if current_start is None:
                current_start = value
            started += 1
        else:
            started -= 1
            if started == 0:
                result.append((current_start, value))
                current_start = None
    return result


def create_lrzip(archive, compression, cmd, verbosity, interactive, filenames):
    """Create a LRZIP archive."""
    cmdlist = [cmd, '-o', archive]
    if verbosity > 1:
        cmdlist.append('-v')
    cmdlist.extend(filenames)
    return cmdlist


@classmethod
def mk_kwargs(cls, kwargs):
    """
        Pop recognized arguments from a keyword list.
        """
    ret = {}
    kws = ['row_factory', 'body', 'parent']
    for k in kws:
        if k in kwargs:
            ret[k] = kwargs.pop(k)
    return ret


def anyheader_filter(reader, header_match):
    """
    Filter dialogs by a regexp which must match any packet in the dialog.
    """
    for dialog in reader:
        for packet in dialog:
            if packet.search(header_match):
                yield dialog
                break


def zeta_H3PO4_Na_Cl_MP98(T, P):
    """phosphoric-acid sodium chloride [MP98]."""
    zeta = 0
    valid = T == 298.15
    return zeta, valid


def riseFallAmp():
    """Rises and falls amplitude between -30 and -3 dB, 1 db at the time."""
    global db, dir
    db += dir
    if db >= -3:
        dir = -1
    elif db < -30:
        dir = 1
    return db


@classmethod
def modify_url_for_impersonation(cls, url, impersonate_user, username):
    """
        Modify the SQL Alchemy URL object with the user to impersonate if applicable.
        :param url: SQLAlchemy URL object
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        """
    pass


def ShowBanner(pFile=None):
    """Print authorship, copyright and citation notice"""
    pFile.write(80 * '*' + '\n')
    pFile.write(
        '   General Structure Analysis System-II Crystal Structure Refinement\n'
        )
    pFile.write('              by Robert B. Von Dreele & Brian H. Toby\n')
    pFile.write('                Argonne National Laboratory(C), 2010\n')
    pFile.write(
        ' This product includes software developed by the UChicago Argonne, LLC,\n'
        )
    pFile.write('            as Operator of Argonne National Laboratory.\n')
    pFile.write('                          Please cite:\n')
    pFile.write(
        '   B.H. Toby & R.B. Von Dreele, J. Appl. Cryst. 46, 544-549 (2013)\n')
    pFile.write(80 * '*' + '\n')


def filter_addresses(filter):
    """Returns only a particular type of email from addresses."""


@classmethod
def set_current_date(cls, date):
    """set current simulation date
        :param date: string date, "2016-01-04"
        """
    cls.get_active()._set_current_date(date)


def is_not_whitespace(bag):
    """filter: cells which do contain printable characters"""
    return bag.filter(lambda cell: str(cell.value).strip())


def lcp(string, i, j):
    """ Longest-Common-Prefix """
    l = 0
    n = len(string)
    while l + max(i, j) < n and string[i + l] == string[j + l]:
        l += 1
    return l


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 is_asset_path(request):
    """
    Check the request path is asset path or not
    :param request: Django Request instance
    :return: boolean
    """
    is_asset = False
    black_list = ['media', 'static', 'favicon.ico',
        '/__debug_toolbar__/render_panel/']
    for p in black_list:
        if p in request.path:
            is_asset = True
            break
    return is_asset


def linalg_slogdet(A=None, name=None, attr=None, out=None, **kwargs):
    """Compute the sign and log of the determinant of a matrix.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, *A* is a square matrix. We compute:

      *sign* = *sign(det(A))*
      *logabsdet* = *log(abs(det(A)))*

    If *n>2*, *slogdet* is performed separately on the trailing two dimensions
    for all inputs (batch mode).

    .. note:: The operator supports float32 and float64 data types only.
    .. note:: The gradient is not properly defined on sign, so the gradient of
              it is not backwarded.
    .. note:: No gradient is backwarded when A is non-invertible. Please see
              the docs of operator det for detail.

    Examples::

       Single matrix signed log determinant
       A = [[2., 3.], [1., 4.]]
       sign, logabsdet = slogdet(A)
       sign = [1.]
       logabsdet = [1.609438]

       Batch matrix signed log determinant
       A = [[[2., 3.], [1., 4.]],
            [[1., 2.], [2., 4.]],
            [[1., 2.], [4., 3.]]]
       sign, logabsdet = slogdet(A)
       sign = [1., 0., -1.]
       logabsdet = [1.609438, -inf, 1.609438]

    Defined in src/operator/tensor/la_op.cc:L1031

    Parameters
    ----------
    A : Symbol
        Tensor of square matrix

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

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


@classmethod
def mutex_base(cls):
    """Returns the root class in a mutex group.

        Members of the group will all mix in this class and it should implement this method
        concretely to return itself.
        """
    raise NotImplementedError()


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


@classmethod
def get_partial_form(cls, Form, fields):
    """ Get partial form based on original Form and fields set.

        :param Form: django.forms.ModelForm
        :param list fields: list of field names.

        """
    if not fields:
        return Form
    if not set(fields) <= set(Form.base_fields.keys()):
        fields = set(fields) & set(Form.base_fields.keys())
    meta_attributes = dict(fields=list(fields))
    meta_bases = Form.Meta,
    if not issubclass(Form.Meta, object):
        meta_bases += object,
    PartialForm = type('PartialForm', (Form,), {'Meta': type('Meta',
        meta_bases, meta_attributes)})
    return PartialForm


def process_edited_message(bot, chains, update):
    """Process an edited message"""
    for hook in chains['messages_edited']:
        bot.logger.debug(
            'Processing edited message in update #%s with the hook %s...' %
            (update.update_id, hook.name))
        result = hook.call(bot, update)
        if result is True:
            bot.logger.debug('Update %s was just processed by the %s hook.' %
                (update.update_id, hook.name))
            return
    bot.logger.debug('No hook actually processed the #%s update.' % update.
        update_id)


@staticmethod
def extensions():
    """Return accepted extensions for this loader"""
    return ('bmp', 'jpg', 'jpeg', 'jpe', 'lbm', 'pcx', 'png', 'pnm', 'tga',
        'tiff', 'webp', 'xcf', 'xpm', 'xv')


@staticmethod
def _timedelta_is_positive(tdelta):
    """
        Is the given timedelta positive?
        """
    return tdelta == abs(tdelta)


@staticmethod
def calculate(vm, arg):
    """
        Calculate the result of the unary operation, given a concrete argument.

        The virtual machine is passed in so that the overflow and carry flags can be
        set if necessary.
        """
    raise NotImplementedError


def int_to_alpha(n, upper=True):
    """Generates alphanumeric labels of form A-Z, AA-ZZ etc."""
    casenum = 65 if upper else 97
    label = ''
    count = 0
    if n == 0:
        return str(chr(n + casenum))
    while n >= 0:
        mod, div = n % 26, n
        for _ in range(count):
            div //= 26
        div %= 26
        if count == 0:
            val = mod
        else:
            val = div
        label += str(chr(val + casenum))
        count += 1
        n -= 26 ** count
    return label[::-1]


def tomorrow(event):
    """ show todo items for tomorrow. """
    if not event._parsed.rest:
        event.reply('tomorrow <txt>')
        return
    event.tomorrow = event.txt.replace('tomorrow', '').strip()
    event.prefix = 'tomorrow'
    event.save()
    event.ok()


def multiply(image1, image2):
    """
    Superimposes two images on top of each other.

    If you multiply an image with a solid black image, the result is black. If
    you multiply with a solid white image, the image is unaffected. At least
    one of the images must have mode "1".

    .. code-block:: python

        out = image1 * image2 / MAX

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_multiply(image2.im))


def p_select_command(p):
    """select_command : SELECT WORD newline_list DO list DONE
                      | SELECT WORD newline_list LEFT_CURLY list RIGHT_CURLY
                      | SELECT WORD SEMICOLON newline_list DO list DONE
                      | SELECT WORD SEMICOLON newline_list LEFT_CURLY list RIGHT_CURLY
                      | SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
                      | SELECT WORD newline_list IN word_list list_terminator newline_list LEFT_CURLY list RIGHT_CURLY"""
    raise NotImplementedError('select command')


@classmethod
def registertest(cls, function):
    """Decorator to register a jinja2 test"""
    cls.tests[function.__name__] = function
    return function


def p_bloqueD(p):
    """bloqueD : declaracion bloqueD
               | empty
    """


def _gf_gcd(fp, gp, p):
    """Compute the GCD of two univariate polynomials in `\\mathbb{Z}_p[x]`."""
    dom = fp.ring.domain
    while gp:
        rem = fp
        deg = gp.degree()
        lcinv = dom.invert(gp.LC, p)
        while True:
            degrem = rem.degree()
            if degrem < deg:
                break
            rem = (rem - gp.mul_monom((degrem - deg,)) * (lcinv * rem.LC)
                ).trunc_ground(p)
        fp = gp
        gp = rem
    return (fp * dom.invert(fp.LC, p)).trunc_ground(p)


def convert_distance(val, old_scale='meter', new_scale='centimeter'):
    """
    Convert from a length scale to another one among meter, centimeter, inch,
    feet, and mile.

    Parameters
    ----------
    val: float or int
        Value of the length to be converted expressed in the original scale.

    old_scale: str
        Original scale from which the length value will be converted.
        Supported scales are Meter ['Meter', 'meter', 'm'],
        Centimeter ['Centimeter', 'centimeter', 'vm'], Inch ['Inch', 'inch', 'in'], Feet ['Feet', 'feet', 'ft'] or Mile ['Mile', 'mile', 'mil'].

    new_scale: str
        New scale from which the length value will be converted.
        Supported scales are Meter ['Meter', 'meter', 'm'],
        Centimeter ['Centimeter', 'centimeter', 'cm'], Inch ['Inch', 'inch', 'in'], Feet ['Feet', 'feet', 'ft'] or Mile ['Mile', 'mile', 'mil'].

    Raises
    -------
    NotImplementedError if either of the scales are not one of the requested
    ones.

    Returns
    -------
    res: float
        Value of the converted length expressed in the new scale.
    """
    if old_scale.lower() in ['centimeter', 'cm']:
        temp = val / 100.0
    elif old_scale.lower() in ['meter', 'm']:
        temp = val
    elif old_scale.lower() in ['inch', 'in']:
        temp = val / 39.37008
    elif old_scale.lower() in ['feet', 'ft']:
        temp = val / 3.28084
    elif old_scale.lower() in ['mile', 'mil']:
        temp = 1609.344 * val
    else:
        raise AttributeError(
            f'{old_scale} is unsupported. m, cm, ft, in and mile are supported'
            )
    if new_scale.lower() in ['centimeter', 'cm']:
        result = 100 * temp
    elif new_scale.lower() in ['meter', 'm']:
        result = temp
    elif new_scale.lower() in ['inch', 'in']:
        result = 39.37008 * temp
    elif new_scale.lower() in ['feet', 'ft']:
        result = 3.28084 * temp
    elif new_scale.lower() in ['mile', 'mil']:
        result = temp / 1609.344
    else:
        raise AttributeError(
            f'{new_scale} is unsupported. m, cm, ft, in and mile are supported'
            )
    return result


def get_dist(matches):
    """Gets distance to the closest match of every point"""
    output = []
    for x in matches:
        dic = []
        for y in x:
            min_dist = 255
            for z in x:
                if y != z and max(abs(y[0] - z[0]), abs(y[1] - z[1])
                    ) < min_dist:
                    min_dist = max(abs(y[0] - z[0]), abs(y[1] - z[1]))
            dic.append(min_dist)
        output.append(dic)
    return output


def validate_and_build_instance_fleets(parsed_instance_fleets):
    """
    Helper method that converts --instance-fleets option value in
    create-cluster to Amazon Elastic MapReduce InstanceFleetConfig
    data type.
    """
    instance_fleets = []
    for instance_fleet in parsed_instance_fleets:
        instance_fleet_config = {}
        keys = instance_fleet.keys()
        if 'Name' in keys:
            instance_fleet_config['Name'] = instance_fleet['Name']
        else:
            instance_fleet_config['Name'] = instance_fleet['InstanceFleetType']
        instance_fleet_config['InstanceFleetType'] = instance_fleet[
            'InstanceFleetType']
        if 'TargetOnDemandCapacity' in keys:
            instance_fleet_config['TargetOnDemandCapacity'] = instance_fleet[
                'TargetOnDemandCapacity']
        if 'TargetSpotCapacity' in keys:
            instance_fleet_config['TargetSpotCapacity'] = instance_fleet[
                'TargetSpotCapacity']
        if 'InstanceTypeConfigs' in keys:
            if 'TargetSpotCapacity' in keys:
                for instance_type_config in instance_fleet[
                    'InstanceTypeConfigs']:
                    instance_type_config_keys = instance_type_config.keys()
            instance_fleet_config['InstanceTypeConfigs'] = instance_fleet[
                'InstanceTypeConfigs']
        if 'LaunchSpecifications' in keys:
            instanceFleetProvisioningSpecifications = instance_fleet[
                'LaunchSpecifications']
            instance_fleet_config['LaunchSpecifications'] = {}
            if 'SpotSpecification' in instanceFleetProvisioningSpecifications:
                instance_fleet_config['LaunchSpecifications'][
                    'SpotSpecification'
                    ] = instanceFleetProvisioningSpecifications[
                    'SpotSpecification']
        instance_fleets.append(instance_fleet_config)
    return instance_fleets


def items():
    """
        Return list of key, value tuples for user login name, user object.
        """


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

        :param FileTransfersPolicyChangedDetails val:
        :rtype: EventDetails
        """
    return cls('file_transfers_policy_changed_details', val)


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

        :param SharedFolderAccessError val:
        :rtype: ListFolderMembersContinueError
        """
    return cls('access_error', val)


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


@staticmethod
def _json_update(model, **params):
    """Temporary method to update"""
    aqhttp = model.session._AqSession__aqhttp
    data = {'model': {'model': model.__class__.__name__}}
    data.update(model.dump(**params))
    model_data = aqhttp.post('json/save', json_data=data)
    model.reload(model_data)
    return model


@staticmethod
def lowerconfig(config):
    """
        Method that makes all keys in the config dict lowercase. Prevents errors where users supply old
        config style forlogging.
        :param config: Dict containing configuration data
        :return: Returns config dict with all of it's keys in lowercase.
        """
    newconf = {}
    for key in config.keys():
        newconf[key.lower()] = config[key]
    del config
    return newconf


def wsgi_key_of_header_name(header_name):
    """
    >>> wsgi_key_of_header_name('Accept-Language')
    'HTTP_ACCEPT_LANGUAGE'
    >>> wsgi_key_of_header_name('Authorization')
    'HTTP_AUTHORIZATION'

    """
    return 'HTTP_' + header_name.replace('-', '_').upper()


def initIterate(container, generator):
    """Call the function *container* with an iterable as
    its only argument. The iterable must be returned by
    the method or the object *generator*.

    :param container: The type to put in the data from func.
    :param generator: A function returning an iterable (list, tuple, ...),
                      the content of this iterable will fill the container.
    :returns: An instance of the container filled with data from the
              generator.

    This helper function can be used in conjunction with a Toolbox
    to register a generator of filled containers, as individuals or
    population.

        >>> import random
        >>> from functools import partial
        >>> random.seed(42)
        >>> gen_idx = partial(random.sample, list(range(10)), 10)
        >>> initIterate(list, gen_idx)      # doctest: +SKIP
        [1, 0, 4, 9, 6, 5, 8, 2, 3, 7]

    See the :ref:`permutation` and :ref:`arithmetic-expr` tutorials for
    more examples.
    """
    return container(generator())


def _diplay_stats_duration(type_, duration, percent):
    """
    Return a string representing a duration in the stats report.
    """
    return '%s Duration: %s (%2.1f %%)' % (type_, duration, percent)


def dir_actions(obj):
    """ Return list of CAS actionsets / actions associated with the object """
    if hasattr(obj, '__dir_actions__'):
        return obj.__dir_actions__()
    return []


@classmethod
def _fix_function(cls, fn):
    """
        Ensure fn is a classmethod or staticmethod.
        """
    if not isinstance(fn, (classmethod, staticmethod)):
        return classmethod(fn)
    return fn


def path():
    """Return unicode string: URL or empty string"""


def store_in_file(service):
    """Sets ``store_in_file`` attribute to ``True``"""
    service.store_in_file = True
    return service


@staticmethod
def ghetto_encode(obj):
    """
            if everything else failed, try to encode the public obj attributes
            i.e. those attributes without a _ prefix
            :param obj: object to be encoded
            :return: encoded/serizlaized object
        """
    try:
        result = {}
        for k, v in vars(obj).items():
            if not k.startswith('_'):
                if isinstance(v, (int, float)) or v is None:
                    result[k] = v
                else:
                    result[k] = str(v)
    except TypeError:
        result = str(obj)
    return result


def hex2int(hexstr):
    """Convert a hexdecimal string to integer."""
    return int(hexstr, 16)


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

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


@staticmethod
def _add_nullbytes(buffer_str):
    """
        Adds nullbits between letters.

        :param buffer_str:
        :return: string with nullbits

        >>> McdParserBase._add_nullbytes('abc')
        'a\\x00b\\x00c\\x00'
        """
    pad_str = ''
    for s in buffer_str:
        pad_str += s + '\x00'
    return pad_str


def _is_subclass(type_, class_or_tuple):
    """Determine if the type is a subclass of the given class or classes.

    This takes __origin__ classes into consideration and does not raise.

    Args:
        type_: The type that may be a subclass.
        class_or_tuple: A type or a tuple containing multiple types of which
            type_ may be a subclass.

    Returns:
        A boolean indicating whether the given type is a subclass of the
    """
    try:
        return issubclass(type_, class_or_tuple)
    except (TypeError, AttributeError):
        pass
    if hasattr(type_, '__origin__') and type_.__origin__:
        try:
            return issubclass(type_.__origin__, class_or_tuple)
        except (TypeError, AttributeError):
            pass
    return False


def write_kw_prefs(meta_keys):
    """Write all located fcs Parameter keys to text file

    Arg:
        meta_keys: iterable of fcs metadata Parameter keys in order relative to
            location in fcs file text section.

    Returns:
        kw_prefs_filename: name of generated text file
    """
    kw_prefs_filename = 'FCS_USER_KW.txt'
    with open(kw_prefs_filename, 'w') as kw_file:
        for keyword in meta_keys:
            kw_file.write('{}\n'.format(keyword))
    return kw_prefs_filename


def llaves_a_dic(l_ubics, vals):
    """
    Esta función toma una lista de ubicaciones (listas de llaves) y valores correspondientes y genera un diccionario.
    Es el opuesto de `dic_a_lista`.

    :param l_ubics: La lista de ubicaciones de valores.
    :type l_ubics: list[list[str]]
    :param vals: La lista de los valores.
    :type vals: list
    :return: El diccionario reconstruido.
    :rtype: dict
    """
    if len(l_ubics) != len(vals):
        raise ValueError(
            'La lista de ubicaciones debe tener el mismo tamaño que la lista de valores.'
            )
    dic = {}
    for val, l_llvs in zip(vals, l_ubics):
        d = dic
        for i, ll in enumerate(l_llvs):
            if i == len(l_llvs) - 1:
                d[ll] = val
            else:
                if ll not in d:
                    d[ll] = {}
                d = d[ll]
    return dic


@staticmethod
def match_proc(assr_info, auto_proc_list):
    """
        Check if an assessor is a match with the processors

        :param assr_info: dictionary containing the assessor info
                          (See XnatUtils.list_assessors)
        :param auto_proc_list: list of processors running
        :return: processor if found, None otherwise
        """
    for auto_proc in auto_proc_list:
        if auto_proc.xsitype == assr_info['xsiType'
            ] and auto_proc.name == assr_info['proctype']:
            return auto_proc
    return None


@classmethod
def DeregisterDecoder(cls, decoder):
    """Deregisters a decoder for a specific encoding method.

    Args:
      decoder (type): decoder class.

    Raises:
      KeyError: if the corresponding decoder is not set.
    """
    encoding_method = decoder.ENCODING_METHOD.lower()
    if encoding_method not in cls._decoders:
        raise KeyError('Decoder for encoding method: {0:s} not set.'.format
            (decoder.ENCODING_METHOD))
    del cls._decoders[encoding_method]


def setpnumber_connect(postnrid):
    """Add onblur handler that connects the above event handler."""
    return "connect($('%s'), 'onblur', setpnumber);" % postnrid


@classmethod
def handle_configurable_attrs(cls, **kwargs):
    """Handle attributes that can be passed to ``configure``.

        For the parameters, see ``configure``.

        Returns
        -------
        Union[str, None]
            The name passed in ``kwargs``
        dict
            The attrs extracted from kwargs and prepared
        kwargs
            A copy of ``kwargs`` without the handled fields, like ``name`` and the ones extracted.
            The dict must be empty once gone through this method in all the class tree, else
            a ``TypeError`` exception will be raised in ``configure``.

        """
    kwargs = kwargs.copy()
    attrs = {}
    for key in ('prefix', 'handle_uniqueness', 'key'):
        if key in kwargs and key in cls.configurable_attrs:
            attrs[key] = kwargs.pop(key)
    if 'transform' in kwargs:
        attrs['transform'] = staticmethod(kwargs.pop('transform'))
    name = kwargs.pop('name', None)
    return name, attrs, kwargs


def to_spec_brackets(format_spec):
    """Return PEP 3101 format string with format specification.
    """
    if format_spec:
        return '{' + ':' + format_spec + '}'
    return '{}'


def conditional_content_removal(request, response):
    """
    Removes the content of responses for HEAD requests, 1xx, 204 and 304
    responses. Ensures compliance with RFC 2616, section 4.3.
    """
    if 100 <= response.status_code < 200 or response.status_code in (204, 304):
        if response.streaming:
            response.streaming_content = []
        else:
            response.content = ''
        response['Content-Length'] = '0'
    if request.method == 'HEAD':
        if response.streaming:
            response.streaming_content = []
        else:
            response.content = ''
    return response


def wf_run():
    """
    It returns the run number for the current workflow job, normally 0 unless the
    workflow job is re-run, in which case indicates the current run.
    """


def dbh_checklist_2_chf(path, contenttype, extension, roottag, nsurl):
    """ Generic Checklist Handler - Returns checlist for Checklist Files """
    if (extension.lower() == 'chf' or extension.lower() == 'plf'
        ) and nsurl.startswith('http://thermal.cnde.iastate.edu'):
        return 'db_checklist_viewer'
    else:
        return False


def restore_bot_from_backup(backup_filename, *, bot, log):
    """Restores the given bot by executing the 'backup' script.

    The backup file is a python script which manually execute a series of commands on the bot
    to restore it to its previous state.

    :param backup_filename: the full path to the backup script.
    :param bot: the bot instance to restore
    :param log: logger to use during the restoration process
    """
    with open(backup_filename) as f:
        exec(f.read(), {'log': log, 'bot': bot})
    bot.close_storage()


def logical_or(image1, image2):
    """Logical OR between two images. At least one of the images must have
    mode "1".

    .. code-block:: python

        out = ((image1 or image2) % MAX)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_or(image2.im))


def to_dd_type(oc_kind):
    """ to_dd_type takes an OC kind int ID and returns a dd string of the span type

    :type oc_kind: int
    :param oc_kind: OC kind id

    :rtype: string
    :returns: A string of the Span type.
    """
    if oc_kind == 2:
        return 'client'
    elif oc_kind == 1:
        return 'server'
    else:
        return 'unspecified'


@classmethod
def render_paginator_for_es_result(cls, records, total, page=1, limit=10,
    page_len=0, reverse=False):
    """DEPRECATED WILL BE REMOVED DO NOT USE.

    Format an orderedDict ElasticSearch result in paginator object format.

    records: ordered dict (elastic result)
    """
    from .utils import ElasticSearchPaginatorDict
    e = ElasticSearchPaginatorDict(records, total, reverse)
    return cls._render_paginator(e, page, limit, page_len)


def read_mm_stamp(fh, byteorder, dtype, count, offsetsize):
    """Read FluoView mm_stamp tag from file and return as numpy.ndarray."""
    return fh.read_array(byteorder + 'f8', 8)


@staticmethod
def _create_object(_panobject, pandevice_object):
    """Create (non-destructive) the given pandevice_object on the given pandevice
        """
    _panobject.add(pandevice_object)
    pandevice_object.create()


def surround_with_header(string, width, char='-'):
    """
    Surround the string by a header.  The result has length min(len(string)+2, width)
    :param string: A string
    :param width: Width of the entire header
    :param char: Character to repeat
    :return: A header, whose length will be
    """
    left = (width - len(string) - 1) // 2
    right = (width - len(string) - 2) // 2
    return char * left + ' ' + string + ' ' + char * right


def truncate(string: str, max_length: int) ->str:
    """
    Truncate /string/ to at most /max_length/ using an ellipsis.
    max_length must be at least 3.

    >>> truncate("The quick brown fox jumps over the lazy dog.", 10)
    'The qui...'

    >>> truncate("I fit already.", 20)
    'I fit already.'

    >>> truncate("The quick brown fox jumps over the lazy dog.", 2)
    Traceback (most recent call last):
      ...
    AssertionError: max_length must be at least 3...
    """
    assert max_length > 3, 'max_length must be at least 3, as an ellipsis is 3 characters itself'
    if len(string) > max_length:
        string = string[:max_length - 3] + '...'
    return string


@classmethod
def class_print_help(cls, inst=None):
    """Get the help string for a single trait and print it."""
    print(cls.class_get_help(inst))


def wx2Sphinx(name):
    """
    Converts a wxWidgets specific string into a Phoenix-ReST-ready string.

    :param string `name`: any string.
    """
    from etgtools.tweaker_tools import removeWxPrefix
    if '<' in name:
        name = name[0:name.index('<')]
    name = name.strip()
    newname = fullname = removeWxPrefix(name)
    if '.' in newname and len(newname) > 3:
        lookup, remainder = newname.split('.')
        remainder = '.%s' % remainder
    else:
        lookup = newname
        remainder = ''
    from etgtools.item_module_map import ItemModuleMap
    imm = ItemModuleMap()
    if lookup in imm:
        fullname = imm[lookup] + lookup + remainder
    return newname, fullname


def celsius_to_kelvin(celsius):
    """
    Convert Celsius to Kelvin
    """
    return 273.15 + celsius


def valid_roles():
    """Return list of valid roles.
        """


def detect_clause(parser, clause_name, tokens, as_filter_expr=True):
    """Helper function detects a certain clause in tag tokens list.
    Returns its value.

    """
    if clause_name in tokens:
        t_index = tokens.index(clause_name)
        clause_value = tokens[t_index + 1]
        if as_filter_expr:
            clause_value = parser.compile_filter(clause_value)
        del tokens[t_index:t_index + 2]
    else:
        clause_value = None
    return clause_value


@classmethod
def clear(cls):
    """Clear the global list of Peekers."""
    cls._peekers = dict()


def intersect_line_sphere_2d(line_a: 'mathutils.Vector', line_b:
    'mathutils.Vector', sphere_co: 'mathutils.Vector', sphere_radius, clip=True
    ) ->'mathutils.Vector':
    """Takes a line (as 2 points) and a sphere (as a point and a radius) and returns the intersection

    :param line_a: First point of the line
    :type line_a: 'mathutils.Vector'
    :param line_b: Second point of the line
    :type line_b: 'mathutils.Vector'
    :param sphere_co: The center of the sphere
    :type sphere_co: 'mathutils.Vector'
    :param sphere_radius: Radius of the sphere
    :return:  The intersection points as a pair of vectors or None when there is no intersection
    """
    pass


def _displaystr2num(st):
    """Return a display number from a string"""
    num = None
    for s, n in [('DFP-', 16), ('TV-', 8), ('CRT-', 0)]:
        if st.startswith(s):
            try:
                curnum = int(st[len(s):])
                if 0 <= curnum <= 7:
                    num = n + curnum
                    break
            except Exception:
                pass
    if num is not None:
        return num
    else:
        raise ValueError('Unrecognised display name: ' + st)


def setDefaultEditor(context, wanted_editor='', dry_run=False):
    """Use the deault editor for all users."""
    from collective.setdefaulteditor.utils import set_editor_for_all
    set_editor_for_all(wanted_editor, dry_run)


def _parse_vasp_kinter(xml_tree):
    """Extract KINTER from an XML ElementTree representing a vasprun.xml file.
    If this parameter is not present, return 0.
    """
    xml_incar = xml_tree.find('./incar')
    nruter = 0
    for e in xml_incar:
        attribs = e.attrib
        if 'type' in attribs and attribs['type'] == 'int' and attribs['name'
            ] == 'KINTER':
            nruter = int(e.text.strip())
            break
    return nruter


@classmethod
def get(cls, code):
    """
        Returns the IOValue for the given code.

        Args:
            code (Integer): the code corresponding to the IOValue to get.

        Returns:
            :class:`.IOValue`: the IOValue with the given code, ``None`` if there is not any IOValue with that code.
        """
    try:
        return cls.lookupTable[code]
    except KeyError:
        return None


@staticmethod
def generateSaveModel(model=None):
    """
        generateSaveModel builds from the model file a format which could be serialized
        in json. this format will be used for storing model on file

        :param model:
        :return: save model format
        """
    modelDataForSave = list()
    for mPoint in model:
        sPoint = {'name': mPoint.mParam.name, 'path': mPoint.mParam.path,
            'number': mPoint.mParam.number, 'count': mPoint.mParam.count,
            'expTime': mPoint.iParam.expTime, 'binning': mPoint.iParam.
            binning, 'subFrame': mPoint.iParam.subFrame, 'fastReadout':
            mPoint.iParam.fastReadout, 'altitude': mPoint.point.altitude,
            'azimuth': mPoint.point.azimuth, 'raMJNow': mPoint.mData.
            raMJNow.hours, 'decMJNow': mPoint.mData.decMJNow.degrees,
            'raSJNow': mPoint.mData.raSJNow.hours, 'decSJNow': mPoint.mData
            .decSJNow.degrees, 'sidereal': mPoint.mData.sidereal.hours,
            'julian': mPoint.mData.julian.utc_iso(), 'pierside': mPoint.
            mData.pierside, 'errorRMS': mPoint.rData.errorRMS, 'errorRa':
            mPoint.rData.errorRA, 'errorDEC': mPoint.rData.errorDEC}
        modelDataForSave.append(sPoint)
    return modelDataForSave


def tigerxml_end(stream, **params):
    """The end of a tigerxml document, to be completed.
    """
    stream.write(u'</body>\n')
    stream.write(u'</corpus>')


def items():
    """ Return a list of [(k,v)] pairs from the dictionary """


def update_projects():
    """Called when projects may have changed, to refresh the available
        projects"""


def getCurrencyFactor(id=None):
    """returns the factor of the currency"""


def ft_emb(data, i, cols, rel=0, j=0, e=None, *args, **kwargs):
    """Generates features from word embeddings based on the `form` column.

    See links for more details on data resource format:

        http://metaoptimize.com/projects/wordreprs/
        https://code.google.com/p/word2vec/

    GOTCHA: some resources come with separators of 4 space characters
    (replacing a tab?), while the default is a single space.

    :param data: data
    :type data: DataFrame
    :param i: index
    :type i: int
    :param cols: column map
    :type cols: dict
    :param c: clusters
    :type c: dict
    :param rel: relative index
    :type rel: int
    :return: feature string
    :rtype: str
    """
    if 0 <= i + rel < len(data):
        try:
            emb = e[data[i + rel][cols['form']]][j]
        except KeyError:
            emb = None
    else:
        emb = None
    return 'emb[%s][%s]=%s' % (rel, j, emb)


@classmethod
def get_model_title_plural(cls):
    """
        Return a "humanized" (and plural) version of the model name, for
        display in templates.
        """
    if hasattr(cls, 'model_title_plural'):
        return cls.model_title_plural
    try:
        return cls.get_model_class().get_model_title_plural()
    except (NotImplementedError, AttributeError):
        return '{}s'.format(cls.get_model_title())


def _predict_output_python_function(model, input):
    """
    Predict output function for python functions.
    """
    output = model(input)
    return output


def glIndexMask(mask: int):
    """Control the writing of individual bits in the color index buffers

    :param mask: Specifies a bit mask to enable and disable the writing of individual bits in the color index buffers. Initially, the mask is all 1’s.
    :type mask: int
    """
    pass


def set_entry_attribute(entry, attribute, value, overwrite=False):
    """Set an entry attribute."""
    if value and (not getattr(entry, attribute) or overwrite):
        entry = entry._replace(**{attribute: value})
    return entry


def psi_H_Li_ClO4_PK74(T, P):
    """c-c'-a: hydrogen lithium perchlorate [PK74]."""
    psi = -0.0017
    valid = T == 298.15
    return psi, valid


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

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

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


def HiWord(value):
    """Return the high word from a long"""
    return value >> 16 & 65535


def LET(_in, _vars):
    """
    Binds variables for use in the specified expression, and returns the result of the expression.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/let/
    for more details
    :param _in: The expression to evaluate.
    :param _vars: Assignment block for the variables accessible in the in expression.
    :return: Aggregation operator
    """
    return {'$let': {'vars': _vars, 'in': _in}}


@classmethod
def from_geojson(cls, geojson):
    """
        Construct a Workflows FeatureCollection from a GeoJSON mapping.

        Note that the GeoJSON must be relatively small (under 10MiB of serialized JSON).

        Parameters
        ----------
        geojson: Dict

        Returns
        -------
        ~descarteslabs.workflows.FeatureCollection
        """
    try:
        if geojson['type'].lower() != 'featurecollection':
            raise ValueError(
                'Expected a GeoJSON FeatureCollection type, not {!r}'.
                format(geojson['type']))
        return cls._from_apply(cls._constructor, geojson['features'])
    except KeyError:
        raise ValueError(
            "Expected a GeoJSON mapping containing the field 'type' and 'features', but got {}"
            .format(geojson))


def normalize_node_id(nid):
    """Returns a suitable DOT node id for `nid`."""
    return '"%s"' % nid


def dict_strs_to_dict(*dict_strs):
    """
    Parses a list of key:value strings into a dict. Used to go from CLI->Python.
    """
    d = {}
    for dict_str in dict_strs:
        try:
            k, v = dict_str.split(':', 1)
        except ValueError:
            raise ValueError(
                "can't parse string '{0}': must have format 'key:value'".
                format(dict_str))
        d[k] = v
    return d


def convert_prefix_forced_case(data, prefix):
    """If <prefix> is a prefix of data, case insensitive, then force its case

    This converter forces the case of a given prefix of a string.

    Example, with prefix="Foo":
    * 'foobar' converted into 'Foobar'
    * 'fOozar' converted into 'Foozar'
    * 'FOObaz' converted into 'Foobaz'

    :param data: The data to convert
    :returns: if data is a string starting with <prefix> in a case insensitive
              comparison, then the return value is data with this prefix
              replaced by <prefix>
    """
    plen = len(prefix)
    if isinstance(data, str) and len(data) >= plen and data[0:plen].lower(
        ) == prefix.lower():
        return prefix + data[plen:]
    return data


def getcapabilities():
    """Make a request to the WMS, returns an XML document wrapped in a
        Python file object."""


def exportText_single_pages(pages, base_path=''):
    """Function that exports the text of
    pages in separated files"""
    pf = open(base_path + '/pages.txt', 'w')
    for page in pages.values():
        pf.write('# [[' + page.url + ']]\n')
        if not page.collapsed:
            if page.text != '':
                text = []
                text.append('##########')
                text.append("'''" + page.url + "'''")
                text.append(page.text)
                text.append('@@@@@@@@@@')
                path = base_path + '/' + page.title + '.txt'
                path = path.encode('utf-8')
                f = open(path, 'w')
                f.write('\n'.join(text))
                f.close()
    pf.close()


def p_expression_comment_text(p):
    """comment_text : comment_text CTEXT
                    | comment_text fwsp
                    | CTEXT
                    | fwsp"""
    p[0] = ''.join(p[1:])


def p_enum_constant_list_1(t):
    """enum_constant_list : enum_constant"""
    t[0] = t[1]


def extract_envars(raw):
    """
    Returns a list of environment variables given a string containing
    NAME=VALUE definitions on separate lines.
    """
    result = []
    for line in raw.split('\n'):
        definition = line.split('=', 1)
        if len(definition) == 2:
            result.append([definition[0].strip(), definition[1].strip()])
    return result


def _weave_conflicting_selectors(prefixes, a, b, suffix=()):
    """Part of the selector merge algorithm above.  Not useful on its own.  Pay
    no attention to the man behind the curtain.
    """
    both = a and b
    for prefix in prefixes:
        yield prefix + a + b + suffix
        if both:
            yield prefix + b + a + suffix


def create_vpc(DryRun=None, CidrBlock=None, InstanceTenancy=None,
    AmazonProvidedIpv6CidrBlock=None):
    """
    Creates a VPC with the specified IPv4 CIDR block. The smallest VPC you can create uses a /28 netmask (16 IPv4 addresses), and the largest uses a /16 netmask (65,536 IPv4 addresses). To help you decide how big to make your VPC, see Your VPC and Subnets in the Amazon Virtual Private Cloud User Guide .
    You can optionally request an Amazon-provided IPv6 CIDR block for the VPC. The IPv6 CIDR block uses a /56 prefix length, and is allocated from Amazon's pool of IPv6 addresses. You cannot choose the IPv6 range for your VPC.
    By default, each instance you launch in the VPC has the default DHCP options, which includes only a default DNS server that we provide (AmazonProvidedDNS). For more information about DHCP options, see DHCP Options Sets in the Amazon Virtual Private Cloud User Guide .
    You can specify the instance tenancy value for the VPC when you create it. You can't change this value for the VPC after you create it. For more information, see Dedicated Instances in the Amazon Elastic Compute Cloud User Guide .
    See also: AWS API Documentation

    Examples
    This example creates a VPC with the specified CIDR block.
    Expected Output:

    :example: response = client.create_vpc(
        DryRun=True|False,
        CidrBlock='string',
        InstanceTenancy='default'|'dedicated'|'host',
        AmazonProvidedIpv6CidrBlock=True|False
    )

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

    :type CidrBlock: string
    :param CidrBlock: [REQUIRED]
            The IPv4 network range for the VPC, in CIDR notation. For example, 10.0.0.0/16 .

    :type InstanceTenancy: string
    :param InstanceTenancy: The tenancy options for instances launched into the VPC. For default , instances are launched with shared tenancy by default. You can launch instances with any tenancy into a shared tenancy VPC. For dedicated , instances are launched as dedicated tenancy instances by default. You can only launch instances with a tenancy of dedicated or host into a dedicated tenancy VPC.
            Important: The host value cannot be used with this parameter. Use the default or dedicated values only.
            Default: default

    :type AmazonProvidedIpv6CidrBlock: boolean
    :param AmazonProvidedIpv6CidrBlock: Requests an Amazon-provided IPv6 CIDR block with a /56 prefix length for the VPC. You cannot specify the range of IP addresses, or the size of the CIDR block.

    :rtype: dict
    :return: {
        'Vpc': {
            'VpcId': 'string',
            'State': 'pending'|'available',
            'CidrBlock': 'string',
            'DhcpOptionsId': 'string',
            'Tags': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ],
            'InstanceTenancy': 'default'|'dedicated'|'host',
            'IsDefault': True|False,
            'Ipv6CidrBlockAssociationSet': [
                {
                    'Ipv6CidrBlock': 'string',
                    'Ipv6CidrBlockState': {
                        'State': 'associating'|'associated'|'disassociating'|'disassociated'|'failing'|'failed',
                        'StatusMessage': 'string'
                    },
                    'AssociationId': 'string'
                },
            ]
        }
    }

    """
    pass


def order_new_success(message, futures):
    """Intercepts order new (on) messages and check for Future objets with
    a matching cid.

    Parameters
    ----------
    message : str
        The unaltered response message returned by bitfinex.
    futures : dict
        A dict of intercept_id's and future objects.
        dict{intercept_id, future_object}

    """
    order_cid = message[2][2]
    future_id = f'on_{order_cid}'
    future = futures[future_id]
    future.set_result({'status': 'SUCCESS', 'id': message[2][0], 'cid':
        order_cid, 'response': message[2], 'comment': None})
    del futures[future_id]


@classmethod
def fromflat(cls, flat):
    """
        Create an instance of this from new logits values

        :param flat: ([float]) the categorical logits input
        :return: (ProbabilityDistribution) the instance from the given categorical input
        """
    return cls(flat)


def enable_metrics_collection(AutoScalingGroupName=None, Metrics=None,
    Granularity=None):
    """
    Enables group metrics for the specified Auto Scaling group. For more information, see Monitoring Your Auto Scaling Groups and Instances in the Auto Scaling User Guide .
    See also: AWS API Documentation

    Examples
    This example enables data collection for the specified Auto Scaling group.
    Expected Output:

    :example: response = client.enable_metrics_collection(
        AutoScalingGroupName='string',
        Metrics=[
            'string',
        ],
        Granularity='string'
    )

    :type AutoScalingGroupName: string
    :param AutoScalingGroupName: [REQUIRED]
            The name or ARN of the Auto Scaling group.

    :type Metrics: list
    :param Metrics: One or more of the following metrics. If you omit this parameter, all metrics are enabled.
            GroupMinSize
            GroupMaxSize
            GroupDesiredCapacity
            GroupInServiceInstances
            GroupPendingInstances
            GroupStandbyInstances
            GroupTerminatingInstances
            GroupTotalInstances
            (string) --

    :type Granularity: string
    :param Granularity: [REQUIRED]
            The granularity to associate with the metrics to collect. The only valid value is 1Minute .

    :return: response = client.enable_metrics_collection(
        AutoScalingGroupName='my-auto-scaling-group',
        Granularity='1Minute',
    )

    print(response)

    """
    pass


def is_datetime_inf_or_equal(date_ref, date_comp):
    """
        Compare if date_ref <= date_comp

        Compare efficiently if date_ref <= date_comp. The date_comp is duplicated to allow the
        chaining function: is datetime_inf_or_equal(a, b), datetime_inf_or_equal(b, c) ...

        :param date_ref: Reference date, format: [Year, Month, Day, Hour, Minute, Second]
        :param date_comp: Compare date, format: [Year, Month, Day, Hour, Minute, Second]
        :return: True if date_ref <= date_comp, False if date_ref > date_comp
    """
    i = 0
    while date_ref[i] == date_comp[i] and i != 4:
        i += 1
    if date_ref[i] < date_comp[i] or i == 4:
        return True
    return False


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 generate_cubes_lookup(raw_cubes):
    """
    Generates a map of {field_id: cubes_list} for use in generating
    tap metadata for the catalog.
    """
    cubes_lookup = {}
    for raw_cube, fields in raw_cubes.items():
        for field in fields:
            if field not in cubes_lookup:
                cubes_lookup[field] = set()
            cubes_lookup[field].add(raw_cube)
    return cubes_lookup


def create_request_url(url: str, params: dict=None):
    """
    Adds query params to the given url

    :param url: the url to extend
    :param params: query params as a keyed dictionary
    :return: the url including the given query params
    """
    if params:
        first_param = True
        for k, v in sorted(params.items(), key=lambda entry: entry[0]):
            if not v:
                continue
            if first_param:
                url += '?'
                first_param = False
            else:
                url += '&'
            url += '%s=%s' % (k, v)
    return url


def _strToBool(v):
    """The built-in conversion to boolean is way too lax. The xsd specification requires that only true, false, 1 or 0 should be used...
    @param v: the literal string defined as boolean
    @return corresponding boolean value
    @raise ValueError: invalid boolean values
    """
    if v.lower() == 'true' or v.lower() == '1':
        return True
    elif v.lower() == 'false' or v.lower() == '0':
        return False
    else:
        raise ValueError('Invalid boolean literal value %s' % v)


def e_value_normalizer(e_value_raw, k, n_celltypes):
    """
    Normalizes the e-value due to disparity in number of celltypes

    :param e_value_raw: value to normalize
    :param int k: number of rows, in practice it's the number of regulatory elements that give the VEnCode.
    :param int n_celltypes: Number of celltypes in the data (columns)
    :return: normalized e-value
    """
    coefs = {'a': -164054.1, 'b': 0.9998811, 'c': 6.088948e-06, 'd':
        1.00051, 'm': 0.9527, 'e': -0.1131}
    e_value_expected = (coefs['m'] * k + coefs['e']) * n_celltypes ** (coefs
        ['d'] + (coefs['a'] - coefs['d']) / (1 + (k / coefs['c']) ** coefs[
        'b']))
    e_value_norm = e_value_raw / e_value_expected * 100
    if e_value_norm < 100:
        return e_value_norm
    else:
        return 100


def recipe_og(recipe):
    """Returns a recipe's Original Gravity"""
    if 'fermentables' not in recipe:
        return '0.000'
    points = 0
    grain_points = 0
    for fermentable in recipe['fermentables']:
        if fermentable['type'] == 'Grain':
            grain_points += float(fermentable['amount']) * float(fermentable
                ['ppg'])
        else:
            points += float(fermentable['amount']) * float(fermentable['ppg'])
    points += grain_points * float(recipe['efficiency']) / 100
    return '{:.3f}'.format(round(1 + points / (1000 * float(recipe['volume'
        ])), 3))


def add_subfig_label(ax, label, size=14):
    """ Adds a subplot label to an axis."""
    ax.text(-0.1, 1, label, transform=ax.transAxes, fontsize=size,
        fontweight='bold', va='top', ha='right')
    return ax


@classmethod
def make_middleware(cls, app, **options):
    """Creates the application WSGI middleware in charge of serving local files.

        A Depot middleware is required if your application wants to serve files from
        storages that don't directly provide and HTTP interface like
        :class:`depot.io.local.LocalFileStorage` and :class:`depot.io.gridfs.GridFSStorage`

        """
    from depot.middleware import DepotMiddleware
    mw = DepotMiddleware(app, **options)
    cls.set_middleware(mw)
    return mw


def patch_click() ->None:
    """Make Click not crash.

    On certain misconfigured environments, Python 3 selects the ASCII encoding as the
    default which restricts paths that it can access during the lifetime of the
    application.  Click refuses to work in this scenario by raising a RuntimeError.

    In case of Black the likelihood that non-ASCII characters are going to be used in
    file paths is minimal since it's Python source code.  Moreover, this crash was
    spurious on Python 3.7 thanks to PEP 538 and PEP 540.
    """
    try:
        from click import core
        from click import _unicodefun
    except ModuleNotFoundError:
        return
    for module in (core, _unicodefun):
        if hasattr(module, '_verify_python3_env'):
            module._verify_python3_env = lambda : None


def dict_diff(dict_a, dict_b):
    """
    Performs an elementwise subtraction of dict_b from dict_a
    """
    diff_dict = {}
    a = set(dict_a.keys())
    b = set(dict_b.keys())
    a_only = a.difference(b)
    b_only = b.difference(a)
    common = a.intersection(b)
    for k in a_only:
        diff_dict[k] = dict_a[k]
    for k in b_only:
        diff_dict[k] = -dict_b[k]
    for k in common:
        diff_dict[k] = dict_a[k] - dict_b[k]
    return diff_dict


def area_move(x: int=0, y: int=0, delta: int=0):
    """Move selected area edges

    :param x: X
    :type x: int
    :param y: Y
    :type y: int
    :param delta: Delta
    :type delta: int
    """
    pass


def lat_lon_region(lower_left_corner_latitude, lower_left_corner_longitude,
    upper_right_corner_latitude, upper_right_corner_longitude):
    """
    Converts a geographical region with lower left corner
    and upper right corner into a Basemap compatible structure.

    :param lower_left_corner_latitude:
        The latitude of the lower left corner.
    :param lower_left_corner_longitude:
        The longitude of the lower left corner.
    :param upper_right_corner_latitude:
        The latitude of the lower left corner.
    :param upper_right_corner_longitude:
        The longitude of the lower left corner.

    :return: A dict with the keys ``llcrnrlat``, ``llcrnrlon``,
             ``urcrnrlat``, and ``urcrnrlon``.
    """
    return {'llcrnrlat': lower_left_corner_latitude, 'llcrnrlon':
        lower_left_corner_longitude, 'urcrnrlat':
        upper_right_corner_latitude, 'urcrnrlon': upper_right_corner_longitude}


def listPersons():
    """Sorted list of all persons incl. external ones as strings."""


def decode(string, encoding='utf-8'):
    """Decode string if it is a bytes instance."""
    if isinstance(string, bytes):
        return string.decode(encoding)
    return string


def get_environ(environ):
    """
    Returns our whitelisted environment variables.
    """
    for key in ('REMOTE_ADDR', 'SERVER_NAME', 'SERVER_PORT'):
        if key in environ:
            yield key, environ[key]


@classmethod
def _parse_value(cls, stream_rdr, offset, value_count, value_offset):
    "\n        Return the ASCII string parsed from *stream_rdr* at *value_offset*.\n        The length of the string, including a terminating '\x00' (NUL)\n        character, is in *value_count*.\n        "
    return stream_rdr.read_str(value_count - 1, value_offset)


def pytest_addoption(parser):
    """
    Add CLI options to py.test
    """
    group = parser.getgroup('tempdir', 'Temporary Directory Options')
    group.addoption('--tempdir-basename', default=None, help=
        'The predictable temporary directory base name. Defaults to the current directory name if not passed as a CLI parameter and if not defined using the tempdir_basename session scoped fixture. If the temporary directory exists when the test session starts, IT WILL BE WIPED!'
        )
    group.addoption('--tempdir-no-clean', default=False, action=
        'store_true', help=
        'Disable the removal of the created temporary directory')


def _default_key_normalizer(key_class, request_context):
    """
    Create a pool key out of a request context dictionary.

    According to RFC 3986, both the scheme and host are case-insensitive.
    Therefore, this function normalizes both before constructing the pool
    key for an HTTPS request. If you wish to change this behaviour, provide
    alternate callables to ``key_fn_by_scheme``.

    :param key_class:
        The class to use when constructing the key. This should be a namedtuple
        with the ``scheme`` and ``host`` keys at a minimum.
    :type  key_class: namedtuple
    :param request_context:
        A dictionary-like object that contain the context for a request.
    :type  request_context: dict

    :return: A namedtuple that can be used as a connection pool key.
    :rtype:  PoolKey
    """
    context = request_context.copy()
    context['scheme'] = context['scheme'].lower()
    context['host'] = context['host'].lower()
    for key in ('headers', '_proxy_headers', '_socks_options'):
        if key in context and context[key] is not None:
            context[key] = frozenset(context[key].items())
    socket_opts = context.get('socket_options')
    if socket_opts is not None:
        context['socket_options'] = tuple(socket_opts)
    for key in list(context.keys()):
        context['key_' + key] = context.pop(key)
    for field in key_class._fields:
        if field not in context:
            context[field] = None
    return key_class(**context)


def pytest_instrument_labels(config, labels):
    """Called in pytest_runtest_setup(item) after collecting labels from @pytest.mark.instrument"""


def common_prefix(string_list):
    """Return the common prefix of a list of strings

    TODO: move it into utils package

    :param list(str) string_list: List of strings
    :rtype: str
    """
    prefix = ''
    for ch in zip(string_list):
        c = ch[0]
        good = True
        for i in ch:
            if i != c:
                good = False
                break
        if good:
            prefix += c
        else:
            break
    return prefix


def rosetta_query(key, rosetta, output_cls_instance):
    """
    Return the highest-priority value
    """
    if isinstance(rosetta[key], list):
        for num, count in enumerate(rosetta[key]):
            temp_val = None
            temp_key = None
            try:
                if isinstance(count, str):
                    if count == '!':
                        temp_key = key
                        temp_val = rosetta[key][num + 1]
                        print('Using default meta_configs value for: {}'.
                            format(key))
                        break
                    else:
                        temp_key = count
                        temp_val = output_cls_instance._meta[temp_key]
                        break
                else:
                    pass
            except:
                temp_val = None
                temp_key = None
        if temp_val is not None:
            return temp_val, temp_key
        else:
            return None
    elif isinstance(rosetta[key], str):
        try:
            temp = output_cls_instance._meta[rosetta[key]]
        except:
            return None
        else:
            return temp, rosetta[key]
    else:
        return None


def getWrappedOwner():
    """Get the owner, modestly wrapped in the user folder.

        o If the object is not owned, return None.

        o If the owner's user database doesn't exist, return Nobody.

        o If the owner ID does not exist in the user database, return Nobody.
        """


@classmethod
def header_prevhash(cls, header):
    """Given a header return previous hash"""
    return header[4:36]


@staticmethod
def flatten(fields):
    """Returns a list which is a single level of flattening of the
        original list."""
    flat = []
    for field in fields:
        if isinstance(field, (list, tuple)):
            flat.extend(field)
        else:
            flat.append(field)
    return flat


def _get_country(node):
    """
    Get the country where the checklist was recorded.

    :param node: the Tag for the body of the Location section.

    :return: the two-letter ISO 8601 code doe the country.

    """
    tag = node.find('h5', class_='obs-loc')
    location = tag.text.split('( Map )')[0]
    country = location.split(',')[-1].strip()[:2]
    return country


def tune_axes(axes):
    """
    BlueSky plan to tune a list of axes in sequence

    EXAMPLE

    Sequentially, tune a list of preconfigured axes::

        RE(tune_axes([mr, m2r, ar, a2r])

    SEE ALSO

    .. autosummary::

       ~TuneAxis
    """
    for axis in axes:
        yield from axis.tune()


def compatibility_layer(spec):
    """Make specs compatible with older versions of Connexion."""
    if not isinstance(spec, dict):
        return spec
    for path_name, methods_available in spec.get('paths', {}).items():
        for method_name, method_def in methods_available.items():
            if method_name == 'parameters' or not isinstance(method_def, dict):
                continue
            response_definitions = {}
            for response_code, response_def in method_def.get('responses', {}
                ).items():
                response_definitions[str(response_code)] = response_def
            method_def['responses'] = response_definitions
    return spec


def stringLine(line, length):
    """simple case: line with just strings and spacings which can be ignored"""
    strings = []
    for x in line:
        if isinstance(x, str):
            strings.append(x)
    text = ' '.join(strings)
    result = [text, float(length)]
    nextlinemark = 'nextLine', 0
    if line and line[-1] == nextlinemark:
        result.append(nextlinemark)
    return result


def _hdf5_yt_array_lite(fh, field):
    """
    Read an hdf5 dataset.  If that dataset has a "units" attribute,
    return that as well, but do not cast as a YTArray.
    """
    units = ''
    if 'units' in fh[field].attrs:
        units = fh[field].attrs['units']
    if units == 'dimensionless':
        units = ''
    return fh[field][()], units


def _merge_fields_and_pk(pk, fields):
    """
    Tweaked variant of DRF's model_meta function to accommodate for
    abstract models

    Used by EmbeddedModelFields and EmbeddedModelSerializers
    """
    fields_and_pk = {}
    fields_and_pk['pk'] = pk
    if pk is not None:
        fields_and_pk[pk.name] = pk
    fields_and_pk.update(fields)
    return fields_and_pk


def before_transition(state, newstate, transition_id, content, **kw):
    """
        Hook method to be overridden by subclasses (or injected
        directly onto an instance) to allow for before transition
        actions (such as firing an event).

        Raise an exception here to abort the transition.
        """


def _build_locale_table(filename_or_file):
    """
    Parses the FacebookLocales.xml file and builds a dict relating every
    available language ('en, 'es, 'zh', ...) with a list of available regions
    for that language ('en' -> 'US', 'EN') and an (arbitrary) default region.
    """
    from xml.dom.minidom import parse
    dom = parse(filename_or_file)
    reps = dom.getElementsByTagName('representation')
    locs = map(lambda r: r.childNodes[0].data, reps)
    locale_map = {}
    for loc in locs:
        lang, _, reg = loc.partition('_')
        lang_map = locale_map.setdefault(lang, {'regs': [], 'default': reg})
        lang_map['regs'].append(reg)
    locale_map['en']['default'] = 'US'
    locale_map['es']['default'] = 'LA'
    locale_map['zh']['default'] = 'CN'
    locale_map['fr']['default'] = 'FR'
    locale_map['pt']['default'] = 'PT'
    return locale_map


def date_iso_format(value):
    """
    Serialise a datetime.date to ISO string format.
    """
    return value.isoformat()


@classmethod
def make_separator(cls, value):
    """Create a separator token"""
    assert value in (',', ';')
    subtype = cls.ARG if value == ',' else cls.ROW
    return cls(value, cls.SEP, subtype)


def is_aware(value):
    """
    Determines if a given datetime.datetime is aware.
    The logic is described in Python's docs:
    http://docs.python.org/library/datetime.html#datetime.tzinfo
    """
    return value.tzinfo is not None and value.tzinfo.utcoffset(value
        ) is not None


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

        :param DeviceApprovalsRemoveExceptionDetails val:
        :rtype: EventDetails
        """
    return cls('device_approvals_remove_exception_details', val)


def update_manager(module, array):
    """Update SNMP Manager"""
    changed = True
    if not module.check_mode:
        try:
            mgr = array.get_snmp_manager(module.params['name'])
        except Exception:
            module.fail_json(msg=
                'Failed to get current configuration for SNMP manager {0}.'
                .format(module.params['name']))
        if mgr['version'] != module.params['version']:
            module.fail_json(msg=
                'Changing an SNMP managers version is not supported.')
        elif module.params['version'] == 'v2c':
            try:
                array.set_snmp_manager(module.params['name'], community=
                    module.params['community'], notification=module.params[
                    'notification'], host=module.params['host'])
            except Exception:
                module.fail_json(msg='Failed to update SNMP manager {0}.'.
                    format(module.params['name']))
        elif module.params['auth_protocol'] and module.params[
            'privacy_protocol']:
            try:
                array.set_snmp_manager(module.params['name'],
                    auth_passphrase=module.params['auth_passphrase'],
                    auth_protocol=module.params['auth_protocol'],
                    privacy_passphrase=module.params['privacy_passphrase'],
                    privacy_protocol=module.params['privacy_protocol'],
                    notification=module.params['notification'], user=module
                    .params['user'], host=module.params['host'])
            except Exception:
                module.fail_json(msg='Failed to update SNMP manager {0}.'.
                    format(module.params['name']))
        elif module.params['auth_protocol'] and not module.params[
            'privacy_protocol']:
            try:
                array.set_snmp_manager(module.params['name'], version=
                    module.params['version'], auth_passphrase=module.params
                    ['auth_passphrase'], auth_protocol=module.params[
                    'auth_protocol'], notification=module.params[
                    'notification'], user=module.params['user'], host=
                    module.params['host'])
            except Exception:
                module.fail_json(msg='Failed to update SNMP manager {0}.'.
                    format(module.params['name']))
        elif not module.params['auth_protocol'] and module.params[
            'privacy_protocol']:
            try:
                array.set_snmp_manager(module.params['name'], version=
                    module.params['version'], privacy_passphrase=module.
                    params['privacy_passphrase'], privacy_protocol=module.
                    params['privacy_protocol'], notification=module.params[
                    'notification'], user=module.params['user'], host=
                    module.params['host'])
            except Exception:
                module.fail_json(msg='Failed to update SNMP manager {0}.'.
                    format(module.params['name']))
        elif not module.params['auth_protocol'] and not module.params[
            'privacy_protocol']:
            try:
                array.set_snmp_manager(module.params['name'], version=
                    module.params['version'], notification=module.params[
                    'notification'], user=module.params['user'], host=
                    module.params['host'])
            except Exception:
                module.fail_json(msg='Failed to update SNMP manager {0}.'.
                    format(module.params['name']))
        else:
            module.fail_json(msg=
                'Invalid parameters selected in update. Please raise issue in Ansible GitHub'
                )
    module.exit_json(changed=changed)


def get_neighborhood_edge(G, e, h):
    """
    Given an edge and a height/depth to
    traverse, find the neighborhood as defined in the CONGA
    paper.
    """
    neigh = set(G.neighborhood(e[0], order=h - 1))
    neigh.update(G.neighborhood(e[1], order=h - 1))
    return list(neigh)


@classmethod
def RegisterPlugins(cls, plugin_classes):
    """Registers plugin classes.

    The plugin classes are identified based on their lower case name.

    Args:
      plugin_classes (list[type]): a list of class objects of the plugins.

    Raises:
      KeyError: if plugin class is already set for the corresponding name.
    """
    for plugin_class in plugin_classes:
        cls.RegisterPlugin(plugin_class)


@classmethod
def record_id(cls, event, stamp):
    """
        Return a string suitable for use as the document id.

        :param event: A event identifier
        :param stamp: Datetime for this event
        :type event: str
        :type stamp: datetime.datetime

        """
    period = cls._period(stamp)
    info = {'event': event, 'year': period.year, 'month': period.month,
        'day': period.day, 'hour': period.hour, 'minute': period.minute}
    return cls.config_id_format % info


def save_dicom(data_set):
    """Helper function for the Save Worker/Thread"""
    data_set.save_to_file()


def gapup(f):
    """Determine whether or not there has been a gap up.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe with columns ``open`` and ``close``.

    Returns
    -------
    new_column : pandas.Series (bool)
        The array containing the new feature.

    References
    ----------
    *A gap is a break between prices on a chart that occurs when the
    price of a stock makes a sharp move up or down with no trading
    occurring in between* [IP_GAP]_.

    """
    new_column = f['open'] > f['close'].shift(1)
    return new_column


def load_Numeric(finder, module):
    """the Numeric module optionally loads the dotblas module; ignore the error
       if this modules does not exist."""
    module.IgnoreName('dotblas')


@classmethod
def get_name(cls, name_or_numeric):
    """ Get Enum.Value name matching the value argument.
        :param name_or_numeric: Integer value or attribute name
        :return: The name or None if not found
        """
    value = cls.get(name_or_numeric)
    if value is not None:
        return value.name
    return None


def check_for_label_presence(card, tags):
    """Take in a comma-sep list of tag names, and ensure that
    each is on this card"""
    if card['idLabels']:
        user_tags = set(tags.split(','))
        card_tags = set(card['_labels'])
        return user_tags.issubset(card_tags)
    else:
        return False


def _backtrack(matrix):
    """
    This generator backtracks through the matrix created by _build_lcs_matrix
    and yields each item of ONE of the possible largest common subsequences
    (LCS) from seq1 and seq2. Each item is a tuple of the form (i, j) It starts
    at the bottom right corner of the matrix and works backwards up to the top
    left.

    This is an interpretation of the algorithm presented on
    https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
    It has been generalised so that it works with lists rather than strings.
    It also uses while loop rather than recursion.
    """
    j = len(matrix) - 1
    i = len(matrix[0]) - 1
    while i > 0 and j > 0:
        current = matrix[j][i]
        up = matrix[j - 1][i]
        left = matrix[j][i - 1]
        if current == left:
            i -= 1
        elif current == up:
            j -= 1
        else:
            i -= 1
            j -= 1
            yield i, j


def md_alignment(alignment):
    """Given alignment option, return corresponding markdown"""
    if alignment == '<':
        return ':', '-'
    elif alignment == '>':
        return '-', ':'
    else:
        return '-', '-'


def join_words(words, separator, max_length=None):
    """
    words - iterator or list
    """
    if not max_length:
        return separator.join(words)
    words = iter(words)
    try:
        text = next(words)
    except StopIteration:
        return u''
    for word in words:
        if len(text + separator + word) <= max_length:
            text += separator + word
    return text[:max_length]


def _chunk_write(chunk, local_file, progress):
    """Write a chunk to file and update the progress bar."""
    local_file.write(chunk)
    if progress is not None:
        progress.update(len(chunk))


def _iterate_axial_slices(array, limits=None):
    """Iterate axial slices."""
    shape = array.shape[1]
    for ind in range(shape):
        if limits and ind not in limits:
            continue
        yield ind, array[:, (ind), :]


def psi_H_Cl_HSO4_HMW84(T, P):
    """c-a-a': hydrogen chloride bisulfate [HMW84]."""
    psi = 0.013
    valid = T == 298.15
    return psi, valid


def remove_axis_junk(ax, which=['right', 'top']):
    """
    Remove axis lines from axes object that exist in list which.

    Parameters
    ----------
    ax : `matplotlib.axes.AxesSubplot` object
    which : list of str
        Entries in ['right', 'top', 'bottom', 'left'].

    Returns
    -------
    None

    """
    for loc, spine in ax.spines.items():
        if loc in which:
            spine.set_color('none')
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')


@classmethod
def check_return(cls, done):
    """
        Check DLL-API exit code for errors and raise exception.

        :param int done: exit code of an DLL function
        :raises RuntimeError: if the exit code is a known error code != 0
        :raises ValueError: if the exit code is unknown
        """
    if 0 < done and done < len(cls.error_messages):
        raise RuntimeError(cls.error_messages[done])
    elif done != 0:
        raise ValueError('Unknown error: %i' % done)


@staticmethod
def validate(value):
    """Validate and convert the input to a ListType.

        :param value: A comma separated string of values
        :returns: A list of unique values (lower-cased), maintaining the
                  same order
        """
    items = []
    for v in str(value).split(','):
        v_norm = v.strip().lower()
        if v_norm and v_norm not in items:
            items.append(v_norm)
    return items


@classmethod
def get(cls):
    """Get values gathered from the previously set hierarchy.

        Respects the order in which sources are set, the first source set
        has the highest priority, overrides values with the same key that
        exist in sources with lower priority.

        Returns:
            dict: The dictionary containing values gathered from all set sources.
        """
    results = {}
    hierarchy = cls.__hierarchy
    hierarchy.reverse()
    for storeMethod in hierarchy:
        cls.merger.merge(results, storeMethod.get())
    return results


def getPassword():
    """
        Return the HTTP password sent with this request, if any.

        If no password was supplied, return the empty string.

        @returns: the HTTP password, if any
        @rtype: C{str}
        """


def get_class_name(obj):
    """
    Dunders in python are ugly, this gets the class name of an object
    """
    return obj.__class__.__name__


def inique(iterable):
    """ Generate unique elements from `iterable`

    Parameters
    ----------
    iterable : iterable

    Returns
    -------
    gen : generator
       generator that yields unique elements from `iterable`

    Examples
    --------
    >>> tuple(inique([0, 1, 2, 0, 2, 3]))
    (0, 1, 2, 3)
    """
    history = []
    for val in iterable:
        if val not in history:
            history.append(val)
            yield val


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

        :param NoteAclTeamLinkDetails val:
        :rtype: EventDetails
        """
    return cls('note_acl_team_link_details', val)


def pow_3_of(number):
    """
    cube input number
    helper function from lalsimulation/src/LALSimIMRPhenomD_internals.h
    """
    return number * number * number


def add_history_trace(dframe, vector, line_shape):
    """Renders the history line"""
    df = dframe.loc[(dframe['REAL'] == dframe['REAL'].unique()[0]) & (
        dframe['ENSEMBLE'] == dframe['ENSEMBLE'].unique()[0])]
    return {'line': {'shape': line_shape}, 'x': df['DATE'], 'y': df[vector],
        'hovertext': 'History', 'hoverinfo': 'y+x+text', 'name': 'History',
        'marker': {'color': 'black'}, 'showlegend': True}


def aspect(fontid: int, aspect: float):
    """Set the aspect for drawing text.

    :param fontid: The id of the typeface as returned by blf.load(), for default font use 0.
    :type fontid: int
    :param aspect: The aspect ratio for text drawing to use.
    :type aspect: float
    """
    pass


def iso_to_plotly_time_string(iso_string):
    """Remove timezone info and replace 'T' delimeter with ' ' (ws)."""
    if iso_string.split('-')[:3] == '00:00' or iso_string.split('+')[0
        ] == '00:00':
        raise Exception(
            """Plotly won't accept timestrings with timezone info.
All timestrings are assumed to be in UTC."""
            )
    iso_string = iso_string.replace('-00:00', '').replace('+00:00', '')
    if iso_string.endswith('T00:00:00'):
        return iso_string.replace('T00:00:00', '')
    else:
        return iso_string.replace('T', ' ')


def quote(path):
    """ Return a path with quotes added if it contains spaces.  path is the
    path.
    """
    if ' ' in path:
        path = '"%s"' % path
    return path


@classmethod
def from_char(cls, char, **kwargs):
    """Creates a key from a character.

        :param str char: The character.

        :return: a key code
        """
    return cls(char=char, **kwargs)


def _truncate_decimal(num, precision):
    """To avoid coordinates whose precision greatly exceeds their accuracy."""
    return int(num * 10 ** precision) / 10 ** precision


def pause():
    """
    overpython.pause()

    Will ask the user to press ENTER key and exits with code 64.
    overpython.returnf(0) will also do the same exact function.
    """
    print('Press the ENTER key to exit...')
    input()
    exit(64)


def _authenticate(cls, auth_url):
    """Authenticate against the Rackspace auth service."""
    body = {'auth': {'RAX-KSKEY:apiKeyCredentials': {'username': cls.user,
        'apiKey': cls.password}}}
    return cls._authenticate(auth_url, body)


def iter_by(iterable, count):
    """
    Returns a generator which will yield certain elements of the iterable. This elements are defined
    by the count steps
    for obj in iter_by(range(7), 3):
        print(obj)
    [0, 1, 2]
    [3, 4, 5]
    [6]
    :param iterable: iterable
    :param count: int, num of
    :return: generator
    """
    i = iter(iterable)
    while True:
        to_yield = list()
        try:
            for n in range(count):
                to_yield.append(i.next())
                yield to_yield
        except StopIteration:
            if to_yield:
                yield to_yield
            break


def keras_clip(optimizer):
    """ Convenience function for creating kwargs for setting Keras gradient
		clipping.
	"""
    if optimizer.clip_type is None:
        return {}
    elif optimizer.clip_type == 'norm':
        return {'clipnorm': optimizer.clip_value}
    elif optimizer.clip_type == 'abs':
        return {'clipvalue': optimizer.clip_value}
    else:
        raise ValueError('Unhandled clip type: {}. This is a bug.'.format(
            optimizer.clip_type))


@property
def LATEST_VERSION(cls):
    """
        Latest available Boost release version.
        """
    return max(cls.RELEASE_URLS)


@classmethod
def dispatch(cls, handle, token, terminal):
    """ Dispatch a match request to the correct parse job """
    return cls._jobs[handle].matches(token, terminal)


def IF_NULL(expression, _else):
    """
    Evaluates an expression and returns the value of the expression if the expression evaluates to a non-null value.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/ifNull/
    for more details
    :param expression: expression that will be evaluated
    :param _else: value or expression if 'expression' is null
    :return:  Aggregation operator
    """
    return {'$ifNull': [expression, _else]}


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


def _get_ip_axis(ur_number):
    """
    Internal function that gets the ip of the axis machine

    Args:
        ur_number: ID of robot (1,2 or 3)

    Returns:
        ip: string.
    """
    ip = 10 * ur_number
    return '192.168.10.%d' % ip


def is_valid_ticket_id(ticket_id):
    """
    Validates Zadara Ticket ID

    :type ticket_id: int
    :param ticket_id: The ticket to be validated.

    :rtype: bool
    :return: True or False depending on whether ticket ID passes
        validation.
    """
    return ticket_id > 0


def partition_esps_and_esms(filelist):
    """Split filelist into separate lists for esms and esps, retaining order."""
    esm_files = []
    esp_files = []
    for filename in filelist:
        ext = filename[-4:].lower()
        if ext == '.esp':
            esp_files.append(filename)
        elif ext == '.esm':
            esm_files.append(filename)
    return esm_files, esp_files


def validate(item, **kwargs):
    """Checks if item has take_key value"""
    if not item.get('anpa_take_key', '').strip():
        raise KeyError('Take key cannot be empty!')
    return item


def convertbase(num, n):
    """
    Change a number in base 10 to a base-n number.
    Up to base-36 is supported without special notation.
    """
    num_rep = {(10): 'a', (11): 'b', (12): 'c', (13): 'd', (14): 'e', (15):
        'f', (16): 'g', (17): 'h', (18): 'i', (19): 'j', (20): 'k', (21):
        'l', (22): 'm', (23): 'n', (24): 'o', (25): 'p', (26): 'q', (27):
        'r', (28): 's', (29): 't', (30): 'u', (31): 'v', (32): 'w', (33):
        'x', (34): 'y', (35): 'z'}
    digits = []
    current = num
    while current != 0:
        remainder = current % n
        if remainder < 10:
            digit = str(remainder)
        elif remainder < 36:
            digit = num_rep[remainder]
        else:
            digit = '(' + str(remainder) + ')'
        digits.append(digit)
        current = int(current / n)
    return ''.join(reversed(digits))


def PST(val):
    """PublicationStatus"""
    return val


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 filter_zero_weights_feature_processor(segment_name, segment_data):
    """ A default segment processor to use if none is provided.
    """
    return segment_data[segment_data.weight > 0]


def _get_remote_ip_from_request(request):
    """Retrieve remote ip addr from request.

    :param request: Django request
    :type: django.http.HttpRequest
    :return: Ip address
    :rtype: str
    """
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip_addr = x_forwarded_for.split(',')[0]
    else:
        ip_addr = request.META.get('REMOTE_ADDR')
    return ip_addr


def is_forking(argv):
    """
    Return whether commandline indicates we are forking
    """
    if len(argv) >= 2 and argv[1] == '--multiprocessing-fork':
        assert len(argv) == 3
        return True
    else:
        return False


def my_format_warning(message, category, filename, lineo, line=None):
    """
    Override the default showwarning to customize the appearance of warnings
    :return:
    """
    return '\nWARNING %s: %s\n\n' % (category.__name__, message)


def getDmax(peaks):
    """needs a doc string"""
    return peaks[0][-2]