def _lmax(a, r):
    """
    Utility function giving the maximal value of the harmonic index `\\ell`
    for tabulated values of `Z^\\infty_{\\ell m}(r)`.

    INPUT:

    - ``a`` -- BH angular momentum parameter (in units of `M`, the BH mass)
    - ``r`` -- areal radius of the orbit (in units of `M`)

    OUTPUT:

    - maximal value of `\\ell` for which `Z^\\infty_{\\ell m}(r)` is tabulated

    EXAMPLES::

        sage: from kerrgeodesic_gw.zinf import _lmax
        sage: _lmax(0, 6.)
        10
        sage: _lmax(0, 40.)
        5
        sage: _lmax(0.9, 12.)
        10
        sage: _lmax(0.95, 12.)
        5

    """
    r_high_l = 20.0 if a <= 0.9 else 10.0
    l_max = 10 if r <= r_high_l else 5
    return l_max


def checkread(stream, n):
    """Read exactly *n* bytes from *stream*.

    A ParseError is raised if less than *n* bytes are available.

    """
    data = stream.read(n)
    if len(data) < n:
        raise ValueError('unexpected end of file')
    return data


def get_style(kwargs):
    """
    Return the style of this widget.
    """
    style = kwargs.get('style', 'horizontal')
    valid_styles = ['horizontal', 'vertical']
    if style not in valid_styles:
        raise ValueError('{0} is not a valid form style!'.format(style))
    return style


def clean_url(url):
    """Convert user input URL to clean URL."""
    if url.endswith('/api/'):
        url = url[:-5]
    elif url.endswith('/api'):
        url = url[:-4]
    elif url.endswith('/'):
        url = url[:-1]
    return url


def _get_check_id(index, *args, **kwargs):
    """Return the check ID in args or kwargs."""
    try:
        return args[int(index)]
    except ValueError:
        return kwargs[str(index)]


def get_counts(group, category):
    """
    >>> get_counts([[1,2],[2,3],[2,5],[3,6]], 2)
    (3, 1)
    """
    positive_counts = sum(1 for x in group if category in x)
    return positive_counts, len(group) - positive_counts


def get_full_action_name(service, action_name):
    """
    Gets the proper formatting for an action - the service, plus colon, plus action name.
    :param service: service name, like s3
    :param action_name: action name, like createbucket
    :return: the resulting string
    """
    action = service + ':' + action_name
    return action


def _delete_not_existing_keywords(indexer, keywords_api, keywords_db):
    """Delete not existing keywords."""
    to_soft_delete = []
    keys_loaded = keywords_api.keys()
    for keyword in keywords_db:
        if keyword['deleted'] is False and keyword['key_id'
            ] not in keys_loaded:
            keyword['deleted'] = True
            keyword.commit()
            to_soft_delete.append(str(keyword.id))
    indexer.bulk_index(iter(to_soft_delete))


def val_test(arr, min_range):
    """ Does the vertical range of arr (1D) exceed min_range?

        args:
            arr                   # numpy.array()
            min_range             # float64

        return:
            bool
    """
    rng = abs(arr.max() - arr.min())
    return rng > min_range


def return_small_clade(treenode):
    """used to produce balanced trees, returns a tip node from the smaller clade"""
    node = treenode
    while 1:
        if node.children:
            c1, c2 = node.children
            node = sorted([c1, c2], key=lambda x: len(x.get_leaves()))[0]
        else:
            return node


def parse_ignore_file(filename, dirname):
    """
    Parse the ignore file and return a list of ignore patterns.
    Each pattern has the complete file path so we can take into account ignore at different levels.
    :param filename: The name of the ignore file.
    :param dirname: The directory Path where the ignore file was found.
    :return: List of ignore patterns.
    """
    ignore_list = []
    with open(filename) as ignore_file:
        for x in ignore_file.readlines():
            x = x.strip()
            if x == '' or x[0] == '#':
                continue
            pattern = str(dirname / x)
            if x[-1] == '/':
                pattern += '/'
            if pattern[-1] == '/':
                ignore_list.append(pattern[:-1])
                pattern += '*'
            ignore_list.append(pattern)
    return ignore_list


def get_kernel_option(option):
    """Get a dictionary of args for the given kernel command line option"""
    args = {}
    try:
        cmdline = open('/proc/cmdline').read().split()
    except IOError:
        return args
    for cmd in cmdline:
        if '=' in cmd:
            optName, optArgs = cmd.split('=', 1)
        else:
            optName = cmd
            optArgs = ''
        if optName == option:
            for arg in optArgs.split(','):
                if ':' in arg:
                    k, v = arg.split(':', 1)
                    args[k] = v
                else:
                    args[arg] = ''
    return args


def store_callback(option, opt_str, value, parser, *args, **kwargs):
    """Implement optparse's "store" action as a callback."""
    setattr(parser.values, option.dest, value)


def exprToStr(expr):
    """ Convert a sympy expression to a string for BOUT++ input
    """
    s = str(expr).replace('**', '^')
    s = s.replace('(1.0*', '(')
    s = s.replace(' 1.0*', ' ')
    return s


def filter_parameters_to_dict(parameters, param_name):
    """Filters list of parameters for given parameter name suffix."""
    filtered_params = {}
    suffix = '::{0}'.format(param_name)
    for param in parameters:
        if param['name'].endswith(suffix):
            filtered_params[param['name'].replace(suffix, '')] = param['value']
    return filtered_params


@classmethod
def flip(class_, align, dir):
    """Flip p_align(ment) if p_dir indicates a right-to-left language"""
    if dir == 'ltr':
        return align
    if align == 'left':
        return 'right'
    if align == 'right':
        return 'left'
    return align


def __iter__():
    """
        Return iterable over group keys (login name strings).
        """


def total_seconds(td):
    """Since ``timedelta.total_seconds()`` is new in 2.7"""
    return float(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6
        ) / 10 ** 6


def grep(filename, tag, firstOccurrence=False):
    """Greps the line that starts with a specific `tag` string inside the file."""
    import re
    try:
        afile = open(filename, 'r')
    except:
        print('Error in utils.grep(): cannot open file', filename)
        raise RuntimeError()
    content = None
    for line in afile:
        if re.search(tag, line):
            content = line.split()
            if firstOccurrence:
                break
    if content:
        if len(content) == 2:
            content = content[1]
        else:
            content = content[1:]
    afile.close()
    return content


def align():
    """Align selected bones to the active bone (or to their parent)

    """
    pass


@classmethod
def fromkeys(cls, iterable, value=None):
    """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
        and values equal to v (which defaults to None).

        """
    d = cls()
    for key in iterable:
        d[key] = value
    return d


def cluster_replace_nodes(base, cluster_id, nodes, expected_status=
    'SUCCEEDED', wait_timeout=None):
    """Utility function that replace nodes of cluster."""
    params = {'replace_nodes': {'nodes': nodes}}
    res = base.client.cluster_replace_nodes('clusters', cluster_id, params=
        params)
    action_id = res['location'].split('/actions/')[1]
    res = base.client.wait_for_status('actions', action_id, expected_status,
        wait_timeout)
    return res['body']['status_reason']


def add_file(name, uploadable, metadata=None, overwrite=True, progress=None):
    """I upload a file (using the given IUploadable), then attach the
        resulting ImmutableFileNode to the directory at the given name. I set
        metadata the same way as set_uri and set_node. The child name must be
        a unicode string.

        ``progress`` either provides IProgress or is None

        I return a Deferred that fires (with the IFileNode of the uploaded
        file) when the operation completes."""


def nmget(o, key_path, def_val=None, path_delimiter='.', null_as_default=True):
    """
    A short-hand for retrieving a value from nested mappings
    ("nested-mapping-get").  At each level it checks if the given "path"
    component in the given key exists and return the default value whenever
    fails.

    Example:
    >>> o = {'a':{'b':1}, 'x': None}
    >>> nmget(o, 'a', 0)
    {'b': 1}
    >>> nmget(o, 'a.b', 0)
    1
    >>> nmget(o, 'a/b', 0, '/')
    1
    >>> nmget(o, 'a.c', 0)
    0
    >>> nmget(o, 'x', 0)
    0
    >>> nmget(o, 'x', 0, null_as_default=False)
    None
    """
    pieces = key_path.split(path_delimiter)
    while pieces:
        p = pieces.pop(0)
        if o is None or p not in o:
            return def_val
        o = o[p]
    if o is None and null_as_default:
        return def_val
    return o


def _default_to(check, default, comparator=None):
    """ If check is None, apply default; else, return check.
    """
    if comparator is None:
        if check is None:
            return default
        else:
            return check
    elif check == comparator:
        return default
    else:
        return check


@classmethod
def WithData(cls, original_exc, model, fk, field_value):
    """
        Factory method for creating a deserialization error which has a more
        explanatory message.
        """
    return cls("%s: (%s:pk=%s) field_value was '%s'" % (original_exc, model,
        fk, field_value))


def include_latexdefs(name):
    """This function is used to include latex user definitions
    in the html template, using the syntax
    {{ include_latexdefs('latexdefs.tex') }}
    This function is included in jinja2 environment"""
    text = ''
    try:
        with open(name) as f:
            for line in f:
                text += '$' + line[:-1] + '$\n'
    except:
        pass
    return text


def features(sentence, i):
    """Features for i'th token in sentence.

    Currently baseline named-entity recognition features, but these can
    easily be changed to do POS tagging or chunking.
    """
    word = sentence[i]
    yield 'word:{}' + word.lower()
    if word[0].isupper():
        yield 'CAP'
    if i > 0:
        yield 'word-1:{}' + sentence[i - 1].lower()
        if i > 1:
            yield 'word-2:{}' + sentence[i - 2].lower()
    if i + 1 < len(sentence):
        yield 'word+1:{}' + sentence[i + 1].lower()
        if i + 2 < len(sentence):
            yield 'word+2:{}' + sentence[i + 2].lower()


def get_function_signature(f, d=None):
    """
    returns the signature of a bound c function
    """
    if d is None:
        d = {}
    return d.get(f, f'function not found: {f}')


def peer():
    """Returns an object conforming to this interface.

        Most implementations will ``return self``.
        """


def get_outgoing_edges(dfg):
    """
    Gets outgoing edges of the provided DFG graph
    """
    outgoing = {}
    for el in dfg:
        if type(el[0]) is str:
            if not el[0] in outgoing:
                outgoing[el[0]] = {}
            outgoing[el[0]][el[1]] = dfg[el]
        else:
            if not el[0][0] in outgoing:
                outgoing[el[0][0]] = {}
            outgoing[el[0][0]][el[0][1]] = el[1]
    return outgoing


