def _get_consecutive_portions_of_front(front):
    """
    Yields lists of the form [(f, s), (f, s)], one at a time from the given front (which is a list of the same form),
    such that each list yielded is consecutive in frequency.
    """
    last_f = None
    ls = []
    for f, s in front:
        if last_f is not None and f != last_f + 1:
            yield ls
            ls = []
        ls.append((f, s))
        last_f = f
    yield ls


def _make_entity_from_id(entity_cls, entity_obj_or_id, server_config):
    """Given an entity object or an ID, return an entity object.

    If the value passed in is an object that is a subclass of :class:`Entity`,
    return that value. Otherwise, create an object of the type that ``field``
    references, give that object an ID of ``field_value``, and return that
    object.

    :param entity_cls: An :class:`Entity` subclass.
    :param entity_obj_or_id: Either a :class:`nailgun.entity_mixins.Entity`
        object or an entity ID.
    :returns: An ``entity_cls`` object.
    :rtype: nailgun.entity_mixins.Entity

    """
    if isinstance(entity_obj_or_id, entity_cls):
        return entity_obj_or_id
    return entity_cls(server_config, id=entity_obj_or_id)


@classmethod
def _cache_key(cls, *args, **kwargs):
    """An AbstractTensor caches on the class type itself."""
    return cls


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 from_data(cls, data, ids=None, feature_names=None, static=True):
    """Converts two arrays or a sparse matrix data and its associated
        id array to Dataset.

        Parameters
        ----------
        data : array or scipy 2-D sparse matrix of shape
               [n_samples, n_features]
        ids : array of shape [n_samples], optional
        feature_names : array of shape [n_features], optional
        """
    if hasattr(data, 'todense'):
        return cls.from_matrix(data, ids, feature_names, static)
    else:
        return cls.from_array(data, ids, feature_names, static)


