def get_halos_per_forest(f_in, Snap_Keys, haloID_field='ID', forestID_field
    ='ForestID'):
    """
    Determines the number of halos in each forest.

    The resulting Dictionary is nested with the outer-key given by the ForestID
    and the inner-key given by the snapshot field name.

    We also generate the offset for each Forest at each snapshot.  This is
    necessary because whilst Forest 5 may saved first at snapshot 20, it isn't
    necessarily saved first at snapshot 21.

    .. note::
        The default parameters are chosen to match the ASTRO3D Genesis trees as
        produced by VELOCIraptor + Treefrog.

    Parameters
    ----------

    f_in: Open HDF5 file.
        HDF5 file that contains the sorted trees.

    Snap_Keys: List of strings.
        List of keys that correspond to the fields containing the snapshot
        data.

    haloID_field: String. Default: 'ID'.
        Field name within the HDF5 file that corresponds to the unique halo ID.

    forestID_field: String. Default: 'ForestID'.
        Field name within the HDF5 file that corresponds to forest ID.

    Returns
    ----------

    NHalos_forest: Nested Dictionary.
        Nested dictionary that contains the number of halos for each Forest at
        each snapshot.  Outer-key is the ForestID and inner-key is the snapshot
        key.

    NHalos_forest_offset: Nested Dictionary.
        Nested dictionary that contains the offset for each Forest at each
        snapshot. Outer-key is the ForestID and inner-key is the snapshot key.
        This is required because whilst the tree is sorted by ForestID, the
        relative position of the tree can change from snapshot to snapshot.
    """
    import numpy as np
    import time
    import os
    from tqdm import tqdm
    start_time = time.time()
    print('')
    print(
        'Generating the dictionary for the number of halos in each forest at each snapshot.'
        )
    NHalos_forest = {}
    NHalos_forest_offset = {}
    for count, snap_key in enumerate(tqdm(Snap_Keys)):
        if len(f_in[snap_key][haloID_field]) == 0:
            continue
        halos_counted = 0
        halo_forestids = f_in[snap_key][forestID_field][:]
        forests_binned = np.bincount(halo_forestids)
        forestIDs = np.nonzero(forests_binned)[0]
        for forest_id in forestIDs:
            this_snap_NHalos = forests_binned[forest_id]
            try:
                NHalos_forest[forest_id][snap_key] = this_snap_NHalos
                NHalos_forest_offset[forest_id][snap_key] = halos_counted
            except KeyError:
                NHalos_forest[forest_id] = {snap_key: this_snap_NHalos}
                NHalos_forest_offset[forest_id] = {snap_key: halos_counted}
            halos_counted += this_snap_NHalos
    end_time = time.time()
    print('Creation of number of halos per forest took {0:3f} seconds.'.
        format(end_time - start_time))
    print('')
    return NHalos_forest, NHalos_forest_offset


def ipython():
    """
    Use IPython.embed() to experiment in the python environment.
    """
    import IPython
    IPython.embed()


@classmethod
def bound_from_string(cls, s):
    """Convert `s` to boundary value"""
    return None if s in ('None', '') else cls._sub_type_from_str(s)


@staticmethod
def simplify_tag(tag):
    """
        Maps part of speech (PoS) tag to a subset of PoS tags to better consolidate categorical labels.

        Parameters
        ----------
        tag : str
            The Penn-style PoS tag to be mapped to a simplified form.

        Returns
        -------
        str
            A simplified form of `tag`.  In some cases, the returned form may be identical to `tag`.
        """
    simple_tag = '"{}"'.format(tag)
    if tag.startswith('NNP'):
        simple_tag = '/^NNP/'
    elif tag.startswith('NN'):
        simple_tag = '/^N/'
    elif tag.startswith('VB'):
        simple_tag = '/^V/'
    elif tag.startswith('JJ'):
        simple_tag = '/^J/'
    elif tag.startswith('RB'):
        simple_tag = '/^RB/'
    elif tag.startswith('PRP'):
        simple_tag = '/^PRP/'
    elif tag == 'WDT':
        simple_tag = '/DT$/'
    elif tag == 'DT':
        simple_tag = '/DT$/'
    return simple_tag


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


@classmethod
def bookmarksManager(cls):
    """
        Class method to get a reference to the bookmarks manager.

        @return reference to the bookmarks manager (BookmarksManager)
        """
    if cls._bookmarksManager is None:
        from .Bookmarks.BookmarksManager import BookmarksManager
        cls._bookmarksManager = BookmarksManager()
    return cls._bookmarksManager


@staticmethod
def _sanitizer(obj):
    """Sanitizer method that will be passed to jsonutils.loads."""
    return obj


def alias(prop_name, doc=None):
    """
    Returns a property that is a read/write alias for another attribute
    of the object.

    See :func:`dict_alias`.
    """
    if doc is None:
        doc = 'Alias for :attr:`' + prop_name + '`'
    prop_name = str(prop_name)
    return property(lambda self: getattr(self, prop_name), lambda self, nv:
        setattr(self, prop_name, nv), doc=doc)


@classmethod
def from_dict(cls, data: dict) ->'CollectionArgument':
    """
        Creates a :class:`~github.query.CollectionArgument` object from
        a dict.

        Parameters
        ----------
        data: :class:`dict`
            The dict to convert to a
            :class:`~github.query.CollectionArgument`.

        Returns
        -------
        :class:`~github.query.CollectionArgument`
            The collection argument object.
        """
    name = data['name']
    value = data['value']
    argument = cls(name=name, value=value)
    return argument


def scalarToPython(ascalar):
    """Convert an array scalar to a python type
    """
    return ascalar


def build_tree(assignments, initial=None):
    """
    Builds a tree of dictionaries from lists of LineagePair objects
    in 'assignments'.  This tree can then be used to find lowest common
    ancestor agreements/confusion.
    """
    if initial is None:
        tree = {}
    else:
        tree = initial
    if not assignments:
        raise ValueError('empty assignment passed to build_tree')
    for assignment in assignments:
        node = tree
        for lineage_tup in assignment:
            if lineage_tup.name:
                child = node.get(lineage_tup, {})
                node[lineage_tup] = child
                node = child
    return tree


def max_pool_forward_reshape(x, pool_param):
    """
    A fast implementation of the forward pass for the max pooling layer that uses
    some clever reshaping.

    This can only be used for square pooling regions that tile the input.
    """
    N, C, H, W = x.shape
    pool_height, pool_width = pool_param['pool_height'], pool_param[
        'pool_width']
    stride = pool_param['stride']
    assert pool_height == pool_width == stride, 'Invalid pool params'
    assert H % pool_height == 0
    assert W % pool_height == 0
    x_reshaped = x.reshape(N, C, H // pool_height, pool_height, W //
        pool_width, pool_width)
    out = x_reshaped.max(axis=3).max(axis=4)
    cache = x, x_reshaped, out
    return out, cache


def get_schema():
    """Schema structure of this resource

    :return: schema dictionary
    :rtype: dict
    """
    return {'mongo_indexes': {'index_updated': [('_updated', 1)],
        'index_name': [('name', 1)]}, 'schema': {'schema_version': {'type':
        'integer', 'default': 1}, 'imported_from': {'schema_version': 1,
        'title': 'Imported from', 'comment':
        'Item importation source (alignak-backend-import, ...)', 'type':
        'string', 'default': 'unknown'}, 'definition_order': {
        'schema_version': 1, 'title': 'Definition order', 'comment':
        'Priority level if several elements have the same name', 'type':
        'integer', 'default': 100}, 'name': {'schema_version': 1, 'title':
        'Services group name', 'comment': 'Unique services group name',
        'type': 'string', 'required': True, 'empty': False, 'unique': True},
        'alias': {'schema_version': 1, 'title': 'Alias', 'comment':
        'Element friendly name used by the Web User Interface.', 'type':
        'string', 'default': ''}, 'notes': {'schema_version': 1, 'title':
        'Notes', 'comment':
        'Element notes. Free text to store element information.', 'type':
        'string', 'default': ''}, 'notes_url': {'schema_version': 1,
        'title': 'Notes URL', 'comment':
        'Element notes URL. Displayed in the Web UI as some URL to be navigatesd. Note that a very specific text format must be used for this field, see the Web UI documentation.'
        , 'type': 'string', 'default': ''}, 'action_url': {'schema_version':
        1, 'title': 'Actions URL', 'comment':
        'Element actions URL. Displayed in the Web UI as some available actions. Note that a very specific text format must be used for this field, see the Web UI documentation.'
        , 'type': 'string', 'default': ''}, 'servicegroups': {
        'schema_version': 1, 'title': 'Groups', 'comment':
        'List of the groups of this group', 'type': 'list', 'schema': {
        'type': 'objectid', 'data_relation': {'resource': 'servicegroup',
        'embeddable': True}}, 'default': []}, 'services': {'schema_version':
        1, 'title': 'Members', 'comment':
        'List of the members of this group', 'type': 'list', 'schema': {
        'type': 'objectid', 'data_relation': {'resource': 'service',
        'embeddable': True}}, 'default': []}, '_level': {'schema_version':
        1, 'title': 'Level', 'comment': 'Level in the hierarchy', 'type':
        'integer', 'default': 0}, '_parent': {'schema_version': 1, 'title':
        'Parent', 'comment': 'Immediate parent in the hierarchy', 'type':
        'objectid', 'data_relation': {'resource': 'servicegroup',
        'embeddable': True}, 'nullable': True, 'default': None},
        '_tree_parents': {'schema_version': 1, 'title': 'Parents',
        'comment': 'List of parents in the hierarchy', 'type': 'list',
        'schema': {'type': 'objectid', 'data_relation': {'resource':
        'servicegroup', 'embeddable': True}}, 'default': []}, '_realm': {
        'schema_version': 1, 'title': 'Realm', 'comment':
        'Realm this element belongs to.', 'type': 'objectid',
        'data_relation': {'resource': 'realm', 'embeddable': True},
        'required': True}, '_sub_realm': {'schema_version': 1, 'title':
        'Sub-realms', 'comment':
        'Is this element visible in the sub-realms of its realm?', 'type':
        'boolean', 'default': True}, '_users_read': {'schema_version': 1,
        'type': 'list', 'schema': {'type': 'objectid', 'data_relation': {
        'resource': 'user', 'embeddable': True}}}, '_users_update': {
        'schema_version': 1, 'type': 'list', 'schema': {'type': 'objectid',
        'data_relation': {'resource': 'user', 'embeddable': True}}},
        '_users_delete': {'schema_version': 1, 'type': 'list', 'schema': {
        'type': 'objectid', 'data_relation': {'resource': 'user',
        'embeddable': True}}}}, 'schema_deleted': {}}


def ct_bytes_compare(a, b):
    """
    Constant-time string compare.
    http://codahale.com/a-lesson-in-timing-attacks/
    """
    if not isinstance(a, bytes):
        a = a.decode('utf8')
    if not isinstance(b, bytes):
        b = b.decode('utf8')
    if len(a) != len(b):
        return False
    result = 0
    for x, y in zip(a, b):
        result |= x ^ y
    return result == 0


