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 format_seconds(seconds, hide_seconds=False):
    """
    Returns a human-readable string representation of the given amount
    of seconds.
    """
    if seconds < 1:
        return '0s'
    output = ''
    for period, period_seconds in (('y', 31557600), ('d', 86400), ('h',
        3600), ('m', 60), ('s', 1)):
        if seconds >= period_seconds and not (hide_seconds and period == 's'):
            output += str(int(seconds / period_seconds))
            output += period
            output += ' '
            seconds = seconds % period_seconds
    return output.strip()


def encode(code, readline=False):
    """ Adds escape and control characters for ANSI codes

    :param code: pick a constant, any constant
    :type code: int
    :param readline: add readline compatibility, which causes bugs in other formats
    :type content: unicode
    :return: ansi string
    :rtype: unicode
    """
    if readline:
        return '\x01\x1b[' + str(code) + 'm\x02'
    return '\x1b[' + str(code) + 'm'


def name_experiment(experiment_details=None):
    """Generate a unique name for the experiment."""
    if experiment_details is None:
        experiment_details = dict()
    if 'name' in experiment_details:
        name = experiment_details['name'].strip().replace(' ', '_')
    else:
        exp_type = experiment_details['type'].replace('.', '_')
        h_larmor_frq = float(experiment_details['h_larmor_frq'])
        temperature = float(experiment_details['temperature'])
        b1_frq = float(experiment_details['b1_frq'])
        time_t1 = float(experiment_details['time_t1'])
        name = '{:s}_{:.0f}Hz_{:.0f}ms_{:.0f}MHz_{:.0f}C'.format(exp_type,
            b1_frq, time_t1 * 1000.0, h_larmor_frq, temperature).lower()
    return name


def GetIPListByCom(APCG, IPSet=None):
    """
	Return a list of APCG nodes sorted by communication requirements.
	"""
    DegreeDict = APCG.degree()
    SortedIPList = sorted(DegreeDict, key=DegreeDict.get, reverse=True)
    if IPSet is None:
        return SortedIPList
    else:
        return list(filter(lambda x: x in IPSet, SortedIPList))


def note_favorite(note):
    """
    get the status of the note as a favorite

    returns True if the note is marked as a favorite
            False otherwise
    """
    if 'favorite' in note:
        return note['favorite']
    return False


def remove_invisible(s: str) ->str:
    """
    support remove
   ...
    :param s:
    :return:
    """
    return ''.join(s.split())


def get_total_line_for_file(path_to_file, ignore_blank_lines=False):
    """
    Calculate the total number of line in the given file.
    """
    i = 0
    with open(path_to_file) as f:
        for line in f:
            if line == '\n' and ignore_blank_lines:
                pass
            else:
                i += 1
    return i


def get(project, version=None):
    """Return a tuple (version, file) with the the egg for the specified
        project and version. If version is None, the latest version is
        returned. If no egg is found for the given project/version (None, None)
        should be returned."""


def normalized_efficiency(P, G_poa, P_ref, G_ref=1000):
    """
    Compute normalized efficiency defined as:

    :math:`NE = \\dfrac{\\dfrac{P}{P_{ref}}}{\\dfrac{G_{poa}}{G_{ref}}}`

    where
    :math:`P` is the observed power (AC or DC),
    :math:`P_{ref}` is the DC power rating at STC conditions,
    :math:`G_{poa}` is the plane-of-array irradiance, and
    :math:`G_{ref}` is the reference irradiance.

    Parameters
    -----------
    P : pandas Series or float
        Power (AC or DC)

    G_poa : pandas Series or float
         Plane of array irradiance

    P_ref : float
        DC power rating at STC conditions

    G_ref : float (optional)
        Reference irradiance, default = 1000

    Returns
    -------
    pandas Series or float
        Normalized efficiency in a pandas Series (if P or G_poa are Series) or
        float (if P and G_poa are floats)
    """
    Yf = P / P_ref
    Yr = G_poa / G_ref
    NE = Yf / Yr
    return NE


def dmas_tanh(module, input, output):
    """DMAs estimation for `torch.nn.Tanh`"""
    input_dma = input.numel() * 2
    output_dma = output.numel()
    return input_dma + output_dma


def write_data(output, iterable):
    """ Write (index, data) iterable to `output`

    Write some data to `output`. Iterable should return 2-tuples of the form
    index, data such that::

        output[index] = data

    makes sense.

    Examples
    --------
    >>> a=np.zeros((2,2))
    >>> write_data(a, data_generator(np.asarray([[1,2],[3,4]])))
    >>> a
    array([[ 1.,  2.],
           [ 3.,  4.]])
    """
    for index, data in iterable:
        output[index] = data


def _context_license_spdx(context, value):
    """convert a given known spdx license to another one"""
    mapping = {'Apache-1.1': 'ASL 1.1', 'Apache-2.0': 'ASL 2.0',
        'BSD-3-Clause': 'BSD', 'GPL-1.0+': 'GPL+', 'GPL-2.0': 'GPLv2',
        'GPL-2.0+': 'GPLv2+', 'GPL-3.0': 'GPLv3', 'GPL-3.0+': 'GPLv3+',
        'LGPL-2.1': 'LGPLv2.1', 'LGPL-2.1+': 'LGPLv2+', 'LGPL-2.0':
        'LGPLv2 with exceptions', 'LGPL-2.0+': 'LGPLv2+ with exceptions',
        'LGPL-3.0': 'LGPLv3', 'LGPL-3.0+': 'LGPLv3+', 'MIT':
        'MIT with advertising', 'MPL-1.0': 'MPLv1.0', 'MPL-1.1': 'MPLv1.1',
        'MPL-2.0': 'MPLv2.0', 'OFL-1.1': 'OFL', 'Python-2.0': 'Python'}
    if context['spec_style'] == 'fedora':
        return mapping[value]
    else:
        return value


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

        :param BinderReorderSectionDetails val:
        :rtype: EventDetails
        """
    return cls('binder_reorder_section_details', val)


def flatten(*args):
    """
    Flatten a list of iterables. Returns an iterable.
    """
    for arg in args:
        for item in arg:
            yield item


def get_text_by_tag(start, tagname, default=None):
    """Returns a text node from a tag"""
    node_back = start.getElementsByTagName(tagname)[0]
    for node in node_back.childNodes:
        if node.nodeType == node.TEXT_NODE:
            return node.data
    return default


@classmethod
def set_cursor(cls, widget, cursor_name='parent'):
    """ Set the cursor named cursor_name'.

        Args:
            widget (:class:`~Gtk.Widget`): The widget triggering the cursor change, used to retrieve a Gdk.Window
            cursor_name (`str`): Name of the cursor to be set
        """
    try:
        cursor = cls._cursors[cursor_name]
    except KeyError:
        cls._populate_cursors()
        cursor = cls._cursors[cursor_name]
    widget.get_window().set_cursor(cursor)


@classmethod
def list(cls, context, limit=None, marker=None, sort_key=None, sort_dir=None):
    """Return a list of DeployTemplate objects.

        :param context: security context. NOTE: This should only
                        be used internally by the indirection_api.
                        Unfortunately, RPC requires context as the first
                        argument, even though we don't use it.
                        A context should be set when instantiating the
                        object, e.g.: DeployTemplate(context).
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`DeployTemplate` objects.
        """
    db_templates = cls.dbapi.get_deploy_template_list(limit=limit, marker=
        marker, sort_key=sort_key, sort_dir=sort_dir)
    return cls._from_db_object_list(context, db_templates)


def _get_sub_charset(raw_headers: list) ->list:
    """Hardcode for some invalid mail-encoding."""
    for k, _ in raw_headers:
        if b'X-QQ' in k:
            return ['gbk']
    return []


@conf
def common_flags_gdc(conf):
    """
	Sets the flags required by *gdc*
	"""
    v = conf.env
    v.DFLAGS = []
    v.D_SRC_F = ['-c']
    v.D_TGT_F = '-o%s'
    v.D_LINKER = v.D
    v.DLNK_SRC_F = ''
    v.DLNK_TGT_F = '-o%s'
    v.DINC_ST = '-I%s'
    v.DSHLIB_MARKER = v.DSTLIB_MARKER = ''
    v.DSTLIB_ST = v.DSHLIB_ST = '-l%s'
    v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L%s'
    v.LINKFLAGS_dshlib = ['-shared']
    v.DHEADER_ext = '.di'
    v.DFLAGS_d_with_header = '-fintfc'
    v.D_HDR_F = '-fintfc-file=%s'


@classmethod
def decode(cls, stream):
    """Decodes generic data sub-item from data stream

        User data value is left in raw string format. The Application Entity
        is responsible for dealing with it.

        :param stream: raw data stream
        :return: decoded generic data sub-item
        """
    item_type, reserved, item_length = cls.header.unpack(stream.read(4))
    user_data = stream.read(int(item_length))
    return cls(item_type=item_type, user_data=user_data, reserved=reserved)


def url_flask_to_swagger(source):
    """Convert Flask URL to swagger path."""
    return source.replace('<', '{').replace('>', '}')


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

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


def clear_stacks(topology):
    """Remove all stacks from all nodes of the topology

    Parameters
    ----------
    topology : Topology
    """
    for v in topology.nodes():
        topology.node[v].pop('stack', None)


def clamp(x, low, high):
    """
    Ensures that x is between the limits set by low and high.
    For example,
    * clamp(5, 10, 15) is 10.
    * clamp(15, 5, 10) is 10.
    * clamp(20, 15, 25) is 20.

    :param    x: the value to clamp.
    :param  low: the minimum value allowed.
    :param high: the maximum value allowed.
    :returns: the clamped value
    """
    return min(max(x, low), high)


def __del(collection, item, _sa_initiator=None):
    """Run del events, may eventually be inlined into decorators."""
    if _sa_initiator is not False:
        executor = collection._sa_adapter
        if executor:
            executor.fire_remove_event(item, _sa_initiator)


def file_basename(fp, **kwargs):
    """
    Return the basename of a file without folder location and extension
    """
    return fp.rpartition('/')[2].partition('.')[0]


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


def _join_lines(lines):
    """join lines that have been written by splitlines()

    Has logic to protect against `splitlines()`, which
    should have been `splitlines(True)`
    """
    if lines and lines[0].endswith(('\n', '\r')):
        return u''.join(lines)
    else:
        return u'\n'.join(lines)


def _modinv(e, m):
    """
    Modular Multiplicative Inverse. Returns x such that: (x*e) mod m == 1
    """
    x1, x2 = 1, 0
    a, b = e, m
    while b > 0:
        q, r = divmod(a, b)
        xn = x1 - q * x2
        a, b, x1, x2 = b, r, x2, xn
    return x1 % m


def dl_delete(dl, curr):
    """ Delete current item
    """
    if curr is None:
        print('ERROR dl_delete(): DELETING ITEM NULL')
        return False
    if dl.head is None or dl.tail is None or dl.itemsInContainer == 0:
        print('ERROR dl_delete(): DELETING ITEM IN EMPTY LIST')
        return False
    if curr.prev is None:
        dl.head = dl.head.next
        if dl.head:
            dl.head.prev = None
        else:
            dl.tail = None
    else:
        curr.prev.next = curr.next
        if curr.next:
            curr.next.prev = curr.prev
        else:
            dl.tail = curr.prev
    dl.itemsInContainer -= 1
    curr.prev = None
    curr.next = None
    del curr
    return True


def __iter__():
    """iterates over items in sort order"""


def multi_getattr(obj, attr, default=None):
    """
    Get a named attribute from an object; multi_getattr(x, 'a.b.c.d') is
    equivalent to x.a.b.c.d. When a default argument is given, it is
    returned when any attribute in the chain doesn't exist; without
    it, an exception is raised when a missing attribute is encountered.
    :param Object obj: The object to extract attributes from
    :param string attr:
    :param default:
    """
    attributes = attr.split('.')
    for i in attributes:
        try:
            obj = getattr(obj, i)
        except AttributeError:
            if default:
                return default
            else:
                raise
    return obj


@staticmethod
def _safe_pop(l):
    """Safely pop from a list.

        Returns None if list empty.

        """
    return l.pop(0) if l else None


@classmethod
def premieres(cls, date=None, days=None):
    """
        Returns all shows premiering during the time period specified.

        :param date: Start date for the calendar. (today)
        :param days: Number of days to display starting from the date. (7)
        """
    if date:
        date = date.strftime('%Y%m%d')
    else:
        days = None
    return cls._get('calendar/premieres', date, days)


@classmethod
def policy_is_required(cls, pcluster_config):
    """Describe whether the policy represented by this class must be included."""
    cw_log_settings = pcluster_config.get_section('cluster').get_param(
        'cw_log_settings')
    if cw_log_settings.value is not None:
        cw_log_section = pcluster_config.get_section('cw_log',
            cw_log_settings.value)
        should_include_policy = cw_log_section.get_param_value('enable')
    else:
        should_include_policy = cw_log_settings.referred_section_definition[
            'params']['enable']['default']
    return should_include_policy


@staticmethod
def _read_file(filename):
    """OVERRIDE: Reads from the the libraries format and returns an object
        in the given library's format."""
    raise NotImplementedError()