def _mul(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Multiplies arguments element-wise.

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

       - elemwise_mul(default, default) = default
       - elemwise_mul(row_sparse, row_sparse) = row_sparse
       - elemwise_mul(default, row_sparse) = row_sparse
       - elemwise_mul(row_sparse, default) = row_sparse
       - elemwise_mul(csr, csr) = csr
       - otherwise, ``elemwise_mul`` generates output with default storage

    Parameters
    ----------
    lhs : NDArray
        first input
    rhs : NDArray
        second input

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

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


def p_key_decl(p):
    """ key_decl : KEY STRING BRACE_OPEN key_decl_block BRACE_CLOSE SEMICOLON """
    p[0] = {p[1]: p[2]}
    p[0].update(p[4])


def get_scaling_function(y_m, y_M, x_m, x_M):
    """
    Returns a linear function y = k x + b, where y \\in [m, M]
    :param y_m:
    :param y_M:
    :param x_m:
    :param x_M:
    :return:
    """
    if x_M <= x_m:
        return lambda _: y_m
    k = (y_M - y_m) / (x_M - x_m)
    b = y_m - k * x_m
    return lambda _: int(k * _ + b)


def quantify(iterable, pred=bool):
    """Count how many times the predicate is true"""
    return sum(map(pred, iterable))


def nessus_x509scan_loopy(var1, reporthost, x509_obs, var2):
    """ Specific Nessus loop to find all X.509 certificate issues """
    for reportitem in reporthost.findall('ReportItem'):
        if int(reportitem.get('pluginID')) in x509_obs.keys():
            if var1 == 'addr':
                var2.append(reporthost.get('name') + ':' + reportitem.get(
                    'port'))
            elif var1 == 'obs':
                var2.append(x509_obs.get(int(reportitem.get('pluginID'))))


def PNT2TidalOcto_Tv16(XA, beta0PNT=0, beta1PNT=0):
    """ TaylorT2 1PN Octopolar Tidal Coefficient, v^16 Timing Term.

   XA = mass fraction of object
   beta0PNT = 0PN Octopole Tidal Flux coefficient
   beta1PNT = 1PN Octopole Tidal Flux coefficient """
    XATo2nd = XA * XA
    XATo3rd = XATo2nd * XA
    XATo4th = XATo3rd * XA
    XATo5th = XATo4th * XA
    return 33440 / 21 + 995 * beta0PNT / 168 + beta1PNT + (24670 / 7 + 17 *
        beta0PNT / 3) * XA - 17 / 6 * (1825 + 2 * beta0PNT
        ) * XATo2nd + 325 * XATo3rd / 6


@staticmethod
def _reduce(res, result_single_frame):
    """ 'accumulate' action for a time series"""
    if isinstance(res, list) and len(res) == 0:
        res = result_single_frame
    else:
        res += result_single_frame
    return res


def validate_inferred_freq(freq, inferred_freq, freq_infer):
    """
    If the user passes a freq and another freq is inferred from passed data,
    require that they match.

    Parameters
    ----------
    freq : DateOffset or None
    inferred_freq : DateOffset or None
    freq_infer : bool

    Returns
    -------
    freq : DateOffset or None
    freq_infer : bool

    Notes
    -----
    We assume at this point that `maybe_infer_freq` has been called, so
    `freq` is either a DateOffset object or None.
    """
    if inferred_freq is not None:
        if freq is not None and freq != inferred_freq:
            raise ValueError(
                f'Inferred frequency {inferred_freq} from passed values does not conform to passed frequency {freq.freqstr}'
                )
        elif freq is None:
            freq = inferred_freq
        freq_infer = False
    return freq, freq_infer


@staticmethod
def _time_event(dt, self):
    """The timer callback.
        """
    if not self._is_active:
        return
    if self.viewer_flags['record']:
        self._record()
    if self.viewer_flags['rotate'] and not self.viewer_flags['mouse_pressed']:
        self._rotate()
    if self._message_text is not None:
        if self._message_opac > 1.0:
            self._message_opac -= 1.0
        else:
            self._message_opac *= 0.9
        if self._message_opac < 0.05:
            self._message_opac = 1.0 + self._ticks_till_fade
            self._message_text = None
    if self._should_close:
        self.on_close()
    else:
        self.on_draw()


def isInfoSupported(ob, name):
    """ Return True if the given info name is supported by this workflow
            for a given content object, else False.

        o 'ob' is the content object.

        o 'name' is the name of the requested workflow information.

        o Invoked by the portal_workflow tool.

        o Permission:  Private (Python only)
        """


def formatUintHex32(value):
    """
    Format an 32 bits unsigned integer.
    """
    return u'0x%08x' % value


@classmethod
def fromYaml(cls, filename):
    """Load an `Optic` (commonly a complete telescope) from the given yaml
        file.  This is the most common way to create an `Optic`.  If the file
        is not initially found, then look in the ``batoid.datadir`` directory
        and subdirectories for the first matching filename and use that.

        Look in ``batoid.datadir`` for examples of how to format a batoid optic
        yaml file.

        Parameters
        ----------
        filename : str
            Name of yaml file to load

        Returns
        -------
        `Optic`
        """
    import os
    import yaml
    try:
        with open(filename) as f:
            config = yaml.safe_load(f)
    except FileNotFoundError:
        import glob
        from . import datadir
        filenames = glob.glob(os.path.join(datadir, '**', '*.yaml'))
        for candidate in filenames:
            if os.path.basename(candidate) == filename:
                with open(candidate) as f:
                    config = yaml.safe_load(f)
                break
        else:
            raise FileNotFoundError(filename)
    from .parse import parse_optic
    return parse_optic(config['opticalSystem'])


def toolbox():
    """Display button panel toolbox

    """
    pass


def __new__(cls, _str_: str, if_empty: str='', s: str=' or ', quote_args:
    bool=False) ->'AtRule':
    """Create the ``AtRule`` and save parameters.

        Parameters
        ----------
        _str_ : str
            The string of the current ``Var``

        For the other parameters, see the class docstring (``if_empty`` and ``quote_args`` have
        the same name as the arguments to ``__new__`, but ``separator`` comes from the ``s``
        argument.

        Returns
        -------
        AtRule
            The newly created AtRule.

        """
    obj = super().__new__(cls, _str_)
    obj.if_empty = if_empty
    obj.separator = s
    obj.quote_args = quote_args
    return obj


@classmethod
def Character(cls):
    """Postgres Character Type"""
    return cls(str, 'CHARACTER')


@classmethod
def decode_ssh_public(cls, packet):
    """Decode an SSH format U2F Ed25519 public key"""
    public_value = packet.get_string()
    application = packet.get_string()
    return public_value, application


def bresenham(x1, y1, x2, y2):
    """
    Iterate over points in a bresenham line.

    Implementation hastily copied from RogueBasin.

    @return: Returns an iterator of (x, y) points.
    """
    points = []
    is_steep = abs(y2 - y1) > abs(x2 - x1)
    if is_steep:
        x1, y1 = y1, x1
        x2, y2 = y2, x2
    rev = False
    if x1 > x2:
        x1, x2 = x2, x1
        y1, y2 = y2, y1
        rev = True
    dx = x2 - x1
    dy = abs(y2 - y1)
    error = int(dx / 2)
    y = y1
    if y1 < y2:
        y_step = 1
    else:
        y_step = -1
    for x in range(x1, x2 + 1):
        if is_steep:
            points.append((y, x))
        else:
            points.append((x, y))
        error -= dy
        if error < 0:
            y += y_step
            error += dx
    if rev:
        points.reverse()
    return iter(points)


def Get_epsg(g, extension='tiff'):
    """
    This function reads the projection of a GEOGCS file or tiff file

    Keyword arguments:
    g -- string
        Filename to the file that must be read
    extension -- tiff or GEOGCS
        Define the extension of the dataset (default is tiff)
    """
    try:
        if extension == 'tiff':
            g_proj = g.GetProjection()
            Projection = g_proj.split('EPSG","')
        if extension == 'GEOGCS':
            Projection = g
        epsg_to = int(str(Projection[-1]).split(']')[0][0:-1])
    except:
        epsg_to = 4326
    return epsg_to


def cast(value):
    """Cast appropriately: a sequence to a tuple, otherwise as a str."""
    if isinstance(value, (list, tuple, set)):
        return tuple(value)
    else:
        return str(value),


def format_float_or_int_string(text: str) ->str:
    """Formats a float string like "1.0"."""
    if '.' not in text:
        return text
    before, after = text.split('.')
    return f'{before or 0}.{after or 0}'


def _num_ln(keys, num):
    """Arranging buttons"""
    if type(keys[0]) is list:
        keys = keys[0]
    len_k = len(keys)
    num_of_lines = len_k // num
    lst, curr = [], 0
    for d in range(num_of_lines):
        temp_lst = []
        for e in range(curr, num + curr):
            temp_lst.append(keys[e])
        lst.append(temp_lst)
        curr += num
    lst.append(keys[len_k - len_k % num:])
    return lst


def datetime_iso_format(date):
    """
    Return an ISO-8601 representation of a datetime object.
    """
    return '{0:0>4}-{1:0>2}-{2:0>2}T{3:0>2}:{4:0>2}:{5:0>2}Z'.format(date.
        year, date.month, date.day, date.hour, date.minute, date.second)


@classmethod
def pulp_name(cls) ->str:
    """Return a unique name for a new variable."""
    cls._NAME += 1
    return 'x' + str(cls._NAME)


def tag(colontag):
    """Return the fully-qualified XML tag name for a GnuCash tag."""
    prefix, name = colontag.split(':')
    return '{http://www.gnucash.org/XML/%s}%s' % (prefix, name)


@staticmethod
def get_prereq_packages():
    """Should return a list of system packages to be installed before
        running database configuration."""
    return []


def top_index_iter(shape):
    """Iterator for the top boundary indices of a structured grid."""
    return range(shape[1] * (shape[0] - 1), shape[0] * shape[1])


def get_all_sources(item=None):
    """Return all sources for News Item, global, or below the given item.
        """


@classmethod
def get(cls, doctree):
    """Return the first slideconf node for the doctree."""
    conf_nodes = doctree.traverse(cls)
    if conf_nodes:
        return conf_nodes[0]


def _read_one(stream):
    """Read a byte from the file (as an integer)

    raises EOFError if the stream ends while reading bytes.
    """
    c = stream.read(1)
    if c == '':
        raise EOFError('Unexpected EOF while reading bytes')
    return ord(c)


@classmethod
def from_json(cls, val):
    """ Create a taxon from JSON

        Args:
            val (:obj:`dict`)

        Returns:
            :obj:`Taxon`
        """
    return cls(id=val.get('id', None), name=val.get('name', None))


def reply(zelf, *args, **kwargs):
    """ send reply to origin. """
    if 'outer' in zelf:
        zelf.outer.write(str(args[0]) + '\n')
        zelf.outer.flush()
        return
    if 'channel' in zelf:
        zelf.say(zelf.channel, args[0])
    else:
        zelf.say(zelf.origin, args[0])


def cobyla_positivity_constraint(volume_fractions, *args):
    """COBYLA positivity constraint on volume fractions"""
    return volume_fractions - 0.001


def help_content():
    """ commands possible for use. Need to be improved """
    some = """
    start                   --create window to draw image
    exit, quit              --finish drawing
    help                    --this help content
    save                    --save image as "drawing.png"
    draw                    --draw some random line
    clear                   --clear image
    refresh                 --refresh live mode
    resize                  --resize objects
    sound on/off            --turn on/off sound effects
    list_files              --list files from lines_only directory
    load <file> <x_pos>
         <y_pos> <size>     --load image
    set_color <color>       --just a name of color? like red, green...
    """
    return some


@classmethod
def _summarize_text(cls, text, max_len=24):
    """Avoid spamming logs by truncating text."""
    if len(text) > max_len:
        return '{!r} + {} chars'.format(text[:max_len], len(text) - max_len)
    return repr(text)


def iterator(d):
    """
    Helper to get and a proper dict iterator with Py2k and Py3k
    """
    try:
        return d.iteritems()
    except AttributeError:
        return d.items()


def pool_output_length(input_length, pool_size, stride, pad, ignore_border):
    """
    Compute the output length of a pooling operator
    along a single dimension.

    Parameters
    ----------
    input_length : integer
        The length of the input in the pooling dimension
    pool_size : integer
        The length of the pooling region
    stride : integer
        The stride between successive pooling regions
    pad : integer
        The number of elements to be added to the input on each side.
    ignore_border: bool
        If ``True``, partial pooling regions will be ignored.
        Must be ``True`` if ``pad != 0``.

    Returns
    -------
    output_length
        * None if either input is None.
        * Computed length of the pooling operator otherwise.

    Notes
    -----
    When ``ignore_border == True``, this is given by the number of full
    pooling regions that fit in the padded input length,
    divided by the stride (rounding down).

    If ``ignore_border == False``, a single partial pooling region is
    appended if at least one input element would be left uncovered otherwise.
    """
    if input_length is None or pool_size is None:
        return None
    if ignore_border:
        output_length = input_length + 2 * pad - pool_size + 1
        output_length = (output_length + stride - 1) // stride
    else:
        assert pad == 0
        if stride >= pool_size:
            output_length = (input_length + stride - 1) // stride
        else:
            output_length = max(0, (input_length - pool_size + stride - 1) //
                stride) + 1
    return output_length


def parse_meta(obj, response):
    """
    Get ``_id`` and ``_rev`` from response
    and update document with updated values
    """
    if '_id' in response.data:
        obj._id = str(response.data.get('_id'))
    obj._rev = str(response.data.get('_rev'))
    return response


@staticmethod
def _computeElidedText(text):
    """ Compute the minimum elided text for the tab title.

        """
    if len(text) > 3:
        text = text[:2] + '...'
    return text


def is_tensor(obj):
    """Returns true if the given object is a framework-specific tensor."""
    pass


def prepare_makefile_lines(makefile_path):
    """return makefile content"""
    with open(makefile_path, 'r') as makefile:
        lines = makefile.readlines()
    return lines


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


def is_ascii_problem(s):
    """
    Test if a string contains other chars than ASCII

    :param s: a string to test
    :return: True if string contains other chars than ASCII, False otherwise
    """
    try:
        s.encode('ascii')
        return False
    except (UnicodeEncodeError, UnicodeDecodeError):
        return True


def rollback(dryrun=False, force=False):
    """Undo the last transaction.

        DANGEROUS.
        """


def ban(email):
    """Ban an email address from subscribing to a mailing list.

        When an email address is banned, it will not be allowed to subscribe
        to the mailing list.  This does not affect any email address that may
        already be subscribed to a mailing list.

        It is also possible to add a 'ban pattern' whereby all email addresses
        matching a Python regular expression can be banned.  This is
        accomplished by using a `^` as the first character in `email`.

        When an email address is already banned.  However, it is possible to
        extend a ban for a specific mailing list into a global ban; both bans
        would be in place and they can be removed individually.

        :param email: The text email address being banned or, if the string
            starts with a caret (^), the email address pattern to ban.
        :type email: str
        """


def get_source(trip):
    """
    Return the source name for the trip
    :param trip: trip Object
    :return: string containing source name
    """
    if 'srcname' in trip.keys():
        return trip['srcname']
    if 'src' in trip.keys():
        if isinstance(trip['src'], list):
            return trip['src'][0]
        elif isinstance(trip['src'], str):
            return trip['src']
        else:
            return ''
    else:
        return ''


def compose_tfms(x, tfms, is_enc=True, reverse=False, **kwargs):
    """Apply all `func_nm` attribute of `tfms` on `x`, maybe in `reverse` order"""
    if reverse:
        tfms = reversed(tfms)
    for f in tfms:
        if not is_enc:
            f = f.decode
        x = f(x, **kwargs)
    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


def is_throttled(e):
    """
    Determines whether the exception is due to API throttling.

    :param e:                           Exception raised
    :return:                            True if it's a throttling exception else False
    """
    return True if hasattr(e, 'response'
        ) and 'Error' in e.response and e.response['Error']['Code'] in [
        'Throttling', 'RequestLimitExceeded', 'ThrottlingException',
        'TooManyRequestsException'] else False


def writelist(mylist, outfile, mode='w'):
    """Write list of strings to an output file with each row an element of
    the list"""
    with open(outfile, mode) as f:
        for s in mylist:
            f.write(str(s) + '\n')
    return outfile


@staticmethod
def get_banks_request():
    """
        Get a transaction getbanks :class:`paynlsdk.api.transaction.getbanks.Request` instance

        :return: Transaction getbanks request instance
        :rtype: paynlsdk.api.transaction.getbanks.Request
        """
    from paynlsdk.api.transaction.getbanks import Request
    return Request()


def _set_defaults(d):
    """Adds the default values to the specified dictionary if they don't already
    exist. This includes all the parameters necessary to construct the templates
    for the classes.

    .. note:: This mutates the given dictionary if some of the keys are missing.
    """
    d.setdefault('title', 'No schema information available.')
    d.setdefault('inclusion', 'unknown')
    d.setdefault('status', 'unknown')
    d.setdefault('description', 'No description was returned from AFLUX.')
    d.setdefault('type')


@staticmethod
def find_bool(name, *dicts):
    """
        Finds the value for the key name in multiple dicts

        :param name: the key to find
        :param dicts: the list of dicts
        :return:
        """
    value = False
    for d in dicts:
        if type(d) == str:
            value = d == 'True'
        elif name in d:
            value = d[name]
        if type(value) == str:
            value = value == 'True'
        if value:
            return True
    return False


def long_timestamp(time):
    """
    Generate a (long) human-readable timestamp
    (e.g., `"Wednesday June 05, 2013; 02:58:21 PM"`)

    **Parameters:**

    * `time`: an instance of `datetime.datetime`

    **Returns:** a string containing a human-readable representation of the
    given time
    """
    return time.strftime('%A %B %d, %Y; %I:%M:%S %p')


def get_name():
    """
    Return this driver's name
    """
    return 'dummy'


def maybe_first(a, b):
    """Returns first argument 'a' if it is not None else 'b' """
    return b if a is None else a


@classmethod
def clearSize(cls, f0):
    """Return a copy of f0 with no size specified, or None if f0 is None."""
    if (f0 is None or f0.owner is None and f0.dataset is None and f0.mtime is
        None and f0.notPaths == [] and f0.regex is None):
        return None
    else:
        return cls(f0.owner, f0.dataset, None, f0.mtime, f0.notPaths, f0.regex)


@staticmethod
def setup_command_line(parser):
    """Setup the command line options for Counting Principle formula

        Arguments:
        - `parser`: parser to load with options.
        """
    parser.add_argument('M', metavar='<M>', type=int, help='domain size')
    parser.add_argument('p', metavar='<p>', type=int, help='size of the parts')


def is_numeric(obj: object) ->bool:
    """
    ``True`` only if the passed object is **numeric** (i.e., instance of either
    the `int` or `float` types).
    """
    return isinstance(obj, (int, float))


@property
def slug(cls):
    """
        The state in string form so that it can be stored in databases etc.
        If a state is renamed, this should be set explicitly as a class attribute
        to the original value to avoid data problems.
        """
    return cls.__dict__.get('slug', cls.__name__)


def _unpack_bitmap(bitmap, xenum):
    """
    Given an integer bitmap and an enumerated type, build
    a set that includes zero or more enumerated type values
    corresponding to the bitmap.
    """
    unpacked = set()
    for enval in xenum:
        if enval.value & bitmap == enval.value:
            unpacked.add(enval)
    return unpacked


@classmethod
def class_print_help(cls, inst=None):
    """Get the help string for a single trait and print it."""
    print(cls.class_get_help(inst))


def _upgrade_chunk_info(chunk_info, improved_chunk_info):
    """Replace chunk info items with better ones while preserving number of dumps."""
    for key, improved_info in improved_chunk_info.items():
        original_info = chunk_info.get(key, improved_info)
        if improved_info['shape'][1:] != original_info['shape'][1:]:
            raise ValueError(
                "Original '{}' array has shape {} while improvedversion has shape {}"
                .format(key, original_info['shape'], improved_info['shape']))
        chunk_info[key] = improved_info
    return chunk_info


@classmethod
def validate(cls, version: str) ->bool:
    """Test if string is valid SemVer."""
    try:
        cls(version=version)
        return True
    except ValueError:
        return False


@classmethod
def update_mv(cls):
    """
        Return False if an mv SHOULD NOT be updated
        :return:
        """
    return True


def fizzbuzz(n: int) ->str:
    """
    Outputs 'fizz', if the input is dividable by 5.
    Outputs 'buzz', if the input is dividable by 7.
    Outputs 'fizzbuzz', if the input is dividable by 5 and 7.

    Example:
        >>> fizzbuzz(35)
        'fizzbuzz'
        >>> fizzbuzz(36)
        ''

    :param n: Positive integer
    :return: String 'fizz', 'buzz', 'fizzbuzz' oder empty string
    """
    if type(n) != int:
        raise TypeError(f'int expected as input, got {type(n)}')
    if n < 0:
        raise ValueError(f'Positive input expected')
    return f"{'fizz' if n % 5 == 0 else ''}{'buzz' if n % 7 == 0 else ''}"


@staticmethod
def fix_text(text):
    """Function that removes useless spaces from text"""
    text = text.replace('\t', '')
    text = text.replace('    ', '')
    return text


def makeDocStructures(context):
    """
    makeDocStructures(context) -> namespaces, subdirs

    Creates two structures that provide a friendly format for
    documentation.

    *namespaces* is a dictionary that maps namespaces to a directives
    dictionary with the key being the name of the directive and the
    value is a tuple: (schema, handler, info).

    *subdirs* maps a (namespace, name) pair to a list of subdirectives
    that have the form (namespace, name, schema, info).
    """
    namespaces = {}
    subdirs = {}
    registry = context._docRegistry
    for (namespace, name), schema, usedIn, handler, info, parent in registry:
        if not parent:
            ns_entry = namespaces.setdefault(namespace, {})
            ns_entry[name] = schema, handler, info
        else:
            sd_entry = subdirs.setdefault((parent.namespace, parent.name), [])
            sd_entry.append((namespace, name, schema, handler, info))
    return namespaces, subdirs


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 compose_all(stream, Loader=Loader):
    """
    Parse all YAML documents in a stream
    and produce corresponding representation trees.
    """
    loader = Loader(stream)
    try:
        while loader.check_node():
            yield loader._composer.get_node()
    finally:
        loader._parser.dispose()


def open(filename, compression=None, mode='rb', *args, **kwargs):
    """ Override default open() function """
    open_statement = 'builtins.open(filename, mode=mode, *args, **kwargs)'
    if compression:
        open_statement = open_statement.replace('builtins', compression)
    return eval(open_statement)


def _is_in(a, b):
    """ Method used only in `In` """
    return a in b


def f1(x):
    """f1 is a quadratic with roots at 0 and 1"""
    return x * (x - 1.0)


def philly_storm_intensity(tc, return_period=0):
    """
	given a tc, return the intensity of the
	Philadelphia Water Dept design storm (in/hr)
	"""
    I = 116.0 / (tc + 17.0)
    if return_period == 1:
        I = 100.0 / (tc + 18.0)
    if return_period == 2:
        I = 131.0 / (tc + 21.0)
    if return_period == 5:
        I = 171.0 / (tc + 23.5)
    if return_period == 10:
        I = 214.0 / (tc + 26.0)
    if return_period == 25:
        I = 252.0 / (tc + 28.0)
    if return_period == 50:
        I = 289.0 / (tc + 30.0)
    if return_period == 100:
        I = 325.0 / (tc + 32.0)
    return I


@classmethod
def isWeekly(cls, expiration):
    """isWeekly checks if the expiration date corresponds to a Weekly
        SPX option.

        Weeklys were introduced in 2005, but had a very low liquidity for many
        years. The CBOE itself did not include Weeklys in the computation of
        the VIX until after 2013 (in 2014 Weeklys were included). For this
        reason, when selecting options it is often argued that Weeklys
        prior to 2014 should be disconsidered.

        Args:
            expiration (datetime): A datetime object containing the expiration
                       date of the option. Must have year, month and
                       day.

        Returns:
            (bool): True if Weekly SPX option.

        """
    return not cls.isStandard(expiration)


def parse_signature(signature):
    """
    Breaks 'func(address)(uint256)' into ['func', '(address)', '(uint256)']
    """
    parts = []
    stack = []
    start = 0
    for end, letter in enumerate(signature):
        if letter == '(':
            stack.append(letter)
            if not parts:
                parts.append(signature[start:end])
                start = end
        if letter == ')':
            stack.pop()
            if not stack:
                parts.append(signature[start:end + 1])
                start = end + 1
    return parts


def parse_port_list(string, limit=None, zero_count=False):
    """
    Parse a binary port list
    :param string:
    :param limit:
    :param zero_count: Count index from zero
    :return:
    """
    ports = dict()
    for pos, byte in enumerate(string):
        binary = format(ord(byte), '08b')
        offset = 8 * pos
        for binpos, binbyte in enumerate(binary):
            if not zero_count:
                index = binpos + offset + 1
            else:
                index = binpos + offset
            if binbyte == '1':
                ports[index] = True
            else:
                ports[index] = False
            if limit and index >= limit:
                return ports
    return ports


def ni(i):
    """
    Return a usable interval (called resolution in the api). Note that ni accepts D W and M but structjour
    will never put it in a a request.
    :return: The given argument if its supported or 1, enabling resample for all other (int) values
    """
    supported = [1, 5, 15, 30, 60, 'D', 'W', 'M']
    if i in supported:
        return i
    elif isinstance(i, int):
        return 1
    return 5


@staticmethod
def recast(val, datatype):
    """ Re-cast the value based upon an AWS supplied datatype
            and treat nulls sensibly.
        """
    ret_val = val
    if datatype == 'string':
        ret_val = str(val)
    elif datatype == 'boolean':
        if val.isdigit():
            ret_val = bool(int(val))
        elif val == 'TRUE':
            ret_val = True
        elif val == 'FALSE':
            ret_val = False
    elif datatype == 'integer':
        if val.isdigit():
            ret_val = int(val)
    elif datatype == 'float':
        ret_val = float(val) if val else 0.0
    return ret_val


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

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

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


def with_metaclass(meta, base=object):
    """Create a base class with a metaclass."""
    return meta('NewBase', (base,), {})


def explain_aw(fsm, state, phi, psi):
    """
    Explain why state of fsm satisfies A phi W psi.

    fsm -- the fsm;
    state -- a state of fsm satisfying A phi W psi;
    phi -- the set of states of fsm satifying phi;
    psi -- the set of states of fsm satifying psi.
    """
    pass


def odml_tuple_import(t_count, new_value):
    """
    Checks via a heuristic if the values in a string fit the general
    odml style tuple format and the individual items match the
    required number of tuple values.
    Legacy Python2 code required to parse unicode strings to a list
    of odml style tuples.

    :param t_count: integer, required values within a single odml style tuple.
    :param new_value: string containing an odml style tuple list.
    :return: list of odml style tuples.
    """
    try:
        unicode = unicode
    except NameError:
        unicode = str
    if len(new_value) != 1 and not isinstance(new_value[0], unicode):
        return new_value
    cln = new_value[0].strip()
    l_check = cln.startswith('[') and cln.endswith(']')
    br_check = cln.count('(') == cln.count(')')
    com_check = cln.count('(') == cln.count(',') + 1
    sep_check = t_count == 1 or cln.count('(') == cln.count(';') / (t_count - 1
        )
    if l_check and br_check and com_check and sep_check:
        new_value = cln[1:-1].split(',')
    return new_value


def is_valid_float(val):
    """ Checks if given value is float """
    if val and not isinstance(val, float) and not isinstance(val, int):
        return False
    return True


def _get_normal_name(orig_enc):
    """Imitates get_normal_name in tokenizer.c."""
    enc = orig_enc[:12].lower().replace('_', '-')
    if enc == 'utf-8' or enc.startswith('utf-8-'):
        return 'utf-8'
    if enc in ('latin-1', 'iso-8859-1', 'iso-latin-1') or enc.startswith((
        'latin-1-', 'iso-8859-1-', 'iso-latin-1-')):
        return 'iso-8859-1'
    return orig_enc


def perm_get_request_by_did(issuer, kwargs):
    """
    Checks if an account can get a request by DID.

    :param issuer: Account identifier which issues the command.
    :param kwargs: List of arguments for the action.
    :returns: True if account is allowed, otherwise False
    """
    return True


@classmethod
def _complexes_index(cls, complexes, index):
    """Map initial complex root index to an index in a factor where the root belongs."""
    index, i = index, 0
    for j, (_, factor, k) in enumerate(complexes):
        if index < i + k:
            poly, index = factor, 0
            for _, factor, _ in complexes[:j]:
                if factor == poly:
                    index += 1
            index += poly.count_roots()
            return poly, index
        else:
            i += k


def strip(value):
    """ Functor to return a whitespace stripped string.
    """
    return value.strip()


def _generate_stack_status_path(stack_path):
    """
    Given a path to the stack configuration template JSON file, generates a path to where the
    deployment status JSON will be stored after successful deployment of the stack.

    :param stack_path: Path to the stack config template JSON file
    :return: The path to the stack status file.

    >>> self._generate_stack_status_path('./stack.json')
    './stack.deployed.json'
    """
    stack_status_insert = 'deployed'
    stack_path_split = stack_path.split('.')
    stack_path_split.insert(-1, stack_status_insert)
    return '.'.join(stack_path_split)


def no_dec(num: float) ->str:
    """Format a floating point number with no decimal places."""
    return '{}'.format(round(num))


@staticmethod
def row_factory(row):
    """Process rows before they are returned.

        You can overwrite this statically with a custom row factory, or
        you can build a row factory dynamically with build_row_factory().

        For example, you can create a Cursor class that returns rows as
        Python dictionaries like this:

            class DictCursor(pgdb.Cursor):

                def row_factory(self, row):
                    return {desc[0]: value
                        for desc, value in zip(self.description, row)}

            cur = DictCursor(con)  # get one DictCursor instance or
            con.cursor_type = DictCursor  # always use DictCursor instances
        """
    raise NotImplementedError


def get_slack_user(user, slack_users):
    """Return user profile from Slack."""
    if hasattr(user, 'profile'):
        if user.profile.slack_api_id:
            for slack_user in slack_users:
                if slack_user['id'] == user.profile.slack_api_id:
                    return slack_user
        return None
    else:
        for slack_user in slack_users:
            if user.email and slack_user.get('profile', {}).get('email', None
                ) == user.email:
                return slack_user
        return None


@classmethod
def _split_module_object(cls, target_name):
    """
        split the target_name into module part
        and object part
        """
    path = target_name.split('.')
    target_module = cls._extract_module_from_name(target_name)
    target_module_path = target_module.__name__.split('.')
    assert len(path) >= len(target_module_path)
    i = 0
    for i, p in enumerate(target_module_path):
        if p != path[i]:
            break
    if p == path[i]:
        i = i + 1
    path = path[i:]
    return target_module, path


def get_familydata(lims_sample):
    """Parse out common (family-level) data."""
    data = {'customer': lims_sample.udf['customer'], 'family_id':
        lims_sample.udf['familyID'], 'case_id': '{}-{}'.format(lims_sample.
        udf['customer'], lims_sample.udf['familyID']), 'gene_panels':
        lims_sample.udf['Gene List'].split(';'), 'reference_genome':
        lims_sample.udf.get('Reference Genome', 'hg19')}
    return data


def store_true(arg, _, args, acc):
    """
    lambda that store a True boolean value on the parser result

    """
    acc[arg] = True
    return args, acc


def crown_capture_probability(n, k):
    """
    Calculate the probability that a sample of `k` taxa from a clade
    of `n` total taxa includes a root node, under a Yule process.

    This equation is taken from:

    Sanderson, M. J. 1996. How many taxa must be sampled to identify
    the root node of a large clade? Systematic Biology 45:168-173
    """
    if n < k:
        raise Exception('n must be greater than or equal to k (n={}, k={})'
            .format(n, k))
    if n == 1 and k == 1:
        return 0
    return 1 - 2 * (n - k) / ((n - 1) * (k + 1))


def ctx1(**kw):
    """swap to one-armed context"""


def drop_outliers(df, df_outliers):
    """Drops the detected outliers."""
    df_no_outliers = df.drop(df_outliers.index.values)
    return df_no_outliers


def ToolMatches(tools=None, version='HEAD'):
    """ Get the tools paths and versions that were specified """
    matches = []
    if tools:
        for tool in tools:
            match_version = version
            if tool[1] != '':
                match_version = tool[1]
            match = ''
            if tool[0].endswith('/'):
                match = tool[0][:-1]
            elif tool[0] != '.':
                match = tool[0]
            if not match.startswith('/') and match != '':
                match = '/' + match
            matches.append((match, match_version))
    return matches


def transform(tr, x, y):
    """Try transforming with X and y. Else, transform with only X."""
    try:
        x = tr.transform(x)
    except TypeError:
        x, y = tr.transform(x, y)
    return x, y


@classmethod
def all(cls, client):
    """
        Get all networks.

        :param client: client instance
        :type client: :class:`~pylxd.client.Client`
        :rtype: list[:class:`Network`]
        """
    response = client.api.networks.get()
    networks = []
    for url in response.json()['metadata']:
        name = url.split('/')[-1]
        networks.append(cls(client, name=name))
    return networks


def integer(message, err='Please enter an integer.'):
    """Command line input and error checking for integers.

    Args:
        message (str): The input message displayed in the command line.
        err (str, optional): The message displayed for an erroneous input.
            Defaults to "Please enter an integer.".

    Returns:
        int: The first sucessfully input integer.
    """
    while True:
        data = input(message)
        data = data.strip()
        if data == '':
            print('Please provide an input.')
            continue
        if '.' in data:
            print(err)
            continue
        try:
            data = int(data)
        except ValueError:
            print(err)
            continue
        return data


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


@staticmethod
def get_refindices(variable):
    """Reference to the associated instance of |Lnk|."""
    return variable.subvars.vars.model.parameters.control.lnk


def copyPoint(previousPoint, currentPoint):
    """Deep copies previous point."""
    previousPoint[0] = currentPoint[0]
    previousPoint[1] = currentPoint[1]


def k_wood(gb, so, x):
    """
    Thermal conductivity of wood based on moisture content, volumetric
    shrinkage, and basic specific gravity

    .. math:: k = G_x (B + C x) + A

    where :math:`k` is thermal conductivity [W/(mK)] of wood, :math:`G_x` is
    specific gravity [-] based on volume at moisture content :math:`x` [%] and
    :math:`A, B, C` are constants.

    The :math:`G_x` term is determined from

    .. math:: G_x = \\frac{G_b}{1 - S_x / 100}

    where :math:`G_b` is basic specific gravity [-] and :math:`S_x` is
    volumetric shrinkage [%] from green condition to moisture content :math:`x`.

    The :math:`S_x` term is calculated from

    .. math:: S_x = S_o \\left(1 - \\frac{x}{MC_{fs}} \\right)

    where :math:`S_o` is volumetric shrinkage [%] from Table 4-3 [1]_ and :math:`MC_{fs}`
    is the fiber saturation point assumed to be 30% moisture content.

    Parameters
    ----------
    gb : float
        Basic specific gravity [-]
    so : float
        Volumetric shrinkage [%]
    x : float
        Moisture content [%]

    Returns
    -------
    k : float
        Thermal conductivity [W/(mK)]

    Example
    -------
    >>> k_wood(0.54, 12.3, 10)
    0.1567

    References
    ----------
    .. [1] Samuel V. Glass and Samuel L. Zelinka. Moisture Relations and
       Physical Properties of Wood. Ch. 4 in Wood Handbook, pp. 1-19, 2010.
    """
    mcfs = 30
    sx = so * (1 - x / mcfs)
    gx = gb / (1 - sx / 100)
    a = 0.01864
    b = 0.1941
    c = 0.004064
    k = gx * (b + c * x) + a
    return k


@staticmethod
def modify_snapshot_prefix(snapshot_name, manage=False, unmanage=False):
    """Modify a Snapshot prefix on PowerMax/VMAX backend.

        Prepare a snapshot name for manage/unmanage snapshot process either
        by adding or removing 'OS-' prefix.

        :param snapshot_name: the old snapshot backend display name
        :param manage: (bool) if the operation is managing a snapshot
        :param unmanage: (bool) if the operation is unmanaging a snapshot
        :return: snapshot name ready for backend PowerMax/VMAX assignment
        """
    new_snap_name = None
    if manage:
        new_snap_name = '%(prefix)s%(snapshot_name)s' % {'prefix': 'OS-',
            'snapshot_name': snapshot_name}
    if unmanage:
        snap_split = snapshot_name.split('-', 1)
        if snap_split[0] == 'OS':
            new_snap_name = snap_split[1]
    return new_snap_name


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 convert_units(input, input_units, output_units):
    """
    Convert energy, frequency and wavelength units

    Description

        Using fundamental physical constants ==  there is a unique way of
        converting an energy into different units. For example ==  we often want
        to know the energy ==  wavelength or frequency of a photon. This
        function converts between these representations easily ==  threading
        over
        vectors automatically.

        This function uses the INDEX OF REFRACTION OF AIR as 1.000268746.
        To use a different index of refraction ==  modify the speed of light in
        the code.

        Frequency units are in cycles per second.

    Example:
        Convert 820 nm into 1.512 eV.

        > convertUnits(820, 'nm', 'eV')

    Available choices of units:

        'nm' (nanometers)
        'm' (meters)
        'eV' (electron Volts) ==
        'cm-1' (inverse centimeters)
        'Hz' (Hertz) ==  'KHz' ==  'MHz' ==  'GHz' ==  'THz' ==
        'K' (kelvin) ==  'J' (Joules)
        'kJ/mol'

    Todd Karin

    """
    e = 1.602176463e-19
    h = 6.62606957e-34
    c = 299792458 / 1.000268746
    kB = 1.3806503e-23
    Na = 6.0221409e+23
    inch2mm = 25.4
    if input_units == 'nm':
        energy = h * c / (input * 1e-09)
    elif input_units == 'mm':
        energy = h * c / (input * 0.001)
    elif input_units == 'm':
        energy = h * c / input
    elif input_units == 'eV':
        energy = input * e
    elif input_units == 'Hz':
        energy = h * input
    elif input_units == 'KHz':
        energy = h * input * 1000.0
    elif input_units == 'MHz':
        energy = h * input * 1000000.0
    elif input_units == 'GHz':
        energy = h * input * 1000000000.0
    elif input_units == 'THz':
        energy = h * input * 1000000000000.0
    elif input_units == 'cm-1':
        energy = h * c * input * 100
    elif input_units == 'J':
        energy = input
    elif input_units == 'K':
        energy = kB * input
    elif input_units == 'kJ/mol':
        energy = input * 1000 / Na
    else:
        Exception('Input units not recognized')
    if output_units == 'GHz':
        output = energy / h / 1000000000.0
    elif output_units == 'eV':
        output = energy / e
    elif output_units == 'Hz':
        output = energy / h
    elif output_units == 'KHz':
        output = energy / h / 1000.0
    elif output_units == 'MHz':
        output = energy / h / 1000000.0
    elif output_units == 'THz':
        output = energy / h / 1000000000000.0
    elif output_units == 'm':
        output = h * c / energy
    elif output_units == 'in':
        output = h * c / energy
    elif output_units == 'nm':
        output = h * c / energy * 1000000000.0
    elif output_units == 'cm-1':
        output = (h * c / energy * 100) ** -1
    elif output_units == 'K':
        output = energy / kB
    elif output_units == 'J':
        output = energy
    elif output_units == 'kJ/mol':
        output = energy / 1000 * Na
    else:
        Exception('Output units not recognized')
    return output


def image_mode(image):
    """
    Show mode of image is 'RGB' or 'RGBA'
    image: an Image object
    return: mode
    """
    mode = image.mode
    return mode


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


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

        :param WriteError val:
        :rtype: RelocationError
        """
    return cls('to', val)


def is_valid_py_file(path):
    """
    Checks whether the file can be read by the coverage module. This is especially
    needed for .pyx files and .py files with syntax errors.
    """
    import os
    is_valid = False
    if os.path.isfile(path) and not os.path.splitext(path)[1] == '.pyx':
        try:
            with open(path, 'rb') as f:
                compile(f.read(), path, 'exec')
                is_valid = True
        except:
            pass
    return is_valid


@classmethod
def can_use_order_function(cls, order_function):
    """Fail if the engine can't be used with an empty order parameter."""
    if order_function is None and cls.needs_order:
        raise ValueError(
            'No order parameter was defined, but the engine *does* require it.'
            )


@classmethod
def from_string(cls, sort_method):
    """Returns the sort method specified. sort_method is case insensitive.
        Will raise an AttributeError if the provided sort_method does not
        exist.

        >>> SortMethod.from_string('title')
        """
    return getattr(cls, sort_method.upper())


def constraints_clear():
    """Clear all the constraints for the selected bones

    """
    pass


def _get_instances(cls, path, context=None, site=None, language=None):
    """ A sequence of instances to discover metadata.
            Each instance from each backend is looked up when possible/necessary.
            This is a generator to eliminate unnecessary queries.
        """
    backend_context = {'view_context': context}
    for model in cls._meta.models.values():
        for instance in (model.objects.get_instances(path, site, language,
            backend_context) or []):
            if hasattr(instance, '_process_context'):
                instance._process_context(backend_context)
            yield instance


@classmethod
def is_readable(cls):
    """
        Check if this instrument is able to read any properties
        """
    return not callable(getattr(cls, 'set_value', None)) or len(cls.
        get_readable_properties()) > 0


def get_id(function):
    """Given a function, calculate its identifier.

    A identifier is a string in the format ``<module name>:<function name>``,
    similarly to the convention used for setuptools entry points.

    Note:
        This function does not return a Python 3 ``__qualname__`` equivalent.
        If the function is nested inside another function or class, the parent
        name is ignored.

    Args:
        function (callable): function object

    Returns:
        str: identifier
    """
    return '{}:{}'.format(function.__module__, function.__name__)


def sn(ok):
    """converts boolean value to +1 or -1
  """
    if ok:
        return 1
    else:
        return -1


def ma(f, c, p=20):
    """Calculate the mean on a rolling basis.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the column ``c``.
    c : str
        Name of the column in the dataframe ``f``.
    p : int
        The period over which to calculate the rolling mean.

    Returns
    -------
    new_column : pandas.Series (float)
        The array containing the new feature.

    References
    ----------
    *In statistics, a moving average (rolling average or running average)
    is a calculation to analyze data points by creating series of averages
    of different subsets of the full data set* [WIKI_MA]_.

    .. [WIKI_MA] https://en.wikipedia.org/wiki/Moving_average

    """
    new_column = f[c].rolling(p).mean()
    return new_column


@classmethod
def forget(cls, db):
    """Forget cache for database."""
    cls._cache.pop(db, None)


def get_hook(cls, unique_id):
    """
        Fetch a registered hook instance by its unique_id
        """
    if not cls.abstract:
        raise TypeError('get_hook method used on a non-abstract hook')
    return cls._registered_hooks.get(unique_id, None)


def get_student_users_in_group(group):
    """
    Fetches all Student-users in group.

    Args:
        group: ``AssignmentGroup``.

    Returns:
        QuerySet: QuerySet of ``User``-objects.
    """
    from django.contrib.auth import get_user_model
    user_queryset = get_user_model().objects.filter(id__in=group.candidates
        .values_list('relatedstudent__user', flat=True))
    return user_queryset


@classmethod
def apply_filter_prefix(cls, queryset, options, value):
    """Apply `prefix` filter.

        Syntax:

            /endpoint/?field_name__prefix={value}

        Example:

            http://localhost:8000/api/articles/?tags__prefix=bio

        :param queryset: Original queryset.
        :param options: Filter options.
        :param value: value to filter on.
        :type queryset: elasticsearch_dsl.search.Search
        :type options: dict
        :type value: str
        :return: Modified queryset.
        :rtype: elasticsearch_dsl.search.Search
        """
    return cls.apply_filter(queryset=queryset, options=options, args=[
        'prefix'], kwargs={options['field']: value})


@classmethod
def get_choice(cls, value):
    """
        Return the underlying :class:`ChoiceItem` for a given value.
        """
    attribute_for_value = cls.attributes[value]
    return cls._fields[attribute_for_value]


def _is_float(float_value):
    """
    Check if a number is actually a float

    :type float_value: int or float
    :param float_value: number to check
    :return True if it is not an integer number
    """
    if int(float_value) != float_value:
        return True


def _is_neighbor(index, props, neighborhood):
    """
    Check if index is already in the neighborhood with props
    """
    for neighbors in neighborhood:
        for n in neighbors:
            if index == neighbors[n].i:
                for p in props:
                    if p in neighbors[n].props:
                        return True
    return False


def return_fq_name(func, klass=None):
    """
    Resolve a fully qualified name for a function
    or method
    """
    func_name = getattr(func, 'func_name', None)
    func_module = getattr(func, '__module__', None)
    if klass:
        name = '%s.%s.%s' % (klass.__module__, klass.__name__, 'PyCallable')
    elif func_name:
        name = '%s.%s' % (func_module, func_name)
    else:
        name = str(func)
        if name.startswith('<') and name.endswith('>'):
            name = name[1:-1]
    return name


def get_a_receiver(base, receiver_id):
    """Utility function that gets a Senlin receiver."""
    res = base.client.get_obj('receivers', receiver_id)
    return res['body']


def is_task_ready(task):
    """Workaround broken ready() for failed Celery results.

    In case the task ends with an exception, the result tries to reconstruct
    that. It can fail in case the exception can not be reconstructed using
    data in args attribute.

    See https://github.com/celery/celery/issues/5057
    """
    try:
        return task.ready()
    except TypeError:
        return True


def i_or_args(result, results):
    """Return an iterable for functions with signature f(arg, *args).
    f can be called with f([a, b, c, ...]) or f(a, b, c, ...).
    In both cases, calling i_or_args(arg, args) returns an iterable
    over a, b, c, ...
    """
    if len(results) == 0:
        return iter(result)
    return (result,) + results


def has_extension(fp, ext, pos=-1, raise_exception=False, **kwargs):
    """
    Test presence of extension in a file path
    * ext
        Single extension name or list of extension names  without dot. Example ["gz, "fa"]
    * pos
        Postition of the extension in the file path. -1 for the last, -2 for the penultimate and so on [DEFAULT -1 = Last position]
    """
    if type(ext) == str:
        ext = [ext]
    if not fp.split('.')[pos].lower() in ext:
        if raise_exception:
            raise ValueError(
                'Invalid extension for file {}. Valid extensions: {}'.
                format(fp, '/'.join(ext)))
        else:
            return False
    else:
        return True


def get_model_name(model_class):
    """Example: ModelName"""
    return model_class.__name__


@classmethod
def parse(cls, name, data_size, reader, parsers):
    """given a 4 byte name, data_size int, BitstreamReader
        and dict of {"atom":handler} sub-parsers,
        returns an atom of this class"""
    assert name == b'data'
    type, flags = reader.parse('8u 24u 32p')
    return cls(type, flags, reader.read_bytes(data_size - 8))


def uniq(trains):
    """Returns only uniq trains."""
    seen = set()
    result = []
    for train in trains:
        if train.train_link not in seen:
            seen.add(train.train_link)
            result.append(train)
    return result


@classmethod
def fromkeys(cls, iterable, value='', mutable=False, encoding=None):
    """
        Return a new QueryDict with keys (may be repeated) from an iterable and
        values from value.
        """
    q = cls('', mutable=True, encoding=encoding)
    for key in iterable:
        q.appendlist(key, value)
    if not mutable:
        q._mutable = False
    return q


@staticmethod
def srow_to_list(row_num, s):
    """Convert a sheet row to a list"""
    values = []
    try:
        for col in range(s.ncols):
            values.append(s.cell(row_num, col).value)
    except:
        raise
    return values


def canonical_format_name(format):
    """Convert format name "format" to a consistent version."""
    format = format.lower()
    if format in ['jpg', 'jpeg']:
        return 'jpeg'
    elif format in ['tiff', 'tif']:
        return 'tiff'
    else:
        return format


def mergeRecordExtra(record, target, reserved):
    """ Merges extra attributes from LogRecord object into target dictionary

    Args:
        record (logging.LogRecord): logging.LogRecord
        target (dict): dict to update
        reserved (dict or list): reserved keys to skip

    Returns:
        dict: target dict
    """
    for key, value in record.__dict__.items():
        if key not in reserved and not (hasattr(key, 'startswith') and key.
            startswith('_')):
            target[key] = value
    return target


@staticmethod
def match_list(column, patterns):
    """Test if a column matches any of the patterns in a list.
        @param column: the column to test
        @param patterns: a list of zero or more patterns.
        @returns: True if there is a match
        """
    for pattern in patterns:
        if pattern.match(column):
            return True
    return False


def write_objs_as_uri(output_obj, subject, predicate, raw_value):
    """Write object(s) for the column as a URI"""
    output_obj.write(u'<{}> <{}> <{}> .\n'.format(subject, predicate,
        raw_value).encode('utf-8'))


@classmethod
def escape_json_value(cls, json_value_IN, do_double_escape_quotes_IN=False,
    compact_white_space_IN=False):
    """
        Accepts a JSON value, adds a back slash in front of all quotation marks
           within the value.  Returns the escaped string.  Will add more things
           as I find them.
        """
    value_OUT = None
    if json_value_IN is not None and json_value_IN != '':
        value_OUT = json_value_IN
        if do_double_escape_quotes_IN == True:
            value_OUT = cls.REGEX_MATCH_UNESCAPED_QUOTES.sub('\\"', value_OUT)
            value_OUT = value_OUT.replace('\\"', '\\\\\\"')
        else:
            value_OUT = value_OUT.replace('"', '\\"')
        if '\n' in value_OUT:
            value_OUT = value_OUT.replace('\n', cls.REPLACE_NEWLINE_WITH)
        if compact_white_space_IN == True:
            value_OUT = cls.REGEX_MATCH_MULTIPLE_WHITE_SPACE.sub(' ', value_OUT
                )
    else:
        value_OUT = ''
    return value_OUT


def should_build_with_cython(package, release=None):
    """Returns the previously used Cython version (or 'unknown' if not
    previously built) if Cython should be used to build extension modules from
    pyx files.  If the ``release`` parameter is not specified an attempt is
    made to determine the release flag from `astropy.version`.
    """
    try:
        version_module = __import__(package + '.cython_version', fromlist=[
            'release', 'cython_version'])
    except ImportError:
        version_module = None
    if release is None and version_module is not None:
        try:
            release = version_module.release
        except AttributeError:
            pass
    try:
        cython_version = version_module.cython_version
    except AttributeError:
        cython_version = 'unknown'
    have_cython = False
    try:
        import Cython
        have_cython = True
    except ImportError:
        pass
    if have_cython and (not release or cython_version == 'unknown'):
        return cython_version
    else:
        return False


def surface_slot_add():
    """Add a new Dynamic Paint surface slot

    """
    pass


def resource_exists(resource):
    """Check whether the given `resource` exists physically.

        :rtype: bool

        Attempting to retrieve the model object for a non-existing
        resource should raise a `ResourceNotFound` exception.
        (''since 0.11.8'')
        """


@classmethod
def check_token(cls, db, token):
    """Check if a token is acceptable"""
    if len(token) < cls.min_length:
        raise ValueError('Tokens must be at least %i characters, got %r' %
            (cls.min_length, token))
    found = cls.find(db, token)
    if found:
        raise ValueError('Collision on token: %s...' % token[:cls.
            prefix_length])


def require(cond: bool, exception=AssertionError, msg: str=None):
    """
    Deliberately defined assert function which will never be omitted by python interpreter and
    raise custom type exception
    :param cond: bool
    :param exception: Exception type which will be raised
    :param msg: str
    :return:
    """
    if not cond:
        raise exception(msg)


def current_version(module_path):
    """Return the current application version label"""
    with open(module_path) as f1:
        f2 = f1.read()
    return f2.split('=')[1].strip()[1:-1]


def _parse_content_type_header(header):
    """Returns content type and parameters from given header

    :param header: string
    :return: tuple containing content type and dictionary of
         parameters
    """
    tokens = header.split(';')
    content_type, params = tokens[0].strip(), tokens[1:]
    params_dict = {}
    items_to_strip = '"\' '
    for param in params:
        param = param.strip()
        if param:
            key, value = param, True
            index_of_equals = param.find('=')
            if index_of_equals != -1:
                key = param[:index_of_equals].strip(items_to_strip)
                value = param[index_of_equals + 1:].strip(items_to_strip)
            params_dict[key.lower()] = value
    return content_type, params_dict


def get_labels_order_2ab(l, a, b):
    """Get all combinations ij, where i,j are feature labels.

    Parameters
    ----------
    x : list
        Length m vector, where m is the number of features.

    Returns
    -------
    new_features : list
        List of new feature names.
    """
    L = len(l)
    new_features = []
    for f1 in range(L):
        for f2 in range(f1, L):
            new_features.append(l[f1] + '_' + str(a) + '_x_' + l[f2] + '_' +
                str(b))
    return new_features


def nlg_response_format_spec():
    """Expected response schema for an NLG endpoint.

    Used for validation of the response returned from the NLG endpoint."""
    return {'type': 'object', 'properties': {'text': {'type': 'string'},
        'buttons': {'type': ['array', 'null'], 'items': {'type': 'object'}},
        'elements': {'type': ['array', 'null'], 'items': {'type': 'object'}
        }, 'attachment': {'type': ['object', 'null']}, 'image': {'type': [
        'string', 'null']}}}


def get_rule(RuleId=None):
    """
    Returns the  Rule that is specified by the RuleId that you included in the GetRule request.
    See also: AWS API Documentation

    Examples
    The following example returns the details of a rule with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.
    Expected Output:

    :example: response = client.get_rule(
        RuleId='string'
    )

    :type RuleId: string
    :param RuleId: [REQUIRED]
            The RuleId of the Rule that you want to get. RuleId is returned by CreateRule and by ListRules .

    :rtype: dict
    :return: {
        'Rule': {
            'RuleId': 'string',
            'Name': 'string',
            'MetricName': 'string',
            'Predicates': [
                {
                    'Negated': True|False,
                    'Type': 'IPMatch'|'ByteMatch'|'SqlInjectionMatch'|'SizeConstraint'|'XssMatch',
                    'DataId': 'string'
                },
            ]
        }
    }

    """
    pass


def cut():
    """Cut selected text to clipboard

    """
    pass


def nth_combination(iterable, r, index):
    """Equivalent to ``list(combinations(iterable, r))[index]``.

    The subsequences of *iterable* that are of length *r* can be ordered
    lexicographically. :func:`nth_combination` computes the subsequence at
    sort position *index* directly, without computing the previous
    subsequences.

    """
    pool = tuple(iterable)
    n = len(pool)
    if r < 0 or r > n:
        raise ValueError
    c = 1
    k = min(r, n - r)
    for i in range(1, k + 1):
        c = c * (n - k + i) // i
    if index < 0:
        index += c
    if index < 0 or index >= c:
        raise IndexError
    result = []
    while r:
        c, n, r = c * r // n, n - 1, r - 1
        while index >= c:
            index -= c
            c, n = c * (n - r) // n, n - 1
        result.append(pool[-1 - n])
    return tuple(result)


def etype_name(element):
    """Return entity type for the given XSD `element`."""
    if element.local_name == 'uri':
        return 'SEDAUri'
    return 'SEDA' + element.local_name


def getLinks(i, translated_strings):
    """Generate hyperlinks for the archive page.

    Takes a Strip object and links it according to the archive link
    format for the current language from strings.json.

    Parameters
    ----------
    i : Strip
        The Strip whose link is to be formatted.
    translated_strings: dict
        The translation file contents for this site.
    Returns
    -------
    archive_link : str
        The formatted link to the page.
    """
    archive_l = translated_strings['archive_l_s'].format(title=i.title,
        page=i.page)
    link_format = '
{archive_l}
'
    archive_link = link_format.format(html_filename=i.html_filename,
        archive_l=archive_l)
    return archive_link


def version_tnf(t1, t2=None):
    """
    return True if ruamel.yaml version_info < t1, None if t2 is specified and bigger else False
    """
    from ruamel.yaml import version_info
    if version_info < t1:
        return True
    if t2 is not None and version_info < t2:
        return None
    return False


def inherit_doc(cls):
    """
    A decorator that makes a class inherit documentation from its parents.
    """
    for name, func in vars(cls).items():
        if name.startswith('_'):
            continue
        if not func.__doc__:
            for parent in cls.__bases__:
                parent_func = getattr(parent, name, None)
                if parent_func and getattr(parent_func, '__doc__', None):
                    func.__doc__ = parent_func.__doc__
                    break
    return cls


def segment_range_to_fragment_range(segment_start, segment_end,
    segment_size, fragment_size):
    """
    Takes a byterange spanning some segments and converts that into a
    byterange spanning the corresponding fragments within their fragment
    archives.

    Handles prefix, suffix, and fully-specified byte ranges.

    :param segment_start: first byte of the first segment
    :param segment_end: last byte of the last segment
    :param segment_size: size of an EC segment, in bytes
    :param fragment_size: size of an EC fragment, in bytes

    :returns: a 2-tuple (frag_start, frag_end) where

      * frag_start is the first byte of the first fragment, or None if this
        is a suffix byte range

      * frag_end is the last byte of the last fragment, or None if this is a
        prefix byte range
    """
    fragment_start = (segment_start // segment_size * fragment_size if
        segment_start is not None else None)
    fragment_end = None if segment_end is None else (segment_end + 1
        ) // segment_size * fragment_size if segment_start is None else (
        segment_end + 1) // segment_size * fragment_size - 1
    return fragment_start, fragment_end