def personImageFile(person):
    """Finds primary person image file name.

    Scans INDI's OBJE records and finds "best" FILE record from those.

    OBJE record contains one (in 5.5) or few (in 5.5.1) related multimedia
    files. In 5.5 file contents can be embedded as BLOB record though we do
    not support this. In 5.5.1 file name is stored in a record.

    In 5.5.1 OBJE record is supposed to have structure::

        OBJE
          +1 FILE <MULTIMEDIA_FILE_REFN>    {1:M}
            +2 FORM <MULTIMEDIA_FORMAT>     {1:1}
                +3 MEDI <SOURCE_MEDIA_TYPE> {0:1}
          +1 TITL <DESCRIPTIVE_TITLE>       {0:1}
          +1 _PRIM {Y|N}                    {0:1}

    Some applications which claim to be  5.5.1 version still store OBJE
    record in 5.5-like format::

        OBJE
          +1 FILE <MULTIMEDIA_FILE_REFN>    {1:1}
          +1 FORM <MULTIMEDIA_FORMAT>       {1:1}
          +1 TITL <DESCRIPTIVE_TITLE>       {0:1}
          +1 _PRIM {Y|N}                    {0:1}

    This method returns the name of the FILE corresponding to _PRIM=Y, or if
    there is no _PRIM record then the first FILE record. Potentially we also
    need to look at MEDI record to only chose image type, but I have not seen
    examples of MEDI use yet, so for now I only select FORM which correspond
    to images.

    :param person: :py:class:`ged4py.model.Individual` instance
    :return: String with file name or None.
    """
    first = None
    for obje in person.sub_tags('OBJE'):
        objform = obje.sub_tag('FORM')
        objform = objform.value if objform else 'jpg'
        primary = obje.sub_tag('_PRIM')
        primary = primary.value == 'Y' if primary is not None else False
        files = obje.sub_tags('FILE')
        for file in files:
            form = file.sub_tag('FORM')
            form = form.value if form is not None else objform
            if form.lower() in ('jpg', 'gif', 'tif', 'bmp'):
                if primary:
                    return file.value
                elif not first:
                    first = file.value
    return first


def _split_string_at_outer_commas(s):
    """
    Splits a string only at those commas that are not inside some sort of parentheses
    e.g. "hello, [2, 5], {2: 7}" => ["hello", "[2, 5]", "{2: 7}"]
    """
    out = []
    paren_count = square_count = curly_count = 0
    last_split = i = 0
    for character in s:
        i += 1
        if character == '(':
            paren_count += 1
        elif character == '[':
            square_count += 1
        elif character == '{':
            curly_count += 1
        elif character == ')':
            paren_count -= 1
        elif character == ']':
            square_count -= 1
        elif character == '}':
            curly_count -= 1
        elif character == ',' and paren_count == square_count == curly_count == 0:
            out.append(s[last_split:i - 1].strip())
            last_split = i
    out.append(s[last_split:].strip())
    return out


def select_pick(report_index: int=0, extend: bool=False):
    """Select reports by index

    :param report_index: Report, Index of the report
    :type report_index: int
    :param extend: Extend, Extend report selection
    :type extend: bool
    """
    pass


def generate_bounding_box(bottom_left, top_right):
    """
    Takes two opposite corners of a bounding box (order matters!) & generates
    a two-tuple of the correct coordinates for the bounding box.

    The two-tuple is in the form ``((min_lat, min_lng), (max_lat, max_lng))``.
    """
    west, lat_1 = bottom_left.coords
    east, lat_2 = top_right.coords
    min_lat, max_lat = min(lat_1, lat_2), max(lat_1, lat_2)
    return (min_lat, west), (max_lat, east)


def append_to_list_in_config(yaml_filepath, key_path, value):
    """
    Load YAML. Find the key or a sub key. It must be a list.
    Append the value the end of the list.
    """


def p_definition(t):
    """definition : constant_def
                  | type_def
                  | program_def"""


def qt_font_to_style(font, color):
    """
    Convert a Qt font to CSS style
    """
    if font is None:
        font = 'TypeWriter,10,-1,5,75,0,0,0,0,0'
    font_info = font.split(',')
    style = 'font-family: {};font-size: {};'.format(font_info[0], font_info[1])
    if font_info[4] == '75':
        style += 'font-weight: bold;'
    if font_info[5] == '1':
        style += 'font-style: italic;'
    if color is None:
        color = '000000'
    if len(color) == 9:
        style += 'fill: #' + color[-6:] + ';'
        style += 'fill-opacity: {};'.format(round(1.0 / 255 * int(color[:3]
            [-2:], base=16), 2))
    else:
        style += 'fill: #' + color[-6:] + ';'
        style += 'fill-opacity: {};'.format(1.0)
    return style


def storageinfo(exclusivefiles=False, sharedfiles=False, revisionscount=
    False, trackedsize=False, storedsize=False):
    """Obtain information about storage for this file's data.

        Returns a dict describing storage for this tracked path. The keys
        in the dict map to arguments of the same. The arguments are bools
        indicating whether to calculate and obtain that data.

        exclusivefiles
           Iterable of (vfs, path) describing files that are exclusively
           used to back storage for this tracked path.

        sharedfiles
           Iterable of (vfs, path) describing files that are used to back
           storage for this tracked path. Those files may also provide storage
           for other stored entities.

        revisionscount
           Number of revisions available for retrieval.

        trackedsize
           Total size in bytes of all tracked revisions. This is a sum of the
           length of the fulltext of all revisions.

        storedsize
           Total size in bytes used to store data for all tracked revisions.
           This is commonly less than ``trackedsize`` due to internal usage
           of deltas rather than fulltext revisions.

        Not all storage backends may support all queries are have a reasonable
        value to use. In that case, the value should be set to ``None`` and
        callers are expected to handle this special value.
        """


def process_embed(embed_items=None, embed_tracks=None, embed_metadata=None,
    embed_insights=None):
    """Returns an embed field value based on the parameters."""
    result = None
    embed = ''
    if embed_items:
        embed = 'items'
    if embed_tracks:
        if embed != '':
            embed += ','
        embed += 'tracks'
    if embed_metadata:
        if embed != '':
            embed += ','
        embed += 'metadata'
    if embed_insights:
        if embed != '':
            embed += ','
        embed += 'insights'
    if embed != '':
        result = embed
    return result


def Capillary(V, mu, sigma):
    """Calculates Capillary number `Ca` for a characteristic velocity `V`,
    viscosity `mu`, and surface tension `sigma`.

    .. math::
        Ca = \\frac{V \\mu}{\\sigma}

    Parameters
    ----------
    V : float
        Characteristic velocity, [m/s]
    mu : float
        Dynamic viscosity, [Pa*s]
    sigma : float
        Surface tension, [N/m]

    Returns
    -------
    Ca : float
        Capillary number, [-]

    Notes
    -----
    Used in porous media calculations and film flow calculations.
    Surface tension may gas-liquid, or liquid-liquid.

    .. math::
        Ca = \\frac{\\text{Viscous forces}}
        {\\text{Surface forces}}

    Examples
    --------
    >>> Capillary(1.2, 0.01, .1)
    0.12

    References
    ----------
    .. [1] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook,
       Eighth Edition. McGraw-Hill Professional, 2007.
    .. [2] Kundu, Pijush K., Ira M. Cohen, and David R. Dowling. Fluid
       Mechanics. Academic Press, 2012.
    """
    return V * mu / sigma


def index_doc(docid, value):
    """Add a document to the index.

        docid: int, identifying the document

        value: the value to be indexed

        return: None

        This can also be used to reindex documents.
        """


def shortest_loop(code):
    """Sorts crossing by shortest loop described"""
    return sorted(code, key=lambda x: abs(abs(x[0]) - abs(x[1])))


def _add_conversion_and_inverse(conv_dict, value, unit1, unit2):
    """Add a specific conversion and it's inverse.

    This function is mainly here to ensure that we don't forget to add
    the inverse conversions.

    Parameters
    ----------
    conv_dict : dict
        This is where we store the conversion.
    value : float
        The conversion factor to add
    unit1 : string
        The unit we are converting from.
    unit2 : string
        The unit we are converting to.

    Returns
    -------
    None, but updates the given `conv_dict`.

    """
    conv_dict[unit1, unit2] = value
    conv_dict[unit2, unit1] = 1.0 / conv_dict[unit1, unit2]


@staticmethod
def pc_func(x, *params):
    """Bernoulli likelihood given model parameters."""
    raise NotImplementedError


@classmethod
def where(cls, session, params):
    """Finds a list of models by some parameters"""
    if params is None:
        return None
    interface = cls.interface(session)
    return interface.where(params)


def visual_transform_apply():
    """Apply final constrained position of pose bones to their transform

    """
    pass


def parse_quant(quant):
    """
    Normalise quanitifers
    """
    if quant.startswith('}{'):
        quant = quant.strip('}{ ')
        if ',' in quant:
            return quant.replace(',', ':')
        else:
            return quant
    return quant


def endswith_strip(s, endswith='.txt', ignorecase=True):
    """ Strip a suffix from the end of a string

    >>> endswith_strip('http://TotalGood.com', '.COM')
    'http://TotalGood'
    >>> endswith_strip('http://TotalGood.com', endswith='.COM', ignorecase=False)
    'http://TotalGood.com'
    """
    if ignorecase:
        if s.lower().endswith(endswith.lower()):
            return s[:-len(endswith)]
    elif s.endswith(endswith):
        return s[:-len(endswith)]
    return s


def ensure_trailing_newline(s: str) ->str:
    """Returns the passed string, but with a guaranteed trailing newline."""
    return s + ('' if s[-1] == '\n' else '\n')


def _decorate_tree(t, series):
    """ Attaches some default values on the tree for plotting.

    Parameters
    ----------
    t: skbio.TreeNode
        Input tree
    series: pd.Series
        Input pandas series

    """
    for i, n in enumerate(t.postorder()):
        n.size = 30
        if n.is_root():
            n.size = 50
        elif n.name == n.parent.children[0].name:
            n.color = '#00FF00'
        else:
            n.color = '#FF0000'
        if not n.is_tip():
            t.length = series.loc[n.name]
    return t


def getPendingBuildRequestStatuses():
    """
        Get a L{IBuildRequestStatus} implementations for all unclaimed build
        requests.

        @returns: list of objects via Deferred
        """


@classmethod
def table_name_col(cls):
    """
        Return the name of the metadata column used to store the feature table
        name.
        """
    return 'f_table_name'


@classmethod
def convert_to_minor_ver(cls, version):
    """
        Converts the a version number into the minor version.

        :param int version: Version number to be converted.
        :return: Minor version.
        :rtype: int
        """
    return (version & 65280) >> 8


def mark_sharp(clear: bool=False, use_verts: bool=False):
    """(Un)mark selected edges as sharp

    :param clear: Clear
    :type clear: bool
    :param use_verts: Vertices, Consider vertices instead of edges to select which edges to (un)tag as sharp
    :type use_verts: bool
    """
    pass


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

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

    Example::

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

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


def datetime_range(start, end, step):
    """Generates dates from *start* (inclusive) to *end* (exclusive) with the
    given *step*."""
    dt = start
    while dt < end:
        yield dt
        dt += step


def contains_list(longer, shorter):
    """Check if longer list starts with shorter list"""
    if len(longer) <= len(shorter):
        return False
    for a, b in zip(shorter, longer):
        if a != b:
            return False
    return True