def ndof_orbit():
    """Orbit the view using the 3D mouse

    """
    pass


@classmethod
def clear(cls):
    """
        Clear all registered handlers.
        """
    cls._HANDLERS = {}


def zero_prefix_int(num):
    """
    zero_prefix_number(int) -> str

    Puts a zero in fron of 1 digit numbers.

    otherwise just returns the int
    """
    strnum = str(num)
    if len(strnum) == 1:
        return '0' + strnum
    return strnum


def getBuild():
    """Get the L{buildbot.process.build.Build} instance for the current
        build.  Note that this object is not available after the build is
        complete, at which point this method will return None.

        Try to avoid using this method, as the API of L{Build} instances is not
        well-defined.

        @returns L{buildbot.process.build.Build} instance
        """


def _dict_to_text(freq_dict):
    """
    _dict_to_text(freq_dict):

    Internal routine to print items and values
    in a sorted dictionary, to avoid duplicating
    this code in process_file and in process_dir.

    Inputs:
        freq_dict, dict
            Dictionary of words and frequencies.

    Outputs:
        str:
            Text block with numerated key-value pairs.
    """
    stats_text = ''
    for i, (key, value) in enumerate(freq_dict.items()):
        stats_text += f'{i + 1}. {key}, {value}\n'
    stats_text += '\n'
    return stats_text


@classmethod
def filter_query_for_user(cls, query, user):
    """List only assets created by user."""
    return query.filter(cls.owner_id == user.id)


def rgb(rgb_colors):
    """
    Return a tuple of integers, as used in AWT/Java plots.

    Parameters
    ----------
    rgb_colors : list
        Represents a list with three positions that correspond to the percentage red, green and
        blue colors.

    Returns
    -------
    tuple
        Represents a tuple of integers that correspond the colors values.

    Examples
    --------
    >>> from pymove.visualization.visualization import rgb
    >>> rgb([0.6,0.2,0.2])
        (51, 51, 153)
    """
    blue = rgb_colors[0]
    red = rgb_colors[1]
    green = rgb_colors[2]
    return int(red * 255), int(green * 255), int(blue * 255)


def string_to_num(s):
    """Converts a string to an int/float

    Returns ``None`` if it can't be converted

    >>> string_to_num('5')
    5
    >>> string_to_num('5.2')
    5.2
    >>> string_to_num(10)
    10
    >>> string_to_num(10.1)
    10.1
    >>> string_to_num('this is not a string') is None
    True
    """
    if isinstance(s, (int, float)):
        return s
    if s.isdigit():
        return int(s)
    try:
        return float(s)
    except ValueError:
        return None


def quote(str):
    """Prepare string to be used in a quoted string.

    Turns backslash and double quote characters into quoted pairs.  These
    are the only characters that need to be quoted inside a quoted string.
    Does not add the surrounding double quotes.
    """
    return str.replace('\\', '\\\\').replace('"', '\\"')


def iter_prio_dict(prio_dict):
    """
    Iterate over a priority dictionary.  A priority dictionary is a
    dictionary keyed by integer priority, with the values being lists
    of objects.  This generator will iterate over the dictionary in
    priority order (from lowest integer value to highest integer
    value), yielding each object in the lists in turn.

    :param prio_dict: A priority dictionary, as described above.

    :returns: An iterator that yields each object in the correct
              order, based on priority and ordering within the
              priority values.
    """
    for _prio, objs in sorted(prio_dict.items(), key=lambda x: x[0]):
        for obj in objs:
            yield obj


def findfirstnumberpos(s):
    """
    return position in string where the first digit lies and number of digits found

    pattern12345.cor
    => 7
    pattern_0005.cor
    => 8
    """
    if '.' in s:
        splits = s.split('.')
        if len(splits) != 2:
            raise ValueError("%s must contain a single '.'!" % s)
        beforedot = splits[-2]
    else:
        beforedot = s
    l = len(beforedot)
    for _k, elem in enumerate(beforedot[::-1]):
        if elem not in '0123456789':
            break
    nbdigits_found = _k
    indexpos_first_digit = l - _k
    return indexpos_first_digit, nbdigits_found


def evaluate_all():
    """
    Fetch metrics overall.
    :return:
    """
    return


def flatten(fields):
    """Returns a list which is a single level of flattening of the
    original list."""
    flat = []
    for field in fields:
        if isinstance(field, (list, tuple)):
            flat.extend(field)
        else:
            flat.append(field)
    return flat


def get_seq_headers_columns_indexes(headers_string, delimiter, silent_fail=
    False):
    """
            Seq_id	Size	Description
    """
    headers_string = headers_string.strip()
    data = headers_string.split(delimiter)
    seq_id_columns = data.index('Seq_id')
    length_column = data.index('Size')
    description_column = data.index('Description')
    if any(map(lambda x: x < 0, [seq_id_columns, length_column,
        description_column])) and not silent_fail:
        raise ValueError('Could not parse block headers')
    return {'seq_id_column': seq_id_columns, 'seq_length_column':
        length_column, 'seq_description_column': description_column}


def weight_set():
    """Fill the active vertex group with the current paint weight

    """
    pass


@classmethod
def make_views(cls, conn):
    """The make views should be run after all tables imported."""
    pass


def ifset(a, b):
    """
    Returns the second argument if the first is not None or False. Return
    None otherwise.

    This is mostly equivalent to "a and b" but only recognizes None and False
    as "falsy" values.
    """
    return None if a is None or a is False else b


@staticmethod
def char_sim(sc, tc, match_value=2, mismatch_cost=2):
    """
         Basic character similarity.
         @param  sc             source character
         @param  tc             target character
         @param  match_value    Score bump/reward if they match
         @param  mismatch_cost  Penalty if they don't match (should be non-negative)
         @return similarity between sc and tc
        """
    return match_value if sc == tc else -mismatch_cost


def manage_addLocalRoles(userid, roles):
    """Set local roles for a user."""


def next_key(basekey, keys):
    """Returns the next unused key for basekey in the supplied array.

    The first try is `basekey`, followed by `basekey-2`, `basekey-3`, etc
    until a free one is found.
    """
    if basekey not in keys:
        return basekey
    i = 2
    while '{}-{}'.format(basekey, i) in keys:
        i = i + 1
    return '{}-{}'.format(basekey, i)


def distro_is_supported(distro_name):
    """
    An enforcer of supported distros that can differ from what ceph-deploy
    supports.
    """
    supported = ['centos', 'redhat', 'ubuntu', 'debian']
    if distro_name in supported:
        return True
    return False


def convert_single_to_list(val):
    """If a single object is provided, replace with a list containing only that object"""
    if val is None:
        return []
    if not isinstance(val, list):
        return [val]
    return val


@staticmethod
def remove_timeout(handle):
    """
        Cancel asyncio.Handle

        :type handle: asyncio.Handle
        :rtype: bool
        """
    return handle.cancel()


def _header2row_numbers(local_header, global_header):
    """Calculate local grid starting and ending rows in global grid
    Return:
        ind_top: the index of the top row
        ind_bottom: the index of the bottom row
    """
    y_bottom_gap = local_header['yllcorner'] - global_header['yllcorner']
    row_gap = round(y_bottom_gap / local_header['cellsize'])
    ind_bottom = global_header['nrows'] - 1 - row_gap
    ind_top = ind_bottom - local_header['nrows'] + 1
    ind_top = int(ind_top)
    ind_bottom = int(ind_bottom)
    return ind_top, ind_bottom


def insert_index_level(df, level, name, value):
    """For DataFrame df, add an index with name and value between level & (level + 1)"""
    n = df.index.nlevels
    order = list(range(n))
    order.insert(level, n)
    df = df.copy()
    df[name] = value
    df.set_index(name, append=True, inplace=True)
    return df.reorder_levels(order)


def find_version(fn):
    """
    Try to find a __version__ assignment in a source file
    """
    return '0.0.0'
    import compiler
    from compiler.ast import Module, Stmt, Assign, AssName, Const
    ast = compiler.parseFile(fn)
    if not isinstance(ast, Module):
        raise ValueError('expecting Module')
    statements = ast.getChildNodes()
    if not (len(statements) == 1 and isinstance(statements[0], Stmt)):
        raise ValueError('expecting one Stmt')
    for node in statements[0].getChildNodes():
        if not isinstance(node, Assign):
            continue
        if not len(node.nodes) == 1:
            continue
        assName = node.nodes[0]
        if not (isinstance(assName, AssName) and isinstance(node.expr,
            Const) and assName.flags == 'OP_ASSIGN' and assName.name ==
            '__version__'):
            continue
        return node.expr.value
    else:
        raise ValueError('Version not found')