def nfa_word_acceptance(nfa: dict, word: list) ->bool:
    """ Checks if a given word is accepted by a NFA.

    The word w is accepted by a NFA if exists at least an
    accepting run on w.

    :param dict nfa: input NFA;
    :param list word: list of symbols ∈ nfa['alphabet'];
    :return: *(bool)*, True if the word is accepted, False otherwise.
    """
    current_level = set()
    current_level = current_level.union(nfa['initial_states'])
    next_level = set()
    for action in word:
        for state in current_level:
            if (state, action) in nfa['transitions']:
                next_level.update(nfa['transitions'][state, action])
        if len(next_level) < 1:
            return False
        current_level = next_level
        next_level = set()
    if current_level.intersection(nfa['accepting_states']):
        return True
    else:
        return False


def bitmask_get(bm, mn, f):
    """
     returns True if flag f in bitmask bm is set in magic number mn
     throws KeyError if f is not defined in bitmask
     :param bm: bitmask
     :param mn: magic number
     :param f: flag to retrieve
     :returns: defined names
    """
    return int(bm[f] & mn == bm[f])


def decorate_message(event, message, charset):
    """Manipulate the message before it is sent on it's way.

        :param event: a `NotificationEvent`
        :param message: an `email.message.Message` to manipulate
        :param charset: the `email.charset.Charset` to use
        """