def get_bonds(struct):
    """Get a list of bonds in a dot-paren structure."""
    struct = struct.replace('+', '')
    bonds = []
    open_pos = []
    for pos, symb in enumerate(struct):
        if symb == '(':
            open_pos.append(pos)
        elif symb == ')':
            assert len(open_pos) != 0
            start = open_pos.pop()
            bonds.append((start, pos))
        else:
            assert symb == '.', "Structure '%s' not in dot-paren form" % struct
    return bonds


def set_underline(label):
    """Set underscore for mnemonic accelerator"""
    return '_' + label.replace('_', '__')


@classmethod
def get_cities(cls, find=None):
    """
        Method for fetching info about all cities.

        :example:
            ``Address.get_cities()``
            ``Address.get_cities(find='Здолбунів')``
        :return:
            list(dictionary)
        :rtype:
            list
        """
    return cls.send(method='getCities', method_props={'FindByString': find})


@staticmethod
def _max_area_triangle_for_std_form(z):
    """
        Imagine an ideal tetrahedron in the upper half space model with
        vertices at 0, 1, z, and infinity. Pick the lowest (horizontal)
        horosphere about infinity that intersect the tetrahedron in a
        triangle, i.e, just touches the face opposite to infinity.
        This method will return the hyperbolic area of that triangle.

        The result is the same for z, 1/(1-z), and 1 - 1/z.
        """
    if z.real() < 0:
        return 2 * z.imag() / abs(z - 1) ** 2
    if z.real() > 1:
        return 2 * z.imag() / abs(z) ** 2
    if abs(2 * z - 1) < 1:
        return 2 * z.imag()
    return 2 * z.imag() ** 3 / (abs(z) * abs(z - 1)) ** 2


@classmethod
def get_perceval_params_from_url(cls, url):
    """ Get the perceval params given a URL for the data source """
    params = []
    dparam = cls.get_arthur_params_from_url(url)
    params.append(dparam['owner'])
    params.append(dparam['repository'])
    return params


def load_local_kegg_db(db_fname):
    """Load Kegg compound records from a local text DB."""
    kegg = {}
    db = open(db_fname)
    curr_c = None
    curr_txt = None
    for line in db:
        if len(line.strip()) == 0:
            continue
        if line.startswith('---- Compound:'):
            if curr_c is not None:
                whole_rec = ''.join(curr_txt)
                kegg[curr_c] = whole_rec
            curr_c = line.split(':')[1].strip()
            curr_txt = []
        elif curr_c is not None:
            curr_txt.append(line)
    whole_rec = ''.join(curr_txt)
    kegg[curr_c] = whole_rec
    db.close()
    return kegg


def normalize(tensor, stats):
    """
    normalize a tensor using a running mean and std

    :param tensor: (TensorFlow Tensor) the input tensor
    :param stats: (RunningMeanStd) the running mean and std of the input to normalize
    :return: (TensorFlow Tensor) the normalized tensor
    """
    if stats is None:
        return tensor
    return (tensor - stats.mean) / stats.std


def kinks(path, tol=1e-08):
    """returns indices of segments that start on a non-differentiable joint."""
    kink_list = []
    for idx in range(len(path)):
        if idx == 0 and not path.isclosed():
            continue
        try:
            u = path[(idx - 1) % len(path)].unit_tangent(1)
            v = path[idx].unit_tangent(0)
            u_dot_v = u.real * v.real + u.imag * v.imag
            flag = False
        except ValueError:
            flag = True
        if flag or abs(u_dot_v - 1) > tol:
            kink_list.append(idx)
    return kink_list


def powr(x, y):
    """return x^y for x>0"""
    return x ** y


def printList(list_):
    """course list formatted output.

    Args:
        list_ (list): course list.
    """
    for i, oneCourse in enumerate(list_):
        cname = oneCourse.get('cname', '')
        teacher = oneCourse.get('teacher', '')
        op_time_1 = oneCourse.get('op_time_1', '')
        op_time_2 = oneCourse.get('op_time_2', '')
        if op_time_2 == None:
            op_time_2 = ''
        print('{}\t{}\t{}\t{}\t{}\t{}'.format(i, oneCourse['op_code'],
            cname, teacher, op_time_1, op_time_2))


def get_set_wmf_eof(parent=None, new_value=None, **kwargs):
    """Size getter/setter for the length of a wmf file."""
    if parent is None:
        raise KeyError('Cannot get or set the size of the' +
            'wmf file without a supplied parent.')
    if new_value is None:
        return parent.header.filesize * 2 + parent.placeable_header.binsize
    parent.header.filesize = (new_value - parent.placeable_header.binsize) // 2


def unquote_header_value(value, is_filename=False):
    """Unquotes a header value.  (Reversal of :func:`quote_header_value`).
    This does not use the real unquoting but what browsers are actually
    using for quoting.

    :param value: the header value to unquote.
    :rtype: str
    """
    if value and value[0] == value[-1] == '"':
        value = value[1:-1]
        if not is_filename or value[:2] != '\\\\':
            return value.replace('\\\\', '\\').replace('\\"', '"')
    return value


@classmethod
def sensor_map(cls):
    """
        Return sensor map
        """
    return cls.__sensor_map


def unionranges(rangeslist):
    """Return the union of some closed intervals

    >>> unionranges([])
    []
    >>> unionranges([(1, 100)])
    [(1, 100)]
    >>> unionranges([(1, 100), (1, 100)])
    [(1, 100)]
    >>> unionranges([(1, 100), (2, 100)])
    [(1, 100)]
    >>> unionranges([(1, 99), (1, 100)])
    [(1, 100)]
    >>> unionranges([(1, 100), (40, 60)])
    [(1, 100)]
    >>> unionranges([(1, 49), (50, 100)])
    [(1, 100)]
    >>> unionranges([(1, 48), (50, 100)])
    [(1, 48), (50, 100)]
    >>> unionranges([(1, 2), (3, 4), (5, 6)])
    [(1, 6)]
    """
    rangeslist = sorted(set(rangeslist))
    unioned = []
    if rangeslist:
        unioned, rangeslist = [rangeslist[0]], rangeslist[1:]
    for a, b in rangeslist:
        c, d = unioned[-1]
        if a > d + 1:
            unioned.append((a, b))
        else:
            unioned[-1] = c, max(b, d)
    return unioned


def unflatten(dictionary: dict, sep: str='.'):
    """
    Turns a flattened dict into a nested one, e.g. {'a.b':2, 'c':3} becomes {'a':{'b': 2}, 'c': 3}
    From https://stackoverflow.com/questions/6037503/python-unflatten-dict

    Parameters
    ----------
    dictionary: dict to be un-flattened
    sep: separator with which the nested keys are separated

    Returns
    -------
    resultDict: the nested dictionary.
    """
    resultDict = dict()
    for key, value in dictionary.items():
        parts = key.split(sep)
        d = resultDict
        for part in parts[:-1]:
            if part not in d:
                d[part] = dict()
            d = d[part]
        d[parts[-1]] = value
    return resultDict


def checksum(command):
    """
    Satel communication checksum
    """
    crc = 5242
    for b in bytearray(command):
        crc = crc << 1 & 65535 | (crc & 32768) >> 15
        crc = crc ^ 65535
        crc = crc + (crc >> 8) + b & 65535
    return crc


def flip_around_x(pc_data):
    """ flip a structured array around x, in place"""
    pc_data['y'] = -pc_data['y']
    pc_data['z'] = -pc_data['z']
    if 'x_origin' in pc_data:
        pc_data['y_origin'] = -pc_data['y_origin']
        pc_data['z_origin'] = -pc_data['z_origin']


@classmethod
def collection_schema_url(cls, version, filename='collection.json'):
    """
        Return path to collection spec
        :param version: version to validate
        :param filename: json file to find
        :return: url
        """
    return cls(version, 'json-schema', filename).COLLECTION_URL


def on_sampling_rate_change(sampling_rate: int, pass_through):
    """The callback method, that is called, when the JACK server's sampling rate changes."""
    pass_through.input(float(sampling_rate))


def classname_for_table(base, tablename, table):
    """Return the class name that should be used, given the name
    of a table.

    The default implementation is::

        return str(tablename)

    Alternate implementations can be specified using the
    :paramref:`.AutomapBase.prepare.classname_for_table`
    parameter.

    :param base: the :class:`.AutomapBase` class doing the prepare.

    :param tablename: string name of the :class:`.Table`.

    :param table: the :class:`.Table` object itself.

    :return: a string class name.

     .. note::

        In Python 2, the string used for the class name **must** be a
        non-Unicode object, e.g. a ``str()`` object.  The ``.name`` attribute
        of :class:`.Table` is typically a Python unicode subclass, so the
        ``str()`` function should be applied to this name, after accounting for
        any non-ASCII characters.

    """
    return str(tablename)


@classmethod
def _event_key(cls, thing_event):
    """Returns the internal event key for the given Thing Event."""
    return thing_event.thing.url_name, thing_event.url_name


def is_file(obj):
    """
    Check if an object is file-like

    Parameters
    ------------
    obj : object
       Any object type to be checked

    Returns
    -----------
    is_file : bool
        True if object is a file
    """
    return hasattr(obj, 'read') or hasattr(obj, 'write')


def next_url(obj):
    """ Returns the url to be redirected to after successful creation
        """


def color_gradient(x):
    """
        Returns a color in Hex-RGB format between white and red if x is positive
        or between white and green if x is negative
    """
    grad = 220 - abs(x) * 80
    if x > 0:
        return '%.2x%.2x%.2x' % (255, grad, grad)
    elif x < 0:
        return '%.2x%.2x%.2x' % (grad, 255, grad)
    else:
        return '%.2x%.2x%.2x' % (100, 100, 100)


