def degree_histogram(G):
    """Return a list of the frequency of each degree value.

    Parameters
    ----------
    G : Networkx graph
       A graph

    Returns
    -------
    hist : list
       A list of frequencies of degrees.
       The degree values are the index in the list.

    Notes
    -----
    Note: the bins are width one, hence len(list) can be large
    (Order(number_of_edges))
    """
    degseq = list(G.degree().values())
    dmax = max(degseq) + 1
    freq = [(0) for d in range(dmax)]
    for d in degseq:
        freq[d] += 1
    return freq


@staticmethod
def get_output_node_names(graph_def):
    """Get output node names from GraphDef.

    Args:
      graph_def: GraphDef object.

    Returns:
      List of output node names.
    """
    input_names, output_names = set(), set()
    for node in graph_def.node:
        output_names.add(node.name)
        input_names.update(set(node.input))
    return list(output_names - input_names)


def find_uts_hlines(ndvar):
    """Find horizontal lines for uts plots (based on contours)

    Parameters
    ----------
    ndvar : NDVar
        Data to be plotted.

    Returns
    -------
    h_lines : iterator
        Iterator over (y, kwa) tuples.
    """
    contours = ndvar.info.get('contours', None)
    if contours:
        for level in sorted(contours):
            args = contours[level]
            if isinstance(args, dict):
                yield level, args.copy()
            else:
                yield level, {'color': args}


def describe_loa(connectionId=None, providerName=None, loaContentType=None):
    """
    Returns the LOA-CFA for a connection, interconnect, or link aggregation group (LAG).
    The Letter of Authorization - Connecting Facility Assignment (LOA-CFA) is a document that is used when establishing your cross connect to AWS at the colocation facility. For more information, see Requesting Cross Connects at AWS Direct Connect Locations in the AWS Direct Connect user guide.
    See also: AWS API Documentation

    :example: response = client.describe_loa(
        connectionId='string',
        providerName='string',
        loaContentType='application/pdf'
    )

    :type connectionId: string
    :param connectionId: [REQUIRED]
            The ID of a connection, LAG, or interconnect for which to get the LOA-CFA information.
            Example: dxcon-abc123 or dxlag-abc123
            Default: None

    :type providerName: string
    :param providerName: The name of the service provider who establishes connectivity on your behalf. If you supply this parameter, the LOA-CFA lists the provider name alongside your company name as the requester of the cross connect.
            Default: None

    :type loaContentType: string
    :param loaContentType: A standard media type indicating the content type of the LOA-CFA document. Currently, the only supported value is 'application/pdf'.
            Default: application/pdf

    :rtype: dict
    :return: {
        'loaContent': b'bytes',
        'loaContentType': 'application/pdf'
    }

    """
    pass


def stencil_fit_image_aspect(use_repeat: bool=True, use_scale: bool=True,
    mask: bool=False):
    """When using an image texture, adjust the stencil size to fit the image aspect ratio

    :param use_repeat: Use Repeat, Use repeat mapping values
    :type use_repeat: bool
    :param use_scale: Use Scale, Use texture scale values
    :type use_scale: bool
    :param mask: Modify Mask Stencil, Modify either the primary or mask stencil
    :type mask: bool
    """
    pass


def eV(E):
    """
    Returns photon energy in eV if specified in eV or KeV. Assumes that any
    value that is less than 100 is in KeV.

    Parameters
    ----------
    E : float
        The input energy to convert to eV

    Returns
    -------
    E : float
        Energy converted to eV from KeV
    """
    if E < 100:
        E *= 1000.0
    return float(E)


@classmethod
def child_type(cls, name):
    """Given a node, return the type which the child with that name should have.
        The default is "same as this class".
        """
    return cls


@classmethod
def fromdict(cls, mapping, with_dto=False):
    """Create a new Data Transfer Object (DTO) from a regular
        Python dictionary.
        """
    return cls(mapping).as_dto(with_dto=with_dto)


def merge_adjacent(stream, factory=tuple):
    """Yield items from a stream of tuples.

    The first two items of each tuple are regarded as pos and end.
    If they are adjacent, and the rest of the tuples compares the same,
    the items are merged.

    Instead of the default factory `tuple`, you can give a named tuple
    or any other type to wrap the streams items in.

    """
    stream = iter(stream)
    for pos, end, *rest in stream:
        for npos, nend, *nrest in stream:
            if nrest != rest or npos > end:
                yield factory(pos, end, *rest)
                pos, rest = npos, nrest
            end = nend
        yield factory(pos, end, *rest)


def data_disks_are_encrypted_7_3(virtual_machines):
    """
    TODO rather than making a second call here, enrich
    the data during the get_data phase if required.

    Then add the managed disk section commented out section.
    TODO: test this works for encrypted data disks.
    """
    items_flagged_list = []
    items_checked = 0
    for vm in virtual_machines:
        if not vm['storageProfile']['dataDisksEncrypted']:
            for disk in vm['storageProfile']['dataDisks']:
                if disk['managedDisk']:
                    managed = 'True'
                else:
                    managed = 'False'
                items_flagged_list.append((vm['resourceGroup'], vm['name'],
                    disk['name'], managed))
    stats = {'items_flagged': len(items_flagged_list), 'items_checked': len
        (virtual_machines)}
    metadata = {'finding_name': 'data_disks_are_encrypted', 'negative_name':
        '', 'columns': ['Resource Group', 'Name', 'Disk Name', 'Managed']}
    return {'items': items_flagged_list, 'stats': stats, 'metadata': metadata}
    stats = {'items_flagged': len(items_flagged_list), 'items_checked': len
        (virtual_machines)}
    metadata = {'finding_name': 'data_disks_are_encrypted', 'negative_name':
        '', 'columns': ['Resource Group', 'Name', 'Disk Name']}
    return {'items': items_flagged_list, 'stats': stats, 'metadata': metadata}


@staticmethod
def reg_score_function(X, y, mean, scale, shape, skewness):
    """ GAS Normal Regression Update term using gradient only - native Python function

        Parameters
        ----------
        X : float
            datapoint for the right hand side variable

        y : float
            datapoint for the time series

        mean : float
            location parameter for the Normal distribution

        scale : float
            scale parameter for the Normal distribution

        shape : float
            tail thickness parameter for the Normal distribution

        skewness : float
            skewness parameter for the Normal distribution

        Returns
        ----------
        - Score of the Normal family
        """
    return X * (y - mean)


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


@classmethod
def query(cls, *args, **kwargs):
    """ Same as collection.find, but return Document then dict """
    for doc in cls._coll.find(*args, **kwargs):
        yield cls.from_storage(doc)


def envialia_url(debug=False):
    """
    Envialia URL connection

    :param debug: If set to true, use Envialia test URL
    """
    if debug:
        return 'http://wstest.envialia-urgente.com:9082/soap'
    else:
        return 'http://ws.envialia-urgente.com/soap'


def construct_group_name(group):
    """Constructs MirrorGroup name for volumes.

    VNX only allows for 32-character group name, so
    trim the dash(-) from group id.
    """
    return group.id.replace('-', '')


def uppercase_range(code1, code2):
    """
    If the range of characters from code1 to code2-1 includes any
    lower case letters, return the corresponding upper case range.
    """
    code3 = max(code1, ord('a'))
    code4 = min(code2, ord('z') + 1)
    if code3 < code4:
        d = ord('A') - ord('a')
        return code3 + d, code4 + d
    else:
        return None


def custom(message, allowed, err='Invalid input.'):
    """Command line input and error checking for user-defined allowable inputs.

    Args:
        message (str): The input message displayed in the command line.
        allowed (tuple of (str,)): The allowable user inputs.
        err (str, optional): The message displayed for an erroneous input.
            Defaults to "Invalid input.".

    Returns:
        str: The first sucessfully allowed input string.
    """
    while True:
        data = input(message)
        data = data.strip()
        if data == '':
            print('Please provide an input.')
            continue
        if data in allowed:
            return data
        print(err)


@staticmethod
def _compute_final_exit_code(*codes):
    """Returns the exit code with higher abs value in case of negative values."""
    max_code = None
    for code in codes:
        if max_code is None or abs(max_code) < abs(code):
            max_code = code
    return max_code


@classmethod
def is_notifying(cls, user_or_email_, object_id=None, **filters):
    """Return whether the user/email is watching this event (either
        active or inactive watches), conditional on meeting the criteria in
        ``filters``.

        Count only watches that match the given filters exactly--not ones which
        match merely a superset of them. This lets callers distinguish between
        watches which overlap in scope. Equivalently, this lets callers check
        whether :meth:`notify()` has been called with these arguments.

        Implementations in subclasses may take different arguments--for
        example, to assume certain filters--though most will probably just use
        this. However, subclasses should clearly document what filters they
        supports and the meaning of each.

        Passing this an ``AnonymousUser`` always returns ``False``. This means
        you can always pass it ``request.user`` in a view and get a sensible
        response.

        """
    return cls._watches_belonging_to_user(user_or_email_, object_id=
        object_id, **filters).exists()


def evolve(context, generation):
    """Evolve a database to the given schema generation.

        The database should be assumed to be at the schema generation
        one less than the given `generation` argument. In other words,
        the `evolve` method is only required to make one evolutionary
        step.

        The `context` argument has a connection attribute, providing a
        database connection to be used to change the database. A
        `context` argument is passed rather than a connection to make
        it possible to provide additional information later, if it
        becomes necessary.

        This method should *not* commit a transaction. The transaction
        will be committed by the caller if there is no error. The
        method may create savepoints.

        .. versionchanged:: 5.0

            Previously this documentation contained a provision for committing
            the transaction "if there are no subsequent operations." That
            was unclear and incompatible with explicit transaction managers.

            Now, this method must *never* commit the transaction.
        """


def _split_and_keep(_str, separator):
    """Replace end of sentence with separator"""
    if not _str:
        return []
    max_p = chr(ord(max(_str)) + 1)
    return _str.replace(separator, separator + max_p).split(max_p)


def _fzerofall(data):
    """Find zerocrossings on falling edge of a filtered signal"""
    pos = data > 0
    return (pos[:-1] & ~pos[1:]).nonzero()[0]


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


@classmethod
def parse(cls, url):
    """Parses a :term:`VRI` and creates a :class:`VUrl` reference.

        :param url: a :term:`VRI` string for the resource
        :type  url: unicode
        :returns:   :class:`VUrl` identifying the resource.

        This is an abstract method, derived classes must implement.

        """
    raise NotImplementedError()


