def cache_clear(cache):
    """Clears cache with the given name.

    :param str|unicode cache: Cache name with optional address (if @-syntax is used).

    :rtype: None
    """


@classmethod
def backend_version(cls):
    """ Returns which backend is used.

        Returns:
            `str`: The name and version of the backend(s).
        """
    cls._setup_backends()
    return ', '.join(cls._backend_versions)


def trim_zenodo_link(path):
    """Trim a zenodo download link to extract file name.

    e.g. https://zenodo.org/record/3369410/files/gwas.txt.gz?download=1
    -> https://zenodo.org/record/3369410/files/gwas.txt.gz
    """
    path = path.replace('?download=1', '')
    return path


def isCryptographyAdvanced():
    """
    Check if the cryptography library is present, and if it supports X25519,
    ChaCha20Poly1305 and such (v2.0 or later).
    """
    try:
        from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
        X25519PrivateKey.generate()
    except Exception:
        return False
    else:
        return True


def get_float_value(obj):
    """
    Returns float from LLDB value.

    :param lldb.SBValue obj: LLDB value object.
    :return: float from LLDB value.
    :rtype: float | None
    """
    if obj:
        value = obj.GetValue()
        return None if value is None else float(value)
    return None


def dpad_down_heading(controller):
    """
    Callback function that is triggered, when the direction down was pressed

    :param controller:              the controller that triggered the action
    :type controller:               steuer.Controller
    """
    print('DIRECTION:' + str(controller.number) + ':' + controller.name +
        ':DPAD Down heading')


def get_roster(role):
    """Return the appropriate roster for the given role.

        :param role: The requested roster's role.
        :type role: MemberRole
        :return: The requested roster.
        :rtype: Roster
        """


def make_identifier(headername):
    """Make #ifndef identifier that contains uppercase A-Z and digits 0-9"""
    result = ''
    for c in headername.upper():
        if c.isalnum():
            result += c
        else:
            result += '_'
    return result


def get_complete_version(version):
    """
    Returns a tuple of the version. If version argument is non-empty,
    then checks for correctness of the tuple provided.
    """
    if not version:
        return 0, 0, 1, 'alpha', 0
    assert len(version) == 5
    assert version[3] in ('alpha', 'beta', 'rc', 'final')
    return version


def on_off_bool(value):
    """Convert on/off to True/False correspondingly."""
    return value == 'on'


def remap(src, mapping, out=None, inplace=False):
    """Remap elements in an id array.

    Parameters
    ----------
    src : ndarray of int
        Initial array of ids.
    mapping : ndarray of int
        Mapping of ids.
    out : ndarray of int, optional
        Buffer into which to place output.
    inplace : bool, optional
        Mapping of values will include inplace.

    Returns
    -------
    ndarray of int
        Array of remapped values.

    Examples
    --------
    >>> from landlab.graph.sort.sort import remap
    >>> import numpy as np

    >>> src = np.array([1, 2, 3, 4])
    >>> mapping = np.array([-1, 10, 20, 30, 40])
    >>> remap(src, mapping)
    array([10, 20, 30, 40])
    """
    from .ext.remap_element import remap_graph_element
    if inplace:
        out = src
    elif out is None:
        out = src.copy()
    else:
        out[:] = src[:]
    remap_graph_element(out.reshape((-1,)), mapping)
    return out


@classmethod
def _get_version(cls):
    """Return VCS program version."""
    return cls._popen(['--version'], merge_err=False).split()[-1]


@staticmethod
def _acronym_status(status_statement):
    """Convert development status acronym."""
    return status_statement.split(' - ')[1]


def isretweet(tweet):
    """
    Checks if a given tweet is a retweet.
    If tweet is a string, returns True when text starts with 'RT '.
    If tweet is a tweepy.Status object, returns True when ``retweeted_status`` or
    ``retweeted_status_id`` is set.

    Args:
        tweet (str/tweepy.Status/dict): A string, tweepy.Status object, or Status-like dict.

    Returns:
        bool
    """
    try:
        return bool(tweet.retweeted)
    except AttributeError:
        try:
            return bool(tweet.get('retweeted_status') or tweet.get(
                'retweeted_status_id'))
        except AttributeError:
            try:
                return tweet[:3].upper() == 'RT '
            except AttributeError:
                pass
    return False


@staticmethod
def read(sile, *args, **kwargs):
    """ Reads the supercell from the `Sile` using ``Sile.read_supercell``

        Parameters
        ----------
        sile : Sile, str or pathlib.Path
            a `Sile` object which will be used to read the supercell
            if it is a string it will create a new sile using `sisl.io.get_sile`.
        """
    from sisl.io import get_sile, BaseSile
    if isinstance(sile, BaseSile):
        return sile.read_supercell(*args, **kwargs)
    else:
        with get_sile(sile) as fh:
            return fh.read_supercell(*args, **kwargs)


def _parse_short_form(comment, globalns, localns):
    """Return the hints from the comment.

    Parses the left-hand side of a type comment into a list of type objects.
    (e.g. everything to the left of "->").

    Returns:
        A list of types evaluated from the type comment in the given global
        name space.
    """
    if '(...)' in comment:
        return ()
    comment = comment.replace('*', '')
    hints = eval(comment, globalns, localns)
    if not isinstance(hints, tuple):
        hints = hints,
    return hints


def _is_next_word(prev_word, x, y):
    """Checks if previous - current word are located correctly."""
    if (prev_word.x + prev_word.width + 10 >= x and y - 5 <= prev_word.y <=
        y + 5):
        return True
    return False


@classmethod
def _flatten_mapping(cls, mapping, prefix=''):
    """Flatten a mapping for rendering templates."""
    new_mapping = {}
    for key, value in list(mapping.items()):
        if isinstance(value, dict):
            value = cls._flatten_mapping(value, prefix + '_' + key if
                prefix else key)
            new_mapping.update(value)
        else:
            new_mapping[prefix + '_' + key if prefix else key] = value
    return new_mapping


def _issetf_(flags, flag):
    """
      determines if flag is set
      :param flags: current flag value
      :param flag: flag to check
      :return: True if flag is set
     """
    return flags & flag == flag


def insert_duplicate_kanji(kanji_string):
    """
    Inserts full kanji for characters where a shorthand is used.

        >>> k = insert_duplicate_kanji(u'私々')
        >>> expected = u'私私'
        >>> k == expected
        True
    """
    loc = kanji_string.find('々')
    while loc > 0:
        dup = kanji_string[loc - 1]
        kanji_string = kanji_string[:loc] + dup + kanji_string[loc + 1:]
        loc = kanji_string.find('々')
    return kanji_string


@staticmethod
def create_deletion_id(client, container, name):
    """Create a unique deletion id
        :param azure.storage.StorageClient client: storage client
        :param str container: container name
        :param str name: entity name
        :rtype: str
        :return: unique id for deletion
        """
    return ';'.join((client.primary_endpoint, container, name))


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 init_jsobject(cls, bridge, name, value, description=None):
    """Initialize a JS object that is a subclassed base type.

    Arguments:
    cls -- Class the object has to be created from
    bridge -- JSBridge instance to use
    name -- Name of the JS object
    value -- Value of the object wrapped as JS object

    Keyword arguments:
    description -- Additional information about the object

    """
    obj = cls(value)
    obj._bridge_ = bridge
    obj._name_ = name
    obj._description_ = description
    return obj


def _is_sunder(name):
    """Returns True if a _sunder_ name, False otherwise."""
    return len(name) > 2 and name[0] == name[-1] == '_' and name[1:2
        ] != '_' and name[-2:-1] != '_'


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 package_info(rows: str) ->str:
    """
    Parse html sections
    :param rows:
    :return:
    """
    last = 'nozips'
    for row in rows:
        try:
            url = row.split('"')[1]
            if '.zip' in url or '.gz' in url:
                print(url)
                last = url
        except:
            pass
    return last


def _accumulate(iterable, fn=lambda x, y: x + y):
    """Return running totals"""
    it = iter(iterable)
    try:
        total = next(it)
    except StopIteration:
        return
    yield total
    for element in it:
        total = fn(total, element)
        yield total


@classmethod
def get_shutdown_key(cls):
    """Return the key used to flag to workers that they should shutdown"""
    return f'{cls.get_id_prefix()}_shutdown'


def clean_non_printable_char(m):
    """Strip non printable characters."""
    code = int(m.group(0)[1:], 16)
    if code < 20:
        return ''
    return m.group(0)


def _line_parse(line):
    """Removes line ending characters and returns a tuple (`stripped_line`,
    `is_terminated`).
    """
    if line[-2:] in ['\r\n', b'\r\n']:
        return line[:-2], True
    elif line[-1:] in ['\r', '\n', b'\r', b'\n']:
        return line[:-1], True
    return line, False


def check_logic(args):
    """Some arguments/options are not compatible, or required jointly. This
    function checks them and may raise Exceptions if logic rules are failed."""
    if (args.bg or len(args.files) > 0) and (args.config or args.experiment):
        msg = 'Offline mode and XNAT options cannot be used simultaneously'
        raise Exception(msg)
    if (args.bg or len(args.files) > 0) and args.cache:
        msg = '--cache can be used in XNAT mode only.'
        raise Exception(msg)
    if args.config:
        if not args.experiment:
            msg = 'Missing option --experiment'
            raise Exception(msg)
    if args.experiment:
        if not args.config:
            msg = 'Missing option --config'
            raise Exception(msg)
    if args.nobg and args.opacity:
        msg = 'Warning. --nobg and --opacity used simultaneously.'
        raise Exception(msg)
    if args.opacity and not args.config:
        if not args.bg:
            msg = 'Missing option --bg'
            raise Exception(msg)
    if not args.config:
        if len(args.files) == 0 or len(args.files) > 3:
            msg = 'List of files must be of length 1, 2 or 3.'
            raise Exception(msg)
    if not args.opacity:
        args.opacity = 90
    if args.output.endswith('.gif') and (args.config and args.nobg or not
        args.config and not args.bg):
        msg = 'GIF animation can be created only providing a background image.'
        raise Exception(msg)
    if args.disable_warnings:
        import urllib3
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    import logging as log
    logger = log.getLogger()
    if args.verbose:
        logger.setLevel(level=log.DEBUG)
    else:
        logger.setLevel(level=log.INFO)


def stop_user_import_job(UserPoolId=None, JobId=None):
    """
    Stops the user import job.
    See also: AWS API Documentation

    :example: response = client.stop_user_import_job(
        UserPoolId='string',
        JobId='string'
    )

    :type UserPoolId: string
    :param UserPoolId: [REQUIRED]
            The user pool ID for the user pool that the users are being imported into.

    :type JobId: string
    :param JobId: [REQUIRED]
            The job ID for the user import job.

    :rtype: dict
    :return: {
        'UserImportJob': {
            'JobName': 'string',
            'JobId': 'string',
            'UserPoolId': 'string',
            'PreSignedUrl': 'string',
            'CreationDate': datetime(2015, 1, 1),
            'StartDate': datetime(2015, 1, 1),
            'CompletionDate': datetime(2015, 1, 1),
            'Status': 'Created'|'Pending'|'InProgress'|'Stopping'|'Expired'|'Stopped'|'Failed'|'Succeeded',
            'CloudWatchLogsRoleArn': 'string',
            'ImportedUsers': 123,
            'SkippedUsers': 123,
            'FailedUsers': 123,
            'CompletionMessage': 'string'
        }
    }

    :returns:
    Created - The job was created but not started.
    Pending - A transition state. You have started the job, but it has not begun importing users yet.
    InProgress - The job has started, and users are being imported.
    Stopping - You have stopped the job, but the job has not stopped importing users yet.
    Stopped - You have stopped the job, and the job has stopped importing users.
    Succeeded - The job has completed successfully.
    Failed - The job has stopped due to an error.
    Expired - You created a job, but did not start the job within 24-48 hours. All data associated with the job was deleted, and the job cannot be started.

    """
    pass


