@classmethod
def is_installed(cls, language=None):
    """Determine if the necessary libraries are installed for this
        communication class.

        Args:
            language (str, optional): Specific language that should be checked
                for compatibility. Defaults to None and all languages supported
                on the current platform will be checked. If set to 'any', the
                result will be True if this comm is installed for any of the
                supported languages.

        Returns:
            bool: Is the comm installed.

        """
    if language == 'python':
        return True
    return False


def get_tenants(session, cloud_name, return_type=None, **kwargs):
    """
    Get all Cloud Tennants

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type cloud_name: str
    :param cloud_name: Cloud Name: i.e: zadaraqa9

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    path = '/api/clouds/{0}/cloud_users.json'.format(cloud_name)
    return session.get_api(path=path, return_type=return_type, **kwargs)


def primitive_plane_add(radius: float=1.0, calc_uvs: bool=False, view_align:
    bool=False, enter_editmode: bool=False, location: float=(0.0, 0.0, 0.0),
    rotation: float=(0.0, 0.0, 0.0), layers: bool=(False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False, False)):
    """Construct a filled planar mesh with 4 vertices

    :param radius: Radius
    :type radius: float
    :param calc_uvs: Generate UVs, Generate a default UV map
    :type calc_uvs: bool
    :param view_align: Align to View, Align the new object to the view
    :type view_align: bool
    :param enter_editmode: Enter Editmode, Enter editmode when adding this object
    :type enter_editmode: bool
    :param location: Location, Location for the newly added object
    :type location: float
    :param rotation: Rotation, Rotation for the newly added object
    :type rotation: float
    :param layers: Layer
    :type layers: bool
    """
    pass


def gid_from_value(attribute: str, groups: list) ->int:
    """Exract the group id from a list of groups whose values match an attribute

    Args:
        attribute (str): the value to match on.
        groups (list): list of groups to match on

    """
    from .exceptions import GroupNotFound
    for group in groups:
        if attribute in group.values():
            return group['id']
    raise GroupNotFound(
        f'No groups in {groups} found with attribute containing {attribute}')


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


def select_linked_pick(deselect: bool=False):
    """(De)select all points linked to the curve under the mouse cursor

    :param deselect: Deselect
    :type deselect: bool
    """
    pass


@classmethod
def get_exchange_name(cls):
    """
        Get exchange name
        :return: Exchange name string
        """
    return 'Gdax'


def expand_record(record, separator='.'):
    """Expand record represented as dict object by treating keys as key paths separated by
    `separator`, which is by default ``.``. For example: ``{ "product.code": 10 }`` will become
    ``{ "product" = { "code": 10 } }``

    See :func:`brewery.collapse_record` for reverse operation.
    """
    result = {}
    for key, value in record.items():
        current = result
        path = key.split(separator)
        for part in path[:-1]:
            if part not in current:
                current[part] = {}
            current = current[part]
        current[path[-1]] = value
    return result


def delete_rule(ruleset_db, rulename):
    """deletes a rule from the ruleset"""
    from src.praxxis.sqlite import connection
    conn = connection.create_connection(ruleset_db)
    cur = conn.cursor()
    foreign_keys = 'PRAGMA foreign_keys = ON'
    delete_rule = 'DELETE FROM "Rules" WHERE Name = ?'
    cur.execute(foreign_keys)
    cur.execute(delete_rule, (rulename,))
    conn.commit()
    conn.close()


def _is_vicon_instance(obj):
    """ Check if obj is an instance of ViconNexus """
    return obj.__class__.__name__ == 'ViconNexus'


def get_stack_status(heat_cli, stack_id):
    """
    Returns the current status of the Heat stack
    :param heat_cli: the OpenStack heat client
    :param stack_id: the ID of the heat stack to retrieve
    :return:
    """
    return heat_cli.stacks.get(stack_id).stack_status


def _var(ctor, default, callback=None):
    """
    Creates a Tkinter variable, initialize it and possibly trace it.

    @param default the variable initial value
    @param callback function to invoke whenever the variable changes its value
    @return the created variable
    """
    var = ctor()
    var.set(default)
    if callback:
        var.trace('w', callback)
    return var


def softmax(input, dim=-1):
    """Apply the softmax function on given dimension.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    dim : int
        The dimension along which to compute softmax.

    Returns
    -------
    Tensor
        The output tensor.
    """
    pass


def location_dict_to_geocoord_dict(location_dict):
    """
    Converts a dictionary of {users : geopy location objects} to {users : [longitude, latitude]}
    """
    geocoord_dict = {}
    for user, location in location_dict.items():
        geocoord_dict[user] = [location.longitude, location.latitude]
    return geocoord_dict


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 value(x):
    """Return the value

    Returns a complex number if ``x`` is an uncertain complex number

    Returns a real number if ``x`` is an uncertain real number

    Returns ``x`` otherwise.

    **Example**::

        >>> un = ureal(3,1)
        >>> value(un)
        3.0
        >>> un.x
        3.0

    """
    try:
        return x.x
    except AttributeError:
        return x


def maybe_round(val, precision=None):
    """
    Potentially round a number or an array of numbers to a given precision.

    Parameters
    ----------
    val : numeric or numpy.ndarray
        The number or array of numbers to round.
    precision : int, default None
        The precision at which to perform rounding. If None is provided,

    Returns
    -------
    maybe_rounded_val : the number or array of numbers rounded to a
                        given precision, if provided. Otherwise, the
                        original input is returned.
    """
    if precision is None:
        return val
    if hasattr(val, 'round'):
        return val.round(precision)
    else:
        return round(val, precision)


@classmethod
def _fromJSON(cls, jsonobject):
    """Generates a new instance of :class:`maspy.core.Fgi` from a decoded
        JSON object (as generated by :func:`maspy.core.Fgi._reprJSON()`).

        :param jsonobject: decoded JSON object

        :returns: a new instance of :class:`Fgi`
        """
    newInstance = cls(None)
    newInstance.__dict__.update(jsonobject)
    return newInstance


def list_instances(compute, project, zone):
    """ List Compute instances inside a zone.
    """
    result = compute.instances().list(project=project, zone=zone).execute()
    return result['items'] if 'items' in result else None


def execute_func(function, **kwargs):
    """
	Take the function and the args in parameters,
	and return the result of the function with the good args
	"""
    send = {}
    for var in function.__code__.co_varnames[:function.__code__.co_argcount]:
        if var in kwargs and kwargs[var]:
            send[var] = kwargs[var]
        else:
            send[var] = None
    return function(**send)


def time_interval_since(date_1, date_2):
    """ Calculate seconds between two times

    Arguments:
    date_1 -- datetime object #1
    date_2 -- datetime object #2

    Output:
    Num of seconds between the two times (with a sign)
    """
    return (date_1 - date_2).total_seconds()


def parse_image_meta_graph(meta):
    """Parses a tensor that contains image attributes to its components.
    See compose_image_meta() for more details.
    meta: [batch, meta length] where meta length depends on NUM_CLASSES
    Returns a dict of the parsed tensors.
    """
    image_id = meta[:, (0)]
    original_image_shape = meta[:, 1:4]
    image_shape = meta[:, 4:7]
    window = meta[:, 7:11]
    scale = meta[:, (11)]
    active_class_ids = meta[:, 12:]
    return {'image_id': image_id, 'original_image_shape':
        original_image_shape, 'image_shape': image_shape, 'window': window,
        'scale': scale, 'active_class_ids': active_class_ids}


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

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
        {
            "properties": {
                "title_analyzed": {
                  "type": "text",
                  "index": true
                }
           }
        } """
    return {'items': mapping}


def create_egress_only_internet_gateway(DryRun=None, VpcId=None,
    ClientToken=None):
    """
    [IPv6 only] Creates an egress-only Internet gateway for your VPC. An egress-only Internet gateway is used to enable outbound communication over IPv6 from instances in your VPC to the Internet, and prevents hosts outside of your VPC from initiating an IPv6 connection with your instance.
    See also: AWS API Documentation

    :example: response = client.create_egress_only_internet_gateway(
        DryRun=True|False,
        VpcId='string',
        ClientToken='string'
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type VpcId: string
    :param VpcId: [REQUIRED]
            The ID of the VPC for which to create the egress-only Internet gateway.

    :type ClientToken: string
    :param ClientToken: Unique, case-sensitive identifier you provide to ensure the idempotency of the request. For more information, see How to Ensure Idempotency .

    :rtype: dict
    :return: {
        'EgressOnlyInternetGateway': {
            'EgressOnlyInternetGatewayId': 'string',
            'Attachments': [
                {
                    'VpcId': 'string',
                    'State': 'attaching'|'attached'|'detaching'|'detached'
                },
            ]
        },
        'ClientToken': 'string'
    }

    """
    pass


def is_validated(validation: str=None) ->str:
    """Check if validated."""
    if validation == 'Validée':
        validated = 'YES'
    elif validation == 'Non validée':
        validated = 'NO'
    else:
        validated = 'Not yet'
    return validated


def add_position(p, name, pos):
    """Add a position to a portfolio.

    Parameters
    ----------
    p : alphapy.Portfolio
        Portfolio that will hold the position.
    name : int
        Unique identifier for the position, e.g., a stock symbol.
    pos : alphapy.Position
        New position to add to the portfolio.

    Returns
    -------
    p : alphapy.Portfolio
        Portfolio with the new position.

    """
    if name not in p.positions:
        p.positions[name] = pos
    return p


def dataframe_to_bigquery(df):
    """Writes a DataFrame to Big Query. Column names will be downcased and
    all non-alphanumeric characters converted to underscores."""
    df.columns = df.columns.str.strip().str.lower().str.replace('[^\\w]', '_')


@classmethod
def apply(cls, args, run):
    """
        Modify the current Run base on this command-line option.

        This function is executed after constructing the Run object, but
        before actually starting it.

        Parameters
        ----------
        args : bool | str
            If this command-line option accepts an argument this will be value
            of that argument if set or None.
            Otherwise it is either True or False.
        run :  sacred.run.Run
            The current run to be modified

        """
    pass


@staticmethod
def op(value, comparable):
    """Return whether `value` contains `comparable`."""
    try:
        return comparable in value
    except (TypeError, ValueError):
        return False