def safe_issubclass(*args):
    """Like issubclass, but will just return False if not a class."""
    try:
        if issubclass(*args):
            return True
    except TypeError:
        pass
    return False


@staticmethod
def __normalize_int(value, default=0):
    """
        Normalizes an integer value
        """
    try:
        return int(value)
    except (ValueError, TypeError):
        return default


def find_sublist_index(ls, sub_ls):
    """Find the index at which the sublist sub_ls can be found in ls.

    @type ls: list
    @type sub_ls: list

    @return: index of the matching location or None if no match can be made.
    """
    sub_length = len(sub_ls)
    for i in range(len(ls)):
        if ls[i:i + sub_length] == sub_ls:
            return i
    return None


def display(obj, detail='phrase'):
    """ Friendly string for volume, using sink paths. """
    try:
        return obj.display(detail=detail)
    except AttributeError:
        return str(obj)


def is_iterable(obj):
    """
    Are we being asked to look up a list of things, instead of a single thing?
    We check for the `__iter__` attribute so that this can cover types that
    don't have to be known by this module, such as NumPy arrays.

    Strings, however, should be considered as atomic values to look up, not
    iterables. The same goes for tuples, since they are immutable and therefore
    valid entries.

    We don't need to check for the Python 2 `unicode` type, because it doesn't
    have an `__iter__` attribute anyway.
    """
    return hasattr(obj, '__iter__') and not isinstance(obj, str
        ) and not isinstance(obj, tuple)