def no_op(*_, **__):
    """
    This is a no-op. It takes any arguments,
    keyword or positional, and returns none
    """
    return


def create_sql_injection_match_set(Name=None, ChangeToken=None):
    """
    Creates a  SqlInjectionMatchSet , which you use to allow, block, or count requests that contain snippets of SQL code in a specified part of web requests. AWS WAF searches for character sequences that are likely to be malicious strings.
    To create and configure a SqlInjectionMatchSet , perform the following steps:
    For more information about how to use the AWS WAF API to allow or block HTTP requests, see the AWS WAF Developer Guide .
    See also: AWS API Documentation

    Examples
    The following example creates a SQL injection match set named MySQLInjectionMatchSet.
    Expected Output:

    :example: response = client.create_sql_injection_match_set(
        Name='string',
        ChangeToken='string'
    )

    :type Name: string
    :param Name: [REQUIRED]
            A friendly name or description for the SqlInjectionMatchSet that you're creating. You can't change Name after you create the SqlInjectionMatchSet .

    :type ChangeToken: string
    :param ChangeToken: [REQUIRED]
            The value returned by the most recent call to GetChangeToken .

    :rtype: dict
    :return: {
        'SqlInjectionMatchSet': {
            'SqlInjectionMatchSetId': 'string',
            'Name': 'string',
            'SqlInjectionMatchTuples': [
                {
                    'FieldToMatch': {
                        'Type': 'URI'|'QUERY_STRING'|'HEADER'|'METHOD'|'BODY',
                        'Data': 'string'
                    },
                    'TextTransformation': 'NONE'|'COMPRESS_WHITE_SPACE'|'HTML_ENTITY_DECODE'|'LOWERCASE'|'CMD_LINE'|'URL_DECODE'
                },
            ]
        },
        'ChangeToken': 'string'
    }

    :returns:
    Name (string) -- [REQUIRED]
    A friendly name or description for the  SqlInjectionMatchSet that you're creating. You can't change Name after you create the SqlInjectionMatchSet .

    ChangeToken (string) -- [REQUIRED]
    The value returned by the most recent call to  GetChangeToken .

    """
    pass


def write_axsf(ofile, c):
    """ Write the Crys in .axsf file format"""
    print('ANIMSTEPS 1', file=ofile)
    print('CRYSTAL', file=ofile)
    print('PRIMVEC 1', file=ofile)
    for k in range(3):
        print('     %8.5f %8.5f %8.5f' % (c.matrix[k][0], c.matrix[k][1], c
            .matrix[k][2]), file=ofile)
    print('PRIMCOORD 1', file=ofile)
    print('%d 1' % c.natom, file=ofile)
    for i in range(c.natom):
        print('%3s %8.3f %8.3f %8.3f ' % (c.atom_element[i], c.atom_xyz[i][
            0], c.atom_xyz[i][1], c.atom_xyz[i][2]), file=ofile)
    return


def _min_cells(clump, n_cells):
    """True if clump has a minimum number of cells."""
    return clump['index', 'ones'].size >= n_cells


def extractResponse(cls, request, is_member_str):
    """Take a C{L{TeamsRequest}} and a list of Launchpad
        team values and create a C{L{TeamsResponse}}
        object containing that data.

        @param request: The Launchpad teams request object
        @type request: TeamsRequest

        @param is_member: The Launchpad teams data for this
            response, as a list of strings.
        @type is_member: {str:str}

        @returns: a Launchpad teams response object
        @rtype: TeamsResponse
        """
    self = cls()
    self.ns_uri = request.ns_uri
    self.is_member = is_member_str.split(',')
    return self


def migrate(engine):
    """Replace 'backend' with 'store' in meta_data column of image_locations"""
    sql_query = (
        'UPDATE image_locations SET meta_data = REPLACE(meta_data, \'"backend":\', \'"store":\') where INSTR(meta_data,  \'"backend":\') > 0'
        )
    if engine.name == 'postgresql':
        sql_query = (
            'UPDATE image_locations SET meta_data = REPLACE(meta_data, \'"backend":\', \'"store":\') where POSITION(\'"backend":\' IN meta_data) > 0'
            )
    with engine.connect() as con:
        migrated_rows = con.execute(sql_query)
        return migrated_rows.rowcount


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

        :param PaperContentRestoreType val:
        :rtype: EventType
        """
    return cls('paper_content_restore', val)


def get_short_object_id(cid):
    """return shortened contribution ID (ObjectId) for `cid`.

    >>> get_short_object_id('5a8638add4f144413451852a')
    '451852a'
    >>> get_short_object_id('5a8638add4f1400000000000')
    '5a8638a'
    """
    length = 7
    cid_short = str(cid)[-length:]
    if cid_short == '0' * length:
        cid_short = str(cid)[:length]
    return cid_short


def convert_3d_counts_to_cf(ND1, ND2, NR1, NR2, D1D2, D1R2, D2R1, R1R2,
    estimator='LS'):
    """
    Converts raw pair counts to a correlation function.

    Parameters
    ----------

    ND1 : integer
       Number of points in the first dataset

    ND2 : integer
        Number of points in the second dataset

    NR1 : integer
        Number of points in the randoms for first dataset

    NR2 : integer
        Number of points in the randoms for second dataset

    D1D2 : array-like, integer
        Pair-counts for the cross-correlation between D1 and D2

    D1R2 : array-like, integer
        Pair-counts for the cross-correlation between D1 and R2

    D2R1 : array-like, integer
        Pair-counts for the cross-correlation between D2 and R1

    R1R2 : array-like, integer
        Pair-counts for the cross-correlation between R1 and R2

    For all of these pair-counts arrays, the corresponding ``numpy``
    struct returned by the theory/mocks modules can also be passed

    estimator: string, default='LS' (Landy-Szalay)
        The kind of estimator to use for computing the correlation
        function. Currently, only supports Landy-Szalay

    Returns
    ---------

    cf : A numpy array
        The correlation function, calculated using the chosen estimator,
        is returned. NAN is returned for the bins where the ``RR`` count
        is 0.

    Example
    --------

    >>> from __future__ import print_function
    >>> import numpy as np
    >>> from Corrfunc.theory.DD import DD
    >>> from Corrfunc.io import read_catalog
    >>> from Corrfunc.utils import convert_3d_counts_to_cf
    >>> X, Y, Z = read_catalog()
    >>> N = len(X)
    >>> boxsize = 420.0
    >>> rand_N = 3*N
    >>> seed = 42
    >>> np.random.seed(seed)
    >>> rand_X = np.random.uniform(0, boxsize, rand_N)
    >>> rand_Y = np.random.uniform(0, boxsize, rand_N)
    >>> rand_Z = np.random.uniform(0, boxsize, rand_N)
    >>> nthreads = 2
    >>> rmin = 0.1
    >>> rmax = 15.0
    >>> nbins = 10
    >>> bins = np.linspace(rmin, rmax, nbins + 1)
    >>> autocorr = 1
    >>> DD_counts = DD(autocorr, nthreads, bins, X, Y, Z)
    >>> autocorr = 0
    >>> DR_counts = DD(autocorr, nthreads, bins,
    ...                X, Y, Z,
    ...                X2=rand_X, Y2=rand_Y, Z2=rand_Z)
    >>> autocorr = 1
    >>> RR_counts = DD(autocorr, nthreads, bins, rand_X, rand_Y, rand_Z)
    >>> cf = convert_3d_counts_to_cf(N, N, rand_N, rand_N,
    ...                              DD_counts, DR_counts,
    ...                              DR_counts, RR_counts)
    >>> for xi in cf: print("{0:10.6f}".format(xi))
    ...                    # doctest: +NORMALIZE_WHITESPACE
    22.769019
     3.612709
     1.621372
     1.000969
     0.691646
     0.511819
     0.398872
     0.318815
     0.255643
     0.207759

    """
    import numpy as np
    pair_counts = dict()
    fields = ['D1D2', 'D1R2', 'D2R1', 'R1R2']
    arrays = [D1D2, D1R2, D2R1, R1R2]
    for field, array in zip(fields, arrays):
        try:
            npairs = array['npairs']
            pair_counts[field] = npairs
        except IndexError:
            pair_counts[field] = array
    nbins = len(pair_counts['D1D2'])
    if nbins != len(pair_counts['D1R2']) or nbins != len(pair_counts['D2R1']
        ) or nbins != len(pair_counts['R1R2']):
        msg = 'Pair counts must have the same number of elements (same bins)'
        raise ValueError(msg)
    nonzero = pair_counts['R1R2'] > 0
    if 'LS' in estimator or 'Landy' in estimator:
        fN1 = np.float(NR1) / np.float(ND1)
        fN2 = np.float(NR2) / np.float(ND2)
        cf = np.zeros(nbins)
        cf[:] = np.nan
        cf[nonzero] = (fN1 * fN2 * pair_counts['D1D2'][nonzero] - fN1 *
            pair_counts['D1R2'][nonzero] - fN2 * pair_counts['D2R1'][
            nonzero] + pair_counts['R1R2'][nonzero]) / pair_counts['R1R2'][
            nonzero]
        if len(cf) != nbins:
            msg = (
                'Bug in code. Calculated correlation function does not have the same number of bins as input arrays. Input bins ={0} bins in (wrong) calculated correlation = {1}'
                .format(nbins, len(cf)))
            raise RuntimeError(msg)
    else:
        msg = (
            "Only the Landy-Szalay estimator is supported. Pass estimator='LS'. (Got estimator = {0})"
            .format(estimator))
        raise ValueError(msg)
    return cf


def defocus(rho, phi):
    """Zernike defocus."""
    return 2 * rho ** 2 - 1


def send_test_event_notification(Notification=None, TestEventType=None):
    """
    The SendTestEventNotification operation causes Amazon Mechanical Turk to send a notification message as if a HIT event occurred, according to the provided notification specification. This allows you to test notifications without setting up notifications for a real HIT type and trying to trigger them using the website. When you call this operation, the service attempts to send the test notification immediately.
    See also: AWS API Documentation

    :example: response = client.send_test_event_notification(
        Notification={
            'Destination': 'string',
            'Transport': 'Email'|'SQS',
            'Version': 'string',
            'EventTypes': [
                'AssignmentAccepted'|'AssignmentAbandoned'|'AssignmentReturned'|'AssignmentSubmitted'|'AssignmentRejected'|'AssignmentApproved'|'HITCreated'|'HITExpired'|'HITReviewable'|'HITExtended'|'HITDisposed'|'Ping',
            ]
        },
        TestEventType='AssignmentAccepted'|'AssignmentAbandoned'|'AssignmentReturned'|'AssignmentSubmitted'|'AssignmentRejected'|'AssignmentApproved'|'HITCreated'|'HITExpired'|'HITReviewable'|'HITExtended'|'HITDisposed'|'Ping'
    )

    :type Notification: dict
    :param Notification: [REQUIRED]
            The notification specification to test. This value is identical to the value you would provide to the UpdateNotificationSettings operation when you establish the notification specification for a HIT type.
            Destination (string) -- [REQUIRED]The destination for notification messages. or email notifications (if Transport is Email), this is an email address. For Amazon Simple Queue Service (Amazon SQS) notifications (if Transport is SQS), this is the URL for your Amazon SQS queue.
            Transport (string) -- [REQUIRED]The method Amazon Mechanical Turk uses to send the notification. Valid Values: Email | SQS.
            Version (string) --The version of the Notification API to use. Valid value is 2006-05-05.
            EventTypes (list) --The list of events that should cause notifications to be sent. Valid Values: AssignmentAccepted | AssignmentAbandoned | AssignmentReturned | AssignmentSubmitted | AssignmentRejected | AssignmentApproved | HITCreated | HITExtended | HITDisposed | HITReviewable | HITExpired | Ping. The Ping event is only valid for the SendTestEventNotification operation.
            (string) --

    :type TestEventType: string
    :param TestEventType: [REQUIRED]
            The event to simulate to test the notification specification. This event is included in the test message even if the notification specification does not include the event type. The notification specification does not filter out the test event.

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


