@classmethod
def get_range_params(cls, value):
    """Get params for `range` query.

        Syntax:

            /endpoint/?field_name__range={lower}__{upper}__{boost}
            /endpoint/?field_name__range={lower}__{upper}

        Example:

            http://localhost:8000/api/users/?age__range=16__67__2.0
            http://localhost:8000/api/users/?age__range=16__67
            http://localhost:8000/api/users/?age__range=16

        :param value:
        :type: str
        :return: Params to be used in `range` query.
        :rtype: dict
        """
    __values = cls.split_lookup_complex_value(value, maxsplit=3)
    __len_values = len(__values)
    if __len_values == 0:
        return {}
    params = {'gte': __values[0]}
    if __len_values == 3:
        params['lte'] = __values[1]
        params['boost'] = __values[2]
        params.update({'lte': __values[1], 'boost': __values[2]})
    elif __len_values == 2:
        params['lte'] = __values[1]
    return params


def formula(famille, period):
    """
        L'allocation de base de la paje n'est pas cumulable avec le complément familial
        """
    apje_avant_cumul = famille('apje_avant_cumul', period)
    ape_avant_cumul = famille('ape_avant_cumul', period)
    cf_montant = famille('cf_montant', period)
    ape = (apje_avant_cumul < ape_avant_cumul) * (cf_montant < ape_avant_cumul
        ) * ape_avant_cumul
    return round(ape, 2)


def print_warning(string, **kwargs):
    """ Print but angry. """
    print(f'\x1b[93m{string}\x1b[0m', **kwargs)


def vertex_random(offset: float=0.1, uniform: float=0.0, normal: float=0.0,
    seed: int=0):
    """Randomize vertices

    :param offset: Amount, Distance to offset
    :type offset: float
    :param uniform: Uniform, Increase for uniform offset distance
    :type uniform: float
    :param normal: normal, Align offset direction to normals
    :type normal: float
    :param seed: Random Seed, Seed for the random number generator
    :type seed: int
    """
    pass


def unweighted_average(grades):
    """Calculate an unweighted average"""
    return float(sum(grades)) / len(grades)


@staticmethod
def _header_list_to_dict(headers):
    """Expand a list of headers into a dictionary.

        headers: a list of [(key, value), (key, value), (key, value)]

        Returns: a dictionary representation of the list
        """
    d = {}
    for header, value in headers:
        if header.startswith('x-image-meta-property-'):
            prop = header.replace('x-image-meta-property-', '')
            d.setdefault('properties', {})
            d['properties'][prop] = value
        else:
            d[header.replace('x-image-meta-', '')] = value
    return d


def getargnames(argspecs, with_unbox=False):
    """Resembles list of arg-names as would be seen in a function signature, including
    var-args, var-keywords and keyword-only args.
    """
    args = argspecs.args
    vargs = argspecs.varargs
    try:
        kw = argspecs.keywords
    except AttributeError:
        kw = argspecs.varkw
    try:
        kwonly = argspecs.kwonlyargs
    except AttributeError:
        kwonly = None
    res = []
    if not args is None:
        res.extend(args)
    if not vargs is None:
        res.append('*' + vargs if with_unbox else vargs)
    if not kwonly is None:
        res.extend(kwonly)
    if not kw is None:
        res.append('**' + kw if with_unbox else kw)
    return res


def _next_significant(tokens):
    """Return the next significant (neither whitespace or comment) token.

    :param tokens: An *iterator* yielding :term:`component values`.
    :returns: A :term:`component value`, or :obj:`None`.

    """
    for token in tokens:
        if token.type not in ('whitespace', 'comment'):
            return token


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


def trunc(s, min_pos=0, max_pos=75, ellipsis=True):
    """Truncation beautifier function
    This simple function attempts to intelligently truncate a given string
    """
    __author__ = 'Kelvin Wong <www.kelvinwong.ca>'
    __date__ = '2007-06-22'
    __version__ = '0.10'
    __license__ = 'Python http://www.python.org/psf/license/'
    """Return a nicely shortened string if over a set upper limit
    (default 75 characters)

    What is nicely shortened? Consider this line from Orwell's 1984...
    0---------1---------2---------3---------4---------5---------6---------7---->
    When we are omnipotent we shall have no more need of science. There will be

    If the limit is set to 70, a hard truncation would result in...
    When we are omnipotent we shall have no more need of science. There wi...

    Truncating to the nearest space might be better...
    When we are omnipotent we shall have no more need of science. There...

    The best truncation would be...
    When we are omnipotent we shall have no more need of science...

    Therefore, the returned string will be, in priority...

    1. If the string is less than the limit, just return the whole string
    2. If the string has a period, return the string from zero to the first
        period from the right
    3. If the string has no period, return the string from zero to the first
        space
    4. If there is no space or period in the range return a hard truncation

    In all cases, the string returned will have ellipsis appended unless
    otherwise specified.

    Parameters:
        s = string to be truncated as a String
        min_pos = minimum character index to return as Integer (returned
                  string will be at least this long - default 0)
        max_pos = maximum character index to return as Integer (returned
                  string will be at most this long - default 75)
        ellipsis = returned string will have an ellipsis appended to it
                   before it is returned if this is set as Boolean
                   (default is True)
    Returns:
        Truncated String
    Throws:
        ValueError exception if min_pos > max_pos, indicating improper
        configuration
    Usage:
    short_string = trunc(some_long_string)
    or
    shorter_string = trunc(some_long_string,max_pos=15,ellipsis=False)
    """
    NOT_FOUND = -1
    ERR_MAXMIN = 'Minimum position cannot be greater than maximum position'
    if max_pos < min_pos:
        raise ValueError(ERR_MAXMIN)
    if ellipsis:
        suffix = '...'
    else:
        suffix = ''
    length = len(s)
    if length <= max_pos:
        return s + suffix
    else:
        try:
            end = s.rindex('.', min_pos, max_pos)
        except ValueError:
            end = s.rfind(' ', min_pos, max_pos)
            if end == NOT_FOUND:
                end = max_pos
        return s[0:end] + suffix


def recover_backup_files():
    """Move all backup files to active message files.

        It is impossible for both the .bak and .pck files to exist at the same
        time, so moving them is enough to ensure that a normal dequeing
        operation will handle them.
        """


def _update_sky_delta(skyline, skyval_brightness):
    """
    Updates `skyuser_delta` of each member of the
    input skyline. It *does not* modify image data or headers.

    .. note::
        This function does not update members of mosaiced skylines.

    Parameters
    ----------
    skyline: `SkyLine` object
        The `Skyline` of the image to update.

    skyval_brightness: float
        Value of sky (in units of brightness) to be added to
        `skyuser_delta` of each member of the input skyline.

    """
    if skyline.is_mf_mosaic or len(skyline.members) < 1:
        return
    for m in skyline.members:
        skyuser_delta = m.brightness2data(skyval_brightness)
        m.update_skydelta(skyuser_delta)
    return


def update_biomass_coefficients(dict_of_coefficients, model):
    """

    Updates the biomass coefficients given the input metabolite:coefficient dictionary.

    :param dict_of_coefficients: dictionary of metabolites and coefficients

    :param model: model to update

    :return: The biomass objective function is updated.

    """
    from BOFdat import update
    update.update_biomass(dict_of_coefficients, model)


def filter_paired(list):
    """
	require that both pairs are mapped in the sam file in order to remove the reads
	"""
    pairs = {}
    filtered = []
    for id in list:
        read = id.rsplit('/')[0]
        if read not in pairs:
            pairs[read] = []
        pairs[read].append(id)
    for read in pairs:
        ids = pairs[read]
        if len(ids) == 2:
            filtered.extend(ids)
    return set(filtered)


def convert_path(*args, **kwargs):
    """
    Handle converter type "path"

    :param args:
    :param kwargs:
    :return: return schema dict
    """
    schema = {'type': 'string', 'format': 'path'}
    return schema


def PLUS_DM(df, n):
    """
    Plus Directional Movement
    """


def sum_decomposable(perm):
    """Determines whether the permutation is expressible as the direct sum of
    two permutations.

    >>> p = Permutation.random(4).direct_sum(Permutation.random(15))
    >>> p.sum_decomposable()
    True
    >>> p.reverse().sum_decomposable()
    False
    """
    p = list(perm)
    n = perm.__len__()
    for i in range(1, n):
        if set(range(0, i)) == set(p[0:i]):
            return True
    return False


def _pad_series(ts, pad, start=None, end=None):
    """Pad a timeseries to match the specified [start, end) limits

    To cover a gap in data returned from a data source
    """
    span = ts.span
    if start is None:
        start = span[0]
    if end is None:
        end = span[1]
    pada = max(int((span[0] - start) * ts.sample_rate.value), 0)
    padb = max(int((end - span[1]) * ts.sample_rate.value), 0)
    if pada or padb:
        return ts.pad((pada, padb), mode='constant', constant_values=(pad,))
    return ts


def _token_to_dep_tuple(token, id_map):
    """
    Creates a tuple of primitives to represent the dependency on a token.

    Args:
        token: The token to convert to a tupled dependency representation.
        id_map: A mapping from string token ids to indices.

    Returns:
        A triplet where the first element is the minimum of the token id and
        governor id, the second is the maximum, and the third is the direction
        of the dependency.
    """
    token_idx = id_map[token.id]
    head_idx = id_map[token.head]
    if token_idx < head_idx:
        return token_idx, head_idx, 'r'
    return head_idx, token_idx, 'l'


def ndo_real(data, n):
    """mimic of gmx_fio_ndo_real in gromacs"""
    return [data.unpack_real() for i in range(n)]