@staticmethod
def __combine_remote(remote, branch):
    """
        Combine remote and branch together as necessary.
        :param remote: Optional remote
        :param branch: The branch to use
        :return: If remote is not empty a combined remote/branch string, otherwise just branch.
        """
    if not remote:
        return branch
    return '/'.join([remote, branch])


def new_instance():
    """
        Return an instance for use by another RelStorage instance.

        Adapters that are stateless can simply return self. Adapters
        that have mutable state must make a clone and return it.
        """


@staticmethod
def is_app_linked(source, pkg, java_package):
    """ Returns true if the compile project line exists exists in the file

        """
    for line in source.split('\n'):
        if java_package in line:
            return True
    return False


@staticmethod
def get_label_summary(provider):
    """
        UILabel summary.

        :param UILabel.UILabelSyntheticProvider provider: UILabel provider.
        :return: UILabel summary.
        :rtype: str
        """
    return 'text={}'.format(provider.text_value)


@staticmethod
def _set_raw(target, raw_value, bitarray):
    """ put value into bit array """
    offset = int(target['offset'])
    size = int(target['size'])
    for digit in range(size):
        bitarray[offset + digit] = raw_value >> size - digit - 1 & 1 != 0
    return bitarray


def formula_2013_01_01(foyer_fiscal, period, parameters):
    """
        Attention : Pour les années avant 2013, cette formule n'est pas entièrement correcte car le taux de la CSG n'était pas unique (distinction revenus du patrimoine et revenus de placement)
        """
    assiette_csg_revenus_capital = foyer_fiscal('assiette_csg_revenus_capital',
        period)
    P = parameters(period).taxation_capital.prelevements_sociaux
    total = (P.prelevement_social.revenus_du_patrimoine + P.caps.
        revenus_du_patrimoine + P.prelevements_solidarite.revenus_du_patrimoine
        )
    return -assiette_csg_revenus_capital * total