def buildStarted(wfb):
    """Inform the latent worker that a build has started.

        @param wfb: a L{LatentWorkerForBuilder}.  The wfb is the one for whom the
        build finished.
        """


def rpcmethod(func):
    """
    Decorator to expose Node methods as remote procedure calls.

    Apply this decorator to methods in the Node class (or a subclass) in
    order to make them remotely callable via the DHT's RPC mechanism.
    """
    func.rpcmethod = True
    return func


def p_llamadaD(p):
    """llamadaD : expresionL ',' llamadaD
                | expresionL
                | empty
    """


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


def str_2_bytes(input_str):
    """
    用于将 str 类型转换为 bytes 类型
    :param input_str:
    :return:
    """
    return input_str.encode(encoding='GBK')


def describe_event_categories(SourceType=None, Filters=None):
    """
    Lists categories for all event source types, or, if specified, for a specified source type. You can see a list of the event categories and source types in Working with Events and Notifications in the AWS Database Migration Service User Guide.
    See also: AWS API Documentation

    :example: response = client.describe_event_categories(
        SourceType='string',
        Filters=[
            {
                'Name': 'string',
                'Values': [
                    'string',
                ]
            },
        ]
    )

    :type SourceType: string
    :param SourceType: The type of AWS DMS resource that generates events.
            Valid values: replication-instance | migration-task

    :type Filters: list
    :param Filters: Filters applied to the action.
            (dict) --
            Name (string) -- [REQUIRED]The name of the filter.
            Values (list) -- [REQUIRED]The filter value.
            (string) --

    :rtype: dict
    :return: {
        'EventCategoryGroupList': [
            {
                'SourceType': 'string',
                'EventCategories': [
                    'string',
                ]
            },
        ]
    }

    :returns:
    (string) --

    """
    pass


def quickvolshow(data, lighting=False, data_min=None, data_max=None,
    max_shape=256, level=[0.1, 0.5, 0.9], opacity=[0.01, 0.05, 0.1],
    level_width=0.1, extent=None, memorder='C', **kwargs):
    """
    Visualize a 3d array using volume rendering

    :param data: 3d numpy array
    :param lighting: boolean, to use lighting or not, if set to false, lighting parameters will be overriden
    :param data_min: minimum value to consider for data, if None, computed using np.nanmin
    :param data_max: maximum value to consider for data, if None, computed using np.nanmax
    :parap int max_shape: maximum shape for the 3d cube, if larger, the data is reduced by skipping/slicing (data[::N]), set to None to disable.
    :param extent: list of [[xmin, xmax], [ymin, ymax], [zmin, zmax]] values that define the bounds of the volume, otherwise the viewport is used
    :param level: level(s) for the where the opacity in the volume peaks, maximum sequence of length 3
    :param opacity: opacity(ies) for each level, scalar or sequence of max length 3
    :param level_width: width of the (gaussian) bumps where the opacity peaks, scalar or sequence of max length 3
    :param kwargs: extra argument passed to Volume and default transfer function
    :return:

    """
    import ipyvolume as ipv
    ipv.figure()
    ipv.volshow(data, lighting=lighting, data_min=data_min, data_max=
        data_max, max_shape=max_shape, level=level, opacity=opacity,
        level_width=level_width, extent=extent, memorder=memorder, **kwargs)
    return ipv.gcc()


def pd_applyfun_col(df, newcol, ff, use_colname='all/[colname]'):
    """ use all Columns to compute values """
    if use_colname == 'all/[colname]':
        df[newcol] = ff(df.values)
    else:
        df[newcol] = ff(df[use_colname].values)
    return df


def get_lomb_amplitude(lomb_model, i, j):
    """
    Get the amplitude of the jth harmonic of the ith frequency from a fitted
    Lomb-Scargle model.
    """
    return lomb_model['freq_fits'][i - 1]['amplitude'][j - 1]


def add(id):
    """Add the object with the given id to the catalog
        """


def _rehydrate_skeleton_class(skeleton_class, class_dict):
    """Put attributes from `class_dict` back on `skeleton_class`.

    See CloudPickler.save_dynamic_class for more info.
    """
    registry = None
    for attrname, attr in class_dict.items():
        if attrname == '_abc_impl':
            registry = attr
        else:
            setattr(skeleton_class, attrname, attr)
    if registry is not None:
        for subclass in registry:
            skeleton_class.register(subclass)
    return skeleton_class


def _onpick(event):
    """
    pick function for interactive points
    """
    scat = event.artist
    poly = scat._polyline
    pl = len(poly)
    if scat._print:
        msg = '{}'.format(poly)
        if pl > 1:
            msg += ' exactly in {}'.format(poly[event.ind])
        print(msg)
    scat._print = not scat._print
    scat._facecolors[:, :3] = 1 - scat._facecolors[:, :3]
    scat._edgecolors[:, :3] = 1 - scat._edgecolors[:, :3]
    scat._sizes = scat._sizes * scat._sizes_offset
    scat._sizes_offset = 1 / scat._sizes_offset
    scat.figure.canvas.draw()


def generate_runner_subparser(subparsers):
    """Generates the subparser for the run server option."""
    runner_parser = subparsers.add_parser('run')
    runner_parser.set_defaults(action='run')
    runner_parser.add_argument('module', metavar='module', help=
        'Name of the module that uses the symmetric object.')
    runner_parser.add_argument('-s', '--server', dest='server', default=
        '127.0.0.1', help='Server hostname in which the application will run.')
    runner_parser.add_argument('-p', '--port', dest='port', type=int,
        default=5000, help='Port for the webserver.')
    runner_parser.add_argument('-d', '--no-debug', dest='debug', action=
        'store_const', default=True, const=False, help=
        'Do not run in debug mode.')


def customdata_custom_splitnormals_clear():
    """Remove the custom split normals layer, if it exists

    """
    pass


def temporal_snapshots_ids(G):
    """Return the ordered list of snapshot ids present in the dynamic graph.

        Parameters
        ----------

        G : graph
            A DyNetx graph.

        Returns
        -------

        nd : list
            a list of snapshot ids

        Examples
        --------
        >>> G = dn.DynGraph()
        >>> G.add_path([0,1,2,3], t=0)
        >>> G.add_path([0,4,5,6], t=1)
        >>> G.add_path([7,1,2,3], t=2)
        >>> dn.temporal_snapshots(G)
        [0, 1, 2]
    """
    return G.temporal_snapshots_ids()


def scene_drop(object: str='Object', scene: str='Scene'):
    """Drag object to scene in Outliner

    :param object: Object, Target Object
    :type object: str
    :param scene: Scene, Target Scene
    :type scene: str
    """
    pass


def get_content_before_tag(tag, include_tag=False) ->str:
    """
    Get HTML-code before `tag` and return it as string.
    Tag's not included by default.
    """
    result = ''
    bs = tag.previous_sibling
    while bs is not None:
        result = str(bs) + result
        bs = bs.previous_sibling
    return str(tag) + result if include_tag else result


def default_tzinfo(dt, tzinfo):
    """
    Sets the the ``tzinfo`` parameter on naive datetimes only

    This is useful for example when you are provided a datetime that may have
    either an implicit or explicit time zone, such as when parsing a time zone
    string.

    .. doctest::

        >>> from dateutil.tz import tzoffset
        >>> from dateutil.parser import parse
        >>> from dateutil.utils import default_tzinfo
        >>> dflt_tz = tzoffset("EST", -18000)
        >>> print(default_tzinfo(parse('2014-01-01 12:30 UTC'), dflt_tz))
        2014-01-01 12:30:00+00:00
        >>> print(default_tzinfo(parse('2014-01-01 12:30'), dflt_tz))
        2014-01-01 12:30:00-05:00

    :param dt:
        The datetime on which to replace the time zone

    :param tzinfo:
        The :py:class:`datetime.tzinfo` subclass instance to assign to
        ``dt`` if (and only if) it is naive.

    :return:
        Returns an aware :py:class:`datetime.datetime`.
    """
    if dt.tzinfo is not None:
        return dt
    else:
        return dt.replace(tzinfo=tzinfo)


def group_finder(userid, request):
    """Return groups from user ID

    :param userid: the user id (login)
    :param request: request from pyramid
    """
    if hasattr(request, 'anyblok') and request.anyblok:
        return request.anyblok.registry.User.get_roles(userid)
    return userid


def childDataReceived(childFD, data):
    """
        Called when data arrives from the child process.

        @type childFD: C{int}
        @param childFD: The file descriptor from which the data was
            received.

        @type data: C{str}
        @param data: The data read from the child's file descriptor.
        """


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


@classmethod
def broadcast_arrays(cls, array1, array2):
    """
        Broadcast two arrays against each other.

        Returns
        -------
        broadcast_array1 : array1 or a broadcast of array1
        broadcast_array2 : array2 or a broadcast of array2
            The returned arrays will be broadcast against each other.
            Any array which is already in full broadcast shape will be
            returned unchanged.

        """
    shape, bcast_kwargs1, bcast_kwargs2 = cls._compute_broadcast_kwargs(array1
        .shape, array2.shape)
    if any(bcast_kwargs1.values()):
        array1 = cls(array1, **bcast_kwargs1)
    if any(bcast_kwargs2.values()):
        array2 = cls(array2, **bcast_kwargs2)
    return array1, array2


def register_app_activity():
    """
    Create watchers for models defined in settings.py.
    Once created, they will be passed over
    Activity.objects.follow_model(), which lives in managers.py
    """
    from django.conf import settings
    from django.contrib.contenttypes.models import ContentType
    from .models import Activity
    if not hasattr(settings, 'ACTIVITY_MONITOR_MODELS'):
        return
    for item in settings.ACTIVITY_MONITOR_MODELS:
        try:
            app_label, model = item['model'].split('.', 1)
            content_type = ContentType.objects.get(app_label=app_label,
                model=model)
            model = content_type.model_class()
            Activity.objects.follow_model(model)
        except ContentType.DoesNotExist:
            pass


def __delitem__(record):
    """Delete Record from soup.

        If given record not contained in soup, raise ValueError.

        @param record: IRecord implementation
        @raise: ValueError if record not exists in this soup.
        """


def _engine_builder(con):
    """
    Returns a SQLAlchemy engine from a URI (if con is a string)
    else it just return con without modifying it.
    """
    global _SQLALCHEMY_INSTALLED
    if isinstance(con, str):
        try:
            import sqlalchemy
        except ImportError:
            _SQLALCHEMY_INSTALLED = False
        else:
            con = sqlalchemy.create_engine(con)
            return con
    return con