def triangle_area(p1, p2, p3):
    """
    calculates the area of a triangle given its vertices
    """
    return abs(p1[0] * (p2[1] - p3[1]) + p2[0] * (p3[1] - p1[1]) + p3[0] *
        (p1[1] - p2[1])) / 2.0


def polybuild_face_at_cursor_move(MESH_OT_polybuild_face_at_cursor=None,
    TRANSFORM_OT_translate=None):
    """Undocumented contribute <https://developer.blender.org/T51061>

    :param MESH_OT_polybuild_face_at_cursor: Poly Build Face at Cursor
    :param TRANSFORM_OT_translate: Move, Move selected items
    """
    pass


def get_min_samples(N):
    """Get the `min_samples` attribute based on the number of
    users who have transcribed the subject.  These values were
    found based on example data from ASM.

    Parameters
    ----------
    N : integer
        The number of users who have see the subject

    Returns
    -------
    min_samples : integer
        The value to use for the min_samples keyword in OPTICS
    """
    if N <= 6:
        return 2
    elif N <= 10:
        return 3
    elif N <= 15:
        return 4
    elif N <= 20:
        return 5
    else:
        return int(0.25 * N)


def SetDefaultColoring(state):
    """Set coloring behavior to |state|.

  This is useful for overriding config options via the command line.
  """
    if state is None:
        return
    global DEFAULT
    state = state.lower()
    if state in ('auto',):
        DEFAULT = state
    elif state in ('always', 'yes', 'true', True):
        DEFAULT = 'always'
    elif state in ('never', 'no', 'false', False):
        DEFAULT = 'never'


@classmethod
def get_allowances_for_user(cls, exam_id, user_id):
    """
        Returns an allowances for a user within a given exam
        """
    return cls.objects.filter(proctored_exam_id=exam_id, user_id=user_id)


def get_percent(numerator, denominator):
    """
    Generates the percentage of the numerator over the denominator
    """
    return numerator / denominator * 100


@staticmethod
def s(s):
    """Format input as str w/ appropriate quote types for python cli entry.

        Examples
        --------
            list, tuple -> "['one', 'two']"
            dict -> "{'key': 'val'}"
            int, float, None -> '0'
            str, other -> 'string'
        """
    if isinstance(s, (list, tuple, dict)):
        return '"{}"'.format(s)
    elif not isinstance(s, (int, float, type(None))):
        return "'{}'".format(s)
    else:
        return '{}'.format(s)


def get_size():
    """Return the length (in bytes) of the data this node represents. For
        directory nodes, I return the size of the backing store. I return
        synchronously and do not consult the network, so for mutable objects,
        I will return the most recently observed size for the object, or None
        if I don't remember a size. Use get_current_size, which returns a
        Deferred, if you want more up-to-date information."""


def weld():
    """Weld selected UV vertices together

    """
    pass


def db2amp(db: float) ->float:
    """
    convert dB to amplitude (0, 1)

    db: a value in dB
    """
    return 10.0 ** (0.05 * db)


def to_filename(name):
    """Convert a project or version name to its filename-escaped form

    Any '-' characters are currently replaced with '_'.
    """
    return name.replace('-', '_')


@staticmethod
def max_none(a, b):
    """A max() version that discards None values."""
    if a is None:
        return b
    if b is None:
        return a
    return max(a, b)


def precision_from_tpr_fpr(tpr, fpr, positive_prior):
    """
    Computes precision for a given positive prevalence from TPR and FPR
    """
    return positive_prior * tpr / (positive_prior * tpr + (1 -
        positive_prior) * fpr)


def delete_platform_application(PlatformApplicationArn=None):
    """
    Deletes a platform application object for one of the supported push notification services, such as APNS and GCM. For more information, see Using Amazon SNS Mobile Push Notifications .
    See also: AWS API Documentation

    :example: response = client.delete_platform_application(
        PlatformApplicationArn='string'
    )

    :type PlatformApplicationArn: string
    :param PlatformApplicationArn: [REQUIRED]
            PlatformApplicationArn of platform application object to delete.

    """
    pass


def reverse_aliases(aliases):
    """Reverse an `aliases` dict.

    Input:   key: canonical name,  value: list of aliases
    Output:  key: alias,           value: canonical name

    Examples
    --------

    >>> aliases = {
    ...     'J Doe <jdoe@a.com>':['Johnny <jdoe@b.edu>', 'J'],
    ...     'JJJ Smith <jjjs@a.com>':['Jingly <jjjs@b.edu>'],
    ...     None:['Anonymous <a@a.com>'],
    ...     }
    >>> r = reverse_aliases(aliases)
    >>> for item in sorted(r.items()):
    ...     print(item)
    ('Anonymous <a@a.com>', None)
    ('J', 'J Doe <jdoe@a.com>')
    ('Jingly <jjjs@b.edu>', 'JJJ Smith <jjjs@a.com>')
    ('Johnny <jdoe@b.edu>', 'J Doe <jdoe@a.com>')
    """
    output = {}
    for canonical_name, _aliases in aliases.items():
        for alias in _aliases:
            output[alias] = canonical_name
    return output


def project_opened(project):
    """This function is called after opening the project"""


def _get_mac_address_from_sysfs(ifname):
    """
    Fetch the mac address of an interface from sysfs.
    This is a workaround for https://bugzilla.redhat.com/1786937.
    """
    mac = None
    sysfs_path = f'/sys/class/net/{ifname}/address'
    try:
        with open(sysfs_path) as f:
            mac = f.read().rstrip('\n')
    except FileNotFoundError:
        pass
    return mac


def entity_from_primary_key(pkname):
    """Given the name of a primary key, return the mapped entity.

    :param pkname: the name of a primary key
    :rtype: a mapped class
    """
    from sqlalchemy.orm.mapper import _mapper_registry
    for m in list(_mapper_registry):
        if len(m.primary_key) == 1 and m.primary_key[0].name == pkname:
            return m.class_
    raise RuntimeError('Unknown PK: %s' % pkname)


@classmethod
def get_version_naive(cls, name, ignore=''):
    """ Checks a string for a possible version of an object (no prefix, no suffix) without filtering date out
            Assumes only up to 4 digit padding

        :param name: str, string that represents a possible name of an object
        :return: (float, int, list(str), None), gets the version number then the string matches
        """
    match = cls._get_regex_search(name, cls.REGEX_VERSION.format(SEP=cls.
        REGEX_SEPARATORS), ignore=ignore)
    if match is not None:
        if len(match) > 1:
            for m in match:
                m.update({'version': int(m['match'].upper().replace('V', ''))})
            compound_version = '.'.join([str(m['version']) for m in match])
            compound_version = float(compound_version
                ) if compound_version.count('.') == 1 else compound_version
            return {'compound_matches': match, 'compound_version':
                compound_version, 'pattern': match[0]['pattern'], 'input':
                match[0]['input']}
        elif len(match) == 1:
            match = match[0]
            match.update({'version': int(match['match'].upper().replace('V',
                ''))})
            return match
    return None


def _headercorrected(hdr):
    """Handle keywords that have been renamed."""
    i = 1
    while 'COM%03d' % i in hdr:
        value = hdr['COM%03d' % i]
        comment = hdr.cards['COM%03d' % i].comment
        hdr['COMMENT'] = '[%s] %s' % (comment, value)
        del hdr['COM%03d' % i]
        i += 1
    i = 1
    while 'HIST%03d' % i in hdr:
        value = hdr['HIST%03d' % i]
        comment = hdr.cards['HIST%03d' % i].comment
        hdr['HISTORY'] = '%s (%s)' % (value, comment)
        del hdr['HIST%03d' % i]
        i += 1
    if 'ORIGIN' in hdr.keys():
        hdr.rename_keyword('ORIGIN', 'FROM')
    if 'ORIGIN_V' in hdr.keys():
        hdr.rename_keyword('ORIGIN_V', 'FROM_V')
    if 'SOURCE_V' in hdr.keys():
        hdr.rename_keyword('SOURCE_V', 'FORMAT')
    if 'SRC_VERS' in hdr.keys():
        hdr.rename_keyword('SRC_VERS', 'SRC_V')


def clear():
    """Remove all language code mappings."""


@classmethod
def trim_unsupported_chars(cls, string: str) ->str:
    """trim non-font characters"""
    s = string
    for char in ['\x1b', '\\u001b', '\x1b']:
        s = s.replace(char, '')
    return s


def run():
    """    The ``gunicorn`` command line runner for launching Gunicorn with
    generic WSGI applications.
    """
    from gunicorn.app.wsgiapp import WSGIApplication
    WSGIApplication('%(prog)s [OPTIONS] [APP_MODULE]').run()


def is_new_session(handler_input):
    """Return if the session is new for the input request.

    The method retrieves the ``new`` value from the input request's
    session, which indicates if it's a new session or not. The
    :py:class:`ask_sdk_model.session.Session` is only included on all
    standard requests except ``AudioPlayer``, ``VideoApp`` and
    ``PlaybackController`` requests. More information can be found here :
    https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#session-object

    A :py:class:`TypeError` is raised if the input request doesn't have
    the ``session`` information.

    :param handler_input: The handler input instance that is generally
        passed in the sdk's request and exception components
    :type handler_input: ask_sdk_core.handler_input.HandlerInput
    :return: Boolean if the session is new for the input request
    :rtype: bool
    :raises: TypeError if the input request doesn't have a session
    """
    session = handler_input.request_envelope.session
    if session is not None:
        return session.new
    raise TypeError("The provided request doesn't have a session")


def __sub__(other):
    """Either a DateTime or a number may be subtracted from a
        DateTime, however, a DateTime may not be subtracted from a
        number."""


@staticmethod
def gen_fibonacci():
    """Yield the next Fibonacci number.

        Based on https://www.python-course.eu/generators.php
        Starts at Fibonacci number 3 (the second 1)

        Yields
        ------
        int
            The next Fibonacci number

        .. versionadded:: 0.3.0
        .. versionchanged:: 0.3.6
            Encapsulated in class

        """
    num_a, num_b = 1, 2
    while True:
        yield num_a
        num_a, num_b = num_b, num_a + num_b


def SizeBenefitAccDth(t):
    """Accidental death benefit per policy"""
    return 0


def write_to_file(path, contents):
    """Write the given contents to a file

    :param path: Destination file
    :param contents: Desired contents of the file
    """
    with open(path, 'w') as f:
        f.write(contents)


def confusion_matrix(classify=lambda document: False, documents=[(None, False)]
    ):
    """ Returns the performance of a binary classification task (i.e., predicts True or False)
        as a tuple of (TP, TN, FP, FN):
        - TP: true positives  = correct hits,
        - TN: true negatives  = correct rejections,
        - FP: false positives = false alarm (= type I error),
        - FN: false negatives = misses (= type II error).
        The given classify() function returns True or False for a document.
        The list of documents contains (document, bool)-tuples for testing,
        where True means a document that should be identified as True by classify().
    """
    TN = TP = FN = FP = 0
    for document, b1 in documents:
        b2 = classify(document)
        if b1 and b2:
            TP += 1
        elif not b1 and not b2:
            TN += 1
        elif not b1 and b2:
            FP += 1
        elif b1 and not b2:
            FN += 1
    return TP, TN, FP, FN