def range_of(x):
    """All indices of collection `x` (i.e. `list(range(len(x)))`)"""
    return list(range(len(x)))


def manage_setPermissionMapping(permission_names=[], class_permissions=[],
    REQUEST=None):
    """Change the permission mapping
        """


@staticmethod
def not_implemented(*args, **kwargs):
    """
        Raise a new ValueError for blocking forbidden operations.
        """
    raise ValueError('Read Only list proxy')


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

        :param SharedLinkSettingsAllowDownloadEnabledType val:
        :rtype: EventType
        """
    return cls('shared_link_settings_allow_download_enabled', val)


def convert():
    """Convert the selected sketch strokes to bone chains

    """
    pass


def getElementTypeToolTip(*args, **kwargs):
    """Wrapper to prevent loading qtgui when this module is imported"""
    from taurus.qt.qtgui.icon import getElementTypeToolTip
    return getElementTypeToolTip(*args, **kwargs)


@staticmethod
def get_elements_children(elements, timeout=0):
    """ get elements children
        :type timeout: int
        :rtype: list[WebElement] | []
        """
    children_elements = []
    for element in elements:
        children_elements += element.find_children(timeout)
    return children_elements


def fromobject(thrift, tcls, obj):
    """Create thrift object with type `tcls` from a Python object.
    """
    if isinstance(obj, tcls):
        return obj
    return globals().get(tcls.__name__, tcls)(thrift, obj)


def copy():
    """Copy selected text to clipboard

    """
    pass


def enqueue_output(stream, queue):
    """ Read from stream and put line in queue """
    for line in iter(stream.readline, b''):
        queue.put(line)
    stream.close()


def get_triggers(schema_name):
    """
    Return a list of triggers within a schema with given name.

    NOT IMPLEMENTED; TODO:

    SELECT * FROM information_schema.triggers;
    """
    pass


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 num_pos(df, class_feat, pos_class):
    """Return number of instances that are labeled positive."""
    return len(df[df[class_feat] == pos_class])


def get_roles_for_permission(permission_id):
    """Get the roles that have a permission.

        Return a sequence of (role id, setting) tuples for the given
        permission.

        If no roles have been granted this permission, then the empty list is
        returned.
        """


def compareonvar(map_df, colvar='all'):
    """
    subsetting a dataframe based on some columns of interest

    map_df: (dataframe) the dataframe of the mappingfile table
    colvar: (str or list) the column(s) to use for subsetting; 'None' returns an outerjoin, 'all' returns an innerjoin
    """
    if isinstance(colvar, type(None)):
        return map_df
    if colvar is 'all':
        return map_df.dropna()
    else:
        return map_df.dropna(subset=colvar)


def _get_kafka_config(config: dict) ->dict:
    """Returns configurations for a consumer instance

    Parameters
    ----------
    config: dict
        Dictionary of configurations

    Returns
    ----------
    kafka_config: dict
        Dictionary with configurations for creating an instance of
        a secured Kafka consumer
    """
    kafka_config = {}
    default_config = {'auto.offset.reset': 'earliest'}
    if 'username' in config and 'password' in config:
        kafka_config['security.protocol'] = 'sasl_plaintext'
        kafka_config['sasl.mechanism'] = 'SCRAM-SHA-512'
        kafka_config['sasl.username'] = config['username']
        kafka_config['sasl.password'] = config['password']
    kafka_config['group.id'] = config['group_id']
    kafka_config.update(default_config)
    if 'bootstrap.servers' in config:
        kafka_config['bootstrap.servers'] = config['bootstrap.servers']
    else:
        fink_servers = ['localhost:9093', 'localhost:9094', 'localhost:9095']
        kafka_config['bootstrap.servers'] = '{}'.format(','.join(fink_servers))
    return kafka_config


def remove(item):
    """
        removes item from pending list
        """


def mark():
    """Mark the request with IDrafting if there is drafting information
        available.
        """


@classmethod
def dark_teal(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0x11806a``."""
    return cls(1146986)


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 export_type(cls):
    """ Decorator to expose the given class to business_rules.export_rule_data. """
    cls.export_in_rule_data = True
    return cls


def convert_conll2003_to_iob2(filein, fileout):
    """
    This method will post-process the assembled CoNLL-2003 data for NER.
    It will take an input like:

    and transform it into a simple and readable:
      Japanese  B-NORP
    taking into account the sequence markers and an expected IOB2 scheme.
    """
    with open(filein, 'r') as f1:
        with open(fileout, 'w') as f2:
            previous_tag = 'O'
            for line in f1:
                line_ = line.rstrip()
                if len(line_) == 0 or line_.startswith('-DOCSTART-'):
                    f2.write(line_ + '\n')
                    previous_tag = 'O'
                else:
                    word, pos, phrase, tag = line_.split(' ')
                    if tag == 'O' or tag.startswith('B-'):
                        f2.write(word + '\t' + tag + '\n')
                    else:
                        subtag = tag[2:]
                        if previous_tag.endswith(tag[2:]):
                            f2.write(word + '\t' + tag + '\n')
                        else:
                            f2.write(word + '\tB-' + tag[2:] + '\n')
                    previous_tag = tag


def set_history_length(length):
    """Set the maximal number of items which will be written to
    the history file. A negative length is used to inhibit
    history truncation.
    """
    global _history_length
    _history_length = length


@classmethod
def tag_partition(cls, string, tag, is_re=False, headline=False):
    """Split the string into body parts and sections.

        If `headline` is True, the starting tag line is included for
        sections."""
    in_section = False
    body_parts = []
    sections = []
    tagged_line = ''
    for section in cls.tag_split(string, tag, is_re):
        if section[0]:
            in_section = not in_section
            tagged_line = section[1]
            continue
        if in_section:
            if headline:
                sections.append((tagged_line, section[1]))
            else:
                sections.append(section[1])
        else:
            body_parts.append(section[1])
    return body_parts, sections


def add_default_values(doc, user_name, user_type, **kwargs):
    """
    Adds user_name, user_type, is_active: True, needs_activation: False and the values passed to **kwargs to doc.
    """
    doc['username'] = user_name.strip()
    doc['user_type'] = 'user' if user_type is None else user_type
    doc['is_active'] = True
    doc['is_enabled'] = True
    doc['needs_activation'] = False
    doc.update(**kwargs)


def qbytearray_to_str(qba):
    """Convert QByteArray object to str in a way compatible with Python 2/3"""
    return str(bytes(qba.toHex().data()).decode())


def meta_toggle():
    """Toggle a metastrip (to edit enclosed strips)

    """
    pass


@staticmethod
def number(tree):
    """
        Compiles a number tree
        """
    token = tree.child(0)
    if token.value[0] == '+':
        token.value = token.value[1:]
    if token.type == 'FLOAT':
        return token.value
    return token.value


def default_tc_k_factor_curve():
    """
    Returns a default k factor curve for a generic torque converter.

    :return:
        k factor curve.
    :rtype: callable
    """
    from ..defaults import dfl
    par = dfl.functions.default_tc_k_factor_curve
    a = par.STAND_STILL_TORQUE_RATIO, par.LOCKUP_SPEED_RATIO
    from . import define_k_factor_curve
    return define_k_factor_curve(*a)


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

        :param LegalHoldsExportDownloadedDetails val:
        :rtype: EventDetails
        """
    return cls('legal_holds_export_downloaded_details', val)


def _get_continuous_categorical_columns(feat):
    """
    Finds out which columns are continuous and which
    are categorical in the given dataframe and
    returns them as lists
    """
    continuous_columns = []
    categorical_columns = []
    for col in feat.columns:
        if feat[col].dtype in [int, float]:
            if feat[col].unique().shape[0] / feat.shape[0] < 0.01:
                categorical_columns.append(col)
            else:
                continuous_columns.append(col)
        else:
            categorical_columns.append(col)
    return continuous_columns, categorical_columns


def numatoms(mol) ->int:
    """
    Number of atoms.

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

    Returns
    -------
    int
        Number of atoms
    """
    return mol.OBMol.NumAtoms()


def read():
    """Obtain the parsed manifest data structure.

        The returned object conforms to the ``imanifestdict`` interface.
        """


def poll(cache, conn, cursor):
    """
        Poll for invalidations since the last taken state of the viewer.

        Update the state of the viewer and update the global state maintained
        in this coordinator.

        This should be the first thing done after the *conn* is opened or
        a transaction has begun: in fact, to ensure that the global
        state never accidentally goes backwards, no snapshot of the database
        should have been taken with the connection yet. The queries we execute
        in this method should establish the snapshot for the first time.
        """


def to_str(str_or_bytes, encoding='utf-8'):
    """Take argument and return as unicode string.

    :param str_or_bytes: argument to decode.
    :type str_or_bytes: str or bytes
    :param encoding: the encoding to use if argument is of type bytes
    :returns: argument as unicode string.
    :rtype: str
    """
    if isinstance(str_or_bytes, bytes):
        value = str_or_bytes.decode(encoding)
    else:
        value = str_or_bytes
    return value


def create_or_update_problem(problem):
    """
        Persists given `problem` if no other problem of same `hash` exists in
        the database, updates description, last occurrence date and increments
        occurrence counter either way.
        """


def typeof(obj, t):
    """Check if a specific type instance is a subclass of the type.

    Args:
       obj: Concrete type instance
       t: Base type class

    """
    try:
        return issubclass(obj, t)
    except TypeError:
        return False


@staticmethod
def p_if_data_memory_layout_optional_list(p):
    """if_data_memory_layout_optional_list : if_data_memory_layout_optional
                                               | if_data_memory_layout_optional if_data_memory_layout_optional_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


@classmethod
def flush(cls, key=None, default=None):
    """Flush a specific key or all of the databag (i.e. return and delete).

        Args:
            key(str): Key to set(i.e. 'foo' or 'foo.bar.baz' for a deep key)
            default(object, optional): Defaults to None. Default if key does not exist

        Returns:
            object: Value of the key
        """
    if key:
        data = cls.get(key, default)
        cls.delete(key)
        return data
    data = cls.all()
    cls.clear()
    return data


def replicaset_find(client):
    """Check if a replicaset exists.

    Args:
        client (cursor): Mongodb cursor on admin database.
        replica_set (str): replica_set to check.

    Returns:
        dict: when user exists, False otherwise.
    """
    for rs in client['local'].system.replset.find({}):
        return rs['_id']
    return False