def CreationDate():
    """Return the creation date.

        The value of the first Dublin Core `Date` element qualified by
        'creation' is returned as a unicode string if a qualified
        element is defined, otherwise, an empty unicode string is
        returned. The string is formatted  'YYYY-MM-DD H24:MN:SS TZ'.
        """


@staticmethod
def p_alignment_long(p):
    """alignment_long : ALIGNMENT_LONG NUMERIC"""
    p[0] = p[2]


def nearest_colour_index(colour_map, rgb, debug=0):
    """
    General purpose function. Uses Euclidean distance.
    So far used only for pre-BIFF8 ``WINDOW2`` record.
    Doesn't have to be fast.
    Doesn't have to be fancy.
    """
    best_metric = 3 * 256 * 256
    best_colourx = 0
    for colourx, cand_rgb in colour_map.items():
        if cand_rgb is None:
            continue
        metric = 0
        for v1, v2 in zip(rgb, cand_rgb):
            metric += (v1 - v2) * (v1 - v2)
        if metric < best_metric:
            best_metric = metric
            best_colourx = colourx
            if metric == 0:
                break
    if 0 and debug:
        print('nearest_colour_index for %r is %r -> %r; best_metric is %d' %
            (rgb, best_colourx, colour_map[best_colourx], best_metric))
    return best_colourx


def inner_content(node):
    """
    Returns the inner content of a given XML node, including tags.

    Args:
        node (lxml.etree.Element): The node whose inner content is desired.

    Returns:
        str: The inner content of the node.
    """
    from lxml import etree
    parts = [node.text]
    for child in node.getchildren():
        parts.append(etree.tostring(child, encoding='utf-8'))
        parts.append(child.tail)
    return ''.join(filter(None, parts))


def unitsum_tuples(n, k, mn, mx):
    """Generates unitsum k-tuples with elements from mn to mx.

    This function is more general than slots(n,k,normalized=True), as it can
    return unitsum vectors with elements outside of (0,1).

    In order to generate unitsum samples, the following must be satisfied:
        1 = mx + (k-1) * mn

    Parameters
    ----------
    n : int
        The number of increments to include between mn and mx. n >= 1. The
        meaning of n is similar to the n in slots(n,k) and represents the
        number of ``items'' to place in each slot.
    k : int
        The length of the tuples (equivalently, the number of slots).
    mn : float
        The minimum value in the unitsum samples.
    mx : float
        The maximum value in the unitsum samples.

    Examples
    --------
    >>> s = unitsum_tuples(3, 2, .2, .8)
    >>> s.next()
    (0.20000000000000001, 0.80000000000000004)
    >>> s.next()
    (0.40000000000000008, 0.60000000000000009)
    >>> s.next()
    (0.60000000000000009, 0.40000000000000002)
    >>> s.next()
    (0.80000000000000004, 0.19999999999999996)

    """
    s = mx + (k - 1) * mn
    tol = 1e-09
    if not abs(s - 1) <= tol:
        msg = 'Specified min and max will not create unitsum tuples.'
        e = Exception(msg)
        raise e
    n += 1
    if mn < 0:
        shift = float(abs(mn))
    else:
        shift = -float(mn)
    seq, i = [mx + shift] * k + [0], k
    while i:
        t = tuple(seq[i] - seq[i + 1] - shift for i in range(k))
        s = float(sum(t))
        assert s > 0.001
        yield tuple(t)
        for idx, val in enumerate(seq):
            if abs(val) < 1e-09:
                i = idx - 1
                break
        seq[i:k] = [seq[i] - (mx - mn) / float(n - 1)] * (k - i)


def parse_fasta_entry(text, known_species=None):
    """Split an entry of "Acession genus species etc" into fields.

    Returns a two-tuple of taxid (always zero), genus-species.

    >>> parse_fasta_entry('HQ013219 Phytophthora arenaria')
    (0, 'Phytophthora arenaria')

    >>> parse_fasta_entry('P13660 Phytophthora aff infestans')
    (0, 'Phytophthora aff infestans')
    """
    acc, sp = text.split(None, 1)
    taxid = 0
    return taxid, sp


def getGenotype(genotypeStr):
    """
    Return genotype index array from genotype string.
    Indices are separated by / or |

    e.g. '0/1' => ['0','1']
    """
    if '/' in genotypeStr:
        return genotypeStr.split('/')
    if '|' in genotypeStr:
        return genotypeStr.split('|')
    return [genotypeStr]


def _scalar_or_pair(type_, **rules):
    """Expand scalar type to also allow a two-element list of the former.

    Parameters
    ----------
    type_ : str
        The type string.
    **rules
        Additional rules to include.

    Returns
    -------
    composite_type : dict
        A dictionary that allows a scalar or two-element list of the former.
    """
    return {'type': [type_, 'list'], 'schema': {'type': type_, **rules},
        'minlength': 2, 'maxlength': 2, **rules}


def unpack_singleton(x):
    """Gets the first element if the iterable has only one value.

    Otherwise return the iterable.

    # Argument
        x: A list or tuple.

    # Returns
        The same iterable or the first element.
    """
    if len(x) == 1:
        return x[0]
    return x


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


@classmethod
def get(cls, channel, start, end, bits=None, **kwargs):
    """Get data for this channel from frames or NDS

        Parameters
        ----------
        channel : `str`, `~gwpy.detector.Channel`
            the name of the channel to read, or a `Channel` object.

        start : `~gwpy.time.LIGOTimeGPS`, `float`, `str`
            GPS start time of required data,
            any input parseable by `~gwpy.time.to_gps` is fine

        end : `~gwpy.time.LIGOTimeGPS`, `float`, `str`
            GPS end time of required data,
            any input parseable by `~gwpy.time.to_gps` is fine

        bits : `Bits`, `list`, optional
            definition of bits for this `StateVector`

        pad : `float`, optional
            value with which to fill gaps in the source data, only used if
            gap is not given, or ``gap='pad'`` is given

        dtype : `numpy.dtype`, `str`, `type`, or `dict`
            numeric data type for returned data, e.g. `numpy.float`, or
            `dict` of (`channel`, `dtype`) pairs

        nproc : `int`, optional, default: `1`
            number of parallel processes to use, serial process by
            default.

        verbose : `bool`, optional
            print verbose output about NDS progress.

        **kwargs
            other keyword arguments to pass to either
            :meth:`.find` (for direct GWF file access) or
            :meth:`.fetch` for remote NDS2 access

        See also
        --------
        StateVector.fetch
            for grabbing data from a remote NDS2 server
        StateVector.find
            for discovering and reading data from local GWF files
        """
    new = cls.DictClass.get([channel], start, end, **kwargs)[channel]
    if bits:
        new.bits = bits
    return new


def quantity_to_tuple(quantity, unit_str):
    """
    Splits a quantity into a tuple of (value,unit) where unit is FITS complient.

    Useful to write FITS header keywords with units in a comment.

    Parameters
    ----------
    quantity : astropy quantity
        The Astropy quantity to split.
    unit_str: str
        Unit string representation readable by astropy.units (e.g. 'm', 'TeV', ...)

    Returns
    -------
    tuple
        A tuple containing the value and the quantity.
    """
    return quantity.to(unit_str).value, quantity.to(unit_str).unit.to_string(
        format='FITS')


def render_status(model, *args, **kwargs):
    """Render level as label"""
    mapping = {(10): 'warning', (50): 'success', (99): 'danger'}
    return '{}'.format(mapping.get(
        model.status, 'info'), model.get_status_display().upper())