def extract_header(tgt_file):
    """
    Collects lines that don't have a timestep and returns them.

    :param tgt_file: The file to process.
    :return: The headers for the given file.
    """
    with open(tgt_file) as tf:
        h_lines = []
        for t_line in tf:
            s_line = t_line.strip().split()
            if len(s_line) < 2:
                h_lines.append(t_line)
                continue
            try:
                int(s_line[0])
                break
            except ValueError:
                h_lines.append(t_line)
        return h_lines


@staticmethod
def permalink(mlist, msg):
    """See `IArchiver`."""
    return None


@staticmethod
def cmp_item(x, y):
    """ compares items by their update datetime """
    if x.has_key('updated') and y.has_key('updated'):
        return x['updated'] < y['updated'] and 1 or x['updated'] > y['updated'
            ] and -1 or 0
    elif x.has_key('updated') and not y.has_key('updated'):
        return -1
    elif not x.has_key('updated') and y.has_key('updated'):
        return 1
    else:
        return 0


def get_preferred_sparse_format():
    """Get the preferred sparse matrix format supported by the backend.

    Different backends have their preferred backend. This info is useful when
    constructing a sparse matrix.

    Returns
    -------
    string
        the name of the preferred sparse matrix format.
    """
    pass


@classmethod
def autorenew_activate(cls, fqdn):
    """Activate autorenew"""
    fqdn = fqdn.lower()
    result = cls.call('domain.autorenew.activate', fqdn)
    return result


def pene(geno, age, ind):
    """Define an age-dependent penetrance function"""
    if age < 16:
        return 0
    if ind.affected():
        return 1
    return (0.0, 0.001 * age, 0.001 * age)[sum(geno)]


