def same_variable(a, b):
    """
    Cette fonction dit si les deux objets sont en fait le même objet (True)
    ou non (False) s'ils sont différents (même s'ils contiennent la même information).

    @param      a       n'importe quel objet
    @param      b       n'importe quel objet
    @return             ``True`` ou ``False``

    .. faqref::
        :tag: python
        :title: Qu'est-ce qu'un type immuable ou immutable ?
        :lid: faq-py-immutable

        Une variable de type *immuable* ne peut être modifiée. Cela concerne principalement :

        - ``int``, ``float``, ``str``, ``tuple``

        Si une variable est de type *immuable*, lorsqu'on effectue une opération,
        on créé implicitement une copie de l'objet.

        Les dictionnaires et les listes sont *modifiables* (ou *mutable*). Pour une variable
        de ce type, lorsqu'on écrit ``a = b``, ``a`` et ``b`` désigne le même objet même
        si ce sont deux noms différentes. C'est le même emplacement mémoire
        accessible paur deux moyens (deux identifiants).

        Par exemple ::

            a  = (2,3)
            b  = a
            a += (4,5)
            print( a == b ) # --> False
            print(a,b)      # --> (2, 3, 4, 5) (2, 3)

            a  = [2,3]
            b  = a
            a += [4,5]
            print( a == b ) # --> True
            print(a,b)      # --> [2, 3, 4, 5] [2, 3, 4, 5]

        Dans le premier cas, le type (``tuple``) est _immutable_, l'opérateur ``+=`` cache implicitement une copie.
        Dans le second cas, le type (``list``) est _mutable_, l'opérateur ``+=`` évite la copie
        car la variable peut être modifiée. Même si ``b=a`` est exécutée avant l'instruction suivante,
        elle n'a **pas** pour effet de conserver l'état de ``a`` avant l'ajout d'élément.
        Un autre exemple ::

            a  = [1, 2]
            b  = a
            a [0] = -1
            print(a)        # --> [-1, 2]
            print(b)        # --> [-1, 2]

        Pour copier une liste, il faut expliciter la demander ::

            a  = [1, 2]
            b  = list(a)
            a [0] = -1
            print(a)        # --> [-1, 2]
            print(b)        # --> [1, 2]

        La page `Immutable Sequence Types <https://docs.python.org/3/library/stdtypes.html?highlight=immutable#immutable-sequence-types>`_
        détaille un peu plus le type qui sont *mutable* et ceux qui sont *immutable*. Parmi les types standards :

        * **mutable**
            * `bool <https://docs.python.org/3/library/functions.html#bool>`_
            * `int <https://docs.python.org/3/library/functions.html#int>`_,
              `float <https://docs.python.org/3/library/functions.html#float>`_,
              `complex <https://docs.python.org/3/library/functions.html#complex>`_
            * `str <https://docs.python.org/3/library/functions.html#func-str>`_,
              `bytes <https://docs.python.org/3/library/functions.html#bytes>`_
            * `None <https://docs.python.org/3/library/constants.html?highlight=none#None>`_
            * `tuple <https://docs.python.org/3/library/functions.html#func-tuple>`_,
              `frozenset <https://docs.python.org/3/library/functions.html#func-frozenset>`_
        * **immutable**, par défaut tous les autres types dont :
            * `list <https://docs.python.org/3/library/functions.html#func-list>`_
            * `dict <https://docs.python.org/3/library/functions.html#func-dict>`_
            * `set <https://docs.python.org/3/library/functions.html#func-set>`_
            * `bytearray <https://docs.python.org/3/library/functions.html#bytearray>`_

        Une instance de classe est mutable. Il est possible de la rendre
        immutable par quelques astuces :

        * `__slots__ <https://docs.python.org/3/reference/datamodel.html?highlight=_slots__#object.__slots__>`_
        * `How to Create Immutable Classes in Python <http://www.blog.pythonlibrary.org/2014/01/17/
          how-to-create-immutable-classes-in-python/>`_
        * `Ways to make a class immutable in Python <http://stackoverflow.com/questions/4996815/
          ways-to-make-a-class-immutable-in-python>`_
        * `freeze <https://freeze.readthedocs.org/en/latest/>`_

        Enfin, pour les objects qui s'imbriquent les uns dans les autres, une liste de listes, une classe
        qui incluent des dictionnaires et des listes, on distingue une copie simple d'une copie intégrale (**deepcopy**).
        Dans le cas d'une liste de listes, la copie simple recopie uniquement la première liste ::

            import copy
            l1 = [ [0,1], [2,3] ]
            l2 = copy.copy(l1)
            l1 [0][0] = '##'
            print(l1,l2)        # --> [['##', 1], [2, 3]] [['##', 1], [2, 3]]

            l1 [0] = [10,10]
            print(l1,l2)        # --> [[10, 10], [2, 3]] [['##', 1], [2, 3]]

        La copie intégrale recopie également les objets inclus ::

            import copy
            l1 = [ [0,1], [2,3] ]
            l2 = copy.deepcopy(l1)
            l1 [0][0] = '##'
            print(l1,l2)        # --> [['##', 1], [2, 3]] [[0, 1], [2, 3]]

        Les deux fonctions s'appliquent à tout object Python : `module copy <https://docs.python.org/3/library/copy.html>`_.
    """
    return id(a) == id(b)


def get_error_code(client_error):
    """Get the error code from a ClientError (as errorfactory is magic).

    :param pool: the client error exception
    :type pool: :class:`~botocore.client.ClientError`
    :return: The error code or None
    """
    return client_error.response.get('Error', {}).get('Code')


def complete_vault_lock(accountId=None, vaultName=None, lockId=None):
    """
    This operation completes the vault locking process by transitioning the vault lock from the InProgress state to the Locked state, which causes the vault lock policy to become unchangeable. A vault lock is put into the InProgress state by calling  InitiateVaultLock . You can obtain the state of the vault lock by calling  GetVaultLock . For more information about the vault locking process, Amazon Glacier Vault Lock .
    This operation is idempotent. This request is always successful if the vault lock is in the Locked state and the provided lock ID matches the lock ID originally used to lock the vault.
    If an invalid lock ID is passed in the request when the vault lock is in the Locked state, the operation returns an AccessDeniedException error. If an invalid lock ID is passed in the request when the vault lock is in the InProgress state, the operation throws an InvalidParameter error.
    See also: AWS API Documentation

    Examples
    The example completes the vault locking process by transitioning the vault lock from the InProgress state to the Locked state.
    Expected Output:

    :example: response = client.complete_vault_lock(
        vaultName='string',
        lockId='string'
    )

    :type accountId: string
    :param accountId: The AccountId value is the AWS account ID. This value must match the AWS account ID associated with the credentials used to sign the request. You can either specify an AWS account ID or optionally a single '- ' (hyphen), in which case Amazon Glacier uses the AWS account ID associated with the credentials used to sign the request. If you specify your account ID, do not include any hyphens ('-') in the ID.
            Note: this parameter is set to '-' bydefault if no value is not specified.

    :type vaultName: string
    :param vaultName: [REQUIRED]
            The name of the vault.

    :type lockId: string
    :param lockId: [REQUIRED]
            The lockId value is the lock ID obtained from a InitiateVaultLock request.

    :return: response = client.complete_vault_lock(
        accountId='-',
        lockId='AE863rKkWZU53SLW5be4DUcW',
        vaultName='example-vault',
    )

    print(response)

    """
    pass