@staticmethod
def get_triage_store(stream):
    """Get the name of the triaging store from the stream object"""
    return stream.triageStoreId.name


def downgrade():
    """Migrations for the downgrade."""


def PrintMatchingResults(bestmat_list, stats_res_list):
    """
    print on stdout  matching results
    """
    print('\n-----------------------------------------')
    print('results:')
    print('matrix:                                         matching results')
    if len(stats_res_list) == 1 and len(bestmat_list) != 1:
        bestmat_list = [bestmat_list]
    for mat_elem, stat_elem in zip(bestmat_list, stats_res_list):
        mean_angular_residues = stat_elem[2]
        matching_rate = 100.0 * stat_elem[0] / stat_elem[1]
        for kkk in list(range(3)):
            txt = '%s        ' % str(mat_elem[kkk])
            if kkk == 0:
                txt += 'res: %s %.3f %.2f' % (str(stat_elem[:2]),
                    mean_angular_residues, matching_rate)
            if len(stat_elem) > 3:
                if kkk == 1:
                    txt += 'spot indices %s' % str(stat_elem[3])
                if kkk == 2:
                    txt += 'planes %s' % str(stat_elem[4].tolist())
            print('%s' % txt)
        print('')


def get_day_seconds(days=1):
    """
    get days seconds
    :param days:int
    :return:int
    """
    return int(60 * 60 * 24 * abs(days))


def get_value_with_default(var_to_check, default):
    """
    Used when taking values from args of env vars
    :param var_to_check:
    :param default:
    :return:
    """
    if var_to_check:
        return var_to_check
    else:
        return default


def _update_freq_matrix(freq_matrix, indices, freq):
    """
    This updates the frequency matrix by subtracting the supplied frequency from
    the found reads.

    Parameters
    ----------

    freq_matrix : bioa.FrequencyMatrix
        The frequency matrix over the reads.

    indices : list
        List of indices where the chosen reads were in the original matrix.

    freq : float
        The frequency to deduct from other reads.

    Returns
    -------
    None
    """
    for cdx, rdx in enumerate(indices):
        read, val = freq_matrix[cdx][rdx]
        val = max([0, val - freq])
        freq_matrix[cdx][rdx] = read, val
    return


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

        :param GetThumbnailBatchResultData val:
        :rtype: GetThumbnailBatchResultEntry
        """
    return cls('success', val)


def plot_phase_plane(x, y, indices=None, plot=None, names=None, ax=None, **
    kwargs):
    """ Plot the phase portrait of two dependent variables

    Parameters
    ----------
    x: array_like
        Values of the independent variable.
    y: array_like
        Values of the dependent variables.
    indices: pair of integers (default: None)
        What dependent variable to plot for (None => (0, 1)).
    plot: callable (default: None)
        Uses ``matplotlib.pyplot.plot`` if ``None``
    names: iterable of strings
        Labels for x and y axis.
    \\*\\*kwargs:
        Keyword arguemtns passed to ``plot()``.

    """
    if indices is None:
        indices = 0, 1
    if len(indices) != 2:
        raise ValueError('Only two phase variables supported at the moment')
    if ax is None:
        import matplotlib.pyplot as plt
        ax = plt.subplot(1, 1, 1)
    if names is not None:
        ax.set_xlabel(names[indices[0]])
        ax.set_ylabel(names[indices[1]])
    ax.plot(y[:, (indices[0])], y[:, (indices[1])], **kwargs)


def nominal(x):
    """Return the nominal value of an uncertainty quantity.
     This free function allows multiple uncertain quantity types to be supported
     in a generic way."""
    try:
        return x.nominal
    except AttributeError:
        try:
            return x.value
        except AttributeError:
            return x


def _to_hours_mins_secs(time_taken):
    """Convert seconds to hours, mins, and seconds."""
    mins, secs = divmod(time_taken, 60)
    hours, mins = divmod(mins, 60)
    return hours, mins, secs


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

        :param DeviceDeleteOnUnlinkSuccessType val:
        :rtype: EventType
        """
    return cls('device_delete_on_unlink_success', val)


def filter_subnodes(elem, t):
    """ Return a list with all subnodes of a certain concept or role which conform to the given Python type """
    return list(filter(lambda x: type(x) == t, elem.flatten()))


@classmethod
def disable(cls):
    """Disables console domain, prevents further console messages from being reported to the client.
        """
    return cls.build_send_payload('disable', {}), None


def fullname(o):
    """Object's full name.
    :param object o: object.
    :returns: full name.
    """
    return o.__class__.__module__ + '.' + o.__class__.__name__


def getSelectedPaymentData():
    """Returns the payment method of the current customer.
        """


@classmethod
def getSupportedSymbolNames(cls):
    """Returns the list of supported symbol human-readable names.

        :rtype: tuple of str
        """
    return tuple(cls._SUPPORTED_SYMBOLS.values())


def methods_of(obj):
    """Get all callable methods of an object that don't start with underscore

    returns a list of tuples of the form (method_name, method)
    """
    result = []
    for i in dir(obj):
        if callable(getattr(obj, i)) and not i.startswith('_'):
            result.append((i, getattr(obj, i)))
    return result


def select(extend: bool=False, deselect: bool=False, toggle: bool=False,
    location: float=(0.0, 0.0)):
    """Select spline points

    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    :param deselect: Deselect, Remove from selection
    :type deselect: bool
    :param toggle: Toggle Selection, Toggle the selection
    :type toggle: bool
    :param location: Location, Location of vertex in normalized space
    :type location: float
    """
    pass


def provides(base):
    """Returns whether or not this extension can provide for the
        server."""
    return False


def float01(flt):
    """Float value between 0 and 1"""
    flt = float(flt)
    if flt < 0 or flt > 1:
        raise ValueError('Input must be between 0 and 1!')
    return flt


def delete(project, version=None):
    """Delete the egg stored for the given project and version. If should
        also delete the project if no versions are left"""


def _merge_element_contents(el):
    """
    Removes an element, but merges its contents into its place, e.g.,
    given
Hi there!
, if you remove the  element you get

Hi there!

    """
    parent = el.getparent()
    text = el.text or ''
    if el.tail:
        if not len(el):
            text += el.tail
        elif el[-1].tail:
            el[-1].tail += el.tail
        else:
            el[-1].tail = el.tail
    index = parent.index(el)
    if text:
        if index == 0:
            previous = None
        else:
            previous = parent[index - 1]
        if previous is None:
            if parent.text:
                parent.text += text
            else:
                parent.text = text
        elif previous.tail:
            previous.tail += text
        else:
            previous.tail = text
    parent[index:index + 1] = el.getchildren()


@classmethod
def iter_instances(cls):
    """Iterate instances.

        :return: Hoster instances
        """
    raise NotImplementedError(cls.iter_instances)


@staticmethod
def _enc(name):
    """If string is Unicode encode it into UTF-8"""
    if isinstance(name, type(u'')):
        name = name.encode('utf_8')
    return name


def print_error(line_no, message):
    """
    Method called when error occurs
    """
    print('Line: %s --- %s' % (line_no, message))


def dictify(x):
    """Ensure `x` is a dict.
    """
    if isinstance(x, dict):
        return x
    elif x:
        return dict(x)
    else:
        return dict()


@staticmethod
def get_tags(instance):
    """
        Returns a dictionary of tags
        """
    return instance['tags']


def print_examples():
    """Print some examples on how to use this program"""
    examples = """protonvpn connect
               Display a menu and select server interactively.

protonvpn c BE-5
               Connect to BE#5 with the default protocol.

protonvpn connect NO#3 -p tcp
               Connect to NO#3 with TCP.

protonvpn c --fastest
               Connect to the fastest VPN Server.

protonvpn connect --cc AU
               Connect to the fastest Australian server
               with the default protocol.

protonvpn c --p2p -p tcp
               Connect to the fastest torrent server with TCP.

protonvpn c --sc
               Connect to the fastest Secure-Core server with
               the default protocol.

protonvpn reconnect
               Reconnect the currently active session or connect
               to the last connected server.

protonvpn disconnect
               Disconnect the current session.

protonvpn s
               Print information about the current session."""
    print(examples)


def clean(inst):
    """Routine to return PLATFORM/NAME data cleaned to the specified level

    Cleaning level is specified in inst.clean_level and pysat
    will accept user input for several strings. The clean_level is
    specified at instantiation of the Instrument object.

    'clean' All parameters should be good, suitable for statistical and
            case studies
    'dusty' All paramers should generally be good though same may
            not be great
    'dirty' There are data areas that have issues, data should be used
            with caution
    'none'  No cleaning applied, routine not called in this case.

    Parameters
    -----------
    inst : (pysat.Instrument)
        Instrument class object, whose attribute clean_level is used to return
        the desired level of data selectivity.

    Returns
    --------
    Void : (NoneType)
        data in inst is modified in-place.

    Notes
    -----

    """
    return


def list_network_rules(cmd, client, resource_group_name, vault_name):
    """ Lists the network rules from the network ACLs for a Key Vault. """
    vault = client.get(resource_group_name=resource_group_name, vault_name=
        vault_name)
    return vault.properties.network_acls


def is_comment_header(line):
    """Returns if the line is a comment header line."""
    line = line.strip()
    if line.startswith('#'):
        return True
    else:
        return False


def getTOFbetaDeriv(dsp):
    """get derivatives of TOF peak profile beta wrt beta-0, beta-1, & beat-q

    :param float dsp: d-spacing of peak

    :returns: list getTOFbetaDeriv: d(beta)/d(beat-0), d(beta)/d(beta-1) & d(beta)/d(beta-q)

    """
    return 1.0, 1.0 / dsp ** 4, 1.0 / dsp ** 2


@classmethod
def setup(cls, config_key, default_timeout=5, raise_errors=True,
    xml_rules_file_name=None):
    """
        Call this method before start using the SDK
        :param config_key: mandatory parameter, configuration key provided
         by Kount
        :param default_timeout: request timeout, default value is 5 seconds
        :param raise_errors: indicate if the request should throw an exception
         in case of error, default value is True
        :param xml_rules_file_name: xml rules for validation of the request,
         should not be overwritten, unless you know what you are doing
        """
    cls._CONFIGURATION_KEY = config_key
    cls._DEFAULT_TIMEOUT = default_timeout
    cls._RAISE_ERRORS = raise_errors
    if xml_rules_file_name:
        cls._XML_FILENAME = xml_rules_file_name
    from .util import khash
    k = khash.Khash(config_key)
    k.verify()


def _set_delta_rbound(d, size):
    """Truncate the given delta to the given size
    :param size: size relative to our target offset, may not be 0, must be smaller or equal
        to our size
    :return: d"""
    d.ts = size
    return d