def print_character(ordchr):
    """Return a printable character, or '.' for non-printable ones."""
    if 31 < ordchr < 126 and ordchr != 92:
        return chr(ordchr)
    else:
        return '.'


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

        :rtype: str
        """
    return cls.__tablename__


def split_args(line):
    """
    Extract the relevant vars from the command line
    """
    arg = line.split()
    if len(arg) < 2:
        return None
    alias_pos = line.find(' ')
    alias = line[:alias_pos]
    end = line[alias_pos + 1:]
    args_pos = end.find(' ')
    if args_pos == -1:
        command = end
        args = ''
    else:
        command = end[:args_pos]
        args = end[args_pos + 1:]
    return alias, command, args


def no_tqdm(it, total=1, **kwargs):
    """ Do-nothing iterable wrapper to subsitute for tqdm when verbose==False """
    return it


@classmethod
def make_operand(cls, value):
    """Create an operand token."""
    if value.startswith('"'):
        subtype = cls.TEXT
    elif value.startswith('#'):
        subtype = cls.ERROR
    elif value in ('TRUE', 'FALSE'):
        subtype = cls.LOGICAL
    else:
        try:
            float(value)
            subtype = cls.NUMBER
        except ValueError:
            subtype = cls.RANGE
    return cls(value, cls.OPERAND, subtype)


def nothing(*args, **kwargs):
    """A function that does nothing.

  :param args:
    Any number of positional arguments.
  :param kwargs:
    Any number of keyword arguments.
  """
    pass


def abort_document_version_upload(DocumentId=None, VersionId=None):
    """
    Aborts the upload of the specified document version that was previously initiated by  InitiateDocumentVersionUpload . The client should make this call only when it no longer intends or fails to upload the document version.
    See also: AWS API Documentation

    :example: response = client.abort_document_version_upload(
        DocumentId='string',
        VersionId='string'
    )

    :type DocumentId: string
    :param DocumentId: [REQUIRED]
            The ID of the document.

    :type VersionId: string
    :param VersionId: [REQUIRED]
            The ID of the version.

    """
    pass


def getDefaultConfiguration(nodeType):
    """
        Get the default configuration for the given node type.

        @param nodeType: Either C{'leaf'} or C{'collection'}.
        @type nodeType: C{str}
        @return: The default configuration.
        @rtype: C{dict}.
        @raises: L{idavoll.error.NoCollections} if collections are not
                 supported.
        """


def looks_like_issubclass(obj, classname):
    """ Return True if the object has a class or superclass with the given class
    name.

    Ignores old-style classes.
    """
    t = obj
    if t.__name__ == classname:
        return True
    for klass in t.__mro__:
        if klass.__name__ == classname:
            return True
    return False


def pMonth():
    """Return the abreviated (with period) month name."""


def add_arguments(parser):
    """
    Inject an arg into the user's parser. Intented to pair with
    :py:meth:`Auth.from_env_or_args`: after argparse parses the
    args, feed that the args namespace.
    """
    parser.add_argument('--osrc', type=str, help=
        'OpenStack parameters file that overrides envvars.')


@classmethod
def global_config(cls, key, *args):
    """ This reads or sets the global settings stored in class.settings. """
    if args:
        cls.settings = cls.settings.copy()
        cls.settings[key] = args[0]
    else:
        return cls.settings[key]


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


def p_opt_fieldlist_empty(p):
    """opt_fieldlist : """
    p[0] = {}


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

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


def every(y):
    """ Returns all values (sequences) of y """
    return y


def get_features(geojson):
    """
    Helper function to extract features
    from dictionary. If it doesn't find
    it, raise a value error with a more
    informative error message.
    """
    try:
        features = geojson['features']
    except KeyError:
        raise KeyError(
            f'{geojson} is an invalid GeoJSON. Not a feature collection')
    return features


def get_diff_stats(repo, sha_fail, sha_pass, gh_wrapper) ->(int, int, int):
    """
    Get the diff size between two commits by using Github API
    :param repo: repo slug e.g. bugswarm/common
    :param sha_fail: Github failed commit sha
    :param sha_pass: Github passed commit sha
    :param gh_wrapper: Github_wrapper
    :return: additions, deletions, changes
    """
    url = 'https://api.github.com/repos/{}/compare/{}...{}'.format(repo,
        sha_fail, sha_pass)
    response, response_json = gh_wrapper.get(url)
    if response is None or response_json is None:
        return -1, -1, -1
    additions = 0
    deletions = 0
    changes = 0
    for f in response_json['files']:
        additions += f['additions']
        deletions += f['deletions']
        changes += f['changes']
    return additions, deletions, changes


def get_preexisting_shares():
    """Return the number of shares that were already present in the grid."""


@classmethod
def add_user_group(cls, options=None):
    """Associate an user group.

        Usage:
            hammer user-group add-user-group [OPTIONS]

        Options:
            --id ID
            --name NAME                                   Name to search by
            --user-group USER_GROUP_NAME                  Name to search by
            --user-group-id USER_GROUP_ID
        """
    cls.command_sub = 'add-user-group'
    return cls.execute(cls._construct_command(options), output_format='csv')


def _group_filter_values(seg, filter_indices, ms_per_input):
    """
    Takes a list of 1s and 0s and returns a list of tuples of the form:
    ['y/n', timestamp].
    """
    ret = []
    for filter_value, (_segment, timestamp) in zip(filter_indices, seg.
        generate_frames_as_segments(ms_per_input)):
        if filter_value == 1:
            if len(ret) > 0 and ret[-1][0] == 'n':
                ret.append(['y', timestamp])
            elif len(ret) > 0 and ret[-1][0] == 'y':
                ret[-1][1] = timestamp
            else:
                ret.append(['y', timestamp])
        elif len(ret) > 0 and ret[-1][0] == 'n':
            ret[-1][1] = timestamp
        elif len(ret) > 0 and ret[-1][0] == 'y':
            ret.append(['n', timestamp])
        else:
            ret.append(['n', timestamp])
    return ret


def get_num_of_rows(dur, n_rows, sr):
    """Return total number of samples. If dur is set, return dur*sr, if num_samples is set, return num_samples,
    if both set, raise an AttributeError. Only use one of the two.
    """
    if dur and n_rows is None:
        return int(dur * sr)
    elif dur is None and n_rows is None:
        return int(sr)
    elif n_rows and dur is None:
        return int(n_rows)
    else:
        raise AttributeError(
            'Only use either dur or n_rows to specify the number of rows of the signal.'
            )


@classmethod
def workbench_scenarios(cls):
    """A canned scenario for display in the workbench."""
    return [('UBC Peer Instruction: Basic', cls.resource_string(
        'static/xml/basic_scenario.xml'))]


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 PolsAnnuity(t):
    """Number of policies: Annuity"""
    return 0


def manage(value):
    """Returns a cachable attribute value"""


def firstOfMonth():
    """Get the date object which represents the first day of the month."""


def has_single_count(metadata):
    """
    Return True if the metadata dictionary has a single value for a "count" key.

    Written to improve readability, since this is used a lot in the annotation functions.
    """
    return metadata.get('count') is not None and not isinstance(metadata[
        'count'], list)


def load_vocab(vocab_filepath):
    """Load previously saved vocab to dic."""
    vocab = {}
    with open(vocab_filepath, 'r', encoding='utf-8') as vocab_str:
        for line in vocab_str:
            line = line.strip()
            items = line.split('\t')
            vocab[items[0]] = int(items[1])
    return vocab


def split():
    """Split off selected points from connected unselected points

    """
    pass


def put_targets(Rule=None, Targets=None):
    """
    Adds the specified targets to the specified rule, or updates the targets if they are already associated with the rule.
    Targets are the resources that are invoked when a rule is triggered. Example targets include EC2 instances, AWS Lambda functions, Amazon Kinesis streams, Amazon ECS tasks, AWS Step Functions state machines, and built-in targets. Note that creating rules with built-in targets is supported only in the AWS Management Console.
    For some target types, PutTargets provides target-specific parameters. If the target is an Amazon Kinesis stream, you can optionally specify which shard the event goes to by using the KinesisParameters argument. To invoke a command on multiple EC2 instances with one rule, you can use the RunCommandParameters field.
    To be able to make API calls against the resources that you own, Amazon CloudWatch Events needs the appropriate permissions. For AWS Lambda and Amazon SNS resources, CloudWatch Events relies on resource-based policies. For EC2 instances, Amazon Kinesis streams, and AWS Step Functions state machines, CloudWatch Events relies on IAM roles that you specify in the RoleARN argument in PutTarget . For more information, see Authentication and Access Control in the Amazon CloudWatch Events User Guide .
    When you specify Input , InputPath , or InputTransformer , you must use JSON dot notation, not bracket notation.
    When you add targets to a rule and the associated rule triggers soon after, new or updated targets might not be immediately invoked. Please allow a short period of time for changes to take effect.
    This action can partially fail if too many requests are made at the same time. If that happens, FailedEntryCount is non-zero in the response and each entry in FailedEntries provides the ID of the failed target and the error code.
    See also: AWS API Documentation

    :example: response = client.put_targets(
        Rule='string',
        Targets=[
            {
                'Id': 'string',
                'Arn': 'string',
                'RoleArn': 'string',
                'Input': 'string',
                'InputPath': 'string',
                'InputTransformer': {
                    'InputPathsMap': {
                        'string': 'string'
                    },
                    'InputTemplate': 'string'
                },
                'KinesisParameters': {
                    'PartitionKeyPath': 'string'
                },
                'RunCommandParameters': {
                    'RunCommandTargets': [
                        {
                            'Key': 'string',
                            'Values': [
                                'string',
                            ]
                        },
                    ]
                },
                'EcsParameters': {
                    'TaskDefinitionArn': 'string',
                    'TaskCount': 123
                }
            },
        ]
    )

    :type Rule: string
    :param Rule: [REQUIRED]
            The name of the rule.

    :type Targets: list
    :param Targets: [REQUIRED]
            The targets to update or add to the rule.
            (dict) --Targets are the resources to be invoked when a rule is triggered. Target types include EC2 instances, AWS Lambda functions, Amazon Kinesis streams, Amazon ECS tasks, AWS Step Functions state machines, Run Command, and built-in targets.
            Id (string) -- [REQUIRED]The ID of the target.
            Arn (string) -- [REQUIRED]The Amazon Resource Name (ARN) of the target.
            RoleArn (string) --The Amazon Resource Name (ARN) of the IAM role to be used for this target when the rule is triggered. If one rule triggers multiple targets, you can use a different IAM role for each target.
            Input (string) --Valid JSON text passed to the target. In this case, nothing from the event itself is passed to the target. You must use JSON dot notation, not bracket notation. For more information, see The JavaScript Object Notation (JSON) Data Interchange Format .
            InputPath (string) --The value of the JSONPath that is used for extracting part of the matched event when passing it to the target. You must use JSON dot notation, not bracket notation. For more information about JSON paths, see JSONPath .
            InputTransformer (dict) --Settings to enable you to provide custom input to a target based on certain event data. You can extract one or more key-value pairs from the event and then use that data to send customized input to the target.
            InputPathsMap (dict) --Map of JSON paths to be extracted from the event. These are key-value pairs, where each value is a JSON path. You must use JSON dot notation, not bracket notation.
            (string) --
            (string) --

            InputTemplate (string) -- [REQUIRED]Input template where you can use the values of the keys from InputPathsMap to customize the data sent to the target.
            KinesisParameters (dict) --The custom parameter you can use to control shard assignment, when the target is an Amazon Kinesis stream. If you do not include this parameter, the default is to use the eventId as the partition key.
            PartitionKeyPath (string) -- [REQUIRED]The JSON path to be extracted from the event and used as the partition key. For more information, see Amazon Kinesis Streams Key Concepts in the Amazon Kinesis Streams Developer Guide .
            RunCommandParameters (dict) --Parameters used when you are using the rule to invoke Amazon EC2 Run Command.
            RunCommandTargets (list) -- [REQUIRED]Currently, we support including only one RunCommandTarget block, which specifies either an array of InstanceIds or a tag.
            (dict) --Information about the EC2 instances that are to be sent the command, specified as key-value pairs. Each RunCommandTarget block can include only one key, but this key may specify multiple values.
            Key (string) -- [REQUIRED]Can be either tag: tag-key or InstanceIds .
            Values (list) -- [REQUIRED]If Key is tag: tag-key , Values is a list of tag values. If Key is InstanceIds , Values is a list of Amazon EC2 instance IDs.
            (string) --

            EcsParameters (dict) --Contains the Amazon ECS task definition and task count to be used, if the event target is an Amazon ECS task. For more information about Amazon ECS tasks, see Task Definitions in the Amazon EC2 Container Service Developer Guide .
            TaskDefinitionArn (string) -- [REQUIRED]The ARN of the task definition to use if the event target is an Amazon ECS cluster.
            TaskCount (integer) --The number of tasks to create based on the TaskDefinition . The default is one.

    :rtype: dict
    :return: {
        'FailedEntryCount': 123,
        'FailedEntries': [
            {
                'TargetId': 'string',
                'ErrorCode': 'string',
                'ErrorMessage': 'string'
            },
        ]
    }

    :returns:
    Rule (string) -- [REQUIRED]
    The name of the rule.

    Targets (list) -- [REQUIRED]
    The targets to update or add to the rule.

    (dict) --Targets are the resources to be invoked when a rule is triggered. Target types include EC2 instances, AWS Lambda functions, Amazon Kinesis streams, Amazon ECS tasks, AWS Step Functions state machines, Run Command, and built-in targets.

    Id (string) -- [REQUIRED]The ID of the target.

    Arn (string) -- [REQUIRED]The Amazon Resource Name (ARN) of the target.

    RoleArn (string) --The Amazon Resource Name (ARN) of the IAM role to be used for this target when the rule is triggered. If one rule triggers multiple targets, you can use a different IAM role for each target.

    Input (string) --Valid JSON text passed to the target. In this case, nothing from the event itself is passed to the target. You must use JSON dot notation, not bracket notation. For more information, see The JavaScript Object Notation (JSON) Data Interchange Format .

    InputPath (string) --The value of the JSONPath that is used for extracting part of the matched event when passing it to the target. You must use JSON dot notation, not bracket notation. For more information about JSON paths, see JSONPath .

    InputTransformer (dict) --Settings to enable you to provide custom input to a target based on certain event data. You can extract one or more key-value pairs from the event and then use that data to send customized input to the target.

    InputPathsMap (dict) --Map of JSON paths to be extracted from the event. These are key-value pairs, where each value is a JSON path. You must use JSON dot notation, not bracket notation.

    (string) --
    (string) --

    InputTemplate (string) -- [REQUIRED]Input template where you can use the values of the keys from InputPathsMap to customize the data sent to the target.

    KinesisParameters (dict) --The custom parameter you can use to control shard assignment, when the target is an Amazon Kinesis stream. If you do not include this parameter, the default is to use the eventId as the partition key.

    PartitionKeyPath (string) -- [REQUIRED]The JSON path to be extracted from the event and used as the partition key. For more information, see Amazon Kinesis Streams Key Concepts in the Amazon Kinesis Streams Developer Guide .

    RunCommandParameters (dict) --Parameters used when you are using the rule to invoke Amazon EC2 Run Command.

    RunCommandTargets (list) -- [REQUIRED]Currently, we support including only one RunCommandTarget block, which specifies either an array of InstanceIds or a tag.

    (dict) --Information about the EC2 instances that are to be sent the command, specified as key-value pairs. Each RunCommandTarget block can include only one key, but this key may specify multiple values.

    Key (string) -- [REQUIRED]Can be either tag: tag-key or InstanceIds .

    Values (list) -- [REQUIRED]If Key is tag: tag-key , Values is a list of tag values. If Key is InstanceIds , Values is a list of Amazon EC2 instance IDs.

    (string) --

    EcsParameters (dict) --Contains the Amazon ECS task definition and task count to be used, if the event target is an Amazon ECS task. For more information about Amazon ECS tasks, see Task Definitions in the Amazon EC2 Container Service Developer Guide .

    TaskDefinitionArn (string) -- [REQUIRED]The ARN of the task definition to use if the event target is an Amazon ECS cluster.

    TaskCount (integer) --The number of tasks to create based on the TaskDefinition . The default is one.

    """
    pass


@staticmethod
def get_ps1():
    """
        Returns the PS1, the basic shell prompt
        """
    return '$ '


def ElementWiseSum(*args, **kwargs):
    """Adds all input arguments element-wise.

    .. math::
       add\\_n(a_1, a_2, ..., a_n) = a_1 + a_2 + ... + a_n

    ``add_n`` is potentially more efficient than calling ``add`` by `n` times.

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

    - add_n(row_sparse, row_sparse, ..) = row_sparse
    - add_n(default, csr, default) = default
    - add_n(any input combinations longer than 4 (>4) with at least one default type) = default
    - otherwise, ``add_n`` falls all inputs back to default storage and generates default storage

    Defined in src/operator/tensor/elemwise_sum.cc:L155

    Parameters
    ----------
    args : NDArray[]
        Positional input arguments

    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 code_block(lines, language=''):
    """
    Mark the code segment for syntax highlighting.
    """
    return ['```' + language] + lines + ['```']