def unicode_filter(intext):
    """
    Remove Unicode crap.

    :param intext: Text to filter.
    :type intext: str
    """
    return intext.replace('–', '').strip()


def object_for(objectid):
    """ Return the object associated with ``objectid`` or ``None`` if the
        object cannot be found."""


def getidx(i, Ni):
    """
    Get the position of the tuple *i* in the equivalent one-dimensional
    vector. The list *Ni* contains the maximum values of the indices,
    which start all from 0.
    """
    k, pos = len(Ni), 0
    for j in range(k - 1, 0, -1):
        pos = Ni[j - 1] * (i[j] + pos)
    return pos + i[0]


def dfmeta_to_htmlfile(styled_df, filename, head=''):
    """
    styled_df should be <class 'IPython.core.display.HTML'>
    """
    r = f'
{head}
\n' + '\n' + styled_df.data + '\n'
    with open(filename, 'w') as f:
        f.write(r)
    return f'{filename} saved'


@classmethod
def default_penalty(cls):
    """Implement :meth:`~.solver.Solver.default_penalty`."""
    return 1.0


def from_string(s):
    """Converts a time series to a list of (int, int) tuples.

    The string should be a sequence of zero or more <time>:<amount> pairs.
    Whitespace delimits each pair; leading and trailing whitespace is ignored.

    ValueError is raised on any malformed input.
    """
    pairs = s.strip().split()
    ret = []
    for pair in pairs:
        time, amount = pair.split(':')
        time = int(time)
        amount = int(amount)
        if time < 0:
            raise ValueError('Time cannot be less than zero: %s' % time)
        ret.append((time, amount))
    return ret


def fix_name(basename):
    """Fixes illegitimate basename, deprecated."""
    if len(basename) < 3:
        return '{}0{}'.format(*basename)
    return basename


def feedback(forward, backward=1):
    """Calculate closed loop transfer function

         +     ┌────────┐
      ────>o──>│forward ├────┬──>
          -↑   └────────┘    │
           │   ┌────────┐    │
           └───┤backward│<───┘
               └────────┘
    """
    loop = forward * backward
    return forward / (1 + loop)


def components_to_hosts(components):
    """Convert a list of Component namedtuples to a list of their hosts
    :param components: a list of Component namedtuples
    :returns: list of the hosts associated with each Component
    """
    hosts = []
    for component in components:
        hosts.append(component.host)
    return hosts


def get():
    """-> dict with configuration like if it was extracted from the form
        """