def psi_H_Mg_SO4_HMW84(T, P):
    """c-c'-a: hydrogen magnesium sulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@classmethod
def _get_block_manager_axis(cls, axis):
    """Map the axis to the block_manager axis."""
    axis = cls._get_axis_number(axis)
    if cls._AXIS_REVERSED:
        m = cls._AXIS_LEN - 1
        return m - axis
    return axis


def supports_port_resource_request_during_move(req):
    """Check to see if the requested API version is high enough for support
    port resource request during move operation.

    NOTE: At the moment there is no such microversion that supports port
    resource request during move. This function is added as a preparation for
    that microversion (assuming there will be a new microversion, which is
    yet to be decided).

    :param req: The incoming API request
    :returns: True if the requested API microversion is high enough for
        port resource request move support, False otherwise.
    """
    return False


def _ctypes_out(parameter):
    """Returns a parameter variable declaration for an output variable for the specified
    parameter.
    """
    if (parameter.dimension is not None and ':' in parameter.dimension and
        'out' in parameter.direction and ('allocatable' in parameter.
        modifiers or 'pointer' in parameter.modifiers)):
        if parameter.direction == '(inout)':
            return 'type(C_PTR), intent(inout) :: {}_o'.format(parameter.name
                ), True
        else:
            return 'type(C_PTR), intent(inout) :: {}_c'.format(parameter.name
                ), True


@staticmethod
def _add_to_graph(graph, init, list):
    """
            add a list of microcodes to a graph. The init node is duplicated as needed
            (because it may be used many times and mess up the diagram. It hurts to have
            very long edges like that.

        """
    source = {}
    dest = {}
    sans = {}
    for vn in init:
        source[vn] = '#INIT'
        dest[vn] = '#OUT'
    for i, record in enumerate(list):
        microcode, kwargs = record[0], record[1]
        graph.node(str(i) + str(id(microcode)), label=microcode.to_label(
            kwargs, html=True))
        for an in microcode.ain:
            vn = kwargs.get(an, an)
            from_init = []
            if vn in source:
                if vn == '':
                    continue
                if source[vn] == '#INIT':
                    from_init.append(vn)
                else:
                    san = sans[vn]
                    dan = an
                    attrs = {}
                    if san != vn:
                        attrs['taillabel'] = san + ':'
                    if dan != vn:
                        attrs['headlabel'] = ':' + dan
                    attrs['label'] = vn
                    graph.edge(source[vn], str(i) + str(id(microcode)), **attrs
                        )
                dest[vn] = str(i) + str(id(microcode))
            if len(from_init) > 0:
                graph.node(str(i) + '#INIT', label='<#>')
                for vn in from_init:
                    graph.edge(str(i) + '#INIT', str(i) + str(id(microcode)
                        ), label=vn)
        for an in microcode.aout:
            vn = kwargs.get(an, an)
            source[vn] = str(i) + str(id(microcode))
            sans[vn] = an
            dest[vn] = '#OUT'
    for vn, node in dest.items():
        if node != '#OUT':
            continue
        graph.node(source[vn] + '#OUT', label='<#>')
        graph.edge(source[vn], source[vn] + '#OUT', label=vn)


def v_bar(cv):
    """Return the trace of ``cv`` divided by 2

    :arg cv: a variance-covariance matrix
    :type cv: 4-element sequence of float

    :returns: float

    **Example**::

        >>> x1 = 1-.5j
        >>> x2 = .2+7.1j
        >>> z1 = ucomplex(x1,(1,.2))
        >>> z2 = ucomplex(x2,(.2,1))
        >>> y = z1 * z2
        >>> y.v
        VarianceCovariance(rr=2.3464, ri=1.8432, ir=1.8432, ii=51.4216)
        >>> reporting.v_bar(y.v)
        26.884

    """
    assert len(cv) == 4, "'%s' a 4-element sequence is needed" % type(cv)
    return (cv[0] + cv[3]) / 2.0


def formula_2014_01_01(foyer_fiscal, period, parameters):
    """
        Renvoie la liste des charges déductibles avant rbg_int pour 2014
        """
    pensions_alimentaires_deduites = foyer_fiscal(
        'pensions_alimentaires_deduites', period)
    cd_acc75a = foyer_fiscal('cd_acc75a', period)
    cd_deddiv = foyer_fiscal('cd_deddiv', period)
    cd_eparet = foyer_fiscal('cd_eparet', period)
    grosses_reparations = foyer_fiscal('grosses_reparations', period)
    niches1 = (pensions_alimentaires_deduites + cd_acc75a + cd_deddiv +
        cd_eparet + grosses_reparations)
    return niches1


def filter_composite_from_subgroups(s):
    """
    Given a sorted list of subgroups, return a string appropriate to provide as
    the a composite track's `filterComposite` argument

    >>> import trackhub
    >>> trackhub.helpers.filter_composite_from_subgroups(['cell', 'ab', 'lab', 'knockdown'])
    'dimA dimB'

    Parameters
    ----------
    s : list
        A list representing the ordered subgroups, ideally the same list
        provided to `dimensions_from_subgroups`. The values are not actually
        used, just the number of items.
    """
    dims = []
    for letter, sg in zip('ABCDEFGHIJKLMNOPQRSTUVWZ', s[2:]):
        dims.append('dim{0}'.format(letter))
    if dims:
        return ' '.join(dims)


def sim_info(virl_xml, roster=None, interfaces=None, protocol='telnet'):
    """
    common inventory info accross yaml/ini
    """
    inventory = list()
    for node_long_name, device in roster.items():
        if 'managementIP' in device and 'NodeName' in device:
            entry = dict()
            entry['node_long_name'] = node_long_name
            entry['address'] = device['managementIP']
            entry['protocol'] = protocol
        else:
            continue
        name = device['NodeName']
        entry['name'] = name
        entry['ned'] = 'unknown'
        entry['ns'] = 'unkown'
        try:
            type = device['NodeSubtype']
            if 'NX' in type:
                entry['prefix'] = 'cisco-nx-id'
                entry['ned'] = 'cisco-nx'
                entry['ns'] = 'http://tail-f.com/ned/cisco-nx-id'
            elif 'XR' in type:
                entry['prefix'] = 'cisco-ios-xr-id'
                entry['ned'] = 'cisco-ios-xr'
                entry['ns'] = 'http://tail-f.com/ned/cisco-ios-xr-id'
            elif 'CSR' in type or 'IOS' in type:
                entry['prefix'] = 'ios-id'
                entry['ned'] = 'cisco-ios'
                entry['ns'] = 'urn:ios-id'
        except KeyError:
            pass
        if entry.get('ned', None) not in ['unknown', None]:
            inventory.append(entry)
    return inventory


@classmethod
def enable(cls):
    """Enables the Media domain
        """
    return cls.build_send_payload('enable', {}), None


def DefaultSemRule(sargs, context={}):
    """Default  semantic rule"""
    return sargs[0]


@classmethod
def load_from_file(cls, repo_name, base_directory, *args, **kwargs):
    """This will load a TrackedRepo to memory, from a given meta tracked
        file. For automated management without a database.

        The meta tracked file is in the format of self.__dict__

        :type repo_name: str
        :param repo_name: If the git URL is `git@github.com:yelp/detect-secrets`
            this value will be `yelp/detect-secrets`

        :rtype: TrackedRepo
        :raises: FileNotFoundError
        """
    storage = cls.initialize_storage(base_directory)
    data = cls.get_tracked_repo_data(storage, repo_name)
    output = cls(**data)
    output.storage = storage.setup(output.repo)
    return output


def repr_author(Author):
    """
  Get string representation of an Author namedtuple in the format:
  von Last, jr., First.

  Parameters
  ----------
  Author: An Author() namedtuple
     An author name.

  Examples
  --------
  >>> from bibmanager.utils import repr_author, parse_name
  >>> names = ['Last', 'First Last', 'First von Last', 'von Last, First',
  >>>          'von Last, sr., First']
  >>> for name in names:
  >>>     print(f"{name!r:22}: {repr_author(parse_name(name))}")
  'Last'                : Last
  'First Last'          : Last, First
  'First von Last'      : von Last, First
  'von Last, First'     : von Last, First
  'von Last, sr., First': von Last, sr., First
  """
    name = Author.last
    if Author.von != '':
        name = ' '.join([Author.von, name])
    if Author.jr != '':
        name += f', {Author.jr}'
    if Author.first != '':
        name += f', {Author.first}'
    return name


def bye(msg=''):
    """print msg and exit"""
    exit(msg)


def enter(s, blk, rtlir):
    """ entry point for RTLIR type checking """
    s.blk = blk
    s.globals = blk.__globals__
    s.closure = {}
    for i, var in enumerate(blk.__code__.co_freevars):
        try:
            s.closure[var] = blk.__closure__[i].cell_contents
        except ValueError:
            pass
    s.visit(rtlir)


@staticmethod
def __format_phone_number(phone_number):
    """
        Format a local Vietnamese phone number to its international
        representation.

        The function adds a leading digit `0` if the argument `phone_number`
        is only composed of 9 digits.

        :param phone_number: A local Vietnamese phone number composed of 9 or
            10 digits.

        :return: A string representation of an international phone number,
            starting with `+84.`.

        :raise ValueError: If the argument `phone_number` is not composed of
            9 or 10 digits only.
        """
    if not phone_number.isdigit():
        raise ValueError(f'invalid phone number {phone_number}')
    if len(phone_number) < 9:
        raise ValueError(f'the phone number {phone_number} is missing digits')
    return f'+84.{phone_number.zfill(10)}'


def nms(boxes, scores, **kwargs):
    """Do Non Maximal Suppression

    As translated from the OpenCV c++ source in
    `nms.inl.hpp <https://github.com/opencv/opencv/blob/ee1e1ce377aa61ddea47a6c2114f99951153bb4f/modules/dnn/src/nms.inl.hpp#L67>`__
    which was in turn inspired by `Piotr Dollar's NMS implementation in EdgeBox. <https://goo.gl/jV3JYS>`_

    This function is not usually called directly.  Instead use :func:`nms.nms.boxes`, :func:`nms.nms.rboxes`,
    or :func:`nms.nms.polygons`

    :param boxes:  the boxes to compare, the structure of the boxes must be compatible with the compare_function.
    :type boxes:  list
    :param scores: the scores associated with boxes
    :type scores: list
    :param kwargs: optional keyword parameters
    :type kwargs: dict (see below)
    :returns: an list of indicies of the best boxes
    :rtype: list
    :kwargs:

    * score_threshold (float): the minimum score necessary to be a viable solution, default 0.3
    * nms_threshold (float): the minimum nms value to be a viable solution, default: 0.4
    * compare_function (function): function that accepts two boxes and returns their overlap ratio, this function must
      accept two boxes and return an overlap ratio
    * eta (float): a coefficient in adaptive threshold formula: \\ |nmsi1|\\ =eta\\*\\ |nmsi0|\\ , default: 1.0
    * top_k (int): if >0, keep at most top_k picked indices. default:0

    .. |nmsi0| replace:: nms_threshold\\ :sub:`i`
    .. |nmsi1| replace:: nms_threshold\\ :sub:`(i+1)`

    """
    if 'eta' in kwargs:
        eta = kwargs['eta']
    else:
        eta = 1.0
    assert 0 < eta <= 1.0
    if 'top_k' in kwargs:
        top_k = kwargs['top_k']
    else:
        top_k = 0
    assert 0 <= top_k
    if 'score_threshold' in kwargs:
        score_threshold = kwargs['score_threshold']
    else:
        score_threshold = 0.3
    assert score_threshold > 0
    if 'nms_threshold' in kwargs:
        nms_threshold = kwargs['nms_threshold']
    else:
        nms_threshold = 0.4
    assert 0 < nms_threshold < 1
    if 'compare_function' in kwargs:
        compare_function = kwargs['compare_function']
    else:
        compare_function = None
    assert compare_function is not None
    if len(boxes) == 0:
        return []
    assert len(scores) == len(boxes)
    assert scores is not None
    scores = help.get_max_score_index(scores, score_threshold, top_k)
    adaptive_threshold = nms_threshold
    indicies = []
    for i in range(0, len(scores)):
        idx = int(scores[i][1])
        keep = True
        for k in range(0, len(indicies)):
            if not keep:
                break
            kept_idx = indicies[k]
            overlap = compare_function(boxes[idx], boxes[kept_idx])
            keep = overlap <= adaptive_threshold
        if keep:
            indicies.append(idx)
        if keep and eta < 1 and adaptive_threshold > 0.5:
            adaptive_threshold = adaptive_threshold * eta
    return indicies


def expose_ports():
    """
    You specify exposed ports like this:
        EXPOSE external_port : docker_port
    """
    ports = []
    with open('.monobox') as monobox:
        for lines in monobox:
            if lines.partition(' ')[0] == 'EXPOSE':
                port_setting = lines.partition(' ')[2].rstrip()
                ports.append('-p')
                port_number = port_setting.partition(':')[0].rstrip()
                try:
                    internal_port_number = port_setting.partition(':')[3
                        ].rstrip()
                except IndexError:
                    internal_port_number = port_number
                ports.append(port_number + ':' + internal_port_number)
    return ports


@staticmethod
def listen(data):
    """
        * Do something with the data.
        * :param data:
        * :return: url output
        """
    raise NotImplementedError()


@staticmethod
def _encode_block_string(block):
    """Encodes a block to a string."""
    args = ['r%d' % block.num_repeat, 'k%d' % block.kernel_size, 's%d%d' %
        (block.strides[0], block.strides[1]), 'e%s' % block.expand_ratio,
        'i%d' % block.input_filters, 'o%d' % block.output_filters]
    if 0 < block.se_ratio <= 1:
        args.append('se%s' % block.se_ratio)
    if block.id_skip is False:
        args.append('noskip')
    return '_'.join(args)


@staticmethod
def _platform_compatible():
    """Returns true if this provider is compatible on the current platform."""
    raise NotImplementedError


def get_class_from_module(module, class_name):
    """ Returns a class from a module and a class name parameters.
    This function is used by get_class_from_config and get_class_from_name.

    Example:
    >>> get_class_from_module("my.module", "MyClass")

    :param basestring module: The module name.
    :param basestring class_name: The class name.
    :return: The class resolved by the module and class name provided.
    """
    import importlib
    module = importlib.import_module(module)
    return getattr(module, class_name)


def pair_slugify(e):
    """
    Normalizes string, converts to lowercase, removes non-alpha characters,
    and converts spaces to hyphens.type(
    """
    import re
    import unicodedata
    value = '{} {}'.format(*e)
    value = str(value)
    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore'
        ).decode('utf8').strip().lower()
    value = re.sub('[^\\w\\s]', '', value)
    value = re.sub('\\s+', ' ', value)
    value = re.sub('[-\\s]+', '-', value)
    return value


def origin_clear():
    """Clear the object’s origin

    """
    pass


def SVGFinishCurve():
    """
    Finish curve creation
    """
    pass


def get_dailysummary_iex(*args, **kwargs):
    """
    Returns a summary of daily market volume statistics. Without parameters,
    this will return the most recent trading session by default.

    Parameters
    ----------
    start : string, int, date, datetime, Timestamp
        The beginning of the date range.
    end : string, int, date, datetime, Timestamp
        The end of the date range.

    Reference: https://www.iextrading.com/developer/docs/#historical-daily

    :return: DataFrame
    """
    from pandas_datareader.iex.stats import DailySummaryReader
    return DailySummaryReader(*args, **kwargs).read()


@classmethod
def remove(cls, ids_to_delete):
    """Remove an Association instance"""
    raise NotImplementedError('Implement in subclass')


def Al2O3(mw_atmos, mh=1):
    """Defines properties for Al2O3 as condensible"""
    if mh != 1:
        raise Exception(
            'Alert: No M/H Dependence in Al2O3 Routine. Consult your local theorist to determine next steps.'
            )
    gas_mw = 101.961
    gas_mmr = 2.51e-06 * (gas_mw / mw_atmos)
    rho_p = 3.987
    return gas_mw, gas_mmr, rho_p


def turbulent_Colburn(Re, Pr):
    """Calculates internal convection Nusselt number for turbulent flows
    in pipe according to [2]_ as in [1]_.

    .. math::
        Nu = 0.023Re^{0.8}Pr^{1/3}

    Parameters
    ----------
    Re : float
        Reynolds number, [-]
    Pr : float
        Prandtl number, [-]

    Returns
    -------
    Nu : float
        Nusselt number, [-]

    Notes
    -----
    Range according to [1]_ is 0.5 < Pr < 3  and 10^4 < Re < 10^5.

    Examples
    --------
    >>> turbulent_Colburn(Re=1E5, Pr=1.2)
    244.41147091200068

    References
    ----------
    .. [1] Rohsenow, Warren and James Hartnett and Young Cho. Handbook of Heat
       Transfer, 3E. New York: McGraw-Hill, 1998.
    .. [2] Colburn, Allan P. "A Method of Correlating Forced Convection
       Heat-Transfer Data and a Comparison with Fluid Friction." International
       Journal of Heat and Mass Transfer 7, no. 12 (December 1964): 1359-84.
       doi:10.1016/0017-9310(64)90125-5.
    """
    return 0.023 * Re ** 0.8 * Pr ** (1 / 3.0)


def extract_data_error_bar(data, params):
    """Return error bar arrays

    Return error bar arrays along X and Y

    Args:
        data (ndarray): input data
        params (dict): one entry of the 'data' parameter field

    Returns:
        (x_bars, y_bars) where x_bars and y_bars are 1-dimensional numpy arrays
    """
    plot_type = params['plot_type']
    row_begin = params[plot_type]['row_start']
    ooo = []
    for k in ['x', 'y']:
        j = params['error_bar']['data_column'][k]
        if j is None:
            ooo.append(None)
        else:
            ooo.append(data[row_begin:, (j)])
    return tuple(ooo)


@staticmethod
def format_interval(t):
    """
        Formats a number of seconds as a clock time, [H:]MM:SS

        Parameters
        ----------
        t  : int
            Number of seconds.

        Returns
        -------
        out  : str
            [H:]MM:SS
        """
    mins, s = divmod(int(t), 60)
    h, m = divmod(mins, 60)
    if h:
        return '{0:d}:{1:02d}:{2:02d}'.format(h, m, s)
    else:
        return '{0:02d}:{1:02d}'.format(m, s)


def mapping_getter(items, name, if_missing=None):
    """  A mapping should pass this function to its children to get their
    defaults or errors.
    """
    if items:
        return items.get(name, if_missing)
    return if_missing


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 intersect_point_quad_2d(pt, quad_p1, quad_p2, quad_p3, quad_p4):
    """Takes 5 vectors (using only the x and y coordinates): one is the point and the next 4 define the quad, only the x and y are used from the vectors. Returns 1 if the point is within the quad, otherwise 0. Works only with convex quads without singular edges.

	Parameters:
	pt (mathutils.Vector) – Point
	quad_p1 (mathutils.Vector) – First point of the quad
	quad_p2 (mathutils.Vector) – Second point of the quad
	quad_p3 (mathutils.Vector) – Third point of the quad
	quad_p4 (mathutils.Vector) – Fourth point of the quad

	Return type: int"""
    return 1


def psi_Ca_H_CO3_HMW84(T, P):
    """c-c'-a: calcium hydrogen carbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def BoolProperty(name: str='', description: str='', default=False, options:
    set={'ANIMATABLE'}, subtype: str='NONE', update=None, get=None, set=None):
    """Returns a new boolean property definition.

    :param name: Name used in the user interface.
    :type name: str
    :param description: Text used for the tooltip and api documentation.
    :type description: str
    :param options: Enumerator in [‘HIDDEN’, ‘SKIP_SAVE’, ‘ANIMATABLE’, ‘LIBRARY_EDITABLE’, ‘PROPORTIONAL’,’TEXTEDIT_UPDATE’].
    :type options: set
    :param subtype: Enumerator in [‘PIXEL’, ‘UNSIGNED’, ‘PERCENTAGE’, ‘FACTOR’, ‘ANGLE’, ‘TIME’, ‘DISTANCE’, ‘NONE’].
    :type subtype: str
    :param update: Function to be called when this value is modified, This function must take 2 values (self, context) and return None. Warning there are no safety checks to avoid infinite recursion.
    :param get: Function to be called when this value is ‘read’, This function must take 1 value (self) and return the value of the property.
    :param set: Function to be called when this value is ‘written’, This function must take 2 values (self, value) and return None.
    """
    pass


def add(ob):
    """Add a new object 'obj' to the database and assign it an oid.

        A persistent object is normally added to the database and
        assigned an oid when it becomes reachable to an object already in
        the database.  In some cases, it is useful to create a new
        object and use its oid (_p_oid) in a single transaction.

        This method assigns a new oid regardless of whether the object
        is reachable.

        The object is added when the transaction commits.  The object
        must implement the IPersistent interface and must not
        already be associated with a Connection.

        Parameters:
        obj: a Persistent object

        Raises TypeError if obj is not a persistent object.

        Raises InvalidObjectReference if obj is already associated with another
        connection.

        Raises ConnectionStateError if the connection is closed.
        """


def separate_file_from_parents(full_filename):
    """Receives a full filename with parents (separated by dots)
    Returns a duple, first element is the filename and second element
    is the list of parents that might be empty"""
    splitted = full_filename.split('.')
    file = splitted.pop()
    parents = splitted
    return file, parents


def top_stream(cache, user_id):
    """
    Peek at the top of the stack in the cache.

    :param cache: werkzeug BasicCache-like object
    :param user_id: id of user, used as key in cache

    :return: top item in user's cached stack, otherwise None
    """
    if not user_id:
        return None
    stack = cache.get(user_id)
    if stack is None:
        return None
    return stack.pop()


def name() ->str:
    """Field name expected to have CSRF token.

    Useful for passing it to JavaScript for instance.
    """
    return 'csrf_token'


def intToColorHex(color_number):
    """Convert an integer to a hexadecimal string compatible with :class:`QColor`

    Args:
        color_number (int): integer value of a RGB color

    Returns:
        str: QColor compatible hex string in format '#rrggbb'
    """
    return '#%0.6x' % color_number


@classmethod
def _client_class(cls):
    """
    Subclasses must override this method and return the client class.
    """
    raise NotImplementedError()


def tp_fp_fn(CORRECT_SET, GUESS_SET):
    """
    INPUT: dictionary with the elements in the cluster from the ground truth
    (CORRECT_SET) and dictionary with the elements from the estimated cluster
    (ESTIMATED_SET).

    OUTPUT: number of True Positives (elements in both clusters), False
    Positives (elements only in the ESTIMATED_SET), False Negatives (elements
    only in the CORRECT_SET).
    """
    tp = 0
    fp = 0
    fn = 0
    for elem in GUESS_SET:
        if elem in CORRECT_SET:
            tp += 1
        else:
            fp += 1
    for elem in CORRECT_SET:
        if elem not in GUESS_SET:
            fn += 1
    return tp, fp, fn


def _do_xxpend(args, name):
    """ For example, if name is CPPFLAGS, take the
        args.prependcppflags and prepend them to args.CPPFLAGS.
        Similarly for append.
    """
    xxlist = 'prepend', 'append'
    for xx in xxlist:
        xxpendname = ''.join([xx, name.lower()])
        if hasattr(args, xxpendname):
            xxpendattr = getattr(args, xxpendname)
            attr = getattr(args, name)
            if xxpendattr:
                extra = []
                for flag in xxpendattr:
                    if flag not in attr:
                        extra.append(flag)
                if xx == 'prepend':
                    attr = ' '.join(extra + [attr])
                else:
                    attr = ' '.join([attr] + extra)
            setattr(args, name, attr)


def hook_add_selob(use_bone: bool=False):
    """Hook selected vertices to the first selected object

    :param use_bone: Active Bone, Assign the hook to the hook objects active bone
    :type use_bone: bool
    """
    pass


def geom_size(geom, dim=None):
    """Returns the size of a volume or sinogram, based on the projection or volume geometry.

    :param geom: Geometry to calculate size from
    :type geometry: :class:`dict`
    :param dim: Optional axis index to return
    :type dim: :class:`int`
    """
    if 'GridSliceCount' in geom:
        s = geom['GridSliceCount'], geom['GridRowCount'], geom['GridColCount']
    elif 'GridColCount' in geom:
        s = geom['GridRowCount'], geom['GridColCount']
    elif geom['type'] == 'parallel' or geom['type'] == 'fanflat':
        s = len(geom['ProjectionAngles']), geom['DetectorCount']
    elif geom['type'] == 'parallel3d' or geom['type'] == 'cone':
        s = geom['DetectorRowCount'], len(geom['ProjectionAngles']), geom[
            'DetectorColCount']
    elif geom['type'] == 'fanflat_vec':
        s = geom['Vectors'].shape[0], geom['DetectorCount']
    elif geom['type'] == 'parallel3d_vec' or geom['type'] == 'cone_vec':
        s = geom['DetectorRowCount'], geom['Vectors'].shape[0], geom[
            'DetectorColCount']
    if dim != None:
        s = s[dim]
    return s


def scale_clear(clear_delta: bool=False):
    """Clear the object’s scale

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


def squashstr(string):
    """Squashes a string by removing the spaces and lowering it"""
    nospaces = ''.join(string.split())
    return nospaces.lower()


def describe_ssl_policies(Names=None, Marker=None, PageSize=None):
    """
    Describes the specified policies or all policies used for SSL negotiation.
    For more information, see Security Policies in the Application Load Balancers Guide .
    See also: AWS API Documentation

    Examples
    This example describes the specified policy used for SSL negotiation.
    Expected Output:

    :example: response = client.describe_ssl_policies(
        Names=[
            'string',
        ],
        Marker='string',
        PageSize=123
    )

    :type Names: list
    :param Names: The names of the policies.
            (string) --

    :type Marker: string
    :param Marker: The marker for the next set of results. (You received this marker from a previous call.)

    :type PageSize: integer
    :param PageSize: The maximum number of results to return with this call.

    :rtype: dict
    :return: {
        'SslPolicies': [
            {
                'SslProtocols': [
                    'string',
                ],
                'Ciphers': [
                    {
                        'Name': 'string',
                        'Priority': 123
                    },
                ],
                'Name': 'string'
            },
        ],
        'NextMarker': 'string'
    }

    :returns:
    (string) --

    """
    pass


@classmethod
def _convert_path_to_bare_tail_path(cls, path):
    """
        Strips the index (if present) from the last path element (i.e. ensuring
        that it has a "bare tail").

        Parameters
        ----------
        path : unicode
            The path to be converted (may contain indices).

        Returns
        -------
        bare_tail_path : unicode
            Similar as path but the last path element is guaranteed to be without index.

        Examples
        --------
        >>> JSONAdaptor._convert_path_to_bare_tail_path('A/B/C')
        'A/B/C'
        >>> JSONAdaptor._convert_path_to_bare_tail_path('A[0]/B[1]/C[2]')
        'A[0]/B[1]/C'
        """
    if len(cls.split_path(path)) > 1:
        head = cls.join_paths(*cls.split_path(path)[:-1])
        tail = cls._parse_name_from_element_identifier(cls.split_path(path)[-1]
            )
        return cls.join_paths(head, tail)
    else:
        return cls._parse_name_from_element_identifier(path)


def test_zip(archive, compression, cmd, verbosity, interactive):
    """Test a ZIP archive."""
    cmdlist = [cmd, '--test']
    if verbosity > 1:
        cmdlist.append('-v')
    cmdlist.append(archive)
    return cmdlist


def safe_copy_dict(obj):
    """Copy an existing dictionary or default to empty dict...

    This will return a empty dict if given object is falsey, otherwise it
    will create a dict of the given object (which if provided a dictionary
    object will make a shallow copy of that object).
    """
    if not obj:
        return {}
    return dict(obj)


def select_less():
    """Reduce current selection by deselecting boundary elements

    """
    pass


def holtqdl(data, h=24, alpha=0.26, beta=0.19):
    """DEPRECATED: Holt-Winters forecast h-periods ahead (quandlcode aware)."""
    msg = 'holtqdl() DEPRECATED. Instead use get(), holt(), holtforecast().'
    raise DeprecationWarning(msg)


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


@classmethod
def get_real_child_model(cls, data):
    """Returns the real base class specified by the discriminator"""
    discriminator_value = data[cls.json_discriminator_key]
    return cls.discriminator_value_class_map.get(discriminator_value)


def _flux_rate(model, subcatchment, lid_index, layer):
    """
    Get lid net inflow - outflow from previous time step for each lid layer
    ONLY FOR for surface, soil, storage, pave
    :param int layerIndex: layer type (toolkitapi.LidLayers member variable)
    :return: Parameter Value
    :rtype: double
    """
    return model.getLidUFluxRates(subcatchment, lid_index, layer)


def get_policy_arn_suffix(region):
    """Method to return region value as expected by policy arn"""
    region_string = region.lower()
    if region_string.startswith('cn-'):
        return 'aws-cn'
    elif region_string.startswith('us-gov'):
        return 'aws-us-gov'
    else:
        return 'aws'


def decolon(item):
    """Colon has special usage in IRC protocol"""
    if item[0] == ':':
        return item[1:]
    return item


def add_month(year, month, delta):
    """
    Helper function which adds `delta` months to current `(year, month)` tuple
    and returns a new valid tuple `(year, month)`
    """
    year, month = divmod(year * 12 + month + delta, 12)
    if month == 0:
        month = 12
        year = year - 1
    return year, month


def render_view_remove():
    """Remove the selected render view

    """
    pass


def cord(value):
    """Convert (str or int) to ord"""
    if isinstance(value, str):
        return ord(value)
    return value


@staticmethod
def calculate_exponential_historical_returns(asset_prices, resample_by=None,
    frequency=252, span=500):
    """
        Calculates the exponentially-weighted annualized mean of historical returns, giving
        higher weight to more recent data.

        :param asset_prices: (pd.DataFrame) Asset price data
        :param resample_by: (str) Period to resample data ['D','W','M' etc.] None for no resampling
        :param frequency: (int) Average number of observations per year
        :param span: (int) Window length to use in pandas ewm function
        :return: (pd.Series) Exponentially-weighted mean of historical returns
        """
    if resample_by:
        asset_prices = asset_prices.resample(resample_by).last()
    returns = asset_prices.pct_change().dropna(how='all')
    returns = returns.ewm(span=span).mean().iloc[-1] * frequency
    return returns


def findTypeFromString(value: str):
    """
    Returns a fitting basic python data type of a string value, i.e.
    :param value: string
    :return: type out of [str, int or float]
    """
    for t in (int, float, str):
        try:
            _ = t(value)
        except ValueError:
            continue
        return t
    return str


def rectangles_from_histogram(H):
    """Largest Rectangular Area in a Histogram

    :param H: histogram table
    :returns: area, left, height, right, rect. is [0, height] * [left, right)
    :complexity: linear
    """
    best = float('-inf'), 0, 0, 0
    S = []
    H2 = H + [float('-inf')]
    for right in range(len(H2)):
        x = H2[right]
        left = right
        while len(S) > 0 and S[-1][1] >= x:
            left, height = S.pop()
            rect = height * (right - left), left, height, right
            if rect > best:
                best = rect
        S.append((left, x))
    return best


def header():
    """return dotdrop header"""
    return 'This dotfile is managed using dotdrop'


def includeme(config):
    """Pyramid configuration hook: activate the perfmetrics tween.

    A statsd_uri should be in the settings.
    """
    if config.registry.settings.get('statsd_uri'):
        config.add_tween('perfmetrics.tween')


def removeService(service):
    """
        Remove a service from this collection.
        """


def execute_query_return_result_proxy(query):
    """
    Execute a query, yield result proxy.

    :param query: :class:`sqlalchemy.orm.Query`,
        has to be created from ``session.query(Object)``

    :return: :class:`sqlalchemy.engine.result.ResultProxy`
    """
    context = query._compile_context()
    context.statement.use_labels = False
    if query._autoflush and not query._populate_existing:
        query.session._autoflush()
    conn = query._get_bind_args(context, query._connection_from_session,
        close_with_result=True)
    return conn.execute(context.statement, query._params)


@staticmethod
def get_key_hash(key):
    """Return the hash for the given key."""
    if key.joystick:
        return '{}:{} {}'.format(key.joystick, key.keytype, key.number)
    else:
        return '{} {}'.format(key.keytype, key.number)


def lookupMailBox(name, timeout=None):
    """
        Perform an MB record lookup.

        @type name: C{str}
        @param name: DNS name to resolve.

        @type timeout: Sequence of C{int}
        @param timeout: Number of seconds after which to reissue the query.
            When the last timeout expires, the query is considered failed.

        @rtype: L{Deferred}
        @return: A L{Deferred} which fires with a three-tuple of lists of
            L{twisted.names.dns.RRHeader} instances.  The first element of the
            tuple gives answers.  The second element of the tuple gives
            authorities.  The third element of the tuple gives additional
            information.  The L{Deferred} may instead fail with one of the
            exceptions defined in L{twisted.names.error} or with
            C{NotImplementedError}.
        """


@staticmethod
def try_encode(field_encoders, entity_dict):
    """
        Inner encoding and try return string from entity dictionary
        :param field_encoders:
        :param entity_dict:
        :return:
        """
    result = ''
    for field_encoder in field_encoders:
        try:
            result += field_encoder.encode(entity_dict)
        except KeyError as e:
            return False
    return result


@staticmethod
def get_date(filename):
    """
        Obtain the date from the filename. The format is YYMMDD.

        :param filename: Filename
        :type filename: str
        :rtype: datetime
        """
    import datetime
    d = filename.split('/')[-1].split('.')[0]
    return datetime.datetime(year=int(d[:2]) + 2000, month=int(d[2:4]), day
        =int(d[-2:]))


@staticmethod
def p_header_optional_list_optional(p):
    """header_optional_list_optional : empty
                                         | header_optional_list"""
    p[0] = tuple() if p[1] is None else p[1]


def gaus_pixval(g, pix):
    """ Calculates the value at a pixel pix due to a gaussian object g. """
    from .const import fwsig, pi
    from math import sin, cos, exp
    cen = g.centre_pix
    peak = g.peak_flux
    bmaj_p, bmin_p, bpa_p = g.size_pix
    a4 = bmaj_p / fwsig
    a5 = bmin_p / fwsig
    a6 = (bpa_p + 90.0) * pi / 180.0
    spa = sin(a6)
    cpa = cos(a6)
    dr1 = ((pix[0] - cen[0]) * cpa + (pix[1] - cen[1]) * spa) / a4
    dr2 = ((pix[1] - cen[1]) * cpa - (pix[0] - cen[0]) * spa) / a5
    pixval = peak * exp(-0.5 * (dr1 * dr1 + dr2 * dr2))
    return pixval


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 perm_parity(lst):
    """
    Given a permutation of the digits 0..N in order as a list,
    returns its parity (or sign): +1 for even parity; -1 for odd.

    Parameters
    ----------
    lst

    Returns
    -------

    Credits
    -------
    Code obtained with thanks from https://code.activestate.com/recipes/578227-generate-the-parity-or-sign-of-a-permutation/
    licensed with a MIT License
    """
    parity = 1
    for i in range(0, len(lst) - 1):
        if lst[i] != i:
            parity *= -1
            mn = min(range(i, len(lst)), key=lst.__getitem__)
            lst[i], lst[mn] = lst[mn], lst[i]
    return parity


def _add_nave(ax, nave):
    """Add nave to axes."""
    if nave is not None:
        ax.annotate('N$_{\\mathrm{ave}}$=%d' % nave, ha='left', va='bottom',
            xy=(0, 1), xycoords='axes fraction', xytext=(0, 5), textcoords=
            'offset pixels')


def getUserName():
    """Get the name used by the user to log into the system.

        Note that this may not be identical to the user's 'getId' (to allow
        users to change their login names without changing their identity).
        """


def decline_weak_feminine_noun(ns: str, gs: str, np: str):
    """
    Gives the full declension of weak feminine nouns.

    >>> decline_weak_feminine_noun("saga", "sögu", "sögur")
    saga
    sögu
    sögu
    sögu
    sögur
    sögur
    sögum
    sagna

    >>> decline_weak_feminine_noun("kona", "konu", "konur")
    kona
    konu
    konu
    konu
    konur
    konur
    konum
    kvenna

    >>> decline_weak_feminine_noun("kirkja", "kirkju", "kirkjur")
    kirkja
    kirkju
    kirkju
    kirkju
    kirkjur
    kirkjur
    kirkjum
    kirkna

    >>> decline_weak_feminine_noun("völva", "völu", "völur")
    völva
    völu
    völu
    völu
    völur
    völur
    völum
    völna

    >>> decline_weak_feminine_noun("speki", "speki", "")
    speki
    speki
    speki
    speki

    >>> decline_weak_feminine_noun("reiði", "reiði", "")
    reiði
    reiði
    reiði
    reiði

    >>> decline_weak_feminine_noun("elli", "elli", "")
    elli
    elli
    elli
    elli

    >>> decline_weak_feminine_noun("frœði", "frœði", "")
    frœði
    frœði
    frœði
    frœði

    It is to note that the genitive plural of völva is not attested so the given form is analogously reconstructed.

    The main pattern is:
    -a
    -u
    -u
    -u
    -ur
    -ur
    -um
    -na

    :param ns: nominative singular
    :param gs: genitive singular
    :param np: nominative plural
    :return:
    """
    if ns[-1] == 'i' and gs[-1] == 'i' and not np:
        print(ns)
        print(ns)
        print(ns)
        print(ns)
    else:
        print(ns)
        print(gs)
        print(gs)
        print(gs)
        print(np)
        print(np)
        print(np[:-1] + 'm')
        if ns == 'kona':
            print('kvenna')
        elif ns[-2] == 'v' or ns[-2] == 'j':
            print(ns[:-2] + 'na')
        else:
            print(ns[:-1] + 'na')


def topic_matches_sub(sub, topic):
    """Check whether a topic matches a subscription.

    For example:

    foo/bar would match the subscription foo/# or +/bar
    non/matching would not match the subscription non/+/+
    """
    result = True
    multilevel_wildcard = False
    slen = len(sub)
    tlen = len(topic)
    if slen > 0 and tlen > 0:
        if sub[0] == '$' and topic[0] != '$' or topic[0] == '$' and sub[0
            ] != '$':
            return False
    spos = 0
    tpos = 0
    while spos < slen and tpos < tlen:
        if sub[spos] == topic[tpos]:
            if tpos == tlen - 1:
                if spos == slen - 3 and sub[spos + 1] == '/' and sub[spos + 2
                    ] == '#':
                    result = True
                    multilevel_wildcard = True
                    break
            spos += 1
            tpos += 1
            if tpos == tlen and spos == slen - 1 and sub[spos] == '+':
                spos += 1
                result = True
                break
        elif sub[spos] == '+':
            spos += 1
            while tpos < tlen and topic[tpos] != '/':
                tpos += 1
            if tpos == tlen and spos == slen:
                result = True
                break
        elif sub[spos] == '#':
            multilevel_wildcard = True
            if spos + 1 != slen:
                result = False
                break
            else:
                result = True
                break
        else:
            result = False
            break
    if not multilevel_wildcard and (tpos < tlen or spos < slen):
        result = False
    return result


def copy_reduce(reducer, graph, target, in_data, out_size, in_map, out_map):
    """Copy target data and perform reduce based on graph structure.

    Parameters
    ----------
    reducer : str
        Type of reduction: be 'sum', 'max', 'min', 'mean', 'prod', 'none' (no
        reduction)
    graph : GraphIndex
        The graph
    target : int
        The input target (src, dst, edge)
    in_data : Tensor
        The input data
    out_size : int
        Size of first dimension of output data
    in_map : tuple
        Two input id mapping arrays, one for forward, the other for backward
    out_map : tuple
        Two output id mapping arrays, one for forward, the other for backward

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