def screencast(filepath: str='', full: bool=True):
    """Capture a video of the active area or whole Blender window

    :param filepath: filepath
    :type filepath: str
    :param full: Full Screen, Capture the whole window (otherwise only capture the active area)
    :type full: bool
    """
    pass


def removeReader(reader):
    """
        Removes an object previously added with L{addReader}.

        @return: C{None}.
        """


def make_response(*args):
    """Sometimes it is necessary to set additional headers in a view.  Because
    views do not have to return response objects but can return a value that
    is converted into a response object by Flask itself, it becomes tricky to
    add headers to it.  This function can be called instead of using a return
    and you will get a response object which you can use to attach headers.
    """
    from flask_jsonrpc.site import jsonrpc_site
    return jsonrpc_site.make_response(args)


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 has_message_body(status):
    """
    According to the following RFC message body and length SHOULD NOT
    be included in responses status 1XX, 204 and 304.
    https://tools.ietf.org/html/rfc2616#section-4.4
    https://tools.ietf.org/html/rfc2616#section-4.3
    """
    return status not in (204, 304) and not 100 <= status < 200


def bbox(detections):
    """Here we extract the bounding
    boxes of each detected object"""
    bbox = []
    for i in range(len(detections)):
        bbox.append(detections[i]['box_points'])
    return bbox


def decode_set(data, unpackb):
    """Decode MessagePack data into a Python 'set' object."""
    return set(unpackb(data, use_list=False))


def in_other_letter_digits(category):
    """Code points that are letters and digits other than the "traditional"
    letters and digits.

    Args:
        category (str): Unicode general category.

    Returns:
        bool: True if `category` in set.
    """
    return category in {'Lt', 'Nl', 'No', 'Me'}


def user(event):
    """ show user selected by userhost. """
    from bot.space import fleet, users
    if not event._parsed.rest:
        event.reply('user <origin>')
        return
    nick = event._parsed.args[0]
    origin = fleet.get_origin(nick)
    u = users.fetch(origin)
    if u:
        event.reply(slice(u, skip=['type']))


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


@classmethod
def _updateClassDictWithTemplateItems(cls, classdict):
    """If constructed through use_template, we need to construct
        the appropriate type of items based on our item_type of our class."""
    if 'template_items' in classdict:
        for item in classdict['template_items']:
            classdict[item.name] = cls.item_type.construct(item)
        del classdict['template_items']


def _ipython_displayhook(cls, func, fmt='image/png'):
    """
    Register func as a displayhook for class `cls`
    """
    import IPython
    formatter = IPython.get_ipython().display_formatter.formatters[fmt]
    return formatter.for_type(cls, func)


def get_object_proxy(obj):
    """Experimental function. Not part of the official API"""
    return obj._helper.device


@classmethod
def PeekNavi(cls, pre=False):
    """Peek into the navigation cache
        @param cls: Class
        @keyword pre: bool

        """
    if pre:
        if cls._poscache.HasPrevious():
            return cls._poscache.PeekPrevious()
    elif cls._poscache.HasNext():
        return cls._poscache.PeekNext()
    return None, None


def rmv_end_str(w, s):
    """
    remove str at the end of tken
    :param w: str, token to be cleaned
    :param s: str, string to be removed
    :return: str
    """
    if w.endswith(s):
        w = w[:-len(s)]
    return w


def parse_bool(value):
    """Parse string that represents a boolean value.

    Arguments:
        value (str): The value to parse.
    Returns:
        bool: True if the value is "on", "true", or "yes", False otherwise.
    """
    return (value or '').lower() in ('on', 'true', 'yes')


@classmethod
def _get_kdjd(cls, df, n_days):
    """ Get the D of KDJ

        D = 2/3 × (prev. D) +1/3 × (curr. K)
        2/3 and 1/3 are the smooth parameters.
        :param df: data
        :param n_days: calculation range
        :return: None
        """
    k_column = 'kdjk_{}'.format(n_days)
    d_column = 'kdjd_{}'.format(n_days)
    df[d_column] = list(cls._calc_kd(df.get(k_column)))


def get_user_profile_url(user):
    """Return project user's github profile url."""
    return 'https://github.com/{}'.format(user)


@classmethod
def __jsonDecode__(cls, state):
    """Returns an object of cls based on a given state"""
    return cls(state['value'])


def location_clear(clear_delta: bool=False):
    """Clear the object’s location

    :param clear_delta: Clear Delta, Clear delta location in addition to clearing the normal location transform
    :type clear_delta: bool
    """
    pass


def set_run_validators(run):
    """
    Set whether or not validators are run.  By default, they are run.
    """
    if not isinstance(run, bool):
        raise TypeError("'run' must be bool.")
    global _run_validators
    _run_validators = run


def region_2d_to_vector_3d(region: 'bpy.types.Region', rv3d:
    'bpy.types.RegionView3D', coord) ->'mathutils.Vector':
    """Return a direction vector from the viewport at the specific 2d region coordinate.

    :param region: region of the 3D viewport, typically bpy.context.region.
    :type region: 'bpy.types.Region'
    :param rv3d: 3D region data, typically bpy.context.space_data.region_3d.
    :type rv3d: 'bpy.types.RegionView3D'
    :param coord: 2d coordinates relative to the region: (event.mouse_region_x, event.mouse_region_y) for example.
    :return:  normalized 3d vector.
    """
    pass


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


def getLinesFromDict(marker, dictFileName):
    """
   Search for the line marker
   in the dictionary and save all lines until the line '0'
   Return them as List
   """
    selectedLines = []
    ifile = open(dictFileName)
    lines = ifile.readlines()
    ifile.close()
    recording = False
    for line in lines:
        if marker in line:
            recording = True
            continue
        if recording and '0' == line[0]:
            break
        if recording:
            selectedLines.append(line[:-1])
    return selectedLines


@staticmethod
def read_metadata(fs, paths, categories=None, index=None, gather_statistics
    =None, filters=None, **kwargs):
    """ Gather metadata about a Parquet Dataset to prepare for a read

        This function is called once in the user's Python session to gather
        important metadata about the parquet dataset.

        Parameters
        ----------
        fs: FileSystem
        paths: List[str]
            A list of paths to files (or their equivalents)
        categories: list, dict or None
            Column(s) containing categorical data.
        index: str, List[str], or False
            The column name(s) to be used as the index.
            If set to ``None``, pandas metadata (if available) can be used
            to reset the value in this function
        gather_statistics: bool
            Whether or not to gather statistics data.  If ``None``, we only
            gather statistics data if there is a _metadata file available to
            query (cheaply)
        filters: list
            List of filters to apply, like ``[('x', '>', 0), ...]``.
        **kwargs: dict (of dicts)
            User-specified arguments to pass on to backend.
            Top level key can be used by engine to select appropriate dict.

        Returns
        -------
        meta: pandas.DataFrame
            An empty DataFrame object to use for metadata.
            Should have appropriate column names and dtypes but need not have
            any actual data
        statistics: Optional[List[Dict]]
            Either None, if no statistics were found, or a list of dictionaries
            of statistics data, one dict for every partition (see the next
            return value).  The statistics should look like the following:

            [
                {'num-rows': 1000, 'columns': [
                    {'name': 'id', 'min': 0, 'max': 100, 'null-count': 0},
                    {'name': 'x', 'min': 0.0, 'max': 1.0, 'null-count': 5},
                    ]},
                ...
            ]
        parts: List[object]
            A list of objects to be passed to ``Engine.read_partition``.
            Each object should represent a piece of data (usually a row-group).
            The type of each object can be anything, as long as the
            engine's read_partition function knows how to interpret it.
        """
    raise NotImplementedError()


def fsdorigin(fsdobject, setto000=False):
    """return the origin of the surface"""
    if setto000:
        return 0, 0
    else:
        raise NotImplementedError


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 show(operation):
    """Display the operation help string.

    :param callable operation: requested operation.
    """
    print('\n{}\n'.format(operation.__doc__))


def tuplemut(tpl, val, idx):
    """ Return a tuple with *idx* changed to *val* """
    lst = list(tpl)
    lst[idx] = val
    return tuple(lst)


def _check_compensation_grade(info1, info2, name1, name2='data', ch_names=None
    ):
    """Ensure that objects have same compensation_grade."""
    from ..io import Info
    from ..io.pick import pick_channels, pick_info
    from ..io.compensator import get_current_comp
    for t_info in (info1, info2):
        if t_info is None:
            return
        assert isinstance(t_info, Info), t_info
    if ch_names is not None:
        info1 = info1.copy()
        info2 = info2.copy()
        for t_info in [info1, info2]:
            if t_info['comps']:
                t_info['comps'] = []
            picks = pick_channels(t_info['ch_names'], ch_names)
            pick_info(t_info, picks, copy=False)
    grade1 = get_current_comp(info1) or 0
    grade2 = get_current_comp(info2) or 0
    if grade1 != grade2:
        raise RuntimeError(
            'Compensation grade of %s (%s) and %s (%s) do not match' % (
            name1, grade1, name2, grade2))


def total_seconds(delta):
    """Return the total seconds of datetime.timedelta object.

    :param timedelta delta: a delta to convert
    :returns:   seconds
    :rtype:     int
    """
    return delta.total_seconds()


def econfigstr_hole(econfigstr, corelevel, highesunoccp, htype='valence'):
    """
    # '1s2 | 2s2' , '1s2' , '2p0' -> '1s1 | 2s2 2p1'

    :param: string
    :param: string
    :param: string

    :return: string
    """
    corestates = econfigstr.split()
    hoc = int(highesunoccp[2:])
    if htype == 'valence':
        new_highocc = str(hoc + 1)
    elif hoc == 0:
        highesunoccp = ''
        new_highocc = ''
    else:
        new_highocc = str(hoc)
    new_econfig = ''
    added = False
    for state in corestates:
        if state == corelevel:
            occ = int(state[2:])
            new_occ = occ - 1
            state = state[:2] + str(new_occ)
        if state == highesunoccp:
            added = True
            state = highesunoccp[:2] + str(new_highocc)
        new_econfig = new_econfig + state + ' '
    if not added:
        new_econfig = new_econfig + highesunoccp[:2] + str(new_highocc)
    return new_econfig.rstrip(' ')