def sec_to_hms(seconds, ms_places=5, as_str=False):
    """Convert `seconds` to hours, minutes, and seconds

    Parameters
    ----------
    seconds: Integer
        Number of total seconds to be converted to hours, minutes, seconds format
    ms_places: Integer, default=5
        Rounding precision for calculating number of seconds
    as_str: Boolean, default=False
        If True, return string "{hours} h, {minutes} m, {seconds} s". Else, return a triple

    Returns
    -------
    String or tuple
        If `as_str=True`, return a formatted string containing the hours, minutes, and seconds.
        Else, return a 3-item tuple of (hours, minutes, seconds)

    Examples
    --------
    >>> assert sec_to_hms(55, as_str=True) == '55 s'
    >>> assert sec_to_hms(86400) == (24, 0, 0)
    >>> assert sec_to_hms(86400, as_str=True) == '24 h'
    >>> assert sec_to_hms(86370) == (23, 59, 30)
    >>> assert sec_to_hms(86370, as_str=True) == '23 h, 59 m, 30 s'
    """
    t_hour, temp_sec = divmod(seconds, 3600)
    t_min, t_sec = divmod(temp_sec, 60)
    t_sec = round(t_sec, ms_places)
    if as_str is True:
        result = ''
        if t_hour != 0:
            result += '{} h, '.format(t_hour)
        if t_min != 0:
            result += '{} m, '.format(t_min)
        if t_sec != 0:
            result += '{} s'.format(t_sec)
        return result.strip(', ')
    else:
        return t_hour, t_min, t_sec


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def humansize(num, power=1024, sep=' ', precision=2, unit=None):
    """Converts raw bytes to a human friendly format."""
    if power == 1024:
        units = ['B  ', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
    else:
        units = ['B ', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
    if unit in units:
        if power == 1024:
            num = num >> units.index(unit) * 10
        else:
            div = power ** units.index(unit)
            num /= float(div)
        return f'{num:.{precision}f}{sep}{unit}'
    for unit in units[:-1]:
        if abs(round(num, precision)) < power:
            return f'{num:.{precision}f}{sep}{unit}'
        num /= float(power)
    return f'{num:.{precision}f}{sep}{units[-1]}'


def find_first_non_empty_col(reader, row):
    """ Finds index of the first non-empty column.

        Args:
            reader (CSVReader or XLSReader): object that implements
                interface for reading input data.
            row (list of values): list of values stored in a row.

        Returns:
            int: index of the first non-empty column.
    """
    for col_index, cell in enumerate(row):
        if reader.cell_is_not_empty(cell) and reader.cell_is_not_blank(cell):
            return col_index


def rad2tex(liste):
    """Prépare l'écriture de radians en latex."""
    if liste[0] == 0:
        frac = '$0$'
    elif liste[0] == liste[1]:
        frac = '$\\pi$'
    elif liste[0] == -liste[1]:
        frac = '$-\\pi$'
    elif liste[0] == 1:
        frac = '$\\dfrac{\\pi}{' + str(liste[1]) + '}$'
    elif liste[0] == -1:
        frac = '$\\dfrac{-\\pi}{' + str(liste[1]) + '}$'
    elif liste[1] == -1:
        frac = '$' + str(-liste[0]) + '\\pi$'
    elif liste[1] == 1:
        frac = '$' + str(liste[0]) + '\\pi$'
    else:
        frac = '$\\dfrac{' + str(liste[0]) + '\\pi}{' + str(liste[1]) + '}$'
    return frac


def float_or_str(flt_or_str):
    """Float value from string or number"""
    if isinstance(flt_or_str, str):
        flt_or_str = flt_or_str.strip()
        try:
            value = float(flt_or_str)
        except ValueError:
            return flt_or_str
        else:
            return value
    else:
        return float(flt_or_str)


def _process_2D_plot_args(args, gridding_dz=1):
    """
    Processes input to the plotting class functions. Allows plots to receive
    one (2D) or three (1D) input arguements.
    """
    from numpy import array, ma, nan, ndarray
    from pandas import DataFrame, Series
    from xarray import DataArray
    from .mapping import grid_data
    from .helpers import GliderToolsError
    name = ''
    if len(args) == 3:
        x = array(args[0])
        y = array(args[1]).astype(float)
        z = args[2].copy()
        if isinstance(z, ma.MaskedArray):
            z[z.mask] = nan
        elif isinstance(z, DataArray):
            name = z.name if z.name is not None else ''
            unit = ' [{}]'.format(z.units) if 'units' in z.attrs else ''
            name = name + unit
            z = ma.masked_invalid(array(z)).astype(float)
        else:
            z = ma.masked_invalid(array(z)).astype(float)
        if (x.size == y.size) & (len(z.shape) == 1):
            df = grid_data(x, y, z, interp_lim=6, verbose=False,
                return_xarray=False)
            x = df.columns
            y = df.index
            z = ma.masked_invalid(df.values)
        return x, y, z, name
    elif len(args) == 1:
        z = args[0]
        if isinstance(z, DataArray):
            name = z.name if z.name is not None else ''
            unit = ' [{}]'.format(z.units) if 'units' in z.attrs else ''
            name = name + unit
            if z.ndim == 1:
                raise GliderToolsError(
                    'Please provide gridded DataArray or x and y coordinates')
            elif z.ndim == 2:
                z = z.to_series().unstack()
            elif z.ndim > 2:
                raise GliderToolsError(
                    'GliderTools plotting currently only supports 2 dimensional plotting'
                    )
        elif isinstance(z, (ndarray, Series)):
            if z.ndim == 2:
                z = DataFrame(z)
            else:
                raise IndexError('The input must be a 2D DataFrame or ndarray')
        x = z.columns.values
        y = z.index.values
        z = ma.masked_invalid(z.values).astype(float)
        return x, y, z, name


def can_comment(request, entry):
    """Check if current user is allowed to comment on that entry."""
    return entry.allow_comments and (entry.allow_anonymous_comments or
        request.user.is_authenticated())


def combine(word_list, window=2):
    """构造在window下的单词组合，用来构造单词之间的边。

    Keyword arguments:
    word_list  --  list of str, 由单词组成的列表。
    windows    --  int, 窗口大小。
    """
    if window < 2:
        window = 2
    for x in range(1, window):
        if x >= len(word_list):
            break
        word_list2 = word_list[x:]
        res = zip(word_list, word_list2)
        for r in res:
            yield r


def strip_and_replace_backslashes(path: str) ->str:
    """
    >>> strip_and_replace_backslashes('c:\\\\test')
    'c:/test'
    >>> strip_and_replace_backslashes('\\\\\\\\main\\\\install')
    '//main/install'
    """
    path = path.strip().replace('\\', '/')
    return path


def _sam_header_to_ref_list(header):
    """Modified code from Peter Cock's [BamWriter](https://github.com/peterjc/biopython/blob/SamBam2015/Bio/Sequencing/SamBam/__init__.py#L1714)

    Removes blank lines, ensures trailing newlines, spots some errors.

    """
    references = []
    for line in header.split('\n'):
        if line.startswith('@SQ\t'):
            r = None
            l = None
            for part in line[3:].rstrip().split('\t'):
                if part.startswith('SN:'):
                    r = part[3:]
                elif part.startswith('LN:'):
                    l = int(part[3:])
            if r is None or l is None:
                raise ValueError(
                    'Malformed @SQ header (SN and LN required):\n%r' % line)
            references.append((r, l))
    return references


def isString(s):
    """Return True if s is any string, but not bytes."""
    return isinstance(s, str)


def delete_parameter(Name=None):
    """
    Delete a parameter from the system.
    See also: AWS API Documentation

    :example: response = client.delete_parameter(
        Name='string'
    )

    :type Name: string
    :param Name: [REQUIRED]
            The name of the parameter to delete.

    :rtype: dict
    :return: {}

    """
    pass


def verify_filename(filename: str) ->str:
    """ Check file name is accurate

    Args:
        filename (str): String for file name with extension

    Raises:
        ValueError: Provide filename with extensions
        ValueError: Specify a length > 0

    Returns:
        str: Verified file name
    """
    if len(filename) <= 0:
        raise ValueError('Specify filename')
    if isinstance(filename, str) and '.' not in filename or len(filename.
        split('.')[1]) <= 0:
        raise ValueError('`filename` must be provided & have an extension')
    return filename


def has_multiple_pks(model):
    """
        Return True, if the model has more than one primary key
    """
    if not hasattr(model, '_sa_class_manager'):
        raise TypeError('model must be a sqlalchemy mapped model')
    return len(model._sa_class_manager.mapper.primary_key) > 1


def asciiHexDecode(stream):
    """
        Method to decode streams using hexadecimal encoding

        @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
    """
    eod = '>'
    decodedStream = ''
    char = ''
    index = 0
    while index < len(stream):
        c = stream[index]
        if c == eod:
            if len(decodedStream) % 2 != 0:
                char += '0'
                try:
                    decodedStream += chr(int(char, base=16))
                except:
                    return -1, 'Error in hexadecimal conversion'
            break
        elif c.isspace():
            index += 1
            continue
        char += c
        if len(char) == 2:
            try:
                decodedStream += chr(int(char, base=16))
            except:
                return -1, 'Error in hexadecimal conversion'
            char = ''
        index += 1
    return 0, decodedStream


def convert_dict_to_list(dictionary):
    """
    Accepts a dictionary and return a list of lists.
    @example:   input : { "python" : 50, "json": 100, "text" : 20}
                output : [['python', 50], ['json', 100], ['text', 20]]
    """
    output_list = []
    for k in dictionary.keys():
        output_list.append([k, dictionary[k]])
    return output_list


def findout_subsets(bigset, sub_keylist):
    """
    findout sub dictionary of a dictionary with given list of keys.
    """
    output = {}
    for key in sub_keylist:
        if key in bigset.keys():
            output[key] = bigset[key]
    return output


def tzname():
    """Return the timezone name.

        If tzinfo is None, returns None, else returns self.tzinfo.tzname(None),
        or raises an exception if the latter doesn't return None or a string
        object.
        """


def LorentzTerm(w, w0, gamma, s):
    """
	A single term in a Lorentz Oscillator sum.

	Parameters
	----------

	w:		array-like, frequency at which to evaluate the response (rad/s)

	w0:		scalar, resonance frequency (rad/s)

	gamma:	scalar, width of the resonance (rad/s)

	s:		scalar, strength of the response (unitless)
	"""
    res = s * w0 ** 2 / (w0 ** 2 - w ** 2 - 1.0j * gamma * w)
    return res


@classmethod
def _follow_exprs(cls, exprs, follow_mem=False, follow_call=False):
    """Extracts subnodes from exprs and returns followed/non followed
        expressions according to @follow_mem/@follow_call

        """
    follow, nofollow = set(), set()
    for expr in exprs:
        expr.visit(lambda x: cls.get_expr(x, follow, nofollow), lambda x:
            cls.follow_expr(x, follow, nofollow, follow_mem, follow_call))
    return follow, nofollow


def p_UnionMemberTypes_empty(p):
    """UnionMemberTypes : """
    p[0] = []


def _fit_quality(column, weights, constraint):
    """
    Calculate quality of fit metric for a column of the frequency table.
    (The 𝛿 parameter described in the IPU paper.)

    Parameters
    ----------
    column : 1D array
        Non-zero elements of a column of a frequency table.
        Must have the same length as `weights`.
    weights : 1D array
        Weights corresponding to the household rows in `column`.
        Must have the same length as `column`.
    constraint : float
        Target marginal constraint for this column.

    Returns
    -------
    quality : float

    """
    return abs((column * weights).sum() - constraint) / constraint


def wrap(value):
    """Wrap value around -200 and 200."""
    return value


def check_new_user(username):
    """ Boolean return when username matches ``newcmds`` ini cfg. """
    from x84.bbs import get_ini
    matching = get_ini(section='matrix', key='newcmds', split=True)
    allowed = get_ini(section='nua', key='allow_apply', getter='getboolean')
    return allowed and username in matching


def _update_coefs(x, tau, gradfx, prox, f, g, beta, fk):
    """Non-monotone line search

    parameters
    ----------
    x: ndarray
        current coefficients
    tau: float
        step size
    gradfx: ndarry
        gradient operator evaluated at current coefficients
    prox: function handle
        proximal operator of :math:`g(x)`
    f: callable
        smooth differentiable function, :math:`f(x)`
    g: callable
        non-smooth function, :math:`g(x)`
    beta: float
        backtracking parameter
    fk: float
        maximum of previous function values

    returns
    -------
    z: ndarray
        next coefficients
    """
    x_hat = x - tau * gradfx
    z = prox(x_hat, tau)
    fz = f(z)
    count = 0
    while fz > fk + (gradfx * (z - x)).sum() + ((z - x) ** 2).sum() / (2 * tau
        ):
        count += 1
        tau = beta * tau
        x_hat = x - tau * gradfx
        z = prox(x_hat, tau)
        fz = f(z)
    sg = (x_hat - z) / tau
    return z, fz, sg, tau, count


def assert_called_once_with(_mock_self, *args, **kwargs):
    """assert that the mock was called exactly once and with the specified
        arguments."""
    self = _mock_self
    if not self.call_count == 1:
        msg = 'Expected to be called once. Called %s times.' % self.call_count
        raise AssertionError(msg)
    return self.assert_called_with(*args, **kwargs)


def is_server_error(status):
    """
    Check if HTTP status code is server error.

    :param status: http status code
    :returns: True if status is server error, else False
    """
    return 500 <= status <= 599


def menu(items, heading):
    """Takes list of dictionaries and prints a menu.
        items parameter should be in the form of a list, containing
        dictionaries with the keys: {"key", "text", "function"}.

        Typing the key for a menuitem, followed by return, will run
        "function".
    """
    heading = '\n' * 5 + heading
    while True:
        keydict = {}
        print(heading)
        for item in items:
            menustring = '  ' + item['key'] + ' ' + item['text']
            keydict[item['key']] = item['function']
            print(menustring)
        key = input('\nType key and Return (q to quit): ').strip()
        if key.lower() == 'q':
            return
        else:
            try:
                ret = keydict[key]()
                if ret:
                    return 1
            except KeyError:
                continue


def get_versions(sort_attribute='id'):
    """Return a list of versions.

        If ``sort_attribute`` is False, no sorting is done. By default
        it sorts on ``id`` converted to int (so you receive
        [0,1,2,3,...] instead of [0,1,10,2,3,...]).
        """


def plot_target(target, ax):
    """Add the target to the plot"""
    ax.scatter(target[0], target[1], target[2], c='red', s=80)


def select_by_states(pathways, states):
    """Returns one pathway which goes through a given pattern of states

    Returns unique pathway which goes through a given pattern of states
    or does not return anything

    The following diagram

            |12       12|
        --->|-----------|
            |           |
            |48       12|      2.0
        --->|-----------|
            |           |
            |21       12|      0.0
          >>|***********|<<
            |           |
            |6         6|      0.0
        --->|-----------|
            |           |
            |0         6|      -2.0
            |-----------|<---
            |           |
            |0         0|

    turns into the following tuple

    ((0,0), (0,6), (6,6), (21, 12), (48, 12), (12,12))

    Parameters
    ----------

    pathways : list, tuple
        List of tuple of states to analyze

    states : list, tuple
        List of dyads which describe the states involved in a given Liouville
        pathway. States are listed from left to right, from bottom to the top

    """
    for pw in pathways:
        ch = -1
        for k in range(pw.states.shape[0]):
            if not (pw.states[k, 0] == states[k + 1][0]) & (pw.states[k, 1] ==
                states[k + 1][1]):
                break
            ch += 1
        if ch == k:
            return pw


def _w_idx(str_, idx):
    """Append number to string. Used to generate PlotData labels"""
    return str_ + str(idx)


def get_exception_name(output):
    """
    Reads the traceback from a Python program and grabs the
    fully qualified exception name.
    """
    lines = output.split('\n')
    cue = False
    result = '(unknown)'
    for line in lines[1:]:
        line = line.rstrip()
        if not line:
            continue
        if line[0] == ' ':
            cue = True
            continue
        if cue:
            cue = False
            return line.partition(':')[0]
    return result


def hits2ints(hits, scov):
    """ filter hits by scoverage; convert to intervals """
    intervals = []
    for hit in hits:
        if hit.scov_modified >= scov:
            intervals.append([hit.qstart, hit.qend, hit.sstrand])
    return intervals


def is_policy(obj, check_updateable=False):
    """

    Check whether an object is an :term:`(updateable) policy <updateable
    policy>`.

    Parameters
    ----------
    obj

        Object to check.

    check_updateable : bool, optional

        If the obj is a policy, also check whether or not the policy is
        updateable.

    Returns
    -------
    bool

        Whether ``obj`` is a (updateable) policy.

    """
    from ..policies.base import BasePolicy
    from ..core.base import BaseUpdateablePolicy
    if check_updateable:
        return isinstance(obj, BaseUpdateablePolicy)
    return isinstance(obj, BasePolicy)


def leap_years_before(y, calendar):
    """Return number of years before input year that are leap."""
    y -= 1
    if 'gregorian' == calendar:
        return y * 0.2425
    elif 'julian' == calendar:
        return y / 4
    elif 'leap' == calendar:
        return y
    else:
        return 0


def pval(f, c):
    """Get the positive value, otherwise zero.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the column ``c``.
    c : str
        Name of the column in the dataframe ``f``.

    Returns
    -------
    new_val : float
        Positive value or zero.

    """
    new_val = f[c] if f[c] > 0 else 0
    return new_val


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


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

        :param PaperContentRenameDetails val:
        :rtype: EventDetails
        """
    return cls('paper_content_rename_details', val)


def numberOfDaysInYear(dt):
    """calculate number of day of the year of the given datetime"""
    if dt.isLeapYear():
        return 366
    return 365


def identity(value):
    """Identity function."""
    return value


def _mean(listvalue):
    """
	The mean value of the list data.
	:param listvalue:
	:return:
	"""
    return sum(listvalue) / len(listvalue)


def ebs_optimized_supported(instance_type):
    """
    >>> ebs_optimized_supported('c3.xlarge')
    True
    >>> ebs_optimized_supported('t2.micro')
    False
    """
    return instance_type in ('c1.large', 'c3.xlarge', 'c3.2xlarge',
        'c3.4xlarge', 'c4.large', 'c4.xlarge', 'c4.2xlarge', 'c4.4xlarge',
        'c4.8xlarge', 'd2.xlarge', 'd2.2xlarge', 'd2.4xlarge', 'd2.8xlarge',
        'g2.2xlarge', 'i2.xlarge', 'i2.2xlarge', 'i2.4xlarge', 'm1.large',
        'm1.xlarge', 'm2.2xlarge', 'm2.4xlarge', 'm3.xlarge', 'm3.2xlarge',
        'r3.xlarge', 'r3.2xlarge', 'r3.4xlarge')


def xecm(conn, s, data):
    """ for datainserts data can be tuple or dict """
    c = conn.cursor()
    c.executemany(s, data)
    conn.commit()
    return c


def test_rar(archive, compression, cmd, verbosity, interactive):
    """Test a RAR archive."""
    cmdlist = [cmd, 't']
    if not interactive:
        cmdlist.extend(['-p-', '-y'])
    cmdlist.extend(['--', archive])
    return cmdlist


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

        :param SharedContentViewDetails val:
        :rtype: EventDetails
        """
    return cls('shared_content_view_details', val)


def get_referer(req, replace_ampersands=False):
    """ Return the referring page of a request.
    Referer (wikipedia): Referer is a common misspelling of the word
    "referrer"; so common, in fact, that it made it into the official
    specification of HTTP. When visiting a webpage, the referer or
    referring page is the URL of the previous webpage from which a link was
    followed.
    @param req: request
    @param replace_ampersands: if 1, replace & by & in url
                               (correct HTML cannot contain & characters alone)
    """
    try:
        referer = req.headers_in['Referer']
        if replace_ampersands == 1:
            return referer.replace('&', '&')
        return referer
    except KeyError:
        return ''


def list2string(lista):
    """Covierte lista a string"""
    if len(lista) == 0:
        return ''
    if str(lista[0].__class__) in ["<class 'int'>", "<class 'float'>"]:
        resultado = ''
        for l in lista:
            resultado = resultado + str(l) + ', '
        return resultado[:-2]
    elif str(lista[0].__class__) in ["<class 'str'>"]:
        resultado = ''
        for l in lista:
            resultado = resultado + "'" + str(l) + "', "
        return resultado[:-2]


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


def deserialize_key(key: bytes) ->str:
    """ Deserializes a row key

    :param key: bytes
    :return: str
    """
    return key.decode()


@classmethod
def registered_names(cls):
    """Get all names of |Device| objects initialized so far."""
    return cls._registry.keys()


def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
    """Unsets a cookie by name, by default over all domains and paths.

    Wraps CookieJar.clear(), is O(n).
    """
    clearables = []
    for cookie in cookiejar:
        if cookie.name != name:
            continue
        if domain is not None and domain != cookie.domain:
            continue
        if path is not None and path != cookie.path:
            continue
        clearables.append((cookie.domain, cookie.path, cookie.name))
    for domain, path, name in clearables:
        cookiejar.clear(domain, path, name)


def identity(elem):
    """Return the argument itself."""
    return elem


def string_to_int(s):
    """Convert a string of bytes into an integer, as per X9.62."""
    result = 0
    for c in s:
        if not isinstance(c, int):
            c = ord(c)
        result = 256 * result + c
    return result


def words(zelf, *args, **kwargs):
    """ get the arguments of the txt attribute. """
    if 'txt' in zelf:
        return zelf.txt.split()


def add_link(req, rel, href, title=None, mimetype=None, classname=None, **attrs
    ):
    """Add a link to the chrome info that will be inserted as <link> element in
    the <head> of the generated HTML
    """
    linkid = '%s:%s' % (rel, href)
    linkset = req.chrome.setdefault('linkset', set())
    if linkid in linkset:
        return
    link = {'href': href, 'title': title, 'type': mimetype, 'class': classname}
    link.update(attrs)
    links = req.chrome.setdefault('links', {})
    links.setdefault(rel, []).append(link)
    linkset.add(linkid)


def keplermag_to_sdssr(keplermag, kic_sdssg, kic_sdssr):
    """Converts magnitude measurements in Kepler band to SDSS r band.

    Parameters
    ----------

    keplermag : float or array-like
        The Kepler magnitude value(s) to convert to fluxes.

    kic_sdssg,kic_sdssr : float or array-like
        The SDSS g and r magnitudes of the object(s) from the Kepler Input
        Catalog. The .llc.fits MAST light curve file for a Kepler object
        contains these values in the FITS extension 0 header.

    Returns
    -------

    float or array-like
        SDSS r band magnitude(s) converted from the Kepler band magnitude.

    """
    kic_sdssgr = kic_sdssg - kic_sdssr
    if kic_sdssgr < 0.8:
        kepsdssr = (keplermag - 0.2 * kic_sdssg) / 0.8
    else:
        kepsdssr = (keplermag - 0.1 * kic_sdssg) / 0.9
    return kepsdssr


def Season(ID, **kwargs):
    """
  Returns the season number for a given target.

  """
    raise NotImplementedError('This mission is not yet supported.')


def lambd_H3PO4_K_PS76(T, P):
    """n-c: phosphoric-acid potassium [PS76]."""
    lambd = -0.07
    valid = T == 298.15
    return lambd, valid


def group_link(object: str='Object'):
    """Link Object to Group in Outliner

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


@classmethod
def map(cls, function, source, *otherSources):
    """
    Apply a function to every defined attribute (or item) of a source object.
    Construct an Ens object with attributes of same names, which values are
    results of the applied function.

    If multiple source objects are given, the function must accept that many
    positional arguments and is applied for every attribute which is defined
    for at least one source object. Subsequent arguments of the function are
    values of the attribute of corresponding source objects.

    :param function: the function to be applied
    :type function: callable

    :param source: the source object
    :type source: Ens or dict

    :param *otherSources: other source objects

    :return: the constructed object
    :rtype: Ens
    """
    return cls.__map(function, source, *otherSources)


def _uncapitalize(name: str):
    """ Uncapitalize the first letter of the name, e.g. for use as an ASP constant """
    return name[0].lower() + name[1:]


@staticmethod
def format_num(n):
    """
        Intelligent scientific notation (.3g).

        Parameters
        ----------
        n  : int or float or Numeric
            A Number.

        Returns
        -------
        out  : str
            Formatted number.
        """
    f = '{0:.3g}'.format(n).replace('+0', '+').replace('-0', '-')
    n = str(n)
    return f if len(f) < len(n) else n


def _same_type(type1, type2):
    """Check if type1 is the same as type2."""
    return type1.qname() == type2.qname()


@classmethod
def start_all(kls, num, *args, **kwargs):
    """
        Create and start `num` workers. Arguments are passed to the worker's
        __init__ function.
        """
    workers = [kls(*args, id=id, **kwargs) for id in range(1, num + 1)]
    for worker in workers:
        worker.start()
    return workers


@staticmethod
def module_repr(m):
    """Return repr for the module.

        The method is deprecated.  The import machinery does the job itself.

        """
    return '<module {!r} (frozen)>'.format(m.__name__)


def cbrt(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise cube-root value of the input.

    .. math::
       cbrt(x) = \\sqrt[3]{x}

    Example::

       cbrt([1, 8, -125]) = [1, 2, -5]

    The storage type of ``cbrt`` output depends upon the input storage type:

       - cbrt(default) = default
       - cbrt(row_sparse) = row_sparse
       - cbrt(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_pow.cc:L216

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

    name : string, optional.
        Name of the resulting symbol.

    Returns
    -------
    Symbol
        The result symbol.
    """
    return 0,


def add_lists(*args):
    """
    Append lists. This is trivial but it's here for symmetry with add_dicts
    """
    out = []
    for arg in args:
        out.extend(arg)
    return out


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


@classmethod
def findAll(cls, db=None):
    """Find all and return all instances of the class.

        returns:
            objects (list): ModelBase instances if found else None.
        """
    __db = db if db else cls.__db
    results = __db[cls.__collection__].find()
    return list(cls.generateInstances(results))


@classmethod
def _on_stop(cls):
    """
        Hook to allow subclasses to add extra behaviour to stopping.
        """
    pass


def select_same_collection(collection: str=''):
    """Select object in the same collection

    :param collection: Collection, Name of the collection to select
    :type collection: str
    """
    pass


def compose(bb1, bb2):
    """Construct a value of Compose value type.

    bb1, bb2 -- serialised form of a property value (bytes-like objects)

    (This is only needed if the type of the first value permits colons.)

    """
    return bb1.replace(b':', b'\\:') + b':' + bb2


def scrape_result_count(soup):
    """Scrapes the result count from an Archive-It results page stored in the
    BeautifulSoup object `soup`.
    """
    try:
        pagestring = soup.find_all('div', 'paginator')[0].text
        result_count = pagestring[pagestring.find('(') + 1:].replace(
            ' Total Results', '').rstrip(')')
        result_count = pagestring[pagestring.find('(') + 1:pagestring.find(
            ' Total Results')]
        result_count = result_count.replace(',', '')
    except IndexError:
        result_count = None
    return result_count


def kg2lbs(mass_kg):
    """Convert mass value from kg to lbs"""
    return mass_kg / 0.453592


@staticmethod
def _format_set(values) ->list:
    """
        Formatting list of values in the event of IN operation
        :param values: str
        :return: list
        """
    values = values.values if hasattr(values, 'values') else values
    return list(map('{}'.format, values))


def construct_policy(mode, name, value='', vtype=''):
    """Map the mode and return a list containing the policy dictionary."""
    default = {'policy_type': 'unknown'}
    policy_map = {'set_reg_value': {'policy_type': 'regpol'},
        'delete_reg_value': {'policy_type': 'regpol', 'action': 'DELETE'},
        'set_secedit_value': {'policy_type': 'secedit'}}
    mapped = policy_map.get(mode, default)
    mapped['key'] = name
    mapped['name'] = name
    mapped['value'] = value
    mapped['vtype'] = vtype
    return [mapped]


@staticmethod
def setup_command_line(parser):
    """Setup the command line options for clique-coloring formula

        Arguments:
        - `parser`: parser to load with options.
        """
    parser.add_argument('n', metavar='<n>', type=int, help='Number of vertices'
        )
    parser.add_argument('k', metavar='<k>', type=int, help='Clique size')
    parser.add_argument('c', metavar='<c>', type=int, help='Coloring size')


@staticmethod
def equal(series1, series2):
    """Check equality - same instance.

        Parameters
        ----------
        series1 : TimeSeries
            A time series
        series2 : TimeSeries
            Another time series

        Returns
        -------
        bool
            Are the two the same instance?
        """
    return bool(series1._data is series2._data and series1._collection is
        series2._collection)


def _convert_cell_timer(cell_time_lst):
    """
    Converts a the cell timings list returned by the python extensions
    into a more user-friendly numpy structured array.

    The fields correspond to the C ``struct api_cell_timings`` defined
    in ``utils/defs.h``.

    Returns:
    --------

    cell_times : numpy structured array
        The following fields are present in the ``cell_times``:

        N1 -> number of particles in cell 1
        N2 -> number of particles in cell 2
        time_in_ns -> time taken to compute all pairs between two cells
                      (cellidx1, cellidx2)
        cellidx1, cellidx2 -> the 1-D index for the two cells
        tid -> thread-id that computed the pairs (identically 0 for
               serial/single-threaded runs)

    """
    import numpy as np
    from future.utils import bytes_to_native_str
    dtype = np.dtype([(bytes_to_native_str(b'N1'), np.int64), (
        bytes_to_native_str(b'N2'), np.int64), (bytes_to_native_str(
        b'time_in_ns'), np.int64), (bytes_to_native_str(b'cellidx1'), np.
        int32), (bytes_to_native_str(b'cellidx2'), np.int32), (
        bytes_to_native_str(b'tid'), np.int32)])
    cell_times = np.array(cell_time_lst, dtype=dtype)
    return cell_times


@classmethod
def api_version_fields(cls, **kwargs):
    """
        *** DEFAULT VERSION `v1` ***

        This method will return a dictionary object with version number and fields name. Fields are similar like
        serializer fields. Or you can say exactly as same as serializer fields.
        :param kwargs: Currently nothing to receive on kwargs
        :return: a dictionary object with version number
        """
    versions = {}
    return versions


def count_jobs(squeue_output, whoami):
    """
    Parse SLURM's ``squeue`` output and return a quadruple `(R, Q, r,
    q)` where:

      * `R` is the total number of running jobs (from any user);
      * `Q` is the total number of queued jobs (from any user);
      * `r` is the number of running jobs submitted by user `whoami`;
      * `q` is the number of queued jobs submitted by user `whoami`

    The `squeue_output` must contain the results of an invocation of
    ``squeue --noheader --format='%i^%T^%u^%U^%r^%R'``.
    """
    total_running = 0
    total_queued = 0
    own_running = 0
    own_queued = 0
    for line in squeue_output.split('\n'):
        if line == '':
            continue
        jobid, state, username, uid, reason, nodelist = line.split('^')
        if state in ['RUNNING', 'COMPLETING']:
            total_running += 1
            if username == whoami:
                own_running += 1
        elif state in ['PENDING', 'CONFIGURING']:
            total_queued += 1
            if username == whoami:
                own_queued += 1
    return total_running, total_queued, own_running, own_queued


@classmethod
def constraint_is_method(cls, text):
    """Check from the text of the constraint whether it is
        a Python method, as opposed to a 'normal' constraint.

        :return: True if it is, False if not
        """
    m = cls._PATTERN.match(text)
    return m is not None


@classmethod
def get_configuration_for_impersonation(cls, uri, impersonate_user, username):
    """
        Return a configuration dictionary that can be merged with other configs
        that can set the correct properties for impersonating users
        :param uri: URI string
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        :return: Dictionary with configs required for impersonation
        """
    return {}


@staticmethod
def delete_in_process_data(*args, **kwargs) ->None:
    """mockup of clearing staged directory for upstream calls.
        """
    return


def define_font_attributes(fill='black', stroke='black', stroke_width=0,
    font_family='Verdana'):
    """
    Define font attributes

    Keyword arguments:
    fill -- fill - default 'black'
    stroke -- stroke - default 'black'
    stroke_width -- stroke width - default 0
    font_family -- font family - default 'Verdana'
    """
    global FONT_ATTR
    FONT_ATTR = {'fill': fill, 'stroke': stroke, 'stroke_width':
        stroke_width, 'font_family': font_family}
    return


@classmethod
def process(cls, *, context=None, parameter=None):
    """ Evaluate the ADD command. """
    lhs, rhs = context.stack.pop(), context.stack.pop()
    context.stack.append(lhs + rhs)


def select_linked_to():
    """Select nodes linked to the selected ones

    """
    pass


def whitespace_tokenize(text):
    """Runs basic whitespace cleaning and splitting on a piece of text."""
    text = text.strip()
    if not text:
        return []
    tokens = text.split()
    return tokens


def _wrap(text, wrap_at=120, indent=4):
    """
    Return piece of text, wrapped around if needed.

    :param text: text that may be too long and then needs to be wrapped.
    :param wrap_at: the maximum line length.
    :param indent: number of spaces to prepend to all subsequent lines after the first.
    """
    out = ''
    curr_line_length = indent
    space_needed = False
    for word in text.split():
        if curr_line_length + len(word) > wrap_at:
            out += '\n' + ' ' * indent
            curr_line_length = indent
            space_needed = False
        if space_needed:
            out += ' '
            curr_line_length += 1
        out += word
        curr_line_length += len(word)
        space_needed = True
    return out


def str_rstrip(s, char, count):
    """
        str_rstrip('asss','s',0)
        str_rstrip('asss','s',1)
        str_rstrip('asss','s',2)
        str_rstrip('asss','s',3)
        str_rstrip('asss','s',4)
    """
    c = 0
    for i in range(s.__len__() - 1, -1, -1):
        if c == count:
            break
        elif s[i] == char:
            c = c + 1
        else:
            break
    if c == 0:
        return s
    else:
        ei = s.__len__() - c
        return s[:ei]


@staticmethod
def _is_dict_list(v):
    """
        Return true of the input object is a list of dicts
        """
    return isinstance(v, list) and len(v) > 0 and isinstance(v[0], dict)


def import_string(import_name, silent=False):
    """Imports an object based on a string.  This is useful if you want to
    use import paths as endpoints or something similar.  An import path can
    be specified either in dotted notation (``xml.sax.saxutils.escape``)
    or with a colon as object delimiter (``xml.sax.saxutils:escape``).

    If the `silent` is True the return value will be `None` if the import
    fails.

    :return: imported object
    """
    try:
        if ':' in import_name:
            module, obj = import_name.split(':', 1)
        elif '.' in import_name:
            items = import_name.split('.')
            module = '.'.join(items[:-1])
            obj = items[-1]
        else:
            return __import__(import_name)
        return getattr(__import__(module, None, None, [obj]), obj)
    except (ImportError, AttributeError):
        if not silent:
            raise


def _pathlib_compat(path):
    """
    For path-like objects, convert to a filename for compatibility
    on Python 3.6.1 and earlier.
    """
    try:
        return path.__fspath__()
    except AttributeError:
        return str(path)


def rename(name: str='RenamedMarker'):
    """Rename first selected time marker

    :param name: Name, New name for marker
    :type name: str
    """
    pass


@classmethod
def isnum(cls, nextchar):
    """ Whether the next character is part of a number """
    return nextchar.isdigit()


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 AskPassword(prompt, default='', id=264, ok=None, cancel=None):
    """Original doc: Display a PROMPT string and a text entry field with a DEFAULT string.
    The string is displayed as bullets only.

    Return the contents of the text entry field when the user clicks the
    OK button or presses Return.
    Return None when the user clicks the Cancel button.

    If omitted, DEFAULT is empty.

    The PROMPT and DEFAULT strings, as well as the return value,
    can be at most 255 characters long.
    """
    raise NotImplementedError()


def default_representer(dumper, data):
    """Default representer"""
    return dumper.represent_str(str(data))


@staticmethod
def update_author_min_max_date(min_date, max_date, target_author,
    author_field='author_uuid'):
    """
        Get the query to update demography_min_date and demography_max_date of a given author

        :param min_date: new demography_min_date
        :param max_date: new demography_max_date
        :param target_author: target author to be updated
        :param author_field: author field

        :return: the query to be executed to update demography data of an author
        """
    es_query = (
        """
        {
          "script": {
            "source":
            "ctx._source.demography_min_date = params.min_date;ctx._source.demography_max_date = params.max_date;",
            "lang": "painless",
            "params": {
                "min_date": "%s",
                "max_date": "%s"
            }
          },
          "query": {
            "term": {
              "%s": "%s"
            }
          }
        }
        """
         % (min_date, max_date, author_field, target_author))
    return es_query


def difficult_n_terminal_residue(amino_acids):
    """
    Is the N-terminus one of {Gln, Glu, Cys}?
    ---
    Priority I: avoid N-terminal Gln, Glu, Cys
    """
    return amino_acids[0] in {'Q', 'E', 'C'}


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


def _filter_by_overlay(vids, overlay=True):
    """Filter to get overlay or non-overlay videos"""
    for vid in vids:
        if 'overlay' in vid and overlay:
            yield vid
        elif 'overlay' not in vid and not overlay:
            yield vid


def _plus(lhs=None, rhs=None, name=None, attr=None, out=None, **kwargs):
    """Adds arguments element-wise.

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

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

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

    name : string, optional.
        Name of the resulting symbol.

    Returns
    -------
    Symbol
        The result symbol.
    """
    return 0,


def _contains_date(format):
    """
    Check if a format (string) contains a date.
    (It currently check if the string contains tokens from the simpledateformat
    https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
    that represent, years, months, days).

    :param format: A string format representing a simple date format.
    :type format: str
    :return: True if values part of a date are contained in the format string.
    :rtype: bool
    """
    part_of_date_tokens = 'GyYMwWdDFEu'
    for token in part_of_date_tokens:
        if token in format:
            return True
    return False


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


@staticmethod
def _wrap_bytes(bytestream):
    """Return `bytestream` without changing it."""
    return bytestream


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

    """
    pass


def precomp(point):
    """
    Precomputation placeholder
    :param point:
    :return:
    """
    return point


def get_name_and_checksum(checksums, end):
    """Extract a full filename and checksum from the checksums list for a file ending in given end."""
    for entry in checksums:
        if not entry['file'].endswith(end):
            continue
        if '_from_' not in end and '_from_' in entry['file']:
            continue
        filename = entry['file']
        expected_checksum = entry['checksum']
        return filename, expected_checksum
    raise ValueError('No entry for file ending in {!r}'.format(end))


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 _check_ckan_version(cls, min_version=None, max_version=None):
    """Return ``True`` if the CKAN version is greater than or equal to
        ``min_version`` and less than or equal to ``max_version``,
        return ``False`` otherwise.

        If no ``min_version`` is given, just check whether the CKAN version is
        less than or equal to ``max_version``.

        If no ``max_version`` is given, just check whether the CKAN version is
        greater than or equal to ``min_version``.

        :param min_version: the minimum acceptable CKAN version,
            eg. ``'2.1'``
        :type min_version: string

        :param max_version: the maximum acceptable CKAN version,
            eg. ``'2.3'``
        :type max_version: string

        """
    current = cls._version_str_2_list(cls.ckan.__version__)
    if min_version:
        min_required = cls._version_str_2_list(min_version)
        if current < min_required:
            return False
    if max_version:
        max_required = cls._version_str_2_list(max_version)
        if current > max_required:
            return False
    return True


def send(from_addr, recipients, message):
    """Send message to recipients."""


@classmethod
def parse_text_version(cls, text):
    """Method which extracts latest number from the string.

        Empty string implies 0. No number also implies 0.

        :param str text: Line to search in.
        :return: Latest number
        :rtype: int
        """
    if not text:
        return 0
    matcher = cls.TEXT_VERSION_REGEXP.search(text)
    return int(matcher.group(0)) if matcher is not None else 0


def get_account_balance():
    """
    The GetAccountBalance operation retrieves the amount of money in your Amazon Mechanical Turk account.
    See also: AWS API Documentation

    :example: response = client.get_account_balance()

    :rtype: dict
    :return: {
        'AvailableBalance': 'string',
        'OnHoldBalance': 'string'
    }

    """
    pass


def business(id, search='hotdog'):
    """
    Get a business url from a business id.
    """
    return ('http://arbk.org/sq/Rezultatet-e-Bizneseve/' + id +
        '?part=business_list&code=%2020,0,url_b%20plotesohet%20ne%20ajax%20%20,0,0,'
         + search + ',0,0,0,0')


@staticmethod
def _split_overlapping(variant_pairs, anchor, which='both'):
    """
        Split the variants hitting the anchor into two
        """
    for ref, alt in variant_pairs:
        if ref.start < anchor < ref.end:
            mid = anchor - ref.start
            if which == 'left' or which == 'both':
                yield ref[:mid], alt[:mid]
            if which == 'right' or which == 'both':
                yield ref[mid:], alt[mid:]
        else:
            yield ref, alt


def cbox(i, gray=False, spectrum='alternate', reverse=False, as255=False,
    alpha=None, **kwargs):
    """
    Access a modular list of colors for plotting.
    Defines colours using rgb.

    :param i: (int), index to access color
    :param gray: (bool), if true then color is return as grayscale value
    :param spectrum: (str), choice of spectrum to use
    :param reverse: (bool), reverses the color order
    :param kwargs:
    :return:
    """
    CD = {}
    CD['dark blue'] = 0.0, 0.0, 0.55
    CD['greenish blue'] = 0.12, 0.8, 0.8
    CD['dark green'] = 0.15, 0.35, 0.0
    CD['yellow'] = 1.0, 1.0, 0.0
    CD['orangish yellow'] = 1.0, 0.9, 0.1
    CD['dark red'] = 0.73, 0.0, 0.0
    CD['dark purple'] = 0.8, 0.0, 0.8
    CD['light green'] = 0.49, 0.64, 0.0
    CD['orange'] = 1.0, 0.5, 0.0
    CD['light blue'] = 0.5, 0.85, 1.0
    CD['pink'] = 1.0, 0.8, 0.8
    CD['brown'] = 0.5, 0.3, 0.0
    CD['red'] = 0.9, 0.0, 0.0
    CD['bluey purple'] = 0.8, 0.85, 1.0
    CD['dark gray'] = 0.25, 0.25, 0.25
    CD['mid gray'] = 0.5, 0.5, 0.5
    CD['light gray'] = 0.75, 0.75, 0.75
    CD['dark grey'] = 0.25, 0.25, 0.25
    CD['mid grey'] = 0.5, 0.5, 0.5
    CD['light grey'] = 0.75, 0.75, 0.75
    CD['black5'] = 0.05, 0.05, 0.05
    CD['black'] = 0.0, 0.0, 0.0
    CD['white'] = 1.0, 1.0, 1.0
    if isinstance(i, int):
        i = i
    elif isinstance(i, float):
        i = int(i)
    elif isinstance(i, str):
        dat = CD[i]
        return dat
    if spectrum == 'alternate':
        order = ['dark blue', 'orange', 'light blue', 'dark purple',
            'dark green', 'bluey purple', 'dark red', 'light green', 'pink',
            'brown', 'red', 'yellow', 'greenish blue', 'dark gray',
            'mid gray', 'light gray']
    elif spectrum == 'lighten':
        order = ['dark blue', 'dark green', 'dark red', 'brown',
            'light green', 'orange', 'light blue', 'pink', 'dark purple',
            'red', 'greenish blue', 'bluey purple', 'yellow', 'dark gray',
            'mid gray', 'light gray']
    elif spectrum == 'dots':
        order = ['dark blue', 'yellow', 'light blue', 'dark purple',
            'dark green', 'orange', 'bluey purple', 'dark red',
            'light green', 'pink', 'brown', 'red', 'greenish blue',
            'dark gray', 'mid gray', 'light gray']
    elif spectrum == 'traffic':
        order = ['dark green', 'orange', 'red']
    else:
        order = ['light green', 'orangish yellow', 'orange', 'red', 'black',
            'dark gray']
    index = i % len(order)
    if reverse:
        index = len(order) - index - 1
    rgb = CD[order[index]]
    gray_value = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]
    if gray:
        return gray_value, gray_value, gray_value
    if as255:
        rgb = [int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255)]
    if alpha:
        rgb = list(rgb)
        rgb.append(alpha)
    return rgb


def analogy_func(wrap, a1, b1, a2, weight_direct=2 / 3, weight_transpose=1 / 3
    ):
    """
    Find the vector representing the best b2 to complete the analogy
    a1 : b1 :: a2 : b2, according to `pairwise_analogy_func`.

    This is the partial derivative of `pairwise_analogy_func` with respect
    to b2.
    """
    va1 = wrap.get_vector(a1)
    vb1 = wrap.get_vector(b1)
    va2 = wrap.get_vector(a2)
    return (vb1 - va1) * weight_direct + (va2 - va1) * weight_transpose + vb1


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 append_dict(dict_obj, measure_key, measure_value):
    """appends data to keyed dict.

    Function that appends key to continuous dict, creates if doesn't exist. EAFP

    Parameters
    ----------
    dict_obj : dict
        dictionary object that contains continuous output measures

    measure_key : str
        key for the measure to be stored in continuous_dict

    measure_value : any data container
        value to be appended to dictionary

    Returns
    -------
    dict_obj : dict
        dictionary object passed to function, with specified data container appended

    Examples
    --------
    Given a dict object 'example' with some data in it:

    >>> example = {}
    >>> example['call'] = ['hello']

    We can use the function to append it:

    >>> example = append_dict(example, 'call', 'world')
    >>> example['call']
    ['hello', 'world']

    A new key will be created if it doesn't exist:

    >>> example = append_dict(example, 'different_key', 'hello there!')
    >>> sorted(example.keys())
    ['call', 'different_key']
    """
    try:
        dict_obj[measure_key].append(measure_value)
    except KeyError:
        dict_obj[measure_key] = [measure_value]
    return dict_obj


@classmethod
def encode_bool(cls, b):
    """
        Encodes a boolean *b* into a string (``"yes"`` or ``"no"``).
        """
    return 'yes' if b else 'no'


def write_OWvalue(fp, data_element):
    """Write a data_element with VR of 'other word' (OW).

    Note: This **does not currently do the byte swapping** for Endian state.

    """
    fp.write(data_element.value)


@staticmethod
def on_frontend_preparation(frontend):
    """Plugin hook to manipulate the Frontend object before starting it. If a
        value is returned here it will replace the Frontend object."""


def indent(level, size=2):
    """Return indentation."""
    return ' ' * level * size


def powint(xlow, xhigh, ylow, yhigh, xval, power):
    """Power-based interpolator
    :param xlow: x lower interval
    :param xhigh: x upper interval
    :param ylow: y lower interval
    :param yhigh: y upper interval
    :param xval: value on x
    :param power: power for interpolation
    :return: TODO
    """
    EPSLON = 1e-20
    if xhigh - xlow < EPSLON:
        powint = (yhigh + ylow) / 2.0
    else:
        powint = ylow + (yhigh - ylow) * ((xval - xlow) / (xhigh - xlow)
            ) ** power
    return powint


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 sum_contrast(value, target, reference):
    """Convenience function for creating sum-coded contrasts.

    :param value: value to convert into 1, 0, or -1
    :param target: target (will be recoded to 1)
    :param reference: reference (will be recoded to -1)
    :return: recoded value
    """
    if value == target:
        return 1
    elif value == reference:
        return -1
    else:
        return 0


def _make_mutable(obj, identifier='presentValue', mutable=True):
    """
    This function is not the way to go as it changes the class
    property...As bacpypes issue #224, it will need a lot of work
    """
    for prop in obj.properties:
        if prop.identifier == identifier:
            prop.mutable = mutable
    return obj


def one(iterable, too_short=None, too_long=None):
    """Return the first item from *iterable*, which is expected to contain only
    that item. Raise an exception if *iterable* is empty or has more than one
    item.
    :func:`one` is useful for ensuring that an iterable contains only one item.
    For example, it can be used to retrieve the result of a database query
    that is expected to return a single row.
    If *iterable* is empty, ``ValueError`` will be raised. You may specify a
    different exception with the *too_short* keyword:

    >>> it = []
    >>> one(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    ValueError: too many items in iterable (expected 1)'
    >>> too_short = IndexError('too few items')
    >>> one(it, too_short=too_short)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    IndexError: too few items

    Similarly, if *iterable* contains more than one item, ``ValueError`` will
    be raised. You may specify a different exception with the *too_long*
    keyword:

    >>> it = ['too', 'many']
    >>> one(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    ValueError: too many items in iterable (expected 1)'
    >>> too_long = RuntimeError
    >>> one(it, too_long=too_long)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    RuntimeError

    Note that :func:`one` attempts to advance *iterable* twice to ensure there
    is only one item. If there is more than one, both items will be discarded.
    See :func:`spy` or :func:`peekable` to check iterable contents less
    destructively.
    """
    it = iter(iterable)
    try:
        value = next(it)
    except StopIteration:
        raise (too_short or ValueError(
            'too few items in iterable (expected 1)'))
    try:
        next(it)
    except StopIteration:
        pass
    else:
        raise (too_long or ValueError(
            'too many items in iterable (expected 1)'))
    return value


def port_from_context(context):
    """Get the Port from a Neutron Context.

    :param context: a Neutron Context;
    :return: the port;
    """
    return getattr(context, '_port', None)


@staticmethod
def configuration_key_prefix():
    """
        Return string prefix for configuration key.

        Abstract method, must be implemented in subclass.
        """
    raise NotImplementedError('Please implement in subclass')


def getChildForRequest(resource, request):
    """
    Traverse resource tree to find who will handle the request.
    """
    while request.postpath and not resource.isLeaf:
        pathElement = request.postpath.pop(0)
        request.prepath.append(pathElement)
        resource = resource.getChildWithDefault(pathElement, request)
    return resource


def reconstruct_tokens(tokens):
    """
    Reconstructs string from list of word tokens

    :param tokens: list of word tokens
    :return: reconstructed string
    """
    tokens = list(tokens)
    new_string = ''
    for element in tokens:
        new_string = new_string + str(element) + ' '
    return new_string


def create_query_statement(condition='match'):
    """
    >>> create_query_statement()
    {'query': {'match': {}}}
    >>> create_query_statement(condition='bool')
    {'query': {'bool': {}}}
    """
    return {'query': {condition: {}}}


def format_size(size):
    """Return file size as string from byte size."""
    for unit in ('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'):
        if size < 2048:
            return '%.f %s' % (size, unit)
        size /= 1024.0


@classmethod
def deserialattributes(cls, xstype, elem):
    """
        helper methods to deserialse xml attributes.
        """
    ret = {}
    attributes = xstype.getattributes()
    if attributes:
        for attrib in attributes:
            attrname = attrib.getname()
            attrvalue = None
            if attrname in elem.attrib:
                attrvalue = attrib.decode(elem.attrib[attrname])
                ret[attrname] = attrvalue
    if ret:
        return ret
    return None


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

        :param AppLinkTeamType val:
        :rtype: EventType
        """
    return cls('app_link_team', val)


def opx_drop_all_except_active_sheet(wb, keep=[]):
    """Drop all worksheets except active one.

    Arguments:
        keep: List of exception sheetnames. All sheets on this list will not be dropped.
    """
    sheet_to_keep = [wb.active.title] + keep
    for sh in wb.sheetnames:
        if sh not in sheet_to_keep:
            del wb[sh]
    wb.active = 0


def twilightName(sunAlt):
    """
    Determine the type of twilight for a given altitude of the Sun.

    Definitions of twilight:
      - Solar altitude > 0    : day
      - Solar altitude <= 0   : civil twilight
      - Solar altitude <= -6  : nautical twilight
      - Solar altitude <= -12 : astronomical twilight
      - Solar altitude <= -18 : night

    Parameters
    ----------
    sunAlt : float
        Altitude of the Sun in degrees.

    Returns
    -------
    Twilight flag : string, {"day", "civil twilight", "nautical twilight", "astron. twilight", "night"}
        Specifies the type of twilight corresponding to the
        given solar altitude.

        The twilight flag is either "day", "civil twilight", "nautical twilight",
        "astron. twilight", or "night".
  """
    if sunAlt <= -18.0:
        return 'night'
    if sunAlt <= -12.0:
        return 'astron. twilight'
    if sunAlt <= -6.0:
        return 'nautical twilight'
    if sunAlt <= 0.0:
        return 'civil twilight'
    return 'day'


def b2s(b):
    """
    Binary to string.
    """
    ret = []
    b = b.zfill((len(b) + 7) // 8 * 8)
    for pos in range(0, len(b), 8):
        ret.append(chr(int(b[pos:pos + 8], 2)))
    return ''.join(ret)


@classmethod
def parse_protocol(cls, previous_buffer, input_buffer, gevent_queue,
    separator=b'\n', single_item_processing=False):
    """
        Parse a received protocol.
        - For all COMPLETE token : enqueue in the provided queue (method : put)
        - Return the remaining INCOMPLETE token (ie not
 terminated)
        - Return None if no INCOMPLETE token remains
        :param cls: Our class.
        :param previous_buffer: The previous incomplete buffer.
        :type previous_buffer: bytes,None
        :param input_buffer: The new buffer.
        :type input_buffer: bytes,None
        :param gevent_queue: A gevent queue, which will be populated with complete items.
        :type gevent_queue: Queue
        :param separator: The separator to use
        :type separator: bytes
        :param single_item_processing: If true, process only one item then exit.
        :type single_item_processing: bool
        :return: The new incomplete buffer.
        :rtype bytes
        """
    prev_buf = previous_buffer
    if input_buffer:
        cur_buf = input_buffer
    else:
        cur_buf = b''
    if prev_buf:
        cur_buf = prev_buf + cur_buf
        prev_buf = None
    while True:
        ar = cur_buf.partition(separator)
        if len(ar[1]) > 0:
            if prev_buf is None:
                gevent_queue.put(ar[0])
            else:
                gevent_queue.put(previous_buffer + ar[0])
                prev_buf = None
            if len(ar[2]) == 0:
                return prev_buf
            elif not single_item_processing:
                cur_buf = ar[2]
            else:
                return ar[2]
        elif len(ar[0]) == 0:
            if prev_buf is None:
                return None
            elif len(prev_buf) > 0:
                return prev_buf
            else:
                return None
        elif prev_buf is None:
            return ar[0]
        else:
            return prev_buf + ar[0]


@classmethod
def has_card_provider(cls, store):
    """Find out if there is a card provider
        :param store: a database store
        :returns: if there is a card provider
        """
    return bool(store.find(cls).count())


def check_nd(obj):
    """determine if the percentages are valid"""
    valid = 1
    productions = dict()
    for rule in obj.prod_rules_edit:
        temprule = rule.text().split(':')
        productions[temprule[0]] = 0
    for i, rule in enumerate(obj.prod_rules_edit):
        if rule.valid:
            temprule = rule.text().split(':')
            try:
                productions[temprule[0]] = productions[temprule[0]] + float(obj
                    .prod_percent[i].text())
            except:
                print('[ ERROR ] ', obj.prod_percent[i].text(),
                    ' is not a number.')
                valid = 0
                return valid
    for prod, perc in productions.items():
        if perc != 1.0:
            print('[ ERROR ] Invalid percent of ', perc, ' entered for ', prod)
            valid = 0
    return valid


def removeMember(id):
    """ Remove the member with the provided id from the group """


def new_merged_dict(*dicts):
    """Merges dictionaries into a new dictionary. Necessary for python2 and
    python34 since neither have PEP448 implemented."""
    output = {}
    for d in dicts:
        output.update(d)
    return output


def render(name):
    """Return a rendering of the search form elements

        The query view should use `name` as the prefix for its widgets.
        """


@classmethod
def get_name(cls):
    """ Returns the name of the hook.
		"""
    return 'slack'


def column_index(archive_schema, orig_schema):
    """Create a mapping of names for the snapshot schema to their respective
    column in the archive schema. In addition, a mapping of identifier for
    columns in the snapshot schema to the column object at its schema position
    is created. Returns a tuple with the name mapping and the column identifier
    mapping.

    Parameters
    ----------
    archive_schema: dict(int: histore.archive.schema.ArchiveColumn)
        Dictionary mapping of column identifier to archive columns.
    orig_schema: list(histore.document.schema.Column)
        List of columns in a snapshot schema

    Returns
    -------
    dict, dict
    """
    archive_index = dict()
    orig_index = dict()
    for pos in range(len(orig_schema)):
        col = orig_schema[pos]
        if col in archive_index:
            raise ValueError('cannot match by name with duplicates')
        archive_index[col] = archive_schema[col.colid]
        orig_index[col.colid] = col, pos
    return archive_index, orig_index


def make_key(element_name, element_type, namespace):
    """Return a suitable key for elements"""
    if element_type in ('complexType', 'simpleType'):
        eltype = 'complexType'
    else:
        eltype = element_type
    if eltype not in ('element', 'complexType', 'simpleType'):
        raise RuntimeError('Unknown element type %s = %s' % (element_name,
            eltype))
    return element_name, eltype, namespace


def mark_lite(app):
    """Mark `app` as supporting WSGI Lite, and return it"""
    app.__wsgi_lite__ = True
    return app


def _number_format(count=999):
    """A string format for line numbers

    Should give a '%d' format with width big enough to `count` lines

    >>> assert _number_format(77) == '%2d: '
    """
    digits = len(str(count))
    return '%%%dd: ' % digits


@classmethod
def get_param(cls, params, kwargs, name):
    """Извлечение параметра из объекта."""
    value = getattr(params, name)
    if value is not None:
        kwargs[name] = value


def clearcache():
    """Clear the cache entirely."""
    global cache
    cache = {}


def extract_pkid_from_uuid(pkid_or_uuid):
    """Removes all braces braces encapsulation included with AXL uuid if it exists.

    Does not use regex matching on start/finish for speed.  No validation is provided on uuid format.
    If braces do not exist, the original string should be returned as-is.

    :param pkid_or_uuid: (str) pkid or uuid
    :return: (str) pkid with stripped encapsulation
    """
    return pkid_or_uuid.replace('{', '').replace('}', '')


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 metadata(cls, val):
    """
        Create an instance of this class set to the ``metadata`` tag with value
        ``val``.

        :param SharedLinkMetadata val:
        :rtype: SharedLinkAlreadyExistsMetadata
        """
    return cls('metadata', val)


@staticmethod
def calc_stops(size, start=0.0, end=1.0):
    """Calculates equidistant stops for given number of colors."""
    if size == 0:
        return ()
    stops = []
    step = (end - start) / (size - 1)
    value = start
    while value < end:
        stops.append(value)
        value += step
    stops.append(end)
    return stops


def is_iterable(value):
    """ Check if value is iterable. """
    try:
        iter(value)
        return True
    except TypeError:
        return False


def collection_disable_render():
    """Do not render this collection

    """
    pass


def _is_bonded(item):
    """Determine if the item refers to a bonded port."""
    for attribute in item['attributes']:
        if attribute['attributeTypeKeyName'] == 'NON_LACP':
            return False
    return True


def mq_topic_match(topic, mask):
    """
    Checks if topic matches mqtt-style mask

    Args:
        topic: topic (string)
        mask: mask to check

    Returns:
        True if matches, False if don't
    """
    if topic == mask:
        return True
    else:
        ms = mask.split('/')
        ts = topic.split('/')
        lts = len(ts)
    for i, s in enumerate(ms):
        if s == '#':
            return i < lts
        elif i >= lts or s != '+' and s != ts[i]:
            return False
    return i == lts - 1


def provider_parser(subparser):
    """Configure provider parser for Constellix"""
    subparser.add_argument('--auth-username', help=
        'specify the API key username for authentication')
    subparser.add_argument('--auth-token', help=
        'specify secret key for authenticate=')


def parse_scoped_project_queue(scoped_name):
    """Returns the project and queue name for a scoped catalogue entry.

    :param scoped_name: a project/queue as given by :scope_queue_name:
    :type scoped_name: six.text_type
    :returns: (project, queue)
    :rtype: (six.text_type, six.text_type)
    """
    return scoped_name.split('/')


def is_length_immunity(item):
    """
    Judge whether follow the length rule. Rewrite it when possible.

    :param item: item dict.
    :return: bool.
    """
    if item['title']:
        if item['title'][:4] == '综合消息':
            return True
        if item['title'][:2] == '综述':
            return True
    else:
        print('Missing title!', item)
    return False


def list_orphaned_instances(orphaned_instances):
    """List orphaned instances."""
    for vm_ref, vm_rec, orphaned_instance in orphaned_instances:
        print('ORPHANED INSTANCE (%s)' % orphaned_instance.name)


def _energy_test_statistic_coefficient(n, m):
    """Coefficient of the test statistic."""
    return n * m / (n + m)


def html_box(item):
    """Returns an HTML block with template strings filled-in based on item attributes."""
    is_layer = str(type(item)) == "<class 'Skydipper.layer.Layer'>"
    is_dataset = str(type(item)) == "<class 'Skydipper.dataset.Dataset'>"
    is_widget = str(type(item)) == "<class 'Skydipper.Skydipper.Widget'>"
    is_geometry = str(type(item)) == "<class 'Skydipper.geometry.Geometry'>"
    is_image = str(type(item)) == "<class 'Skydipper.image.Image'>"
    site_link = ""
    site_logo = (
        ""
        )
    if is_layer:
        kind_of_item = 'Layer'
        url_link = f'{item.server}/v1/layer/{item.id}?includes=metadata'
    elif is_dataset:
        kind_of_item = 'Dataset'
        url_link = (
            f'{item.server}/v1/dataset/{item.id}?includes=metadata,layer')
    elif is_image:
        if item.type in ['Classified Image', 'Composite Image']:
            instrument = item.type
        else:
            instrument = item.instrument
        html_string = (
            f"

Image Source: {instrument}
Datetime: {item.date_time}
Cloud score : {item.cloud_score}

"
            )
        return html_string
    elif is_geometry:
        kind_of_item = 'Geometry'
        url_link = f'{item.server}/v1/geostore/{item.id}'
        html_string = (
            f"

{site_link}{site_logo}

Geometry id: {item.id}
"
            )
        for k, v in item.attributes.get('info').items():
            if v and k != 'simplifyThresh':
                html_string += f'
{k}: {v}'
        html_string += '

'
        return html_string
    else:
        kind_of_item = 'Unknown'
        url_link = None
    table_statement = f"Data source {item.attributes.get('provider')}"
    if item.attributes.get('connectorUrl') and item.attributes.get('provider'
        ) == 'cartodb':
        table_statement = (
            f"Carto table: {item.attributes.get('tableName')}"
            )
    if item.attributes.get('provider') == 'gee':
        table_statement = (
            f"GEE asset: {item.attributes.get('tableName')}"
            )
    html = (
        f"

{site_link}{site_logo}

{item.attributes.get('name')}
 {table_statement} | {kind_of_item} in {', '.join(item.attributes.get('application')).upper()}.
Last Modified: {item.attributes.get('updatedAt')}
Fields Connector: {item.attributes.get('provider')} | Published: {item.attributes.get('published')}

"
        )
    return html


def df_add_scorecol(data, metric, win_threshold=0.66, lose_threshold=0.33,
    win_points=2, lose_points=-2, tie_points=0, score_col_name='score'):
    """Adds an arbitrary score based on a metric column
    and parameters that set the score boundaries. Takes
    the win and lose thresholds, and applies them to
    inter quantile range on the metric column. What is above
    win threshold becomes a win, and what is below loss becomes
    a lose, and everything in between becomes a tie.

    data | DataFrame | a pandas dataframe with the data
    metric | str | the column to be used for basis of scoring
    win_threshold | float | the iqr at which point a win is consider
    lose_threshold | float | the iqr at which point a lose is considered
    win_points | int | the number of points for a win
    lose_points | int | the number of points for a lose
    tie_points | int | the number of points for a tie (between win and lose)
    score_col_name | str | name to be used for the score column

    """
    win = data.val_f1score.quantile(win_threshold)
    lose = data.val_f1score.quantile(lose_threshold)
    result = []
    for i in data[metric].values:
        if i >= win:
            result.append(win_points)
        elif i <= lose:
            result.append(lose_points)
        else:
            result.append(tie_points)
    data[score_col_name] = result
    return data


def ensure_list(obj, tuple2list=False):
    """
    Return a list whatever the input object is.

    Examples
    --------
    >>> ensure_list(list("abc"))
    ['a', 'b', 'c']
    >>> ensure_list("abc")
    ['abc']
    >>> ensure_list(tuple("abc"))
    [('a', 'b', 'c')]
    >>> ensure_list(tuple("abc"), tuple2list=True)
    ['a', 'b', 'c']
    >>> ensure_list(None)
    []
    >>> ensure_list(5.0)
    [5.0]

    """
    if obj is None:
        return []
    if isinstance(obj, list):
        return obj
    elif tuple2list and isinstance(obj, tuple):
        return list(obj)
    return [obj]


def check_notwanted(zelf, *args, **kwargs):
    """ whether an thing is not desired. """
    not_want = args[0]
    for key, value in not_want.items():
        if key == 'format':
            continue
        if key not in zelf:
            continue
        if value in zelf[key]:
            return True
    return False


def color_delete():
    """Remove active color from palette

    """
    pass


def remove_ssh(cube):
    """
    Remove all `aux_coords` but time.  Should that has the same shape as
    the data.  NOTE: This also removes `aux_factories` to avoid update error
    when removing the coordinate.

    Examples
    --------
    >>> import iris
    >>> url = ('http://omgsrv1.meas.ncsu.edu:8080/thredds/dodsC/'
    ...        'fmrc/us_east/US_East_Forecast_Model_Run_Collection_best.ncd')
    >>> cube = iris.load_cube(url, 'sea_water_potential_temperature')
    >>> cube = get_surface(cube)
    >>> len(cube.coords())
    10
    >>> cube = remove_ssh(cube)
    >>> len(cube.coords())
    8

    """
    for factory in cube.aux_factories:
        cube.remove_aux_factory(factory)
    for coord in cube.aux_coords:
        if coord.shape == cube.shape:
            if 'time' not in coord.name():
                cube.remove_coord(coord.name())
    return cube


def getWorkers():
    """Return a list of IWorkerStatus objects for the workers that are
        used by this builder."""


@staticmethod
def _needescape(c):
    """
        Return True if character needs escaping, else False.
        """
    return not ascii.isprint(c) or c == '"' or c == '\\' or ascii.isctrl(c)


@classmethod
def aggregate(cls, items, mode):
    """
        Aggregates array of numbers by a given 'mode'
        """
    if mode == cls.AGG_MODE_MAX:
        return max(items)
    elif mode == cls.AGG_MODE_MIN:
        return min(items)
    elif mode == cls.AGG_MODE_AVG:
        return cls.round(sum(items) / len(items))
    elif mode == cls.AGG_MODE_DIFF:
        return cls.round(max(items) - min(items))
    else:
        raise ValueError("unknown mode: '{}'".format(mode))


def _sabr_implied_vol_hagan_A4_fhess_by_strike(underlying, strike, maturity,
    alpha, beta, rho, nu):
    """_sabr_implied_vol_hagan_A4_fhess_by_strike
    See :py:func:`_sabr_implied_vol_hagan_A4`.

    :param float underlying:
    :param float strike:
    :param float maturity:
    :param float alpha: must be within [0, 1].
    :param float beta: must be greater than 0.
    :param float rho: must be within [-1, 1].
    :param float nu: volatility of volatility. This must be positive.

    :return: value of factor.
    :rtype: float.
    """
    one_minus_beta = 1.0 - beta
    one_minus_beta_half = one_minus_beta / 2.0
    one_minus_beta2 = one_minus_beta ** 2
    two_minus_beta = 2.0 - beta
    three_minus_beta = 3.0 - beta
    five_minus_beta_half = (5.0 - beta) / 2.0
    factor1 = strike ** -three_minus_beta
    numerator1 = one_minus_beta2 * alpha ** 2 * -two_minus_beta
    denominator1 = 24.0 * underlying ** one_minus_beta
    term1 = numerator1 * factor1 / denominator1
    factor2 = strike ** -five_minus_beta_half
    numerator2 = rho * beta * nu * alpha * -three_minus_beta
    denominator2 = 16.0 * underlying ** one_minus_beta_half
    term2 = numerator2 * factor2 / denominator2
    return -(term1 + term2) * maturity * one_minus_beta


def animation_cancel(restore_frame: bool=True):
    """Cancel animation, returning to the original frame

    :param restore_frame: Restore Frame, Restore the frame when animation was initialized
    :type restore_frame: bool
    """
    pass


def replace(text, *pairs):
    """Do a series of global replacements on a string."""
    while pairs:
        text = pairs[1].join(text.split(pairs[0]))
        pairs = pairs[2:]
    return text


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)