@classmethod
def from_name(cls, name, frame='icrs', parse=False):
    """
        Given a name, query the CDS name resolver to attempt to retrieve
        coordinate information for that object. The search database, sesame
        url, and  query timeout can be set through configuration items in
        ``astropy.coordinates.name_resolve`` -- see docstring for
        `~astropy.coordinates.get_icrs_coordinates` for more
        information.

        Parameters
        ----------
        name : str
            The name of the object to get coordinates for, e.g. ``'M42'``.
        frame : str or `BaseCoordinateFrame` class or instance
            The frame to transform the object to.
        parse: bool
            Whether to attempt extracting the coordinates from the name by
            parsing with a regex. For objects catalog names that have
            J-coordinates embedded in their names eg:
            'CRTS SSS100805 J194428-420209', this may be much faster than a
            sesame query for the same object name. The coordinates extracted
            in this way may differ from the database coordinates by a few
            deci-arcseconds, so only use this option if you do not need
            sub-arcsecond accuracy for coordinates.

        Returns
        -------
        coord : SkyCoord
            Instance of the SkyCoord class.
        """
    from .name_resolve import get_icrs_coordinates
    icrs_coord = get_icrs_coordinates(name, parse)
    icrs_sky_coord = cls(icrs_coord)
    if frame in ('icrs', icrs_coord.__class__):
        return icrs_sky_coord
    else:
        return icrs_sky_coord.transform_to(frame)