def int2uint32(value):
    """
    Convert a signed 32 bits integer into an unsigned 32 bits integer.

    >>> print(int2uint32(1))
    1
    >>> print(int2uint32(2**32 + 1))  # ignore bits larger than 32 bits
    1
    >>> print(int2uint32(-1))
    4294967295
    """
    return value & 4294967295


def _col_containing_digit_or_digits(record, header_len, alphanumeric_cols):
    """Returns index of column in record with both non-digits and digits if
    one exists. Otherwise, returns None."""
    if record.shape[1] == header_len:
        for col in alphanumeric_cols:
            for char in record[col]:
                if char.isdigit():
                    return col
    return None


@classmethod
def from_iter(cls, iter):
    """
        Creates a variant from a iterable or arguments.
        It assumes that the items are in order, e.g. from a VCF line
        """
    chrom, pos, id, ref, alt, qual, fltr, info, fmt, *genotypes = iter
    self = cls(chrom, pos, id, ref, alt, qual, fltr, info, fmt, genos=genotypes
        )
    return self


def p_testlist_error(p):
    """arguments : argumentlist '(' error ')'"""
    print('Syntax error in test list that starts on line %d' % p.lineno(2))
    raise SyntaxError


def minify(content):
    """
    Remove whitespace in provided content.
    """
    content = content.replace('\n', ' ')
    content = content.replace('\t', ' ')
    content = content.replace('   ', ' ')
    content = content.replace('  ', ' ')
    return content


def _get_dim(data):
    """
    Data dimensionality with error checking
    """
    if data.ndim == 2:
        ndim = 2
    elif data.ndim == 3:
        ndim = 3
    else:
        raise RuntimeError(
            'Unsupported number of dimensions {}. We only supports 2 or 3D arrays.'
            .format(data.ndim))
    return ndim


def dfa_nonemptiness_check(dfa: dict) ->bool:
    """ Checks if the input DFA is nonempty (i.e. if it recognizes a
    language except the empty one), returning True/False.

    An automaton A is nonempty if :math:`L(A) ≠ ∅`. L(A) is
    nonempty iff there are states :math:`s_0 and t ∈ F` such
    that t is connected to :math:`s_0`. Thus, automata
    nonemptiness is equivalent to graph reachability, where a
    breadth-first-search algorithm can construct in linear time
    the set of all states connected to initial state
    :math:`s_0`.
    A is nonempty iff this set intersects F nontrivially.

    :param dict dfa: input DFA.
    :return: *(bool)*, True if the DFA is nonempty, False otherwise
    """
    queue = [dfa['initial_state']]
    visited = set()
    visited.add(dfa['initial_state'])
    while queue:
        state = queue.pop(0)
        visited.add(state)
        for a in dfa['alphabet']:
            if (state, a) in dfa['transitions']:
                if dfa['transitions'][state, a] in dfa['accepting_states']:
                    return True
                if dfa['transitions'][state, a] not in visited:
                    queue.append(dfa['transitions'][state, a])
    return False


def is_hashable(arg):
    """Return True if hash(arg) will succeed, False otherwise.

    Some types will pass a test against collections.Hashable but fail when they
    are actually hashed with hash().

    Distinguish between these and other types by trying the call to hash() and
    seeing if they raise TypeError.

    Examples
    --------
    >>> a = ([],)
    >>> isinstance(a, collections.Hashable)
    True
    >>> is_hashable(a)
    False
    """
    try:
        hash(arg)
    except TypeError:
        return False
    else:
        return True


def _chunks(l, chunksize):
    """Yield successive n-sized chunks from l.
    Taken from https://stackoverflow.com/a/312464/5094480
    """
    for i in range(0, len(l), chunksize):
        yield l[i:i + chunksize]


@staticmethod
def _handle_emailtoken():
    """ Called when Personio requires email token...
        Asks the user to enter the token.

        Args:
            message: Optional.

        Returns:
            A string containing the token.
        """
    print('Personio requires an E-Mail token...')
    email_token = input('Please enter the code sent to you via E-Mail: ')
    return email_token


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['policyType']
    if type == 'threshold':
        return 'UpdateThresholdPolicyDetails'
    else:
        return 'UpdateAutoScalingPolicyDetails'


@classmethod
def load_provisioning(cls):
    """set up the provision.py module for this dialect.

        For dialects that include a provision.py module that sets up
        provisioning followers, this method should initiate that process.

        A typical implementation would be::

            @classmethod
            def load_provisioning(cls):
                __import__("mydialect.provision")

        The default method assumes a module named ``provision.py`` inside
        the owning package of the current dialect, based on the ``__module__``
        attribute::

            @classmethod
            def load_provisioning(cls):
                package = ".".join(cls.__module__.split(".")[0:-1])
                try:
                    __import__(package + ".provision")
                except ImportError:
                    pass

        .. versionadded:: 1.3.14

        """


def median(series, n):
    """
    中位数: 求series在n个周期内居于中间的数值

        注意:
            1. 当n为有效值但当前的series序列元素个数不足n个, 函数返回 NaN 序列
            2. 对n个周期内所有series排序后, 若n为奇数, 则选择第(n + 1) / 2个为中位数, 若n为偶数, 则中位数是(n / 2)以及(n / 2 + 1)的平均数

    Args:
        series (pandas.Series): 数据序列

        n (int): 周期

    Returns:
        pandas.Series: 中位数序列

    Example::

        例1:
            # 假设最近3日的收盘价为2727, 2754, 2748, 那么当前 median(df["close"], 3) 的返回值是2748
            median3 = tafunc.median(df["close"], 3)

        例2:
            # 假设最近4日的开盘价为2752, 2743, 2730, 2728, 那么当前 median(df["open"], 4) 的返回值是2736.5
            median4 = tafunc.median(df["open"], 4)
    """
    median_data = series.rolling(n).median()
    return median_data


def path_is_remote(path, s3=True):
    """
    Determine whether file path is remote or local.

    Parameters
    ----------
    path : path to file

    Returns
    -------
    is_remote : bool
    """
    prefixes = 'http://', 'https://', '/vsicurl/'
    if s3:
        prefixes += 's3://', '/vsis3/'
    return path.startswith(prefixes)


def save(token, step, data=None):
    """Save the state of a workflow.

        :param token: A unique token identifying this workflow instance.
        :type token: str
        :param step: The next step for this workflow.
        :type step: str
        :param data: Additional data (workflow-specific).
        :type data: str
        """


@staticmethod
def version():
    """
        Retourne la version de la classe.

        Attention, le numero de version du setup.py est extrait d'ici.
        """
    print('Version 0.1.1')


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 title_case(field):
    """Validates that as sting is title case
    Args:
        field:str
    Returns:
        returns Boolean
    """
    if field.istitle():
        return True
    else:
        return False


def _mask_X_(X_, confidence_index):
    """
    Helper function to verify that the confidence_index is the correct
    shape.

    Args:
        `X_`: The discretized microstructure function, an
            `(n_samples, n_x, ..., n_states)` shaped array
            where `n_samples` is the number of samples, `n_x` is thes
            patial discretization, and n_states is the number of local states.
        confidence_index: array with same shape as X used to assign a
            confidence value for each data point.

    Returns:
        The discretized microstructure function scaled by the confidence_index.

    """
    if confidence_index is not None:
        if X_.shape[:-1] != confidence_index.shape:
            raise RuntimeError('confidence_index does not match shape of X')
        X_ = X_ * confidence_index[..., None]
    return X_


def _get_default_dict_class_name() ->str:
    """
    Name of the class of the next data descriptor created and returned by the
    next call to the :func:`DefaultDict` function, guaranteed to be unique
    across all such classes.

    Since the human-readability of this name is neither required nor desired,
    this is a non-human-readable name efficiently constructed from a private
    prefix and a unique arbitrary identifier.
    """
    global _DEFAULT_DICT_ID
    _DEFAULT_DICT_ID += 1
    return '__DefaultDict' + str(_DEFAULT_DICT_ID)


def feather_weight_clear():
    """Reset the feather weight to zero

    """
    pass


def get_current(isamAppliance):
    """
    Get permitted features for current user
    """
    return isamAppliance.invoke_get('Get permitted features for current user',
        '/permissions/v1')


@classmethod
def select(cls, table, **filter_args):
    """Return rows of the table matching filter args.

        This is a proxy for sqlalchemy's ``session.query(table).filter(**kwargs)``

        :param type table: the model class
        :returns: all rows in the table matching ``**filter_args``
        """
    return cls.session.query(table).filter_by(**filter_args)


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

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

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


def initialize_event_source(source, node_pool_size, monitor_params):
    """
    Initializes the file event source when reading files from the filesystem.

    This function must be called on the master node before the :func:`event_generator`
    function is called on the worker nodes. There is no need to initialize the event
    source when reading from files, so this function actually does nothing.

    Arguments:

        source (str): the relative or absolute path to a file containing a list of
            files to process (one per line, with their full path).

        node_pool_size (int): the total number of nodes in the OnDA pool, including all
            the worker nodes and the master node.

        monitor_params (:class:`~onda.utils.parameters.MonitorParams`): an object
            storing the OnDA monitor parameters from the configuration file.
    """
    del source
    del node_pool_size
    del monitor_params


def add_argument_parameter(path, kwargs, param, prameter_type):
    """Add query parameter."""
    path_list = path.split(prameter_type + '/')
    arg = '-'
    if len(path_list) > 1:
        arg = path_list[1].split('/')[0]
    kwargs['params'][param] = arg


def getPreviousByDate(message_id):
    """Returns a proxy for the previous message by date"""


@staticmethod
def _get_name_from_dn(dn):
    """
        Get the instance name from the dn

        :param dn: string containing the distinguished name URL
        :return: string containing the name
        """
    name = dn.split('/lb-')[1].split('/')[0]
    return name


def lowercase(string):
    """Convert string into lower case.
    Args:
        string: String to convert.
    Returns:
        string: Lowercase case string.
    """
    return str(string).lower()


def compare_versions(x, y):
    """it will compare 2 version numbers and return the higher value
    example compare_versions('2020.10.6', '2020.3.7') will return '2020.10.6'
    return None if 2 versions are equal
    """
    try:
        a = [int(x) for x in x.split('.')[:3]]
        b = [int(x) for x in y.split('.')[:3]]
        for i in range(3):
            if a[i] > b[i]:
                return x
            elif a[i] < b[i]:
                return y
    except:
        pass
    return None


