def get_names():
    """Return available extensions names.
        """


def ensure_bytes(data):
    """
    Utility to make sure a value is in bytes or encode it.
    """
    if isinstance(data, str):
        return data.encode('latin-1')
    elif isinstance(data, bytes):
        return data
    else:
        raise ValueError(f'data:{data!r} cant be converted to bytes')


def find_block_indexes(lines, key):
    """Find indices of opening and closing block.

    Note, this does not yet handle recursive blocks.

    For example:
    1  if statement1 {
    2    if statement2 {
    3    }
    4  }

    will return 1, 3.

    Args:
        lines: List of text lines.
        key: Search term which starts block.

    Returns: tuple of start and end of block.
    """
    total_lines = len(lines)
    start = None
    end = None
    for line_num in range(total_lines):
        line = lines[line_num]
        if key in line:
            for num in range(line_num, total_lines):
                line = lines[num]
                if '{' in line:
                    start = num
                if '}' in line:
                    end = num
                    break
            break
    return start, end


@classmethod
def register_update_fail_callback(cls, callback, raise_exc=False):
    """Reigister callback.

        :param callback: func to callback
        :param raise_exc: whether to raise exception if occur, default to false
        """
    assert callable(callback), 'callback should be callable!'
    cls._update_cache_fail_callback.add((callback, raise_exc))


def pchange2(f, c1, c2):
    """Calculate the percentage change between two variables.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the two columns ``c1`` and ``c2``.
    c1 : str
        Name of the first column in the dataframe ``f``.
    c2 : str
        Name of the second column in the dataframe ``f``.

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

    """
    new_column = f[c1] / f[c2] - 1.0
    return new_column


def get_wsgi_string(string, encoding='utf-8'):
    """
    Returns wsgi-compatible string
    """
    return string.encode(encoding).decode('iso-8859-1')


def format_host(host):
    """Formats host for PySense"""
    if not host.startswith('http'):
        host = 'http://' + host
    if host.endswith('/'):
        host = host[:-1]
    return host


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

        :param PasswordChangeType val:
        :rtype: EventType
        """
    return cls('password_change', val)


def calculate_growth(photosynthesis_rate):
    """Calculate the plant growth rate from the photosynthesis rate.

    Args:
        photosynthesis_rate (float): Rate of photosynthesis.

    Returns:
        float: Growth rate.

    """
    return 0.5 * photosynthesis_rate


def compute_predictions_y_known(y, n2i, model, dataGen):
    """
    Computes predictions for a model and generator, NOT aggregating scores for long contigs.

    Inputs:
        n2i: dictionary with contig_name -> list of idx corresponding to that contig.
    Output:
        scores:
        pred: scores for individual contigs
        y: corresponding true labels
    """
    score_val = model.predict_generator(dataGen)
    score_val = score_val.flatten()
    scores = {}
    for k in n2i:
        inf = n2i[k][0]
        sup = n2i[k][-1] + 1
        if k[0] not in scores:
            scores[k[0]] = {}
        assert k[1] not in scores[k[0]]
        if sup > len(score_val):
            continue
        assert (y[inf:sup] == y[inf]).all()
        scores[k[0]][k[1]] = {'y': int(y[inf]), 'pred': score_val[inf:sup]}
    return scores


def SDtype():
    """return the software stack on which we are running."""
    return 'library'


def nessus_httpscan_loopy(var1, reporthost, http_obs, var2):
    """ Specific Nessus loop to find all HTTP response header issues """
    for reportitem in reporthost.findall('ReportItem'):
        if int(reportitem.get('pluginID')) in http_obs.keys():
            if var1 == 'addr':
                var2.append(reporthost.get('name') + ':' + reportitem.get(
                    'port'))
            elif var1 == 'obs':
                var2.append(http_obs.get(int(reportitem.get('pluginID'))))


def cycle_sort(l):
    """
    Utility function which takes a list l and returns the minimum
    for the alphabetical order among all cyclic permutations of the list.
    """
    s = l
    for i in range(0, len(l)):
        temp = l[i:] + l[0:i]
        if temp < s:
            s = temp
    return s


def dict_to_sequence(d):
    """Returns an internal sequence dictionary update."""
    if hasattr(d, 'items'):
        d = d.items()
    return d


def repr_video(fname, mimetype):
    """Load the video in the file `fname`, with given mimetype,
    and display as HTML5 video.
    """
    try:
        from IPython.display import HTML
    except ImportError:
        raise ImportError('This feature requires IPython.')
    video_encoded = open(fname, 'rb').read().encode('base64')
    video_tag = (
        """<video controls>