def plot_fleur_relax_wc(node, labels=None):
    """
    This methods takes an AiiDA output parameter node from a relaxation
    workchain and plots some information about atom movements and forces
    """
    if labels is None:
        labels = []
    pass


def convert_to_air(lam):
    """This function converts the vacuum wavelength of spectral lines to
       the air wavelength. The wavelength is the difference in energy
       levels of the upper and lower transition. By defualt in the adf04
       file these energy correspond to the vacuum wavelengths to this
       must be converted at some point for UV and visible light.

    :param lam: The wavelengths in nm in vacuum
    :type lam: array

    :returns: array --wavelengths in nm in air

    """
    s = 10 ** 3 / lam
    return 1 + 8.34254e-05 + 0.02406147 / (130 - s ** 2) + 0.00015998 / (
        38.9 - s ** 2)


def worker_id():
    """Returns current worker ID. 0 if not a worker (e.g. mule).

    :rtype: int
    """
    return 0


def add_on_store_opened(f):
    """
        Add a callable(cursor, restart=bool) for when a store connection
        is opened.

        .. versionadded:: 2.1a1
        """


def authenticate():
    """
        Confirm the user's identity using the available security factors

        @returns a truthy user object, or None
        """


def convert_dict(prop_idents) ->dict:
    """
    Transfet the dict generated by sparql.py, store them in the format of:
    {
      "123" : [ "P345/Q123", "P789/Q234" ],
     "453" : [ "P789/Q43", "P256/Q456", "P31/Q567" ],
      ...
    }
    :param prop_idents:
    :return:
    """
    identifier_nodes_dict = {}
    count = 0
    keys = set()
    for P_number, p_entity in prop_idents.items():
        count += 1
        print(P_number, count)
        for identi, Q_number in p_entity.items():
            if identi in keys:
                identifier_nodes_dict[identi].append(P_number + '/' + Q_number)
            else:
                keys.add(identi)
                identifier_nodes_dict[identi] = [P_number + '/' + Q_number]
    return identifier_nodes_dict


def fmt_class(text: str, cls: str) ->str:
    """Format a string in a certain class (`<span>`).

    Args:
      text: The text to format.
      cls: The name of the class.

    Returns:
        A `<span>` with a class added.
    """
    return f'{text}'


@classmethod
def get(cls, id):
    """Get registry by id."""
    for r in cls.list():
        if r.id == id:
            return r


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

        :param bool val:
        :rtype: HasTeamFileEventsValue
        """
    return cls('enabled', val)


def topics():
    """ Return all topics (list)
        """


def _abi3_applies(python_version):
    """
    Determine if the Python version supports abi3.

    PEP 384 was first implemented in Python 3.2.
    """
    return len(python_version) > 1 and tuple(python_version) >= (3, 2)


def get_parent_window(widget):
    """
    Reliably determine parent window of a widget.

    Just using :meth:`Gtk.Widget.get_toplevel` would return the widget itself
    if it had no parent window.

    On the other hand using :meth:`Gtk.Widget.get_ancestor` would return only
    the closest :class:`Gtk.Window` in the hierarchy.

    https://developer.gnome.org/gtk3/unstable/GtkWidget.html#gtk-widget-get-toplevel
    """
    toplevel = widget.get_toplevel()
    if not toplevel.is_toplevel():
        toplevel = None
    return toplevel


def concat(*data, **kwargs):
    """Joins input arrays along a given axis.

    .. note:: `Concat` is deprecated. Use `concat` instead.

    The dimensions of the input arrays should be the same except the axis along
    which they will be concatenated.
    The dimension of the output array along the concatenated axis will be equal
    to the sum of the corresponding dimensions of the input arrays.

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

    - concat(csr, csr, ..., csr, dim=0) = csr
    - otherwise, ``concat`` generates output with default storage

    Example::

       x = [[1,1],[2,2]]
       y = [[3,3],[4,4],[5,5]]
       z = [[6,6], [7,7],[8,8]]

       concat(x,y,z,dim=0) = [[ 1.,  1.],
                              [ 2.,  2.],
                              [ 3.,  3.],
                              [ 4.,  4.],
                              [ 5.,  5.],
                              [ 6.,  6.],
                              [ 7.,  7.],
                              [ 8.,  8.]]

       Note that you cannot concat x,y,z along dimension 1 since dimension
       0 is not the same for all the input arrays.

       concat(y,z,dim=1) = [[ 3.,  3.,  6.,  6.],
                             [ 4.,  4.,  7.,  7.],
                             [ 5.,  5.,  8.,  8.]]

    Defined in src/operator/nn/concat.cc:L383

    Parameters
    ----------
    data : NDArray[]
        List of arrays to concatenate
    dim : int, optional, default='1'
        the dimension to be concated.

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

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


@classmethod
def expand_code(cls, short_code):
    """
        Returns the numeric ID for a shortcode

        :param short_code:
        :return:
        """
    return cls._decode(short_code)


def new():
    """Add new palette

    """
    pass


@classmethod
def registerAddonModule(cls, module):
    """
        Registers a module to use to import addon subclasses from.

        :param      module | <str> || <module>
        """
    prop = '_{0}__addon_modules'.format(cls.__name__)
    mods = getattr(cls, prop, set())
    mods.add(module)
    setattr(cls, prop, mods)


def should_tag_by_object_type(args, object_):
    """Returns True if object matches object type requirements"""
    valid = True
    if args.tag_folders_only and not object_.is_folder:
        valid = False
    if args.tag_files_only and not object_.is_file:
        valid = False
    if args.tag_datasets_only and not object_.is_dataset:
        valid = False
    if not valid:
        print('{}WARNING: Excluding {} {} by object_type'.format(
            '[Dry Run] ' if args.dry_run else '', object_.object_type,
            object_.full_path))
    return valid


@classmethod
def add_hook(cls, hook_type, hook_func):
    """Add a new hook of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param hook_func: hook function
        """
    if hook_type not in cls._hooks_map:
        cls._hooks_map[hook_type] = []
    cls._hooks_map[hook_type].append(hook_func)


@staticmethod
def __multi_tmp_dir(object_name, upload_id):
    """
        format: object_name.multi-uuid

        :param str object_name: file path
        :param str upload_id: multipart upload id
        :rtype: str
        """
    return '.'.join([object_name, upload_id])


def get_fasttext_train_calls(train_file_path, param_dict, fasttext_path,
    model_path, thread=1, pretrained_vectors_path=None):
    """
    Generates fastText command-line calls for training a supervised model and for compressing the output model.

    :param train_file_path: path to the training dataset
    :param param_dict: dictionary mapping fasttext hyperparameters to their values
    :param fasttext_path: path to the fastText executable
    :param model_path: str, path to output model
    :param thread: int, the number of threads to use
    :param pretrained_vectors_path: str, path to pre-trained `.vec` file with word embeddings
    :return tuple of str - fastText calls for training and quantizing
    """
    train_args = []
    for arg in sorted(param_dict.keys()):
        val = param_dict[arg]
        train_args += [arg, str(val)]
    train_call = [fasttext_path, 'supervised', '-input', train_file_path,
        '-output', model_path]
    train_call += train_args
    train_call += ['-thread', str(thread)]
    if pretrained_vectors_path is not None:
        train_call += ['-pretrainedVectors', pretrained_vectors_path]
    compress_call = [fasttext_path, 'quantize', '-input', model_path,
        '-output', model_path]
    return train_call, compress_call


def calc_commission_tc(trade_cnt, price):
    """
    币类计算交易费用：只简单计算手续费，双向都使用流通币计算手续费，不涉及卖出使用币类的手续计算，
    如需要更精确计算，请使用自定义计算费率，即在AbuCommission初始化中自定义计算手续费的方法
    :param trade_cnt: 交易的币个数（int）
    :param price: 每币的价格（人民币）
    :return: 计算结果手续费
    """
    cost = trade_cnt * price
    commission = cost * 0.002
    return commission


def extension_sort_key(extension):
    """Returns the sorting key for an extension.

    The sorting key can be used to sort a list of extensions
    into the order that is used in the Khronos C OpenGL headers.
    :param Extension extension: Extension to produce sort key for
    :returns: A sorting key
    """
    name = extension.name
    category = name.split('_', 2)[1]
    return (0, name) if category in ('ARB', 'KHR', 'OES') else (1, name)


def model_requires_scaling(model):
    """
    Given a :py:class:`anticipy.forecast_models.ForecastModel`
        return True if the function requires scaling a_x

    :param model: A get_model_<modeltype> function from
        :py:mod:`anticipy.model.periodic_models` or
        :py:mod:`anticipy.model.aperiodic_models`
    :type model: function
    :return: True if function is logistic or sigmoidal
    :rtype: bool
    """
    requires_scaling = model is not None and model.name in ['logistic',
        'sigmoid']
    return requires_scaling


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


def change_utility(ufuncs, curr_state, state):
    """compute the utility for a state change"""
    utility = 0
    for attr, value in state.items():
        if attr in ufuncs:
            new_state_utility = ufuncs[attr](value)
            current_state_utility = ufuncs[attr](curr_state[attr])
            utility += new_state_utility - current_state_utility
    return utility


def uninstall(context):
    """Uninstall script"""


def build_train_and_test_features(df_columns, features_to_process,
    predict_feature, ignore_features):
    """build_train_and_test_features

    Order matters when slicing up datasets using scalers...

    if not, then something that is an int/bool can get into a float
    column and that is really bad for making predictions
    with new or pre-trained models...

    :param df_columns: columns in the dataframe
    :param features_to_process: requested features to train
    :param predict_feature: requested feature to predict
    :param ignore_features: requested non-numeric/not-wanted features
    """
    train_and_test_features = []
    for c in df_columns:
        if c == predict_feature:
            train_and_test_features.append(c)
        else:
            add_feature = True
            for i in ignore_features:
                if i == c:
                    add_feature = False
                    break
            if add_feature:
                for f in features_to_process:
                    if f == c:
                        train_and_test_features.append(c)
                        break
    return train_and_test_features