@classmethod
def from_letter(Automaton, letter, alphabet=None):
    """
        convert word into the minimal deterministic automaton that recognized word

        INPUT:

        - ``letter`` - string different from the empty word

        OUTPUT :

        automaton

        EXAMPLES::

            sage: from pysemigroup import Automaton
            sage: A = Automaton.from_letter('a')
            sage: A
            Automaton of 2 states
            sage: A.is_accepted("a")
            True
            sage: A.is_accepted("")
            False
        """
    if letter == '':
        raise ValueError('input must be non-empty word')
    initial_states = [0]
    final_states = [1]
    transitions = {(0, letter): [1]}
    if alphabet:
        return Automaton(transitions, initial_states, final_states,
            alphabet=alphabet)
    else:
        return Automaton(transitions, initial_states, final_states,
            alphabet=set([letter]))


@classmethod
def all(cls):
    """Get a dictionary of deposition types."""
    from .registry import deposit_types
    return deposit_types.mapping()


def hotspot(fileh, mutation):
    """ PTMs containing motifs in a close proximity are named hotspots (Beltrao et al. Cell 2012)"""
    with open('hotspot.txt', 'w') as hotspot:
        with open(fileh, 'rU') as f:
            for l in f:
                line = l.split()
                with open(mutation, 'r') as mu:
                    for m in mu:
                        m = m.split()
                        if len(line) > 6:
                            if m[0] == line[2] and m[1] == line[3]:
                                take = line[1] + '\t' + line[2] + '\t' + line[3
                                    ] + '\t' + line[5] + '\t' + line[6
                                    ] + '\t' + 'PTMfunc'
                                fi = take.split()
                                with open('yeastID.txt') as id:
                                    for di in id:
                                        di = di.split()
                                        if len(di) > 2 and di[2] == fi[1]:
                                            summary = open('summary.txt', 'a+')
                                            summary.write(di[0] + '\t' + di[2] +
                                                '\t' + fi[2] + '\t' + fi[3] + '\t' +
                                                'HotSpot' + '\t' + 'PTMFunc' + '\n')
                                            if take > str(0):
                                                with open('hotspot.txt', 'a') as hotspot:
                                                    hotspot.write(take + '\n')


def _prox_star(func, z, T):
    """
    Proximity operator of the convex conjugate of a function.

    Notes
    -----
    Based on the Moreau decomposition of a vector w.r.t. a convex function.

    """
    return z - T * func.prox(z / T, 1 / T)


def remove(pcoll: 'ImagePreviewCollection'):
    """Remove the specified previews collection.

    :param pcoll: Preview collection to close.
    :type pcoll: 'ImagePreviewCollection'
    """
    pass


def flush():
    """Flush the file. See Python documentation for :class:`io.IOBase` for details.
        """


def compute_ratios(df_dict, df_str, gridclimname1, gridclimname2, prefix1,
    prefix2='meanmonth', comp_dict=None):
    """
    Compute fold-difference between monthly means (e.g,. Temp) for two different gridded datasets (e.g., Liv, WRF)
    """
    if isinstance(comp_dict, type(None)):
        comp_dict = {}
    for each1 in prefix1:
        for each2 in prefix2:
            ratios = df_dict['_'.join([each2, each1, gridclimname1])
                ] / df_dict['_'.join([each2, each1, gridclimname2])]
            comp_dict['_'.join([str(each1), df_str])] = ratios
    return comp_dict


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

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

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


def drawMagnetizationVector(position, magnetization, angle, axis, color,
    SYSSIZE, ax):
    """Draw the magnetization vector of a magnet.

    Parameters
    ----------
    position : vec3
        position of the magnet
    magnetization : vec3
        magnetization vector
    angle : float
        angle of rotation
    axis : vec3
        Axis of rotation
    color : matplotlib color
        Color of the axis. No default value specified
    SYSSIZE : float
        Size of the display syste
    ax : [pyploy]
        pyplot canvas to draw on

    """
    from magpylib._lib.mathLib import angleAxisRotation
    M = angleAxisRotation(magnetization, angle, axis)
    P = position
    c = [color[0] / 2, color[1] / 2, color[2] / 2, color[3]]
    ax.quiver(P[0], P[1], P[2], M[0], M[1], M[2], normalize=True, length=
        SYSSIZE, color=c)


def printm(fo, printline, mat, LineLen=5):
    """ This is obsolete - kept as source material only.
printm(fo, A matrix, [Line length]) -> Neatly file-prints matrix
mat of size (m x n). Line length variable, default is 5. """
    m, n = mat.m, mat.n
    tmp = (
        'A matrix of dimensions (m x n), where m, n, LineLen =  %i %i %i ' %
        (m, n, LineLen))
    fo.write(tmp + '\n')
    printline(tmp)
    for i in range(m):
        fo.write('\n')
        line = ''
        for j in range(n):
            fo.write(' %12.5E ' % mat[i][j])
            line += ' %12.5E ' % mat[i][j]
            if (j + 1) % LineLen == 0 or j + 1 == n:
                fo.write('\n')
                printline(line)
                if j < n - 1:
                    line = ''
            if j == n - 1 and j + 1 > LineLen:
                fo.write('\n')
                printline(' ')
    fo.write('\n')


@classmethod
def scopes(cls):
    """
        Return a list of valid/understood class scopes.
        Why do we need this? I believe it is not used anywhere.
        """
    return [cls.NONE, cls.ONE, cls.ALL]


def tokenize_line(line):
    """
    Tokenize a line:
    * split tokens on whitespace
    * treat quoted strings as a single token
    * drop comments
    * handle escaped spaces and comment delimiters
    """
    ret = []
    escape = False
    quote = False
    tokbuf = ''
    ll = list(line)
    while len(ll) > 0:
        c = ll.pop(0)
        if c.isspace():
            if not quote and not escape:
                if len(tokbuf) > 0:
                    ret.append(tokbuf)
                tokbuf = ''
            elif quote:
                tokbuf += c
            elif escape:
                tokbuf += c
                escape = False
            else:
                tokbuf = ''
            continue
        if c == '\\':
            escape = True
            continue
        elif c == '"':
            if not escape:
                if quote:
                    ret.append(tokbuf)
                    tokbuf = ''
                    quote = False
                    continue
                else:
                    quote = True
                    continue
        elif c == ';':
            if not escape:
                ret.append(tokbuf)
                tokbuf = ''
                break
        tokbuf += c
        escape = False
    if len(tokbuf.strip(' ').strip('\n')) > 0:
        ret.append(tokbuf)
    return ret


def delta_Omega(X):
    """
        Compute delta_Omega(X[:, j]) for each X[:, j].
        delta_Omega(x) = sup_{y >= 0} y^T x - Omega(y).

        Parameters
        ----------
        X: array, shape = len(a) x len(b)
            Input array.

        Returns
        -------
        v: array, len(b)
            Values: v[j] = delta_Omega(X[:, j])
        G: array, len(a) x len(b)
            Gradients: G[:, j] = nabla delta_Omega(X[:, j])
        """
    raise NotImplementedError