<source alt="test" src="data:video/{0};base64,{1}" type="video/webm">
Use Google Chrome browser.</video>"""
        .format(mimetype, video_encoded))
    return HTML(data=video_tag)


@staticmethod
def evaluation_at(sub_expr1, sub_expr2, val_dict):
    """
        Compute multiplication of sub_expr1 with sub_expr2 using inputs
        of variable values from val_dict.

        INPUTS
        =======
        sub_expr1: expression or constant
        sub_expr2: expression or constant
        val_dict: a dictionary containing variable name and values.

        RETURNS
        ========
        sub_expr1 * sub_expr2
        """
    return sub_expr1.evaluation_at(val_dict) * sub_expr2.evaluation_at(val_dict
        )


def is_choice(action):
    """ action with choices supplied """
    return action.choices


def button(conteudo, classe='', Identificador='', atrPersonalizado=''):
    """Retorna uma tag button o ultimo parametro disponibiliza a possibilidade de criar atributos personalizados"""
    return "<button class='btn %s' id='%s' %s >%s</button>" % (str(classe),
        str(Identificador), str(atrPersonalizado), str(conteudo))


def car(obj):
    """
    Alias of ``obj[0]``.

    >>> car(loads('(a . b)'))
    Symbol('a')
    >>> car(loads('(a b)'))
    Symbol('a')

    """
    return obj[0]


def define_orderers(orderer_names, orderer_hosts, domain=None):
    """Define orderers as connection objects.

        Args:
            orderer_names (Iterable): List of orderer names.
            orderer_hosts (Iterable): List of orderer hosts.
            domain (str): Domain used. Defaults to none.

        Returns:
            dict: A dictionary of Orderer Connections
    """
    orderer_connections = {}
    for name, host in zip(orderer_names, orderer_hosts):
        if domain:
            key = f'{name}.{domain}'
        else:
            key = name
        orderer_connections[key] = {'url': 'grpc://' + host + ':7050'}
    return orderer_connections


def create_pfeffer_simplex(position, size_param=0.05):
    """Create a simplex according to the rule of Lawrence E. Pfeffer.

    This construction method is the default in Matlab's :func:`fminsearch`
    and SciPy's :func:`scipy.optimize.fmin`. According to [Fan2002]_, p. 73,
    this approach was proposed by Lawrence E. Pfeffer at Stanford.

    Parameters
    ----------
    position : iterable
        The position being used as location vector for the simplex. In this
        construction, `position` is the vertex in the simplex closest to
        the origin.
    size_param : float, optional
        For each coordinate, a fraction of itself is added to it. This value
        is the fraction.

    Returns
    -------
    simplex : list of list
        A list containing ``len(position) + 1`` points.

    References
    ----------
    .. [Fan2002] Ellen Fan (2002). Global optimization of Lennard-Jones
        atomic clusters. Master's thesis, McMaster University.
        http://www.cas.mcmaster.ca/~oplab/thesis/faneMS.pdf

    """
    assert len(position) > 0
    assert size_param > 0.0
    nonzero_delta = size_param
    zero_delta = 0.00025
    simplex = [list(position)]
    for i in range(len(position)):
        point = list(position)
        if point[i] != 0.0:
            point[i] *= 1.0 + nonzero_delta
        else:
            point[i] = zero_delta
        simplex.append(point)
    return simplex


def _find_bboxes_in_rect(bboxes, left, bottom, right, top):
    """ Given a list of polygon bounding boxes and a rectangle defined by
    left/bottom/right/top, this function returns those polygons which overlap
    the rectangle. """
    result = (bboxes[:, (0)] <= right) & (bboxes[:, (2)] >= left) & (bboxes
        [:, (1)] <= top) & (bboxes[:, (3)] >= bottom)
    return result


def require(name, field, data_type):
    """Require that the named `field` has the right `data_type`"""
    if not isinstance(field, data_type):
        msg = '{0} must have {1}, got: {2}'.format(name, data_type, field)
        raise AssertionError(msg)


def chunk_iterator(array):
    """
    Utility to iterate over the rows in the specified array efficiently
    by accessing one chunk at a time.
    """
    chunk_size = array.chunks[0]
    for j in range(array.shape[0]):
        if j % chunk_size == 0:
            chunk = array[j:j + chunk_size][:]
        yield chunk[j % chunk_size]


def _tryint(v):
    """
    Tries to convert v to an integer. If it fails, return 0.
    """
    try:
        return int(v)
    except:
        return 0


def get_transpositions(array):
    """
    Generator that iterates through all possible transpositions of
    an n-dimensional array.
    """
    axes = range(len(array.shape))
    for i in axes:
        yield tuple(axes[i:] + axes[:i])


def _indent(string, width=0):
    """ Helper function to indent lines in printouts
    """
    return '{0:>{1}}{2}'.format('', width, string)


def is_multi_byte(ch):
    """Is this an Asian character?"""
    return ord(ch) >= 12288


def make_title(title, width=80):
    """Styles a title to be printed into console.
    """
    space = width - len(title) - 4
    pre_space = space / 2 - 1
    post_space = space - pre_space
    line = '|' + str(int(pre_space) * '=') + ' '
    line += title
    line += ' ' + str(int(post_space) * '=') + '|'
    return line


def endianSwapU16(bytes):
    """Swaps pairs of bytes (16-bit words) in the given bytearray."""
    for b in range(0, len(bytes), 2):
        bytes[b], bytes[b + 1] = bytes[b + 1], bytes[b]
    return bytes


def do_batch(value, linecount, fill_with=None):
    """
    A filter that batches items. It works pretty much like `slice`
    just the other way round. It returns a list of lists with the
    given number of items. If you provide a second parameter this
    is used to fill up missing items. See this example:

    .. sourcecode:: html+jinja

        {%- for row in items|batch(3, ' ') %}

          {%- for column in row %}
            {{ column }}
          {%- endfor %}

        {%- endfor %}

    """
    tmp = []
    for item in value:
        if len(tmp) == linecount:
            yield tmp
            tmp = []
        tmp.append(item)
    if tmp:
        if fill_with is not None and len(tmp) < linecount:
            tmp += [fill_with] * (linecount - len(tmp))
        yield tmp


def cl():
    """Returns current post content length.

    :rtype: int|long
    """
    return 0


def showOperandLines(rh):
    """
    Produce help output related to operands.

    Input:
       Request Handle
    """
    if rh.function == 'HELP':
        rh.printLn('N', '  For the CmdVM function:')
    else:
        rh.printLn('N', 'Sub-Functions(s):')
    rh.printLn('N', '      cmd           - ' +
        "Send a command to a virtual machine's operating system.")
    rh.printLn('N', '      help          - ' +
        'Displays this help information.')
    rh.printLn('N', '      version       - ' +
        'show the version of the power function')
    if rh.subfunction != '':
        rh.printLn('N', 'Operand(s):')
    rh.printLn('N', '      <userid>      - ' +
        'Userid of the target virtual machine')
    rh.printLn('N', '      <cmdToSend>   - ' +
        "Command to send to the virtual machine's OS.")
    return


def is_loop_running(loop):
    """
    Return whether an IOLoop is running. (Stolen from Dask)
    """
    r = getattr(loop, '_running', None)
    if r is not None:
        return r
    try:
        return loop.asyncio_loop.is_running()
    except AttributeError:
        raise TypeError("don't know how to query the running state of %s" %
            (type(loop),))


def prepare():
    """For mutable types, creates and prepares an instance for
        being recovered. For immutable types returns None, and restore()
        should be used instead.
        It returns an empty instance implementing L{ISerializable}.
        The returned instance's method recover() should be called
        with a snapshot to finish the restoration.
        This methods will create an instance without calling __init__()."""


def monet_bool(data):
    """
    returns "true" or "false"
    """
    return ['false', 'true'][bool(data)]


@classmethod
def load(cls, db, id):
    """Load a specific document from the given database.

        :param db: the `Database` object to retrieve the document from
        :param id: the document ID
        :return: the `Document` instance, or `None` if no document with the
                 given ID was found
        """
    doc = db.get(id)
    if doc is None:
        return None
    return cls.wrap(doc)


def create(hub, ref, obj):
    """
    Create an attribute at a given target using just a ref string and the
    object to be saved at said location. The desired location must already
    exist!

    :param ref: The dot delimited string referencing the target location to
        create the given object on the hub
    :param obj: The object to store at the given reference point
    """
    if '.' not in ref:
        setattr(hub, ref, obj)
        return
    comps = ref.split('.')
    sub_ref = ref[:ref.rindex('.')]
    var = comps[-1]
    top = hub.pop.ref.last(sub_ref)
    setattr(top, var, obj)


@classmethod
def _hash_key_attribute(cls):
    """
        Returns the attribute class for the hash key
        """
    return cls.get_attributes()[cls._hash_keyname]


def active_users(account, days_back):
    """ Returns query for finding active users (since days_back value)."""
    query_string = f"""SELECT DISTINCT useridentity.arn
        FROM behold
        WHERE account = '{account}'
        AND useridentity.type = 'IAMUser'
        AND useridentity.arn IS NOT NULL
        AND from_iso8601_timestamp(eventtime) > date_add('day', -{days_back}, now());"""
    return query_string, f'athena_results/active_users/{account}'


@classmethod
def read_file(cls, filepath):
    """Decodes bencoded data of a given file.

        Returns decoded structure(s).

        :param str filepath:
        :rtype: list
        """
    with open(filepath, mode='rb') as f:
        contents = f.read()
    return cls.decode(contents)


def pointgroup_has_inversion(number):
    """
    Return True if the pointgroup with given number has inversion,
    False otherwise.

    :param number: The integer number of the pointgroup, from 1 to 32.
    """
    if number in [2, 5, 8, 11, 15, 17, 20, 23, 27, 29, 32]:
        return True
    elif number in [1, 3, 4, 6, 7, 9, 10, 12, 13, 14, 16, 18, 19, 21, 22,
        24, 25, 26, 28, 30, 31]:
        return False
    else:
        raise ValueError('number should be between 1 and 32')


def _check_argvals_equality(argvals1, argvals2):
    """Check if two provided `argvals` are equals.

    Parameters
    ----------
    argvals1 : list of tuples
    argvals2 : list of tuples

    Return
    ------
    True, if the two argvals are the same.
    """
    if argvals1 != argvals2:
        raise ValueError(
            """The two UnivariateFunctionalData objects are defined
                on different argvals."""
            )
    return True


def conver_color_code(colorcode):
    """Convert color code to valid PPTX color code."""
    colorcode = colorcode.rsplit('#')[-1].lower()
    return colorcode + '0' * (6 - len(colorcode))


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def urljoin(*parts):
    """
    Join terms together with forward slashes

    Parameters
    ----------
    parts

    Returns
    -------
    str
    """
    part_list = []
    for part in parts:
        p = str(part)
        if p.endswith('//'):
            p = p[0:-1]
        else:
            p = p.strip('/')
        part_list.append(p)
    url = '/'.join(part_list)
    return url


def cursor(connection, server_side=False):
    """
        Create and return a new cursor sharing the state of the given
        *connection*.

        The cursor should be closed when it is no longer needed. The
        cursor should be considered forward-only (no backward
        scrolling) and ephemeral (results go away when the attached
        transaction is committed or rolled back).

        For compatibility, previous cursors should not have
        outstanding results pending when this is called and while the
        returned cursor is used (not all drivers permit multiple
        active cursors).

        If *server_side* is true (not the default), request that the
        driver creates a cursor that will **not** buffer the complete
        results of a query on the client. Instead, the results should
        be streamed from the server in batches. This can reduce the
        maximum amount of memory needed to handle results, if done
        carefully.

        For compatibility, server_side cursors can only be used
        to execute a single query.

        Most drivers (``psycopg2``, ``psycopg2cffi``, ``pg8000``,
        ``mysqlclient``) default to buffering the entire results
        client side before returning from the ``execute`` method. This
        can reduce latency and increase overall throughput, but at the
        cost of memory, especially if the results will be copied into
        different data structures.

        Not all drivers support server-side cursors; they will ignore
        that request. At this writing, this includes ``pg8000``. Some
        drivers (at this writing, only ``gevent MySQLdb``) always use
        server-side cursors. The ``cx_Oracle`` driver is unevaluated.

        ``psycopg2`` and ``psycopg2cffi`` both iterate in chunks of
        ``cur.itersize`` by default. PyMySQL seems to iterate one row at a time.
        ``mysqlclient`` defaults to also iterating one row at a time, but
        we patch that to operate in chunks of ``cur.arraysize``.
        """


def _mean_int(*args):
    """Return the mean of the supplied values."""
    return int(sum(args) / len(args))


def sgd_step(param, lr, **kwargs):
    """Example stepper for use with Optimizer."""
    param.data.add_(-lr, param.grad.data)
    return param


def no_op(*args, **kwargs):
    """Function that does nothing."""


def provider_parser(subparser):
    """Configure provider parser for EasyDNS"""
    subparser.add_argument('--auth-username', help=
        'specify username for authentication')
    subparser.add_argument('--auth-token', help=
        'specify token for authentication')


def get_member(member_id):
    """Return a member record matching the member id.

        :param member_id: A member id.
        :type member_id: int
        :return: The matching member, or None if no matching member is found.
        :rtype: `IMember`
        """


def do_OP_SIZE(vm):
    """
    >>> import binascii
    >>> s = [b'abcdef']
    >>> do_OP_SIZE(s)
    >>> print(s == [b'abcdef', b''])
    True
    >>> s = [b'abcdef'*1000]
    >>> do_OP_SIZE(s)
    >>> print(binascii.hexlify(s[-1]) == b'7017')
    True
    """
    vm.push_int(len(vm[-1]))


def dummy_hash(x):
    """
    Supplies a constant dummy hash
    """
    return 'dummy_hash'.encode('utf-8')


def f_to_c(f):
    """
    Convert fahrenheit to celcius
    """
    return (f - 32.0) / 1.8


@classmethod
def is_uncompleted(cls, databases):
    """Check if the database is uncompleted and the index should not be used

        :type databases: int
        :return:
        """
    return databases in [cls.HMagazines, cls.HGameCG, cls.DoujinshiDB, cls.
        Shutterstock, cls.Movies, cls.Shows, cls.SankakuChannel, cls.
        IdolComplex, cls.BcyNetIllust, cls.BcyNetCosplay, cls.DeviantArt,
        cls.PawooNet, cls.MangaDex]


def binary_eval(op, left, right):
    """token_lst has length 3 and format: [left_arg, operator, right_arg]
    operator(left_arg, right_arg) is returned"""
    return op(left, right)


def __call__():
    """Executes a workflow transition or cancels if there are errors.
        It expects the transition to be passed in as request parameter
        ``transition``.

        Redirects to the referrer and adds status messages.
        """


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


def _validate_dependencies_met():
    """
    Verifies that PyOpenSSL's package-level dependencies have been met.
    Throws `ImportError` if they are not met.
    """
    from cryptography.x509.extensions import Extensions
    if getattr(Extensions, 'get_extension_for_class', None) is None:
        raise ImportError(
            "'cryptography' module missing required functionality.  Try upgrading to v1.3.4 or newer."
            )
    from OpenSSL.crypto import X509
    x509 = X509()
    if getattr(x509, '_x509', None) is None:
        raise ImportError(
            "'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer."
            )


def determine_genotype(likelihoods, threshold_prob):
    """given genotype likelihoods for 0/0,0/1,1/1, determines likeliest genotype"""
    to_sort = [(likelihoods[0], 0), (likelihoods[1], 1), (likelihoods[2], 2)]
    to_sort.sort(key=lambda x: x[0])
    if to_sort[2][0] > to_sort[1][0] and to_sort[2][0] > threshold_prob:
        return to_sort[2][1]
    else:
        return -1


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

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


@classmethod
def columns(cls):
    """
        This needs to be implement in models to deine columns.
        """
    raise NotImplementedError()


def _partition(seq, vector, m=None):
    """
    Return the partion of seq as specified by the partition vector.

    Examples
    ========

    >>> _partition('abcde', [1, 0, 1, 2, 0])
    [['b', 'e'], ['a', 'c'], ['d']]

    Specifying the number of bins in the partition is optional:

    >>> _partition('abcde', [1, 0, 1, 2, 0], 3)
    [['b', 'e'], ['a', 'c'], ['d']]

    The output of _set_partitions can be passed as follows:

    >>> output = (3, [1, 0, 1, 2, 0])
    >>> _partition('abcde', *output)
    [['b', 'e'], ['a', 'c'], ['d']]

    See Also
    ========
    combinatorics.partitions.Partition.from_rgs()

    """
    if m is None:
        m = max(vector) + 1
    elif type(vector) is int:
        vector, m = m, vector
    p = [[] for i in range(m)]
    for i, v in enumerate(vector):
        p[v].append(seq[i])
    return p


def retSVGAttrsFromStroke(stroke):
    """Returns SVG attributes as a dictionary from a Stroke() object."""
    r = {'stroke-width': '{:.3f}'.format(stroke.width), 'stroke': str(
        stroke.colour), 'stroke-opacity': '{:.3f}'.format(stroke.opacity)}
    if stroke.coding:
        r['stroke-dasharray'] = '{:d},{:d}'.format(stroke.coding[0], stroke
            .coding[1])
    return r


def calc_raid_partition_sectors(psize, start):
    """Calculates end sector and converts start and end sectors including

    the unit of measure, compatible with parted.
    :param psize: size of the raid partition
    :param start: start sector of the raid partion in integer format
    :return: start and end sector in parted compatible format, end sector
        as integer
    """
    if isinstance(start, int):
        start_str = '%dGiB' % start
    else:
        start_str = start
    if psize == -1:
        end_str = '-1'
        end = '-1'
    else:
        if isinstance(start, int):
            end = start + psize
        else:
            end = psize
        end_str = '%dGiB' % end
    return start_str, end_str, end


@classmethod
def serialize(cls, obj, skip_primary_key=False, skip_foreign_keys=False,
    relations_level=1, relations_ignore=None, relations_include=None):
    """
        Converts the object to a serializable dictionary.
        :param obj: the object to serialize

        :param skip_primary_key: should primary keys be skipped
        :type skip_primary_key: bool

        :param skip_foreign_keys: should foreign keys be skipped
        :type skip_foreign_keys: bool

        :param relations_level: how many levels of relations to serialize
        :type relations_level: int

        :param relations_ignore: relationship names to ignore
        :type relations_ignore: list

        :param relations_include: relationship names to include
        :type relations_include: list

        :return: a serializable dictionary
        :rtype: dict
        """
    data = {}
    data = cls.serialize_columns(obj, data, skip_primary_key, skip_foreign_keys
        )
    if relations_level > 0:
        if relations_ignore is None:
            relations_ignore = []
        data = cls.serialize_relations(obj, data, relations_level,
            relations_ignore, relations_include)
    return data


def shoji_entity_wrapper(body, **kwargs):
    """
    receives a dictionary and wraps its content on a body keyed dictionary
    with the appropiate shoji:<class> attribute
    """
    payload = {'element': 'shoji:entity', 'body': body}
    payload.update(**kwargs)
    return payload


def params(f):
    """
    Read header parameters like ## key=value into a dictionary
    :param f: file handler
    :return: {key: value}
    """
    params = {}
    pos = f.tell()
    line = f.readline()
    while line.startswith('#') or line == '\n':
        if line.startswith('##'):
            line = line[2:].rstrip('\n')
            try:
                idx = line.index('=')
                key = line[0:idx].lstrip()
                value = line[idx + 1:]
                params[key] = value
            except:
                pass
        pos = f.tell()
        line = f.readline()
    f.seek(pos)
    return params


def read_analogy_file(filename):
    """
    Read the analogy task test set from a file.
    """
    section = None
    with open(filename, 'r') as questions_file:
        for line in questions_file:
            if line.startswith(':'):
                section = line[2:].replace('\n', '')
                continue
            else:
                words = line.replace('\n', '').split(' ')
            yield section, words


def prepare_lookup_value(key, value):
    """
    Return a lookup value prepared to be used in queryset filtering.
    """
    if key.endswith('__in'):
        value = value.split(',')
    elif key.endswith('__isnull'):
        value = value.lower() not in ('', 'false', '0')
    return value


@classmethod
def count(cls, user_id):
    """ Count sessions with user_id """
    return cls.query.with_entities(cls.user_id).filter_by(user_id=user_id
        ).count()


def set_aspect_ratio(obj_axis):
    """Fine-tune matrix plot aspect ratio

    Args:
        obj_axis (object): a matplotlib axis object

    Returns:
        same as inputs
    """
    obj_axis.set_aspect('auto', adjustable='box-forced', anchor='SW')
    return


def irange(a, b=None, c=None):
    """
    same signature as range(). However, starts at "1" + its always inclusive of the last element.

    original documentation:
        range(stop) -> range object
        range(start, stop[, step]) -> range object

        Return an object that produces a sequence of integers from start (inclusive)
        to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
        start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
        These are exactly the valid indices for a list of 4 elements.
        When step is given, it specifies the increment (or decrement).
    """
    if c is None:
        c = 1
    if b is None:
        all = list(range(a))
        for i in all:
            yield i + 1
    else:
        if c > 0:
            all = list(range(a, b + 1, c))
        else:
            all = list(range(a, b - 1, c))
        for i in all:
            yield i


def xml_to_html(sbml_file):
    """
    Generates HTML view of XML (SBML) file.

    Parameters
    ----------
    sbml_file: str
        SBML file in string representation.

    Returns: str
        SBML file as HTML view.
    """
    old_sbml = sbml_file.split('\n')
    new_sbml = '<xmp>'
    for row in old_sbml:
        new_sbml += row + '\n'
    new_sbml += '</xmp>'
    return new_sbml


def ebt(ebit, int_exp):
    """
    Computes EBT(Earnings before tax) the gross profit.

    @params
    -------
    ebit: earnings before interest and tax
    int_exp: interest expense

    returns
    -------
    Returns EBT, int or float
    """
    return ebit - int_exp


def logistic4(x, a, b, c, d):
    """4PL lgoistic equation."""
    return (a - d) / (1.0 + (x / c) ** b) + d


def parse_params(func, params, models):
    """
    get spec for (query, headers, cookies)
    """
    if hasattr(func, 'query'):
        params.append({'name': func.query, 'in': 'query', 'required': True,
            'schema': {'$ref': f'#/components/schemas/{func.query}'}})
    if hasattr(func, 'headers'):
        headers = models[func.headers]
        for key, value in headers['properties'].items():
            params.append({'name': key, 'in': 'header', 'type': value[
                'type'], 'required': key in headers['required']})
    if hasattr(func, 'cookies'):
        cookies = models[func.cookies]
        for key, value in cookies['properties'].items():
            params.append({'name': key, 'in': 'cookie', 'type': value[
                'type'], 'required': key in cookies['required']})
    return params


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 free_bake_all():
    """Free all baked caches of all objects in the current scene

    """
    pass


def deriv_series(A, t):
    """ Derivates A with respect to t. """
    [n, nt] = A.shape
    dAdt = (A[:, 2:nt] - A[:, 0:nt - 2]) / (t[2:nt] - t[0:nt - 2])
    tm = (t[0:nt - 2] + t[2:nt]) / 2.0
    return dAdt, tm


def get_silva_addables_allowed_in_container():
    """Get a list of all addables explicitly allowed in this
        container.
        """


@classmethod
def get_friendly_name(cls):
    """Returns a human-readable name of the curve that can be
        used in messages."""
    return 'F-score curve'


def normalise_date(text):
    """This function normalize text, is useful to normalize dates."""
    text = text.replace('/', '-').replace(':', '-').replace('.', '-').replace(
        '@', '-')
    return text


def admin_delete_user_attributes(UserPoolId=None, Username=None,
    UserAttributeNames=None):
    """
    Deletes the user attributes in a user pool as an administrator. Works on any user.
    Requires developer credentials.
    See also: AWS API Documentation

    :example: response = client.admin_delete_user_attributes(
        UserPoolId='string',
        Username='string',
        UserAttributeNames=[
            'string',
        ]
    )

    :type UserPoolId: string
    :param UserPoolId: [REQUIRED]
            The user pool ID for the user pool where you want to delete user attributes.

    :type Username: string
    :param Username: [REQUIRED]
            The user name of the user from which you would like to delete attributes.

    :type UserAttributeNames: list
    :param UserAttributeNames: [REQUIRED]
            An array of strings representing the user attribute names you wish to delete.
            For custom attributes, you must prepend the custom: prefix to the attribute name.
            (string) --

    :rtype: dict
    :return: {}

    """
    pass


@classmethod
def view_list(cls, lst):
    """
        Create a dict that is a view on the given list
        """
    if not isinstance(lst, list):
        raise TypeError(
            '%s.view_list(obj) takes only actual list objects, not %r' % (
            cls.__name__, lst))
    obj = cls()
    obj._items = lst
    return obj


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 modify_fields(trajectory, fields=None, include=None, exclude=None):
    """
    Modify fields of a trajectory.

    Either provide a new list of fields, such as ['id', 'x', 'y'], or
    specify explicit patterns to exclude or include.
    """
    if fields is not None:
        trajectory.fields = fields
    else:
        if exclude is not None:
            for pattern in exclude:
                if pattern in trajectory.fields:
                    trajectory.fields.remove(pattern)
        if include is not None:
            for pattern in include:
                if pattern not in trajectory.fields:
                    trajectory.fields.append(pattern)
    return trajectory


def get_substr_slices(umi_length, idx_size):
    """
    Create slices to split a UMI into approximately equal size substrings
    Returns a list of tuples that can be passed to slice function.
    """
    cs, r = divmod(umi_length, idx_size)
    sub_sizes = [cs + 1] * r + [cs] * (idx_size - r)
    offset = 0
    slices = []
    for s in sub_sizes:
        slices.append((offset, offset + s))
        offset += s
    return slices


def get_for_key_or_first_map_value(my_dict, key=None):
    """
    Return the value in key "key" or the first value from a map
    """
    if key in my_dict:
        return my_dict.get(key)
    for _, v in my_dict.items():
        return v
    return ''


def resolve_meta_key(hub, key, meta):
    """ Resolve a value when it's a string and starts with '>' """
    if key not in meta:
        return None
    value = meta[key]
    if isinstance(value, str) and value[0] == '>':
        topic = value[1:]
        if topic not in hub:
            raise KeyError('topic %s not found in hub' % topic)
        return hub[topic].get()
    return value