def zeros_like(input):
    """Create a zero tensor with the same shape, dtype and context of the
    given tensor.

    Parameters
    ----------
    input : Tensor
        The input

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


def load_xml_etree_cElementTree(finder, module):
    """the xml.etree.cElementTree module implicitly loads the
       xml.etree.ElementTree module; make sure this happens."""
    finder.IncludeModule('xml.etree.ElementTree')


def generate_compute_ATA(L, ATA, A, m, n, index_prefix=''):
    """Generate code to declare and compute ATA[i,j] = sum_k A[k,i]*A[k,j] with given A shaped (m,n)."""
    i = L.Symbol(index_prefix + 'i')
    j = L.Symbol(index_prefix + 'j')
    k = L.Symbol(index_prefix + 'k')
    code = [L.ArrayDecl('double', ATA, (n, n), values=0), L.ForRange(i, 0,
        n, body=L.ForRange(j, 0, n, body=L.ForRange(k, 0, m, body=L.
        AssignAdd(ATA[i, j], A[k, i] * A[k, j]))))]
    return L.StatementList(code)


def _get_element_and_line(xray_line):
    """
    Returns the element name and line character for a particular X-ray line as
    a tuple.

    By example, if xray_line = 'Mn_Ka' this function returns ('Mn', 'Ka')
    """
    lim = xray_line.find('_')
    if lim == -1:
        raise ValueError('Invalid xray-line: %' % xray_line)
    return xray_line[:lim], xray_line[lim + 1:]


@staticmethod
def relabel_pcs(x):
    """Given a list of integers, change the name to be a 1-based
        principal component representation"""
    return 'pc_' + str(int(x) + 1)


@classmethod
def op(cls, *args, **kwargs):
    """
        Shorthand for :py:meth:`get_operation`.
        """
    return cls.get_operation(*args, **kwargs)


@classmethod
def find(cls, db, name):
    """Find a service by name.

        Returns None if not found.
        """
    return db.query(cls).filter(cls.name == name).first()


def isplit(string, sep='\t\n\x0b\x0c\r '):
    """Returns an iterator over string.split().

    This is efficient in combination with cooccurrence(), since the
    string may be very long (e.g., Brown corpus).

    """
    a = []
    for ch in string:
        if ch not in sep:
            a.append(ch)
            continue
        if a:
            yield ''.join(a)
            a = []
    if a:
        yield ''.join(a)


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 '+'


def meetup_time_format(a_datetime):
    """Format a date/time for Meetup."""
    return a_datetime.strftime('%Y-%m-%dT%H:%M:%S.000')


def _is_property_defined(elem, attr):
    """Check if attribute of an element was defined."""
    while elem.parent is not elem:
        try:
            cmdpar = elem.cmdpar[attr]
            if cmdpar.inform:
                return bool(cmdpar.expr)
        except (KeyError, IndexError):
            pass
        elem = elem.parent
    return False


def update_modified_from_license_info(delta, unique_categories):
    """
    Increase a 'modified' Delta object's 'score' attribute and add
    one or more categories to its 'factors' attribute if there has
    been a license change.
    """
    if not delta.new_file.has_licenses() and delta.old_file.has_licenses():
        delta.update(15, 'license info removed')
        return
    new_licenses = delta.new_file.licenses or []
    old_licenses = delta.old_file.licenses or []
    new_categories = set(license.category for license in new_licenses)
    old_categories = set(license.category for license in old_licenses)
    if delta.new_file.has_licenses() and not delta.old_file.has_licenses():
        delta.update(20, 'license info added')
        for category in new_categories:
            if category in unique_categories:
                delta.update(20, category.lower() + ' added')
        return
    new_keys = set(license.key for license in new_licenses)
    old_keys = set(license.key for license in old_licenses)
    if new_keys != old_keys:
        delta.update(10, 'license change')
        for category in (new_categories - old_categories):
            if len(old_categories & unique_categories
                ) == 0 and category in unique_categories:
                delta.update(20, category.lower() + ' added')


def _mid(string, start, end=None):
    """
    Returns a substring delimited by start and end position.
    """
    if end is None:
        end = len(string)
    return string[start:start + end]


def subplot_spacing(params):
    """Adjust subplot plots' inter-spacing

    Args:
        params (dict): parameter dictionary

    Returns:
        a new dictionary whose ['canvas']['figure']
        has updated horizontal and vertical spacing
        between subplots
    """
    params['internal']['canvas']['figure'].subplots_adjust(hspace=params[
        'global']['figure']['subplot']['spacing']['vertical'], wspace=
        params['global']['figure']['subplot']['spacing']['horizontal'])
    return params


def write_result_to_file(output_file, text):
    """
    Write statistics to file
    """
    print('Write to {} text:\n{}'.format(output_file, text))
    print('But not today... :)')


def denoise_animation(input_filepath: str='', output_filepath: str=''):
    """Denoise rendered animation sequence using current scene and view layer settings. Requires denoising data passes and output to OpenEXR multilayer files

    :param input_filepath: Input Filepath, File path for image to denoise. If not specified, uses the render file path and frame range from the scene
    :type input_filepath: str
    :param output_filepath: Output Filepath, If not specified, renders will be denoised in-place
    :type output_filepath: str
    """
    pass


def _unwhiten_cf(cf, x):
    """
    Unwhiten a matrix

    Parameters
    ----------
    cf : array_like(ndim=2, dtype=float)
        The upper triangular part of the cholesky decomposition of a

    x : array_like(ndim=2, dtype=float)
        Not sure, just blindly porting...

    Returns
    -------
    updated matrix.

    """
    return cf.T.dot(x)


def caseinsensitive_in(element, elist):
    """
    Given a list and an element, return true if the element is present in the list
    in a case-insensitive flavor
    """
    return element.lower() in map(str.lower, elist)


def discard_document_variables(app, env, docname):
    """Discard any document specific variables."""
    try:
        env.ipysphinx_widgets.discard(docname)
    except AttributeError:
        pass
    try:
        env.ipysphinx_created_from_nb.discard(docname)
    except AttributeError:
        pass


def original_error(err):
    """
    Returns original exception from graphql exception wrappers.

    graphql-core wraps exceptions that occurs on resolvers into special type
    with ``original_error`` attribute, which contains the real exception.
    """
    return err.original_error if hasattr(err, 'original_error') else err


def check_valid_settings(settings):
    """Validate sane settings"""
    return True


def p_track_cd_text(t):
    """track_flag : CD_TEXT START_BLOCK language_blocks END_BLOCK"""
    from audiotools.toc import CDText
    t[0] = CDText(languages=t[3])


def get_text(node):
    """Get the contents of text nodes in a parent node"""
    return node.text


def check_dtype(array, allowed):
    """Raises TypeError if the array is not of an allowed dtype.

    :param array: array whose dtype is to be checked
    :param allowed: instance or list of allowed dtypes
    """
    if not hasattr(allowed, '__iter__'):
        allowed = [allowed]
    if array.dtype not in allowed:
        raise TypeError('Invalid dtype {}. Allowed dtype(s): {}'.format(
            array.dtype, allowed))


@classmethod
def _get_apic_classes(cls):
    """
        Get the APIC classes used by this acitoolkit class.

        :returns: list of strings containing APIC class names
        """
    return ['l3extInstP']


def parse_stage_name(stage):
    """
    Determine the name of a stage.

    The stage may be provided already as a name, as a Stage object, or as a
    callable with __name__ (e.g., function).

    :param str | pypiper.Stage | function stage: Object representing a stage,
        from which to obtain name.
    :return str: Name of putative pipeline Stage.
    """
    if isinstance(stage, str):
        return stage
    try:
        return stage.name
    except AttributeError:
        try:
            return stage.__name__
        except AttributeError:
            raise TypeError('Unsupported stage type: {}'.format(type(stage)))


def dynamic_import_by_name(name, module_prefix='app'):
    """ dynamic import by name """
    import importlib
    importlib.import_module(f'{module_prefix}.{name}')


def getFilterActive():
    """ Returns active filter """
    return [{'text': 'true', 'id': 'true'}, {'text': 'false', 'id': 'false'}]


def _is_pair(item):
    """Check if an item is a pair (tuple of size 2).
    """
    return isinstance(item, (list, tuple, set)) and len(item
        ) == 2 and not isinstance(item[0], (list, tuple, set)
        ) and not isinstance(item[1], (list, tuple, set))


def get_key(config, kwds, key, default=None, formatted='formatted',
    missing_ok=True):
    """
    Retreive the value of `key` from the mapping `config`.

    If `key` does not exist in `config`, return `default` instead.

    If `formatted` is a string, it determines the key name that
    determines whether `key` is a format string or not (default is
    yes). Otherwise, it is interpreted as a boolean directly.

    Parameters
    ----------
    config : dict
        The :ref:`plugins-data-configuration` dictionary to search.
    kwds : dict
        The :ref:`keywords` dictionary to use for replacements if
        `formatted` turns out to be truthy.
    key : str
        The name of the key in `config` containing the required value.
    default :
        The value to return if `key` is missing from `config`.
    formatted : str or bool
        Either the name of the key to get the formatted flag from (if a
        string), or the flag itself. In either case, ignored if the
        value is not a string.
    missing_ok : bool
        If truthy, missing values are replaced by `default`. Otherwise
        a :py:exc:`KeyError` is raised.

    Return
    ------
    The value in `config` associated with `key`, optionally formatted
    with `kwds`.
    """
    if missing_ok:
        value = config.get(key, default)
    else:
        value = config[key]
    if isinstance(value, str) and config.get(formatted, True):
        value = value.format(**kwds)
    return value


def shared_access_signature_tokens_expire_within_an_hour_3_4(storage_accounts):
    """
    There is no automation possible for this currently
    Manual
    """
    pass


@classmethod
def from_saved_data(cls, data):
    """ Create record from saved Record.SaveData """
    return cls(data=data.data, prop=data.prop, start_time=data.start_time,
        name=data.name)


def get_wid(word):
    """Return the wird id for the given word.

        Return 0 of the word is not in the lexicon.
        """


def ln_acf2ln_acf_MX(ln_acfM, ln_acfX, nM, nX):
    """Calculate the mean activity coefficient for an electrolyte."""
    return (nM * ln_acfM + nX * ln_acfX) / (nM + nX)


def delete_s3user(module, blade):
    """Delete Object Store Account"""
    changed = False
    user = module.params['account'] + '/' + module.params['name']
    try:
        blade.object_store_users.delete_object_store_users(names=[user])
        changed = True
    except Exception:
        module.fail_json(msg='Object Store Account {0}: Deletion failed'.
            format(module.params['name']))
    module.exit_json(changed=changed)


def userpref_show():
    """Edit user preferences and system settings

    """
    pass


def is_patch_applied():
    """Checks if the monkey patch was already applied
    """
    from Products.SiteErrorLog.SiteErrorLog import SiteErrorLog
    from collective.logbook.monkey import raising
    actual_raising = getattr(SiteErrorLog.raising, 'im_func', SiteErrorLog.
        raising)
    return actual_raising is raising


def missing_doi_warning(dummy_form, field, submit=False, fields=None):
    """
    Field processor.

    Checks for existence of a DOI, and otherwise asks people to provide it.
    """
    if not field.errors and not field.data:
        field.add_message('Please provide a DOI if possible.', state='warning')
        raise StopIteration()


def camel_to_space(s):
    """Replace low dashes with spaces.

    Parameters
    ----------
    s : str
        String that may contain "_" characters.
    """
    return ' '.join(s.split('_'))


def float_to_str(value: float) ->str:
    """Converts double number to string using {.12g} formatter."""
    return format(value, '.12g')


def pt_source_file():
    """return some text describing where a bit of ZPT code came from.

        This could be a file path, a object path, etc.
        """


def raise_type_mismatch(ob, expected, **kwargs):
    """ Raises an exception concerning ob having the wrong type. """
    e = 'Object not of expected type:'
    e += '\n  expected: %s' % str(expected)
    e += '\n  obtained: %s' % str(type(ob))
    raise ValueError(e)


def revoke_approval():
    """Revoke the currently approved version.
        """


def zoom_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin: int=0,
    ymax: int=0):
    """Zoom in the view to the nearest item contained in the border

    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    """
    pass


def shift_nodes(nodes, shift, fg):
    """Shift the pos of nodes in fg by shift in-place."""
    for node in nodes:
        fg.nodes[node]['pos'] += shift


def batch_iterable(batch_size, iterable):
    """Return batches to be processes from the given iterable."""
    batch = []
    count = 0
    for element in iterable:
        count += 1
        batch.append(element)
        if count == batch_size:
            yield batch.copy()
            batch.clear()
            count = 0
    yield batch


def avg2(num1, num2):
    """Returns the average of two numbers

    Parameters
    ----------
    num1: float
        The first number.
    num2: float
        The second number.

    Returns
    -------
    float
        The average.
    """
    return (num1 + num2) / 2.0


def vrh(kclay, kqtz, vclay):
    """
    Voigt-Reuss-Hill average to find Kmatrix from clay and qtz components.

    From Smith et al, Geophysics 68(2), 2003.

    Works for any two components.

    Returns Kvrh, AKA Kmatrix.
    """
    vqtz = 1 - vclay
    kreuss = 1.0 / (vclay / kclay + vqtz / kqtz)
    kvoigt = vclay * kclay + vqtz * kqtz
    kvrh = 0.5 * (kreuss + kvoigt)
    return kvrh


def numbonds(mol) ->int:
    """
    Number of bonds.

    Parameters
    ----------
    mol:
        Molecule

    Returns
    -------
    int
        Number of bonds
    """
    return mol.OBMol.NumBonds()


def parse_commit_message(message):
    """Given the full commit message (summary, body), parse out relevant information.

    Mimiron generates commit messages, commits, and pushes changes tfvar changes to
    remote. These generated commit messages contain useful information such as the service
    that was bumped, the person that bumped, environment etc.

    Args:
        message (str): The full git commit message

    Returns:
        Optional[dict]: A dictionary of useful information, None otherwise

    """
    data = {}
    for line in message.split('\n'):
        if not line:
            continue
        key, _, value = line.partition(':')
        if key == 'committed-by':
            name, _, email = value.strip().partition('<')
            data['author_name'] = name.strip()
            data['author_email'] = email.rstrip('>') or None
    return data or None


def scroll_down(deltax: int=0, deltay: int=0, page: bool=False):
    """Scroll the view down

    :param deltax: Delta X
    :type deltax: int
    :param deltay: Delta Y
    :type deltay: int
    :param page: Page, Scroll down one page
    :type page: bool
    """
    pass


@classmethod
def add(cls, name, cases):
    """ Add an adjective ending and its associated form. """
    cls.STEMS[name] = set(cases)


def word2bytes(value):
    """
    >>> word2bytes(0xff09)
    (255, 9)

    >>> [hex(i) for i in word2bytes(0xffab)]
    ['0xff', '0xab']

    >>> word2bytes(0xffff +1)
    Traceback (most recent call last):
    ...
    AssertionError
    """
    assert 0 <= value <= 65535
    return value >> 8, value & 255


def code_image_embed(image_1d_array, code_array):
    """
    embed the code array into the rgb array
    :param image_1d_array: 1D RGB numpy array
    :param code_array: processed code array
    :return: code embeded 1D RGB numpy array
    """
    image_code_array = []
    for i in range(len(code_array)):
        if image_1d_array[i] >= code_array[i]:
            image_code_array.append(image_1d_array[i] - code_array[i])
        else:
            image_code_array.append(image_1d_array[i] + code_array[i])
    return image_code_array


def find_first_number(ll):
    """ Returns nr of first entry parseable to float in ll, None otherwise"""
    for nr, entry in enumerate(ll):
        try:
            float(entry)
        except (ValueError, TypeError) as e:
            pass
        else:
            return nr
    return None


@staticmethod
def do_namespace(data):
    """ Returns a copy of the dictionary with all the keys put in a 'do_' namespace """
    info = {}
    for k, v in data.items():
        info['do_' + k] = v
    return info


def build_model(name, variables, task, subject, run=None, session=None,
    hrf_variables=None, transformations=None, contrasts=None,
    dummy_contrasts=True):
    """ Builds a basic two level BIDS-Model """
    hrf_variables = hrf_variables or []
    transformations = transformations or []
    contrasts = contrasts or []
    if not set(variables) >= set(hrf_variables):
        raise ValueError('HRF Variables must be a subset of all variables')
    transformations.append({'Input': hrf_variables, 'Name': 'Convolve'})
    model = {'Steps': [{'DummyContrasts': {'Type': 't'}, 'Contrasts':
        contrasts, 'Level': 'Run', 'Model': {'X': variables},
        'Transformations': transformations}], 'Input': {'Subject': subject,
        'Task': task}, 'Name': name}
    model['Steps'].append({'DummyContrasts': {'Type': 'FEMA'}, 'Level':
        'Subject'})
    model['Steps'].append({'DummyContrasts': {'Type': 't'}, 'Level': 'Dataset'}
        )
    if not dummy_contrasts:
        model['Steps'][0].pop('DummyContrasts')
    if dummy_contrasts == 'hrf' and hrf_variables:
        model['Steps'][0]['DummyContrasts']['Conditions'] = hrf_variables
    if run is not None:
        model['Input']['Run'] = run
    if session is not None:
        model['Input']['Session'] = session
    return model


def list_tags_for_resource(ResourceName=None):
    """
    Lists all cost allocation tags currently on the named resource. A cost allocation tag is a key-value pair where the key is case-sensitive and the value is optional. You can use cost allocation tags to categorize and track your AWS costs.
    You can have a maximum of 50 cost allocation tags on an ElastiCache resource. For more information, see Using Cost Allocation Tags in Amazon ElastiCache .
    See also: AWS API Documentation

    :example: response = client.list_tags_for_resource(
        ResourceName='string'
    )

    :type ResourceName: string
    :param ResourceName: [REQUIRED]
            The Amazon Resource Name (ARN) of the resource for which you want the list of tags, for example arn:aws:elasticache:us-west-2:0123456789:cluster:myCluster or arn:aws:elasticache:us-west-2:0123456789:snapshot:mySnapshot .
            For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces .

    :rtype: dict
    :return: {
        'TagList': [
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    }

    """
    pass


def kwargs_to_variable_assignment(kwargs: dict, value_representation=repr,
    assignment_operator: str=' = ', statement_separator: str='\n',
    statement_per_line: bool=False) ->str:
    """
    Convert a dictionary into a string with assignments

    Each assignment is constructed based on:
    key assignment_operator value_representation(value) statement_separator,
    where key and value are the key and value of the dictionary.
    Moreover one can seprate the assignment statements by new lines.

    Parameters
    ----------
    kwargs : dict

    assignment_operator: str, optional:
        Assignment operator (" = " in python)
    value_representation: str, optinal
        How to represent the value in the assignments (repr function in python)
    statement_separator : str, optional:
        Statement separator (new line in python)
    statement_per_line: bool, optional
        Insert each statement on a different line

    Returns
    -------
    str
        All the assignemnts.

    >>> kwargs_to_variable_assignment({'a': 2, 'b': "abc"})
    "a = 2\\nb = 'abc'\\n"
    >>> kwargs_to_variable_assignment({'a':2 ,'b': "abc"}, statement_per_line=True)
    "a = 2\\n\\nb = 'abc'\\n"
    >>> kwargs_to_variable_assignment({'a': 2})
    'a = 2\\n'
    >>> kwargs_to_variable_assignment({'a': 2}, statement_per_line=True)
    'a = 2\\n'
    """
    code = []
    join_str = '\n' if statement_per_line else ''
    for key, value in kwargs.items():
        code.append(key + assignment_operator + value_representation(value) +
            statement_separator)
    return join_str.join(code)


def ik_add(with_targets: bool=True):
    """Add IK Constraint to the active Bone

    :param with_targets: With Targets, Assign IK Constraint with targets derived from the select bones/objects
    :type with_targets: bool
    """
    pass


def vertex_color_remove():
    """Remove vertex color layer

    """
    pass


def _get_db_table_for_model(model):
    """
    Return table name in database server for passed model.
    """
    return model._meta.db_table


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 var_definition(cls, name):
    """Get a description of a particular field.

        Parameters
        ----------
        name : str
            A field name.

        Returns
        -------
        tuple of (*name*, *description*)
            A description of each field.
        """
    return cls._info[name]['doc']


@classmethod
def make_node(cls, node, *params):
    """ This will return a node with a param_list
        (declared in a function declaration)
        Parameters:
            -node: A SymbolPARAMLIST instance or None
            -params: SymbolPARAMDECL insances
        """
    if node is None:
        node = cls()
    if node.token != 'PARAMLIST':
        return cls.make_node(None, node, *params)
    for i in params:
        if i is not None:
            node.appendChild(i)
    return node


def to_ranking(arr):
    """
    http://stackoverflow.com/questions/5284646/rank-items-in-an-array-using-python-numpy
    """
    order = arr.argsort()
    ranks = order.argsort()
    return ranks


@staticmethod
def get_parallel_conductance(rs, x):
    """x : reactance (ohm)
rs : series resistance (ohm)
return parallel conductance G (S) if not infinite"""
    if rs == 0 and x == 0:
        return None
    return rs / (rs * rs + x * x)


def replicate_bbls(bbl_list, displacement=None):
    """Returns a copy the given basic block list at the specified displacement.

    :param bbl_list: List of basic blocks to copy
    :type bbl_list: :class:`~.list` of :class:`~.Bbl`
    :param displacement: Displacement of the copied basic blocks
                         (Default value = None)
    :type displacement: :class:`~.int`

    """
    bbls_replicated = []
    for bbl in bbl_list:
        bbls_replicated.append(bbl.replicate(displacement=displacement))
    return bbls_replicated


def _kernel_shape(ndim, dim):
    """Return list of `ndim` 1s except at position `dim`, where value is -1.

    Parameters
    ----------
    ndim : int
        The number of dimensions of the kernel shape.
    dim : int
        The axis of the kernel to expand to shape -1.

    Returns
    -------
    shape : list of int
        The requested shape.

    Examples
    --------
    >>> _kernel_shape(2, 0)
    [-1, 1]
    >>> _kernel_shape(3, 1)
    [1, -1, 1]
    >>> _kernel_shape(4, -1)
    [1, 1, 1, -1]
    """
    shape = [1] * ndim
    shape[dim] = -1
    return shape


def snapshot():
    """Called to retrieve the current state of an object.
        It should return only structures of basic python types
        or instances implementing L{ISnapshot}."""


@classmethod
def list(cls, identifier_list):
    """Model batch get method"""


def is_object(value):
    """Checks if `value` is a ``list`` or ``dict``.

    Args:
        value (mixed): Value to check.

    Returns:
        bool: Whether `value` is ``list`` or ``dict``.

    Example:

        >>> is_object([])
        True
        >>> is_object({})
        True
        >>> is_object(())
        False
        >>> is_object(1)
        False

    .. versionadded:: 1.0.0
    """
    return isinstance(value, (list, dict))


def get_field(dct: dict, name):
    """
    Will check & get field via name
    :param dct: dict
    :param name: any key stored in a dictionary
    :return: any value stored in a dictionary
    """
    if type(dct) == dict and name in dct:
        return dct[name]
    return None


@staticmethod
def get_key(packet):
    """Get key from an auth response packet."""
    return packet.payload[4:20]


def inverte(imagem):
    """
    Invert grey scale image
    :param imagem: input image
    :return: inverted image
    """
    imagem = 255 - imagem
    return imagem


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 get_identity_policies(Identity=None, PolicyNames=None):
    """
    Returns the requested sending authorization policies for the given identity (an email address or a domain). The policies are returned as a map of policy names to policy contents. You can retrieve a maximum of 20 policies at a time.
    Sending authorization is a feature that enables an identity owner to authorize other senders to use its identities. For information about using sending authorization, see the Amazon SES Developer Guide .
    This action is throttled at one request per second.
    See also: AWS API Documentation

    Examples
    The following example returns a sending authorization policy for an identity:
    Expected Output:

    :example: response = client.get_identity_policies(
        Identity='string',
        PolicyNames=[
            'string',
        ]
    )

    :type Identity: string
    :param Identity: [REQUIRED]
            The identity for which the policies will be retrieved. You can specify an identity by using its name or by using its Amazon Resource Name (ARN). Examples: user@example.com , example.com , arn:aws:ses:us-east-1:123456789012:identity/example.com .
            To successfully call this API, you must own the identity.

    :type PolicyNames: list
    :param PolicyNames: [REQUIRED]
            A list of the names of policies to be retrieved. You can retrieve a maximum of 20 policies at a time. If you do not know the names of the policies that are attached to the identity, you can use ListIdentityPolicies .
            (string) --

    :rtype: dict
    :return: {
        'Policies': {
            'string': 'string'
        }
    }

    :returns:
    (string) --
    (string) --

    """
    pass


def configure_locations(event):
    """Configure locations for session."""
    session = event['data']['session']


def _format_user_matrix(user):
    """Given a Quip user dict, return a matrix that terminal tables will accept."""
    return [['Name', user['name']], ['Email(s)', ', '.join(user['emails']) if
        'emails' in user else ''], ['Quip User ID', user['id']]]


def make_key_mapping(key_list, start_note):
    """Return a dictionary of (note, velocity) by computer keyboard key code"""
    mapping = {}
    for i in range(len(key_list)):
        mapping[key_list[i]] = start_note + i, 127
    return mapping


def linexor(listoflists, columnlist, valuelist):
    """
Returns the rows of a list of lists where col (from columnlist) = val
(from valuelist) for ANY pair of values (colunmlist[i],valuelist[i[).
One value is required for each column in columnlist.  If only one value
exists for columnlist but multiple values appear in valuelist, the
valuelist values are all assumed to pertain to the same column.

Usage:   linexor (listoflists,columnlist,valuelist)
Returns: the rows of listoflists where columnlist[i]=valuelist[i] for ANY i
"""
    if type(columnlist) not in [list, tuple]:
        columnlist = [columnlist]
    if type(valuelist) not in [list, tuple]:
        valuelist = [valuelist]
    criterion = ''
    if len(columnlist) == 1 and len(valuelist) > 1:
        columnlist = columnlist * len(valuelist)
    for i in range(len(columnlist)):
        if isinstance(valuelist[i], str):
            critval = "'" + valuelist[i] + "'"
        else:
            critval = str(valuelist[i])
        criterion = criterion + ' x[' + str(columnlist[i]
            ) + ']==' + critval + ' or'
    criterion = criterion[0:-2]
    function = 'filter(lambda x: ' + criterion + ',listoflists)'
    lines = eval(function)
    return lines


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

        :param SharedContentViewType val:
        :rtype: EventType
        """
    return cls('shared_content_view', val)


def isfloat(value):
    """
    returns true if a value can be typecasted as a float, else false
    """
    try:
        float(value)
        return True
    except ValueError:
        return False


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 '+'


def __init__(context, request, layout, view):
    """Adapts context, request, layout and view.
        """


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


@classmethod
def get_all_hd_thermal_elements(cls, session, server_key):
    """Retrieve all storage components that support temperature sensors"""
    query = []
    query.extend([
        'MATCH (:ServerWithBMC {{ key: {} }})-[:HAS_CONTROLLER]->(controller:Controller)'
        .format(server_key),
        'MATCH (controller)-[:HAS_CACHEVAULT|:HAS_PHYSICAL_DRIVE]->(hd_component)'
        , 'WHERE hd_component:PhysicalDrive or hd_component:CacheVault',
        'RETURN controller, hd_component'])
    results = session.run('\n'.join(query))
    hd_thermal_elements = []
    for record in results:
        hd_thermal_elements.append({'controller': dict(record.get(
            'controller')), 'component': dict(record.get('hd_component'))})
    return hd_thermal_elements


def fancy(message):
    """Print message with surrounding ~'s."""
    return '~{0}~'.format(message)


def switch_on(fritz, args):
    """Command that set the device switch state to on."""
    fritz.set_switch_state_on(args.ain)


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


def bytes_fmt(num):
    """Converts bytes to a human readable format

    Parameters
    ----------
    num : int,float
        Number of bytes

    Returns
    -------
    float
        Human readable format with binary prefixes
    """
    for x in ['B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
        if num < 1024:
            return '{:3.1f}{:s}'.format(num, x)
        num /= 1024
    else:
        return '{:3.1f}{:s}'.format(num, 'Y')


def repack_ser_spent_output_to_unspent(ser_spent_output):
    """
    Function for fast repacking without deserialization
  """
    return ser_spent_output[4:]


def input_datasets(s):
    """ returns a list of all used input datasets """
    DSs = set()
    for j in s.jobs:
        for ds in j.infiles.keys():
            DSs.add(ds)
    return list(DSs)


def map_metadata(meta, key, config):
    """Map metadata from other platforms to Nikola names.

    This uses the METADATA_MAPPING and METADATA_VALUE_MAPPING settings (via ``config``) and modifies the dict in place.
    """
    for foreign, ours in config.get('METADATA_MAPPING', {}).get(key, {}).items(
        ):
        if foreign in meta:
            meta[ours] = meta[foreign]
    for meta_key, hook in config.get('METADATA_VALUE_MAPPING', {}).get(key, {}
        ).items():
        if meta_key in meta:
            meta[meta_key] = hook(meta[meta_key])


def general_style_generator():
    """
    Create the general style (alignement, padding ...) of the table, copying the MISP'event's web_view.
    :return: a list of properties, usable in a TableStyle
    """
    lines_list = []
    lines_list.append(('VALIGN', (0, 0), (-1, -1), 'MIDDLE'))
    lines_list.append(('LEFTPADDING', (0, 0), (-1, -1), 0))
    lines_list.append(('RIGHTPADDING', (0, 0), (-1, -1), 0))
    return lines_list


def bounding_box_half_values(bbox_min, bbox_max):
    """
    Returns the values half way between max and min XYZ given tuples
    :param bbox_min: tuple, contains the minimum X,Y,Z values of the mesh bounding box
    :param bbox_max: tuple, contains the maximum X,Y,Z values of the mesh bounding box
    :return: tuple(int, int, int)
    """
    min_x, min_y, min_z = bbox_min
    max_x, max_y, max_z = bbox_max
    half_x = (min_x + max_x) * 0.5
    half_y = (min_y + max_y) * 0.5
    half_z = (min_z + max_z) * 0.5
    return half_x, half_y, half_z


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 x_forwarded_ip(request):
    """
    Amazon ELB stores the IP in the HTTP_X_FORWARDED_FOR META attribute.
    It is realiably the first one of the IP adresses sent and can be
    trusted (eg.: cannot be spoofed) Warning: This might not be true for
    other load balancers
    This function assumes that your Nginx is configured with:
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    """
    ip_address_list = request.META.get('HTTP_X_FORWARDED_FOR')
    if ip_address_list:
        ip_address_list = ip_address_list.split(',')
        return ip_address_list[0]


@classmethod
def register_bool_option(cls, name, description=None):
    """
        Register a Boolean switch as state option.
        This is equivalent to cls.register_option(name, set([bool]), description=description)

        :param str name:        Name of the state option.
        :param str description: The description of this state option.
        :return:                None
        """
    cls.register_option(name, {bool}, default=False, description=description)


@staticmethod
def str2xml_to_file(xml_str, target_file_path):
    """
        use xml string to create logback xml file
        """
    f = open(target_file_path, 'w+')
    f.write(xml_str)


@classmethod
def contains(cls, value):
    """
        gets a value indicating that given input existed in
        the enumeration values.

        :param int | str | CoreEnum value: value to be checked for existence.

        :rtype: bool
        """
    return value in cls


def isclassattr(a, cls):
    """ Test if an attribute is a class attribute. """
    for c in cls.__mro__:
        if a in c.__dict__:
            return True
    return False


@classmethod
def reset(cls):
    """Reset to default state."""
    cls.boxes_number = 0
    return


def setup(outfile):
    """I take a file-like object (providing write and close) to which all
        the plaintext data will be written.

        TODO: producer/consumer . Maybe write() should return a Deferred that
        indicates when it will accept more data? But probably having the
        IDecoder be a producer is easier to glue to IConsumer pieces.
        """


def find_in_enum_members(item, enum_members: list):
    """Matches a string in the provided list of member strings.
	The item must be not fully matched.
	Rules:
	- If the member string starts with underscore, it is cut out before the matching continues.
	- The item is matched if a member string starts with the item (item is a prefix of the member)."""
    found = None
    for x in enum_members:
        if x.startswith(item):
            found = x
            break
        if x.startswith('_'):
            if x.strip('_').startswith(item):
                found = x
                break
    return found


def spectra_apply_wavelength_mask(spectra, mask):
    """ Applies a wavelength mask to a spectra ((wavelengths, values) tuple).
    All values in the spectra that are not in the mask will be removed in the
    returned values. The input spectra is not modified.

    Args:
        spectra (tuple): the (wavelengths, values) spectra tuple.
        mask (array-like): The wavelength values that should be retained.

    Returns:
        The masked tuple of (wavelengths, values).
    """
    boolean_mask = (spectra[0] >= mask.min()) & (spectra[0] <= mask.max())
    return spectra[0][boolean_mask], spectra[1][boolean_mask]


def make_draw_response(reason: str) ->str:
    """Makes a response string for a draw.

    Parameters:
         - reason: The reason for the draw, in the form of a noun, e.g.,
                   'stalemate' or 'insufficient material'.

    Returns: The draw response string.
    """
    return "It's a draw because of {}!".format(reason)


def broadcast_power(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Returns result of first array elements raised to powers from second array, element-wise with broadcasting.

    Example::

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

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

       broadcast_power(x, y) = [[ 2.,  2.,  2.],
                                [ 4.,  4.,  4.]]

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_extended.cc:L45

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

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

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


def __init__(value, context):
    """Adapts value and a context
        """


@staticmethod
def disconnect(controller_widget, control_name, control_instance):
    """ Disconnect a 'Controller' controller trait and a 'ControllerControlWidget'
        controller widget control.

        Parameters
        ----------
        cls: StrControlWidget (mandatory)
            a StrControlWidget control
        controller_widget: ControllerWidget (mandatory)
            a controller widget that contains the controller we want to update
        control_name: str (mandatory)
            the name of the controller widget control we want to synchronize
            with the controller
        control_instance: QFrame (mandatory)
            the instance of the controller widget control we want to
            synchronize with the controller
        """
    if control_instance.connected:
        control_instance.controller_widget.disconnect()
        control_instance.connected = False


def duplicate_move_linked(OBJECT_OT_duplicate=None, TRANSFORM_OT_translate=None
    ):
    """Duplicate selected objects and move them

    :param OBJECT_OT_duplicate: Duplicate Objects, Duplicate selected objects
    :param TRANSFORM_OT_translate: Translate, Translate (move) selected items
    """
    pass


def concline_generator(matches, idxs, df, metadata, add_meta, category,
    fname, preserve_case=False):
    """
    Get all conclines

    :param matches: a list of formatted matches
    :param idxs: their (sent, word) idx
    """
    conc_res = []
    from collections import defaultdict
    mdict = defaultdict(list)
    idxs = list(matches.index)
    for mid, (s, i) in zip(matches, idxs):
        mdict[s].append((i, mid))
    df = df.loc[list(mdict.keys())]
    for s, tup in sorted(mdict.items()):
        sent = df.loc[s]
        if not preserve_case:
            sent = sent.str.lower()
        meta = metadata[s]
        sname = meta.get('speaker', 'none')
        for i, mid in tup:
            if not preserve_case:
                mid = mid.lower()
            ix = '%d,%d' % (s, i)
            start = ' '.join(sent.loc[:i - 1].values)
            end = ' '.join(sent.loc[i + 1:].values)
            lin = [ix, category, fname, sname, start, mid, end]
            if add_meta:
                for k, v in sorted(meta.items()):
                    if k in ['speaker', 'parse', 'sent_id']:
                        continue
                    if isinstance(add_meta, list):
                        if k in add_meta:
                            lin.append(v)
                    elif add_meta is True:
                        lin.append(v)
            conc_res.append(lin)
    return conc_res


def rle_prepend_modify(rle, a_r):
    """
    Append (a, r) (unpacked from *a_r*) to BEGINNING of rle.
    Merge with first run when possible

    MODIFIES rle parameter contents. Returns None.
    """
    a, r = a_r
    if not rle:
        rle[:] = [(a, r)]
    else:
        al, run = rle[0]
        if a == al:
            rle[0] = a, run + r
        else:
            rle[0:0] = [(a, r)]


def readable_size(size: float) ->str:
    """Represent file size in human-readable format.

    .. code:: python

        >>> readable_size(1024 * 1024)
        "1.00M"

    :param size: File size in bytes.
    """
    units = ['', 'K', 'M', 'G', 'T', 'P']
    for unit in units[:-1]:
        if size < 1024:
            return f'{size:.2f}{unit}'
        size /= 1024
    return f'{size:.2f}{units[-1]}'


def file_sorting_key(filename):
    """
    Extract a key for a filename sort, putting JPEGs before everything else.
    """
    extension = filename.lower()[filename.rfind('.') + 1:]
    key = 0 if extension in ('jpg', 'jpeg') else 1
    return key, filename


def parse_remainder(args):
    """Parse the remainder of the command line arguments"""
    if len(args) == 0:
        return {}
    if not args[0].startswith(('-', '--')):
        raise ValueError('Only optional arguments allowed')
    kwargs = {}
    curr_arg = args[0]
    curr_val = None
    for arg in args[1:]:
        if arg.startswith(('-', '--')):
            if not curr_val:
                kwargs[curr_arg] = True
            else:
                kwargs[curr_arg] = curr_val
            curr_arg = arg
            curr_val = None
        elif not curr_val:
            cur_val = arg
        elif isinstance(cur_val, list):
            cur_val.append(arg)
        else:
            cur_val = [cur_val]
            cur_val.append(arg)
    return kwargs


def _locate_bin(bins, n):
    """
    Find the bin where list n has ended up: Follow bin references until
    we find a bin that has not moved.
    """
    while bins[n] != n:
        n = bins[n]
    return n


@staticmethod
def _depth_of_child(item):
    """
        Determine the level / depth of a child item in the sequence tree.
        """
    depth = -1
    while item:
        item = item.parent()
        depth += 1
    return depth


def kmerize_contig(contig, kmer_size):
    """Return generator of kmers in contig

    The returned kmers are not lexicographically lowest.

    >>> list(kmerize_contig('ATTT', 3))
    ['ATT', 'TTT']
    """
    assert len(contig) >= kmer_size
    for start in range(len(contig) - kmer_size + 1):
        yield contig[start:start + kmer_size]


def set_compose_session(request):
    """Initialize a new "compose" session.

    It is used to keep track of attachments defined with a new
    message. Each new message will be associated with a unique ID (in
    order to avoid conflicts between users).

    :param request: a Request object.
    :return: the new unique ID.
    """
    import uuid
    randid = str(uuid.uuid4()).replace('-', '')
    request.session['compose_mail'] = {'id': randid, 'attachments': []}
    return randid


def copy(catalog):
    """return a copy of this index, bound to provided catalog."""


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

        :param LegalHoldsReleaseAHoldType val:
        :rtype: EventType
        """
    return cls('legal_holds_release_a_hold', val)


def get_principals_and_permissions():
    """Get all principal permission settings.

        Get the principal security assertions here in the form
        of a list of three tuple containing
        (permission id, principal id, setting)
        """


def parent_node(max_child_node, max_parent_node):
    """
    Parents child node into parent node hierarchy
    :param max_child_node: MaxPlus.INode
    :param max_parent_node: MaxPlus.INode
    """
    max_child_node.SetParent(max_parent_node)
    return max_child_node


def type_object_attrgetter(obj, attr, *defargs):
    """
    This implements an improved attrgetter for type objects (i.e. classes)
    that can handle class attributes that are implemented as properties on
    a metaclass.

    Normally `getattr` on a class with a `property` (say, "foo"), would return
    the `property` object itself.  However, if the class has a metaclass which
    *also* defines a `property` named "foo", ``getattr(cls, 'foo')`` will find
    the "foo" property on the metaclass and resolve it.  For the purposes of
    autodoc we just want to document the "foo" property defined on the class,
    not on the metaclass.

    For example::

        >>> class Meta(type):
        ...     @property
        ...     def foo(cls):
        ...         return 'foo'
        ...
        >>> class MyClass(metaclass=Meta):
        ...     @property
        ...     def foo(self):
        ...         ""\"Docstring for MyClass.foo property.""\"
        ...         return 'myfoo'
        ...
        >>> getattr(MyClass, 'foo')
        'foo'
        >>> type_object_attrgetter(MyClass, 'foo')
        <property at 0x...>
        >>> type_object_attrgetter(MyClass, 'foo').__doc__
        'Docstring for MyClass.foo property.'

    The last line of the example shows the desired behavior for the purposes
    of autodoc.
    """
    for base in obj.__mro__:
        if attr in base.__dict__:
            if isinstance(base.__dict__[attr], property):
                return base.__dict__[attr]
            break
    return getattr(obj, attr, *defargs)


def path_to_uri(path):
    """ Swaps \\ for / Other stuff will happen here in the future.
    """
    return path.replace('\\', '/')


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


@staticmethod
def _unit_to_bytes(unit):
    """Return the value of an unit."""
    if not unit:
        return 1
    unit = unit.upper()
    if unit.startswith('KI'):
        return 1024
    elif unit.startswith('K'):
        return 1000
    elif unit.startswith('MI'):
        return 1048576
    elif unit.startswith('M'):
        return 1000000
    elif unit.startswith('GI'):
        return 1073741824
    elif unit.startswith('G'):
        return 1000000000
    elif unit.startswith('TI'):
        return 1099511627776
    elif unit.startswith('T'):
        return 1000000000000
    else:
        return 1


@staticmethod
def strategy_use_existing(config, path, base, nxt):
    """ use base, and ignore next. """
    return base


def describe_nat_gateways(NatGatewayIds=None, Filters=None, MaxResults=None,
    NextToken=None):
    """
    Describes one or more of the your NAT gateways.
    See also: AWS API Documentation

    Examples
    This example describes the NAT gateway for the specified VPC.
    Expected Output:

    :example: response = client.describe_nat_gateways(
        NatGatewayIds=[
            'string',
        ],
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        MaxResults=123,
        NextToken='string'
    )

    :type NatGatewayIds: list
    :param NatGatewayIds: One or more NAT gateway IDs.
            (string) --

    :type Filters: list
    :param Filters: One or more filters.
            nat-gateway-id - The ID of the NAT gateway.
            state - The state of the NAT gateway (pending | failed | available | deleting | deleted ).
            subnet-id - The ID of the subnet in which the NAT gateway resides.
            vpc-id - The ID of the VPC in which the NAT gateway resides.
            (dict) --A filter name and value pair that is used to return a more specific list of results. Filters can be used to match a set of resources by various criteria, such as tags, attributes, or IDs.
            Name (string) --The name of the filter. Filter names are case-sensitive.
            Values (list) --One or more filter values. Filter values are case-sensitive.
            (string) --

    :type MaxResults: integer
    :param MaxResults: The maximum number of items to return for this request. The request returns a token that you can specify in a subsequent call to get the next set of results.
            Constraint: If the value specified is greater than 1000, we return only 1000 items.

    :type NextToken: string
    :param NextToken: The token to retrieve the next page of results.

    :rtype: dict
    :return: {
        'NatGateways': [
            {
                'VpcId': 'string',
                'SubnetId': 'string',
                'NatGatewayId': 'string',
                'CreateTime': datetime(2015, 1, 1),
                'DeleteTime': datetime(2015, 1, 1),
                'NatGatewayAddresses': [
                    {
                        'PublicIp': 'string',
                        'AllocationId': 'string',
                        'PrivateIp': 'string',
                        'NetworkInterfaceId': 'string'
                    },
                ],
                'State': 'pending'|'failed'|'available'|'deleting'|'deleted',
                'FailureCode': 'string',
                'FailureMessage': 'string',
                'ProvisionedBandwidth': {
                    'Provisioned': 'string',
                    'Requested': 'string',
                    'RequestTime': datetime(2015, 1, 1),
                    'ProvisionTime': datetime(2015, 1, 1),
                    'Status': 'string'
                }
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    pending : The NAT gateway is being created and is not ready to process traffic.
    failed : The NAT gateway could not be created. Check the failureCode and failureMessage fields for the reason.
    available : The NAT gateway is able to process traffic. This status remains until you delete the NAT gateway, and does not indicate the health of the NAT gateway.
    deleting : The NAT gateway is in the process of being terminated and may still be processing traffic.
    deleted : The NAT gateway has been terminated and is no longer processing traffic.

    """
    pass


def log(data=None, out=None, name=None, **kwargs):
    """Returns element-wise Natural logarithmic value of the input.

    The natural logarithm is logarithm in base *e*, so that ``log(exp(x)) = x``

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

    Defined in src/operator/tensor/elemwise_unary_op_logexp.cc:L76

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

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

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


def ParseBool(text):
    """Parse a boolean value.

  Args:
    text: Text to parse.

  Returns:
    Boolean values parsed

  Raises:
    ValueError: If text is not a valid boolean.
  """
    if text in ('true', 't', '1', 'True'):
        return True
    elif text in ('false', 'f', '0', 'False'):
        return False
    else:
        raise ValueError('Expected "true" or "false".')


def staticderived(cls):
    """
    Decorator designed to be used by concreate classes that only implement
    static abstract methods.

    When a concrete class implements an interface, the object's __new__ method
    is used to verify that all methods and properties have been implemented as
    expected.

    Unfortunately, __new__ is only invoked when an instance of an object is created.
    When it comes to static methods, it is possible to invoke the method without
    creating an instance of the object, meaning __new__ will never fire and the
    abstract verification code will never be called.

    This decorator, when used in conjunction with the concrete class based on the
    abstract interface, will ensure that __new__ is properly invoked and that the
    static methods are evaluated.
    """
    cls()
    return cls


def get_page_id(book_url: str) ->int:
    """Gets page if from a book url."""
    return int(book_url.split('/')[-2][1:])


def _is_leap(year):
    """year -> 1 if leap year, else 0."""
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)


@staticmethod
def deserialize(data: bytes) ->object:
    """Create a _key object from bytes."""
    raise NotImplementedError


def force_bytes(value):
    """
    Forces a Unicode string to become a bytestring.
    """
    if isinstance(value, str):
        value = value.encode('utf-8', 'backslashreplace')
    return value


@classmethod
def initialize(cls, config, logger, *args, **kwargs):
    """Initialize class attributes

        Since drivers may need to cache thing short-term. The emulator
        instantiates the driver every time it serves a client query.

        Driver objects can cache whenever it makes sense for the duration
        of a single session. It is guaranteed that the driver object will
        never be reused for any other session.

        The `initialize` method is provided to set up the driver in a way
        that would affect all the subsequent sessions.

        :params config: system configuration dict
        :params logger: system logger object
        :params *args: driver-specific parameters
        :params **kwargs: driver-specific parameters
        :returns: initialized driver class
        """
    return cls


def primeFactors(x):
    """
    primeFactors(n) takes an argument for which the Prime Factors are to be calculated
    :param n: any integer
    """
    print('Prime Factors are:')
    i = 1
    while i <= x:
        k = 0
        if x % i == 0:
            j = 1
            while j <= i:
                if i % j == 0:
                    k = k + 1
                j = j + 1
            if k == 2:
                print(i)
        i = i + 1


def load_reportlab(finder, module):
    """the reportlab module loads a submodule rl_settings via exec so force
       its inclusion here"""
    finder.IncludeModule('reportlab.rl_settings')


@staticmethod
def initial(connection, *args, **kwargs):
    """
        Метод вызывается перед отправкой любой команды, он должен вернуть сформированный message
        для последующей отправки
        """
    raise NotImplemented('Initialization method not implemented yet')


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


@classmethod
def lazy(cls, *lazy_init_args, **lazy_init_kwargs):
    """Create a lazily instantiated instance of the subclass, cls."""
    return cls._proxy(*lazy_init_args, **lazy_init_kwargs)


def to_utc(df):
    """
    For use in tests; applied UTC timestamp to DataFrame.
    """
    try:
        df.index = df.index.tz_localize('UTC')
    except TypeError:
        df.index = df.index.tz_convert('UTC')
    return df


@classmethod
def disassemble(cls, *args):
    """
        Disassemble the integer arguments into an operation. Subclasses do not
        generally need to override this method; it is provided only for the special
        purposes of the INC and DEC classes.
        """
    return cls(*args)


def ndarray(typed_array, shape, dtype):
    """Return a ndarray."""
    _dtype = type(typed_array)
    if dtype and dtype != _dtype:
        raise Exception("dtype doesn't match the type of the array: " +
            _dtype + ' != ' + dtype)
    shape = shape or (len(typed_array),)
    return {'__jailed_type__': 'ndarray', '__value__': typed_array,
        '__shape__': shape, '__dtype__': _dtype}


def _get_text(topnode):
    """Get the text values in the child nodes."""
    text = ''
    for node in topnode.childNodes:
        if node.nodeType == node.TEXT_NODE:
            text = text + node.data
    return text


def annotate_bus_names(n, ax, shift=-0.012, size=12, color='darkslategray',
    **kwargs):
    """
    Annotate names of buses plot.

    Parameters
    ----------
    n : pypsa.Network
    ax : matplotlib axis
    shift : float/tuple
        Shift of the text with respect to the x and y bus coordinate.
        The default is -0.012.
    size : float, optional
        Text size. The default is 12.
    color : string, optional
        Text color. The default is 'k'.
    **kwargs : dict
        Keyword arguments going to ax.text() function. For example:

        - transform=ccrs.PlateCarree()
        - bbox=dict(facecolor='white', alpha=0.5, edgecolor='None')

    """
    kwargs.setdefault('zorder', 8)
    for index in n.buses.index:
        x, y = n.buses.loc[index, ['x', 'y']] + shift
        text = ax.text(x, y, index, size=size, color=color, ha='center', va
            ='center', **kwargs)
    return text


def chunks(l, n):
    """Yield successive n-sized chunks from l.
    Source: http://stackoverflow.com/a/312464
    """
    if n > 0:
        for i in range(0, len(l), n):
            yield l[i:i + n]
    else:
        yield l


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 get_homopol_run(var):
    """
    Return the largest contiguous homopolymer run of the variant allele,
    or None if it isn't present in the VCF.
    """
    return var.INFO.get('HRun')


def bitarray_to_bytes(b):
    """Convert a bitarray to bytes."""
    return b.tobytes()


def prop(func):
    """Function decorator for defining property attributes

    The decorated function is expected to return a dictionary
    containing one or more of the following pairs:

        fget - function for getting attribute value
        fset - function for setting attribute value
        fdel - function for deleting attribute

    This can be conveniently constructed by the locals() builtin
    function; see:
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/205183
    """
    return property(doc=func.__doc__, **func())


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

        :returns: this backend supports items resuming
        """
    return True


def any_branch(string, success):
    """
    Parser function that modifies the output of the 'branch-any' command.
    This removes the 'heads/' part from the output for a regular branch.
    """
    if success is not True:
        return string
    if 'heads/' in string:
        string = string.replace('heads/', '')
    return string


@classmethod
def convert(cls, var_name, initial_unit, desired_unit, df):
    """
        Givin a valid initial and desired variable dimension for a variable
        within a :obj:`pandas.DataFrame`, make the conversion and return the
        updated :obj:`pandas.DataFrame`.

        For a list of variables that require certain units within
        ``flux-data-qaqc`` see :attr:`Convert.allowable_units` (names of
        allowable options of input variable dimensions) and
        :attr:`Convert.required_units` (for the mandatory dimensions of certain
        variables before running QaQc calculations).

        Arguments:
            var_name (str): name of variable to convert in ``df``.
            initial_unit (str): name of initial unit of variable, must be valid
                from :attr:`Convert.allowable_units`.
            desired_unit (str): name of units to convert to, also must be valid.
            df (:obj:`pandas.DataFrame`): :obj:`pandas.DataFrame` containing
                variable to be converted, i.e. with ``var_name`` in columns.

        Returns:
            df (:obj:`pandas.DataFrame`): updated dataframe with specified variable's units converted

        Note:
            Many potential dimensions may not be provided for automatic
            conversion, if so you may need update your variable dimensions
            manually, e.g. within a :attr:`.Data.df` before creating a
            :obj:`.QaQc` instance. Unit conversions are required for
            variables that can potentially be used in calculations within
            :obj:`.QaQc`.

        """
    conv = cls()
    convert_key = '{}_to_{}'.format(initial_unit, desired_unit)
    convert_func = conv._conversion_map[convert_key]
    print('Converting {} from {} to {}'.format(var_name, initial_unit,
        desired_unit))
    df = convert_func(df, var_name)
    return df


def write():
    """Write strings to the POT file."""


def _get_network_output(spec):
    """
    :param spec : CoreML Specification
    :returns network output names
    """
    network_output_names = []
    for _out in spec.description.output:
        network_output_names.append(_out.name)
    return network_output_names


def create_request_validator(restApiId=None, name=None, validateRequestBody
    =None, validateRequestParameters=None):
    """
    Creates a  ReqeustValidator of a given  RestApi .
    See also: AWS API Documentation

    :example: response = client.create_request_validator(
        restApiId='string',
        name='string',
        validateRequestBody=True|False,
        validateRequestParameters=True|False
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            [Required] The identifier of the RestApi for which the RequestValidator is created.

    :type name: string
    :param name: The name of the to-be-created RequestValidator .

    :type validateRequestBody: boolean
    :param validateRequestBody: A Boolean flag to indicate whether to validate request body according to the configured model schema for the method (true ) or not (false ).

    :type validateRequestParameters: boolean
    :param validateRequestParameters: A Boolean flag to indicate whether to validate request parameters, true , or not false .

    :rtype: dict
    :return: {
        'id': 'string',
        'name': 'string',
        'validateRequestBody': True|False,
        'validateRequestParameters': True|False
    }

    """
    pass


def lnotab(pairs, first_lineno=0):
    """Yields byte integers representing the pairs of integers passed in."""
    assert first_lineno <= pairs[0][1]
    cur_byte, cur_line = 0, first_lineno
    for byte_off, line_off in pairs:
        byte_delta = byte_off - cur_byte
        line_delta = line_off - cur_line
        assert byte_delta >= 0
        assert line_delta >= 0
        while byte_delta > 255:
            yield 255
            yield 0
            byte_delta -= 255
        yield byte_delta
        while line_delta > 255:
            yield 255
            yield 0
            line_delta -= 255
        yield line_delta
        cur_byte, cur_line = byte_off, line_off


def apply_cooling(enduse, fuel_y, cooled_floorarea, cooled_floorarea_p_by,
    curr_yr):
    """Apply changes for cooling enduses depending
    on assumption of how much of the floor area in percent
    is cooled

    It is aassumption a linear correlation between the
    percentage of cooled floor space (area) and energy demand.

    Arguments
    ---------
    enduse : str
        Enduse
    fuel_y : array
        Annual fuel demand
    cooled_floorarea : dict
        Strategy variables
    cooled_floorarea_p_by : dict
        Assumption about cooling floor area in base year
    curr_yr : int
        Current year

    Returns
    -------
    fuel_y : array
        Fuel array (either changed fuel depending on cooling percentage)
        of identical array
    """
    try:
        cooled_floorarea_p_cy = cooled_floorarea[enduse][curr_yr]
        floorarea_cooling_factor = (cooled_floorarea_p_cy /
            cooled_floorarea_p_by)
        fuel_y = fuel_y * floorarea_cooling_factor
    except KeyError:
        pass
    return fuel_y


def inv_entry_to_path(data):
    """
    Determine the path from the intersphinx inventory entry

    Discard the anchors between head and tail to make it
    compatible with situations where extra meta information is encoded.
    """
    path_tuple = data[2].split('#')
    if len(path_tuple) > 1:
        path_str = '#'.join((path_tuple[0], path_tuple[-1]))
    else:
        path_str = data[2]
    return path_str


def get_skill_state(name, device_skill_state) ->dict:
    """Find a skill entry in the device skill state and returns it."""
    skill_state_return = {}
    for skill_state in device_skill_state.get('skills', []):
        if skill_state.get('name') == name:
            skill_state_return = skill_state
    return skill_state_return


def select_circle(x: int=0, y: int=0, radius: int=1, gesture_mode: int=0):
    """Select Grease Pencil strokes using brush selection

    :param x: X
    :type x: int
    :param y: Y
    :type y: int
    :param radius: Radius
    :type radius: int
    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    """
    pass


def get_str_arg(r, name, default=None):
    """
    Retrieve argument from :attr:`flask:flask.request` and convert to string

    :param r: :attr:`flask:flask.request`
    :param name: argument name
    :type: str
    :param default: default value if parameter is non-existent, defaults to None
    :return: string argument value
    """
    val = r.args.get(name)
    if val is None or val == '':
        return default
    else:
        try:
            return str(val)
        except BaseException:
            return default


def prefixes(seq):
    """
    Generate all prefixes of a sequence.

    Examples
    ========

    >>> list(prefixes([1, 2, 3, 4]))
    [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]

    """
    n = len(seq)
    for i in range(n):
        yield seq[:i + 1]


@classmethod
def zeros(cls, *shape):
    """
        Return a sparse N-dim array of zeros.
        """
    return cls({}, shape)


def _to_skybell_level(level):
    """Convert the given Home Assistant light level (0-255) to Skybell (0-100)."""
    return int(level * 100 / 255)


def signal(signum, ref=True, priority=None):
    """
        Create and return a signal watcher for the signal *signum*,
        one of the constants defined in :mod:`signal`.

        This is platform and event loop specific.
        """


def vertex_color_add():
    """Add vertex color layer

    """
    pass


def task_detect(task, task_config):
    """
    监控任务的检测，对任务是否已完成，任务完成质量的检测
    :param task: 任务信息
    :param task_config: 任务的配置信息
    :return: content，报警信息，若检测通过返回空字符串
    """
    content = ''
    queue_length = int(task[b'queue_length'])
    left = int(task[b'left'])
    if left < 0:
        content += f'Abnormal data:: left: {left}
'
    else:
        if left > 0:
            content += f'任务未完成:: {left} left
'
        if task_config.get(b'failure_rate_up') and task.get(b'failed'):
            failure_rate = float(task[b'failed']) / (queue_length - left)
            failure_rate_up = float(task_config[b'failure_rate_up'])
            if failure_rate > failure_rate_up:
                content += (
                    f'失败率超标:: {round(failure_rate, 2)} > {failure_rate_up}
'
                    )
        if task_config.get(b'avg_time_up') and task.get(b'crawl_time'):
            avg_time = float(task[b'crawl_time']) / (queue_length - left)
            avg_time_up = float(task_config[b'avg_time_up'])
            if avg_time > avg_time_up:
                content += f'爬取时长超标:: {round(avg_time, 2)} > {avg_time_up}'
    return content


def counts_to_rate(signal, measurement_interval):
    """
    Transform signal from counts to count rate.

    Parameters
    ----------
    signal: array
       The input signal array
    measurement_interval: float
       The total measurement interval in s

    Returns
    -------
    rate: array
       Count rate signal
    """
    rate = signal / measurement_interval
    return rate


def validate_list(arg, choices):
    """
    Make sure the argument is in the list of choices passed to the function
    """
    if arg not in choices:
        raise ValueError('Value not in list: %s' % str(choices))


@classmethod
def byvolume(cls, base, *parts, **kw):
    """
        Returns an alloy defined by relative volume of the constituents.

        Mixture.byvolume(M1, M2, F2, ..., name='mixture name')
        """
    return cls(base, parts, by='volume', **kw)


@staticmethod
def is_pluggable_section(section_name):
    """ check if section is a pluggable """
    from qiskit.aqua.parser import BaseParser
    return BaseParser.is_pluggable_section(section_name)


def is_valid(stencil, max_neighborhood=None):
    """
    Tests if a nested sequence is a valid stencil i.e. all the inner sequences have the same length.
    If max_neighborhood is specified, it is also verified that the stencil does not contain any direction components
    with absolute value greater than the maximal neighborhood.

    Examples:
        >>> is_valid([(1, 0), (1, 0, 0)])  # stencil entries have different length
        False
        >>> is_valid([(2, 0), (1, 0)])
        True
        >>> is_valid([(2, 0), (1, 0)], max_neighborhood=1)
        False
    """
    expected_dim = len(stencil[0])
    for d in stencil:
        if len(d) != expected_dim:
            return False
        if max_neighborhood is not None:
            for d_i in d:
                if abs(d_i) > max_neighborhood:
                    return False
    return True


def timedelta_to_seconds(td):
    """Equivalent to td.total_seconds() (introduced in python 2.7)."""
    return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6
        ) / float(10 ** 6)