def disable_notebook():
    """Disable the automatic display of figures in the IPython Notebook.

    See Also
    --------
    :func:`enable_notebook` : automatically embed figures in IPython notebook
    """
    try:
        from IPython.core.getipython import get_ipython
        from matplotlib.figure import Figure
    except ImportError:
        raise ImportError('This feature requires IPython 1.0+ and Matplotlib')
    ip = get_ipython()
    formatter = ip.display_formatter.formatters['text/html']
    formatter.type_printers.pop(Figure, None)


def percent(k: int, n: int) ->str:
    """Format a fraction with percentage"""
    if n == 0:
        pc = ''
    else:
        pc = ' (%.1f%%)' % (100.0 * k / n)
    return '%d/%d' % (k, n) + pc


def circuit_failed(circuit, **kw):
    """
        A circuit has been closed because something went wrong.

        The circuit won't be in the TorState's list anymore.

        :param kw:
            A dict of additional args. REASON is alsways included, and
            often REMOTE_REASON also. See the control-spec
            documentation.  As of this writing, REASON is one of the
            following strings: MISC, RESOLVEFAILED, CONNECTREFUSED,
            EXITPOLICY, DESTROY, DONE, TIMEOUT, NOROUTE, HIBERNATING,
            INTERNAL,RESOURCELIMIT, CONNRESET, TORPROTOCOL,
            NOTDIRECTORY, END, PRIVATE_ADDR. However, don't depend on
            that: it could be anything.

            To facilitate declaring args you want in the method
            (e.g. ``circuit_failed(self, circuit, reason=None,
            remote_reason=None, **kw)``) lower-case versions of all the
            keys are also provided (pointing to the same -- usually
            UPPERCASE -- strings as the upper-case keys).
        """


def primes(imax):
    """
    Returns prime numbers up to imax.

    Parameters
    ----------
    imax: int
        The number of primes to return. This should be less or equal to 10000.

    Returns
    -------
    result: list
        The list of prime numbers.
    """
    p = range(10000)
    result = []
    k = 0
    n = 2
    if imax > 10000:
        raise ValueError('imax should be <= 10000')
    while len(result) < imax:
        i = 0
        while i < k and n % p[i] != 0:
            i = i + 1
        if i == k:
            p[k] = n
            k = k + 1
            result.append(n)
            if k > 10000:
                break
        n = n + 1
    return result


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

        :param ShowcaseFileRemovedType val:
        :rtype: EventType
        """
    return cls('showcase_file_removed', val)


@classmethod
def unregister(cls, symbol):
    """Unregister a token class from the symbol table."""
    del cls.symbol_table[symbol.strip()]


def warning(msg):
    """issue a warning message to the user"""
    print('WARNING')
    print(msg)


def dw_WriteAttributesFile(fname, noseg):
    """
    Generates a Delwaq atributes (*.atr) file.

    input:
    - fname : file name to write to
    - noseg : number of delwaq segments
    """
    line_length = 100
    n_lines = noseg // line_length
    remaining_length = noseg % line_length
    buff = ''
    buff += '         ; DELWAQ_COMPLETE_ATTRIBUTES\n'
    buff += '    2    ; two blocks with input\n'
    buff += '    1    ; number of attributes, they are :\n'
    buff += "    1    ;  '1' is active '0' is no\n"
    buff += '    1    ; data follows in this fil\n'
    buff += '    1    ; all data is given without defaults\n'
    buff += ';    layer:            1\n'
    for iline in range(n_lines):
        buff += ' '.join(['1' for _ in range(line_length)])
        buff += '\n'
    buff += ' '.join(['1' for _ in range(remaining_length)])
    buff += '\n'
    buff += '    1    ; number of attributes, they are :\n'
    buff += "    2    ;  '1' has surface '3' has bottom\n"
    buff += "         ;  '0' has both    '2' has none\n"
    buff += '    1    ; data follows in this file\n'
    buff += '    1    ; all data is given without defaults\n'
    buff += ';    layer:            1\n'
    for iline in range(n_lines):
        buff += ' '.join(['0' for _ in range(line_length)])
        buff += '\n'
    buff += ' '.join(['0' for _ in range(remaining_length)])
    buff += '\n'
    buff += '    0    ; no time dependent attributes\n'
    f = open(fname, 'w')
    f.write(buff)
    f.close()


@staticmethod
def truncate_string(value: str, max_bytes: int, encoding: str) ->bytes:
    """
        Truncates a string value to the specified number of bytes.

        :return:
            Returns bytes, truncated to the correct length.

            Note: Might be a bit shorter than `max_bytes`, to avoid
            orphaning a multibyte sequence.
        """
    bytes_ = bytearray(value.encode(encoding))
    if encoding.lower() in ['utf-8', 'utf8']:
        truncated = bytes_[0:max_bytes]
        for i, o in enumerate(reversed(truncated), start=1):
            if i < 2 and o < 128:
                break
            if o >= 192:
                seq_length = 4 if o >= 240 else 3 if o >= 224 else 2
                if seq_length != i:
                    truncated = truncated[0:-i]
                break
        return truncated
    else:
        trim = 0
        while True:
            truncated = bytes_[0:max_bytes - trim]
            try:
                truncated.decode(encoding)
            except UnicodeDecodeError:
                trim += 1
            else:
                return bytes(truncated)
            if trim >= max_bytes:
                raise ValueError(
                    'Unable to truncate {bytes_!r} to {max_bytes} bytes when encoded using {encoding}.'
                    .format(bytes_=bytes_, max_bytes=max_bytes, encoding=
                    encoding))


def phi_square_calc(chi_square, POP):
    """
    Calculate phi-squared.

    :param chi_square: chi squared
    :type chi_square : float
    :param POP: population
    :type POP : int
    :return: phi_squared as float
    """
    try:
        return chi_square / POP
    except Exception:
        return 'None'


def simport(modname):
    """
    Safely import a module without raising an error.

    Parameters
    -----------
    modname : str
              module name needed to import

    Returns
    --------
    tuple of (True, Module) or (False, None) depending on whether the import
    succeeded.

    Notes
    ------
    Wrapping this function around an iterative context or a with context would
    allow the module to be used without necessarily attaching it permanently in
    the global namespace:

        for t,mod in simport('pandas'):
            if t:
                mod.DataFrame()
            else:
                #do alternative behavior here
            del mod #or don't del, your call

    instead of:

        t, mod = simport('pandas')
        if t:
            mod.DataFrame()
        else:
            #do alternative behavior here

    The first idiom makes it work kind of a like a with statement.
    """
    try:
        exec('import {}'.format(modname))
        return True, eval(modname)
    except:
        return False, None


@classmethod
def from_api_data(cls, api_data, auth_token=None, session=None):
    """Return a new instance populated with data from the API"""
    work = cls(api_data.get('id'), auth_token=auth_token, session=session)
    work._load_data(api_data)
    return work


@staticmethod
def get_demo_args():
    """
        Returns iterable of arguments needed to initialize notification for demo purposes
        Usually you want to generate dummy data here for testing
        """
    return []


def sct_report_string(report):
    """Return a human-readable string representation of the error report
    returned by lxml's schematron validator.
    """
    ret = []
    namespaces = {'svrl': 'http://purl.oclc.org/dsdl/svrl'}
    for index, failed_assert_el in enumerate(report.findall(
        'svrl:failed-assert', namespaces=namespaces)):
        ret.append('{}. {}'.format(index + 1, failed_assert_el.find(
            'svrl:text', namespaces=namespaces).text))
        ret.append('   test: {}'.format(failed_assert_el.attrib['test']))
        ret.append('   location: {}'.format(failed_assert_el.attrib[
            'location']))
        ret.append('\n')
    return '\n'.join(ret)


def _getitem_from_frame(f_locals, key, default=None):
    """
    f_locals is not guaranteed to have .get(), but it will always
    support __getitem__. Even if it doesnt, we return ``default``.
    """
    try:
        return f_locals[key]
    except Exception:
        return default


def convert_registers_to_double(registers):
    """
    Convert two 16 Bit Registers to 32 Bit long value - Used to receive 32 Bit values from Modbus (Modbus Registers are 16 Bit long)
    registers: 16 Bit Registers
    return: 32 bit value
    """
    returnValue = int(registers[0]) & 65535 | int(registers[1] << 16
        ) & 4294901760
    return returnValue


def _stop(evt):
    """simple wrapper for stopping an Event, allowing for method rename in gevent 1.0"""
    try:
        evt.stop()
    except AttributeError as e:
        evt.cancel()


def stopped(reason):
    """
        The flow of data from this L{ITube}'s input has ceased; this
        corresponds to L{IDrain.flowStopped}.

        @note: L{ITube} I{has} no notification corresponding to
            L{IFount.stopFlow}, since it has no control over whether additional
            data will be synthesized / processed by I{its} fount, there's no
            useful work it can do.

        @return: The same as L{ITube.received}; values returned (or yielded) by
            this method will be propagated before the L{IDrain.flowStopped}
            notification to the downstream drain.
        @rtype: same as L{ITube.received}
        """


def empty(x):
    """Returns the empty value of its argument's type. Ramda defines the empty