def to_gm_timestamp(timestamp):
    """Convert timestamp in seconds to timestamp in microseconds."""
    return int(timestamp * 1000000)


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

        :param TfaChangePolicyDetails val:
        :rtype: EventDetails
        """
    return cls('tfa_change_policy_details', val)


def source_match(state, source):
    """Check if the state matches the provided source."""
    return state and state.attributes.get('source') == source


def geth_to_parity(genesis):
    """Converts a Geth style genesis to Parity style"""
    ret = {'name': 'etheno', 'engine': {'instantSeal': None}, 'genesis': {
        'seal': {'generic': '0x0'}, 'difficulty': '0x%s' % genesis[
        'difficulty'], 'gasLimit': '0x%s' % genesis['gasLimit'], 'author':
        list(genesis['alloc'])[-1]}, 'params': {'networkID': '0x%x' %
        genesis['config']['chainId'], 'maximumExtraDataSize': '0x20',
        'minGasLimit': '0x%s' % genesis['gasLimit'], 'gasLimitBoundDivisor':
        '1', 'eip150Transition': '0x%x' % genesis['config']['eip150Block'],
        'eip160Transition': '0x0', 'eip161abcTransition': '0x0',
        'eip161dTransition': '0x0', 'eip155Transition': '0x%x' % genesis[
        'config']['eip155Block'], 'eip98Transition': '0x7fffffffffffff',
        'maxCodeSize': 24576, 'maxCodeSizeTransition': '0x0',
        'eip140Transition': '0x0', 'eip211Transition': '0x0',
        'eip214Transition': '0x0', 'eip658Transition': '0x0',
        'wasmActivationTransition': '0x0'}, 'accounts': dict(genesis['alloc'])}
    if 'constantinopleBlock' in genesis['config']:
        block = '0x%x' % genesis['config']['constantinopleBlock']
        ret['params']['eip145Transition'] = block
        ret['params']['eip1014Transition'] = block
        ret['params']['eip1052Transition'] = block
    return ret


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

        :param MemberDeleteProfilePhotoDetails val:
        :rtype: EventDetails
        """
    return cls('member_delete_profile_photo_details', val)


def grouping_data(processed_data):
    """
	A function to group all values for each 'animal_id'
	Input is 'processed_data' which is processed Pandas DataFrame
	Returns a dictionary where-
	key is animal_id, value in Pandas DataFrame for that 'animal_id'
	"""
    data_animal_id = processed_data.groupby('animal_id')
    data_animal_id_groups = {}
    for animal_id in data_animal_id.groups.keys():
        data_animal_id_groups[animal_id] = data_animal_id.get_group(animal_id)
    for animal_id in data_animal_id_groups.keys():
        data_animal_id_groups[animal_id].reset_index(drop=True, inplace=True)
    for aid in data_animal_id_groups.keys():
        data = [(0) for x in range(data_animal_id_groups[aid].shape[0])]
        data_animal_id_groups[aid] = data_animal_id_groups[aid].assign(distance
            =data)
        data_animal_id_groups[aid] = data_animal_id_groups[aid].assign(
            average_speed=data)
        data_animal_id_groups[aid] = data_animal_id_groups[aid].assign(
            average_acceleration=data)
        data_animal_id_groups[aid] = data_animal_id_groups[aid].assign(
            direction=data)
    return data_animal_id_groups


def transform_apply(location: bool=False, rotation: bool=False, scale: bool
    =False):
    """Apply the object’s transformation to its data

    :param location: Location
    :type location: bool
    :param rotation: Rotation
    :type rotation: bool
    :param scale: Scale
    :type scale: bool
    """
    pass


def ctc_batch_cost(y_true, y_pred, input_length, label_length):
    """Runs CTC loss algorithm on each batch element.

    # Arguments
        y_true: tensor `(samples, max_string_length)`
            containing the truth labels.
        y_pred: tensor `(samples, time_steps, num_categories)`
            containing the prediction, or output of the softmax.
        input_length: tensor `(samples, 1)` containing the sequence length for
            each batch item in `y_pred`.
        label_length: tensor `(samples, 1)` containing the sequence length for
            each batch item in `y_true`.

    # Returns
        Tensor with shape (samples,1) containing the
            CTC loss of each element.
    """
    raise NotImplementedError('MXNet Backend: CTC is not supported yet.')


@classmethod
def copy(cls, conn, **where):
    """Copy data from one table to another while filtering data at the same time

        Parameters
        ----------
        conn: sqlite3 DB connection.  It must have a second database
            attached as "other".
        **where : keyword arguments
            specifying (start_ut and end_ut for filtering, see the copy_where clause in the subclasses)
        """
    cur = conn.cursor()
    if where and cls.copy_where:
        copy_where = cls.copy_where.format(**where)
    else:
        copy_where = ''
    cur.execute('INSERT INTO %s SELECT * FROM source.%s %s' % (cls.table,
        cls.table, copy_where))


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

        :param LegalHoldsReportAHoldType val:
        :rtype: EventType
        """
    return cls('legal_holds_report_a_hold', val)


def base36decode(number):
    """
    Decode base36 endcoded positive integer.
    """
    return int(number, 36)


def hide(unselected: bool=False):
    """Hide selected particles

    :param unselected: Unselected, Hide unselected rather than selected
    :type unselected: bool
    """
    pass


def _analyze_unconfigured_modules(status, modules):
    """
    Analyze list of all processes files and find any that do not belong to known modules.
    """
    for mname in sorted(status['processes'].keys()):
        if mname in modules:
            continue
        for pid in sorted(status['processes'][mname].keys()):
            status['messages']['info'].append((
                "Unknown process '{}' with PID '{}'".format(status[
                'processes'][mname][pid]['exec'], pid), 'pidfile', pid))


@classmethod
def difference(cls, col1, col2):
    """
        Разница (расстояние) между двумя колонками

        :param col1: строковое представление первой колонки
        :type col1: str
        :param col2: строковое представление второй колонки
        :type col2: str
        """
    return cls.column_to_number(col1) - cls.column_to_number(col2)


def state_move_up():
    """Move boid state up in the list

    """
    pass


def print_current_session_details(session):
    """
    Prints information regarding the selected account for a given CLI session.
    :param CliSession session: Current CLI session.
    """
    print('\nThe following account was chosen: {}\n'.format(session.to_str()))


def get_float_attr(node, attribute):
    """Cast an element attribute to a float or return None if not present"""
    attr = node.get(attribute)
    return None if attr is None else float(attr)


@classmethod
def search(cls, query=None, filters=None, ordering=None):
    """performs a query using the model's `.search_objects` manager

        :param query: terms used to perform query
        :type query: str

        :param filters: key-value pairs used to build filters to limit search results
        :type filters: dict

        :param ordering: field names used to order the results
        :type ordering: list

        :return: elasticsearch search results mapped to django model proxies
        :rtype: django.db.models.QuerySet
        """
    qs = cls.search_objects.search()
    if query:
        qs = qs.query('match', _all=query)
    if filters:
        built_filters = cls._build_filters(filters)
        qs = qs.filter(built_filters)
    if ordering:
        ordering = cls._build_ordering(ordering)
        qs = qs.sort(*ordering)
    return qs


def matches(event, token_values):
    """See if the token matches the revocation event.

    A brute force approach to checking.
    Compare each attribute from the event with the corresponding
    value from the token.  If the event does not have a value for
    the attribute, a match is still possible.  If the event has a
    value for the attribute, and it does not match the token, no match
    is possible, so skip the remaining checks.

    :param event: a RevokeEvent instance
    :param token_values: dictionary with set of values taken from the
                         token
    :returns: True if the token matches the revocation event, indicating the
              token has been revoked
    """
    if event.domain_id is not None and event.domain_id not in (token_values
        ['identity_domain_id'], token_values['assignment_domain_id']):
        return False
    if event.domain_scope_id is not None and event.domain_scope_id not in (
        token_values['assignment_domain_id'],):
        return False
    if event.expires_at is not None and event.expires_at not in (token_values
        ['expires_at'],):
        return False
    if event.trust_id is not None and event.trust_id not in (token_values[
        'trust_id'],):
        return False
    if event.consumer_id is not None and event.consumer_id not in (token_values
        ['consumer_id'],):
        return False
    if event.audit_chain_id is not None and event.audit_chain_id not in (
        token_values['audit_chain_id'],):
        return False
    if event.role_id is not None and event.role_id not in token_values['roles'
        ]:
        return False
    return True


def get_kana(word):
    """
    Returns the reading of `word` as katakana.

    Parameters
    ----------
    word : str
        The alphabetical string you want to get the katakana reading.
        The case of string is ignored.

    Returns
    ----------
    reading : str
        The reading of `word`.
        `None` if reading is not found.
    """
    from .data import data
    try:
        return data[word]
    except KeyError:
        return None


def _extract_model(headers):
    """
    Return an array containing the column names, extracted from the headers
    """
    return headers['Model']


def test_lzma(archive, compression, cmd, verbosity, interactive):
    """Test an LZMA archive."""
    cmdlist = [cmd, '--format=lzma']
    if verbosity > 1:
        cmdlist.append('-v')
    cmdlist.extend(['--test', archive])
    return cmdlist


def __new__(cls, obj, *args, **kwargs):
    """
        creates an proxy instance referencing `obj`. (obj, *args, **kwargs) are
        passed to this class' __init__, so deriving classes can define an
        __init__ method of their own.
        note: _class_proxy_cache is unique per deriving class (each deriving
        class must hold its own cache)
        """
    try:
        cache = cls.__dict__['_class_proxy_cache']
    except KeyError:
        cls._class_proxy_cache = cache = {}
    try:
        theclass = cache[obj.__class__]
    except KeyError:
        cache[obj.__class__] = theclass = cls._create_class_proxy(obj.__class__
            )
    ins = object.__new__(theclass)
    theclass.__init__(ins, obj, *args, **kwargs)
    return ins


@staticmethod
def concat_url(endpoint, url):
    """Concatenate endpoint and final URL.

        E.g., "http://keystone/v2.0/" and "/tokens" are concatenated to
        "http://keystone/v2.0/tokens".

        :param endpoint: the base URL
        :param url: the final URL
        """
    return '%s/%s' % (endpoint.rstrip('/'), url.strip('/'))


def speccen_header(header, lon=None, lat=None):
    """
    Turn a cube header into a spectrum header, retaining RA/Dec vals where possible
    (speccen is like flatten; spec-ify would be better but, specify?  nah)

    Assumes 3rd axis is velocity
    """
    newheader = header.copy()
    newheader.set('CRVAL1', header.get('CRVAL3'))
    newheader.set('CRPIX1', header.get('CRPIX3'))
    if 'CD1_1' in header:
        newheader.rename_keyword('CD1_1', 'OLDCD1_1')
    elif 'CDELT1' in header:
        newheader.rename_keyword('CDELT1', 'OLDCDEL1')
    if 'CD3_3' in header:
        newheader.set('CDELT1', header.get('CD3_3'))
    elif 'CDELT3' in header:
        newheader.set('CDELT1', header.get('CDELT3'))
    newheader.set('CTYPE1', 'VRAD')
    if header.get('CUNIT3'):
        newheader.set('CUNIT1', header.get('CUNIT3'))
    else:
        print('Assuming CUNIT3 is km/s in speccen_header')
        newheader.set('CUNIT1', 'km/s')
    newheader.set('CRPIX2', 1)
    newheader.set('CTYPE2', 'RA---TAN')
    newheader.set('CRPIX3', 1)
    newheader.set('CTYPE3', 'DEC--TAN')
    if lon is not None:
        newheader.set('CRVAL2', lon)
    if lat is not None:
        newheader.set('CRVAL3', lat)
    if 'CD2_2' in header:
        newheader.rename_keyword('CD2_2', 'OLDCD2_2')
    if 'CD3_3' in header:
        newheader.rename_keyword('CD3_3', 'OLDCD3_3')
    return newheader


def start_rds_backup(db, s3_bucket, s3_backup_object_path, cursor):
    """
    Trigger dbo.rds_backup_database procedure and return its task id.
    """
    cursor.execute(
        """
        EXEC msdb.dbo.rds_backup_database
            @source_db_name={},
            @s3_arn_to_backup_to='arn:aws:s3:::{}/{}',
            @overwrite_S3_backup_file=1,
            @type='full';
    """
        .format(db, s3_bucket, s3_backup_object_path))
    return cursor.fetchall()[0][0]


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

        :param str val:
        :rtype: LookupError
        """
    return cls('malformed_path', val)