def is_iterable(obj):
    """Check weather this ``object`` is an iterable.

    There are two kinds of implementations. The other is using ``collections.Iterable``. [1]_

    .. code:: python

        import collections

        def is_iterable(obj):
            if isinstance(obj, collections.Iterable):
                return True
            else:
                return False

    Checking for :meth:`__iter__` works on sequence types, but it would fail on
    e.g. strings in `Python 2`. The :meth:`iter` built-in checks for the :meth:`__iter__`
    method or in the case of strings the :meth:`__getitem__` method. In `Python 2`, to check
    if an object is "list like" and not "string like" then the key is the attributes
    :meth:`__getitem__` and :meth:`__iter__`. [2]_

    >>> hasattr([1,2,3,4], '__iter__')
    >>> True
    >>> hasattr((1,2,3,4), '__iter__')
    >>> True
    >>> hasattr(u"hello", '__iter__')
    >>> False
    >>> hasattr(u"hello", '__getitem__')
    >>> True

    Parameters
    ----------
    obj : object

    Returns
    -------
    boolean
        True or False.

    References
    ----------

    .. [1] http://stackoverflow.com/questions/19919314/how-to-check-isinstance-of-iterable-in-python
    .. [2] http://stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-an-object-is-iterable

    """
    if hasattr(obj, '__iter__'):
        return True
    if hasattr(obj, '__getitem__'):
        return True
    return False