@classmethod
def all(cls):
    """Возвращает все записи объекта/таблицы."""
    return cls.query().all()


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

        :param SharedFolderCreateType val:
        :rtype: EventType
        """
    return cls('shared_folder_create', val)


def typeName(cls):
    """Get the name of a field/event"""
    if hasattr(cls, 'fieldType'):
        return cls.fieldType
    else:
        return cls.__name__.split('.')[-1]


def setoperator(op):
    """
    Returns a function which performs set operations
    """
    if op == '|':
        return lambda x, y: x | y
    if op == '&':
        return lambda x, y: x & y
    if op == '-':
        return lambda x, y: x - y
    raise Exception('operator %s not found' % op)


@classmethod
def from_dict(cls, connector, ip_dict):
    """Build dict fields as SubObjects if needed.

        Checks if lambda for building object from dict exists.
        _global_field_processing and _custom_field_processing rules
        are checked.
        """
    mapping = cls._global_field_processing.copy()
    mapping.update(cls._custom_field_processing)
    for field in mapping:
        if field in ip_dict:
            ip_dict[field] = mapping[field](ip_dict[field])
    return cls(connector, **ip_dict)


def expand_tabs(line: str) ->str:
    """
    Tabs are treated as 1-8 spaces according to
    https://docs.python.org/3/reference/lexical_analysis.html#indentation

    Given a string with tabs, this removes all tab characters and replaces them with the
    appropriate number of spaces.
    """
    result_list = []
    total = 0
    for ch in line:
        if ch == '\t':
            prev_total = total
            total = (total + 8) // 8 * 8
            result_list.append(' ' * (total - prev_total))
        else:
            total += 1
            result_list.append(ch)
    return ''.join(result_list)


def is_commended_function(line: str) ->bool:
    """
    Check if function is commended.
    """
    return line.strip()[0] == '#'


def sparse_iterator(items, num_steps):
    """Sparse iteration over `items`. Every element of the list `items` is
    returned exactly once, but with a different order which can be tweaked by
    changing `num_steps`. The i-th invocation of the iterator roughly returns
    items[i*len(items)//num_steps].
    """
    assert num_steps >= 1
    items = list(items)
    idx = 0
    while items:
        if idx >= len(items):
            idx = idx % len(items)
        yield items[idx]
        items.pop(idx)
        idx += len(items) // num_steps


def p_encaps_var_curly_variable(p):
    """encaps_var : CURLY_OPEN variable RBRACE"""
    p[0] = p[2]


@staticmethod
def get_short_arguments():
    """Return short arguments for the base fields."""
    return dict(d='description', f='frequency', g='generator', l='length')


def dotify(name):
    """ Add a dot to the end of the name if it wasn't there.
    """
    if not name.endswith('.'):
        return '%s.' % name
    return name


def get_thumbnail(format):
    """Return a piece of HTML with the thumbnail of the first
        document image.
        """


def assert_nx_graph_eq(g1, g2):
    """Assertion function for graph equality."""
    assert set(g1.nodes()) == set(g2.nodes())
    assert set(g1.edges()) == set(g2.edges())
    for n in g1.nodes():
        assert g1.node[n] == g2.node[n]
    for e1, e2 in g1.edges():
        assert g1.adj[e1][e2] == g2.adj[e1][e2]
    return


@classmethod
def from_result(cls, story, deprecations):
    """
        Creates a CompilationResult from a result.
        """
    return cls(story, errors=[], deprecations=deprecations)


def is_wall(maze, y, x):
    """Return weather the cell (x, y) is wall."""
    return maze[y][x] != '0'


@staticmethod
def make_message(topic, datamessage):
    """
        Wraps given datamessage into a json-payload

        :param str topic: mqtt topic
        :param DataMessage datamessage: a datamessage object
        :return: tuple of topic and json payload
        :rtype: tuple
        """
    payload = datamessage.to_json()
    return topic, payload


def generate_oauth_headers(access_token: str) ->dict:
    """Convenience function to generate oauth stand authorization header

    :param access_token: Oauth access token
    :return: Request headers
    """
    return {'Authorization': 'Bearer ' + access_token}


def _table_is_free(table_name, dependencies, sorted_tables):
    """Check if every child of this table is already sorted

    Look at the unit test test_table_is_free_simple to see some
    usage examples.
    """
    tables_this_table_depends_upon = dependencies.get(table_name, {})
    for dependency in tables_this_table_depends_upon.copy():
        if dependency.table_name_to in sorted_tables:
            tables_this_table_depends_upon.remove(dependency)
    return len(tables_this_table_depends_upon) == 0


def _convert_hex_str_to_int(val):
    """Convert hexadecimal formatted ids to signed int64"""
    if val is None:
        return None
    hex_num = int(val, 16)
    if hex_num > 9223372036854775807:
        hex_num -= 18446744073709551616
    assert -9223372036854775808 <= hex_num <= 9223372036854775807
    return hex_num


def processEnded(reason):
    """
        Called when the child process exits and all file descriptors associated
        with it have been closed.

        @type reason: L{twisted.python.failure.Failure}
        @param reason: A failure giving the reason the child process
            terminated.  The type of exception for this failure is either
            L{twisted.internet.error.ProcessDone} or
            L{twisted.internet.error.ProcessTerminated}.
        """


def displayMessage(message):
    """Print a message for the player."""
    print(message)


@staticmethod
def _setup_log_file(log_file):
    """
        Open a log file if necessary and return the file handle. This will create a file if it does not exist

        :param string log_file: Path to a file where the logs should be written to
        :return: Handle to the opened log file, if necessary. None otherwise
        """
    if not log_file:
        return None
    return open(log_file, 'wb')


def get_motif_names():
    """
  Get common motif names.

  Get the names of some common motifs as strings.

  Returns
  -------
  motif_names : list
    A list of names (strings) of common motifs.
  """
    motif_names = ['Ms', 'Md']
    for i in range(1, 14):
        motif_name = 'M' + str(i)
        motif_names = motif_names + [motif_name]
    motif_names = motif_names + ['Mcoll'] + ['Mexpa']
    return motif_names


def bake_action_iter(obj: 'bpy.types.Object', *, action: 'bpy.types.Action',
    only_selected: bool=False, do_pose: bool=True, do_object: bool=True,
    do_visual_keying: bool=True, do_constraint_clear: bool=False,
    do_parents_clear: bool=False, do_clean: bool=False) ->'bpy.types.Action':
    """An coroutine that bakes action for a single object.

    :param obj: Object to bake.
    :type obj: 'bpy.types.Object'
    :param action: An action to bake the data into, or None for a new action to be created.
    :type action: 'bpy.types.Action'
    :param only_selected: Only bake selected bones.
    :type only_selected: bool
    :param do_pose: Bake pose channels.
    :type do_pose: bool
    :param do_object: Bake objects.
    :type do_object: bool
    :param do_visual_keying: Use the final transformations for baking (‘visual keying’)
    :type do_visual_keying: bool
    :param do_constraint_clear: Remove constraints after baking.
    :type do_constraint_clear: bool
    :param do_parents_clear: Unparent after baking objects.
    :type do_parents_clear: bool
    :param do_clean: Remove redundant keyframes after baking.
    :type do_clean: bool
    :return:  an action or None
    """
    pass


@classmethod
def from_json_file(cls, filename, **kwargs):
    """Instantiate a JSONSchema object from a JSON file"""
    import json
    with open(filename) as f:
        schema = json.load(f)
    return cls(schema, **kwargs)


def stringify(val):
    """
    Accepts either str or bytes and returns a str
    """
    try:
        val = val.decode('utf-8')
    except (UnicodeDecodeError, AttributeError):
        pass
    return val


@classmethod
def _build_hash(cls):
    """Clear hash and rebuild hash by rules"""
    raise NotImplementedError()


def connect_terminals(vertices, terminals, genes):
    """
    Add the connections from *terminals* associated to the given *genes* to the
    graph *vertices*.

    Parameters
    ----------
    vertices : DataFrame
        Dataframe of the street graph plus the connection nodes.
    terminals : DataFrame
        Dataframe of the terminals to connect to the graph.
    genes : list
        List of terminal single connections of the considered configuration.

    Returns
    -------
    DataFrame
        Updated *vertices* dataframe.
    """
    tst_vertices = vertices.copy()
    n = len(tst_vertices)
    for i, a in enumerate(genes):
        terminal = terminals.iloc[i]
        tst_vertices.at[n + i, 'idA'] = terminal.name
        tst_vertices.at[n + i, 'idB'] = terminal['_id'][a]
        tst_vertices.at[n + i, 'geometry'] = terminal['_geometry'][a]
        tst_vertices.at[n + i, 'weight'] = terminal['_weight'][a]
    return tst_vertices


def partials_stretch(partials, factor, inplace=False):
    """
    Stretch the partials in time by a given constant factor

    Args:
        partials: a list of partials
        factor: float
            a factor to multiply all times by
        inplace:
            modify partials in place
    """
    if inplace:
        for p in partials:
            p[:, (0)] *= factor
        return partials
    else:
        out = []
        for p in partials:
            p = p.copy()
            p[:, (0)] *= factor
            out.append(p)
        return out


@classmethod
def allowed_is_valid(cls, allowed):
    """
        Make sure that all of the required fields are present, and that
        bucketId is set if bucketName is.

        If the bucketId is for a bucket that no longer exists, or the
        capabilities do not allow for listBuckets, then we will not have a bucketName.

        :param dict allowed: the structure to use for old account info that was saved without 'allowed'
        :rtype: bool
        """
    return 'bucketId' in allowed and 'bucketName' in allowed and (allowed[
        'bucketId'] is not None or allowed['bucketName'] is None
        ) and 'capabilities' in allowed and 'namePrefix' in allowed


def _padded(region, pad):
    """
    >>> _padded([1, 1, 4, 4], [0, 1, 2 ,3])
    (1, 0, 6, 7)
    >>> _padded([1, 1, 4, 4], 2)
    (-1, -1, 6, 6)
    """
    if not pad:
        return region
    if isinstance(pad, (int, float)):
        pad = pad, pad, pad, pad
    return region[0] - pad[0], region[1] - pad[1], region[2] + pad[2], region[3
        ] + pad[3]


def pygments_token_to_classname(token: 'Token') ->str:
    """
    Turn e.g. `Token.Name.Exception` into `'pygments.name.exception'`.

    (Our Pygments lexer will also turn the tokens that pygments produces in a
    prompt_toolkit list of fragments that match these styling rules.)
    """
    parts = ('pygments',) + token
    return '.'.join(parts).lower()


def prettyFloat(val, format='%5.2f'):
    """output a float or "na" if not defined"""
    try:
        x = format % val
    except (ValueError, TypeError):
        x = 'na'
    return x


def guess_decode(text):
    """Decode *text* with guessed encoding.

    First try UTF-8; this should fail for non-UTF-8 encodings.
    Then try the preferred locale encoding.
    Fall back to latin-1, which always works.
    """
    try:
        text = text.decode('utf-8')
        return text, 'utf-8'
    except UnicodeDecodeError:
        try:
            import locale
            prefencoding = locale.getpreferredencoding()
            text = text.decode()
            return text, prefencoding
        except (UnicodeDecodeError, LookupError):
            text = text.decode('latin1')
            return text, 'latin1'


def adapt_shape_array(X, shape_must_be):
    """
    This function takes care of the unspecified dimensions in the required shapes of data structures.
    The None elements in the shape tuple will be replaced with actual shape of the input array.

    Parameters
    ----------
    X: ndarray
        The input numpy array.

    shape_must_be: tuple
        The required shape of the input array, might contains None elements.

    Returns
    -------
    tuple
        The actual shape with no None elements.

    """
    if None in shape_must_be:
        copy_shape_must_be = list(shape_must_be)
        while None in copy_shape_must_be:
            ind = copy_shape_must_be.index(None)
            copy_shape_must_be[ind] = X.shape[ind]
        return tuple(copy_shape_must_be)
    else:
        return shape_must_be


def output_clip(score, min_score=0, max_score=100):
    """
      Limits the output of the score between min_score and max_score

    :param score:
    :param min_score:
    :param max_score:
    :return:
    """
    if score < min_score:
        return 0.0
    elif score > max_score:
        return 100.0
    else:
        return score


def p_pos_parameter_types1(p):
    """
    parameter_types : pos_parameter_types1
    pos_parameter_types1 : parameter_types_list1
    pos_parameter_types : parameter_types_list
    """
    p[0] = p[1], ()


def get_target_dimension_order(out_dims, direction_to_names):
    """
    Takes in an iterable of directions ('x', 'y', 'z', or '*') and a dictionary
    mapping those directions to a list of names corresponding to those
    directions. Returns a list of names in the same order as in out_dims,
    preserving the order within direction_to_names for each direction.
    """
    target_dimension_order = []
    for direction in out_dims:
        target_dimension_order.extend(direction_to_names[direction])
    return target_dimension_order


def bin_num(n, n_bits):
    """
    Produce a signed representation of the number n using n_bits.

    :param n: Number n
    :param n_bits: Number of bits
    :return:
    """
    mask = (2 << n_bits - 1) - 1
    num = int(n) & mask
    f_str = '{:0' + str(n_bits) + 'b}'
    f_res = f_str.format(int(num))
    return f_res


@staticmethod
def get_attr_summary(provider):
    """
        Returns attr provider.

        :param CALayerIvars.CALayerIvarsSyntheticProvider provider: Attributes provider.
        :return: Attributes summary.
        :rtype: str
        """
    return provider.summary()


@staticmethod
def name_to_simple(fname):
    """ Translate name to one of simple base names.

        :return str:

        """
    fname = fname or ''
    return fname.lower().strip()


def get_code_type(code):
    """
    判断代码是属于那种类型，目前仅支持 ['fund', 'stock']
    :return str 返回code类型, fund 基金 stock 股票
    """
    if code.startswith(('00', '30', '60')):
        return 'stock'
    return 'fund'


def _rectangle_size(rectangle):
    """Return the dimension of rectangle (width, height)."""
    return rectangle.upperRight[0] - rectangle.lowerLeft[0
        ], rectangle.upperRight[1] - rectangle.lowerLeft[1]


@classmethod
def getModule(cls):
    """
        Get the module name (e.g. "dhcp", "wireless") for a ConfigObject class.
        """
    parts = cls.__module__.split('.')
    return parts[-1]


def squadratic_distance(p, q):
    """ The *quadratic distance*, :math:`d_{sq}(p, q) := 2 (p - q)^2`."""
    return 2 * (p - q) ** 2


def list_numbering_start(attrs):
    """extract numbering from list element attributes"""
    if 'start' in attrs:
        return int(attrs['start']) - 1
    else:
        return 0


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

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


def first_non_none_response(responses, default=None):
    """Find first non None response in a list of tuples.

    This function can be used to find the first non None response from
    handlers connected to an event.  This is useful if you are interested
    in the returned responses from event handlers. Example usage::

        print(first_non_none_response([(func1, None), (func2, 'foo'),
                                       (func3, 'bar')]))
        # This will print 'foo'

    :type responses: list of tuples
    :param responses: The responses from the ``EventHooks.emit`` method.
        This is a list of tuples, and each tuple is
        (handler, handler_response).

    :param default: If no non-None responses are found, then this default
        value will be returned.

    :return: The first non-None response in the list of tuples.

    """
    for response in responses:
        if response[1] is not None:
            return response[1]
    return default


def _output_text(complete_output, categories):
    """Output the results obtained in text format.

    :return: str, html formatted output
    """
    output = ''
    for result in complete_output:
        list_result = complete_output[result]
        if list_result:
            list_result_sorted = sorted(list_result, key=lambda x:
                list_result[x], reverse=True)
            output += '\n\n{0}:\n'.format(result)
            for element in list_result_sorted:
                output += '\n{0} {1}'.format(list_result[element], element)
    output += '\n--'
    return output


def verification_run_events(base_verification_run_url: str) ->str:
    """
    Build the URL to communicate with the verification run event API.
    """
    return '/'.join([base_verification_run_url, 'events'])


def as_uri(value):
    """ puts <> around if not a CURIE """
    try:
        parts = value.split(':')
        if len(parts) == 2:
            return value
    except:
        pass
    return value.join('<', '>')


@classmethod
def is_interface_initialized(cls, provider_uri: str) ->bool:
    """
        Returns True if there is an existing connection with an equal provider_uri.
        """
    return bool(cls._interfaces.get(provider_uri, False))


@staticmethod
def get_prefix_position_in_list(i):
    """
        Gets the prefix for the string "ith element of the list", handling first, second, and third.
        :param i:
        :return:
        """
    prefix = '{} th '.format(str(i))
    if i == 1:
        prefix = 'first '
    elif i == 2:
        prefix = 'second '
    elif i == 3:
        prefix = 'third '
    return prefix


def has_header(path, encoding='utf-8'):
    """
    Auto-detect if csv file has header.
    """
    from pandas import read_csv
    df0 = read_csv(path, header=None, nrows=10, skipinitialspace=True,
        encoding=encoding)
    df1 = read_csv(path, nrows=10, skipinitialspace=True, encoding=encoding)
    return tuple(df0.dtypes) != tuple(df1.dtypes)


def _issubclass(sub, sup):
    """Safe issubclass().
    """
    if sup is not object:
        try:
            return issubclass(sub, sup)
        except TypeError:
            pass
    return False


def n(obj):
    """" use __class___ to return a named string of an object. """
    return str(obj.__class__).split()[-1].split('.')[-1][:-2].lower()


def addCallback(service, nodeIdentifier, callback):
    """
        Register a callback URI.

        The registered HTTP callback URI will have an Atom Entry documented
        POSTed to it upon receiving a notification for the given pubsub node.

        @param service: The XMPP entity that holds the node.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: The identifier of the publish-subscribe node.
        @type nodeIdentifier: C{unicode}.
        @param callback: The callback URI to be registered.
        @type callback: C{str}.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def chip_converter(chip):
    """Converts a chip name to usable string."""
    chip_map = {'3xc': 'TC', 'wildcard': 'WC', 'bboost': 'BB', 'freehit': 'FH'}
    return chip_map[chip]


def broadcast_mul(lhs=None, rhs=None, name=None, attr=None, out=None, **kwargs
    ):
    """Returns element-wise product of the input arrays with broadcasting.

    Example::

       x = [[ 1.,  1.,  1.],
            [ 1.,  1.,  1.]]

       y = [[ 0.],
            [ 1.]]

       broadcast_mul(x, y) = [[ 0.,  0.,  0.],
                              [ 1.,  1.,  1.]]

    Supported sparse operations:

       broadcast_mul(csr, dense(1D)) = csr

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_basic.cc:L146

    Parameters
    ----------
    lhs : Symbol
        First input to the function
    rhs : Symbol
        Second input to the function

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

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


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

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

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

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

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

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

    out : NDArray, optional
        The output NDArray to hold the result.

    Returns
    -------
    out : NDArray or list of NDArrays
        The output of this function.
    """
    return 0,


def _const_compare_digest_backport(a, b):
    """
    Compare two digests of equal length in constant time.

    The digests must be of type str/bytes.
    Returns True if the digests match, and False otherwise.
    """
    result = abs(len(a) - len(b))
    for l, r in zip(bytearray(a), bytearray(b)):
        result |= l ^ r
    return result == 0


@conf
def gcc_modifier_platform(conf):
    """Execute platform-specific functions based on *gcc_modifier_+NAME*"""
    gcc_modifier_func = getattr(conf, 'gcc_modifier_' + conf.env.DEST_OS, None)
    if gcc_modifier_func:
        gcc_modifier_func()


def interaction_plot():
    """
    Interaction plot
    """
    pass


def bin2gray(val):
    """ convert an unsigned binary number to reflected binary Gray code.
    :param val: value to convert (binary)
    :return: gray code """
    return val >> 1 ^ val


def pytest_generate_tests(metafunc):
    """ Repeating each test n times, based on --repeat argument. """
    if metafunc.config.option.repeat is not None:
        count = int(metafunc.config.option.repeat)
        metafunc.fixturenames.append('tmp_ct')
        metafunc.parametrize('tmp_ct', range(count))


def provider_parser(subparser):
    """Module provider for Dreamhost"""
    subparser.add_argument('--auth-token', help=
        'specify api key for authentication')


def _add_default_fields(ds, fields):
    """
    Add some default fields to rays to assure they can be processed correctly.
    """
    if ('gas', 'temperature') in ds.derived_field_list:
        fields.append(('gas', 'temperature'))
    if ('gas', 'H_nuclei_density') in ds.derived_field_list:
        fields.append(('gas', 'H_nuclei_density'))
    return fields


def sanitize(string):
    """
    Ensure that the text does not contain any malicious HTML code which might
    break the page.
    """
    from html5lib import parseFragment, serialize
    parsed = parseFragment(string)
    clean = serialize(parsed, sanitize=True, omit_optional_tags=False,
        quote_attr_values='always')
    return clean


@staticmethod
def converter(o):
    """Convert if possible a bytes object to a known python object."""
    if o.mimeType in ['application/x-netcdf']:
        import netCDF4 as nc
        if nc.getlibversion() > '4.5':
            return lambda x: nc.Dataset(o.fileName, memory=x)
        else:
            return None
    if o.mimeType in ['application/json']:
        import json
        return json.loads
    else:
        return None


@classmethod
def create_flavor(cls, name, description, service_type):
    """Wrapper utility that returns a test flavor."""
    body = cls.admin_client.create_flavor(description=description,
        service_type=service_type, name=name)
    flavor = body['flavor']
    cls.flavors.append(flavor)
    return flavor


def driverconclude(repo, ms, wctx, labels=None):
    """run the conclude step of the merge driver, if any

    This is currently not implemented -- it's an extension point."""
    return True


@classmethod
def loads(cls, data: bytes) ->'SOCKS5UsernamePasswordReply':
    """Unpacks the reply authentication data into an instance.

        Returns:
            The unpacked authentication reply instance.
        """
    return cls(success=data == b'\x01\x00')


def p_sub_channel_mode(t):
    """sub_channel_mode : RW
                        | RW_RAW"""
    t[0] = t[1]


def is_snp(reference_bases, alternate_bases):
    """ Return whether or not the variant is a SNP """
    if len(reference_bases) > 1:
        return False
    for alt in alternate_bases:
        if alt is None:
            return False
        if alt not in ['A', 'C', 'G', 'T', 'N', '*']:
            return False
    return True


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

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

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


@classmethod
def is_compatible(cls, download_target, osutil):
    """Determines if the target for the download is compatible with manager

        :param download_target: The target for which the upload will write
            data to.

        :param osutil: The os utility to be used for the transfer

        :returns: True if the manager can handle the type of target specified
            otherwise returns False.
        """
    raise NotImplementedError('must implement is_compatible()')


def enable_filter_traceback(enable):
    """Enable/disable replacing asynq boilerplate lines in stacktraces.

    These lines are repeated many times in stacktraces of codebases using asynq.
    By default we replace them so it's easier to read the stacktrace, but you can enable
    if you're debugging an issue where it's useful to know the exact lines.

    """
    global _should_filter_traceback
    _should_filter_traceback = enable


@classmethod
def from_pycbc(cls, fs, copy=True):
    """Convert a `pycbc.types.frequencyseries.FrequencySeries` into
        a `FrequencySeries`

        Parameters
        ----------
        fs : `pycbc.types.frequencyseries.FrequencySeries`
            the input PyCBC `~pycbc.types.frequencyseries.FrequencySeries`
            array

        copy : `bool`, optional, default: `True`
            if `True`, copy these data to a new array

        Returns
        -------
        spectrum : `FrequencySeries`
            a GWpy version of the input frequency series
        """
    return cls(fs.data, f0=0, df=fs.delta_f, epoch=fs.epoch, copy=copy)


def compare_JSON(json1, json2, raise_error=False):
    """! @brief Will compare two JSON strings, and return False if they differ. An
    extra argument can be used to force the function to raise an error with the line
    the difference was observed.
    """
    for linenumber, (line1, line2) in enumerate(zip(json1.splitlines(),
        json2.splitlines())):
        if line1 != line2:
            if raise_error:
                raise Exception('JSON differs at line: ' + str(linenumber))
            return False
    return True


def flatten(iterable):
    """ Given an iterable of iterables, flatten out the embedded rows into one list.

        :param iterable: The iterable to flatten.
    """
    new_list = []
    for row in iterable:
        new_list.extend(row)
    return new_list


def get_date_time_from_timestamp(timestamp):
    """Get the date time from a timestamp.

    The timestamp must have the following format:
    'year.month.day.hour.minutes'
    Example:
    '2017.12.20.10.31' -> '2017/12/20 10:31'
    """
    date_time_string = timestamp
    sp = timestamp.split('.')
    if len(sp) >= 5:
        date_time_string = '{0}/{1}/{2} {3}:{4}'.format(sp[0], sp[1], sp[2],
            sp[3], sp[4])
    return date_time_string


def _applytfms(args):
    """
    Applies ANTs' antsApplyTransforms to the input image.
    All inputs are zipped in one tuple to make it digestible by
    multiprocessing's map
    """
    import nibabel as nb
    from nipype.utils.filemanip import fname_presuffix
    from ..niworkflows.interfaces.fixes import FixHeaderApplyTransforms as ApplyTransforms
    in_file, in_xform, ifargs, index, newpath = args
    out_file = fname_presuffix(in_file, suffix='_xform-%05d' % index,
        newpath=newpath, use_ext=True)
    copy_dtype = ifargs.pop('copy_dtype', False)
    xfm = ApplyTransforms(input_image=in_file, transforms=in_xform,
        output_image=out_file, **ifargs)
    xfm.terminal_output = 'allatonce'
    xfm.resource_monitor = False
    runtime = xfm.run().runtime
    if copy_dtype:
        nii = nb.load(out_file)
        in_dtype = nb.load(in_file).get_data_dtype()
        if in_dtype != nii.get_data_dtype():
            nii.set_data_dtype(in_dtype)
            nii.to_filename(out_file)
    return out_file, runtime.cmdline


def get_pkg_name():
    """
    Return package name
    """
    return __name__.split('.')[0]


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 isRootNode(tree, mrcaNum):
    """Is mrcaNum the root node?"""
    return mrcaNum == tree[0]


@staticmethod
def from_centre(x, y, xsize=None, ysize=None, aspect=1.0):
    """Helper method to aid in constructing a new instance centred on the
        given location, with a given width and/or height.  If only one of the
        width or height is specified, the aspect ratio is used.

        :return: `(xmin, xmax, ymin, ymax)`
        """
    if xsize is None and ysize is None:
        raise ValueError('Must specify at least one of width and height')
    x, y, aspect = float(x), float(y), float(aspect)
    if xsize is not None:
        xsize = float(xsize)
    if ysize is not None:
        ysize = float(ysize)
    if xsize is None:
        xsize = ysize * aspect
    if ysize is None:
        ysize = xsize / aspect
    xmin, xmax = x - xsize / 2, x + xsize / 2
    ymin, ymax = y - ysize / 2, y + ysize / 2
    return xmin, xmax, ymin, ymax


def apply_filter_metadata(filt, dev_raw):
    """apply metadata value filter"""
    k = 'tag_hostdev_{}'.format(filt['name'])
    return dev_raw[k] == str(filt['val'])


def number(random=random, *args, **kwargs):
    """
    Return a number!

    >>> number(random=mock_random)
    0
    """
    return random.randint(0, 9)


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

        :param PaperDocumentLogInfo val:
        :rtype: AssetLogInfo
        """
    return cls('paper_document', val)


def paths_calculate(start_frame: int=1, end_frame: int=250):
    """Calculate motion paths for the selected objects

    :param start_frame: Start, First frame to calculate object paths on
    :type start_frame: int
    :param end_frame: End, Last frame to calculate object paths on
    :type end_frame: int
    """
    pass


def post_process_request(req, template, data, content_type):
    """Do any post-processing the request might need; typically adding
        values to the template `data` dictionary, or changing template or
        mime type."""
    return template, data, content_type


def buildMessage(words):
    """Constructs a message from a list of words."""
    return ' '.join(words) + '\n'


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 setTcpNoDelay(enabled):
    """
        Enable/disable C{TCP_NODELAY}.

        Enabling C{TCP_NODELAY} turns off Nagle's algorithm. Small packets are
        sent sooner, possibly at the expense of overall throughput.
        """


def set_verbosity(level):
    """Sets the modules message verbosity level for *all* messages printed.

    :arg level: a positive integer (>0); higher levels including more detail.
    """
    global verbosity
    verbosity = level


@classmethod
def from_data(cls, data):
    """Construct a plane from its data representation.

        Parameters
        ----------
        data : dict
            The data dictionary.

        Returns
        -------
        :class:`compas.geometry.Plane`
            The constructed plane.

        Examples
        --------
        >>> plane = Plane.from_data({'point': [0.0, 0.0, 0.0], 'normal': [0.0, 0.0, 1.0]})
        >>> plane.point
        Point(0.000, 0.000, 0.000)
        >>> plane.normal
        Vector(0.000, 0.000, 1.000)
        """
    return cls(data['point'], data['normal'])


def environments_command_parser(parent_parser, **kwargs):
    """sets up the argument parser for the environments command"""
    parser = parent_parser.add_parser('environments', description=
        'List all environments in the control-repository of the currently selected profile.'
        , help='list all environments of the selected profile')
    return parser


def dqdsst_adjustment(file: str, group_files: str, cdo, options, verbose,
    **kwargs):
    """
        Compute the kinematic surface net heat flux sensitivity to the sea surface temperature: dQdSST
        Q_model ~ Q + dQdSST * (T_model - SST)
        dQdSST = - 4 * eps * stef * T^3 - rho_atm * Cp * CH * U - rho_atm * CE * L * U * 2353 * ln(10 * q_s / T^2)
        SST: sea surface temperature
        t_air: sea surface atmospheric temperature
        rho_air: atmospheric density
        u_air: wind speed
        humidity: sea level specific humidity
        dQdSST: kinematic surface net heat flux sensitivity to the sea surface temperature (Watts meter-2 Celsius-1)
        :param preprocessor: PreProcessor object, contains a lot of necessary adjustments
        :param file: file which contains all necessary parameters to calculate dQdSST
        :param group_files: list of all files which contain necessary parameters to calculate dQdSST
        :param flags: any extra info necessary
    """
    if verbose:
        print('Calculating dQdSST')
    Cp = str(1004.8)
    Ch = str(0.00066)
    Ce = str(0.00115)
    stef = str(5.6697e-08)
    sstk_formula = '_sst = SST + 273.15;'
    l = '(2.008E6 - 2.3E3 * t_air)'
    q1 = '(-4.0 * ' + stef + '* _sst * _sst * _sst)'
    q2 = '(-rho_air * ' + Cp + ' * ' + Ch + '* u_air)'
    dqsdt = (
        '(5417.9827238149900949792936444282531738281250 * humidity / (_sst * _sst))'
        )
    q3 = '(-rho_air * ' + Ce + ' * ' + l + ' * u_air * ' + dqsdt + ' )'
    dqdsst_formula = ("'" + sstk_formula + 'dQdSST=' + q1 + ' + ' + q2 +
        ' + ' + q3 + "'")
    temp = cdo.setattribute(
        "dQdSST@long_name='surface net heat flux sensitivity to SST',dQdSST@unit='Watts meter-2 Celsius-1',dQdSST@files='"
         + group_files + "'", input='-delname,sat,rho_atm,U,qsea -aexpr,' +
        dqdsst_formula + ' ' + file, options=options)
    cdo.copy(input=temp, output=file, options=options)
    if verbose:
        print('dQdSST has been added.')


def get_local_session(env={'LC_ALL': 'C'}, pty=False, shared=None):
    """A shortcut to get a local session"""
    from reproman.resource.shell import Shell
    session = Shell('localshell').get_session(pty=pty, shared=shared)
    if env:
        session.set_envvar(env)
    return session


def _need_snippet_displayed(overall_messages_dets, block_messages_dets, *,
    multi_block=False):
    """
    Don't need to see the code snippet displayed when it is already visible:
    * because there is only one block in snippet and there is a block message
      for it (which will display the block i.e. the entire snippet) UNLESS there
      is an overall message separating them
    Otherwise we need it displayed.
    """
    mono_block_snippet = not multi_block
    if (mono_block_snippet and block_messages_dets and not
        overall_messages_dets):
        return False
    return True


@staticmethod
def _comparator_or(values, levels):
    """
        If at least one of values is bigger than its level, the function returns True.
        :param values: [float]. List of calculated distance
        :param levels: [float]. List of levels
        :return: bool
        :return:
        """
    for i, value in enumerate(values):
        if value is None:
            continue
        if value >= levels[i]:
            return True
    return False


@classmethod
def _valid_intent_code(klass, intent_code):
    """ Return True if `intent_code` matches our class `klass`
        """
    return intent_code >= 3000 and intent_code < 3100


def inglobal(lat, lon, mode=None):
    """True if lat and lon within global coordinates.

    Default coords: lat in (-90, 90) and lon in (-180, 180).
    mode='pos': lat in (-90, 90) and lon in (0, 360).

    Examples
    --------
    >>> lat = -10
    >>> lon = -10
    >>> inbounds(lat, lon)
    True
    >>> inbounds(lat, lon, 'pos')
    False
    """
    if mode == 'pos':
        return -90 <= lat <= 90 and 0 <= lon <= 360
    else:
        return -90 <= lat <= 90 and -180 <= lon <= 180


def message_get(transport, request, queue_name, message_id, callback=None):
    """Gets one message from the queue by id

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    :param queue_name: Queue reference name.
    :type queue_name: `six.text_type`
    :param message_id: Message reference.
    :param message_id: `six.text_type`
    :param callback: Optional callable to use as callback.
        If specified, this request will be sent asynchronously.
        (IGNORED UNTIL ASYNC SUPPORT IS COMPLETE)
    :type callback: Callable object.
    """
    request.operation = 'message_get'
    request.params['queue_name'] = queue_name
    request.params['message_id'] = message_id
    resp = transport.send(request)
    return resp.deserialized_content


def eager(func):
    """Dummy decorator used in TensorFlow 2.0 to exit the Keras graph."""
    return func


@staticmethod
def _define_module_argument_spec():
    """
        Define the argument spec for the ansible module
        :return: argument spec dictionary
        """
    argument_spec = dict(server_ids=dict(type='list', required=True),
        protocol=dict(default='TCP', choices=['TCP', 'UDP', 'ICMP']), ports
        =dict(type='list'), source_restrictions=dict(type='list'), wait=
        dict(type='bool', default=True), state=dict(default='present',
        choices=['present', 'absent']))
    return argument_spec


def getANSIbgarray_for_ANSIcolor(ANSIcolor):
    """Return array of color codes to be used in composing an SGR escape
    sequence. Using array form lets us compose multiple color updates without
    putting out additional escapes"""
    return ['48', '5', str(ANSIcolor)]


def _label_all(rag, attr_name):
    """Assign a unique integer to the given attribute in the RAG.

    This function assumes that all labels in `rag` are unique. It
    picks up a random label from them and assigns it to the `attr_name`
    attribute of all the nodes.

    rag : RAG
        The Region Adjacency Graph.
    attr_name : string
        The attribute to which a unique integer is assigned.
    """
    node = min(rag.nodes())
    new_label = rag.nodes[node]['labels'][0]
    for n, d in rag.nodes(data=True):
        d[attr_name] = new_label


def _invoke_setter_on(input_object, method_name, value):
    """ If a given input object has the given setter method
    name, use this method to set "value" on the object.

    :param input_object: Python object
    :param method_name: name of the setter method
    :param value: value to set
    """
    remove = '_' + type(input_object).__name__ + '__'
    real_method_name = method_name.replace(remove, '')
    setter_method = '_set_' + real_method_name
    if hasattr(input_object, setter_method):
        method = getattr(input_object, setter_method)
        method(value)


def distance(val, begin, end):
    """Provides a distance between the absPos and an item"""
    if val >= begin and val <= end:
        return 0
    return min(abs(val - begin), abs(val - end))


def threshImg(diff, threshL, threshH):
    """Takes in difference image, low and high thresold values, and outputs a map of all defects.
    """
    assert isinstance(threshL, float), ('Wrong data type',
        'threshL must be a float')
    assert isinstance(threshH, float), ('Wrong data type',
        'threshH must be a float')
    threshIL = diff < threshL
    threshIH = diff > threshH
    threshI = threshIL + threshIH
    return threshI


def locale_date(date):
    """Render a date in the current locale date."""
    return date.strftime('%d %B %Y').lstrip('0')


@classmethod
def _remove_trace(cls, name):
    """ Resource subclasses will invoke this method to remove a
        resource trace

        """
    del cls._traces[name]


@classmethod
def from_axes(cls, axes):
    """
        Creates a new Cifti2 header based on the Cifti2 axes

        Parameters
        ----------
        axes : tuple of :class`.cifti2_axes.Axis`
            sequence of Cifti2 axes describing each row/column of the matrix to be stored

        Returns
        -------
        header : Cifti2Header
            new header describing the rows/columns in a format consistent with Cifti2
        """
    from . import cifti2_axes
    return cifti2_axes.to_header(axes)


def title_and_id():
    """Return the title if it is not blank and the id otherwise.

        If the title is not blank, then the id is included in parens.
        """


def _fits_read_header(hdr):
    """
    Convert pyfits header into dictionary with relevant values

    Parameters
    ----------

    hdr: pyftis.Header
        fits unit

    Returns
    -------
    header: dict
        header dictionary

    alias: dict
        aliases

    units: dict
        units

    comments: dict
        comments/description of keywords
    """
    header = {}
    alias = {}
    units = {}
    comments = {}
    genTerms = ['XTENSION', 'BITPIX', 'NAXIS', 'NAXIS1', 'NAXIS2', 'PCOUNT',
        'GCOUNT', 'TFIELDS', 'EXTNAME']
    fieldTerms = ['TTYPE', 'TFORM', 'TUNIT', 'ALIAS']
    for k, name, comment in hdr.ascard['TTYPE*']:
        comments[name] = comment
        u = hdr.get(k.replace('TYPE', 'UNIT'), None)
        if u is not None:
            units[name] = u
    for k, val, _ in hdr.ascard['ALIAS*']:
        al, orig = val.split('=')
        alias[al] = orig
    header_comments = []
    header_history = []
    for k, v in hdr.items():
        if k not in genTerms and k[:5] not in fieldTerms:
            if k == 'COMMENT':
                header_comments.append(v)
            elif k == 'HISTORY':
                header_history.append(v)
            else:
                header[k] = v
    if len(header_comments) > 0:
        header['COMMENT'] = '\n'.join(header_comments)
    if len(header_history) > 0:
        header['HISTORY'] = '\n'.join(header_history)
    if 'EXTNAME' in hdr:
        header['NAME'] = hdr['EXTNAME']
    return header, alias, units, comments


def user_details(strategy, details, user=None, *args, **kwargs):
    """Update user details using data from provider."""
    if not user:
        return
    changed = False
    protected = ('username', 'id', 'pk', 'email') + tuple(strategy.setting(
        'PROTECTED_USER_FIELDS', []))
    for name, value in details.items():
        if value is None or not hasattr(user, name) or name in protected:
            continue
        current_value = getattr(user, name, None)
        if current_value or current_value == value:
            continue
        changed = True
        setattr(user, name, value)
    if changed:
        strategy.storage.user.changed(user)


def deltatus():
    """
    Returns the duration, in microseconds, of the current system timestep.

    **Note**: In Python Mode, this function always returns `10,000` for a rate of 100Hz.
    """
    return 10000


@classmethod
def connect(cls, database, timeout=5, isolation_level='', uri=None,
    own_process=False, verbose: bool=False, tasks: int=1):
    """Alias to __init__, to be alike sqlite3 interface"""
    return cls(database, timeout, isolation_level, uri, own_process,
        verbose, tasks)


def clientConnectionForTLS(tlsProtocol):
    """
        Create a connection for the given client protocol.

        @param tlsProtocol: the client protocol making the request.
        @type tlsProtocol: L{twisted.protocols.tls.TLSMemoryBIOProtocol}.

        @return: an OpenSSL connection object configured appropriately for the
            given Twisted protocol.
        @rtype: L{OpenSSL.SSL.Connection}
        """


def p_proc_return(t):
    """proc_return : type_specifier
                   | VOID"""


def special_path_string(path_string):
    """ Replace the path string . -> /
    rather than the following cases
    .
    ..
    path/./../
    """
    if path_string.startswith('.'):
        return path_string
    if path_string.find('/.') != -1:
        return path_string
    return path_string.replace('.', '/')


def list_runs(arn=None, nextToken=None):
    """
    Gets information about runs, given an AWS Device Farm project ARN.
    See also: AWS API Documentation

    Examples
    The following example returns information about a specific test run.
    Expected Output:

    :example: response = client.list_runs(
        arn='string',
        nextToken='string'
    )

    :type arn: string
    :param arn: [REQUIRED]
            The Amazon Resource Name (ARN) of the project for which you want to list runs.

    :type nextToken: string
    :param nextToken: An identifier that was returned from the previous call to this operation, which can be used to return the next set of items in the list.

    :rtype: dict
    :return: {
        'runs': [
            {
                'arn': 'string',
                'name': 'string',
                'type': 'BUILTIN_FUZZ'|'BUILTIN_EXPLORER'|'APPIUM_JAVA_JUNIT'|'APPIUM_JAVA_TESTNG'|'APPIUM_PYTHON'|'APPIUM_WEB_JAVA_JUNIT'|'APPIUM_WEB_JAVA_TESTNG'|'APPIUM_WEB_PYTHON'|'CALABASH'|'INSTRUMENTATION'|'UIAUTOMATION'|'UIAUTOMATOR'|'XCTEST'|'XCTEST_UI',
                'platform': 'ANDROID'|'IOS',
                'created': datetime(2015, 1, 1),
                'status': 'PENDING'|'PENDING_CONCURRENCY'|'PENDING_DEVICE'|'PROCESSING'|'SCHEDULING'|'PREPARING'|'RUNNING'|'COMPLETED'|'STOPPING',
                'result': 'PENDING'|'PASSED'|'WARNED'|'FAILED'|'SKIPPED'|'ERRORED'|'STOPPED',
                'started': datetime(2015, 1, 1),
                'stopped': datetime(2015, 1, 1),
                'counters': {
                    'total': 123,
                    'passed': 123,
                    'failed': 123,
                    'warned': 123,
                    'errored': 123,
                    'stopped': 123,
                    'skipped': 123
                },
                'message': 'string',
                'totalJobs': 123,
                'completedJobs': 123,
                'billingMethod': 'METERED'|'UNMETERED',
                'deviceMinutes': {
                    'total': 123.0,
                    'metered': 123.0,
                    'unmetered': 123.0
                },
                'networkProfile': {
                    'arn': 'string',
                    'name': 'string',
                    'description': 'string',
                    'type': 'CURATED'|'PRIVATE',
                    'uplinkBandwidthBits': 123,
                    'downlinkBandwidthBits': 123,
                    'uplinkDelayMs': 123,
                    'downlinkDelayMs': 123,
                    'uplinkJitterMs': 123,
                    'downlinkJitterMs': 123,
                    'uplinkLossPercent': 123,
                    'downlinkLossPercent': 123
                }
            },
        ],
        'nextToken': 'string'
    }

    :returns:
    BUILTIN_FUZZ: The built-in fuzz type.
    BUILTIN_EXPLORER: For Android, an app explorer that will traverse an Android app, interacting with it and capturing screenshots at the same time.
    APPIUM_JAVA_JUNIT: The Appium Java JUnit type.
    APPIUM_JAVA_TESTNG: The Appium Java TestNG type.
    APPIUM_PYTHON: The Appium Python type.
    APPIUM_WEB_JAVA_JUNIT: The Appium Java JUnit type for Web apps.
    APPIUM_WEB_JAVA_TESTNG: The Appium Java TestNG type for Web apps.
    APPIUM_WEB_PYTHON: The Appium Python type for Web apps.
    CALABASH: The Calabash type.
    INSTRUMENTATION: The Instrumentation type.
    UIAUTOMATION: The uiautomation type.
    UIAUTOMATOR: The uiautomator type.
    XCTEST: The XCode test type.
    XCTEST_UI: The XCode UI test type.

    """
    pass


def p_attr(p):
    """
    attr : CARDINALITY cardinality
         | DATATYPE datatype
         | idattr IDENTIFIER
    """
    p[0] = {p[1]: p[2]}


def take_n(n, iterable):
    """Take the first `n` items of a collection."""
    for i, item in enumerate(iterable):
        if i >= n:
            break
        yield item


def get_ver():
    """
    Gather the version number from git
    """
    import subprocess
    proc = subprocess.run(['git', 'describe'], stdout=subprocess.PIPE)
    if not proc.returncode == 0:
        return
    v = proc.stdout.decode().strip()
    if '-' not in v:
        ret = v
    else:
        csum = v[v.rindex('-') + 1:]
        base = v[:v.rindex('-')]
        count = base[base.rindex('-') + 1:]
        tag = base[:base.rindex('-')]
        ret = f'{tag}.post{count}+{csum}'
    return ret


def rotate3(rot, vector):
    """Return the rotation of 3-dimension ``vector`` by 3x3 (row major) matrix
	``rot``.

	"""
    return vector[0] * rot[0] + vector[1] * rot[1] + vector[2] * rot[2
        ], vector[0] * rot[3] + vector[1] * rot[4] + vector[2] * rot[5
        ], vector[0] * rot[6] + vector[1] * rot[7] + vector[2] * rot[8]


def _validate_chunksize(chunksize: int) ->None:
    """
    Raises the proper exception if chunksize is not valid.

    Parameters
    ----------
    chunksize: int
    The chunksize to validate.
    """
    if not isinstance(chunksize, int):
        raise TypeError('Invalid chunksize: Must be an int')
    if not chunksize > 0:
        raise ValueError('Invalid chunksize: Must be > 0')


def distance(c1, c2):
    """ returns the distance between the two coordinates c1 and c2,
            which are of type ICoordinate.
        """


def _find_all_instances_in_string(string, substr):
    """ Find indices of all instances of substr in string """
    indices = []
    idx = string.find(substr, 0)
    while idx > -1:
        indices.append(idx)
        idx = string.find(substr, idx + 1)
    return indices


def p_numbers(p):
    """numbers : numbers number"""
    p[1].append(p[2])
    p[0] = p[1]


def _to_kebab_case(value: str) ->str:
    """Converts a snake_case string into a kebab-case one."""
    return value.replace('_', '-').lower()


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

        :param TokenScopeError val:
        :rtype: AuthError
        """
    return cls('missing_scope', val)


def parse_rangestring(rangestring):
    """
    Parses a string that represents a range of numbers
    such as 1-4 or 1 or 1,3 or combinations such as
    1-3,5,7,8-10

    .. code-block:: python

        >>> from pypbs import util
        >>> util.parse_rangestring('1-3,5,7,8-10')
        [1, 2, 3, 5, 7, 8, 9, 10]

    :param str rangestring: range string to parse
    :returns: list of all numbers in range
    """
    if not rangestring:
        return []
    _range = []
    parts = rangestring.split(',')
    for part in parts:
        if '-' in part:
            s, e = part.split('-')
            for i in range(int(s), int(e) + 1):
                _range.append(i)
        else:
            _range.append(int(part))
    return _range


def update_namespace(D, *attributes):
    """ Add arbitrary attributes to a :class: `Namespace <argparse.Namespace>`.

    ==========  ================================================================
    D           argparse.Namespace; the namespace holding the data and
                metadata. The format is the same as what is returned by a
                dataloader.
    attributes  tuples or len(2) lists; (name, value) pairs of the attributes
                to add. Where `name` is a str and value any python object.
    ==========  ================================================================
    """
    for name, attribute in attributes:
        D.__dict__.update({name: attribute})


@classmethod
def prepare_tools(cls, round_manager):
    """Subclasses must call this method to ensure jvm tool products are available."""
    round_manager.require_data('jvm_build_tools_classpath_callbacks')


def count_lines(text, width):
    """Return a fractional line count (filled lines plus fraction of last line)"""
    lines = text.splitlines()
    count = len(lines[:-1]) + len(lines[-1]) / width
    return count


@staticmethod
def is_absolute_name(name):
    """
        Returns True if the given name starts with a namespace.
        """
    return name[0:1] == '/'


def wave_period_tlv(wavelength, velocity):
    """Usage: Calculate wave period (T) using wavelength (l) and velocity (v)"""
    return wavelength / velocity


def set_cache(cache):
    """Set the caching options. It is recommended to
    set it via environment variables.

    Use a shared directory:
    `FILE_CACHE=/path/to/cache`

    Use redis:
    `REDIS_CACHE=redis://example.com:6379`

    Default is that a local cache will be used. This
    local cache is not distributed, so use it only it
    in environments where you use one process!
    """
    globals['cache'] = cache


@classmethod
def name_tags(cls, name, version):
    """Return :term:`VER` tags for given name and version.

        :param name:    :term:`VER` encoding name
        :type  name:    (unicode,)
        :param version: :term:`VER` encoding version
        :type  version: (int,)
        :returns:       encoding tags
        :rtype:         tuple

        Convenience method for generating the appropriate tags for the
        :term:`VER` encoding format.

        """
    return -1, name, version


def ChannelFirst(arr):
    """Convert a HWC array to CHW."""
    ndim = arr.ndim
    return arr.swapaxes(ndim - 1, ndim - 2).swapaxes(ndim - 2, ndim - 3)


@classmethod
def type_descriptor(cls, typeobj):
    """Transform a generic type to a dialect-specific type.

        Dialect classes will usually use the
        :func:`.types.adapt_type` function in the types module to
        accomplish this.

        The returned result is cached *per dialect class* so can
        contain no dialect-instance state.

        """
    raise NotImplementedError()


def sparse_matrix(data, index, shape, force_format=False):
    """Create a sparse matrix.

    NOTE: Please make sure that the data and index tensors are not
    copied. This is critical to the performance.

    Parameters
    ----------
    data : Tensor
        Data tensor. It should be of shape (nnz,).
    index : tuple
        This is used to support different sparse formats.
        For COO format:
          index=('coo', coord), where coord is of shape (2, nnz).
          coord[0,:] should be the row index and coord[1,:] should be
          the column index.
        For CSR format:
          index=('csr', indices, indptr), where indices is of shape (nnz,)
          and indptr is of shape (nrows+1,). See ``scipy.sparse.csr_matrix``
          for more documents on what each array means.
    shape : tuple of int
        The shape.
    force_format : bool
        If true, the returned sparse matrix must be stored in the same
        format as the given index.

    Returns
    -------
    SparseMatrix
        The framework-specific sparse matrix. It can be stored in any format
        unless force_format is True.
    Tensor
        The data convert index due to sparse format change.
        None if no conversion is needed.
    """
    pass


def is_directed_lanboot_requested(node):
    """Checks if directed lanboot is requested

    """
    directed_lanboot_requested = node.driver_info.get('enable_directed_lanboot'
        , 'false').lower()
    return directed_lanboot_requested == 'true'


def getBestCmap(font, cmapPreferences=((3, 10), (3, 1), (0, 3))):
    """Return a unicode -> glyphName dictionary from the 'best' unicode cmap that the font
    contains. In order of preference, the font will be searched for cmaps 3,10, 3,1 and 0,3.
    """
    """
        TODO: Fix docTests

        >>> from pagebot.fonttoolbox.objects.font import findFont
        >>> pf = findFont('Bungee-Regular')
        >>> font = pf.ttFont
        >>> cmap = getBestCmap(font)
        >>> len(cmap)
        248
        >>> max(cmap)
        64258
        >>> path = getFontPath("ProW6.otf")
        >>> font = TTFont(path)
        >>> cmap = getBestCmap(font)
        >>> len(cmap)
        13641
        >>> print(hex(max(cmap)))  # if result > 0xffff then it must have been a 3,10 cmap
        0x2f9f4
        >>> getBestCmap(font, cmapPreferences=[(123, 456)])
        Traceback (most recent call last):
            ...
        ValueError: None of the requested cmap subtables were found
    """
    cmapTable = font['cmap']
    for platformID, platEncID in cmapPreferences:
        cmapSubtable = cmapTable.getcmap(platformID, platEncID)
        if cmapSubtable is not None:
            return cmapSubtable.cmap
    raise ValueError('None of the requested cmap subtables were found')


@classmethod
def hascreds(cls, config):
    """Determine if the given configuration has proper credentials

        Parameters
        ----------
        cls : class
            A Session class.
        config : dict
            GDAL configuration as a dict.

        Returns
        -------
        bool

        """
    return ('AWS_ACCESS_KEY_ID' in config and 'AWS_SECRET_ACCESS_KEY' in
        config or 'AWS_NO_SIGN_REQUEST' in config)


def write_convolution_layer(model_name='sas', layer_name='conv', nfilters=
    '-1', width='3', height='3', stride='1', nobias='False', activation=
    'identity', dropout='0', src_layer='none', padding='None', pad_height=
    'None', pad_width='None'):
    """
    Generate Python code defining a SAS deep learning convolution layer

    Parameters
    ----------
    model_name : string, optional
       Name for deep learning model
    layer_name : string, optional
       Layer name
    nfilters : string, optional
       number of output feature maps
    width : string, optional
       image width
    height : string, optional
       image height
    stride : string, optional
       vertical/horizontal step size in pixels
    nobias : string, optional
       omit (True) or retain (False) the bias term
    activation : string, optional
       activation function
    dropout : string, optional
       dropout factor (0 < dropout < 1.0)
    src_layer : string, optional
       source layer(s) for the convolution layer
    padding : string, optional
       symmetric zero padding value
    pad_height : string, optional
       symmetric height zero padding value
    pad_width : string, optional
        symmetric width zero padding value

    Returns
    -------
    string

    """
    if pad_height.lower() != 'none' or pad_width.lower() != 'none':
        out = ['   s.addLayer(model=' + repr(model_name) + ', name=' + repr
            (layer_name) + ',',
            '              layer=dict(type="convolution", nfilters=' +
            nfilters + ', width=' + width + ', height=' + height + ',',
            '                         stride=' + stride + ', nobias=' +
            nobias + ', act=' + repr(activation) + ', dropout=' + dropout +
            ', padHeight=' + pad_height + ', padWidth=' + pad_width + '),',
            '              srcLayers=' + src_layer + ')']
    else:
        out = ['   s.addLayer(model=' + repr(model_name) + ', name=' + repr
            (layer_name) + ',',
            '              layer=dict(type="convolution", nfilters=' +
            nfilters + ', width=' + width + ', height=' + height + ',',
            '                         stride=' + stride + ', nobias=' +
            nobias + ', act=' + repr(activation) + ', dropout=' + dropout +
            ', pad=' + padding + '),', '              srcLayers=' +
            src_layer + ')']
    return '\n'.join(out)


def soft_sign(x):
    """ Returns the soft sign function x/(1 + |x|).

    Parameters
    ----------
    x : mygrad.Tensor
        Input data.

    Returns
    -------
    mygrad.Tensor
        The soft sign function applied to `x` elementwise.
    """
    return x / (1 + abs(x))


def fix_imports(script):
    """
    Replace "from PyQt5 import" by "from pyqode.qt import".

    :param script: script path
    """
    with open(script, 'r') as f_script:
        lines = f_script.read().splitlines()
    new_lines = []
    for l in lines:
        if l.startswith('import '):
            l = 'from . ' + l
        if 'from PyQt5 import' in l:
            l = l.replace('from PyQt5 import', 'from pyqode.qt import')
        new_lines.append(l)
    with open(script, 'w') as f_script:
        f_script.write('\n'.join(new_lines))


def autoexec_warn_clear():
    """Ignore autoexec warning

    """
    pass


def _get_lut_id(lut, label, use_lut):
    """Convert a label to a LUT ID number."""
    if not use_lut:
        return 1
    assert isinstance(label, str)
    mask = lut['name'] == label
    assert mask.sum() == 1
    return lut['id'][mask]


def set_filters(query, filters):
    """Put together all filters we have and set them as 'and' filter
    within filtered query.

    :param query: elastic query being constructed
    :param base_filters: all filters set outside of query (eg. resource config, sub_resource_lookup)
    """
    query['query'].setdefault('bool', {})
    if filters:
        for f in filters:
            if f is not None:
                query['query']['bool'].setdefault('filter', []).append(f)


def ms_to_sec(ms):
    """Returns an Integer approximated value"""
    return int(ms / 1000)


def reduce_min(input):
    """Returns the min of all elements in the input tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.

    Returns
    -------
    Tensor
        A framework-specific tensor with shape (1,)
    """
    pass


def top_to_down(card):
    """ If the password from the card is read from top to down """
    data = card.m.getT().getA1().flatten()
    results = data.tolist()
    return results


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

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


def array_map2(*referls, **kwargs):
    """
        obseleted just for compatible
        from elist.elist import *
        ol = [1,2,3,4]
        refl1 = ['+','+','+','+']
        refl2 = [7,7,7,7]
        refl3 = ['=','=','=','=']
        def map_func(ele,ref_ele1,ref_ele2,ref_ele3,prefix,suffix):
            s = prefix+': ' + str(ele) + str(ref_ele1) + str(ref_ele2) + str(ref_ele3) + suffix
            return(s)

        ####
        rslt = array_map2(ol,refl1,refl2,refl3,map_func=map_func,map_func_args=['Q','?'])
        pobj(rslt)
    """
    map_func = kwargs['map_func']
    if 'map_func_args' in kwargs:
        map_func_args = kwargs['map_func_args']
    else:
        map_func_args = []
    length = referls.__len__()
    rslt = []
    anum = list(referls)[0].__len__()
    for j in range(0, anum):
        args = []
        for i in range(0, length):
            refl = referls[i]
            args.append(refl[j])
        args.extend(map_func_args)
        v = map_func(*args)
        rslt.append(v)
    return rslt


def height_from_forearm_length(segment_length):
    """
    Calculates body height based on the forearm length (elbow to wrist)

    args:
        segment_length (float): length of forearm

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


@staticmethod
def validate(value=None):
    """
        Check if the given value is non empty.

        Args:
            value (any): Value to be validated.
        """
    if value is None or value in (0, 0.0, 0.0j):
        return True
    return bool(value)


def colored_info(outLn: str, lnType: str='e', debug: bool=False) ->None:
    """Output a color line based on the type of information."""
    if debug:
        print('colored_info :: START')
        print('Input string:\t{:s}'.format(outLn))
        print('String type:\t{:s}'.format(lnType.strip().lower()[0]))
    lnType = lnType.strip().lower()[0]
    validTypes = ['s', 'e', 'w', 'i']
    if not lnType in validTypes:
        print(
            '\x1b[5;30;41mError:\x1b[0m {:s} is not a valid type of output line.'
            .format(lnType))
        print('Please use one of the following:\n{:s}'.format(str(validTypes)))
    if lnType == 's':
        print('\x1b[5;30;42mSuccess:\x1b[0m {:s}'.format(outLn))
    elif lnType == 'e':
        print('\x1b[5;30;41mError:\x1b[0m {:s}'.format(outLn))
    elif lnType == 'w':
        print('\x1b[5;30;43mWarning:\x1b[0m {:s}'.format(outLn))
    elif lnType == 'i':
        print('\x1b[5;30;44mInfo:\x1b[0m {:s}'.format(outLn))


def is_rule_in_set(rule, rule_list):
    """Check if the given rule is present in the rule_list

    :param rule_list: list of existing rules in dictionary format
    :param rule: new rule to be added
    :return boolean:
    """
    for old_rule in rule_list:
        if rule['source'] == old_rule['source'] and rule['destination'
            ] == old_rule['destination'] and rule['action'] == old_rule[
            'action'] and rule['priority'] == old_rule['priority']:
            return True
    return False


def trace(__self, __message, *args, **kwargs):
    """Log ``message.format(*args, **kwargs)`` with severity ``'TRACE'``."""
    __self._log('TRACE', None, False, __self._options, __message, args, kwargs)


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


@staticmethod
def cookies_exist(resp):
    """
        Check if cookies sent during response.

        :param resp: response object.
        :returns: dictionary of cookies from response if exists or None.
        """
    if not resp.cookies.get_dict():
        return
    else:
        cookies = resp.cookies.get_dict()
        if len(cookies) >= 1:
            return f'(cookies: {len(cookies)})'


@classmethod
def get(cls):
    """
        .. note:: Experimental

        Return the currently active :class:`BarrierTaskContext`.
        This can be called inside of user functions to access contextual information about
        running tasks.

        .. note:: Must be called on the worker, not the driver. Returns None if not initialized.
        """
    return cls._taskContext


def num(num):
    """
    The result will be a ParseTree instance with type
    expression and value equal to the token num.
    """
    return num.val()


def displacement_from_effective_period(eta, corner_disp, t_eff, corner_period):
    """
    Displacement of SDOF using displacement-based assessment. # Eq. 11 Millen et al. (2016)
    :param eta: Displacement reduction factor
    :param corner_disp: Corner spectral displacement
    :param t_eff: Effective displacement
    :param corner_period:
    :return:
    """
    if t_eff > corner_period:
        return eta * corner_disp
    return eta * corner_disp * t_eff / corner_period


def AddResultList(*args, **kwargs):
    """ Stub Anduin function."""
    print('AddResultList', args, kwargs)


@staticmethod
def _format_datetime(value):
    """ Method for formatting datetime objects into report
        """
    return value.strftime('%X %x %Z')


def evaluations(ty, pv):
    """
    evaluations(ty, pv) -> (ACC, MSE, SCC)

    Calculate accuracy, mean squared error and squared correlation coefficient
    using the true values (ty) and predicted values (pv).
    """
    if len(ty) != len(pv):
        raise ValueError('len(ty) must equal to len(pv)')
    total_correct = total_error = 0
    sumv = sumy = sumvv = sumyy = sumvy = 0
    for v, y in zip(pv, ty):
        if y == v:
            total_correct += 1
        total_error += (v - y) * (v - y)
        sumv += v
        sumy += y
        sumvv += v * v
        sumyy += y * y
        sumvy += v * y
    l = len(ty)
    ACC = 100.0 * total_correct / l
    MSE = total_error / l
    try:
        SCC = (l * sumvy - sumv * sumy) * (l * sumvy - sumv * sumy) / ((l *
            sumvv - sumv * sumv) * (l * sumyy - sumy * sumy))
    except:
        SCC = float('nan')
    return ACC, MSE, SCC


@staticmethod
def serialize_point(point: dict) ->dict:
    """ Prepare the point to be sent to the API """
    serialized_point = {'method': point['method'], 'uri': point['uri'],
        'time_request_started': point['time_request_started'].isoformat(),
        'time_elapsed': point['time_elapsed'], 'interactions': point[
        'interactions'], 'response_status': point['response_status'],
        'endpoint_name': point['endpoint_name']}
    if 'url_rule' in point and point['url_rule']:
        serialized_point['url_rule'] = point['url_rule']
    if 'is_not_found' in point and point['is_not_found'] is not None:
        serialized_point['is_not_found'] = point['is_not_found']
    return serialized_point


def validate_int(value, min_value=None, max_value=None, logger=None, name=None
    ):
    """ Validate value is integer and between min and max values (if specified) """
    if value is None:
        if logger and name:
            logger.debug('%s value is not set', name)
        return False
    try:
        int_value = int(value)
        if min_value is not None and int_value < min_value:
            if logger and name:
                logger.debug('%s value %s is less than minimum (%s)', name,
                    int_value, min_value)
            return False
        if max_value is not None and int_value > max_value:
            if logger and name:
                logger.debug('%s value %s is greater than maximum (%s)',
                    name, int_value, max_value)
            return False
    except ValueError:
        if logger and name:
            logger.debug('%s value (%s) is not an integer', name, value)
        return False
    return True


def combinations_2d(iterable1, iterable2):
    """
    Given two lists, a list with all possible combinations of elements from the two lists will be returned. The
    combinations will be in the form of tuples, where the first element is always from the list that was given as
    the first argument to this function.

    CHANGELOG

    Added 16.11.2018

    @param list iterable1:
    @param list iterable2:
    @return:
    """
    combinations = []
    for i in iterable1:
        for j in iterable2:
            combinations.append((i, j))
    return combinations


def format_time(time):
    """
    Format seconds into human readable format.

    Parameters
    ----------
    time : float
        Time specified in seconds

    Returns
    -------
    str
        Formated time.
    """
    mins, seconds = divmod(int(time), 60)
    hours, minutes = divmod(mins, 60)
    if hours > 0:
        return '{:0>2d}:{:0>2d}:{:0>2d}'.format(hours, minutes, seconds)
    elif minutes > 0:
        return '{:0>2d}:{:0>2d}'.format(minutes, seconds)
    elif seconds > 0:
        return '{:.0f} sec'.format(seconds)
    elif time >= 0.001:
        return '{:.0f} ms'.format(time * 1000.0)
    elif time >= 1e-06:
        return '{:.0f} μs'.format(time * 1000000.0)
    return '{:.0f} ns'.format(time * 1000000000.0)


def bytes_32_to_int(b: bytes) ->int:
    """Deserialize an integer from the corresponding big endian bytes."""
    assert len(b) == 32
    return int.from_bytes(b, byteorder='big')


def psi_Mg_Cl_HSO4_HMW84(T, P):
    """c-a-a': magnesium chloride bisulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def get_next_index(i: int, list_of_tags: list) ->int:
    """
    return the i after the next <br/>

    :type i: int
    :param i: an index
    :type list_of_tags: list
    :param list_of_tags: list of tags to check the i on
    :rtype: int
    """
    while i < len(list_of_tags) and list_of_tags[i].name != 'br':
        i += 1
    return i + 1


def _null_to_blank(_value):
    """This function returns a blank string when a null / NoneType value is passed.

    .. versionadded:: 2.3.0
    """
    return '' if _value is None else _value


@staticmethod
def poisson_ratio(x):
    """
        calculate the Poisson ratio of the alloy
        """
    return 2 * (4.54 + 0.8 * x) / (8.34 + 3.56 * x)


def iter_chunks(sizes, max_size):
    """Split sizes into chunks of total max_size each

    Parameters
    ----------
    sizes : iterable of numbers
        The sizes to be chunked
    max_size : number
        Maximum total size per chunk.
        It must be greater or equal than each size in sizes
    """
    chunk, chunk_sum = [], 0
    iter_sizes = iter(sizes)
    size = next(iter_sizes, None)
    while size is not None:
        assert size <= max_size
        if chunk_sum + size <= max_size:
            chunk.append(size)
            chunk_sum += size
            size = next(iter_sizes, None)
        else:
            assert chunk
            yield chunk
            chunk, chunk_sum = [], 0
    if chunk:
        yield chunk


def add_tagged_report_number(reading_line, len_reportnum, reportnum,
    startpos, true_replacement_index, extras):
    """In rebuilding the line, add an identified institutional REPORT-NUMBER
       (standardised and tagged) into the line.
       @param reading_line: (string) The reference line before capitalization
        was performed, and before REPORT-NUMBERs and TITLEs were stipped out.
       @param len_reportnum: (integer) the length of the matched REPORT-NUMBER.
       @param reportnum: (string) the replacement text for the matched
        REPORT-NUMBER.
       @param startpos: (integer) the pointer to the next position in the
        reading-line from which to start rebuilding.
       @param true_replacement_index: (integer) the replacement index of the
        matched REPORT-NUMBER in the reading-line, with stripped punctuation
        and whitespace accounted for.
       @param extras: (integer) extras to be added into the replacement index.
       @return: (tuple) containing a string (the rebuilt line segment) and an
        integer (the next 'startpos' in the reading-line).
    """
    rebuilt_line = u''
    if true_replacement_index - startpos - 1 >= 0:
        rebuilt_line += reading_line[startpos:true_replacement_index - 1]
    else:
        rebuilt_line += reading_line[startpos:true_replacement_index]
    rebuilt_line += u'<cds.REPORTNUMBER>%(reportnum)s</cds.REPORTNUMBER>' % {
        'reportnum': reportnum}
    startpos = true_replacement_index + len_reportnum + extras
    try:
        if reading_line[startpos] in (u']', u')'):
            startpos += 1
    except IndexError:
        pass
    return rebuilt_line, startpos


def multiapply(funcs, elm):
    """ Applies functions `funcs` to element `elm` iteratively. """
    for func in funcs:
        elm = func(elm)
    return elm


@staticmethod
def pixel_size(z):
    """
        Returns the pixel resolution of the input zoom level.

        Inputs:
        z -- zoom level value for the input tile
        """
    return 156543.033928041 / 2 ** z


@staticmethod
def to_red(data):
    """Hex color feed to red channel.
        :param int data: Color value, in hexadecimal.
        """
    return int(data[1], 16) * 16 + int(data[2], 16)


def _delete_duplicates(l, keep_last):
    """Delete duplicates from a sequence, keeping the first or last."""
    seen = set()
    result = []
    if keep_last:
        l.reverse()
    for i in l:
        try:
            if i not in seen:
                result.append(i)
                seen.add(i)
        except TypeError:
            result.append(i)
    if keep_last:
        result.reverse()
    return result


def _check_token_spans(token, token_start, token_end, prev_index):
    """Check that token fits into its span; output a helpful message is it doesn't."""
    if len(token) > token_end - token_start:
        raise ValueError(
            'Token is longer than its allocated span.\nToken: {}\nSpan: ({}, {})'
            .format(token, token_start, token_end))
    if token_start < prev_index:
        raise ValueError('Overlapping token spans.\nToken: {}\nSpan: ({}, {})'
            .format(token, token_start, token_end))


@classmethod
def isMember(cls, string):
    """
        Returns true if the given string is a member of Blocks
        """
    return string in cls._value2member_map_


@staticmethod
def _from_db_object(registry, db_registry):
    """Converts a database entity to a formal object."""
    for field in registry.fields:
        setattr(registry, field, db_registry[field])
    registry.obj_reset_changes()
    return registry


def _wrap_impl(f, args, kwargs, task):
    """
    Helper method, needs to be at the top level
    """
    return f(task, *args, **kwargs)


def remove_line_break(text):
    """Remove line breaks from text"""
    return text.replace('\n', '')


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 mapper(dictionary):
    """A formatter that map a value to another given a dict.
    Useful to quickly map categorical variables with very few levels (e.g a "sex" variable)
    to something more understandable (or translated).
    """
    return lambda a: dictionary[a] if a in dictionary else a


def get_code_object(obj):
    """Shamelessly borrowed from llpython"""
    return getattr(obj, '__code__', getattr(obj, 'func_code', None))


def min(dictionary, key=None, recursive=True):
    """

    Return the smallest item in a dictionary. The optional key argument
    specifies a one-argument ordering function like that used for list.sort().
    The key argument, if supplied, must be in keyword form
    (for example, min(dictionary, key=func)).
    """
    minimum = None
    if key == None:
        keyfunc = lambda key, _: key
    else:
        keyfunc = key
    for key in dictionary:
        value = dictionary[key]
        if minimum == None:
            minimum = keyfunc(key, value)
        if recursive and type(value) == dict:
            sub_minimum = min(value, key=keyfunc, recursive=recursive)
            if sub_minimum != None and sub_minimum < minimum:
                minimum = sub_minimum
        current_min = keyfunc(key, value)
        if current_min < minimum:
            minimum = current_min
    return minimum


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

        :param SharedLinkSettingsAllowDownloadEnabledDetails val:
        :rtype: EventDetails
        """
    return cls('shared_link_settings_allow_download_enabled_details', val)


def unique(input):
    """
    If the same N_S_L_C occurs twice, merge the dates into a single entry.
    Needed for the fast comparison (of sorted files) to work correctly.
    """
    output = []
    for sncl, dates in sorted(input):
        if output and sncl == output[-1][0]:
            output[-1][1].append(dates[0])
        else:
            output.append((sncl, dates))
    return output


def generate_sha5_hash():
    """ Generate sha5 hash """
    return 0


@staticmethod
def canonical_url(project_url):
    """
        Case insensitive
        Path can contain only letters, digits, '_', '-' and '.'.
        Cannot start with '-', end in '.git' or end in '.atom'

        Implementation is copied from Github API
        """
    url = project_url.lower()
    for chunk in ('http://', 'https://', 'gitlab.com'):
        if url.startswith(chunk):
            url = url[len(chunk):]
    if url.endswith('/'):
        url = url[:-1]
    while url.endswith('.git'):
        url = url[:-4]
    return 'gitlab.com/' + url


def get_metadata_url(illust_id: int) ->str:
    """Get illust Metadata URL from ``illust_id``.

    :param illust_id: Pixiv illust_id
    :type illust_id: :class:`int`
    :return: Pixiv Metadata URL
    :rtype: :class:`str`

    """
    return 'https://www.pixiv.net/ajax/illust/{}/ugoira_meta'.format(illust_id)


@classmethod
def _from_dict(cls, _dict):
    """Initialize a AnalyticsEngine object from a json dictionary."""
    return cls.from_dict(_dict)


def ColumnToIndex(col):
    """convert column to index. Eg: ConvertInIndex("AB") = 28"""
    ndx = 0
    for c in col:
        ndx = ndx * 26 + ord(c.upper()) - 64
    return ndx


def linear_service_fee(principal, fee=0.0):
    """Calculate service fee proportional to the principal.

    If :math:`S` is the principal and :math:`g` is the fee aliquot, then the
    fee is given by :math:`gS`.
    """
    return float(principal * fee)


def add_missing_tokens(t, marking):
    """
    Adds missing tokens needed to activate a transition

    Parameters
    ----------
    t
        Transition that should be enabled
    marking
        Current marking
    """
    missing = 0
    tokens_added = {}
    for a in t.in_arcs:
        if marking[a.source] < a.weight:
            missing = missing + (a.weight - marking[a.source])
            tokens_added[a.source] = a.weight - marking[a.source]
            marking[a.source] = marking[a.source] + a.weight
    return [missing, tokens_added]


@classmethod
def recover_orphaned_artifact(cls, component_build):
    """
        Searches for a complete build of an artifact belonging to the module and sets the
        component_build in the MBS database to the found build. This usually returns nothing since
        these builds should *not* exist.
        :param artifact_name: a ComponentBuild object
        :return: a list of msgs that MBS needs to process
        """
    return []


def factor_octets(octet_array, is_ipv6):
    """Convert each decimal octet into a factor of the
    divisor (16 or 256) and a remainder"""
    if is_ipv6:
        divisor = 256
    else:
        divisor = 16
    factord_octet_array = []
    for i in range(len(octet_array)):
        factord_octet_array.extend([octet_array[i] // divisor, octet_array[
            i] % divisor])
    return factord_octet_array


def sequence(value):
    """Return tuple containing value if value is not a tuple or list.

    >>> sequence(1)
    (1,)
    >>> sequence([1])
    [1]
    >>> sequence('ab')
    ('ab',)

    """
    return value if isinstance(value, (tuple, list)) else (value,)


def callFilterVisible(dropdownInput):
    """Handle visibility of filter input fields and description depending on
    whether a value is selected in the dropdown. Refers to the Second Order Section of the UI.

    Parameters
    ----------
    dropdownInput : :obj:`String`
        Either filter type as a string or "".

    Returns
    -------
    :obj:`Dictionary`
        Dictionary containing CSS style information for Dash.
        Changes 'display' style of filter inputs to either 'none' or 'inline-block'.

    """
    if dropdownInput != '':
        return {'display': 'inline-block'}, {'display': 'inline-block'}, {
            'display': 'inline-block'}
    return {'display': 'none'}, {'display': 'none'}, {'display': 'none'}


def overlappingDates(date_set1, date_set2):
    """
    date_set1: (tuple) a tuple with the start date and end date
    date_set2: (tuple) a tuple with the start date and end date
    """
    if date_set1[0] > date_set2[0]:
        start_date = date_set1[0]
    else:
        start_date = date_set2[0]
    if date_set1[-1] < date_set2[-1]:
        end_date = date_set1[-1]
    else:
        end_date = date_set2[-1]
    return start_date, end_date


@staticmethod
def _test_is_single_matrix(data):
    """Static method because it belongs to the class, ie is only invoked via self.test_single_matrix or Adjacency.test_single_matrix and requires no self argument."""
    if len(data.shape) == 1:
        return True
    else:
        return False


def logout(request):
    """Perform a logout."""


def _add_module_to_zip(zf, remote_module_fqn, b_module_data):
    """Add a module from ansible or from an ansible collection into the module zip"""
    module_path_parts = remote_module_fqn.split('.')
    module_path = '/'.join(module_path_parts) + '.py'
    zf.writestr(module_path, b_module_data)
    if module_path_parts[0] == 'ansible':
        start = 2
        existing_paths = frozenset()
    else:
        start = 1
        existing_paths = frozenset(zf.namelist())
    for idx in range(start, len(module_path_parts)):
        package_path = '/'.join(module_path_parts[:idx]) + '/__init__.py'
        if package_path in existing_paths:
            continue
        zf.writestr(package_path, b'')


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

        :param SharedLinkSettingsChangeAudienceDetails val:
        :rtype: EventDetails
        """
    return cls('shared_link_settings_change_audience_details', val)


def concatenate(items):
    """
    Concatenate a list of items in a human friendly way.

    :param items: A sequence of strings.
    :returns: A single string.

    >>> from humanfriendly.text import concatenate
    >>> concatenate(["eggs", "milk", "bread"])
    'eggs, milk and bread'
    """
    items = list(items)
    if len(items) > 1:
        return ', '.join(items[:-1]) + ' and ' + items[-1]
    elif items:
        return items[0]
    else:
        return ''


def verifyIdentifier(identifier):
    """
        Verify if an identity corresponds to a valid session. Returns
        a boolean indicating if the identify is valid.
        """


def serialise_none(b, context=None):
    """Serialise a None value.

    Ignores its parameter.

    """
    return b''


@classmethod
def get_unit_number(cls):
    """I know, stupid. But it parallels other methods
        so the selection buttons will work the same"""
    return [cls.unit_number]


def make_config(key, show_index=True, available_transforms=[],
    initial_visible_columns=[]):
    """Utility function for creating front-end configurations.

    For some frequently used parameters, it creates the nested tree structure
    expected by the JavaScript front-end, but thus can't exhaust all the configuration
    possibilities.

    Args:
        key (str): in the document table, which column contains the unique key for that row,
            that is used to request the corresponding record.
        show_index (bool, optional): indicates whether the index of the pandas dataframe is
            visible in the document table.
        availabe_transforms (optional): list of strings of transform types, for each of
            which a button is created in the UI to use that transform.
        initial_visible_columns (optional): a list of column names that are visible in the table
            upon first loading of the page.
    """
    return {'datatable': {'state': {'initialVisibleColumns':
        initial_visible_columns}, 'transforms': {'toolbox': {'available':
        available_transforms}}, 'table': {'show_index': show_index, 'rows':
        {'keyField': key}}}}