def _get_auxmodel_id(line: str, uline: str) ->int:
    """
    parses the superelement header::

        BEGIN AUXMODEL=2
        BEGIN BULK AUXMODEL=2
        BEGIN BULK AUXMODEL = 2

    """
    sline = uline.split('=')
    try:
        auxmodel_id = int(sline[1])
    except (IndexError, ValueError):
        msg = 'expected "BEGIN AUXMODEL=1"\nline = %s' % line
        raise SyntaxError(msg)
    if auxmodel_id < 0:
        raise SyntaxError('auxmodel_id=%i must be greater than 0; line=%s' %
            (auxmodel_id, line))
    return auxmodel_id


def patch_lines(lines, patches):
    """Applies patches to lines.  Updates lines in place."""
    for first, last, args in patches:
        lines[first:last] = args


def copy_lookahead(from_parser, to):
    """
    Copy lookahead mode from 'from_parser' to 'to' and return the modified
    parser.
    """
    try:
        to.lookahead = from_parser.lookahead
    except AttributeError:
        pass
    return to


def glGetAttachedShaders(program: int, maxCount: int, count: int, shaders: int
    ):
    """Returns the handles of the shader objects attached to a program object.

    :param program: Specifies the program object to be queried.
    :type program: int
    :param maxCount: Specifies the size of the array for storing the returned object names.
    :type maxCount: int
    :param count: Returns the number of names actually returned in objects.
    :type count: int
    :param shaders: Specifies an array that is used to return the names of attached shader objects.
    :type shaders: int
    """
    pass


def formula_2017_01_01(foyer_fiscal, period, parameters):
    """
        Investissements OUTRE-MER dans le secteur du logement et autres secteurs d’activité
        2017
        """
    fhod = foyer_fiscal('fhod', period)
    fhoe = foyer_fiscal('fhoe', period)
    fhof = foyer_fiscal('fhof', period)
    fhog = foyer_fiscal('fhog', period)
    fhox = foyer_fiscal('fhox', period)
    fhoy = foyer_fiscal('fhoy', period)
    fhoz = foyer_fiscal('fhoz', period)
    fhqb = foyer_fiscal('fhqb', period)
    fhqc = foyer_fiscal('fhqc', period)
    fhqd = foyer_fiscal('fhqd', period)
    fhql = foyer_fiscal('fhql', period)
    fhqm = foyer_fiscal('fhqm', period)
    fhqt = foyer_fiscal('fhqt', period)
    fhoa = foyer_fiscal('fhoa', period)
    fhob = foyer_fiscal('fhob', period)
    fhoc = foyer_fiscal('fhoc', period)
    fhoh = foyer_fiscal('fhoh', period)
    fhoi = foyer_fiscal('fhoi', period)
    fhoj = foyer_fiscal('fhoj', period)
    fhok = foyer_fiscal('fhok', period)
    fhol = foyer_fiscal('fhol', period)
    fhom = foyer_fiscal('fhom', period)
    fhon = foyer_fiscal('fhon', period)
    fhoo = foyer_fiscal('fhoo', period)
    fhop = foyer_fiscal('fhop', period)
    fhoq = foyer_fiscal('fhoq', period)
    fhor = foyer_fiscal('fhor', period)
    fhos = foyer_fiscal('fhos', period)
    fhot = foyer_fiscal('fhot', period)
    fhou = foyer_fiscal('fhou', period)
    fhov = foyer_fiscal('fhov', period)
    fhow = foyer_fiscal('fhow', period)
    fhua = foyer_fiscal('fhua', period)
    fhub = foyer_fiscal('fhub', period)
    fhuc = foyer_fiscal('fhuc', period)
    fhud = foyer_fiscal('fhud', period)
    fhue = foyer_fiscal('fhue', period)
    fhuf = foyer_fiscal('fhuf', period)
    fhug = foyer_fiscal('fhug', period)
    fhuh = foyer_fiscal('fhuh', period)
    fhui = foyer_fiscal('fhui', period)
    fhuj = foyer_fiscal('fhuj', period)
    fhuk = foyer_fiscal('fhuk', period)
    fhul = foyer_fiscal('fhul', period)
    fhum = foyer_fiscal('fhum', period)
    fhun = foyer_fiscal('fhun', period)
    fhuo = foyer_fiscal('fhuo', period)
    fhup = foyer_fiscal('fhup', period)
    fhuq = foyer_fiscal('fhuq', period)
    fhur = foyer_fiscal('fhur', period)
    fhus = foyer_fiscal('fhus', period)
    fhut = foyer_fiscal('fhut', period)
    fhuu = foyer_fiscal('fhuu', period)
    fhva = foyer_fiscal('fhva', period)
    fhvb = foyer_fiscal('fhvb', period)
    fhvc = foyer_fiscal('fhvc', period)
    fhvd = foyer_fiscal('fhvd', period)
    fhve = foyer_fiscal('fhve', period)
    fhvf = foyer_fiscal('fhvf', period)
    fhvg = foyer_fiscal('fhvg', period)
    reduction_invest_2009 = fhqc + fhql
    reduction_invest_2010 = fhqd + fhqm + fhqt
    reduction_invest_2011 = fhoa + fhob + fhoc + fhoh + fhoi + fhoj + fhok
    reduction_invest_2012 = (fhol + fhom + fhon + fhoo + fhop + fhoq + fhor +
        fhos + fhot + fhou + fhov + fhow)
    reduction_invest_2013 = fhod + fhoe + fhof + fhog + fhox + fhoy + fhoz
    reduction_invest_2014 = fhua + fhub + fhuc + fhud + fhue + fhuf + fhug
    reduction_invest_2015 = fhuh + fhui + fhuj + fhuk + fhul + fhum + fhun
    reduction_invest_2016 = fhuo + fhup + fhuq + fhur + fhus + fhut + fhuu
    reduction_invest_2017 = fhva + fhvb + fhvc + fhvd + fhve + fhvf + fhvg
    reduction_invest_2018 = fhqb
    return (reduction_invest_2009 + reduction_invest_2010 +
        reduction_invest_2011 + reduction_invest_2012 +
        reduction_invest_2013 + reduction_invest_2014 +
        reduction_invest_2015 + reduction_invest_2016 +
        reduction_invest_2017 + reduction_invest_2018)


def bytes2human(num):
    """
    Convert a size into a human readable format.
    """
    symbols = 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'
    prefix = {}
    nume = ''
    if num < 0:
        num = num * -1
        nume = '-'
    for pos, sym in enumerate(symbols):
        prefix[sym] = 1 << (pos + 1) * 10
    for sym in reversed(symbols):
        if num >= prefix[sym]:
            value = '%.2f' % float(float(num) / float(prefix[sym]))
            return '%s%s%s' % (nume, value, sym)
    return '%s%.2fB' % (nume, num)


def graph_delete_knot():
    """Delete curve knots

    """
    pass


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


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


def localZone(ltm=None):
    """Returns the time zone on the given date.  The time zone
        can change according to daylight savings."""


def truncate_string_from_end(string: str, max_len: int) ->str:
    """If the string len is below the max_len, the function returns the same string.
	If the string is above the max len, the function returns only the last max_len characters plus '...' at the beginning."""
    if len(string) <= max_len:
        return string
    return f'Last {max_len} chars: "...{string[-max_len:]}"'


def delete_object():
    """Delete an object from TimeSync"""
    return [{'status': 200}]


def _exec_first_ready_in_order(ready_tasks, ordered_tasks, ch_ops,
    _exec_first_ready=_exec_first_ready):
    """Execute the first ready task from ordered_task.

    Returns a tuple of (execution_output, retry_ch_opts), one element will be
    None.
    """
    next_ch_opts = []
    for i, task in enumerate(ordered_tasks):
        if task in ready_tasks:
            ready = ch_ops[i]
            out = _exec_first_ready((ready,))
            if out:
                return out, None
        else:
            next_ch_opts.append(ch_ops[i])
    return None, next_ch_opts


def output_results(file_type, plotter, result, rawdata):
    """Plot the results.

    Plotting might here refer to both figures and text.

    Parameters
    ----------
    file_type : string
        This determines what we are going to plot.
    plotter : object like :py:class:`.Plotter`
        This is the object that handles the plotting.
    result : list of lists or dicts
        This contains the results from a specific analysis.
    rawdata : list of floats, lists or objects
        The raw data with analysis results.

    Returns
    -------
    out : list of strings
        These are the files that the plotter created.

    """
    if file_type == 'cross':
        return plotter.output_flux(result)
    if file_type == 'order':
        return plotter.output_orderp(result, rawdata)
    if file_type == 'energy':
        return plotter.output_energy(result, rawdata)
    if file_type == 'pathensemble':
        return plotter.output_path(result, rawdata)
    return None


@classmethod
def update(cls, id, name, size, quantity, password, sshkey, upgrade,
    console, snapshot_profile, reset_mysql_password, background):
    """Update a PaaS instance."""
    if not background and not cls.intty():
        background = True
    paas_params = {}
    if name:
        paas_params['name'] = name
    if size:
        paas_params['size'] = size
    if quantity:
        paas_params['quantity'] = quantity
    if password:
        paas_params['password'] = password
    paas_params.update(cls.convert_sshkey(sshkey))
    if upgrade:
        paas_params['upgrade'] = upgrade
    if console:
        paas_params['console'] = console
    if snapshot_profile is not None:
        paas_params['snapshot_profile'] = snapshot_profile
    if reset_mysql_password:
        paas_params['reset_mysql_password'] = reset_mysql_password
    result = cls.call('paas.update', cls.usable_id(id), paas_params)
    if background:
        return result
    cls.echo('Updating your PaaS instance.')
    cls.display_progress(result)