def SizeBenefitAccHosp(t):
    """Accidental hospitalization benefit per policy"""
    return 0


def diffuser_curved(Di1, Di2, l):
    """Returns loss coefficient for any curved wall pipe expansion
    as shown in [1]_.

    .. math::
        K_1 = \\phi(1.43-1.3\\beta^2)(1-\\beta^2)^2

    .. math::
        \\phi = 1.01 - 0.624\\frac{l}{d_1} + 0.30\\left(\\frac{l}{d_1}\\right)^2
        - 0.074\\left(\\frac{l}{d_1}\\right)^3 + 0.0070\\left(\\frac{l}{d_1}\\right)^4

    .. figure:: fittings/curved_wall_diffuser.png
       :scale: 25 %
       :alt: diffuser curved; after [1]_

    Parameters
    ----------
    Di1 : float
        Inside diameter of original pipe (smaller), [m]
    Di2 : float
        Inside diameter of following pipe (larger), [m]
    l : float
        Length of the curve along the pipe axis, [m]

    Returns
    -------
    K : float
        Loss coefficient [-]

    Notes
    -----
    Beta^2 should be between 0.1 and 0.9.
    A small mismatch between tabulated values of this function in table 11.3
    is observed with the equation presented.

    Examples
    --------
    >>> diffuser_curved(Di1=.25**0.5, Di2=1., l=2.)
    0.2299781250000002

    References
    ----------
    .. [1] Rennels, Donald C., and Hobart M. Hudson. Pipe Flow: A Practical
       and Comprehensive Guide. 1st edition. Hoboken, N.J: Wiley, 2012.
    """
    beta = Di1 / Di2
    phi = 1.01 - 0.624 * l / Di1 + 0.3 * (l / Di1) ** 2 - 0.074 * (l / Di1
        ) ** 3 + 0.007 * (l / Di1) ** 4
    return phi * (1.43 - 1.3 * beta ** 2) * (1 - beta ** 2) ** 2