value of Array ([]), Object ({}), String (''), and Arguments. Other
types are supported if they define <Type>.empty,
<Type>.prototype.empty or implement the
FantasyLand Monoid spec.
Dispatches to the empty method of the first argument, if present"""
    if x:
        return False
    else:
        return True


def isarray(o):
    """Checks whether or nor an object is an array.

    Parameters
    ----------
    o : object
        Some object.

    Returns
    -------
    bool
        Indicates whether or not the object is an array.

    Examples
    --------

    >>> isarray([1, 2, 3])
    True
    >>> isarray('text')
    False

    """
    return not isinstance(o, str) and hasattr(o, '__getitem__') and hasattr(o,
        '__iter__')


def quote_filter(value, single_quotes=False):
    """
    Wraps an input string in quotes.

    Args:
        value (string): the original string
    Returns:
        string: the quoted string
    """
    if single_quotes:
        return "'" + str(value) + "'"
    else:
        return '"' + str(value) + '"'


def geos2cf(proj_dict):
    """Return the cf grid mapping from a geos proj dict.
    """
    return {'grid_mapping_name': 'geostationary',
        'latitude_of_projection_origin': 0.0,
        'longitude_of_projection_origin': eval(proj_dict['lon_0']),
        'semi_major_axis': eval(proj_dict['a']), 'semi_minor_axis': eval(
        proj_dict['b']), 'perspective_point_height': eval(proj_dict['h'])}


def checksubstate(repo, baserev=None):
    """return list of subrepos at a different revision than substate.
    Abort if any subrepos have uncommitted changes."""
    inclsubs = []
    wctx = repo[None]
    if baserev:
        bctx = repo[baserev]
    else:
        bctx = wctx.p1()
    for s in sorted(wctx.substate):
        wctx.sub(s).bailifchanged(True)
        if s not in bctx.substate or bctx.sub(s).dirty():
            inclsubs.append(s)
    return inclsubs


def initialize(debug=None):
    """Initialize the database layer, using whatever means necessary.

        :param debug: When None (the default), the configuration file
            determines whether the database layer should have increased
            debugging or not.  When True or False, this overrides the
            configuration file setting.
        """


def unset_order():
    """Removes the folder internal ordering, making it an unordered
        folder."""


def attach_volume(DryRun=None, VolumeId=None, InstanceId=None, Device=None):
    """
    Attaches an EBS volume to a running or stopped instance and exposes it to the instance with the specified device name.
    Encrypted EBS volumes may only be attached to instances that support Amazon EBS encryption. For more information, see Amazon EBS Encryption in the Amazon Elastic Compute Cloud User Guide .
    For a list of supported device names, see Attaching an EBS Volume to an Instance . Any device names that aren't reserved for instance store volumes can be used for EBS volumes. For more information, see Amazon EC2 Instance Store in the Amazon Elastic Compute Cloud User Guide .
    If a volume has an AWS Marketplace product code:
    For an overview of the AWS Marketplace, see Introducing AWS Marketplace .
    For more information about EBS volumes, see Attaching Amazon EBS Volumes in the Amazon Elastic Compute Cloud User Guide .
    See also: AWS API Documentation

    Examples
    This example attaches a volume (vol-1234567890abcdef0) to an instance (i-01474ef662b89480) as /dev/sdf.
    Expected Output:

    :example: response = client.attach_volume(
        DryRun=True|False,
        VolumeId='string',
        InstanceId='string',
        Device='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 VolumeId: string
    :param VolumeId: [REQUIRED]
            The ID of the EBS volume. The volume and instance must be within the same Availability Zone.

    :type InstanceId: string
    :param InstanceId: [REQUIRED]
            The ID of the instance.

    :type Device: string
    :param Device: [REQUIRED]
            The device name to expose to the instance (for example, /dev/sdh or xvdh ).

    :rtype: dict
    :return: {
        'VolumeId': 'string',
        'InstanceId': 'string',
        'Device': 'string',
        'State': 'attaching'|'attached'|'detaching'|'detached',
        'AttachTime': datetime(2015, 1, 1),
        'DeleteOnTermination': True|False
    }

    :returns:
    DryRun (boolean) -- 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 .
    VolumeId (string) -- [REQUIRED]
    The ID of the EBS volume. The volume and instance must be within the same Availability Zone.

    InstanceId (string) -- [REQUIRED]
    The ID of the instance.

    Device (string) -- [REQUIRED]
    The device name to expose to the instance (for example, /dev/sdh or xvdh ).

    """
    pass


def get_flavor():
    """Get the flavor of the library (jovian or jovian-pro)"""
    try:
        from jovian._flavor import __flavor__
        return __flavor__
    except ImportError:
        return 'jovian'


def commonancestorsheads(node1, node2):
    """Obtain an iterable of nodes containing heads of common ancestors.

        See ``ancestor.commonancestorsheads()``.
        """


def list_associations(AssociationFilterList=None, MaxResults=None,
    NextToken=None):
    """
    Lists the associations for the specified Systems Manager document or instance.
    See also: AWS API Documentation

    :example: response = client.list_associations(
        AssociationFilterList=[
            {
                'key': 'InstanceId'|'Name'|'AssociationId'|'AssociationStatusName'|'LastExecutedBefore'|'LastExecutedAfter',
                'value': 'string'
            },
        ],
        MaxResults=123,
        NextToken='string'
    )

    :type AssociationFilterList: list
    :param AssociationFilterList: One or more filters. Use a filter to return a more specific list of results.
            (dict) --Describes a filter.
            key (string) -- [REQUIRED]The name of the filter.
            value (string) -- [REQUIRED]The filter value.

    :type MaxResults: integer
    :param MaxResults: The maximum number of items to return for this call. The call also returns a token that you can specify in a subsequent call to get the next set of results.

    :type NextToken: string
    :param NextToken: The token for the next set of items to return. (You received this token from a previous call.)

    :rtype: dict
    :return: {
        'Associations': [
            {
                'Name': 'string',
                'InstanceId': 'string',
                'AssociationId': 'string',
                'DocumentVersion': 'string',
                'Targets': [
                    {
                        'Key': 'string',
                        'Values': [
                            'string',
                        ]
                    },
                ],
                'LastExecutionDate': datetime(2015, 1, 1),
                'Overview': {
                    'Status': 'string',
                    'DetailedStatus': 'string',
                    'AssociationStatusAggregatedCount': {
                        'string': 123
                    }
                },
                'ScheduleExpression': 'string'
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    (string) --

    """
    pass


def apply_bids_label_restrictions(value):
    """Sanitize file names for BIDS.
    """
    if value is None:
        return None
    from six import string_types
    if not isinstance(value, string_types):
        value = str(value)
    import re
    pattern = re.compile('[\\W_]+')
    return pattern.sub('', value)


def islast(iterable):
    """
	Iterate through items of the iterable and give information about whether the
	item is the last in the iterable::

		>>> list(misc.islast("foo"))
		[(False, 'f'), (False, 'o'), (True, 'o')]
	"""
    lastitem = None
    it = iter(iterable)
    try:
        item = next(it)
    except StopIteration:
        return
    while True:
        try:
            lastitem, item = item, next(it)
        except StopIteration:
            yield True, item
            return
        else:
            yield False, lastitem


def unit_fn(arg):
    """Used as dummy serializer and deserializer."""
    return arg


def getRootURL():
    """
        Get a previously-remembered URL.
        """


@staticmethod
def startDiagram(*args):
    """ Called first during the render to initialise a diagram """
    pass


def info_dict(H, obj=None):
    """
    Create a summary of simple statistics for H

    Parameters
    ----------
    H : Hypergraph
    obj : optional
        either a node or edge uid from the hypergraph

    Returns
    -------
     info_dict : dict
        Returns a dictionary of statistics of the size,
        aspect ratio, and density of the hypergraph.

    """
    report = dict()
    if not H.edges.elements:
        return {}
    if obj:
        if obj in H.nodes:
            membs = list(H.nodes[obj].memberships)
            report['degree'] = len(membs)
        if obj in H.edges:
            report['size'] = H.edges[obj].size()
    else:
        lnodes = len(H.nodes)
        ledges = len(H.edges)
        M = H.incidence_matrix(index=False)
        ncells = M.nnz
        report['nrows'] = lnodes
        report['ncols'] = ledges
        report['aspect ratio'] = lnodes / ledges
        report['ncells'] = ncells
        report['density'] = ncells / (lnodes * ledges)
    return report


def _safe_single_attr(x):
    """Handle cleaning of attributes after extraction:
      - '.'s to indicate None
      - tuples where we expect a single value
    """
    if x is None or x is '.':
        return None
    elif isinstance(x, (list, tuple)):
        return x[0]
    else:
        return x


@classmethod
def _from_file(cls, directory: str):
    """Internal method to load a table from disk."""
    return cls(directory=directory)


@classmethod
def from_pycbc(cls, fs, copy=True):
    """Convert a `pycbc.types.frequencyseries.FrequencySeries` into
        a `FrequencySeries`

        Parameters
        ----------
        fs : `pycbc.types.frequencyseries.FrequencySeries`
            the input PyCBC `~pycbc.types.frequencyseries.FrequencySeries`
            array

        copy : `bool`, optional, default: `True`
            if `True`, copy these data to a new array

        Returns
        -------
        spectrum : `FrequencySeries`
            a GWpy version of the input frequency series
        """
    return cls(fs.data, f0=0, df=fs.delta_f, epoch=fs.epoch, copy=copy)


def safe_method(func):
    """
    Marks function as safe to use by the api
    """
    func.safe_method = True
    return func


def abort_pr_review_arguments(parser):
    """ Abort review of pull request.
    """
    parser.add_argument('name', type=str, action='store', nargs=1, help=
        'pull request name')


def implementation():
    """ Return the object that the underlying templating system
        uses to render the template; it is typically a callable that
        accepts arbitrary keyword arguments and returns a string or
        unicode object """


@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": {
               "message_analyzed": {
                    "type": "text",
                    "index": true
               }
           }
        }"""
    return {'items': mapping}


def get_indices(seq, val):
    """Return indices of elements containing given value in a sequence."""
    r = []
    for i, v in enumerate(seq):
        if v == val:
            r.append(i)
    return r


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


@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 set_config(config):
    """
    Store parsing config object.

    :type config: ``dict``

    :rtype: ``dict``
    """
    global CONFIG
    CONFIG = config
    return config


def ShowDockingGuides(guides, show):
    """
    Shows or hide the docking guide windows.

    :param `guides`: a list of :class:`AuiDockingGuide` classes;
    :param bool `show`: whether to show or hide the docking guide windows.
    """
    for target in guides:
        if show and not target.host.IsShown():
            target.host.Show()
            target.host.Update()
        elif not show and target.host.IsShown():
            target.host.Hide()


def get_labels(ds, qties, weight, normed):
    """
    Returns the labels of given qties.

    Parameters
    ----------
    ds : {PhaseSpace, ScalarField, EventLocation}
        Dataset to use.
    qties : list of str
        Names of the qties
    normed : list of bool or None
        Weight normalization. If None, the last labels element is "Number", otherwise it is "Number/unit1/unit2/..."

    Returns
    -------
    labels : list of str
        Labels of given qty and label of weight
    """
    labels = []
    qties_labels = []
    qties_units = []
    for qty in qties:
        qties_labels.append(ds.metadata.quantity[qty]['label'])
        qty_dim = ds.metadata.quantity[qty]['dimension']
        qties_units.append(ds.metadata.unit[qty_dim]['label'])
    axis_labels = []
    for qty_label, qty_unit in zip(qties_labels, qties_units):
        if qty_unit == '':
            axis_labels.append('${label}$'.format(label=qty_label))
        else:
            axis_labels.append('${label}$ [${unit}$]'.format(label=
                qty_label, unit=qty_unit))
    weight_label = ds.metadata.quantity[weight]['label']
    weight_dim = ds.metadata.quantity[weight]['dimension']
    weight_unit = ds.metadata.unit[weight_dim]['label']
    title_unit = ' ~'.join(qties_units)
    if normed == False:
        title_label = '${label}$'.format(label=weight_label)
    else:
        numerator_label = 'd' + weight_label
        denominator_label = 'd' + ' ~d'.join(qties_labels)
        if title_unit.strip() == '':
            title_label = '$%s/%s$' % (numerator_label, denominator_label)
        else:
            title_label = '$%s/%s$ [$(%s)^{-1}$]' % (numerator_label,
                denominator_label, title_unit)
    return [*axis_labels, title_label]


def sort_ballot(ballot):
    """Put a ballot in alphabetical order.

    Parameters
    ----------
    ballot : str
        A ballot, e.g. ``'a'``, ``'ab'``, ``'ba'``, etc.

    Returns
    -------
    str
        The same ballot in alphabetical order.

    Examples
    --------
        >>> sort_ballot('a')
        'a'
        >>> sort_ballot('ab')
        'ab'
        >>> sort_ballot('ba')
        'ab'
    """
    return ''.join(sorted(ballot))


def iter_slices(string, slice_length):
    """Iterate over slices of a string."""
    pos = 0
    if slice_length is None or slice_length <= 0:
        slice_length = len(string)
    while pos < len(string):
        yield string[pos:pos + slice_length]
        pos += slice_length


@staticmethod
def _cmp_closed(low, item, high):
    """
        The ranges are closed intervals, i.e.
        value is in interval if and only if start <= value <= stop
        """
    if low <= high:
        return low <= item <= high
    return low <= item or item <= high


@classmethod
def set_position(cls, x_pos, y_pos):
    """ sets the cursor position """
    position = u'\x1b[' + str(x_pos) + ';' + str(y_pos) + 'H'
    print(position)


@classmethod
def inch(cls, x=None, y=None):
    """
        Return the character and attributes of the character at the specified
        position in the window or cursor.

        :param x: optional x value
        :param y: optional y value
        :return: (character, attributes)
        """
    x, y = cls._fix_xy(x, y)
    ret = cls.WINDOW.inch(y, x)
    char = 15 & ret
    attrs = 240 & ret
    return char, attrs


def stimKeywords(hdr, segment, avg_s1, avg_s2, rms_s1, rms_s2, s1_ref, s2_ref):
    """Update keywords for the locations of the stims.

    hdr: pyfits Header object
        The input events extension header (updated).

    segment: {"FUVA", "FUVB"}
        Segment name.

    avg_s1:  list of two floats
        avg_s1[0] is the average Y location of the first stim.
        avg_s1[1] is the average X location of the first stim.

    avg_s2:  list of two floats
        avg_s2[0] is the average Y location of the second stim.
        avg_s2[1] is the average X location of the second stim.

    rms_s1:  list of two floats
        rms_s1[0] is the RMS in Y for the first stim.
        rms_s1[1] is the RMS in X for the first stim.

    rms_s2:  list of two floats
        rms_s2[0] is the RMS in Y for the second stim.
        rms_s2[1] is the RMS in X for the second stim.

    s1_ref:  list of two floats
        s1_ref[0] is the Y position of the first stim, from the BRFTAB.
        s1_ref[1] is the X position of the first stim, from the BRFTAB.

    s2_ref:  list of two floats
        s2_ref[0] is the Y position of the second stim, from the BRFTAB.
        s2_ref[1] is the X position of the second stim, from the BRFTAB.
    """
    seg = segment[-1]
    hdr['STIM' + seg + '0LX'] = s1_ref[1]
    hdr['STIM' + seg + '0LY'] = s1_ref[0]
    hdr['STIM' + seg + '0RX'] = s2_ref[1]
    hdr['STIM' + seg + '0RY'] = s2_ref[0]
    if avg_s1[0] is None or avg_s1[1] is None:
        hdr['STIM' + seg + '_LX'] = -1.0
        hdr['STIM' + seg + '_LY'] = -1.0
    else:
        hdr['STIM' + seg + '_LX'] = round(avg_s1[1], 3)
        hdr['STIM' + seg + '_LY'] = round(avg_s1[0], 3)
        hdr['STIM' + seg + 'SLX'] = round(rms_s1[1], 3)
        hdr['STIM' + seg + 'SLY'] = round(rms_s1[0], 3)
    if avg_s2[0] is None or avg_s2[1] is None:
        hdr['STIM' + seg + '_RX'] = -1.0
        hdr['STIM' + seg + '_RY'] = -1.0
    else:
        hdr['STIM' + seg + '_RX'] = round(avg_s2[1], 3)
        hdr['STIM' + seg + '_RY'] = round(avg_s2[0], 3)
        hdr['STIM' + seg + 'SRX'] = round(rms_s2[1], 3)
        hdr['STIM' + seg + 'SRY'] = round(rms_s2[0], 3)


@classmethod
def instance(cls, *args, **kwgs):
    """Will be the only instance"""
    if not hasattr(cls, '_instance'):
        cls._instance = cls(*args, **kwgs)
    return cls._instance


@staticmethod
def get_length(x) ->int:
    """Return total packet length."""
    datalen = x._.data.length
    return datalen + 32


def format_size(size):
    """Return file size as string from byte size."""
    for unit in ('B', 'KB', 'MB', 'GB', 'TB'):
        if size < 2048:
            return '%.f %s' % (size, unit)
        size /= 1024.0


def isqrt(n):
    """
    Find the integer square root of a positive integer.
    """
    s = n
    while True:
        d = n // s
        if s <= d:
            return s
        s = (s + d) // 2


def clang_expand_template_args(node, args):
    """TODO: Broken version handling defaults
    automatically::

        count,defaults = clang_template_arg_info(node)
        print('SP %s, COUNT %s, %s, %s'%(node.spelling,count,defaults,args))
        if len(args) < count:
            return tuple(args) + defaults[(count-len(args)):]
        return tuple(args)+defaults[count-len(args)]

    TODO: Needs a better docstring.
    """
    return args


def get_connection_index(connection, terminal, d):
    """
    Find if the connection 'C' lies on the edge 'A'-'B', on the edge end 'A' or
    on the edge end 'B' and return the associted connection index.

    Parameters
    ----------
    connection: Series
        Row of the dataframe *connections* obtained from the function
        *dhd.connect.second_selection*.
    terminal: Series
        Row of the dataframe *terminals*.
    d: dict
        Dictionary of the distances between the connection and the edge ends.

    Returns
    -------
    bool
        True if 'C' lies on 'A'-'B', False otherwise.
    str
        Index of the connection 'C': index of 'A' if 'C'='A', index of 'B' if
        'C'='B', concatenation of the *terminal* index and the *connection*
        index otherwise.
    """
    if d['A'] == 0:
        idC = connection['idA']
        on_edge = False
    elif d['B'] == 0:
        idC = connection['idB']
        on_edge = False
    else:
        idC = '{}_{}'.format(terminal.name, connection.name)
        on_edge = True
    return on_edge, idC


def fix_IE_for_vary(request, response):
    """
    This function will fix the bug reported at
    http://support.microsoft.com/kb/824847/en-us?spid=8722&sid=global
    by clearing the Vary header whenever the mime-type is not safe
    enough for Internet Explorer to handle.  Poor thing.
    """
    useragent = request.META.get('HTTP_USER_AGENT', '').upper()
    if 'MSIE' not in useragent and 'CHROMEFRAME' not in useragent:
        return response
    safe_mime_types = 'text/html', 'text/plain', 'text/sgml'
    mime_type = response.get('Content-Type', '').partition(';')[0]
    if mime_type not in safe_mime_types:
        try:
            del response['Vary']
        except KeyError:
            pass
    return response


def pytest_addoption(parser):
    """Adds `--run-without-docker` argument."""
    group = parser.getgroup('docker_pexpect')
    group.addoption('--run-without-docker', action='store_true', default=
        False, help="Don't use docker")


def diff_lists(list_a, list_b):
    """
    Return the difference between list_a and list_b.

    :param list_a: input list a.
    :param list_b: input list b.
    :return: difference (list).
    """
    return list(set(list_a) - set(list_b))


@classmethod
def _plan_assign_field_values(cls, path, graph, canvas):
    """Assign :class:`FieldValue` to a path.

        :param path: list of node_ids
        :param graph: BrowserGraph instance
        :param canvas: Planner instance
        :return:
        """
    prev_node = None
    for n, ndata in graph.iter_model_data(model_class='AllowableFieldType',
        nbunch=path):
        aft = ndata['model']
        sample = ndata['sample']
        if aft.field_type.role == 'output':
            if 'operation' not in ndata:
                op = canvas.create_operation_by_type_id(aft.field_type.
                    parent_id)
                fv = op.output(aft.field_type.name)
                canvas.set_field_value(fv, sample=sample)
                ndata['field_value'] = fv
                ndata['operation'] = op
            else:
                op = ndata['operation']
            if prev_node:
                input_aft = prev_node[1]['model']
                input_sample = prev_node[1]['sample']
                input_name = input_aft.field_type.name
                if input_aft.field_type.array:
                    input_fv = canvas.set_input_field_value_array(op,
                        input_name, sample=input_sample)
                else:
                    input_fv = canvas.set_field_value(op.input(input_name),
                        sample=input_sample)
                prev_node[1]['field_value'] = input_fv
                prev_node[1]['operation'] = op
        prev_node = n, ndata


def end_of_function_def(editor, start_line):
    """ Find where a function ends, beginning with `start_line` and working forward """
    for i in range(start_line, len(editor.lines)):
        if editor.lines[i].endswith('):'):
            return i
    return None


def find_prepositions(chunked):
    """ The input is a list of [token, tag, chunk]-items.
        The output is a list of [token, tag, chunk, preposition]-items.
        PP-chunks followed by NP-chunks make up a PNP-chunk.
    """
    for ch in chunked:
        ch.append('O')
    for i, chunk in enumerate(chunked):
        if chunk[2].endswith('PP') and chunk[-1] == 'O':
            if i < len(chunked) - 1 and (chunked[i + 1][2].endswith(('NP',
                'PP')) or chunked[i + 1][1] in ('VBG', 'VBN')):
                chunk[-1] = 'B-PNP'
                pp = True
                for ch in chunked[i + 1:]:
                    if not (ch[2].endswith(('NP', 'PP')) or ch[1] in ('VBG',
                        'VBN')):
                        break
                    if ch[2].endswith('PP') and pp:
                        ch[-1] = 'I-PNP'
                    if not ch[2].endswith('PP'):
                        ch[-1] = 'I-PNP'
                        pp = False
    return chunked


@classmethod
def _endf_to_id(cls, endf):
    """Convert ENDF (ZZZAAAM) notation to Nuclide ID integer"""
    return int(endf)


def get(isamAppliance, check_mode=False, force=False):
    """
    Get current date/time settings
    """
    return isamAppliance.invoke_get('Retrieving current date and time settings'
        , '/time_cfg')


@classmethod
def _create_column_info(cls, name: str, data_type: str) ->dict:
    """
        Create column info object
        :param name: column name
        :param data_type: column data type
        :return: column info object
        """
    return {'name': name, 'type': f'{data_type}'}


def get_return_data_type(func_name):
    """Return a somewhat-helpful data type given a function name"""
    if func_name.startswith('get_'):
        if func_name.endswith('_list'):
            return 'List'
        elif func_name.endswith('_count'):
            return 'Integer'
    return ''


@staticmethod
def _parse_dn_pod_node(dn):
    """Parses the pod, node, and slot from a
           distinguished name of the node.

           :param dn: str - distinguished name

           :returns: pod, node, slot strings
        """
    name = dn.split('/')
    pod = str(name[1].split('-')[1])
    node = str(name[2].split('-')[1])
    return pod, node


def type_convert_median(dataframe, colname, data_type):
    """Replace mistyped values with the median on dataframe[colname]"""
    col = dataframe[colname]
    col_numerics = col.loc[col.apply(lambda x: isinstance(x, (int, float)))]
    dataframe.loc[col.notnull() & col.apply(lambda x: not isinstance(x,
        data_type)), colname] = col_numerics.median()
    return dataframe


@staticmethod
def get_cpu_usage():
    """ Get the CPU used by this vertex

        :return:  0
        :rtype: int
        """
    return 0


def computeContribs(urls, rank):
    """Calculates URL contributions to the rank of other URLs."""
    num_urls = len(urls)
    for url in urls:
        yield url, rank / num_urls


def ensurelist(paramname, val, comment='#'):
    """
    Returns `val` as a list of strings.

    If `val` is already a list of strings, it is returned as-is.  If a string
    is passed, it is split into lines and blink and (optionally) comment lines
    are removed.

    paramname
      The parameter name to put into error messages.

    comment
      The single-line comment identifier.  Any lines starting with this are
      removed.  Note that end-of-line comments are *not* removed.
    """
    if isinstance(val, list):
        for line in val:
            if not isinstance(line, str):
                typename = type(line).__qualname__
                raise TypeError(
                    f'{paramname} should be a list of strings.  Found: {typename}'
                    )
        return val
    if isinstance(val, str):
        lines = (line.strip() for line in val.strip().split('\n'))
        lines = (line for line in lines if line)
        if comment:
            lines = (line for line in lines if not line.startswith())
        return lines
    raise TypeError(f'{paramname} must be a list of strings or a string')


def mer_runner_dummy(instance):
    """This method is a helper method for class MerRunner. It allows
    multiprocessing module in python to map parallelism to a class method."""
    instance.meraculous_runner()


def two_dec_places(x, pos):
    """
    Adds 1/100th decimal to plot ticks.
    """
    return '%.2f' % x


@staticmethod
def _auto_detect_post(params):
    """
        Determine if a post request should be made instead of a get depending on the size of the parameters
        in the request.

        Args:
            params (dict): params to pass in the request

        Returns:
            Boolean: True if post is needed
        """
    if params:
        for k, v in params.items():
            if isinstance(v, (list, tuple)):
                if len(v) > 3:
                    return True
    return False


def hist_zero(df, *args, **kwargs):
    """Returns df (no change)"""
    df = df.copy()
    return df


def is_float(val):
    """Check if the given string can be converted to float or not.
    This method is fast when returning True

    Args:
        val (str): The input

    Returns:
        bool: Return True if the input can be converted to float

    """
    try:
        float(val)
        return True
    except ValueError:
        return False


def split(head, x, y, dx, dy):
    """Split the area define by x, y, dx, dy into two rectangular boxes
    along the longer axis

    Returns two split rectanges (x1, y1, dx1, dy1), (x2, y2, dx2, dy2)
    """
    covered_area = sum(head)
    if dx >= dy:
        width = covered_area / dy
        return (x, y, width, dy), (x + width, y, dx - width, dy)
    else:
        height = covered_area / dx
        return (x, y, dx, height), (x, y + height, dx, dy - height)


def init_frag_list(fragment_list, new_frag_list):
    """Adapt the original fragment list to fit the build function requirements

    Parameters
    ----------
    fragment_list : str, file or pathlib.Path
        The input fragment list.
    new_frag_list : str, file or pathlib.Path
        The output fragment list to be written.

    Returns
    -------
    i : int
        The number of records processed this way.
    """
    handle_frag_list = open(fragment_list, 'r')
    handle_new_frag_list = open(new_frag_list, 'w')
    handle_new_frag_list.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (
        'id', 'chrom', 'start_pos', 'end_pos', 'size', 'gc_content',
        'accu_frag', 'frag_start', 'frag_end'))
    handle_frag_list.readline()
    i = 0
    while 1:
        line_frag = handle_frag_list.readline()
        if not line_frag:
            handle_frag_list.close()
            handle_new_frag_list.close()
            break
        i += 1
        data = line_frag.split('\t')
        id_init = data[0]
        contig_name = data[1]
        start_pos = data[2]
        end_pos = data[3]
        length_kb = data[4]
        gc_content = str(float(data[5]))
        accu_frag = str(1)
        frag_start = id_init
        frag_end = id_init
        handle_new_frag_list.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' %
            (id_init, contig_name, start_pos, end_pos, length_kb,
            gc_content, accu_frag, frag_start, frag_end))
    return i


def is_mutating(status):
    """Determines if the statement is mutating based on the status."""
    if not status:
        return False
    mutating = set(['insert', 'update', 'delete'])
    return status.split(None, 1)[0].lower() in mutating


def isiterable(x):
    """Returns `True` if the specified object is iterable."""
    try:
        iter(x)
    except TypeError:
        return False
    return True


def sliding_impl(wrap, size, step, sequence):
    """
    Implementation for sliding_t
    :param wrap: wrap children values with this
    :param size: size of window
    :param step: step size
    :param sequence: sequence to create sliding windows from
    :return: sequence of sliding windows
    """
    i = 0
    n = len(sequence)
    while i + size <= n or step != 1 and i < n:
        yield wrap(sequence[i:i + size])
        i += step


def file_to_str(fname):
    """
    Read a file into a string
    PRE: fname is a small file (to avoid hogging memory and its discontents)
    """
    data = None
    with open(fname, 'rU') as fd:
        data = fd.read()
    return data


@staticmethod
def argparser_get_bareos_parameter(args):
    """
        This method is usally used together with the method argparser_add_default_command_line_arguments.

        @param args: Arguments retrieved by ArgumentParser.parse_args()
        @type args:  ArgParser.Namespace

        @return: returns the relevant parameter from args to initialize a connection.
        @rtype: dict
        """
    result = {}
    for key, value in vars(args).items():
        if value is not None:
            if key.startswith('BAREOS_'):
                bareoskey = key.split('BAREOS_', 1)[1]
                result[bareoskey] = value
    return result


def assert_cmd_has_no_qmark(command: str, context: str='') ->None:
    """Throws Exception if the query contains a question marks."""
    if '?' not in command:
        return
    message = ''
    if context:
        message = ' ' + context
    message = (message +
        "Set commands must not contain question-marks. Sent command: '{0}'"
        .format(command.strip('\n')))
    raise Exception(message)


def _replace_ref(matched, citations):
    """citations: ref => index"""
    cite = matched[7:-3]
    if cite not in citations:
        citations[cite] = len(citations) + 1
    return '[[{i}]](#PYPPL-REF-{i}){{.pyppl-report-refindex}}'.format(i=
        citations[cite])


def create_sql_params(dbkeys=[], **kwargs):
    """Return dictionary of parameters for SQL statement."""
    params = kwargs.copy()
    for i in range(len(dbkeys)):
        params['criterion' + str(i)] = dbkeys[i]
    return params


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 cached_objects(iter):
    """Return objects from a session/iterator that are tagged as cached."""
    for obj in iter:
        if hasattr(obj, '__memcached__'):
            yield obj


def atoi(text):
    """
    helper for natural_keys
    attempt to convert text to int, or return text
    :param text: arbitrary text
    :return: int if succeeded to convert, the input text as is otherwise
    """
    return int(text) if text.isdigit() else text


def pamWithUsernameAndPassword(username, password, service='login'):
    """
        Check username and password using PAM.

        Returns True if credentials are accepted, False otherwise.
        """


@staticmethod
def assign_student(student, school):
    """Assigns a student to a school."""
    student.assigned_school = school
    student.assigned = True
    school.assignation.append(student)


@classmethod
def has_model_perm(cls, principals, permission):
    """Check that one of principals has permission on given model.

        Since this is a classmethod, even if called on a record, only its
        model class will be considered for the permission check.
        """
    return cls.registry.check_permission(cls, principals, permission)


def lnbr(text):
    """Converts line breaks to html breaks
    """
    return '<br/>'.join(text.strip().splitlines()) if text else text


def connectionMade():
    """
        Called when a connection is made.

        This may be considered the initializer of the protocol, because
        it is called when the connection is completed.  For clients,
        this is called once the connection to the server has been
        established; for servers, this is called after an accept() call
        stops blocking and a socket has been received.  If you need to
        send any greeting or initial message, do it here.
        """


@classmethod
def is_wheel_archive(cls, path):
    """Returns True if `path` is a wheel."""
    return path.lower().endswith('.whl')


def load_app(module_name, objects=None):
    """Simply loads and returns an app module for you.

    Params:
    - module_name - module name of your app.
    - objects (str) - if provided, returns a certain part of the module
    instead of the whole thing. Example:
    `load_app('my_app', objects='views')` will return `my_app.views`.
    """
    from importlib import import_module
    if objects:
        return import_module(module_name + '.' + objects)
    else:
        return import_module(module_name)


def int_to_base_n(integer, charset):
    """Convert an integer into a base-N string using a given character set.

    :param int integer: The integer to convert
    :param str charset: The character set to use for the conversion
    :returns str: The converted string
    :raises ValueError: If `charset` contains duplicate characters

    """
    if len(charset) > len(set(charset)):
        raise ValueError('character set contains duplicate characters')
    base = len(charset)
    integer = int(integer)
    places = []
    while integer >= base:
        places.append(charset[integer % base])
        integer //= base
    places.append(charset[integer])
    return ''.join(reversed(places))


def decode(packet):
    """
    https://github.com/telldus/telldus/blob/master/telldus-core/service/ProtocolMandolyn.cpp

    >>> decode(dict(data=0x134039c3))["data"]["temp"]
    7.8
    """
    data = packet['data']
    value = int(data)
    value >>= 1
    temp = ((value & 32767) - 6400) / 128
    temp = round(temp, 1)
    value >>= 15
    humidity = value & 127
    value >>= 7
    value >>= 3
    channel = (value & 3) + 1
    value >>= 2
    house = value & 15
    return dict(packet, sensorId=house * 10 + channel, data=dict(temp=temp,
        humidity=humidity))