def prody_select(selstr, *pdbs, **kwargs):
    """Write selected atoms from a PDB file in PDB format.

    :arg selstr: atom selection string, see :ref:`selections`

    :arg pdbs: PDB identifier(s) or filename(s)

    :arg output: output filename, default is :file:`pdb_selected.pdb`

    :arg prefix: prefix for output file, default is PDB filename

    :arg suffix: output filename suffix, default is :file:`_selected`"""
    from os.path import isfile
    from prody import LOGGER, parsePDB, writePDB
    if not pdbs:
        raise ValueError('pdb argument must be provided')
    if (isfile(selstr) or len(selstr) == 4 and selstr[0].isdigit()) and len(
        pdbs) == 1 and not isfile(pdbs[0]):
        pdbs, selstr = selstr, pdbs[0]
        LOGGER.warn(
            'The order of selstr and pdb arguments have switched to support multiple files, old order will be supported until v1.4.'
            )
        pdbs = [pdbs]
    prefix = kwargs.get('prefix', None)
    suffix = kwargs.get('suffix', '_selected')
    output = kwargs.get('output', None)
    for pdb in pdbs:
        pdb = parsePDB(pdb)
        pdbselect = pdb.select(selstr)
        if pdbselect is None:
            LOGGER.warn('Selection {0} did not match any atoms.'.format(
                repr(selstr)))
            return
        LOGGER.info('Selection {0} matched {1} atoms.'.format(repr(selstr),
            len(pdbselect)))
        outname = output or (prefix or pdb.getTitle()) + suffix
        LOGGER.info('Selection is written into: ' + writePDB(outname,
            pdbselect))


@staticmethod
def evaluate(x, slope, intercept):
    """One dimensional Line model function"""
    return slope * x + intercept


def _evaluate_term_fwd(term, eta0, eps0, deps, eta_derivs,
    eval_directional_derivative, validate=False):
    """Evaluate the DerivativeTerm in forward mode.

    Parameters
    ----------------------
    term: `DerivativeTerm`
        A `DerivativeTerm` object to evaluate.
    eta0, eps0 : `numpy.ndarray`
        Where to evaluate the derivative.
    deps : `numpy.ndarray`
        The direction in which to evaluate the derivative.
    eta_derivs : `list` of `numpy.ndarray`
        A list where ``eta_derivs[i]`` contains
        :math:`d\\eta^i / d\\epsilon^i \\Delta \\epsilon^i`.
    eval_directional_derivative:
        A function matching `eval_directional_derivative` in
        ForwardModeDerivativeArray.
    validate: optional `bool`
        If `True`, run checks for the appropriate sizes of arguments and
        produce helpful error messages if necessary.
        Default is `False`.
    """
    if validate:
        if len(eta_derivs) < term.order() - 1:
            raise ValueError('Not enough derivatives in ``eta_derivs``.')
    vec_args = []
    eta_directions = []
    for i in range(len(term.eta_orders)):
        eta_order = term.eta_orders[i]
        if eta_order > 0:
            for j in range(eta_order):
                eta_directions.append(eta_derivs[i])
    eps_directions = []
    for i in range(term.eps_order):
        eps_directions.append(deps)
    return term.prefactor * eval_directional_derivative(eta0, eps0,
        eta_directions, eps_directions, validate=validate)


def _convertStr2Other(value):
    """
    数据转换,把字符串的结果进行类型转换尝试,转换成为 int float boolean
    :param value:
    :return:
    """
    if value is None:
        return None
    if isinstance(value, bool) or isinstance(value, int) or isinstance(value,
        float):
        return value
    if 'true' == value.lower():
        return True
    elif 'false' == value.lower():
        return False
    try:
        return int(value)
    except ValueError:
        try:
            return float(value)
        except ValueError:
            return value


def draw_decision_node(_box, context, _bounding_box):
    """
    Draw diamond shape, which represents decision and merge nodes.
    """
    cr = context.cairo
    r = 15
    r2 = r * 2 / 3
    cr.move_to(r2, 0)
    cr.line_to(r2 * 2, r)
    cr.line_to(r2, r * 2)
    cr.line_to(0, r)
    cr.close_path()
    cr.stroke()


def view_lock_clear():
    """Clear all view locking

    """
    pass


def rm_dict_uppercase_dupli(src):
    """
                rm_dict_uppercase_dupli()

                remove each <key> from the dict <src> if <key.lowercase()>
                already exist in <src>.

                { "a" : "a_value, "A" : "A_value", "c" : "c_value" }
                        -> { "a" : "a_value, "c" : "c_value" }
    """
    res = dict()
    for key, value in src.items():
        if key.lower() != key and key.lower() in src:
            pass
        else:
            res[key] = value
    return res


def get_previous_item(lst, item):
    """ Given an item, find its previous item in the list
        If the item appears more than once in the list, return the first index

        Args:
            lst: the list to search
            item: the item we want to find the previous item for

        Returns: The previous item or None if not found.
    """
    try:
        i = lst.index(item)
        if i > 0:
            return lst[i - 1]
    except (IndexError, ValueError):
        pass
    return None


def SVGFlipHandle(x, y, x1, y1):
    """
    Flip handle around base point
    """
    x = x + (x - x1)
    y = y + (y - y1)
    return x, y


@staticmethod
def mixed_case(identifier):
    """helper function to turn token name into mixed case"""
    if identifier is '':
        return ''
    else:
        if identifier[0] == 'I':
            lowly = 'i'
        else:
            lowly = identifier[0].lower()
        return lowly + identifier[1:]


def is_hashable(obj) ->bool:
    """
    Return True if hash(obj) will succeed, False otherwise.

    Some types will pass a test against collections.abc.Hashable but fail when
    they are actually hashed with hash().

    Distinguish between these and other types by trying the call to hash() and
    seeing if they raise TypeError.

    Returns
    -------
    bool

    Examples
    --------
    >>> import collections
    >>> a = ([],)
    >>> isinstance(a, collections.abc.Hashable)
    True
    >>> is_hashable(a)
    False
    """
    try:
        hash(obj)
    except TypeError:
        return False
    else:
        return True


@staticmethod
def get_alarms(name=None, user=None, state=None, meter=None, project=None,
    enabled=None, alarm_id=None, alarm_type=None, severity=None, exclude=
    None, pagination=None):
    """Yields a lists of alarms that match filters."""
    return []


def Workbench():
    """ A lazy forward import function for the Workbench type.

    """
    from .workbench import Workbench
    return Workbench


def backimage_sample():
    """Use mouse to sample background image

    """
    pass


def unwrap(tokens):
    """ Unwraps grouped tokens. """
    if tokens:
        return tokens[0]


def complex2float(array):
    """Sums real and imaginary parts of an array together element-
    wise. This is used for finding the power of negative numbers
    which are calcuable but not in numpy which returns a nan.

    This is a workaround routine and is typically using as follows:

    complex2float(np.array(array, dtype=complex)**power)

    """
    return array.real + array.imag


def last(iter: (list or range)):
    """Returns the last element from the list or range
    """
    if type(iter) == list:
        return iter[len(iter) - 1]
    elif type(iter) == range:
        return iter.stop - (iter.stop - 1 - iter.start) % iter.step - 1
    else:
        raise ValueError('iter must be of type list or range')


def exception_is_4xx(exception):
    """Returns True if exception is in the 4xx range."""
    if not hasattr(exception, 'response'):
        return False
    if exception.response is None:
        return False
    if not hasattr(exception.response, 'status_code'):
        return False
    return 400 <= exception.response.status_code < 500


def arg_to_dict(arg):
    """Convert an argument that can be None, list/tuple or dict to dict

    Example::

        >>> arg_to_dict(None)
        []
        >>> arg_to_dict(['a', 'b'])
        {'a':{},'b':{}}
        >>> arg_to_dict({'a':{'only': 'id'}, 'b':{'only': 'id'}})
        {'a':{'only':'id'},'b':{'only':'id'}}

    :return: dict with keys and dict arguments as value
    """
    if arg is None:
        arg = []
    try:
        arg = dict(arg)
    except ValueError:
        arg = dict.fromkeys(list(arg), {})
    return arg


def _is_secure_boot(instance_info_caps, node_caps):
    """Extract node secure boot property"""
    return 'true' == str(instance_info_caps.get('secure_boot', node_caps.
        get('secure_boot', 'false'))).lower()


def string_keys_to_dict(key_strings, callback):
    """
    Maps each string in `key_strings` to `callback` function
    and return as a dict.
    """
    return dict.fromkeys(key_strings, callback)


def exit(args):
    """This method is used to exit from the PyShell"""
    quit()


@classmethod
def __copy__(cls, the_filter: 'FilterRepeater') ->'FilterRepeater':
    """
        Creates a shallow copy of the object.
        """
    new_filter = super().__copy__(the_filter)
    new_filter._filter_chain = the_filter._filter_chain
    new_filter.restrict_keys = the_filter.restrict_keys
    return new_filter


def parse_cron_options(argstring):
    """
    Parse periodic task options.
    Obtains configuration value, returns dictionary.

    Example::

        my_periodic_task = 60; now=true

    Respective "argstring"::

        60; now=true

    """
    parts = argstring.split(';')
    options = {'interval': float(parts[0].strip())}
    for part in parts[1:]:
        name, value = part.split('=')
        options[name.strip()] = value.strip()
    return options


def validate_type(data, types):
    """
    Validate type are defined in types.db and matching data values
    """
    if data.type not in types:
        raise Exception(
            'Do not know how to handle type %s. Do you have all your types.db files configured?'
             % data.type)
    if len(data.values) != len(types[data.type]):
        raise Exception('Number values %s differ from types defined for %s' %
            (data.values, data.type))


def constant(_):
    """
    Returns a constant value for the Scheduler

    :param _: ignored
    :return: (float) 1
    """
    return 1.0


def __exit__(exc_type, exc_val, exc_tb):
    """Support for the context manager protocol.

        Close the file and allow exceptions to propogate.
        """


@staticmethod
def _sanitize_key(key):
    """Strip the key of newlines only."""
    return str(key).replace('\n', '')


@classmethod
def check(cls, tag):
    """Create exception instance, but check type of tag first."""
    if not isinstance(tag, str):
        return TypeError(f'tag must be str, not {type(tag).__name__}')
    return cls(tag)