@staticmethod
def _parse_filter(value):
    """Parse timer filters."""
    return value.split(',') if value is not None else None


def bisect_func_left(x, lo, hi, func):
    """Bisect `func(i)`, returning an index such that preceding values are less
    than `x`. If `x` is present, the returned index is its first occurrence.
    EOF is assumed if `func` returns None."""
    while lo < hi:
        mid = (lo + hi) // 2
        k = func(mid)
        if k is not None and k < x:
            lo = mid + 1
        else:
            hi = mid
    return lo


def compatible_boxes(one, two):
    """
    move me to data.py? XXXv1
    """
    fl1 = one.get('firstline', [None])[0]
    fl2 = two.get('firstline', [None])[0]
    if fl1 is None or fl2 is None:
        print('hey greg compatible_boxes box1 is', one)
        print('     and compatible_boxes box2 is', two)
    id1, kind1, subkind1 = fl1.split(' ', maxsplit=2)
    id2, kind2, subkind2 = fl2.split(' ', maxsplit=2)
    if kind1 != kind2:
        return False
    if subkind1 != subkind2:
        if '-in-progress' in subkind1 and subkind1.replace('-in-progress', ''
            ) == subkind2:
            return True
        if subkind2 == 'collapsed mine' and subkind1 == 'mine':
            return True
        return False
    return True


def import_object(name):
    """Imports an object by name.

    import_object('x.y.z') is equivalent to 'from x.y import z'.

    >>> import cyclone.escape
    >>> import_object('cyclone.escape') is cyclone.escape
    True
    >>> import_object('cyclone.escape.utf8') is cyclone.escape.utf8
    True
    """
    parts = name.split('.')
    obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0)
    method = getattr(obj, parts[-1], None)
    if method:
        return method
    else:
        raise ImportError('No method named %s' % parts[-1])


def _subsection(iterable, exclude, start, end):
    """

    Selects a subsection of an array, excluding a single subsection

    :param iterable: some iterable data structure, which can be indexed.
    :type iterable: ``list`` or ``tuple``
    :param exclude: the index to exclude.
    :type exclude: ``int``
    :param start: where to start the slice.
    :type start: ``int``
    :param end: where to end the slice
    :type end: ``int``
    :return: a list of the desired subsection.
    :rtype: ``list``
    """
    return iterable[start:exclude] + iterable[exclude + 1:end]


def normalize(name: str) ->str:
    """Normalize a value name to a valid Python (PEP8 compliant) identifier.

    Args:
        name: The name of a value returned by MPD.

    Returns:
        The normalized name, in all lowercase with - replaced by _.
    """
    return name.lower().replace('-', '_')


def no_op(*args, **kwargs):
    """
    No-op function to serve as default ``get_runtime_attrs``.
    """
    return None