def print_summary():
    """Print wireless monthly summary among users."""
    from attbillsplitter.services import run_print_summary
    run_print_summary()


def pad_line(line):
    """Helper function to pad line to 80 characters in case it is shorter"""
    size_of_line = len(line)
    if size_of_line < 80:
        padding = 80 - size_of_line + 1
        line = line.strip('\n') + ' ' * padding + '\n'
    return line[:81]


@staticmethod
def channel():
    """ Provides the mask needed to decode the Channel from Word 0 """
    return 15, 0


def generic_positional_rendering_helper(tagname, message, attrs, rendered,
    pos, tag):
    """returns new tag with rendered content dependent on position

    tagname
        name of new tag, ie. div, p, label and so on

    message
        text included in new tag

    attrs
        attributes on new tag

    rendered
        prior rendered text

    pos
        position how to place the newtag relative to the prior rendered:
        'before'='<newtag>message</newtag>rendered',
        'after' ='<newtag>message</newtag>'
        'inner-before'= <newtag>message rendered</newtag>
        'inner-after'= <newtag>rendered message</newtag>
    """
    if pos not in ['before', 'after', 'inner-before', 'inner-after']:
        raise ValueError('Invalid value for position "{0}"'.format(pos))
    if pos.startswith('inner'):
        if pos.endswith('before'):
            inner = message, rendered
        else:
            inner = rendered, message
        return tag(tagname, *inner, **attrs)
    else:
        newtag = tag(tagname, message, **attrs)
        if pos == 'before':
            return newtag + rendered
        return rendered + newtag