def jpxDecode(stream):
    """
        Method to decode streams using the JPEG2000 standard (NOT IMPLEMENTED YET)

        @param stream: A PDF stream
        @return: A tuple (status,statusContent), where statusContent is the decoded PDF stream in case status = 0 or an error in case status = -1
    """
    return -1, 'JpxDecode not supported yet'


@classmethod
def from_comp(cls, xx=1, xy=0, xz=0, yx=0, yy=1, yz=0, zx=0, zy=0, zz=1):
    """Return ``DefGrad`` tensor defined by individual components. Default is identity tensor.

        Keyword Args:
          xx, xy, xz, yx, yy, yz, zx, zy, zz (float): tensor components

        Example:
          >>> F = DefGrad.from_comp(xy=1, zy=-0.5)
          >>> F
          DefGrad:
          [[ 1.   1.   0. ]
           [ 0.   1.   0. ]
           [ 0.  -0.5  1. ]]

        """
    return cls([[xx, xy, xz], [yx, yy, yz], [zx, zy, zz]])


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

        :param ShowcasePostCommentDetails val:
        :rtype: EventDetails
        """
    return cls('showcase_post_comment_details', val)


@classmethod
def where(cls, *args):
    """Retrieve a model instance by where"""
    return cls.builder().where(*args)


def helical_turbulent_fd_Mori_Nakayama(Re, Di, Dc):
    """Calculates Darcy friction factor for a fluid flowing inside a curved
    pipe such as a helical coil under turbulent conditions, using the method of
    Mori and Nakayama [1]_, also shown in [2]_ and [3]_.

    .. math::
        f_{curv} = 0.3\\left(\\frac{D_i}{D_c}\\right)^{0.5}
        \\left[Re\\left(\\frac{D_i}{D_c}\\right)^2\\right]^{-0.2}\\left[1
        + 0.112\\left[Re\\left(\\frac{D_i}{D_c}\\right)^2\\right]^{-0.2}\\right]

    Parameters
    ----------
    Re : float
        Reynolds number with `D=Di`, [-]
    Di : float
        Inner diameter of the coil, [m]
    Dc : float
        Diameter of the helix/coil measured from the center of the tube on one
        side to the center of the tube on the other side, [m]

    Returns
    -------
    fd : float
        Darcy friction factor for a curved pipe [-]

    Notes
    -----
    Valid from the transition to turbulent flow up to
    :math:`Re=6.5\\times 10^{5}\\sqrt{D_i/D_c}`. Does not use a straight pipe
    correlation, and so will not converge on the
    straight pipe result at very low curvature.

    Examples
    --------
    >>> helical_turbulent_fd_Mori_Nakayama(1E4, 0.01, .2)
    0.037311802071379796

    References
    ----------
    .. [1] Mori, Yasuo, and Wataru Nakayama. "Study of Forced Convective Heat
       Transfer in Curved Pipes (2nd Report, Turbulent Region)." International
       Journal of Heat and Mass Transfer 10, no. 1 (January 1, 1967): 37-59.
       doi:10.1016/0017-9310(67)90182-2.
    .. [2] El-Genk, Mohamed S., and Timothy M. Schriener. "A Review and
       Correlations for Convection Heat Transfer and Pressure Losses in
       Toroidal and Helically Coiled Tubes." Heat Transfer Engineering 0, no. 0
       (June 7, 2016): 1-28. doi:10.1080/01457632.2016.1194693.
    .. [3] Ali, Shaukat. "Pressure Drop Correlations for Flow through Regular
       Helical Coil Tubes." Fluid Dynamics Research 28, no. 4 (April 2001):
       295-310. doi:10.1016/S0169-5983(00)00034-4.
    """
    term = (Re * (Di / Dc) ** 2) ** -0.2
    return 0.3 * (Dc / Di) ** -0.5 * term * (1.0 + 0.112 * term)


def _test():
    """Run ``doctest`` on this module."""
    import doctest
    doctest.testmod()


@classmethod
def add_options(cls, parser):
    """Provides the --with-solutions option"""
    parser.add_option('--with-solutions', default=False, action='store',
        help='Enables mastool possible solutions')


def perms_transitive_components(p):
    """
    Return the list of transitive components of the subgroup generated by the
    permutations ``p``.

    INPUT:

    - ``p`` -- a list of permutations given as lists

    EXAMPLES::

        sage: from surface_dynamics.misc.permutation import perms_transitive_components

        sage: perms_transitive_components([[1,0,2,3],[0,1,3,2]])
        [(0, 1), (2, 3)]

        sage: perms_transitive_components([[2,3,0,1]])
        [(0, 2), (1, 3)]

        sage: perms_transitive_components([[3,1,2,0], [0,3,2,1], [0,1,3,2]])
        [(0, 1, 2, 3)]
    """
    n = len(p[0])
    seen = [-1] * n
    cc_num = 0
    for i in range(n):
        if seen[i] != -1:
            continue
        todo = [i]
        seen[i] = cc_num
        while todo:
            j = todo.pop()
            for pp in p:
                k = pp[j]
                if seen[k] == -1:
                    todo.append(k)
                    seen[k] = cc_num
        cc_num += 1
    return [tuple(i for i in range(n) if seen[i] == j) for j in range(cc_num)]


@property
def __members__(cls):
    """Returns a mapping of member name->value.

        This mapping lists all enum members, including aliases. Note that this
        is a copy of the internal mapping.

        """
    return cls._member_map_.copy()


def _to_pickleable_representation(model_name, model_type):
    """
    Extract a pickleable representation of the input Model type.

    Model types are runtime created types and so they are not pickleable.
    In order to workaround this limitation we extract a representation,
    which is pickleable such that we can re-create the input Model type
    (via ``_from_pickleable_representation``).

    NOTE:   This API should not be considered a public API and is meant
            only to be used by bravado_core.spec.Spec.__getstate__ .
    """
    return {'swagger_spec': model_type._swagger_spec, 'model_name':
        model_name, 'model_spec': model_type._model_spec, 'bases':
        model_type.__bases__, 'json_reference': model_type._json_reference}


def _clean_values(val_dict, replace_internal_space=None, replace_null_val=
    None, subst_dict={}, filter_dict={}, predicate=None, predicate2=None):
    """Helper function for reformat_table. Clean the extracted values"""
    for key in val_dict.keys():
        val_dict[key] = val_dict[key].strip()
        if replace_null_val and not val_dict[key]:
            val_dict[key] = replace_null_val
        if replace_internal_space:
            val_dict[key] = val_dict[key].replace(' ', '_')
        if key in filter_dict and val_dict[key] in filter_dict[key]:
            return None
        if predicate and not predicate(val_dict):
            return None
        if predicate2 and not predicate2(val_dict):
            return None
        if key in subst_dict and val_dict[key] in subst_dict[key]:
            val_dict[key] = subst_dict[key][val_dict[key]]
    return val_dict


def get(names):
    """ Read controlpanel children by names
        """


def _0wpF(*w_p_f):
    """(INTERNAL) Float deg, min, sec formatter'.
    """
    return '%0*.*F' % w_p_f


def edited_clear():
    """Undo all edition performed on the particle system

    """
    pass


def generic_find_fk_constraint_name(table, columns, referenced, insp):
    """Utility to find a foreign-key constraint name in alembic migrations"""
    for fk in insp.get_foreign_keys(table):
        if fk['referred_table'] == referenced and set(fk['referred_columns']
            ) == columns:
            return fk['name']


@classmethod
def op(cls, text, *args, **kwargs):
    """ This method must be overriden in derived classes """
    return cls.fn(text, *args, **kwargs)


@classmethod
def isDisabled(cls):
    """ Return True if this Protocol is disabled.
        Disabled protocols will not be offered in the available protocols."""
    return False


def keyframe_delete():
    """Delete a keyframe from selected tracks at current frame

    """
    pass


def determine_best_bee(bees: list) ->tuple:
    """ determine_best_bee: return highest fitness score w/ corresponding
    objective function return value and parameters given a list of bees

    Args:
        bees (list): list of Bee objects

    Returns:
        tuple: (best fitness score, best return value, best parameters)
    """
    best_fitness = 0
    best_ret_val = None
    best_params = None
    for bee in bees:
        if bee._fitness_score > best_fitness:
            best_fitness = bee._fitness_score
            best_ret_val = bee._obj_fn_val
            best_params = bee._params
    return best_fitness, best_ret_val, best_params


def performance(real, ideal):
    """    performance(real, ideal)

    (TODO)
    """
    real = real.squeeze()
    ideal = ideal.squeeze()
    if real.ndim != 1 or ideal.ndim != 1:
        raise ValueError(
            'Cannot compare classifications with more than one dimension')
    return (real == ideal).sum() / real.size


def check_input_size(array, num):
    """Check that an array has the expected number of elements."""
    if array.shape[0] != num:
        raise ValueError(
            'Input arrays must have the same length (the                           number of clusters).'
            )


def ordinal(value):
    """
    Converts zero or a *postive* integer (or their string
    representations) to an ordinal value.

    >>> for i in range(1,13):
    ...     ordinal(i)
    ...
    '1st'
    '2nd'
    '3rd'
    '4th'
    '5th'
    '6th'
    '7th'
    '8th'
    '9th'
    '10th'
    '11th'
    '12th'

    >>> for i in (100, '111', '112',1011):
    ...     ordinal(i)
    ...
    '100th'
    '111th'
    '112th'
    '1011th'

    Notes
    -----
    Author:  Serdar Tumgoren
    http://code.activestate.com/recipes/576888-format-a-number-as-an-ordinal/
    MIT license
    """
    try:
        value = int(value)
    except ValueError:
        return value
    if value % 100 // 10 != 1:
        if value % 10 == 1:
            ordval = '%d%s' % (value, 'st')
        elif value % 10 == 2:
            ordval = '%d%s' % (value, 'nd')
        elif value % 10 == 3:
            ordval = '%d%s' % (value, 'rd')
        else:
            ordval = '%d%s' % (value, 'th')
    else:
        ordval = '%d%s' % (value, 'th')
    return ordval


def _get_func_code(obj):
    """Get funcion code."""
    return obj.func_code


def lookupMailGroup(name, timeout=None):
    """
        Perform an MG record lookup.

        @type name: L{bytes} or L{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}.
        """


def get_key_of_min(dict_obj):
    """Returns the key that maps to the minimal value in the given dict.

    Example:
    --------
    >>> dict_obj = {'a':2, 'b':1}
    >>> print(get_key_of_min(dict_obj))
    b
    """
    return min(dict_obj, key=lambda key: dict_obj[key])


def action_unlink(force_delete: bool=False):
    """Unlink this action from the active action slot (and/or exit Tweak Mode)

    :param force_delete: Force Delete, Clear Fake User and remove copy stashed in this datablock’s NLA stack
    :type force_delete: bool
    """
    pass


@staticmethod
def break_into_lines(text):
    """
        Breaks down multi-line text into a list of strings.

        :param text: The text to be converted to list of string lines.

        :return: List of strings represent lines of supplied text.
        :rtype: list
        """
    return text.split('\n')


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