def mnist():
    """Note that this dataset, unlike other Talos datasets,returns:

    x_train, y_train, x_val, y_val"""
    import keras
    import numpy as np
    (x_train, y_train), (x_val, y_val) = keras.datasets.mnist.load_data()
    img_rows, img_cols = 28, 28
    if keras.backend.image_data_format() == 'channels_first':
        x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
        x_val = x_val.reshape(x_val.shape[0], 1, img_rows, img_cols)
        input_shape = 1, img_rows, img_cols
    else:
        x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
        x_val = x_val.reshape(x_val.shape[0], img_rows, img_cols, 1)
        input_shape = img_rows, img_cols, 1
    x_train = x_train.astype('float32')
    x_val = x_val.astype('float32')
    x_train /= 255
    x_val /= 255
    classes = len(np.unique(y_train))
    y_train = keras.utils.to_categorical(y_train, classes)
    y_val = keras.utils.to_categorical(y_val, classes)
    print('Use input_shape %s' % str(input_shape))
    return x_train, y_train, x_val, y_val


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


@staticmethod
def p_protocol_layer_optional(p):
    """protocol_layer_optional : generic_parameter_list"""


def function_to_signature(function_name):
    """
    Convert function definition to function signature.

    input: string
    output: string
    """
    import sha3
    signature = sha3.keccak_256(str(function_name).encode('utf-8')).hexdigest(
        ).lower()[:8]
    return signature


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def highlight_source(linenumber, index, lines, offset=None):
    """Extracts a few relevant lines from a file content given as a list
        of lines, adding line number information and identifying
        a particular line.

        When dealing with a ``SyntaxError`` or its subclasses, offset is an
        integer normally used by Python to indicate the position of
        the error with a ``^``, like::

            if True
                  ^

        which, in this case, points to a missing colon. We use the same
        representation in this case.
    """
    if lines is None:
        return '', ''
    if index is None:
        print('problem in highlight_source(): index is None')
        index = 0
    new_lines = []
    problem_line = ''
    nb_digits = len(str(linenumber + index))
    no_mark = '       {:%d}: ' % nb_digits
    with_mark = '    -->{:%d}: ' % nb_digits
    if offset is not None:
        offset_mark = ' ' * (8 + nb_digits + offset) + '^'
    i = linenumber - index
    for line in lines:
        if i == linenumber:
            num = with_mark.format(i)
            problem_line = line
            new_lines.append(num + line.rstrip())
            if offset is not None:
                new_lines.append(offset_mark)
            break
        else:
            num = no_mark.format(i)
        new_lines.append(num + line.rstrip())
        i += 1
    return '\n'.join(new_lines), problem_line


def enable_ds(module, array):
    """Enable Directory Service"""
    changed = False
    try:
        array.enable_directory_service()
        changed = True
    except Exception:
        module.fail_json(msg=
            'Enable Directory Service failed: Check Configuration')
    module.exit_json(changed=changed)


def locfmt(loc):
    """ Return a (lat, lon) location tuple in a standard string format """
    return '({0:.6f},{1:.6f})'.format(loc[0], loc[1])


def snap_cursor_to_selected():
    """Snap cursor to center of selected points

    """
    pass


def _swap_curly(string):
    """Swap single and double curly brackets"""
    return string.replace('{{ ', '{{').replace('{{', '\x00').replace('{', '{{'
        ).replace('\x00', '{').replace(' }}', '}}').replace('}}', '\x00'
        ).replace('}', '}}').replace('\x00', '}')


def apply():
    """
        Apply all values from vocabularies
        and return object with all fields.
        """


@staticmethod
def is_tag():
    """ Determines if the object is a Tag. """
    return False


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

        :param SfTeamJoinType val:
        :rtype: EventType
        """
    return cls('sf_team_join', val)


def addAttributesToFile(fileSection, **attributes):
    """
    _addAttributesToFiles_

    Add attributes to a file in the FWJR.
    """
    for attName, attValue in attributes.items():
        setattr(fileSection, attName, attValue)
    return


def tessellate_polygon(veclist_list) ->list:
    """Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.

    :param veclist_list: list of polylines
    """
    pass


def harmonicmean(inlist):
    """
Calculates the harmonic mean of the values in the passed list.
That is:  n / (1/x1 + 1/x2 + ... + 1/xn).  Assumes a '1D' list.