@classmethod
def darker_grey(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0x546e7a``."""
    return cls(5533306)


@classmethod
def instances(cls):
    """Return a list of available data instances for the player

        A data instance can be historical data of a particular year/team or it
        can be from a prediction system.

        :return: Names of the available sources
        :rtype: list(str)
        """
    return cls.instance_map.keys()


def safe_str(s, known_words=None):
    """return ``s`` as `str` safe to `eval` or raise an exception.

    Strings in the `dict` `known_words` are replaced by their values
    surrounded with a space, which the caller considers safe to evaluate
    with `eval` afterwards.

    Known issues:

    >>> try: from cma.purecma import safe_str
    ... except ImportError: from purecma import safe_str
    >>> safe_str('int(p)', {'int': 'int', 'p': 3.1})  # fine
    ' int ( 3.1 )'
    >>> safe_str('int(n)', {'int': 'int', 'n': 3.1})  # unexpected
    ' i 3.1 t ( 3.1 )'

    """
    safe_chars = ' 0123456789.,+-*()[]e'
    if s != str(s):
        return str(s)
    if not known_words:
        known_words = {}
    stest = s[:]
    sret = s[:]
    for word in sorted(known_words.keys(), key=len, reverse=True):
        stest = stest.replace(word, '  ')
        sret = sret.replace(word, ' %s ' % known_words[word])
    for c in stest:
        if c not in safe_chars:
            raise ValueError(
                '"%s" is not a safe string (known words are %s)' % (s, str(
                known_words)))
    return sret


def _noop_check_fix() ->None:
    """A lambda is not pickleable, this must be a module-level function"""


@classmethod
def get_scriptPubKey_type(cls) ->str:
    """return scriptPubKey type for a given concrete class.
        For example, when called on P2SHCoinAddress, will return 'scripthash'.

        calling this method on generic address class is an error."""
    spk_type = getattr(cls, '_scriptpubkey_type', None)
    if not spk_type:
        raise TypeError('scriptPubKey type is not available for {}'.format(
            cls.__name__))
    return cls._scriptpubkey_type


def _get_nb_bytes_from_file(file_path):
    """ return the number of bytes of a file """
    with open(file_path, 'rb') as f:
        return len(f.read())


def stripBranchLen(tree):
    """Remove branch lengths from tree. Modifies in place."""
    for n in (tree.get_nonterminals() + tree.get_terminals()):
        del n.branch_length
    return tree


def get_location():
    """Returns location
        """


def get_driver_for_ext(file_ext: str) ->str:
    """
    Get the driver to use for this file extension.
    """
    file_ext_lower = file_ext.lower()
    if file_ext_lower == '.shp':
        return 'ESRI Shapefile'
    elif file_ext_lower == '.geojson':
        return 'GeoJSON'
    elif file_ext_lower == '.gpkg':
        return 'GPKG'
    else:
        raise Exception(f'Not implemented for extension {file_ext_lower}')


def has_token(username):
    """ Whether the provided user already received a token
        """


def migrSteppingStoneRates(r, n, circular=False):
    """migration rate matrix for circular stepping stone model (X=1-m)

::

           X   m/2               m/2
           m/2 X   m/2           0
           0   m/2 x   m/2 ......0
           ...
           m/2 0 ....       m/2  X

or non-circular

::

           X   m/2               m/2
           m/2 X   m/2           0
           0   m/2 X   m/2 ......0
           ...
           ...              m   X

    This function returns [[1]] when there is only one subpopulation.
    """
    if n < 2:
        return [[1]]
    elif n == 2:
        return [[1 - r, r], [r, 1 - r]]
    m = []
    for i in range(0, n):
        m.append([0] * n)
        m[i][i] = 1 - r
        m[i][(i + 1) % n] = r / 2.0
        m[i][(i + n - 1) % n] = r / 2.0
    if not circular:
        m[0][1] = r
        m[0][-1] = 0
        m[n - 1][0] = 0
        m[n - 1][n - 2] = r
    return m


@classmethod
def getProtocolTag(cls, isInstalled):
    """ Return the proper tag depending if the protocol is installed or not.
        """
    return cls.TAG_PROTOCOL if isInstalled else cls.TAG_PROTOCOL_DISABLED


def psi_Na_HSO4_SO4_HMW84(T, P):
    """c-a-a': sodium bisulfate sulfate [HMW84]."""
    psi = -0.0094
    valid = T == 298.15
    return psi, valid


@classmethod
def generate_filename(cls, modifier: str=None) ->str:
    """
        Generates the configuration filename with an optional modification string.

        :param modifier: String to modify default filename with.
        :return: The generated filepath string.
        """
    name = cls._NAME.lower()
    if modifier:
        name += f'-{modifier}'
    filename = f'{name}.{cls._CONFIG_FILE_EXTENSION.lower()}'
    return filename


def vibration_decode(value):
    """
    Special decoder for XIAOMI Vibration sensor
    """
    if value == '' or value is None:
        return value
    events = {(1): 'touched', (2): 'tilt', (3): 'drop'}
    if value in events:
        return events[value]
    return value


def getParentMessage(message_id):
    """Returns a proxy for the parent of the givern message_id"""


def macs_linear(module, input, output):
    """MACs estimation for `torch.nn.Linear`"""
    mm_mac = input.shape[0] * output.shape[1] * input.shape[1]
    return mm_mac


def __call__(context, request, query=None):
    """
        The context provides a location that the vocabulary can make use of.
        The request provides a user that the vocabulary can personalize for.
        The query provides a filter the user has input so far.
        """


@classmethod
def load_all_options(cls, inst):
    """
        Try reading values from all methods on *inst* instance which
        are decorated by :class:`option` decorator. Reading will cause
        validation of theese values and cache them.
        """
    for attrname in cls.get_option_names(inst):
        getattr(inst, attrname)


def rip_move_fill(MESH_OT_rip=None, TRANSFORM_OT_translate=None):
    """Rip-fill polygons and move the result

    :param MESH_OT_rip: Rip, Disconnect vertex or edges from connected geometry
    :param TRANSFORM_OT_translate: Translate, Translate (move) selected items
    """
    pass


def boolean_mask(input, mask):
    """Selects elements in x according to the given mask from the first
    dimension.

    Parameters
    ----------
    input : Tensor
        The input tensor
    mask : Boolean Tensor
        The mask

    Returns
    -------
    Tensor
        The result
    """
    pass


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 get_public_version_publication_datetime():
    """Get the publication datetime of the public version.
        """


def p_entry(p):
    """
    entry : key value SEMICOLON
          | key value_list SEMICOLON
          | key block
          | key block SEMICOLON
    """
    p[0] = {p[1]: p[2]}


def get_arg(instr, var):
    """Returns the bracketed argument that immediately follows the first
        occurance of the 'var' string, along with the entire expression
        for easy replace

        example:
        >>> instr = "some text $var['user'] more text"
        >>> get_arg(instr,'$var')
        ("$var['user']", 'user')
    """
    s = len(var) + 1
    i = instr.find(var + '[')
    if i != -1:
        o = instr.find(']', i + s)
        if o != -1:
            arg = instr[i + s:o].strip('"\'')
            exp = instr[i:o + 1]
            return exp, arg
        else:
            return '', ''
    else:
        return '', ''


def no_return(qry):
    """
    Query logic to capture queries that have no return
    other than successfull or not"""
    return ('CREATE TABLE' in qry.upper()) | ('SELECT' not in qry.upper()) & (
        'SHOW' not in qry.upper())


def _substitute_macros(line, macros):
    """
    Substitute macros by their content.

    A macro starts with a '$' and ends with one amongst ' ${}\\n\\t"'.

    Parameters
    ----------
    line: str
        The line to fix.
    macros: dict[str, str]
        Keys are macro names, values are the replacement content.

    Returns
    -------
    str
    """
    start = None
    while True:
        start = line.find('$', start)
        if start < 0:
            break
        for end, char in enumerate(line[start + 1:], start=start + 1):
            if char in ' \t\n{}$"':
                break
        else:
            end += 1
        macro_name = line[start + 1:end]
        macro_value = macros[macro_name]
        line = line[:start] + macro_value + line[end:]
        end = start + len(macro_value)
    return line


def to_dict_old(inst):
    """
    Converts a SQLAlchemy model instance in a dictionary
    """
    convert = dict()
    my_dict = dict()
    for column in inst.__class__.__table__.columns:
        value = getattr(inst, column.name)
        if column.type in convert.keys():
            try:
                my_dict[column.name] = convert[column.type](value)
            except:
                my_dict[column.name] = 'Error:  Failed to covert using ', str(
                    convert[column.type])
        else:
            my_dict[column.name] = value
    return my_dict


def call(f, *args):
    """Returns the result of calling its first argument with the remaining
arguments. This is occasionally useful as a converging function for
R.converge: the first branch can produce a function while the
remaining branches produce values to be passed to that function as its
arguments"""
    if len(args) > 1:
        return f(*args)
    return lambda *args: f(*args)


def reindex(obj, attributes=None):
    """ queue a reindex operation for the given object and attributes """


@classmethod
def less_or_equal_constraint(cls, variables, upperbound):
    """Clauses encoding a "less than or equal to" constraint

        E.g. X1 + X2 + X3 + X4 <= 2

        (~X1 v ~X2 v ~X3)
        (~X1 v ~X2 v ~X4)
        (~X1 v ~X3 v ~X4)
        (~X2 v ~X3 v ~X4)

        Parameters
        ----------
        variables : list of variables
           variables in the constraint
        upperbound: int
           upper bound of the constraint

        Returns
        -------
            a list of clauses

        Examples
        --------
        >>> list(CNF.less_than_constraint(['a','b','c'],3)) == list(CNF.less_or_equal_constraint(['a','b','c'],2))
        True
        >>> list(CNF.less_or_equal_constraint(['a','b','c'],1))
        [[(False, 'a'), (False, 'b')], [(False, 'a'), (False, 'c')], [(False, 'b'), (False, 'c')]]
        >>> list(CNF.less_or_equal_constraint(['a','b'],0))
        [[(False, 'a')], [(False, 'b')]]
        >>> list(CNF.less_or_equal_constraint(['a','b','c'],-1))
        [[]]
        >>> list(CNF.less_or_equal_constraint(['a','b','c'],10))
        []
        """
    return cls._inequality_constraint_builder(variables, upperbound + 1,
        greater=False)


def nedc_gears_domain(cycle_type, gear_box_type, *args):
    """
    Returns if the cycle is NEDC and the gearbox is manual.

    :param cycle_type:
        Cycle type (WLTP or NEDC).
    :type cycle_type: str

    :param gear_box_type:
        Gear box type (manual or automatic or cvt).
    :type gear_box_type: str

    :return:
        If the cycle is NEDC and the gearbox is manual.
    :rtype: bool
    """
    return cycle_type == 'NEDC' and gear_box_type == 'manual'


def has_qt():
    """
    Returns True if PyQt5 is installed.
    """
    try:
        import PyQt5
        return True
    except ImportError:
        return False


def calculate_density_after_time(densities, time_0, time_explosion):
    """
    scale the density from an initial time of the model to the time of the explosion by ^-3

    Parameters:
    -----------

    densities: ~astropy.units.Quantity
        densities

    time_0: ~astropy.units.Quantity
        time of the model

    time_explosion: ~astropy.units.Quantity
        time to be scaled to

    Returns:
    --------

    scaled_density
    """
    return densities * (time_explosion / time_0) ** -3


@staticmethod
def mandatory_attrs():
    """Retruns a list of mandatory attributes.

        Mandatory attributes can't be removed from the document. This
        method should be overwritten by derived class.

        """
    return []


def to_lower(ctx, param, value):
    """Click callback, converts values to lowercase."""
    return value.lower()


def batches(l, n):
    """Yield successive n-sized batches from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]