def sort_3(l):
    """
    An incorrect implementation of the sort() function. Sorts given list in
    reverse order.
    """
    l.sort(reverse=True)


@staticmethod
def generate_file(content, destination_path):
    """
        Given the generated content and a destination path, it will
        write that content to a file in that path.
        """
    with open(destination_path, 'w') as file_handle:
        file_handle.write(content)


def _justify_pair(pair, width=80, padding_with='.'):
    """align first element along the left margin, second along the right, padding spaces"""
    n = width - len(pair[0])
    return '{key}{value:{c}>{n}}'.format(key=pair[0], value=pair[1], c=
        padding_with, n=n)


def integer_bit_length(number):
    """
  Number of bits needed to represent a integer excluding any prefix
  0 bits.

  :param number:
      Integer value. If num is 0, returns 0. Only the absolute value of the
      number is considered. Therefore, signed integers will be abs(num)
      before the number's bit length is determined.
  :returns:
      Returns the number of bits in the integer.
  """
    if number == 0:
        return 0
    if number < 0:
        number = -number
    _ = number & 1
    hex_num = '%x' % number
    return (len(hex_num) - 1) * 4 + {'0': 0, '1': 1, '2': 2, '3': 2, '4': 3,
        '5': 3, '6': 3, '7': 3, '8': 4, '9': 4, 'a': 4, 'b': 4, 'c': 4, 'd':
        4, 'e': 4, 'f': 4}[hex_num[0]]


def add_edges(graph, edges):
    """Add edge(s) to graph

    Args:
        graph (Graph): Graph to add edge(s) to
        edges (list): List of edges

    Returns:
        Graph: Return the modified graph

    """
    for e in edges:
        if isinstance(e[0], tuple):
            graph.edge(*e[0], **e[1])
        else:
            graph.edge(*e)
    return graph


def SGPtGroup(SGData):
    """
    Determine point group of the space group - done after space group symbol has
    been evaluated by SpcGroup. Only short symbols are allowed

    :param SGData: from :func SpcGroup
    :returns: SSGPtGrp & SSGKl (only defaults for Mono & Ortho)
    """
    Flds = SGData['SpGrp'].split()
    if len(Flds) < 2:
        return '', []
    if SGData['SGLaue'] == '-1':
        if '-' in Flds[1]:
            return '-1', [-1]
        else:
            return '1', [1]
    elif SGData['SGLaue'] == '2/m':
        if '/' in SGData['SpGrp']:
            return '2/m', [-1, 1]
        elif '2' in SGData['SpGrp']:
            return '2', [-1]
        else:
            return 'm', [1]
    elif SGData['SGLaue'] == 'mmm':
        if SGData['SpGrp'].count('2') == 3:
            return '222', [-1, -1, -1]
        elif SGData['SpGrp'].count('2') == 1:
            if SGData['SGPolax'] == 'x':
                return '2mm', [-1, 1, 1]
            elif SGData['SGPolax'] == 'y':
                return 'm2m', [1, -1, 1]
            elif SGData['SGPolax'] == 'z':
                return 'mm2', [1, 1, -1]
        else:
            return 'mmm', [1, 1, 1]
    elif SGData['SGLaue'] == '4/m':
        if '/' in SGData['SpGrp']:
            return '4/m', [1, -1]
        elif '-' in Flds[1]:
            return '-4', [-1]
        else:
            return '4', [1]
    elif SGData['SGLaue'] == '4/mmm':
        if '/' in SGData['SpGrp']:
            return '4/mmm', [1, -1, 1, 1]
        elif '-' in Flds[1]:
            if '2' in Flds[2]:
                return '-42m', [-1, -1, 1]
            else:
                return '-4m2', [-1, 1, -1]
        elif '2' in Flds[2:]:
            return '422', [1, -1, -1]
        else:
            return '4mm', [1, 1, 1]
    elif SGData['SGLaue'] in ['3', '3R']:
        if '-' in Flds[1]:
            return '-3', [-1]
        else:
            return '3', [1]
    elif SGData['SGLaue'] == '3mR' or 'R' in Flds[0]:
        if '2' in Flds[2]:
            return '32', [1, -1]
        elif '-' in Flds[1]:
            return '-3m', [-1, 1]
        else:
            return '3m', [1, 1]
    elif SGData['SGLaue'] == '3m1':
        if '2' in Flds[2]:
            return '321', [1, -1, 1]
        elif '-' in Flds[1]:
            return '-3m1', [-1, 1, 1]
        else:
            return '3m1', [1, 1, 1]
    elif SGData['SGLaue'] == '31m':
        if '2' in Flds[3]:
            return '312', [1, 1, -1]
        elif '-' in Flds[1]:
            return '-31m', [-1, 1, 1]
        else:
            return '31m', [1, 1, 1]
    elif SGData['SGLaue'] == '6/m':
        if '/' in SGData['SpGrp']:
            return '6/m', [1, -1]
        elif '-' in SGData['SpGrp']:
            return '-6', [-1]
        else:
            return '6', [1]
    elif SGData['SGLaue'] == '6/mmm':
        if '/' in SGData['SpGrp']:
            return '6/mmm', [1, -1, 1, 1]
        elif '-' in Flds[1]:
            if '2' in Flds[2]:
                return '-62m', [-1, -1, 1]
            else:
                return '-6m2', [-1, 1, -1]
        elif '2' in Flds[2:]:
            return '622', [1, -1, -1]
        else:
            return '6mm', [1, 1, 1]
    elif SGData['SGLaue'] == 'm3':
        if '2' in Flds[1]:
            return '23', []
        else:
            return 'm3', []
    elif SGData['SGLaue'] == 'm3m':
        if '4' in Flds[1]:
            if '-' in Flds[1]:
                return '-43m', []
            else:
                return '432', []
        else:
            return 'm3m', []


@staticmethod
def to_romer(kelvin):
    """ Convert kelvin to romer """
    return (kelvin - 273.15) * (21 / 40) + 7.5


def export_month(form, action):
    """Form handler function exporting the current month."""
    calendar = form.getContent().context
    form.request.response.redirect(form.url(calendar, 'export-month'))


def fill_metadata(jobs, entry, mtable):
    """Fill the metadata table with the info on the downloaded files.

    Parameters
    ----------
    jobs: List[DownloadJob]
        List of all different file format download jobs for an entry
    entry:
        An assembly entry describing the current download jobs
    mtable:
        Metadata table object to write into

    Returns
    -------
    None
    """
    for job in jobs:
        if job.full_url is not None:
            mtable.add(entry, job.local_file)