def _escape(txt):
    """Basic html escaping."""
    txt = txt.replace('&', '&')
    txt = txt.replace('<', '<')
    txt = txt.replace('>', '>')
    return txt


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

        :param JoinTeamDetails val:
        :rtype: ActionDetails
        """
    return cls('team_join_details', val)


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


def parse_biom_config_file(biom_config_file):
    """Parses lines in a biom_config file.

    This function is ported from QIIME (http://www.qiime.org), previously named
    parse_qiime_config_file. QIIME is a GPL project, but we obtained permission
    from the authors of this function to port it to the BIOM Format project
    (and keep it under BIOM's BSD license).
    """
    result = {}
    for line in biom_config_file:
        line = line.strip()
        if not line or line.startswith('#'):
            continue
        fields = line.split()
        param_id = fields[0]
        param_value = ' '.join(fields[1:]) or None
        result[param_id] = param_value
    return result


def write_rmsd(data, tgt_file):
    """Writes the given RMSD data list into the given target location.

    :param data: The list of data to write.
    :param tgt_file: The target file location.
    """
    with open(tgt_file, 'w') as w_file:
        for i, rmsd_val in enumerate(data, 1):
            w_file.write('\t'.join((str(i), str(rmsd_val))))
            w_file.write('\n')
    print('Wrote file: {}'.format(tgt_file))


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

        :param TfaAddSecurityKeyDetails val:
        :rtype: EventDetails
        """
    return cls('tfa_add_security_key_details', val)


def reshape_nd(data_or_shape, ndim):
    """Return image array or shape with at least ndim dimensions.

    Prepend 1s to image shape as necessary.

    >>> reshape_nd(numpy.empty(0), 1).shape
    (0,)
    >>> reshape_nd(numpy.empty(1), 2).shape
    (1, 1)
    >>> reshape_nd(numpy.empty((2, 3)), 3).shape
    (1, 2, 3)
    >>> reshape_nd(numpy.empty((3, 4, 5)), 3).shape
    (3, 4, 5)
    >>> reshape_nd((2, 3), 3)
    (1, 2, 3)

    """
    is_shape = isinstance(data_or_shape, tuple)
    shape = data_or_shape if is_shape else data_or_shape.shape
    if len(shape) >= ndim:
        return data_or_shape
    shape = (1,) * (ndim - len(shape)) + shape
    return shape if is_shape else data_or_shape.reshape(shape)


def get(isamAppliance, check_mode=False, force=False):
    """
    Retrieve all update history records
    """
    return isamAppliance.invoke_get('Retrieve all update history records',
        '/updates/history/')


def get_nofile_limit(pid):
    """Returns the NOFILE limit for a given PID

    :param int pid: The PID of the process
    :returns: (*int*) The NOFILE limit
    """
    with open('/proc/%s/limits' % pid, 'r') as f:
        for line in f:
            if line.startswith('Max open files'):
                return int(line.split()[4])
    raise RuntimeError('Could not find "Max open files" limit')


def negative(data=None, name=None, attr=None, out=None, **kwargs):
    """Numerical negative of the argument, element-wise.

    The storage type of ``negative`` output depends upon the input storage type:

       - negative(default) = default
       - negative(row_sparse) = row_sparse
       - negative(csr) = csr

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

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

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


def args_to_list(items):
    """Convert an argument into a list of arguments (by splitting each element on comma)"""
    result = []
    if items is not None:
        for item in items:
            if item:
                for val in item.split(','):
                    val = val.strip()
                    if val:
                        result.append(val)
    return result


def formatUrlParam(parameter, value, addition=False):
    """
    Function used to format a string of URL parameters. Example output: "user=bob&title=builder"
    :param parameter: URL parameter that the value will be assigned to
    :param value: Value that will be assigned to the provided URL parameter
    :param addition: True or false value to indicate if this parameter is being added as an addition to other values.
    :return: If a valid value is given, a formatted string is returned. Otherwise an empty string is returned.
    """
    if addition:
        addition = '&'
    else:
        addition = ''
    if value:
        return '{}{}={}'.format(addition, parameter, value)
    else:
        return ''


def smartsplit(code):
    """Split `code` at " symbol, only if it is not escaped."""
    strings = []
    pos = 0
    while pos < len(code):
        if code[pos] == '"':
            word = ''
            pos += 1
            while pos < len(code):
                if code[pos] == '"':
                    break
                if code[pos] == '\\':
                    word += '\\'
                    pos += 1
                word += code[pos]
                pos += 1
            strings.append('"%s"' % word)
        pos += 1
    return strings


def a2msbi(array):
    """ array to int (MSB first) """
    integer = 0
    for i in range(len(array)):
        integer *= 256
        integer += array[i]
    return integer


def cell_in_raster(shape, cell):
    """Check if specified cell is within raster.

    Parameters
    ----------
    shape : pair of ints
        Shape of raster (num_rows, num_cols)
    cell : pair of ints
        Cell indices (row, col)

    Returns
    -------
    True if the specified cell is within the raster

    """
    if not 0 <= cell[0] < shape[0]:
        return False
    if not 0 <= cell[1] < shape[1]:
        return False
    return True


@staticmethod
def is_acceptor(a):
    """
        returns true if a given atom is a acceptor

        :param a: a `ccdc.molecule.Atom` instance
        :return: bool, true if the atom classification is "acceptor"
        """
    if a.is_acceptor and a.formal_charge == 0:
        return True
    else:
        return False


def describe_target_health(TargetGroupArn=None, Targets=None):
    """
    Describes the health of the specified targets or all of your targets.
    See also: AWS API Documentation

    Examples
    This example describes the health of the targets for the specified target group. One target is healthy but the other is not specified in an action, so it can't receive traffic from the load balancer.
    Expected Output:
    This example describes the health of the specified target. This target is healthy.
    Expected Output:

    :example: response = client.describe_target_health(
        TargetGroupArn='string',
        Targets=[
            {
                'Id': 'string',
                'Port': 123
            },
        ]
    )

    :type TargetGroupArn: string
    :param TargetGroupArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the target group.

    :type Targets: list
    :param Targets: The targets.
            (dict) --Information about a target.
            Id (string) -- [REQUIRED]The ID of the target.
            Port (integer) --The port on which the target is listening.

    :rtype: dict
    :return: {
        'TargetHealthDescriptions': [
            {
                'Target': {
                    'Id': 'string',
                    'Port': 123
                },
                'HealthCheckPort': 'string',
                'TargetHealth': {
                    'State': 'initial'|'healthy'|'unhealthy'|'unused'|'draining',
                    'Reason': 'Elb.RegistrationInProgress'|'Elb.InitialHealthChecking'|'Target.ResponseCodeMismatch'|'Target.Timeout'|'Target.FailedHealthChecks'|'Target.NotRegistered'|'Target.NotInUse'|'Target.DeregistrationInProgress'|'Target.InvalidState'|'Elb.InternalError',
                    'Description': 'string'
                }
            },
        ]
    }

    :returns:
    Elb.RegistrationInProgress - The target is in the process of being registered with the load balancer.
    Elb.InitialHealthChecking - The load balancer is still sending the target the minimum number of health checks required to determine its health status.

    """
    pass


def enforce_access_rights(update):
    """
    Check that the update should be allowed.
    """
    if update.old:
        if update.user != update.old.get_owner() and update.user.role not in [
            'admin', 'owner']:
            raise Exception('Not permitted to modify existing chute {}'.
                format(update.old.name))


def read_factory_settings(app_template='Template', use_empty: bool=False):
    """Load default file and user preferences

    :param use_empty: Empty
    :type use_empty: bool
    """
    pass


def int_to_unknown_bytes(num, byteorder='big'):
    """Converts an int to the least number of bytes as possible."""
    return num.to_bytes((num.bit_length() + 7) // 8 or 1, byteorder)


def my_callback(file_path):
    """Callback for new file"""
    print('New File Created: {:s}'.format(file_path))


def _format_finite(negative, digits, dot_pos):
    """Given a (possibly empty) string of digits and an integer
    dot_pos indicating the position of the decimal point relative to
    the start of that string, output a formatted numeric string with
    the same value and same implicit exponent."""
    olddigits = digits
    digits = digits.lstrip('0')
    dot_pos -= len(olddigits) - len(digits)
    use_exponent = dot_pos <= -4 or dot_pos > len(digits)
    if use_exponent:
        exp = dot_pos - 1 if digits else dot_pos
        dot_pos -= exp
    if dot_pos <= 0:
        digits = '0' * (1 - dot_pos) + digits
        dot_pos += 1 - dot_pos
    assert 1 <= dot_pos <= len(digits)
    if dot_pos < len(digits):
        digits = digits[:dot_pos] + '.' + digits[dot_pos:]
    if use_exponent:
        digits += 'e{0:+03d}'.format(exp)
    return '-' + digits if negative else digits


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

        :param GoogleSsoChangePolicyType val:
        :rtype: EventType
        """
    return cls('google_sso_change_policy', val)


def forwards_add_perms(apps, schema_editor):
    """
        Adds permissions for this app to the group 'Tester'.
        This is useful in case that is an existing installation
        upgrading post 7.0.
    """
    Group = apps.get_model('auth', 'Group')
    Permission = apps.get_model('auth', 'Permission')
    tester = Group.objects.get(name='Tester')
    app_perms = Permission.objects.filter(content_type__app_label__contains
        ='bugs')
    tester.permissions.add(*app_perms)


def to_list_if_other(obj):
    """
    Convenience function to ensure list-like output
    """
    if not isinstance(obj, list):
        return [obj]
    else:
        return obj


@classmethod
def __merge(cls, *multicolors):
    """ Produces a new :class:`Multicolor` object resulting from gathering information from all supplied :class:`Multicolor` instances.

        New :class:`Multicolor` is created and its :attr:`Multicolor.multicolors` attribute is updated with similar attributes of supplied :class:`Multicolor` objects.

        Accounts for subclassing.

        :param multicolors: variable number of :class:`Multicolor` objects
        :type multicolors: :class:`Multicolor`
        :return: object containing gathered information from all supplied arguments
        :rtype: :class:`Multicolor`
        """
    result = cls()
    for multicolor in multicolors:
        result.multicolors = result.multicolors + multicolor.multicolors
    return result


def vert_connect_concave():
    """Make all faces convex

    """
    pass


def __new__(cls, *args, **kwargs):
    """ Accept any arguments, necessary for AbstractModule __new__ override.

        AbstractModule, in its overridden __new__, removes itself from class hierarchy
        so its __new__ is called only once. In python 3, default (object) __new__ is
        then used for next instantiations but it's a slot/"fixed" version supporting
        only one argument (type to instanciate).
        """
    return object.__new__(cls)


@classmethod
def validate_timestamp_field(cls, value, null=True):
    """
        Validate timestamp field value

        :type value: int | float
        :param value:

        :type null: bool
        :param null: is allow None value

        :rtype: dict
        :return: {'is_valid':bool, 'error_msg':str}
        """
    is_valid = True
    error_msg = None
    if null is False and value is None:
        is_valid = False
        error_msg = 'Data should not be None'
    if value is not None and isinstance(value, int) is False and isinstance(
        value, float) is False:
        is_valid = False
        error_msg = 'Data type should be <float> or <int> timestamp'
    return {'is_valid': is_valid, 'error_msg': error_msg}


def get_dependencies(cells):
    """
    Retrieves the 'pip install' commands from the cells.

    :param cells: the cells to iterate
    :type cells: list
    :return: the list of dependencies (instances of "pip install ...")
    :rtype: list
    """
    result = []
    for cell in cells:
        if 'cell_type' in cell and cell['cell_type'
            ] == 'code' and 'source' in cell:
            for line in cell['source']:
                if '%' in line and 'pip ' in line:
                    result.append(line[line.index('%') + 1:])
    return result


def checkNoRepeated(l1, l2):
    """Make sure there are no repeated elements in both lists"""
    for i in l1:
        if i in l2:
            raise Exception('Repeated item ' + str(i))


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

        :param DeviceUnlinkDetails val:
        :rtype: EventDetails
        """
    return cls('device_unlink_details', val)


def map_faces(rotor):
    """Are you ready for bad entry pinning mapping?"""
    pos = rotor.position + 1
    neutral_to_pins = {}
    pins_to_neutral = {}
    for i in range(1, 27):
        if pos > 26:
            pos -= 26
        neutral_to_pins.update({i: pos})
        pins_to_neutral.update({pos: i})
        pos += 1
    return neutral_to_pins, pins_to_neutral


def send_pending_messages():
    """Send all pending messages.

        This needs to be called at the end of a request otherwise any
        messages pending may be lost.
        """


@staticmethod
def _estimate_calibrated_volume(volume, liquid, tip_type):
    """Gives an estimation of calibrated volume

        If tip_type is specified then gets the actual calibrated volume,
        but if it is None then gets a rough estimate of the maximum volume
        calibration that might be experienced.

        This is used for estimates of calibrated volume used for calculating
        overage volume within the tip.

        Parameters
        ----------
        volume : Unit
            the uncalibrated volume
        liquid : LiquidClass
            the liquid class to be calibrated against
        tip_type : str or None
            the name of the TipType to be used

        Returns
        -------
        Unit
            an estimate of the calibrated volume

        See Also
        --------
        _calculate_overage_volume : uses this method
        LiquidClass._safe_volume_multiplier : used if no tip_type is specified
        """
    estimated = liquid._safe_volume_multiplier * volume
    if tip_type:
        calculated = liquid._get_calibrated_volume(volume, tip_type)
        cal_vol = calculated if calculated is not None else estimated
    else:
        cal_vol = estimated
    return cal_vol


def compact_from_uint256(v):
    """Convert uint256 to compact encoding
    """
    nbytes = v.bit_length() + 7 >> 3
    compact = 0
    if nbytes <= 3:
        compact = (v & 16777215) << 8 * (3 - nbytes)
    else:
        compact = v >> 8 * (nbytes - 3)
        compact = compact & 16777215
    if compact & 8388608:
        compact >>= 8
        nbytes += 1
    return compact | nbytes << 24


def _get_function_name(function, class_name=None):
    """Return a string representation of the function as
    module_path.Class_name.function_name

    note: the class name is the first parent class
    """
    names = [function.__module__]
    if class_name:
        names.append(class_name)
    names.append(function.__name__)
    return '.'.join(names)


def remove(hub, subname):
    """
    Remove a pop from the hub, run the shutdown if needed
    """
    if hasattr(hub, subname):
        sub = getattr(hub, subname)
        if hasattr(sub, 'init'):
            mod = getattr(sub, 'init')
            if hasattr(mod, 'shutdown'):
                mod.shutdown()
        hub._remove_subsystem(subname)


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

        :param SharedContentUnshareDetails val:
        :rtype: EventDetails
        """
    return cls('shared_content_unshare_details', val)


def is_power2(num):
    """tests if a number is a power of two"""
    return num != 0 and num & num - 1 == 0


def single_type(input_list: list) ->bool:
    """llogic.single_type(input_list)

    Returns True if all elements of an input_list are of the same type and
    False if they are not. Usage:

    >>> alist = [3, 4, 1, 5, 2]
    >>> llogic.single_type(alist)
    True

    >>> alist = [3.1, 4, 1, 5, '2']
    >>> llogic.single_type(alist)
    False

    Note that llogic.single_type does not flatten the lists so nested lists are
    of type list:

    >>> alist = [3, 4, [1, [5, 2]]]
    >>> llogic.single_type(alist)
    False

    >>> alist = [[1, 4], [5, 7], [2], [9, 6, 10], [8, 3]]
    >>> llogic.single_type(alist)
    True

    Also note that empty lists return False:

    >>> alist = []
    >>> llogic.single_type(alist)
    False
    """
    if not isinstance(input_list, list):
        raise TypeError("'input_list' must be 'list'")
    return len(set(map(type, input_list))) == 1


def getHost():
    """
        Get the host that this port is listening for.

        @return: An L{IAddress} provider.
        """


def _calculate_degree_days(temperature_equivalent, base_temperature,
    cooling=False):
    """
    Calculates degree days, starting with a series of temperature equivalent values

    Parameters
    ----------
    temperature_equivalent : Pandas Series
    base_temperature : float
    cooling : bool
        Set True if you want cooling degree days instead of heating degree days

    Returns
    -------
    Pandas Series called HDD_base_temperature for heating degree days or
    CDD_base_temperature for cooling degree days.
    """
    if cooling:
        ret = temperature_equivalent - base_temperature
    else:
        ret = base_temperature - temperature_equivalent
    ret[ret < 0] = 0
    prefix = 'CDD' if cooling else 'HDD'
    ret.name = '{}_{}'.format(prefix, base_temperature)
    return ret


def PMID(val):
    """PubMedUniqueIdentifier"""
    return 'PMID:{}'.format(val[0])


def use_old_cz():
    """ Use the CZ lookup table from A&B's code, rather than our own. Useful for testing. """
    global cz_table
    from .anders_cz import cz_table


def aligned_bases(read):
    """Function that counts the number of aligned bases from the CIGAR string and returns and integer"""
    aligned = 0
    for cigar in read.cigar:
        if cigar[0] == 0:
            aligned += cigar[1]
        else:
            pass
    assert aligned >= 0
    return aligned


def restore_values(dest, ranges):
    """Restore a list given the description returned by `collapse_list`
    """
    for value, start, end in ranges:
        dest[start:end] = value


def contract_goto_edges(g, u):
    """Identify nodes connected with `goto` edge."""
    assert u in g
    assert g.root in g
    n = g.out_degree(u)
    if n == 0 or 1 < n:
        return
    assert n == 1, n
    _, q, d = next(iter(g.edges(u, data=True)))
    if d['stmt'] != 'goto':
        return
    assert u != q, 'loop of `goto`s detected'
    for p, _, d in g.in_edges(u, data=True):
        g.add_edge(p, q, **d)
    u_label = g.node[u].get('labels')
    if u_label is not None:
        g.node[q].setdefault('labels', set()).update(u_label)
    g.remove_node(u)
    if u == g.root:
        g.root = q


def determine_num_coefs(dates, min_coef, mid_coef, max_coef, num_obs_factor):
    """
    Determine the number of coefficients to use for the main fit procedure

    This is based mostly on the amount of time (in ordinal days) that is
    going to be covered by the model

    This is referred to as df (degrees of freedom) in the model section

    Args:
        dates: 1-d array of representative ordinal dates
        min_coef: minimum number of coefficients
        mid_coef: mid number of coefficients
        max_coef: maximum number of coefficients
        num_obs_factor: used to scale the time span

    Returns:
        int: number of coefficients to use during the fitting process
    """
    span = dates.shape[0] / num_obs_factor
    if span < mid_coef:
        return min_coef
    elif span < max_coef:
        return mid_coef
    else:
        return max_coef


def show(zelf):
    """ show the event on the server is originated on. """
    for txt in zelf._result:
        zelf.direct(txt)
    zelf._done = True
    zelf.ready()


def quote(s):
    """
    Converts a variable into a quoted string
    """
    if s[0] == s[-1] and s.startswith(("'", '"')):
        return str(s)
    return '"' + str(s) + '"'


def rotate_v1(array, k):
    """
    Rotate the entire array 'k' times
    T(n)- O(nk)

    :type array: List[int]
    :type k: int
    :rtype: void Do not return anything, modify array in-place instead.
    """
    array = array[:]
    n = len(array)
    for i in range(k):
        temp = array[n - 1]
        for j in range(n - 1, 0, -1):
            array[j] = array[j - 1]
        array[0] = temp
    return array


def colorTuple(c):
    """Return a tuple (R,G,B,A) from a QColor"""
    return c.red(), c.green(), c.blue(), c.alpha()


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['type']
    if type == 'DomainNameServer':
        return 'DhcpDnsOption'
    if type == 'SearchDomain':
        return 'DhcpSearchDomainOption'
    else:
        return 'DhcpOption'


def property_tpl(data):
    """Generates variable data, according to name, type, storage.
    Output:
        @property (nonatomic, copy) NSString *testString;
    """
    name = data['name'] if data['storage'] == 'assign' else '*{}'.format(data
        ['name'])
    result = '@property (nonatomic, {}) {} {};'.format(data['storage'],
        data['class_name'], name)
    return result


def set_tmpdir(dirname):
    """Set the temporary directory to use instead of __pycache__."""
    global _TMPDIR
    _TMPDIR = dirname


def get_atomic_numbers(mol, indices):
    """Get the atomic numbers for the specified atoms.

    Parameters
    ----------
    mol : rdkit.Chem.rdchem.Mol
        RDKit molecule instance.
    indices : list of int
        Specifying atoms.

    Returns
    -------
    list of int
        Atomic numbers computed.
    """
    atomic_numbers = []
    for i in indices:
        atom = mol.GetAtomWithIdx(i)
        atomic_numbers.append(atom.GetAtomicNum())
    return atomic_numbers


def len_in_bits(n):
    """
    Return number of bits in binary representation of @n.
    """
    try:
        return n.bit_length()
    except AttributeError:
        if n == 0:
            return 0
        return len(bin(n)) - 2


@classmethod
def register_solve(cls, name, func):
    """Adds a solve method to the Problem class.

        Parameters
        ----------
        name : str
            The keyword for the method.
        func : function
            The function that executes the solve method. This function must
            take as its first argument the problem instance to solve.
        """
    cls.REGISTERED_SOLVE_METHODS[name] = func


def psi_H_Cl_HCO3_HMW84(T, P):
    """c-a-a': hydrogen chloride bicarbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def content_types(content_type):
    """Return an ordered tuple of content types from pyxst `textual_content_type` that may be None, a
    set or a string value.
    """
    if content_type:
        if isinstance(content_type, set):
            content_types = sorted(content_type)
        else:
            if content_type == 'IDREF':
                content_type = 'NCName'
            content_types = content_type,
    else:
        content_types = ()
    return content_types


def munge_coolprop_input_prop(prop):
    """Munge an input property pair from CoolProp into our format.

    Example CoolProp input: ``XY_INPUTS``, where ``X`` and ``Y`` are one of
    ``T``, ``P``, ``Dmass``, ``Hmass``, ``Umass``, ``Q``, or ``Smass``. For
    use in ThermoState, we use lower case letters (except for T), replace
    ``D`` with ``v``, and replace ``Q`` with ``x``.

    Examples
    --------
    * ``DmassHmass_INPUTS``: ``vh``
    * ``DmassT_INPUTS``: ``vT``
    * ``PUmass_INPUTS``: ``pu``

    """
    prop = prop.replace('_INPUTS', '').replace('mass', '').replace('D', 'V')
    return prop.replace('Q', 'X').lower().replace('t', 'T')


def split_extension(file_name, special=['tar.bz2', 'tar.gz']):
    """
    Find the file extension of a file name, including support for
    special case multipart file extensions (like .tar.gz)

    Parameters
    ------------
    file_name : str
      File name
    special : list of str
      Multipart extensions
      eg: ['tar.bz2', 'tar.gz']

    Returns
    ----------
    extension : str
      Last characters after a period, or
      a value from 'special'
    """
    file_name = str(file_name)
    if file_name.endswith(tuple(special)):
        for end in special:
            if file_name.endswith(end):
                return end
    return file_name.split('.')[-1]


@classmethod
def debug(cls, message):
    """
        Logs a message with level DEBUG on this logger
        :param message: Log record content
        :type message: str
        """
    cls.log('DEBUG', message)


def is_stat(tmp):
    """
    Check if the string is a station.

    Parameters
    ----------
    tmp : str
        String to check.

    Returns
    -------
    station : str
        station identified.

    """
    station = ''
    stationlist = ['SNA', 'BEW', 'SNA', 'BEW', 'BPI', 'BFT', 'BLE', 'BLF',
        'BOSA', 'BFS', 'CVN', 'CER', 'ERS', 'FRS', 'GRM', 'HVD', 'KSR',
        'KSD', 'MSN', 'NWL', 'PRY', 'PHA', 'POF', 'POG', 'PKA', 'SLR',
        'SEK', 'SOE', 'SBO', 'SUR', 'SWZ', 'UPI', 'WIN', 'KTS', 'KT1',
        'KT2', 'KT3', 'KIM', 'TUH', 'CAV', 'BUL', 'BOS', 'SME', 'CAV',
        'NCA', 'SPB', 'JOZ', 'EVA', 'KIM', 'VIR', 'BPI', 'UMT', 'ZOM',
        'LLO', 'MZU', 'VPT', 'CGY', 'PRE', 'MDN', 'MDL', 'PSD', 'QUA']
    for i in stationlist:
        if tmp.find(i) > -1:
            station = i
    if station == '':
        tmp2 = tmp.replace('P', 'F')
        for i in stationlist:
            if tmp2.find(i) > -1:
                station = i
    return station


def p_next_stmt(p):
    """next_stmt : NEXT"""
    p[0] = ['NEXT']


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 edit_distance(str1, str2):
    """
    Compute the Levenshtein distance between @p str1 and @p str2.

    This is evolved from the Wagner-Fischer Dynamic Programming solution that
    has been posted in multiple places all over Google.
    """
    if len(str1) < len(str2):
        str1, str2 = str2, str1
    if len(str2) == 0:
        return len(str1)
    prev_row = list(range(len(str2) + 1))
    for i, char1 in enumerate(str1):
        cur_row = [i + 1]
        for j, char2 in enumerate(str2):
            insertions = prev_row[j + 1] + 1
            deletions = cur_row[j] + 1
            substitutions = prev_row[j]
            if char1 != char2:
                substitutions += 1
            cur_row.append(min(insertions, deletions, substitutions))
        prev_row = cur_row
    return prev_row[-1]


def display_list_by_prefix(names_list, starting_spaces=0):
    """Creates a help string for ``names_list`` grouped by prefix."""
    cur_prefix, result_lines = None, []
    space = ' ' * starting_spaces
    for name in sorted(names_list):
        split = name.split('_', 1)
        prefix = split[0]
        if cur_prefix != prefix:
            result_lines.append(space + prefix + ':')
            cur_prefix = prefix
        result_lines.append(space + '  * ' + name)
    return '\n'.join(result_lines)


def delete(context):
    """Delete the existing annotation on the context.
        """


def convertbits(data, frombits, tobits, pad=True):
    """General power-of-2 base conversion."""
    acc = 0
    bits = 0
    ret = []
    maxv = (1 << tobits) - 1
    max_acc = (1 << frombits + tobits - 1) - 1
    for value in data:
        if value < 0 or value >> frombits:
            return None
        acc = (acc << frombits | value) & max_acc
        bits += frombits
        while bits >= tobits:
            bits -= tobits
            ret.append(acc >> bits & maxv)
    if pad:
        if bits:
            ret.append(acc << tobits - bits & maxv)
    elif bits >= frombits or acc << tobits - bits & maxv:
        return None
    return ret


def center_crop(x, crop_h, crop_w):
    """make center crop"""
    center_h = x.shape[2] // 2
    center_w = x.shape[3] // 2
    half_crop_h = crop_h // 2
    half_crop_w = crop_w // 2
    y_min = center_h - half_crop_h
    y_max = center_h + half_crop_h + crop_h % 2
    x_min = center_w - half_crop_w
    x_max = center_w + half_crop_w + crop_w % 2
    return x[:, :, y_min:y_max, x_min:x_max]


def getInteraction():
    """
        Return the current interaction.

        :raise NoInteraction: if there isn't a current interaction.
        """


def popcorn(t=120, T=None):
    """
    Simulation of stovetop popcorn cooking.

    A fixed number of popcorn kernels are cooked are heated at the same
    temperature. This simulation returns the number of kernels that are edible
    when the pot is left on the stove for a given number of `t` seconds.

    Parameters
    ----------

    `t` is the number of seconds that the pot is left on the stove. The
    default amount, if not provided, is 120 seconds.

    Time durations less than 77 seconds are not supported. A vector (list) of
    time values is not permitted, since the goal is to perform sequential
    experimentation to determine the optimum time, with the fewest number of
    function calls.

    Returns
    -------
    The number of edible popcorn kernels. Random noise is added for realism.

    Source
    ------
    Kevin Dunn, Process Improvement using Data, Chapter 5, 2010 to 2019,
    https://learnche.org/pid

    Examples
    --------
    >>> popcorn(t=55)    # will fail
    >>> popcorn(t=120)
    >>> popcorn(t=152.2)

    >>> # What happens if we leave the pot on the stove for too long?
    >>> popcorn(t=500)

    Also see
    grocery
    manufacter

    """
    pass


def faces_select_linked_flat(sharpness: float=0.0174533):
    """Select linked faces by angle

    :param sharpness: Sharpness
    :type sharpness: float
    """
    pass


def dP_demister_dry_Setekleiv_Svendsen_lit(S, voidage, vs, rho, mu, L=1):
    """Calculates dry pressure drop across a demister, using the
    correlation in [1]_. This model is for dry demisters with no holdup only.
    Developed with literature data included as well as their own experimental
    data.

    .. math::
        \\frac{\\Delta P \\epsilon^2}{\\rho_f v^2} = 7.3 - \\frac{320}
        {69.6SL - (SL)^2 - 779} - \\frac{52.4}{161 - 4.85SL} + 27.2\\left(
        \\frac{\\mu_f \\epsilon S^2 L}{\\rho_f v}\\right)^{0.75}

    Parameters
    ----------
    S : float
        Specific area of the demister, normally ~250-1000 [m^2/m^3]
    voidage : float
        Voidage of bed of the demister material, normally ~0.98 []
    vs : float
        Superficial velocity of fluid, Q/A [m/s]
    rho : float
        Density of fluid [kg/m^3]
    mu : float
        Viscosity of fluid [Pa*s]
    L : float, optional
        Length of the demister [m]

    Returns
    -------
    dP : float
        Pressure drop across a dry demister [Pa]

    Notes
    -----
    Useful at startup and in modeling. Dry pressure drop is normally negligible
    compared to wet pressure drop. Coefficients obtained by evolutionary
    programming and may not fit data outside of the limits of the variables.

    Examples
    --------
    >>> dP_demister_dry_Setekleiv_Svendsen_lit(S=250, voidage=.983, vs=1.2, rho=10, mu=3E-5, L=1)
    209.083848658307

    References
    ----------
    .. [1] Setekleiv, A. Eddie, and Hallvard F. Svendsen. "Dry Pressure Drop in
       Spiral Wound Wire Mesh Pads at Low and Elevated Pressures." Chemical
       Engineering Research and Design 109 (May 2016): 141-149.
       doi:10.1016/j.cherd.2016.01.019.
    """
    term = 7.3 - 320.0 / (69.6 * S * L - (S * L) ** 2 - 779) - 52.4 / (161 -
        4.85 * S * L)
    right = term + 27.2 * (mu * voidage * S ** 2 * L / rho / vs) ** 0.75
    return right * rho * vs ** 2 / voidage ** 2


def _iscomment(line):
    """
    Determine if a line is a comment line. A valid line contains at least three
    words, with the first two being integers.
    """
    if line.isspace():
        return True
    elif len(line.split()) >= 3:
        if line.split()[0].isdecimal() and line.split()[1].isdecimal():
            return False
        else:
            return True
    else:
        return True


@classmethod
def starting(cls, value):
    """Return level starting with value (case-insensitive)"""
    for member in cls:
        if member.name.startswith(value.upper()):
            return member
    raise ValueError('No level starting with {!r}'.format(value))


def write(packet, address):
    """
        Write packet to given address.
        """


def get_action_cache_key(name, argument):
    """Get an action cache key string."""
    tokens = [str(name)]
    if argument:
        tokens.append(str(argument))
    return '::'.join(tokens)


def uri_from_details(namespace: str, load_name: str, version: str,
    delimiter='/') ->str:
    """ Build a labware URI from its details.

    A labware URI is a string that uniquely specifies a labware definition.

    :returns str: The URI.
    """
    return f'{namespace}{delimiter}{load_name}{delimiter}{version}'


def hms_string(sec_elapsed):
    """
    Format seconds in H/M/S
    :param sec_elapsed:
    :return: Formatted seconds
    """
    h = int(sec_elapsed / (60 * 60))
    m = int(sec_elapsed % (60 * 60) / 60)
    s = sec_elapsed % 60.0
    return '{}:{:>02}:{:>05.2f}'.format(h, m, s)


def json_date_formatter(obj):
    """
    Used to format datetimes when serialising JSON.

    Usage: json.dumps(x, default=json_date_formatter)

    :param obj: object to serialise
    :return: serialised object
    """
    if hasattr(obj, 'isoformat'):
        return obj.isoformat()
    else:
        raise TypeError


@staticmethod
def ls8_sr_corr(img):
    """ Method to correct Landsat 8 based on Landsat 7 reflectance.
            This method scales the SR reflectance values to match LS7 reflectance
            The returned values are generally lower than input image
            based on roy et al 2016"""
    return img.select(['B2'], ['BLUE']).float().multiply(0.885).add(183).int16(
        ).addBands(img.select(['B3'], ['GREEN']).float().multiply(0.9317).
        add(123).int16()).addBands(img.select(['B4'], ['RED']).float().
        multiply(0.9372).add(123).int16()).addBands(img.select(['B5'], [
        'NIR']).float().multiply(0.8339).add(448).int16()).addBands(img.
        select(['B6'], ['SWIR1']).float().multiply(0.8639).add(306).int16()
        ).addBands(img.select(['B7'], ['SWIR2']).float().multiply(0.9165).
        add(116).int16()).addBands(img.select(['pixel_qa'], ['PIXEL_QA']).
        int16()).addBands(img.select(['radsat_qa'], ['RADSAT_QA']).int16()
        ).copyProperties(img).copyProperties(img, ['system:time_start',
        'system:time_end', 'system:index', 'system:footprint'])


def is_statsmodels_installed():
    """Test if statsmodels is installed."""
    try:
        import statsmodels
    except:
        raise IOError(
            'statsmodels not installed. See http://www.statsmodels.org/stable/install.html'
            )


@staticmethod
def from_json(blob):
    """
        Recreate a filesystem instance from JSON representation

        See ``.to_json()`` for the expected structure of the input

        Parameters
        ----------
        blob: str

        Returns
        -------
        file system instance, not necessarily of this particular class.
        """
    from .registry import _import_class, get_filesystem_class
    import json
    dic = json.loads(blob)
    protocol = dic.pop('protocol')
    try:
        cls = _import_class(dic.pop('cls'))
    except (ImportError, ValueError, RuntimeError, KeyError):
        cls = get_filesystem_class(protocol)
    return cls(*dic.pop('args', ()), **dic)


def do_OP_ROT(stack):
    """
    >>> s = [1, 2, 3]
    >>> do_OP_ROT(s)
    >>> print(s)
    [2, 3, 1]
    """
    stack.append(stack.pop(-3))


def compare_floats(a, b, absoulte_precision=1e-12, relative_precision=None):
    """ Returns true if the absolute difference between the numbers a and b is less than the precision.

    Arguments:
    a -- a float
    b -- a float

    Keyword Arguments (optional):
    absolute_precision -- the absolute precision, abs(a-b) of the comparison.
    relative_precision -- the relative precision, max(a,b)/min(a,b) - 1. of the comparison.

    Returns:
    True if the numbers are the same within the limits of the precision.
    False if the number are not the same within the limits of the precision.
    """
    if relative_precision is None:
        absolute = abs(a - b)
        if absolute < absoulte_precision:
            return True
        else:
            return False
    else:
        relative = max(a, b) / min(a, b) - 1.0
        if relative < relative_precision:
            return True
        else:
            return False


def _table_row(line):
    """
    Return all elements of a data line.

    Return all elements of a data line. Simply splits it.

    Parameters
    ----------
    line: string
        A stats line.

    Returns
    -------
    list of strings
        A list of strings, containing the data on the line, split at white space.
    """
    return line.split()


def mbar2inhg(press_mbar):
    """Convert pressure value from mbar to inHg"""
    return press_mbar / 33.8639


def getInfo(requestor, service, nodeIdentifier):
    """
        Get node type and meta data.

        @param requestor: The entity the request originated from.
        @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param service: The publish-subscribe service entity.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: Identifier of the node to request the info for.
        @type nodeIdentifier: C{unicode}
        @return: A deferred that fires with a dictionary. If not empty,
                 it must have the keys C{'type'} and C{'meta-data'} to keep
                 respectively the node type and a dictionary with the meta
                 data for that node.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def _check_inputs(X, y=None):
    """Converts a matrix X into a list of lists and a vector y into a list."""
    new_X = []
    for row in X:
        new_row = []
        for val in row:
            new_row.append(float(val))
        new_X.append(new_row)
    if y is None:
        return new_X
    else:
        new_y = []
        for val in y:
            try:
                new_y.append(float(val))
            except:
                new_y.append(float(val[0]))
        assert len(X) == len(y), 'Dimensions of X and y do not match.'
        return new_X, new_y


@classmethod
def start_first_scene(cls):
    """
        Start the first scene
        """
    cls.current_running_scene = cls.scenes_list[0]()
    cls.current_running_scene_index = 0
    cls.current_running_scene.start()
    cls.current_running_scene.scene_loop()


def get_paginator(operation_name=None):
    """
    Create a paginator for an operation.

    :type operation_name: string
    :param operation_name: The operation name. This is the same name
            as the method name on the client. For example, if the
            method name is create_foo, and you'd normally invoke the
            operation as client.create_foo(**kwargs), if the
            create_foo operation can be paginated, you can use the
            call client.get_paginator('create_foo').

    :rtype: L{botocore.paginate.Paginator}
    """
    pass


def rfile(node):
    """
    A function to return the results of a Node's rfile() method,
    if it exists, and the Node itself otherwise (if it's a Value
    Node, e.g.).
    """
    try:
        rfile = node.rfile
    except AttributeError:
        return node
    else:
        return rfile()


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


def pathfor(request, *args, **kwargs):
    """Generate relative url for request using route definitions, ``args``
        and ``kwargs``. To learn more about ``args`` and ``kwargs``,
        refer corresponding router's :meth:`pathfor` interface method. Returns
        a URL path as string.

        ``request``,
            The :class:`IHTTPRequest` object for which url is generated.
        """


def get_host(environ):
    """Return the real host for the given WSGI environment.  This takes care
    of the `X-Forwarded-Host` header.

    :param environ: the WSGI environment to get the host of.
    """
    scheme = environ.get('wsgi.url_scheme')
    if 'HTTP_X_FORWARDED_HOST' in environ:
        result = environ['HTTP_X_FORWARDED_HOST']
    elif 'HTTP_HOST' in environ:
        result = environ['HTTP_HOST']
    else:
        result = environ['SERVER_NAME']
        if (scheme, str(environ['SERVER_PORT'])) not in (('https', '443'),
            ('http', '80')):
            result += ':' + environ['SERVER_PORT']
    if result.endswith(':80') and scheme == 'http':
        result = result[:-3]
    elif result.endswith(':443') and scheme == 'https':
        result = result[:-4]
    return result


def containsOnly(str, set):
    """Check whether sequence str contains ONLY items in set."""
    for c in str:
        if c not in set:
            return 0
    return 1


def topScore(L1, L2, sharedScoresO):
    """Find the best norm score between genes in L1 and L2. Return the index of
each and the score."""
    besti1 = 0
    besti2 = 0
    bestSc = -float('inf')
    for i1, gn1 in enumerate(L1):
        for i2, gn2 in enumerate(L2):
            sc = sharedScoresO.getScoreByEndNodes(gn1, gn2, 'rawSc')
            if sc != None and sc > bestSc:
                bestSc = sc
                besti1 = i1
                besti2 = i2
    return besti1, besti2, bestSc


def JSONObjectReader(registry, fi, deref=False):
    """Stream objects from a JSON file.

    :param registry: serialisation registry.
    :param fi: input file
    :param deref: flag, if True, objects will be dereferenced on decoding,
        otherwise we are lazy about decoding a JSON string.
    """
    for line in fi:
        yield registry.from_json(line, deref=deref)


def expected(typ, val=None):
    """
    Return an indication of expected input and the position where it was
    expected and not encountered.
    """
    return [('expected', typ, val)]


@staticmethod
def list_from_matrix(A, m, n):
    """Convert a Matlab matrix to a Python list."""
    nlist = []
    for row in range(m):
        nlist.append([None] * n)
        for col in range(n):
            nlist[row][col] = A[row, col]
    return nlist


def dellist():
    """
    @api {post} /music/collect/dellist 取消收藏歌单
    @apiVersion 1.0.0
    @apiGroup Collect
    @apiDescription 取消收藏歌单

    @apiParam (Headers) {string} token 令牌
    @apiParam (Headers) {String} device_token 设备令牌
    @apiParam (Headers) {String} content_type 内容类型
    @apiParam (Headers) {String} timestamp 时间戳

    @apiParam (Body) {String} selflist 自建歌单
    @apiParam (Body) {String} playlistid 播放列表编号

    @apiSuccessExample {json} Success-Response:
    "Success."

    @apiError (Error) 31013 No selflist in the request params!

    @apiErrorExample {json} Error-Response:
    {
        "data": "No selflist in the request params!"
    }
    """


@staticmethod
def max_number_sequences(n):
    """
        Returns the maximum number of sequences
        given the number of dices.
        """
    res = []
    for k in range(1, n + 1):
        res.append(((6.0 * n / k) ** k, k))
    return max(res)


def last(iterable):
    """
    Return the last item from the iterable, discarding the rest.

    >>> last(range(20))
    19
    >>> last([])
    Traceback (most recent call last):
    ...
    ValueError: Iterable contains no items
    """
    for item in iterable:
        pass
    try:
        return item
    except NameError:
        raise ValueError('Iterable contains no items')


def apply_ants_transform_to_image(transform, image, reference,
    interpolation='linear'):
    """
    Apply transform to an image

    ANTsR function: `applyAntsrTransformToImage`

    Arguments
    ---------
    image : ANTsImage
        image to which the transform will be applied

    reference : ANTsImage
        reference image

    interpolation : string
        type of interpolation to use

    Returns
    -------
    list : transformed vector

    Example
    -------
    >>> import ants
    >>> img = ants.image_read(ants.get_ants_data("r16")).clone('float')
    >>> tx = ants.new_ants_transform(dimension=2)
    >>> tx.set_parameters((0.9,0,0,1.1,10,11))
    >>> img2 = tx.apply_to_image(img, img)
    """
    return transform.apply_to_image(image, reference, interpolation)


def _format_defaults(value):
    """
    Format value to CLI syntax.

    Example usage: if default value of a parameter is ['gene'], the description
    in CLI would be::

        (default: ['gene'])

    After using this function the description is tailored to CLI usage::

        (default: gene)
    """
    if isinstance(value, list):
        return ' '.join(value)
    else:
        return value


def _mul(lhs=None, rhs=None, name=None, attr=None, out=None, **kwargs):
    """Multiplies arguments element-wise.

    The storage type of ``elemwise_mul`` output depends on storage types of inputs

       - elemwise_mul(default, default) = default
       - elemwise_mul(row_sparse, row_sparse) = row_sparse
       - elemwise_mul(default, row_sparse) = row_sparse
       - elemwise_mul(row_sparse, default) = row_sparse
       - elemwise_mul(csr, csr) = csr
       - otherwise, ``elemwise_mul`` generates output with default storage

    Parameters
    ----------
    lhs : Symbol
        first input
    rhs : Symbol
        second input

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

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


def assert_block32_length(data):
    """Assert that data length is at a 32-bit boundary"""
    rem_bytes = len(data) % 4
    assert 0 == rem_bytes, 'data must be 32-bit aligned; len={}  rem_bytes={}'.format(
        len(data), rem_bytes)


def ramp(s, width, annealing_time):
    """Schedule with a ramp shape.

    Args:
        s (float):
            The mid-point of the ramp, as a fraction of the annealing time.

        width (float):
            The width of the ramp, as a fraction of the annealing time. Note
            that QPUs have a maximum slope.

        annealing_time (float):
            The total annealing time, in microseconds.

    Returns:
        list[2-tuple]: The points defining in a piece-wise curve in the shape of
        a ramp.

    Examples:
        This example constructs a schedule for a QPU that supports
        configuring an `h_gain_schedule`.

        >>> sampler = DWaveSampler(solver=dict(annealing_time=True,
                                               h_gain_schedule=True))
        >>> h = {v: -1 for v in sampler.nodelist}
        >>> schedule = ramp(.5, .2, sampler.properties['default_annealing_time'])
        >>> sampleset = sampler.sample_ising(h, {}, h_gain_schedule=schedule)

    """
    if s <= 0 or s >= 1:
        raise ValueError('s should be in interval (0, 1)')
    if width >= min(s, 1 - s) / 2:
        raise ValueError('given width takes curve outside of [0, 1] interval')
    return [(0, 0), (annealing_time * (s - width / 2), 0), (annealing_time *
        (s + width / 2), 1), (annealing_time, 1)]


def get_regexp_pattern(regexp):
    """
    Helper that returns regexp pattern from given value.

    :param regexp: regular expression to stringify
    :type regexp: _sre.SRE_Pattern or str
    :returns: string representation of given regexp pattern
    :rtype: str
    """
    try:
        return regexp.pattern
    except AttributeError:
        return str(regexp)


def setVocabularyRegistry(registry):
    """Set the vocabulary registry."""
    global _vocabularies
    _vocabularies = registry


def get_admin_extension_href(href):
    """Returns sys admin version of a given vCD url.

    This function is idempotent, which also means that if input href is already
    an admin extension href no further action would be taken.

    :param str href: the href whose sys admin version we need.

    :return: sys admin version of the href.

    :rtype: str
    """
    if '/api/admin/extension/' in href:
        return href
    elif '/api/admin/' in href:
        return href.replace('/api/admin/', '/api/admin/extension/')
    else:
        return href.replace('/api/', '/api/admin/extension/')


@classmethod
def split(cls, s):
    """
        Split an OID string.

        :param s: An OID string Eg: (1.2.3)
        :type s: str
        :return: A list of OID parts.
        :rtype: [str,]
        """
    return s.split('.')


def _region_list():
    """Returns a static list of AWS regions for bash completion"""
    return ['eu-north-1', 'ap-south-1', 'eu-west-3', 'eu-west-2',
        'eu-west-1', 'ap-northeast-2', 'ap-northeast-1', 'sa-east-1',
        'ca-central-1', 'ap-southeast-1', 'ap-southeast-2', 'eu-central-1',
        'us-east-1', 'us-east-2', 'us-west-1', 'us-west-2']


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 disconnect(server):
    """disconnect from the mail server"""
    if server:
        server.quit()


@staticmethod
def _is_end_regex(word):
    """Returns `True` if `word` is the end of a regex."""
    return word.endswith('/') or word.endswith('/g') or word.endswith('/i'
        ) or word.endswith('/ig') or word.endswith('/gi')


def timezone():
    """Return the timezone in which the object is represented."""


def select_worstcase_snapshots(network):
    """
    Select two worst-case snapshots from time series

    Two time steps in a time series represent worst-case snapshots. These are

    1. Load case: refers to the point in the time series where the
        (load - generation) achieves its maximum and is greater than 0.
    2. Feed-in case: refers to the point in the time series where the
        (load - generation) achieves its minimum and is smaller than 0.

    These two points are identified based on the generation and load time
    series. In case load or feed-in case don't exist None is returned.

    Parameters
    ----------
    network : :class:`~.grid.network.Network`
        Network for which worst-case snapshots are identified.

    Returns
    -------
    :obj:`dict`
        Dictionary with keys 'load_case' and 'feedin_case'. Values are
        corresponding worst-case snapshots of type
        :pandas:`pandas.Timestamp<timestamp>` or None.

    """
    timeseries_load_feedin_case = network.timeseries.timesteps_load_feedin_case
    timestamp = {}
    timestamp['load_case'] = timeseries_load_feedin_case.residual_load.idxmax(
        ) if max(timeseries_load_feedin_case.residual_load) > 0 else None
    timestamp['feedin_case'
        ] = timeseries_load_feedin_case.residual_load.idxmin() if min(
        timeseries_load_feedin_case.residual_load) < 0 else None
    return timestamp


def callmethod_if(o, method, default=None, a=None, kw=None):
    """ Call the named `method` on the object `o` if it exists.

      If it does not exist, return `default` (which defaults to None).
      Otherwise call getattr(o, method)(*a, **kw).
      `a` defaults to ().
      `kw` defaults to {}.
  """
    try:
        m = getattr(o, method)
    except AttributeError:
        return default
    if a is None:
        a = ()
    if kw is None:
        kw = {}
    return m(*a, **kw)


def _max_jaccard_underneath_internal_node(node, mh):
    """    calculate the maximum possibility similarity score below
    this node, based on the number of matches in 'hashes' at this node,
    divided by the smallest minhash size below this node.

    This should yield be an upper bound on the Jaccard similarity
    for any signature below this point.
    """
    if len(mh) == 0:
        return 0.0
    matches = node.data.matches(mh)
    min_n_below = node.metadata.get('min_n_below', -1)
    if min_n_below == -1:
        raise Exception(
            'cannot do similarity search on this SBT; need to rebuild.')
    max_score = float(matches) / min_n_below
    return max_score


@classmethod
def is_integrity_error(cls, exception):
    """Check if given exception flags an integrity error in the DB"""
    raise NotImplementedError('Implement in subclass')


def split_once_or_fail_with(strink, pattern, error_message):
    """
    split selected string (string is a builtin, hence strink) using the given pattern;
    raise RuntimeError with provided error message if that fails

    :param strink: str, string to split
    :param pattern: str, pattern to split on
    :param error_message: str, error message to raise in case of split fails
    :return: (str, str)
    """
    try:
        k, v = strink.split(pattern, 1)
    except ValueError:
        raise RuntimeError(error_message)
    return k, v


@classmethod
def middle(cls, p0, p1):
    """ Return the middle point. """
    return cls(p0 + p1) * 0.5


def family_compare(a, b, attrs, flags):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/genl/family.c#L150

    Positional arguments:
    a -- nl_object class instance.
    b -- nl_object class instance.
    attrs -- integer.
    flags -- integer.

    Returns:
    Integer.
    """
    raise NotImplementedError


def as_bytes(data):
    """Convert input string or json value into bytes.
    """
    if isinstance(data, str):
        return data.encode('utf8')
    if isinstance(data, int):
        return b'%d' % data
    if isinstance(data, float):
        return b'%r' % data
    if isinstance(data, bool):
        return data and b't' or b'f'
    raise ValueError('Invalid input type for hashing: %s' % type(data))


def p_field_decl(p):
    """field_decl : field_name_decl COLON gql_type"""
    p[0] = p[1], p[3]


@classmethod
def _specialize_clusters(cls, clusters, **kwargs):
    """
        Backend hook for specialization at the Cluster level.
        """
    return clusters