Usage:   lharmonicmean(inlist)
"""
    sum = 0
    for item in inlist:
        sum = sum + 1.0 / item
    return len(inlist) / sum


def condor_format_sequence(sequence):
    """Format a Sequence According to Condor Conventions."""
    return ' '.join(map(str, sequence))


def rot_clear():
    """Reset rotations of selected bones to their default values

    """
    pass


def __process_name(name):
    """map the name colorblind to deuteranomaly (most common type of common blindness)"""
    if name == 'colorblind':
        return 'deuteranomaly'
    else:
        return name


@staticmethod
def param_set(param):
    """
        ``param_set <instance_number> <param_symbol> <param_value>``

        set a value to given control

        e.g.::

            param_set 0 gain 2.50

        :param Lv2Param param: Parameter that will be updated your value
        """
    instance = param.effect.instance
    return 'param_set {} {} {}'.format(instance, param.symbol, param.value)


def get_public_key_location(private_key_location: str) ->str:
    """Returns the location of the public key based on the location of
        the private key.

        :param private_key_location: Private key location.

    """
    return private_key_location + '.pub'


def check_in(choices, **params):
    """Checks parameters are in a list of allowed parameters

    Parameters
    ----------

    choices : array-like, accepted values

    params : object
        Named arguments, parameters to be checked

    Raises
    ------
    ValueError : unacceptable choice of parameters
    """
    for p in params:
        if params[p] not in choices:
            raise ValueError('{} value {} not recognized. Choose from {}'.
                format(p, params[p], choices))


@classmethod
def set_class_unknown_command_message(cls, unknown_command_message):
    """Set class unknown command message.

        It will be returned if user sends an unknown command in private chat.
        """
    cls._unknown_command_message = unknown_command_message


def count_sequences(data):
    """Counts the number of sequences in the data.

    :param data: data
    :type data: np.array
    :return: number of sequences
    :rtype: int
    """
    c = 0
    s, e = 0, 0
    while 0 <= s < len(data):
        e = data[s]['eos']
        s = e
        c += 1
    return c


def resume_processes(AutoScalingGroupName=None, ScalingProcesses=None):
    """
    Resumes the specified suspended Auto Scaling processes, or all suspended process, for the specified Auto Scaling group.
    For more information, see Suspending and Resuming Auto Scaling Processes in the Auto Scaling User Guide .
    See also: AWS API Documentation

    Examples
    This example resumes the specified suspended scaling process for the specified Auto Scaling group.
    Expected Output:

    :example: response = client.resume_processes(
        AutoScalingGroupName='string',
        ScalingProcesses=[
            'string',
        ]
    )

    :type AutoScalingGroupName: string
    :param AutoScalingGroupName: [REQUIRED]
            The name or Amazon Resource Name (ARN) of the Auto Scaling group.

    :type ScalingProcesses: list
    :param ScalingProcesses: One or more of the following processes. If you omit this parameter, all processes are specified.
            Launch
            Terminate
            HealthCheck
            ReplaceUnhealthy
            AZRebalance
            AlarmNotification
            ScheduledActions
            AddToLoadBalancer
            (string) --

    :return: response = client.resume_processes(
        AutoScalingGroupName='my-auto-scaling-group',
        ScalingProcesses=[
            'AlarmNotification',
        ],
    )

    print(response)

    """
    pass


def subclassof(c, b):
    """Wrap issubclass to return True/False without throwing TypeError"""
    try:
        return issubclass(c, b)
    except TypeError:
        return False


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 _read_tag_garbage_str(dmfile):
    """
    DM4 has four bytes of % symbols in the tag.  Ensure it is there.
    """
    garbage_str = dmfile.read(4).decode('utf-8')
    assert garbage_str == '%%%%'


@staticmethod
def transform(rule, target):
    """
        The transform rule produces different values based on the target's
        value.
        """
    return rule['transform'][getattr(target, rule['from'])]


@staticmethod
def convert_to_type(value):
    """
        Convert a memory value into its python type counterpart
        :param value: The value to be converted
        """
    if value is None:
        return None
    if value == 'false' or value == 'true':
        return bool(value)
    elif value[0] == '"' and value[-1] == '"':
        return str(value[1:-1])
    elif '.' in value:
        return float(value)
    try:
        return int(value)
    except ValueError:
        return float(value)


@staticmethod
def iter(start, end=None):
    """Generate months between passed months.

		Args:
			start: The first month to yield.
			end: The final month to yield. If None, yield infinitely.

		Yields:
			Months between the passed values inclusive.
		"""
    month = start
    while end is None or month <= end:
        yield month
        month = month.next()


def select(SelectExpression=None, NextToken=None, ConsistentRead=None):
    """
    The Select operation returns a set of attributes for ItemNames that match the select expression. Select is similar to the standard SQL SELECT statement.
    The total size of the response cannot exceed 1 MB in total size. Amazon SimpleDB automatically adjusts the number of items returned per page to enforce this limit. For example, if the client asks to retrieve 2500 items, but each individual item is 10 kB in size, the system returns 100 items and an appropriate NextToken so the client can access the next page of results.
    For information on how to construct select expressions, see Using Select to Create Amazon SimpleDB Queries in the Developer Guide.
    See also: AWS API Documentation

    :example: response = client.select(
        SelectExpression='string',
        NextToken='string',
        ConsistentRead=True|False
    )

    :type SelectExpression: string
    :param SelectExpression: [REQUIRED] The expression used to query the domain.

    :type NextToken: string
    :param NextToken: A string informing Amazon SimpleDB where to start the next list of ItemNames .

    :type ConsistentRead: boolean
    :param ConsistentRead: Determines whether or not strong consistency should be enforced when data is read from SimpleDB. If true , any data previously written to SimpleDB will be returned. Otherwise, results will be consistent eventually, and the client may not see data that was written immediately before your read.

    :rtype: dict
    :return: {
        'Items': [
            {
                'Name': 'string',
                'AlternateNameEncoding': 'string',
                'Attributes': [
                    {
                        'Name': 'string',
                        'AlternateNameEncoding': 'string',
                        'Value': 'string',
                        'AlternateValueEncoding': 'string'
                    },
                ]
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    (dict) --
    Items (list) -- A list of items that match the select expression.
    (dict) --
    Name (string) -- The name of the item.
    AlternateNameEncoding (string) --
    Attributes (list) -- A list of attributes.
    (dict) --
    Name (string) -- The name of the attribute.
    AlternateNameEncoding (string) --
    Value (string) -- The value of the attribute.
    AlternateValueEncoding (string) --

    NextToken (string) -- An opaque token indicating that more items than MaxNumberOfItems were matched, the response size exceeded 1 megabyte, or the execution time exceeded 5 seconds.

    """
    pass


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


def _commit_and_push(git_repo, branch_name, commit_message, verbose):
    """Commit and push to the remote branch."""
    git_repo.index.commit(commit_message)
    if verbose:
        print('Add commit: {0}'.format(commit_message))
    remote = git_repo.remote(name='origin')
    refspec = 'refs/heads/{br}:refs/heads/{br}'.format(br=branch_name)
    remote.push(refspec=refspec, force=True)


def catch_index_error(what, otherwise):
    """
    runs callable 'what' and catches IndexErrors, returning 'otherwise' if one occurred
    :param what: callable
    :param otherwise: alternate result in case of IndexError
    :return: result of 'what' or 'otherwise' in case of IndexError
    """
    try:
        return what()
    except IndexError:
        return otherwise


def create_metaRd_db(dbcon):
    """ Create an database to store R help pages.

    dbcon: database connection (assumed to be SQLite - may or may not work
           with other databases)
    """
    dbcon.execute(
        """
CREATE TABLE package (
name TEXT UNIQUE,
title TEXT,
version TEXT,
description TEXT
);
"""
        )
    dbcon.execute(
        """
CREATE TABLE rd_meta (
id INTEGER, file TEXT UNIQUE, name TEXT, type TEXT, title TEXT, encoding TEXT,
package_rowid INTEGER
);
"""
        )
    dbcon.execute('\nCREATE INDEX type_idx ON rd_meta (type);\n')
    dbcon.execute(
        '\nCREATE TABLE rd_alias_meta (\nrd_meta_rowid INTEGER, alias TEXT\n);\n'
        )
    dbcon.execute('\nCREATE INDEX alias_idx ON rd_alias_meta (alias);\n')
    dbcon.commit()


def _vax_to_ieee_single_float(data):
    """Converts a float in Vax format to IEEE format.

    Data should be a single string of chars that have been read in from
    a binary file. These will be processed 4 at a time into float values.
    Thus the total number of byte/chars in the string should be divisible
    by 4.

    Notes
    -----
    Based on VAX data organization in a byte file, we need to do a bunch of
    bitwise operations to separate out the numbers that correspond to the
    sign, the exponent and the fraction portions of this floating point
    number

    role :      S        EEEEEEEE      FFFFFFF      FFFFFFFF      FFFFFFFF
    bits :      1        2      9      10                               32
    bytes :     byte2           byte1               byte4         byte3

    Returns
    -------
    f : array
        Contains floats in IEEE format

    """
    f = []
    nfloat = int(len(data) / 4)
    for i in range(nfloat):
        byte2 = data[0 + i * 4]
        byte1 = data[1 + i * 4]
        byte4 = data[2 + i * 4]
        byte3 = data[3 + i * 4]
        sign = (byte1 & 128) >> 7
        expon = ((byte1 & 127) << 1) + ((byte2 & 128) >> 7)
        fract = ((byte2 & 127) << 16) + (byte3 << 8) + byte4
        if sign == 0:
            sign_mult = 1.0
        else:
            sign_mult = -1.0
        if 0 < expon:
            val = sign_mult * (0.5 + fract / 16777216.0) * pow(2.0, expon -
                128.0)
            f.append(val)
        elif expon == 0 and sign == 0:
            f.append(0)
        else:
            f.append(0)
    return f


@staticmethod
def accepted__aggregation_functions():
    """
        Returns the list of aggregation functions that may be
        applied on arrays.
        """
    return {'sum': 'Sum', 'average': 'Average'}


def int2name(i):
    """ Convert integer to Excel column name. """
    div = i + 1
    name = ''
    while div > 0:
        mod = (div - 1) % 26
        name = chr(65 + mod) + name
        div = (div - mod) // 26
    return name


def rank_selection(random, population, args):
    """Return a rank-based sampling of individuals from the population.

    This function behaves similarly to fitness proportionate selection,
    except that it uses the individual's rank in the population, rather
    than its raw fitness value, to determine its probability. This
    means that it can be used for both maximization and minimization
    problems, since higher rank can be defined correctly for both.

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

    Optional keyword arguments in args:

    - *num_selected* -- the number of individuals to be selected (default 1)

    """
    num_selected = args.setdefault('num_selected', 1)
    len_pop = len(population)
    population.sort()
    psum = list(range(len_pop))
    den = len_pop * (len_pop + 1) / 2.0
    for i in range(len_pop):
        psum[i] = (i + 1) / den
    for i in range(1, len_pop):
        psum[i] += psum[i - 1]
    selected = []
    for _ in range(num_selected):
        cutoff = random.random()
        lower = 0
        upper = len_pop - 1
        while upper >= lower:
            mid = (lower + upper) // 2
            if psum[mid] > cutoff:
                upper = mid - 1
            else:
                lower = mid + 1
        lower = max(0, min(len_pop - 1, lower))
        selected.append(population[lower])
    return selected


def import_element(node):
    """Set the properties on the given element, based on the given
        element schema interface. The node is the <condition /> or <action />
        root node. Settings are expected to be found in children of the node.
        """


def float_range(start, end, step=1.0, exceed=False):
    """Returns a range list of float"""
    l = []
    i = start
    if exceed:
        more = step
    else:
        more = 0.0
    while i < end + more:
        l.append(i)
        i += step
    return l


def navmesh_make():
    """Create navigation mesh for selected objects

    """
    pass


def report_task_progress(taskId=None, fields=None):
    """
    Task runners call ReportTaskProgress when assigned a task to acknowledge that it has the task. If the web service does not receive this acknowledgement within 2 minutes, it assigns the task in a subsequent  PollForTask call. After this initial acknowledgement, the task runner only needs to report progress every 15 minutes to maintain its ownership of the task. You can change this reporting time from 15 minutes by specifying a reportProgressTimeout field in your pipeline.
    If a task runner does not report its status after 5 minutes, AWS Data Pipeline assumes that the task runner is unable to process the task and reassigns the task in a subsequent response to  PollForTask . Task runners should call ReportTaskProgress every 60 seconds.
    See also: AWS API Documentation

    :example: response = client.report_task_progress(
        taskId='string',
        fields=[
            {
                'key': 'string',
                'stringValue': 'string',
                'refValue': 'string'
            },
        ]
    )

    :type taskId: string
    :param taskId: [REQUIRED]
            The ID of the task assigned to the task runner. This value is provided in the response for PollForTask .

    :type fields: list
    :param fields: Key-value pairs that define the properties of the ReportTaskProgressInput object.
            (dict) --A key-value pair that describes a property of a pipeline object. The value is specified as either a string value (StringValue ) or a reference to another object (RefValue ) but not as both.
            key (string) -- [REQUIRED]The field identifier.
            stringValue (string) --The field value, expressed as a String.
            refValue (string) --The field value, expressed as the identifier of another object.

    :rtype: dict
    :return: {
        'canceled': True|False
    }

    """
    pass


def num_columns(classification, df_group):
    """
    Get the columns number to plot.

    :param classification: (str) classification
    :param df_group: grouped dataframe.
    :return: number of columns to plot
    """
    if classification is None:
        return 2
    if df_group is None and classification is not None:
        return 4
    else:
        return 5


def addon_remove(module: str=''):
    """Delete the add-on from the file system

    :param module: Module, Module name of the add-on to remove
    :type module: str
    """
    pass


def slstrip(st, subst, require=False):
    """ Strip a substring `subst` from the left of `st` """
    if st.startswith(subst):
        return st[len(subst):]
    if require:
        raise ValueError('st does not start with subst', st, subst)
    return st


def lcp(s1, s2):
    """longest common prefix

    >>> lcp('abcdx', 'abcdy'), lcp('', 'a'), lcp('x', 'yz')
    (4, 0, 0)
    """
    i = 0
    for i, (c1, c2) in enumerate(zip(s1, s2)):
        if c1 != c2:
            return i
    return min(len(s1), len(s2))


def get_file_metadata(root):
    """Read and parse ReSpecTh XML file metadata (file author, version, etc.)

    Parameters
    ----------
    root : ``etree.Element``
        root of ReSpecTh XML file

    Returns
    -------
    properties : dict
        Dictionary with file metadata

    """
    properties = {}
    properties['file-authors'] = [{'name': '', 'ORCID': ''}]
    try:
        properties['file-authors'][0]['name'] = root.find('fileAuthor').text
    except AttributeError:
        print('Warning: no fileAuthor given')
    properties['file-version'] = '(1, 0)'
    elem = root.find('fileVersion')
    if elem is None:
        print('Warning: no fileVersion element')
    try:
        version = int(elem.find('major').text), int(elem.find('minor').text)
    except AttributeError:
        print('Warning: missing fileVersion major/minor')
    properties['file-version'] = str(version)
    properties['reference'] = {}
    elem = root.find('bibliographyLink')
    try:
        properties['reference']['citation'] = elem.attrib['preferredKey']
    except KeyError:
        print('Warning: missing preferredKey attribute in bibliographyLink')
    try:
        properties['reference']['doi'] = elem.attrib['doi']
    except KeyError:
        print('Warning: missing doi attribute in bibliographyLink')
    return properties


@staticmethod
def from_type_string(type_string):
    """
        Gives the parser class corresponding to the input type_string.

        Args:
            type_string (str): A string indicating the desired type of parser.
                Currently only 'api' and 'shell' types are supported, but 'shell' must be implemented by the inheriting
                class.

        Raises:
            NotImplementedError: Support for the 'shell' type is not currently implemented.
            AttributeError: Raised if the input type_string is not supported.

        Returns:
            The parser class corresponding to the input type_string.

        """
    if type_string == 'api':
        import parser.api_sphero_parser as api_sphero_parser
        return api_sphero_parser.Parser
    if type_string == 'shell':
        raise NotImplementedError
    else:
        raise AttributeError


@staticmethod
def stop():
    """Stops the finding process (subclass and implement as needed)."""


def catch_key_error(what, otherwise):
    """
    runs callable 'what' and catches KeyErrors, returning 'otherwise' if one occurred
    :param what: callable
    :param otherwise: alternate result in case of IndexError
    :return: result of 'what' or 'otherwise' in case of IndexError
    """
    try:
        return what()
    except KeyError:
        return otherwise


def mgmt_path(obj, *arg, **kw):
    """ Return the route_path inside the SDI for an object """


def clamp(value, min_value, max_value):
    """
    Returns *value* clamped to the range *min_value* to *max_value* inclusive.
    """
    return min(max_value, max(min_value, value))


def dupli_extrude_cursor(rotate_source: bool=True):
    """Duplicate and extrude selected vertices, edges or faces towards the mouse cursor

    :param rotate_source: Rotate Source, Rotate initial selection giving better shape
    :type rotate_source: bool
    """
    pass


@classmethod
def parse(cls, string):
    """
			Parse the entire supplied string as an instance of the present class.
			Mainly for internal use in unit tests because it drops through to match()
			in a convenient way.
		"""
    obj, i = cls.match(string, 0)
    if i != len(string):
        raise Exception("Could not parse '" + string + "' beyond index " +
            str(i))
    return obj


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

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

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


def run_parallel_processes(command_list: list, max_processes=-1):
    """
    Runs commands in a list in parallel and waits for them to complete

    :param max_processes:
    :param command_list:
    :return: list of commands that failed
    """
    import subprocess
    from tqdm import tqdm
    from functools import partial
    from multiprocessing import cpu_count
    from multiprocessing.dummy import Pool
    n = len(command_list)
    processor_pool_size = cpu_count() if n > cpu_count() else n
    processor_pool_size = (max_processes if max_processes > 0 else
        processor_pool_size)
    failed_commands = []
    pool = Pool(processor_pool_size)
    for i, response_code in tqdm(enumerate(pool.imap(partial(subprocess.
        call, shell=True), command_list)), total=n):
        if response_code != 0:
            failed_commands.append(command_list[i])
    return failed_commands


def identity(p):
    """Identity fnc, for flows that don't accept lambda (pickling etc).

    Parameters
    ----------
    p : object
        Input parameter.

    Returns
    -------
    object
        Same as `p`.

    """
    return p


def _normalize_response_tuple(tuple_):
    """
    Helper function to normalize view return values .
    It always returns (dict, status, headers). Missing values will be None.
    For example in such cases when tuple_ is
      (dict, status), (dict, headers), (dict, status, headers),
      (dict, headers, status)

    It assumes what status is int, so this construction will not work:
    (dict, None, headers) - it doesn't make sense because you just use
    (dict, headers) if you want to skip status.
    """
    v = tuple_ + (None,) * (3 - len(tuple_))
    return v if isinstance(v[1], int) else (v[0], v[2], v[1])


@classmethod
def isspace(cls, nextchar):
    """ Whether the next character is whitespace """
    return nextchar.isspace()


def warning_check_1(Vcell, I_Warning, I, warning_flag):
    """
    Check Vcell is negative or not.

    :param Vcell: Vcell of FC voltage
    :type Vcell : float
    :param I_Warning: first I of negative range
    :type I_Warning : float
    :param I: test current
    :type I : float
    :param warning_flag: input warning flag
    :type warning_flag : bool
    :return:  update warning_flag and I_Warning [bool,float]
    """
    if not warning_flag:
        try:
            if Vcell < 0:
                return [True, I]
            return [False, I]
        except Exception:
            return [False, I]
    else:
        return [True, I_Warning]


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

        :param ExportMembersReportFailType val:
        :rtype: EventType
        """
    return cls('export_members_report_fail', val)


@staticmethod
def _build_legacy_tag(format, version):
    """
        Legacy tags (prior to 0.5.5) dropped epochs and didn't honor the '~'

        >>> DebianGitRepository._build_legacy_tag('upstream/%(version)s', '1:2.0~3')
        'upstream/2.0.3'
        """
    if ':' in version:
        version = version.split(':', 1)[1]
    version = version.replace('~', '.')
    return format % dict(version=version)


@staticmethod
def _addCustomerTagOption(parser):
    """Adds the --customerTag option to the given parser
        The --customerTag is used by multiple commands so this common function
        can be used to add that command line option"""
    parser.add_argument('--customerTag', '-t', action='append', help=
        """Narrow down the matching resources by their tags. Multiple
            customer tags can be passed. Resources that contain all tags will
            be returned."""
        )


@staticmethod
def construct_default(flow):
    """Construct default predicate for edge.

        :param flow: flow to which predicate belongs to
        :type flow: Flow
        :rtype: Predicate
        """
    from .builtin_predicate import AlwaysTruePredicate
    return AlwaysTruePredicate(flow=flow)


def _make_mutant_node(nd):
    """Create a new logic for mutation that can be activated from .cfg file."""
    curent_rt_up = nd.rt_up
    curent_rt_down = nd.rt_down
    lowvar = '$Low_' + nd.name
    highvar = '$High_' + nd.name
    rt_up = (lowvar + ' ? 0 : (' + highvar + ' ? 1E308/$nb_mutable : (' +
        curent_rt_up + '))')
    rt_down = (highvar + ' ? 0 : (' + lowvar + ' ? 1E308/$nb_mutable : (' +
        curent_rt_down + '))')
    newNode = nd.copy()
    newNode.rt_up = rt_up
    newNode.rt_down = rt_down
    newNode.is_mutant = True
    return newNode


def extract_attr_for_match(items, **kwargs):
    """Helper method to get attribute value for an item matching some criterion.
  Specify target criteria value as dict, with target attribute having value -1

  Example:
    to extract state of vpc matching given vpc id

  response = [{'State': 'available', 'VpcId': 'vpc-2bb1584c'}]
  extract_attr_for_match(response, State=-1, VpcId='vpc-2bb1584c') #=> 'available'"""
    query_arg = None
    for arg, value in kwargs.items():
        if value == -1:
            assert query_arg is None, 'Only single query arg (-1 valued) is allowed'
            query_arg = arg
    result = []
    filterset = set(kwargs.keys())
    for item in items:
        match = True
        assert filterset.issubset(item.keys()
            ), 'Filter set contained %s which was not in record %s' % (
            filterset.difference(item.keys()), item)
        for arg in item:
            if arg == query_arg:
                continue
            if arg in kwargs:
                if item[arg] != kwargs[arg]:
                    match = False
                    break
        if match:
            result.append(item[query_arg])
    assert len(result) <= 1, '%d values matched %s, only allow 1' % (len(
        result), kwargs)
    if result:
        return result[0]
    return None


def line_break():
    """Insert line break at cursor position

    """
    pass


@staticmethod
def increment(number=0):
    """Increment an integer by one.

        Parameters
        ----------
        number: :class: `int`
            integer that should be incremented

        """
    incremented = number + 1
    return incremented


def restart_process(modeladmin, request, queryset):
    """
    restarts a dedicated process
    :return:
    """
    for process in queryset:
        process.restart()


@staticmethod
def is_collapsed(block):
    """
        Checks if the block is expanded or collased.

        :param block: QTextBlock
        :return: False for an open trigger, True for for closed trigger
        """
    if block is None:
        return False
    state = block.userState()
    if state == -1:
        state = 0
    return bool(state & 134217728)


@classmethod
def register_options_on_scope(cls, options):
    """Trigger registration of this optionable's options.

        Subclasses should not generally need to override this method.
        """
    cls.register_options(options.registration_function_for_optionable(cls))


def _getDictWithKey(key, dict_list):
    """ Returns the first dictionary in dict_list which contains the given key"""
    for d in dict_list:
        if key in d:
            return d
    return None


def ok():
    """Is this feed ok to display?"""


def _get_backup_name(basename):
    """
    Create a name for a current backup, including timestamp suffix.
    """
    from datetime import datetime
    return '{}_{}'.format(basename, datetime.now().replace(microsecond=0).
        isoformat().replace(':', '-'))


def loadLanguage(filename):
    """This function loads up a language configuration file and returns
	the configuration to be passed to the syllabify function."""
    L = {'consonants': [], 'vowels': [], 'onsets': []}
    f = open(filename, 'r')
    section = None
    for line in f:
        line = line.strip()
        if line in ('[consonants]', '[vowels]', '[onsets]'):
            section = line[1:-1]
        elif section == None:
            raise ValueError(
                'File must start with a section header such as [consonants].')
        elif not section in L:
            raise ValueError('Invalid section: ' + section)
        else:
            L[section].append(line)
    for section in ('consonants', 'vowels', 'onsets'):
        if len(L[section]) == 0:
            raise ValueError(
                'File does not contain any consonants, vowels, or onsets.')
    return L


def ratio2int(p, k):
    """Returns p * k if k < 1 else k

    Result is cast to nearest integer in [1, p]

    Parameters:
    -----------
    p : int

    k : int or float

    >>> ratio2int(10, 1)
    1
    >>> ratio2int(10, 1.0)
    1
    >>> ratio2int(10, .99)
    10
    >>> ratio2int(12, 3)
    3
    >>> ratio2int(10, 15)
    10
    >>> ratio2int(10, 0)
    1
    >>> ratio2int(10, 0.5)
    5
    >>> ratio2int(10, 0.1)
    1
    >>> ratio2int(10, 0.01)
    1
    >>> ratio2int(87, np.float64(0.8))
    70
    """
    return min(max(int(round(p * k if k < 1 else k)), 1), p)


def getComponents(glyph):
    """Answers the list of components for this glyph."""
    if glyph is not None:
        if hasattr(glyph, '_components'):
            return glyph._components
        elif hasattr(glyph, 'components'):
            return glyph.components
    return None


def build_reverse_dictionary(word_to_id):
    """Given a dictionary that maps word to integer id.
    Returns a reverse dictionary that maps a id to word.

    Parameters
    ----------
    word_to_id : dictionary
        that maps word to ID.

    Returns
    --------
    dictionary
        A dictionary that maps IDs to words.

    """
    reverse_dictionary = dict(zip(word_to_id.values(), word_to_id.keys()))
    return reverse_dictionary


def int_one(vals):
    """ Return an integer value of 1
    """
    return int(1)


def createSurveyEventHandler(ob, event):
    """Initialise the survey"""
    if 'acl_users' not in ob.objectIds():
        ob.createLocalPas()
    try:
        ob.aq_inner.aq_base.respondents
    except AttributeError:
        ob.reset()


def list_recent_downloads():
    """Return a list of IDownloadStatus objects for the most recently
        started downloads."""


def mac(dic, data, macro=None, noRd=False, noWr=False, all=False, **kwargs):
    """
    Dispatcher similar to the MAC command.

    Parameters
    ----------
    dic : dict
        Dictionary of NMRPipe parameters
    data : ndarray
        Array of NMR data.
    macro : callable
        Python function to apply.
    kwargs : keyword arguments
        Keyword arguments that get passed to the macro

    Returns
    -------
    ndic : dict
        Dictionary of updated NMRPipe parameters.
    ndata : ndarray
        Array of data with macro function applied.

    Notes
    -----
    This is not intended to be a true macro interpreter.  Instead, the purpose
    is to act as a dispatch mechanism to other Python code so that the
    look and feel of nmrPipe is maintained.  The -var and -str parameters
    are not used, as they can be passed directly to the macro as keyword
    arguements.
    """
    if macro is None:
        return dic, data
    if noRd and noWr:
        return macro(dic, data, **kwargs)
    raise NotImplementedError('Only noRd and noWr macros work for now.')


def save(frames, path, duration=100):
    """
    Save decorated frames to an animated gif.

    - frames (list): collection of frames built with the frame decorator
    - path (str): filename with relative or absolute path
    - duration (int): milliseconds between frames
    """
    frames[0].save(path, save_all=True, append_images=frames[1:], optimize=
        True, duration=duration, loop=0)


def get_circle_rect(center_point, radius):
    """Returns the rectangle containing a circle with given centre and radius.

    :param center_point: the center of the circle
    :param radius: the radius of the circle
    :return: tuple containing (`top_left_x`, `top_left_y`, `width`, `height`) of the rectangle.
    """
    center_x, center_y = center_point
    return center_x - radius, center_y - radius, radius * 2, radius * 2


def is_ntuple(L, *types):
    """
    Checks whether the object L is an n-element tuple throughout.
    """
    if isinstance(L, (list, tuple)):
        if len(L) == len(types):
            for elem, t in zip(L, types):
                if not isinstance(elem, t):
                    raise TypeError("'L' element {} is not of type {}".
                        format(elem, t))
        else:
            raise ValueError('L must be the same length as type list')
    else:
        raise TypeError("'L' must be of type [list, tuple]")


def update_conditional_forwarder(DirectoryId=None, RemoteDomainName=None,
    DnsIpAddrs=None):
    """
    Updates a conditional forwarder that has been set up for your AWS directory.
    See also: AWS API Documentation

    :example: response = client.update_conditional_forwarder(
        DirectoryId='string',
        RemoteDomainName='string',
        DnsIpAddrs=[
            'string',
        ]
    )

    :type DirectoryId: string
    :param DirectoryId: [REQUIRED]
            The directory ID of the AWS directory for which to update the conditional forwarder.

    :type RemoteDomainName: string
    :param RemoteDomainName: [REQUIRED]
            The fully qualified domain name (FQDN) of the remote domain with which you will set up a trust relationship.

    :type DnsIpAddrs: list
    :param DnsIpAddrs: [REQUIRED]
            The updated IP addresses of the remote DNS server associated with the conditional forwarder.
            (string) --

    :rtype: dict
    :return: {}

    """
    pass


def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy."""
    z = x.copy()
    z.update(y)
    return z


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

        :param list of [str] val:
        :rtype: GroupMembersRemoveError
        """
    return cls('users_not_found', val)


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 et_actual_mm(e_24_mm, t_24_mm):
    """
    Computes the actual evapotranspiration based on the separate calculations
    of evaporation and transpiration:

    .. math ::
        ET = E + T

    Parameters
    ----------
    e_24_mm : float
        daily evaporation in mm
        :math:`E`
        [mm d-1]
    t_24_mm : float
        daily transpiration in mm
        :math:`T`
        [mm d-1]

    Returns
    -------
    et_24_mm : float
        daily evapotranspiration in mm
        :math:`ET`
        [mm d-1]
    """
    return e_24_mm + t_24_mm


def intro_interps(toc, reg_part):
    """Logic to fill in any introduction headers for the entire
    interpretations. Note that at some point, we might have headers randomly
    appear elsewhere in the interpretations, unrelated to a specific
    section. That's a @todo."""
    elements = []
    for el in toc.get(reg_part + '-Interp', []):
        if el['index'][1] == 'Interp':
            elements.append({'label': 'Interpretations', 'sub_label': el[
                'title'], 'index': el['index'], 'section_id': '-'.join(el[
                'index'])})
    return elements


def validate_file(file):
    """
    Valida que una variable refiera a una instancia de un archivo.

    :file: [any] - Elemento a validar

    :return: [Boolean] - True si es una instancia de archivo, False en caso contrario
    """
    return hasattr(file, 'read')


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 references_to_json(resources, references):
    """ Make a JSON/catalog representation of the references db,
     including the count for each """
    dump_references = {}
    for reftype, refvalue in references.items():
        dump_references[reftype] = {}
        for label, reference_resource in refvalue.items():
            target_count = len(reference_resource.get_sources(resources))
            dump_references[reftype][label] = dict(count=target_count,
                docname=reference_resource.docname)
    return dump_references


def get_length_breakdown(model, property_ids=None, stop_if_no_length=True):
    """
    Gets a breakdown of the length by property region.

    Returns
    -------
    pids_to_length : Dict[int pid] : float length
        the pid to length dictionary

    TODO: What about CONRODs?

    """
    skip_props = {'PSOLID', 'PLPLANE', 'PPLANE', 'PELAS', 'PDAMP', 'PBUSH',
        'PBUSH1D', 'PBUSH2D', 'PELAST', 'PDAMPT', 'PBUSHT', 'PDAMP5',
        'PFAST', 'PGAP', 'PRAC2D', 'PRAC3D', 'PCONEAX', 'PLSOLID', 'PCOMPS',
        'PVISC', 'PSHELL', 'PCOMP', 'PCOMPG', 'PSHEAR', 'PIHEX', 'PBEND',
        'PACABS', 'PAABSF', 'PACBAR'}
    bar_properties = {'PBAR', 'PBARL', 'PBEAM', 'PBEAML', 'PROD', 'PTUBE',
        'PBRSECT', 'PBMSECT', 'PBCOMP', 'PBEAM3'}
    pid_eids = model.get_element_ids_dict_with_pids(property_ids,
        stop_if_no_eids=stop_if_no_length, msg=
        ' which is required by get_length_breakdown')
    pids_to_length = {}
    for pid, eids in pid_eids.items():
        prop = model.properties[pid]
        lengths = []
        if prop.type in skip_props:
            continue
        elif prop.type in bar_properties:
            for eid in eids:
                elem = model.elements[eid]
                try:
                    lengths.append(elem.Length())
                except AttributeError:
                    print(prop)
                    print(elem)
                    raise
        else:
            print('prop\n%s' % prop)
            eid0 = eids[0]
            elem = model.elements[eid0]
            msg = str(prop) + str(elem)
            raise NotImplementedError(msg)
        if lengths:
            pids_to_length[pid] = sum(lengths)
    has_length = len(pids_to_length)
    if not has_length:
        msg = 'No elements with length were found'
        model.log.warning(msg)
        if stop_if_no_length:
            raise RuntimeError(msg)
    return pids_to_length


def F3d(state, qubit):
    """
    Applies a rotation (F3^{\\dagger}) about a stabilizer octahedron face to stabilizers and destabilizers

    X -> -Z
    Z -> -iW = -Y
    W -> -iX
    Y -> X
    """
    stabs = state.stabs
    stabs.signs_minus ^= stabs.col_x[qubit] | stabs.col_z[qubit]
    gens_common = stabs.signs_i & stabs.col_z[qubit]
    gens_only_z = stabs.col_z[qubit] - stabs.signs_i
    stabs.signs_minus ^= gens_common
    stabs.signs_i -= gens_common
    stabs.signs_i |= gens_only_z
    for gens in state.gen_list:
        xonly = gens.col_x[qubit] - gens.col_z[qubit]
        zonly = gens.col_z[qubit] - gens.col_x[qubit]
        xzshared = gens.col_x[qubit] & gens.col_z[qubit]
        for i in xzshared:
            gens.row_z[i].discard(qubit)
        for i in zonly:
            gens.row_x[i].add(qubit)
        for i in xonly:
            gens.row_x[i].discard(qubit)
            gens.row_z[i].add(qubit)
        gens.col_x[qubit], gens.col_z[qubit] = gens.col_z[qubit], gens.col_x[
            qubit]
        gens.col_z[qubit] ^= gens.col_x[qubit]


def simpleSubs(expr, substitutions, *args, **kwarg):
    """Perform expression substitution, ignoring derivatives."""
    if expr in substitutions:
        return substitutions[expr]
    elif not expr.args:
        return expr


@staticmethod
def cidr_to_netmask(cidr):
    """
        Converts a CIDR Network string to full blown IP/Subnet format in decimal format.
        Decided not use IP Address module to keep includes to a minimum.

        :param cidr: String object in CIDR format to be processed
        :type cidr: str

        :return: A string object that looks like this "x.x.x.x/y.y.y.y"
        :rtype: str
        """
    if isinstance(cidr, str):
        cidr = int(cidr)
        mask = 4294967295 >> 32 - cidr << 32 - cidr
        return str((4278190080 & mask) >> 24) + '.' + str((16711680 & mask) >>
            16) + '.' + str((65280 & mask) >> 8) + '.' + str(255 & mask)


def first_occurences(iterable):
    """
    Given an iterable, return a generator of value first occurences only.
    """
    seen = set()
    for x in iterable:
        if x not in seen:
            seen.add(x)
            yield x


@classmethod
def from_jsondict(cls, jsondict):
    """ initialize a DimArray from a json-compatible dictionary
        """
    jsondict = jsondict.copy()
    dima = cls(jsondict.pop('values', None), axes=jsondict.pop('labels',
        None), dims=jsondict.pop('dims', None))
    if 'meta' in jsondict:
        dima._metadata(jsondict['meta'])
    return dima


def flatten(iterable):
    """
    Flatten a sequence, returning a sequence of all its items' items.

    For example, `flatten([[1, 2], [3], [4, 'meow']]) == [1, 2, 3, 4, 'meow']`.
    """
    iterator = iter(iterable)
    try:
        first_item = next(iterator)
    except StopIteration:
        return []
    return sum(iterator, first_item)


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


def ask(prompt: str='', default: str='') ->str:
    """Print the ``prompt``, get user's answer, return it -- or a default."""
    if prompt:
        if default:
            prompt = prompt + ' [' + default + ']'
        prompt = prompt + ' '
    answer = None
    while not answer:
        answer = input(prompt)
        if default and not answer:
            return default
    return answer