def manhattanDistance(xy1, xy2):
    """Returns the Manhattan distance between points xy1 and xy2"""
    return abs(xy1[0] - xy2[0]) + abs(xy1[1] - xy2[1])


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

        :param FileSaveCopyReferenceDetails val:
        :rtype: EventDetails
        """
    return cls('file_save_copy_reference_details', val)


def segmented_date_range(start_date, end_date, segment='A'):
    """
    Split a date range into smaller segments.

    Parameters
    ----------

    start_date : str (YYYY-MM-DD), required
        start date, inclusive

    end_date : str (YYYY-MM-DD), required
        end date, inclusive

    segment : str, required
        split date range into segments of this size (use Pandas
        frequency string, e.g. 'A' for annual segments or 'Q' for quarterly
        segments; default 'A')

    Returns
    -------
    list
        list of tuples of (start_date, end_date)

    Examples
    --------
    >>> segmented_date_range("2013-06-01", "2015-12-15")
    [('2013-06-01', '2013-12-30'),
    ('2013-12-31', '2014-12-30'),
    ('2014-12-31', '2015-12-15')]
    """
    try:
        import pandas as pd
    except ImportError:
        raise ImportError('pandas must be installed to use this function')
    date_segments = []
    period_boundaries = list(pd.date_range(start_date, end_date, freq=segment))
    start_date = pd.Timestamp(start_date)
    end_date = pd.Timestamp(end_date)
    if start_date not in period_boundaries:
        period_boundaries.insert(0, start_date)
    if end_date not in period_boundaries:
        period_boundaries.append(end_date)
    for i in range(len(period_boundaries) - 1):
        period_start_date = period_boundaries[i].date()
        period_end_date = period_boundaries[i + 1].date()
        if period_end_date < end_date.date():
            period_end_date -= pd.Timedelta(days=1)
        period_start_date = period_start_date.isoformat()
        period_end_date = period_end_date.isoformat()
        date_segments.append((period_start_date, period_end_date))
    return date_segments


def fromOpenIDRequest(cls, request):
    """Instantiate a Request object from the arguments in a
        C{checkid_*} OpenID message
        """
    self = cls()
    args = request.message.getArgs(self.ns_uri)
    is_openid1 = request.message.isOpenID1()
    if args == {}:
        return None
    self.parseExtensionArgs(args, is_openid1)
    return self


def levelize_strength_or_aggregation(to_levelize, max_levels, max_coarse):
    """Turn parameter into a list per level.

    Helper function to preprocess the strength and aggregation parameters
    passed to smoothed_aggregation_solver and rootnode_solver.

    Parameters
    ----------
    to_levelize : {string, tuple, list}
        Parameter to preprocess, i.e., levelize and convert to a level-by-level
        list such that entry i specifies the parameter at level i
    max_levels : int
        Defines the maximum number of levels considered
    max_coarse : int
        Defines the maximum coarse grid size allowed

    Returns
    -------
    (max_levels, max_coarse, to_levelize) : tuple
        New max_levels and max_coarse values and then the parameter list
        to_levelize, such that entry i specifies the parameter choice at level
        i.  max_levels and max_coarse are returned, because they may be updated
        if strength or aggregation set a predefined coarsening and possibly
        change these values.

    Notes
    --------
    This routine is needed because the user will pass in a parameter option
    such as smooth='jacobi', or smooth=['jacobi', None], and this option must
    be "levelized", or converted to a list of length max_levels such that entry
    [i] in that list is the parameter choice for level i.

    The parameter choice in to_levelize can be a string, tuple or list.  If
    it is a string or tuple, then that option is assumed to be the
    parameter setting at every level.  If to_levelize is inititally a list,
    if the length of the list is less than max_levels, the last entry in the
    list defines that parameter for all subsequent levels.

    Examples
    --------
    >>> from pyamg.util.utils import levelize_strength_or_aggregation
    >>> strength = ['evolution', 'classical']
    >>> levelize_strength_or_aggregation(strength, 4, 10)
    (4, 10, ['evolution', 'classical', 'classical'])

    """
    if isinstance(to_levelize, tuple):
        if to_levelize[0] == 'predefined':
            to_levelize = [to_levelize]
            max_levels = 2
            max_coarse = 0
        else:
            to_levelize = [to_levelize for i in range(max_levels - 1)]
    elif isinstance(to_levelize, str):
        if to_levelize == 'predefined':
            raise ValueError(
                "predefined to_levelize requires a user-provided                              CSR matrix representing strength or aggregation                              i.e., ('predefined', {'C' : CSR_MAT})."
                )
        else:
            to_levelize = [to_levelize for i in range(max_levels - 1)]
    elif isinstance(to_levelize, list):
        if isinstance(to_levelize[-1], tuple) and to_levelize[-1][0
            ] == 'predefined':
            max_levels = len(to_levelize) + 1
            max_coarse = 0
        elif len(to_levelize) < max_levels - 1:
            mlz = max_levels - 1 - len(to_levelize)
            toext = [to_levelize[-1] for i in range(mlz)]
            to_levelize.extend(toext)
    elif to_levelize is None:
        to_levelize = [(None, {}) for i in range(max_levels - 1)]
    else:
        raise ValueError('invalid to_levelize')
    return max_levels, max_coarse, to_levelize


def get_cs(c, s):
    """
    cs is a compound with its state in parentheses. This function generates

    """
    if s is None or s == '':
        return c
    s = s.strip()
    c = c.strip()
    if not (s[0] == '(' and s[-1] == ')'):
        s = '(' + s + ')'
    cs = c + s
    return cs


@staticmethod
def p_left_shift(p):
    """left_shift : LEFT_SHIFT NUMERIC"""
    p[0] = p[2]


def getNumberOfRevisions(obj):
    """Return the total number of revisions."""


def build_template(data):
    """
    Build and return an addressbook file template
    """
    template = (
        '# abook addressbook file\n\n[format]\nprogram=abook\nversion=0.6.1\n\n'
        )
    for index, entry in enumerate(data):
        template += (
            f"\n[{index}]\nname={entry['name']}\nemail={','.join(entry['email'])}\n"
            )
        if entry['notes']:
            template += f"notes={entry['notes']}\n"
    template += '\n'
    return template


def rollup_resources(resources):
    """Rollup resources together: if a resource include multiple
    separate ones (i.e. is a rollup) and all the separate ones are
    included the rollup will be used instead.
    """
    potential_rollups = {}
    for resource in resources:
        for rollup in resource.rollups:
            s = potential_rollups.setdefault((rollup.library, rollup.
                relpath), set())
            s.add((resource.library, resource.relpath))
    result = set()
    for resource in resources:
        superseders = []
        for rollup in resource.rollups:
            s = potential_rollups[rollup.library, rollup.relpath]
            if len(s) == len(rollup.supersedes):
                superseders.append(rollup)
        if superseders:
            superseders = sorted(superseders, key=lambda i: len(i.supersedes))
            result.add(superseders[-1])
        else:
            result.add(resource)
    return result


def confirm(token, *, expunge=True):
    """Return the IPendable matching the token.

        :param token: The token string for the IPendable given by the `.add()`
            method, or None if there is no record associated with the token.
        :param expunge: A flag indicating whether the pendable record should
            also be removed from the database or not.
        :return: The matching IPendable or None if no match was found.
        """


def ppd_threshold_from_comfort_class(comf_class):
    """Get acceptable PPD comfort threshold given the EN-15251 comfort class.

    Args:
        comf_class: An integer representing the EN-15251 comfort class.
            Choose from: 1, 2, 3 (the higher the class, the greater the PPD threshold)

    Returns:
        ppd_thresh -- Acceptable PPD threshold.
    """
    if comf_class == 1:
        ppd_thresh = 6
    elif comf_class == 2:
        ppd_thresh = 10
    elif comf_class == 3:
        ppd_thresh = 15
    else:
        raise ValueError(
            'Comfort class {} is not an acceptable value. Choose from: 1, 2, 3'
            .format(comf_class))
    return ppd_thresh


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


def listenMulticast(port, protocol, interface='', maxPacketSize=8192,
    listenMultiple=False):
    """
        Connects a given
        L{DatagramProtocol<twisted.internet.protocol.DatagramProtocol>} to the
        given numeric UDP port.

        @param listenMultiple: If set to True, allows multiple sockets to
            bind to the same address and port number at the same time.
        @type listenMultiple: C{bool}

        @returns: An object which provides L{IListeningPort}.

        @see: L{twisted.internet.interfaces.IMulticastTransport}
        @see: U{http://twistedmatrix.com/documents/current/core/howto/udp.html}
        """


def osr_proj(input_osr):
    """Return the projection WKT of a spatial reference object

    Parameters
    ----------
    input_osr : class:`osr.SpatialReference`
        The input OSR spatial reference.

    Returns
    -------
    WKT: :class:`osr.SpatialReference` in WKT format

    """
    return input_osr.ExportToWkt()


def view_frame():
    """Reset viewable area to show range around current frame

    """
    pass


def format_title(host: str) ->str:
    """Format the title for config entries."""
    return f'Controller ({host})'


def Values2Dict(parmdict, varylist, values):
    """ Use after call to leastsq to update the parameter dictionary with
    values corresponding to keys in varylist"""
    parmdict.update(zip(varylist, values))


def chk_centigrade():
    """
    Provide hint for setting C/F preference (! key)
    """
    from x84.bbs import getterminal, getsession, echo
    session, term = getsession(), getterminal()
    echo(u'\r\n\r\n')
    echo(u'USiNG ')
    if session.user.get('centigrade', None):
        echo(term.yellow(u'Celcius'))
    else:
        echo(term.yellow(u'Fahrenheit'))
    echo(term.bold_black('...'))


def is_pathlib(obj):
    """
    Check if the object is a `pathlib.Path` or subclass.

    Parameters
    ------------
    obj : object
      Object to be checked

    Returns
    ------------
    is_pathlib : bool
      Is the input object a pathlib path
    """
    name = obj.__class__.__name__
    return hasattr(obj, 'absolute') and name.endswith('Path')


def tail(dfx, n=7):
    """Quick look at the LATEST data point(s)."""
    return dfx.tail(n)


def Calc_Bulk_surface_resistance(sl_es_24, Rn_24, Refl_rad_water, air_dens,
    esat_24, eact_24, rah_pm_act, ETA_24, Lhv, Psychro_c):
    """
    Function to calculate the bulk surface resistance
    """
    bulk_surf_resis_24 = (((sl_es_24 * (Rn_24 - Refl_rad_water) + air_dens *
        1004 * (esat_24 - eact_24) / rah_pm_act) / (ETA_24 * Lhv / 86400) -
        sl_es_24) / Psychro_c - 1.0) * rah_pm_act
    bulk_surf_resis_24[ETA_24 <= 0.0] = 100000.0
    bulk_surf_resis_24 = bulk_surf_resis_24.clip(0.0, 100000.0)
    return bulk_surf_resis_24


def merge_dict(data, *override):
    """
    Merges any number of dictionaries together, and returns a single dictionary

    Usage::

        >>> util.merge_dict({"foo": "bar"}, {1: 2}, {"Pay": "Pal"})
        {1: 2, 'foo': 'bar', 'Pay': 'Pal'}
    """
    result = {}
    for current_dict in ((data,) + override):
        result.update(current_dict)
    return result


def select_mirror(only_active: bool=False, extend: bool=False):
    """Mirror the bone selection

    :param only_active: Active Only, Only operate on the active bone
    :type only_active: bool
    :param extend: Extend, Extend the selection
    :type extend: bool
    """
    pass


@classmethod
def quit_all_threads(cls):
    """ call quit on all SafeQThread instances """
    for thread in cls.thread_set:
        thread.quit()


def square_brackets(s):
    """
    Surrounds the string with ⟦ ⟧ characters.  Useful when verifying string
    truncation i.e. when checking the UI these characters should be visible.

    :param s: String to surround
    :returns: String surrounded with ⟦ ⟧
    """
    return u'⟦{0}⟧'.format(s)


def get(name, type='<', rval=[], g=globals()):
    """ get an object from global space. """
    for k, v in g.items():
        t = str(v)
        if t.startswith(type):
            if name and name in t:
                return v


def _MakeList(input):
    """ input is a tuple.
    Example:
    (a, b, c)   --> [a, b, c]
    (a)         --> [a]
    ([a, b, c]) --> [a, b, c]
    """
    if len(input) == 0:
        raise ValueError('input cannot be empty.')
    elif len(input) == 1:
        output = input[0]
        if not isinstance(output, list):
            output = [output]
    else:
        output = list(input)
    return output


def volume_fn(cnt):
    """
    Construct filename for 'volume' metadata file.

    Args:
        cnt (int): Number of the MODS record.

    Returns:
        str: Filename in format ``mods_volume.xml`` or ``mods_volume_cnt.xml``.
    """
    return 'mods_volume%s.xml' % ('_%d' if cnt > 0 else '')


@staticmethod
def _window_group_operator():
    """Method to add window group operator"""
    pass


def put_fdata(fh, fdata):
    """
    Put NMR data, fdata, to a NMRPipe file described by file object fh.
    """
    if fdata.dtype != 'float32':
        raise TypeError('fdata.dtype is not float32')
    fh.write(fdata.tostring())
    return


def p_pdcontent(p):
    """pdcontent : line
                 | line pdcontent"""
    lst = filter(None, p[1:])
    p[0] = ' '.join(lst)


@classmethod
def from_joint_constraint(cls, joint_constraint):
    """Creates a `JointConstraint` from a :class:`compas_fab.robots.JointConstraint`.
        """
    c = joint_constraint
    return cls(c.joint_name, c.value, c.tolerance_above, c.tolerance_below,
        c.weight)


def p_enum_constant_list_1(t):
    """enum_constant_list : enum_constant"""
    t[0] = t[1]


def get_char_size(baudrate):
    """ Get the size of 1 character in seconds.

    From the implementation guide:

        "The implementation of RTU reception driver may imply the management of
        a lot of interruptions due to the t 1.5  and t 3.5  timers. With high

        communication baud rates, this leads to a heavy CPU load. Consequently
        these two timers must be strictly respected when the baud rate is equal
        or lower than 19200 Bps. For baud rates greater than 19200 Bps, fixed
        values for the 2 timers should be used:  it is recommended to use a
        value of 750us for the inter-character time-out (t 1.5) and a value of
        1.750ms for inter-frame delay (t 3.5)."
    """
    if baudrate <= 19200:
        return 11 / baudrate
    return 0.0005


def finalize_wrapper(finalizable):
    """
    Wrapper around the finalize method for the object
    :param finalizable: an object with the finalize method
    :return:
    """
    finalizable.finalize()
    return finalizable


@staticmethod
def _stripOutAnds(inStr):
    """Takes a string and returns the same without ands or ampersands."""
    assert isinstance(inStr, str)
    return inStr.replace(' and ', ' ').replace(' & ', ' ')


def search(df, text):
    """
    Search function on result (file .pkl)

    :param df: (dataframe) dataframe of pandas
    :param text: (str) text

    :return: a dataframe of pandas that include text
    """
    df = df.astype(str)
    result_set = set()
    for column in df.columns:
        result = df[column].str.contains(text)
        for i in range(len(result.values)):
            if result.values[i] == True:
                result_set.add(result.index[i])
    return df.loc[result_set]


def height_from_height_head(segment_length):
    """
    Calculates body height based on the height of the head (up to the bottom of the chin) from the ground

    args:
        segment_length (float): height of the head (up to the bottom of the chin)

    Returns:
        float: total body height
    """
    if segment_length <= 0:
        raise ValueError('segment_length must be > 0')
    return segment_length / 0.87


@classmethod
def build(cls, args, is_training, batch_size=128, shuffle=True, **kwargs):
    """ Subclass inheriting `Dataset` should implement this function to
        return a `tf.data.Datset`.
        @param args: argparse.Namespace. The argument to the dataset.
        @param is_training: boolean. Indicating whether to load training/tesing
                            data split.
        @param batch_size: int. The batch size.
        @param shuffle: boolean. Whether to shuffle the dataset.
        @param kwargs: dict. Optional arguments for specific dataset.
        @return tuple of (`tf.data.Dataset`, dict): The dict serves as
                meta-information for model to add additional arguments, for
                e.g. the image height and width.
        """
    raise NotImplementedError


def _is_long_optname(n):
    """ Determine whether a given option name is "long" form. """
    return n.startswith('--')


@classmethod
def list_by_names(cls, context, names):
    """Return a list of DeployTemplate objects matching a set of names.

        :param context: security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: DeployTemplate(context).
        :param names: a list of names to filter by.
        :returns: a list of :class:`DeployTemplate` objects.
        """
    db_templates = cls.dbapi.get_deploy_template_list_by_names(names)
    return cls._from_db_object_list(context, db_templates)


def jsc(sc):
    """Returns the underlying Scala SparkContext

    :param sc: SparkContext
    :return: :class:`py4j.java_gateway.JavaObject` (org.apache.spark.SparkContext)
    """
    return sc._jsc.sc()


def psi_Cs_K_Cl_PK74(T, P):
    """c-c'-a: caesium potassium chloride [PK74]."""
    psi = -0.0013
    valid = T == 298.15
    return psi, valid


def iter_fields(node):
    """
    Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
    that is present on *node*.
    """
    for field in node._fields:
        try:
            yield field, getattr(node, field)
        except AttributeError:
            pass


def _py3ord(l):
    """Python 3 can work with bytes quite well, return the list of data.
    """
    return l


@classmethod
def info(cls, id):
    """ Display information about a certificate."""
    return cls.call('cert.info', id)


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


def getSubModuleInfo(name):
    """Get sub module info for <name>.

        In a package, give module info for sub-module.
        Returns None if no such sub module is found. In a module,
        always returns None.
        """


@classmethod
def convert_to_review_url(cls, base_url, review_num):
    """Create a web url from review number."""
    return base_url + '/pull/' + review_num.strip('#')


def pad_chunk_columns(chunk, columns):
    """Given a set of items to be inserted, make sure they all have the
    same columns by padding columns with None if they are missing."""
    for record in chunk:
        for column in columns:
            record.setdefault(column, None)
    return chunk


def load_font():
    """
    Load standard font
    """
    return {'family': 'serif', 'size': 20}


def find_last_true(sorted_list, true_criterion):
    """
    Suppose we have a list of item [item1, item2, ..., itemN].

    :type array: list
    :param array: an iterable object that support inex

    :param x: a comparable value

    If we do a mapping::

        >>> def true_criterion(item):
        ...     return item <= 6
        >>> [true_criterion(item) for item in sorted_list]
        [True, True, ... True(last true), False, False, ... False]

    this function returns the index of last true item.

    we do can do the map for all item, and run a binary search to find the
    index. But sometime the mapping function is expensive. This method avoid
    run mapping function for all items.

    Example::

        array     = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        index     = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        criterion = def true_criterion(x): return x <= 6
        boolean   = [1, 1, 1, 1, 1, 1, 1, 0, 0, 0]

    Solution::

        # first, we check index = int((0 + 9)/2.0) = 4, it's True.
        # Then check array[4 + 1], it's still True.
        # Then we jump to int((4 + 9)/2.0) = 6, it's True.
        # Then check array[6 + 1], ite's False. So array[6] is the one we need.

        >>> find_last_true([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], true_criterion)
        6

    **中文文档**

    功能: 假设有一组排序号了的元素, 从前往后假设前面的元素都满足某一条件, 而到了
    中间某处起就不再满足了。本函数返回满足这一条件的最后一个元素。这在当检验是否
    满足条件本身开销较大时, 能节约大量的计算时间。例如你要判定一系列网页中, 从
    page1 到 page999, 从第几页开始出现404错误。假设是第400个, 那么如果一个个地
    去试, 需要400次, 那如果从0 - 999之间去试, 只需要试验9次即可 (2 ** 9 = 512)

    算法:

    我们检验最中间的元素, 如果为False, 那么则检验左边所有未检验过的元素的最中间
    的那个。如果为True, 那么检验右边所有未检验过的元素的最中间那个。重复这一过程
    直到被检验的元素为True, 而下一个元素为False, 说明找到了。

    例题::

        有序数组    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        序号        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        条件        小于等于6
        真值表      [1, 1, 1, 1, 1, 1, 1, 0, 0, 0]

    解::

        第一次检查``index = int((0+9)/2.0) = 4``, 为True,
        检查array[4+1], 也是True。那么跳跃至``int((4+9)/2.0)=6``, 为True,。
        再检查array[6+1], 为False, 很显然, 我们找到了。
    """
    if not true_criterion(sorted_list[0]):
        raise ValueError
    if true_criterion(sorted_list[-1]):
        return sorted_list[-1]
    lower, upper = 0, len(sorted_list) - 1
    index = int((lower + upper) / 2.0)
    while 1:
        if true_criterion(sorted_list[index]):
            if true_criterion(sorted_list[index + 1]):
                lower = index
                index = int((index + upper) / 2.0)
            else:
                return index
        else:
            upper = index
            index = int((lower + index) / 2.0)


def reynolds_number(length, velocity, kinematic_viscosity):
    """Computes the Reynolds number.

    All arguments have to be in the same set of units, for example all in SI units.
    """
    return length / kinematic_viscosity * velocity


def links_line(context, rels, extra=None):
    """String with one link relation formatted according to RFC6690.

    Example line:

    <http://arxiv.example.net/timemap/http://a.example.org>
      ; rel="self";type="application/link-format"
      ; from="Tue, 20 Jun 2000 18:02:59 GMT"
      ; until="Wed, 09 Apr 2008 20:30:51 GMT"

    (and multiple lines are separated with commas)

    Ref: https://tools.ietf.org/html/rfc6690
    """
    s = '<' + context + '>'
    s += '\n  ;rel="' + ' '.join(rels) + '"'
    if extra is not None:
        for k, v in sorted(extra.items()):
            s += '\n  ;' + k + '="' + v + '"'
    return s


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

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


def unicode2str(unicodestr):
    """unicode2str decodes unicode into standard string, replacing errors with space
    :param unicodestr: the unicode to convert
    """
    return unicodestr.decode('utf-8').encode('ascii', errors='replace'
        ).replace('?', ' ')


def xunicode(s):
    """If ``s`` is None return empty string

    .. deprecated::
       Use :func:`xstr` instead.

    :param s: string
    :return: s or an empty string if s in None
    :rtype: str
    """
    return '' if s is None else str(s)


@staticmethod
def parse_condition(condition):
    """
        Transforms conditions in the correct format.

        Conditions are given by users as key-value params, and arrive here as
        (key, value) tuple.

        Value can be a string with an operator prefixed, e.g. '>value', or a
        tuple like (operator, value).
        """
    column = condition[0]
    value = condition[1]
    if value[0:2] in ('>=', '<='):
        return column, value[0:2], value[2:]
    elif value[0] in ('!', '>', '<'):
        return column, value[0], value[1:]
    elif value[0] in ('<=', '>='):
        return column, value[0], (value[1],)
    return column, '=', value


def write_fixed(encoder, datum, schema=None):
    """Fixed instances are encoded using the number of bytes declared in the
    schema."""
    encoder.write_fixed(datum)


def delete_directory(DirectoryId=None):
    """
    Deletes an AWS Directory Service directory.
    Before you call DeleteDirectory , ensure that all of the required permissions have been explicitly granted through a policy. For details about what permissions are required to run the DeleteDirectory operation, see AWS Directory Service API Permissions: Actions, Resources, and Conditions Reference .
    See also: AWS API Documentation

    :example: response = client.delete_directory(
        DirectoryId='string'
    )

    :type DirectoryId: string
    :param DirectoryId: [REQUIRED]
            The identifier of the directory to delete.

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

    """
    pass


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


@staticmethod
def add_callback(callback, control_instance):
    """ Method to add a callback to the control instance when a 'editTextChanged'
        signal is emited.

        Parameters
        ----------
        callback: @function (mandatory)
            the function that will be called when a 'editTextChanged' signal is
            emited.
        control_instance: QComboBox (mandatory)
            the control widget we want to validate
        """
    control_instance.editTextChanged.connect(callback)


def view_selected():
    """View all selected elements

    """
    pass


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


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def get_cat_feats(data=None):
    """
    Returns the categorical features in a data set

    Parameters:
    -----------
        data: DataFrame or named Series

    Returns:
    -------
        List
            A list of all the categorical features in a dataset.
    """
    if data is None:
        raise ValueError("data: Expecting a DataFrame or Series, got 'None'")
    cat_features = num_features = data.select_dtypes(include=['object']
        ).columns
    return list(cat_features)


def camera_to_view_selected():
    """Move the camera so selected objects are framed

    """
    pass


def _invoke_setter_on(input_object, method_name, value):
    """ If a given input object has the given setter method
    name, use this method to set "value" on the object.

    :param input_object: Python object
    :param method_name: name of the setter method
    :param value: value to set
    """
    remove = '_' + type(input_object).__name__ + '__'
    real_method_name = method_name.replace(remove, '')
    setter_method = '_set_' + real_method_name
    if hasattr(input_object, setter_method):
        method = getattr(input_object, setter_method)
        method(value)


@classmethod
def register_resource(cls, name, url):
    """Method to register a resource necessary to the app

        Args:
            name (string): Name of system to check health
            url (string): Url of system to check health
        """
    cls.RESOURCES.append({name: url})


@classmethod
def of(cls, x):
    """
        Factory for creating new IO monad
        @sig of :: a -> IO a
        """
    return cls(lambda : x)


def API520_F2(k, P1, P2):
    """Calculates coefficient F2 for subcritical flow for use in API 520
    subcritical flow relief valve sizing.

    .. math::
        F_2 = \\sqrt{\\left(\\frac{k}{k-1}\\right)r^\\frac{2}{k}
        \\left[\\frac{1-r^\\frac{k-1}{k}}{1-r}\\right]}

    .. math::
        r = \\frac{P_2}{P_1}

    Parameters
    ----------
    k : float
        Isentropic coefficient or ideal gas heat capacity ratio [-]
    P1 : float
        Upstream relieving pressure; the set pressure plus the allowable
        overpressure, plus atmospheric pressure, [Pa]
    P2 : float
        Built-up backpressure; the increase in pressure during flow at the
        outlet of a pressure-relief device after it opens, [Pa]

    Returns
    -------
    F2 : float
        Subcritical flow coefficient `F2` [-]

    Notes
    -----
    F2 is completely dimensionless.

    Examples
    --------
    From [1]_ example 2, matches.

    >>> API520_F2(1.8, 1E6, 7E5)
    0.8600724121105563

    References
    ----------
    .. [1] API Standard 520, Part 1 - Sizing and Selection.
    """
    r = P2 / P1
    return (k / (k - 1) * r ** (2.0 / k) * ((1 - r ** ((k - 1.0) / k)) / (
        1.0 - r))) ** 0.5


def channels_click(extend: bool=False, children_only: bool=False):
    """Handle mouse-clicks over animation channels

    :param extend: Extend Select
    :type extend: bool
    :param children_only: Select Children Only
    :type children_only: bool
    """
    pass


def can_access(sm, permission_name, view_name, user):
    """Protecting from has_access failing from missing perms/view"""
    if user.is_anonymous():
        return sm.is_item_public(permission_name, view_name)
    else:
        return sm._has_view_access(user, permission_name, view_name)


@classmethod
def getConfigSection(cls):
    """Overriden because [domain/path] section for multiple-adapter domain."""
    return cls.getSiteDomain() + cls.getPathToArchive()


def untag_resource(Resource=None, TagKeys=None):
    """
    Remove tags from a CloudFront resource.
    See also: AWS API Documentation

    :example: response = client.untag_resource(
        Resource='string',
        TagKeys={
            'Items': [
                'string',
            ]
        }
    )

    :type Resource: string
    :param Resource: [REQUIRED]
            An ARN of a CloudFront resource.

    :type TagKeys: dict
    :param TagKeys: [REQUIRED]
            A complex type that contains zero or more Tag key elements.
            Items (list) --A complex type that contains Tag key elements.
            (string) --A string that contains Tag key.
            The string length should be between 1 and 128 characters. Valid characters include a-z , A-Z , 0-9 , space, and the special characters _ - . : / = + @ .

    """
    pass


def rescaling(array, floor=0, ceil=1):
    """ Rescale the range of features to a given range. """
    arr_min = array.min(axis=0)
    array = (array - arr_min) / (array.max(axis=0) - arr_min)
    return array * (ceil - floor) + floor


def precalculateVars(paramDict):
    """ Get binning, gain and defect files. """
    bin = 2.0 if paramDict['Mode'] == 'Super-resolution' else 1.0
    gain = '' if paramDict['GainReference'] == 'None' else paramDict[
        'GainReference']
    defect = '' if paramDict['DefectFile'] == 'None' else paramDict[
        'DefectFile']
    return bin, gain, defect


@classmethod
def init(cls, *args, **kwargs):
    """Fabric to build attributes"""
    return cls(*args, **kwargs).get_field()


def labeledfeatures(eqdata, featurefunc, labelfunc):
    """
    Return features and labels for the given equity data.

    Each row of the features returned contains `2 * n_sessions + 1` columns
    (or 1 less if the constant feature is excluded). After the constant feature,
    if present, there will be `n_sessions` columns derived from daily growth
    of the given price column, which defaults to 'Adj Close'. There will then
    follow another `n_sessions` columns representing current volume as
    a multiple of average volume over the previous 252 (or other value determined
    by the user) sessions.

    The returned features are not centered or normalized because these
    adjustments need to be made after test or cross-validation data has
    been removed.

    The constant feature is prepended by default.

    The labels are derived from `eqdata` using `labelfunc`.

    Parameters
    ----------
    eqdata : DataFrame
        Expected is a dataframe as return by the `get()` function. A column
        labeled 'Volume' must be present.

    featurefunc : function
        Function taking a dataframe of simple equity data as argument
        and returning a dataframe of features and an integer representing
        the number of rows that had to be skipped at the beginning of
        the index of the input dataframe. The rows skipped are used
        to synchronize the indices of features and labels. For example,
        if the features are composed of 4 successive daily returns, then
        the date of row 0 of features would be the same as the date of row 3
        (counting from 0) of input data. So the corresponding `featurefunc`
        would return a dataframe and the value 3.

    labelfunc : function
        function for deriving labels from `eqdata`. `labelfunc` must
        take a single argument: `df`, a dataframe to which `labelfunc` will be applied.
        `labelfunc` should return a dataframe of labels followed by an int
        specifying the number of feature rows to skip at the end of the feature
        dataframe. For example, if features are relative prices 64 days out,
        these features will only be known up until 64 days before the data
        runs out. In order to properly align features and labels, the features
        should not include the last 64 rows that would otherwise be possible.

        Usage:
        `labels, skipatend = labelfunc(eqdata)`

    Returns
    -------
    features : DataFrame
        The features derived from the given parameters.

    labels : DataFrame
        The labels derived from the given parameters.
    """
    _size = len(eqdata.index)
    _labels, _skipatend = labelfunc(eqdata)
    _features, _skipatstart = featurefunc(eqdata.iloc[:_size - _skipatend, :])
    return _features, _labels.iloc[_skipatstart:, :]


def rp_get_args(c):
    """Compute and return oldSel,oldYview,original,pageWidth,tabWidth."""
    body = c.frame.body
    w = body.wrapper
    d = c.scanAllDirectives()
    if c.editCommands.fillColumn > 0:
        pageWidth = c.editCommands.fillColumn
    else:
        pageWidth = d.get('pagewidth')
    tabWidth = d.get('tabwidth')
    original = w.getAllText()
    oldSel = w.getSelectionRange()
    oldYview = w.getYScrollPosition()
    return oldSel, oldYview, original, pageWidth, tabWidth


@conf
def fc_add_flags(conf):
    """
	Adds FCFLAGS / LDFLAGS / LINKFLAGS from os.environ to conf.env
	"""
    conf.add_os_flags('FCPPFLAGS', dup=False)
    conf.add_os_flags('FCFLAGS', dup=False)
    conf.add_os_flags('LINKFLAGS', dup=False)
    conf.add_os_flags('LDFLAGS', dup=False)


def is_instance_id(instance):
    """ Return True if the user input is an instance ID instead of a name """
    if instance[:2] == 'i-':
        return True
    return False


@classmethod
def interpret_response(cls, response):
    """
        Populates the response ``service_data`` property with an instance of :class:`ClearDiagnosticInformation.ResponseData<udsoncan.services.ClearDiagnosticInformation.ResponseData>`

        :param response: The received response to interpret
        :type response: :ref:`Response<Response>`
        """
    response.service_data = cls.ResponseData()


def chunkify(iterable, n, drop_incomplete=False):
    """Return a generator providing chunks (lists of size n) of the iterable.

    >>> tuple(chunkify(range(10), 5))  # len(iterable) % n == 0
    ([0, 1, 2, 3, 4], [5, 6, 7, 8, 9])
    >>> tuple(chunkify(range(12), 5))  # len(iterable) % n != 0
    ([0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11])
    >>> tuple(chunkify([], 100))       # Empty iterable example
    ([],)
    """
    offset = 0
    ret = [None] * n
    i = -1
    for i, e in enumerate(iterable):
        if i - offset == n:
            yield ret
            offset += n
            ret = [None] * n
        ret[i - offset] = e
    last_n = i - offset + 1
    if last_n == n or not drop_incomplete:
        yield ret[:last_n]


def __new__(cls, rargname, post):
    """
        Create new instance, forcing strings to be uppercase
        """
    if isinstance(rargname, str):
        rargname = rargname.upper()
    if isinstance(post, str):
        post = post.upper()
    return super().__new__(cls, rargname, post)


def b_ord(byte):
    """Return the Unicode code point for a byte or iteration product of a byte string alike object (e.g. bytearray).

    :param byte: The single byte or iteration product of a byte string to convert
    :type byte: bytes or str or int
    :return: Unicode code point
    :rtype: int"""
    return byte if isinstance(byte, int) else ord(byte)


def root_query(*service):
    """ This function returns the name of the root query for a model service. """
    return 'all_models'


def InitVars():
    """Initializes all constraint information"""
    global dependentParmList, arrayList, invarrayList, indParmList, fixedDict, consNum, symGenList
    dependentParmList = []
    arrayList = []
    invarrayList = []
    indParmList = []
    fixedDict = {}
    symGenList = []
    consNum = 0
    global genVarLookup
    genVarLookup = {}


def get_all(isamAppliance, check_mode=False, force=False):
    """
    Retrieving all Client Certificate Mapping
    """
    return isamAppliance.invoke_get('Retrieving all Client Certificate Mapping'
        , '/wga/client_cert_cdas')


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


def _set_θ(method):
    """Retorna o valor de '𝛉' conforme 'method'."""
    if method[1] == 'c':
        return 0
    elif method[1] == 'u':
        return 1


def local_to_global(pose, point):
    """
    Same as pose.transform_point(point)
    :param point: instance of ``util.Point``
    """
    return pose.transform_point(point)


@classmethod
def get_anchors(cls, url):
    """urlの文書に含まれるアンカー配列を返す

        Args:
            url:

        Returns:
            list(str): URL配列を返す
        """
    query = (
        f'MATCH (n:Node{{url:"{url}"}}) MATCH (n)-[r:Link]->(to:Node) return r, to'
        )
    anchors = []
    with cls.DRIVER.session() as session:
        for record in session.run(query):
            data = {'to_url': record[0].nodes[1]['url'], 'heuristic':
                record[0]['heuristic'], 'pheromone': record[0]['pheromone']}
            anchors.append(data)
    return anchors


def get_spec(obj):
    """
   Gets the spec from any labeled data object.
   """
    return obj.__class__.__name__, obj.group, obj.label


def number_of_bits(num):
    """
    Return the number of bits required to represent num.

    In python >= 2.7, there is num.bit_length().

    NOTE: This function appears unused, so it might go away.
    """
    assert num >= 0
    return len(bin(num)) - 2


def swap_inputs():
    """Swap the first two inputs for the effect strip

    """
    pass


def _dict_mixed_conll_formatter(v, v_delimiter):
    """
    Format a mixed value into a string representation.

    Args:
        v: The value to convert to a mixed CoNLL string format.
        v_delimiter: The delimiter between values in the string.

    Returns:
        A CoNLL representation of the mixed value.
    """
    if v is None:
        return v
    sorted_vs = sorted(v, key=str.lower)
    str_vs = v_delimiter.join(sorted_vs)
    return str_vs


@staticmethod
def _is_arr_like(val):
    """Returns true if SAM data is array-like. False if scalar."""
    if isinstance(val, (int, float, str)):
        return False
    else:
        try:
            len(val)
        except TypeError:
            return False
        else:
            return True


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

        :param SharingUserError val:
        :rtype: ListFilesContinueError
        """
    return cls('user_error', val)


def contains_symbol(text: str, symbols: str) ->bool:
    """If text contains a symbol in symbols, return True."""
    for character in text:
        if character in symbols:
            return True
    return False


def help_message(initial_desc: str, usage: tuple, long_desc: (tuple or None)
    ) ->None:
    """
    Used to simplify and standardize printing out help messages for the various
    help_XXX methods
    :param initial_desc: Short usage description
    :param usage: usage example
    :param long_desc: longer description, additional usage examples or info
    :return:
    """
    print('-' * 40)
    print(initial_desc)
    print()
    print('\n'.join(usage))
    if long_desc:
        print('*' * 80)
        print('\n'.join(long_desc))
        print('*' * 80)


def same_indexes(l1, l2):
    """
        from elist.elist import *
        l1 = [1,2,3,5]
        l2 = [0,2,3,4]
        same_indexes(l1,l2)
    """
    rslt = []
    for i in range(0, l1.__len__()):
        if l1[i] == l2[i]:
            rslt.append(i)
    return rslt


def scale_npeaks(context, topn, factor):
    """Adjust top N demand peaks by X%.

    >>> class C: pass
    >>> c = C()
    >>> c.demand = pd.DataFrame(np.zeros((5,5)))
    >>> c.demand.loc[3] = 5000
    >>> c.demand.loc[4] = 3000
    >>> scale_npeaks(c, 1, 0.5)
    >>> c.demand.loc[4]
    0    3000.0
    1    3000.0
    2    3000.0
    3    3000.0
    4    3000.0
    Name: 4, dtype: float64
    >>> c.demand.loc[3]
    0    2500.0
    1    2500.0
    2    2500.0
    3    2500.0
    4    2500.0
    Name: 3, dtype: float64
    """
    agg_demand = context.demand.sum(axis=1).sort_values(ascending=False)
    rng = agg_demand.head(topn).index
    context.demand.loc[rng] *= factor


def get_history(instance):
    """Get the latest history entry of an instance."""
    try:
        history = {'id': str(instance.history.latest('pk').pk), 'class':
            instance.history.model.__name__}
    except:
        history = None
    return history


def p_compound_stmt_2(p):
    """compound_stmt : while_stmt"""
    p[0] = [p[1]]


@classmethod
def make_separator(cls, value):
    """Create a separator token"""
    assert value in (',', ';')
    subtype = cls.ARG if value == ',' else cls.ROW
    return cls(value, cls.SEP, subtype)


@classmethod
def open(cls, storage, name):
    """Convenience method to open a hash file given a
        :class:`whoosh.filedb.filestore.Storage` object and a name. This takes
        care of opening the file and passing its length to the initializer.
        """
    length = storage.file_length(name)
    dbfile = storage.open_file(name)
    return cls(dbfile, length)


def ibm2ieee(ibm):
    """
    Converts an IBM floating point number into IEEE format.
    :param: ibm - 32 bit unsigned integer: unpack('>L', f.read(4))
    """
    if ibm == 0:
        return 0.0
    sign = ibm >> 31 & 1
    exponent = ibm >> 24 & 127
    mantissa = (ibm & 16777215) / float(pow(2, 24))
    print('x', sign, exponent - 64, mantissa)
    return (1 - 2 * sign) * mantissa * float(pow(16, exponent - 64))


def set_all_for_tid(tid_int, state_oid_iter):
    """
        Store the states for the ``(state, oid_int)`` pairs under
        ``(oid_int, tid_int)`` keys.

        The *state_oid_iter* is an **iteable** of ``(state, oid_int,
        prev_tid_int)`` pairs; this method may choose to buffer a
        limited amount of those pairs before passing them on to the
        underlying storage in a bulk group.

        As an **iterable**, *state_oid_iter* may be consumed multiple
        times.
        """


def _subsequence(s, c):
    """
    Takes as parameter list like object s and returns the length of the longest
    subsequence of s constituted only by consecutive character 'c's.
    Example: If the string passed as parameter is "001000111100", and c is '0',
    then the longest subsequence of only '0's has length 3.
    """
    bit = 0
    count = 0
    maxlen = 0
    for i in range(len(s)):
        bit = s[i]
        if bit == c:
            count = count + 1
            if count > maxlen:
                maxlen = count
        else:
            count = 0
    return maxlen


def create_parameter(key):
    """Make a command line parameter out of a key in a YAML file."""
    if len(key) == 1:
        return '-{}'.format(key)
    else:
        return '--{}'.format(key)


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        Non dynamic discovery of type for:
            * data.runs
            * data.actions

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
         {
            "dynamic":true,
                "properties": {
                    "data": {
                        "properties": {
                            "_class" : {
                                "type" : "keyword"
                            },
                            "runs": {
                                "dynamic":false,
                                "properties": {}
                            },
                            "actions": {
                                "dynamic":false,
                                "properties": {}
                            },
                            "building" : {
                                "type" : "boolean"
                            },
                            "builtOn" : {
                                "type" : "keyword"
                            },
                            "changeSet": {
                                "properties": {
                                    "items": {
                                        "properties": {
                                            "comment": {
                                                "type": "text",
                                                "index": true
                                            }
                                        }
                                    }
                                }
                            },
                            "description" : {
                                "type" : "keyword"
                            },
                            "displayName" : {
                                "type" : "keyword"
                            },
                            "duration" : {
                                "type" : "long"
                            },
                            "estimatedDuration" : {
                                "type" : "long"
                            },
                            "executor" : {
                                "type" : "object"
                            },
                            "fullDisplayName" : {
                                "type" : "keyword"
                            },
                            "id" : {
                                "type" : "keyword"
                            },
                              "keepLog" : {
                                "type" : "boolean"
                            },
                              "number" : {
                                "type" : "long"
                            },
                            "queueId" : {
                                "type" : "long"
                            },
                            "result" : {
                                "type" : "keyword"
                            },
                            "subBuilds" : {
                                "type" : "object"
                            },
                            "timestamp" : {
                                "type" : "long"
                            },
                            "url" : {
                                "type" : "keyword"
                            }
                        }
                    }
                }
        }
        """
    return {'items': mapping}


def debug(__self, __message, *args, **kwargs):
    """Log ``message.format(*args, **kwargs)`` with severity ``'DEBUG'``."""
    __self._log('DEBUG', None, False, __self._options, __message, args, kwargs)


@classmethod
def create(cls, **kwargs):
    """Create a new record and save it the database."""
    instance = cls(**kwargs)
    return instance.save()


def document_model_driven_signature(section, name, operation_model, include
    =None, exclude=None):
    """Documents the signature of a model-driven method

    :param section: The section to write the documentation to.

    :param name: The name of the method

    :param operation_model: The operation model for the method

    :type include: Dictionary where keys are parameter names and
        values are the shapes of the parameter names.
    :param include: The parameter shapes to include in the documentation.

    :type exclude: List of the names of the parameters to exclude.
    :param exclude: The names of the parameters to exclude from
        documentation.
    """
    params = {}
    if operation_model.input_shape:
        params = operation_model.input_shape.members
    parameter_names = list(params.keys())
    if include is not None:
        for member in include:
            parameter_names.append(member.name)
    if exclude is not None:
        for member in exclude:
            if member in parameter_names:
                parameter_names.remove(member)
    signature_params = ''
    if parameter_names:
        signature_params = '**kwargs'
    section.style.start_sphinx_py_method(name, signature_params)


@classmethod
def get_region_rep_profile(cls, gen_fpath, rev_summary, gid_col='gen_gids',
    cf_dset='cf_profile', rep_method='meanoid', err_method='rmse', weight=
    'gid_counts', n_profiles=1):
    """Class method for parallelization of rep profile calc.

        Parameters
        ----------
        gen_fpath : str
            Filepath to reV gen output file to extract "cf_profile" from.
        rev_summary : pd.DataFrame
            Aggregated rev supply curve summary file trimmed to just one
            region to get a rep profile for.
        gid_col : str
            Column label in rev_summary that contains the generation gids
            (data index in gen_fpath).
        cf_dset : str
            Dataset name to pull generation profiles from.
        rep_method : str
            Method identifier for calculation of the representative profile.
        err_method : str
            Method identifier for calculation of error from the representative
            profile.
        weight : str | None
            Column in rev_summary used to apply weighted mean to profiles.
            The supply curve table data in the weight column should have
            weight values corresponding to the gid_col in the same row.
        n_profiles : int
            Number of representative profiles to retrieve.

        Returns
        -------
        rep_profile : np.ndarray
            (time, n_profiles) array for the most representative profile(s)
        i_rep : list
            Column Index in profiles of the representative profile(s).
        gen_gid_reps : list
            Generation gid(s) of the representative profile(s).
        res_gid_reps : list
            Resource gid(s) of the representative profile(s).
        """
    r = cls(gen_fpath, rev_summary, gid_col=gid_col, cf_dset=cf_dset,
        rep_method=rep_method, err_method=err_method, weight=weight,
        n_profiles=n_profiles)
    return r.rep_profiles, r.i_reps, r.rep_gen_gids, r.rep_res_gids


@classmethod
def options(cls, param=None, **kwargs):
    """Bind middleware's method as OPTIONS endpoint.
        """
    return cls.bind(param, methods=['OPTIONS'], **kwargs)


def pchange2(f, c1, c2):
    """Calculate the percentage change between two variables.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the two columns ``c1`` and ``c2``.
    c1 : str
        Name of the first column in the dataframe ``f``.
    c2 : str
        Name of the second column in the dataframe ``f``.

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

    """
    new_column = f[c1] / f[c2] - 1.0
    return new_column


def make_progress_str(i, L=100):
    """Make a progress string with a rotating stick"""
    return '\r%3d%s %s' % (100 * i / L, '%', ('|', '/', '-', '\\')[i % 4])


def is_macho(filename):
    """ Check that a file is in the Mach-O format. """
    with open(filename, 'rb') as fp:
        data = fp.read(2)
    fp.close()
    return data == 'Ïú'


@classmethod
def get_or_create(cls, name):
    """Return a Message object.

        Args:
            name (str): The fully qualified name of the message (for example:
                ``google.protobuf.SourceCodeInfo``)

        Returns:
            ``MessageStructure``: A ``MessageStructure`` object.
        """
    cls._registry.setdefault(name, cls(name=name))
    return cls._registry[name]


def __gt__(i1, i2):
    """ Test if i1.inf > i2.sup
        """
    return i1.inf > i2.sup


def remove_new_line(text: str) ->str:
    """ Removes new line chars
    :param text: Text to be cleaned
    :return: Clean text
    """
    return text.translate(str.maketrans('\n\r', '  '))


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


def is_dictionary_subclass(obj):
    """Returns True if *obj* is a subclass of the dict type. *obj* must be
    a subclass and not the actual builtin dict.

    >>> class Temp(dict): pass
    >>> is_dictionary_subclass(Temp())
    True
    """
    return hasattr(obj, '__class__') and issubclass(obj.__class__, dict
        ) and type(obj) is not dict


def certificate_type(string):
    """ Loads file and outputs contents as base64 encoded string. """
    import os
    with open(os.path.expanduser(string), 'rb') as f:
        cert_data = f.read()
    return cert_data


def ixs_in_region(bboxes, y1, y2, x1, x2):
    """Heuristic for determining objects in a region.

    Args:
        bboxes (:obj:`list` of :obj:`carpedm.data.util.BBox`): Bounding
            boxes for object boundaries.
        y1 (int): Top (lowest row index) of region.
        y2 (int): Bottom (highest row index) of region.
        x1 (int): left side (lowest column index) of region.
        x2 (int): right side (highest column index) of region.

    Returns:
        :obj:`list` of :obj:`int`: Indices of objects inside region.
    """
    result = []
    for i in range(len(bboxes)):
        b = bboxes[i]
        if b.xmin >= x1 and b.xmax <= x2 and y1 <= b.ymin and b.ymax <= y2:
            result.append(i)
    return result


@staticmethod
def _get_not_unwinded_naming_map(source_series, fields_not_to_unwind):
    """Form a dict mapping the path to the fields inside fields_not_to_unwind
        to the subfields.
        It is needed in order to use the json_normalize in pandas.io.json.

        Example: {"doctor": {"last_name": "Doe", "first_name": "John"}} will return
        -not_unwinded_naming_map = {"doctor.first_name": "first_name",
                                    "doctor.last_name": "last_name"}"""
    not_unwinded_naming_map = {}
    for field in source_series:
        if field in fields_not_to_unwind:
            for subfield in source_series[field]:
                not_unwinded_naming_map['{}.{}'.format(field, subfield)
                    ] = subfield
    return not_unwinded_naming_map


@classmethod
def vline(cls, x=None, y=None, char='|', n=None):
    """
        Insert a vertical line at position, at most n characters or height of
        window.

        :param x: optional x value
        :param y: optional y value
        :param char: the character to print, default '|'
        :param n: the number of characters, default rest of height of window
        """
    x, y = cls._fix_xy(x, y)
    n = cls.HEIGHT if n is None else n
    return cls.WINDOW.vline(y, x, char, n)


def parse_target_miRNAlist(miRNAlist_fp):
    """Parses list of miRNA of interests.
	Attribute:
		miRNAlist_fp (str): File path to a miRNA list file.
	"""
    miRNAlist = []
    infile = open(miRNAlist_fp, 'r')
    for line in infile:
        miRNA = line.strip()
        miRNAlist.append(miRNA)
    return sorted(miRNAlist)


def make_droid_skeleton_bbm(method, build, device, variant='common'):
    """
    Make an Android autoloader/hash URL, on the BB Mobile site.

    :param method: None for regular OS links, "sha256/512" for SHA256 or 512 hash.
    :type method: str

    :param build: Build to check, 3 letters + 3 numbers.
    :type build: str

    :param device: Device to check.
    :type device: str

    :param variant: Autoloader variant. Default is "common".
    :type variant: str
    """
    devices = {'KEYone': 'qc8953', 'Motion': 'qc8953krypton', 'KEY2': 'sdm660'}
    base = 'bbry_{2}_autoloader_user-{0}-{1}'.format(variant, build.upper(),
        devices[device])
    if method is None:
        skel = 'http://54.247.87.13/softwareupgrade/BBM/{0}.zip'.format(base)
    else:
        skel = 'http://54.247.87.13/softwareupgrade/BBM/{0}.{1}sum'.format(base
            , method.lower())
    return skel


def MPInt(value):
    """Encode a multiple precision integer value"""
    l = value.bit_length()
    l = l // 8 + 1 if value != 0 and l % 8 == 0 else (l + 7) // 8
    return l.to_bytes(4, 'big') + value.to_bytes(l, 'big', signed=True)


def date_format(value, instance):
    """
    Format cell value to friendly date string
    """
    return value.strftime('%d/%m/%Y')


def check_valid_input(input_value):
    """Checks if an input value corresponds to a valid value - i.e. not None, "", "None",..."""
    if input_value is None or input_value == '' or input_value == 'None':
        valid = False
    else:
        valid = True
    return valid


def unauthenticated(func):
    """Adds 'unauthenticated' attribute to decorated function.

    Usage:

    >>> @unauthenticated
    ... def mymethod(f):
    ...     pass
    """
    func.unauthenticated = True
    return func


def find_classes_in_module(module, clstypes):
    """Find classes of clstypes in module
    """
    classes = []
    for item in dir(module):
        item = getattr(module, item)
        try:
            for cls in clstypes:
                if issubclass(item, cls) and item != cls:
                    classes.append(item)
        except:
            pass
    return classes


def dynamic_import(import_string):
    """
    Dynamically import a module or object.
    """
    lastdot = import_string.rfind('.')
    if lastdot == -1:
        return __import__(import_string, {}, {}, [])
    module_name, attr = import_string[:lastdot], import_string[lastdot + 1:]
    parent_module = __import__(module_name, {}, {}, [attr])
    return getattr(parent_module, attr)


def libsolv_formatted_evr(epoch, version, release):
    """Create an epoch-version-release string from the separate values.

    Pulp stores epoch-version-release separately, libsolv uses them together.
    Convert from Pulp separate values to a combined EVR formatted as libsolv expects.
    """
    if version is None:
        return None
    return '{}{}{}'.format('{}:'.format(epoch) if epoch else '', version,
        '-{}'.format(release) if release else '')


def wavelength_tlv(wave_period, velocity):
    """Usage: Calculate wavelength (l) using wave period (T) and velocity (v)"""
    return wave_period * velocity


@staticmethod
def vendor_package_pairs(docstring):
    """Generator yielding each instance of a vendor name, package name pair
        in a checkers docstring"""
    for line in docstring.split('\n'):
        if line.strip().startswith('VPkg:'):
            yield tuple(map(lambda x: x.strip(), line.replace('VPkg:', '').
                split(',')))


def _pickle_custom_node(node, base_node, base_node_method_name, kwargs):
    """
    same as _pickle_node but with the addition of kwargs
    if the node was created using a MDFCustomNodeMethod.
    """
    if base_node is not None:
        return (node.name, node._modulename, node._is_bound, base_node,
            base_node_method_name, kwargs)
    return node.name, node._modulename, node._is_bound, None, None, None


@staticmethod
def _cast_to_float(value):
    """
        Cast ``value`` to a float if possible.

        Parameters
        ----------
        value : str
            string to cast

        Returns
        -------
        value : float or str
            A float if it can be casted so otherwise the initial string.
        """
    try:
        return float(value)
    except (ValueError, TypeError):
        return value


def is_path_like(obj, attr=('name', 'is_file', 'is_dir', 'iterdir')):
    """test if object is pathlib.Path like"""
    for a in attr:
        if not hasattr(obj, a):
            return False
    return True


def is_user_context(context):
    """Indicates if the request context is a normal user."""
    if not context:
        return False
    if context.is_admin:
        return False
    if not context.user_id or not context.project_id:
        return False
    return True


def validate_enum(datum, schema, **kwargs):
    """
    Check that the data value matches one of the enum symbols.

    i.e "blue" in ["red", green", "blue"]

    Parameters
    ----------
    datum: Any
        Data being validated
    schema: dict
        Schema
    kwargs: Any
        Unused kwargs
    """
    return datum in schema['symbols']


@classmethod
def base_url(klass, space_id, webhook_id, resource_id=None):
    """
        Returns the URI for the webhook call.
        """
    return 'spaces/{0}/webhooks/{1}/calls/{2}'.format(space_id, webhook_id,
        resource_id if resource_id is not None else '')


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 render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

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


@classmethod
def isabreaker(cls, c, alist, esc):
    """ where we find char in c within a list alist that is not escaped by esc """
    for i, x in enumerate(alist):
        if c == x and alist[i - 1] != esc:
            return x
    return 0


def plot_line(ax, ob, line_color):
    """Plot boundaries of shapely line

    Parameters
    ----------
    ax : ``matplotlib.pyplot.Axes`` object
        Axes for plotting
    ob : ``Shapely`` object
        Geometry object whose boundaries should be plotted
    line_color : str
        matplotlib color to use for plotting the line

    """
    try:
        x, y = ob.xy
        ax.plot(x, y, color=line_color, alpha=0.7, linewidth=3,
            solid_capstyle='round', zorder=2)
    except NotImplementedError:
        for line in ob:
            x, y = line.xy
            ax.plot(x, y, color=line_color, alpha=0.7, linewidth=3,
                solid_capstyle='round', zorder=2)


@classmethod
def from_dict(cls, data, name=None):
    """Initialize a new table from a dict.

        data (dict): The dictionary.
        name (unicode): Optional table name for reference.
        RETURNS (Table): The newly created object.

        DOCS: https://spacy.io/api/lookups#table.from_dict
        """
    self = cls(name=name)
    self.update(data)
    return self


@classmethod
def cms(cls, *args):
    """
        executes cm with the given arguments
        :param args:
        :return:
        """
    return cls.execute('cms', args)


@classmethod
def _from_dict(cls, _dict):
    """Initialize a MessageContextSkill object from a json dictionary."""
    args = {}
    if 'user_defined' in _dict:
        args['user_defined'] = _dict.get('user_defined')
    return cls(**args)


@classmethod
def manager_name(cls) ->str:
    """returns the name of the property manager"""
    return 'master'


def saturation(p):
    """
    Returns the saturation of a pixel, defined as the ratio of chroma to value.
    :param p: A tuple of (R,G,B) values
    :return: The saturation of a pixel, from 0 to 1
    """
    max_c = max(p)
    min_c = min(p)
    if max_c == 0:
        return 0
    return (max_c - min_c) / float(max_c)


def handleProcess(game, queue):
    """
    Handle the genWorld queue and link it back into the main thread
    """
    game.getModInstance('ClientMod').genLock = True
    while True:
        data = queue.get()
        if isinstance(data, list):
            game.world.centrePos = data
        elif data != 'end':
            game.world.setTileMap(data)
        else:
            game.getModInstance('ClientMod').genLock = False
            return


def get_ssl_client_options(conf):
    """Format SSL-related requests options.

    :param conf: oslo_config CONF object
    :returns: tuple of 'verify' and 'cert' values to pass to requests
    """
    if conf.insecure:
        verify = False
    else:
        verify = conf.cafile or True
    if conf.certfile and conf.keyfile:
        cert = conf.certfile, conf.keyfile
    else:
        cert = None
    return verify, cert


@classmethod
def from_golix(cls, golix_obj):
    """ Convert the golix object to a lightweight representation.
        """
    return cls(ghid=golix_obj.ghid_dynamic, author=golix_obj.binder,
        counter=golix_obj.counter, target_vector=golix_obj.target_vector,
        frame_ghid=golix_obj.ghid)


def __repr__():
    """Get a string representation """


def discard_context(func, **ctx):
    """Call a callable unable to handle context."""
    return func()


def copy():
    """Copy all items to a new instance and return it."""


def TO_LOWER(expression):
    """
    Converts a string to lowercase, returning the result.
    https://docs.mongodb.com/manual/reference/operator/aggregation/toLower/
    for more details
    :param expression: The string or expression of string
    :return: Aggregation operator
    """
    return {'$toLower': expression}


def pgettext_tip(msgid: str, msgctxt: str):
    """Try to translate the given msgid (with optional msgctxt), if tooltips’ translation is enabled.

    :param msgid: The string to translate.
    :type msgid: str
    :param msgctxt: The translation context (defaults to BLT_I18NCONTEXT_DEFAULT).
    :type msgctxt: str
    :return:  The translated string (or msgid if no translation was found).
    """
    pass


def _transform_positioning(ha, va):
    """Converts matplotlib positioning to pgf node positioning.
    Not quite accurate but the results are equivalent more or less."""
    if ha == 'center' and va == 'center':
        return None
    ha_mpl_to_tikz = {'right': 'east', 'left': 'west', 'center': ''}
    va_mpl_to_tikz = {'top': 'north', 'bottom': 'south', 'center': '',
        'baseline': 'base'}
    return 'anchor={} {}'.format(va_mpl_to_tikz[va], ha_mpl_to_tikz[ha]).strip(
        )


def clearmemo():
    """Clears all function memoizations for autodescribers."""
    for x in globals().values():
        if callable(x) and hasattr(x, 'cache'):
            x.cache.clear()


def remote_addr_from_request(request):
    """
    Returns the correct remote address from the request object. If the
    request was proxied, this correct information is in HTTP_X_FORWARDED_FOR
    """
    if not request:
        raise TypeError('No request passed to function')
    if 'HTTP_X_FORWARDED_FOR' in request.META:
        return request.META['HTTP_X_FORWARDED_FOR']
    else:
        return request.META['REMOTE_ADDR']


def annotate(open_file, contents):
    """
    Add annotation to a single file
    """
    from corpkit.constants import PYTHON_VERSION
    contents = ''.join(contents)
    if PYTHON_VERSION == 2:
        contents = contents.encode('utf-8', errors='ignore')
    open_file.seek(0)
    open_file.write(contents)
    open_file.truncate()


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def size_inshape(module_masks, mask):
    """
    No need to do anything for this ```size``` op
    """
    return None


def lchop(text, beginning):
    """ Removes the beginning from the text if the text starts with it. """
    if text.startswith(beginning):
        return text[len(beginning):]
    return text


def _multi_adamw_update(*data, **kwargs):
    """Update function for AdamW optimizer.

    AdamW is seen as a modification of Adam by decoupling the weight decay from the
    optimization steps taken w.r.t. the loss function.

    Adam update consists of the following steps, where g represents gradient and m, v
    are 1st and 2nd order moment estimates (mean and variance).

    .. math::

     g_t = \\nabla J(W_{t-1})\\\\
     m_t = \\beta_1 m_{t-1} + (1 - \\beta_1) g_t\\\\
     v_t = \\beta_2 v_{t-1} + (1 - \\beta_2) g_t^2\\\\
     W_t = W_{t-1} - \\eta_t (\\alpha \\frac{ m_t }{ \\sqrt{ v_t } + \\epsilon } + wd W_{t-1})

    It updates the weights using::

     m = beta1*m + (1-beta1)*grad
     v = beta2*v + (1-beta2)*(grad**2)
     w -= eta * (learning_rate * m / (sqrt(v) + epsilon) + w * wd)

    Note that gradient is rescaled to grad = rescale_grad * grad. If rescale_grad is NaN, Inf, or 0,
    the update is skipped.

    Defined in src/operator/contrib/adamw.cc:L167

    Parameters
    ----------
    data : NDArray[]
        data
    lrs : tuple of <float>, required
        Learning rates
    beta1 : float, optional, default=0.899999976
        The decay rate for the 1st moment estimates.
    beta2 : float, optional, default=0.999000013
        The decay rate for the 2nd moment estimates.
    epsilon : float, optional, default=9.99999994e-09
        A small constant for numerical stability.
    wds : tuple of <float>, required
        Weight decay augments the objective function with a regularization term that penalizes large weights. The penalty scales with the square of the magnitude of each weight.
    etas : tuple of <float>, required
        Learning rates schedule multiplier
    clip_gradient : float, optional, default=-1
        Clip gradient to the range of [-clip_gradient, clip_gradient] If clip_gradient <= 0, gradient clipping is turned off. grad = max(min(grad, clip_gradient), -clip_gradient).
    num_weights : int, optional, default='1'
        Number of updated weights.

    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 collapse_group_expr(groupx, cols, ret_row):
    """collapses columns matching the group expression. I'm sure this is buggy; look at a real DB's imp of this."""
    for i, col in enumerate(cols.children):
        if col == groupx:
            ret_row[i] = ret_row[i][0]
    return ret_row


def double_middle_drop(progress):
    """
    Returns a linear value with two drops near the middle to a constant value for the Scheduler

    :param progress: (float) Current progress status (in [0, 1])
    :return: (float) if 0.75 <= 1 - p: 1 - p, if 0.25 <= 1 - p < 0.75: 0.75, if 1 - p < 0.25: 0.125
    """
    eps1 = 0.75
    eps2 = 0.25
    if 1 - progress < eps1:
        if 1 - progress < eps2:
            return eps2 * 0.5
        return eps1 * 0.1
    return 1 - progress


@staticmethod
def join(argv):
    """ Join a list of arguments into a command line string """
    raise NotImplementedError


def replicate(item, match):
    """Create tuple of `item` copied `len(match)` times"""
    return (item,) * len(match)


def edge_type_to_class(edge_type):
    """Return the edge class for layout purposes based on the edge type"""
    if 'Amount' in edge_type:
        return 'amount'
    if edge_type in ('Activation', 'Inhibition'):
        return 'activity'
    if edge_type == 'Complex':
        return 'complex'
    else:
        return 'modification'


def howManyAtStart(text, string):
    """ how many times a (sub)string appears at start of text """
    pos = 0
    n = 0
    length = len(string)
    while text[pos:].startswith(string):
        pos += length
        n += 1
    return n


@classmethod
def register(cls, name, value=None):
    """Register a identifier"""
    local_value = cls._identifiers.get(name, None)
    if local_value is None:
        local_value = cls.new(name, value)
    elif value is not None:
        assert value == local_value
    return local_value


def is_enum_namestack(nameStack):
    """Determines if a namestack is an enum namestack"""
    if not nameStack:
        return False
    if nameStack[0] == 'enum':
        return True
    if len(nameStack) > 1 and nameStack[0] == 'typedef' and nameStack[1
        ] == 'enum':
        return True
    return False


def refresh(train, test, real_test=None):
    """
    Returns deep copies of all of the provided DataFrames for easily refreshing or undoing feature engineering
    """
    if real_test is not None:
        return train.copy(deep=True), test.copy(deep=True), real_test.copy(deep
            =True)
    else:
        return train.copy(deep=True), test.copy(deep=True)


def add_atom_selection_arg(parser):
    """
    Add selection optional argument.

    Selection argument is a string that defines the atom selection,
    this is defined by ``-l`` and ``--selection``, and defaults to ``all``.

    Parameters
    ----------
    parser : `argparse.ArgumentParser <https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser>`_
        The argument parser to which add the selection argument.
    """
    parser.add_argument('-l', '--selection', help=
        "Atom selection for the output trajectory. Selection rules are as defined by the MD analysis library used by the client interface. For instructions read the main command-line client description. Defaults to 'all'."
        , default='all', type=str)


def add_oval(pic, x, y, w, h, col):
    """Draw an empty oval of Color col, width w, and height h on Picture pic.
    The upper left corner of the oval is at (x, y)."""
    pic.add_oval(col, x, y, w, h)


def get(isamAppliance, id, check_mode=False, force=False):
    """
    Retrieve a Client Certificate Mapping
    """
    return isamAppliance.invoke_get('Retrieve a Client Certificate Mapping',
        '/wga/client_cert_cdas/{0}'.format(id))


def _truncate_with_offset(resource, value_list, offset):
    """Truncate a list of dictionaries with a given offset.
    """
    if not offset:
        return resource
    offset = offset.lower()
    for i, j in enumerate(value_list):
        if j == offset:
            return resource[i + 1:]
        if j > offset:
            return resource[i:]
    return []


def SetVersionNumber(RevString):
    """Set the subversion version number

    :param str RevString: something like "$Revision: 4155 $"
      that is set by subversion when the file is retrieved from subversion.

    Place ``GSASIIpath.SetVersionNumber("$Revision: 4155 $")`` in every python
    file.
    """
    try:
        RevVersion = int(RevString.split(':')[1].split()[0])
        global version
        version = max(version, RevVersion)
    except:
        pass


def _add(parent, arg):
    """Add the values of the parent and the param."""
    if arg:
        return parent + arg
    return sum(parent)


def has_systemd():
    """Detect if Linux init is systemd."""
    with open('/proc/1/comm', 'r') as init_proc:
        init = init_proc.readline().strip()
        return init == 'systemd'


@staticmethod
def get_path_cost(c, _):
    """Returns the cost for the current path.

        Parameters
        ----------
        c : float
            The current cost for the path.

        Returns
        -------
        float :
            The updated cost.

        """
    return c + 1


def _ipv6_host(host):
    """
    Process IPv6 address literals
    """
    if host.startswith('[') and host.endswith(']'):
        host = host.replace('%25', '%').strip('[]')
    return host


def paths_update():
    """Recalculate paths for selected objects

    """
    pass


def _coalesce_version_id(*args):
    """Helper to coalesce a list of version_ids down to one"""
    version_ids = set(args)
    if None in version_ids:
        version_ids.remove(None)
    if len(version_ids) > 1:
        raise ValueError(
            'Cannot coalesce version_ids where more than one are defined, {}'
            .format(version_ids))
    elif len(version_ids) == 0:
        return None
    else:
        return version_ids.pop()


def _get_first_child(base, tag):
    """Get a child element of the base node with a given tag.

    Args:
        base: The base node element. (lxml node)
        tag: Child elements group tag used to select the elements. (string)

    Returns:
        The first child lxml node element found or None.
    """
    for node in base:
        if node.tag.replace('{http://www.rdml.org}', '') == tag:
            return node
    return None