def __new__(cls, sha, type, size, stream, *args, **kwargs):
    """Helps with the initialization of subclasses"""
    return tuple.__new__(cls, (sha, type, size, stream))


def json_append(filename, entry):
    """
    This function incrementally add entries to a json file
    while keeping the format correct

    Parameters
    ----------
    filename: str
        the name of the JSON file
    entry:
        the new entry to append
    """
    import json
    with open(filename, 'at') as f:
        if f.tell() == 0:
            json.dump([entry], f, indent=0)
        else:
            f.seek(f.tell() - 2, 0)
            f.truncate()
            f.write(',\n')
            json.dump(entry, f, indent=0)
            f.write('\n]')


def format_timing(value: float) ->str:
    """Format a timing value, returning a human-friendly float representation.

    :param value: Timing value.
    """
    return f'{value:.4f} s'


@classmethod
def get_queue_type(cls, queue_id):
    """ Return the queue type, currently determined only by its suffix. """
    for queue_type in ('timed_set', 'sorted_set', 'set', 'raw'):
        if queue_id.split('/')[0].endswith('_%s' % queue_type):
            return queue_type
    return 'regular'


def isnum(number):
    """Check if number."""
    try:
        int(number)
        return True
    except ValueError:
        return False


def is_utility_vehicle(df):
    """Return if vehicle is a utility vehicle, per NHTSA convention."""
    yr = df['YEAR']
    body = df['BODY_TYP']
    return yr.between(1975, 1981) & (body == 43) | yr.between(1982, 1990
        ) & body.isin([12, 56, 68]) | (1991 <= yr) & body.isin([14, 15, 16, 19]
        )


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 get_id(node, default=None):
    """Gets the id attribute of a node, or returns a default."""
    return getattr(node, 'id', default)


@classmethod
def from_json(cls, user_id, timestamp, json):
    """Builds an OptIn object from JSON provided by the API.

        Args:
            user_id: An integer Messenger ID of the user who triggered the
                    event.
            timestamp: An integer timestamp (in milliseconds since epoch) of
                    the event.
            json: A dict containing the JSON representation that is converted
                  into the OptIn object.

        Returns:
            An OptIn object.

        """
    return cls(user_id, timestamp, json['ref'])


def link(detach: bool=False):
    """Use the mouse to create a link between two nodes

    :param detach: Detach, Detach and redirect existing links
    :type detach: bool
    """
    pass


def valid_citekey(citekey):
    """Return if a citekey is a valid filename or not"""
    return not '/' in citekey


def edge_matcher(graph1, graph2, node11, node12, node21, node22):
    """
    Checks whether the resids for node11 and node12 in graph1 are the same, and
    whether that's also true for node21 and node22 in graph2.

    Parameters
    ----------
    graph1: networkx.Graph
    graph2: networkx.Graph
    node11: collections.abc.Hashable
        A node key in `graph1`.
    node12: collections.abc.Hashable
        A node key in `graph1`.
    node21: collections.abc.Hashable
        A node key in `graph2`.
    node22: collections.abc.Hashable
        A node key in `graph2`.

    Returns
    -------
    bool
    """
    node11 = graph1.nodes[node11]
    node12 = graph1.nodes[node12]
    node21 = graph2.nodes[node21]
    node22 = graph2.nodes[node22]
    return (node11.get('resid') == node12.get('resid')) == (node21.get(
        'resid') == node22.get('resid'))


@staticmethod
def __filter_predictions(predictions: list, precision_threshold: float) ->dict:
    """
        Filter predictions such that all items with precision below threshold are disregarded.

        :param predictions: list of lists with a single tuple with predictions and their softmax score
        :param precision_threshold: threshold below which predictions are disregarded.
        :return: filtered predictions: list of predictions that above the threshold.
        """
    filtered_predictions = []
    for prediction in predictions:
        if prediction[0][1] > precision_threshold:
            filtered_predictions.append(prediction[0])
        else:
            filtered_predictions.append(())
    return filtered_predictions


def render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

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


@classmethod
def delete_auth_token(cls, user_id, token):
    """Deletes a given authorization token.

        :param user_id:
            User unique ID.
        :param token:
            A string with the authorization token.
        """
    cls.token_model.get_key(user_id, 'auth', token).delete()


def read_file(file_path):
    """Read initial program"""
    with open(file_path, 'r') as program:
        program = open(file_path, 'r')
        program = str(program.read())
        return program.split('\n')


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['protocol']
    if type == 'SAML2':
        return 'CreateSaml2IdentityProviderDetails'
    else:
        return 'CreateIdentityProviderDetails'


def safesetattr(obj, attr, value):
    """
    Because we are overriding __setattr__, we need a
    non-recursive way of setting attributes.

    This is to be used to set attributes internally.
    """
    object.__setattr__(obj, attr, value)


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 print_config_report(warnings, errors, logger=None):
    """
    Pass in the list of string messages generated by check_config file.
    print out in a pretty format the issues

    Args:
        warnings: List of non-critical messages returned from
                :func:`~utilities.check_config`.
        errors: List of critical messages returned from
              :func:`~utilities.check_config`.
        logger: pass in the logger function being used. If no logger is
                provided, print is used. Default = None
    """
    msg = '{: <20} {: <25} {: <60}'
    if logger != None:
        out = logger.info
    else:
        out = print
    msg_len = 90
    out(' ')
    out(' ')
    out('Configuration File Status Report:')
    header = '=' * msg_len
    out(header)
    any_warnings = False
    any_errors = False
    if len(warnings) > 0:
        any_warnings = True
        out('WARNINGS:')
        out(' ')
        out(msg.format(' Section', 'Item', 'Message'))
        out('-' * msg_len)
        for w in warnings:
            out(w)
        out(' ')
        out(' ')
    if len(errors) > 0:
        any_errors = True
        out('ERRORS:')
        out(' ')
        out(msg.format('Section', 'Item', 'Message'))
        out('-' * msg_len)
        for e in errors:
            out(e)
        out(' ')
        out(' ')
    if not any_errors and not any_warnings:
        out('No errors or warnings were reported with the config file.\n')


@classmethod
def _add_workflow(mcs, field_name, state_field, attrs):
    """Attach the workflow to a set of attributes.

        Constructs the ImplementationWrapper for transitions, and adds them to
        the attributes dict.

        Args:
            field_name (str): name of the attribute where the StateField lives
            state_field (StateField): StateField describing that attribute
            attrs (dict): dictionary of attributes for the class being created
        """
    pass


def get_connection(database_name):
    """Return a Connection for the named database.

        This is intended to be called from an open Connection associated with
        a multi-database.  In that case, database_name must be the name of a
        database within the database collection (probably the name of a
        different database than is associated with the calling Connection
        instance, but it's fine to use the name of the calling Connection
        object's database).  A Connection for the named database is
        returned.  If no connection to that database is already open, a new
        Connection is opened.  So long as the multi-database remains open,
        passing the same name to get_connection() multiple times returns the
        same Connection object each time.
        """


def add_ta_alias_to_map(ta_aliases, ta_map):
    """ adds alias to the ta_map. Needs arguments ta_map defaultdict with sets,
    and tuples with two strings in each. Assumes that all threat actors are
    already in the ta_map. """
    for tup in ta_aliases:
        ta1, ta2 = tup
        s = ta_map[ta1]
        s.update(ta_map[ta2])
        for x in s:
            ta_map[x] = s
    return ta_map


def setUpWidgets(ignore_request=False):
    """Set up the form's widgets.

        The default implementation uses the form definitions in the
        form_fields attribute and setUpInputWidgets.

        The function should set the widgets attribute.
        """


def mirror_mag_d(distance_image, distance_object):
    """Usage: Find magnification using distance of image and distance of object"""
    neg_di = -1 * distance_image
    return neg_di / distance_object


def getLocalRolesForPrincipal(principal):
    """Return a sequence of all local roles for a principal.
        """


def get(isamAppliance, check_mode=False, force=False):
    """
    Retrieving the general configuration
    """
    return isamAppliance.invoke_get('Retrieving the general configuration',
        '/isam/packet_tracing')


@staticmethod
def _identify_eds_ing(first, second):
    """Find nodes connecting adjacent edges.

        Args:
            first (Edge):
                Edge object representing the first edge.
            second (Edge):
                Edge object representing the second edge.

        Returns:
            tuple[int, int, set[int]]:
                The first two values represent left and right node
                indicies of the new edge. The third value is the new dependence set.
        """
    A = set([first.L, first.R])
    A.update(first.D)
    B = set([second.L, second.R])
    B.update(second.D)
    depend_set = A & B
    left, right = sorted(list(A ^ B))
    return left, right, depend_set


def _lovasz_grad(gt_sorted):
    """
    Computes gradient of the Lovasz extension w.r.t sorted errors
    See Alg. 1 in paper
    """
    p = len(gt_sorted)
    gts = gt_sorted.sum()
    intersection = gts - gt_sorted.float().cumsum(0)
    union = gts + (1 - gt_sorted).float().cumsum(0)
    jaccard = 1.0 - intersection / union
    if p > 1:
        jaccard[1:p] = jaccard[1:p] - jaccard[0:-1]
    return jaccard


def ModifyInstance(r, instance, **kwargs):
    """
    Modifies an instance.

    More details for parameters can be found in the RAPI documentation.

    @type instance: string
    @param instance: Instance name
    @rtype: int
    @return: job id
    """
    return r.request('put', '/2/instances/%s/modify' % instance, content=kwargs
        )


def getHits(fileName, evalueThresh):
    """Given a BLAST output file, returns a dictionary keyed by the genes
    in the query species, with the values being the top hit (if any)
    for those genes. Assumes the blast hits for each query are given
    from most to least significant. which appears to be the
    case. Thresholds for minimum similarity and maximum length
    difference are globally defined.
    """
    f = open(fileName, 'r')
    hitsD = {}
    queryGene = ''
    line = f.readline()
    while line != '':
        L = line.split('\t')
        if len(L) < 12:
            line = f.readline()
            continue
        queryGene = L[0].split('_')[0]
        hit = L[1].split('_')[0]
        evalue = float(L[10])
        if evalue < evalueThresh:
            hitsD[int(queryGene)] = int(hit)
        while line.split('_')[0] == queryGene:
            line = f.readline()
    f.close()
    return hitsD


def _collapse0(a):
    """Collapse all dimensions of `a` except the first.
    """
    return a.reshape(a.shape[0], -1)


def init_defaults(*sections):
    """
    Returns a standard dictionary object to use for application defaults.
    If sections are given, it will create a nested dict for each section name.

    :arg sections: Section keys to create nested dictionaries for.
    :returns: Dictionary of nested dictionaries (sections)
    :rtype: dict

    .. code-block:: python

        from cement.core import foundation
        from cement.utils.misc import init_defaults

        defaults = init_defaults('myapp', 'section2', 'section3')
        defaults['myapp']['debug'] = False
        defaults['section2']['foo'] = 'bar
        defaults['section3']['foo2'] = 'bar2'

        app = foundation.CementApp('myapp', config_defaults=defaults)

    """
    defaults = dict()
    for section in sections:
        defaults[section] = dict()
    return defaults


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 _get_endian_str(endian):
    """
    DM4 header encodes little endian as byte value 1 in the header
    :return: 'big' or 'little' for use with python's int.frombytes function
    """
    if isinstance(endian, str):
        return endian
    assert isinstance(endian, int)
    if endian == 1:
        return 'little'
    return 'big'


def embed_ipython_shell(namespace=None, history_filename=None):
    """Start an IPython Shell"""
    from IPython import embed
    embed(user_ns=namespace)


def get_root_url():
    """Determine the root URL for the site."""
    from django.conf import settings
    return settings.DJCORE.SITE_URL


def de(value):
    """Returns an RDF literal from the de language for the given value."""
    from pymantic.primitives import Literal
    return Literal(value, language='de')


def decode_polyline(polyline):
    """Decodes a Polyline string into a list of lat/lng dicts.

    See the developer docs for a detailed description of this encoding:
    https://developers.google.com/maps/documentation/utilities/polylinealgorithm

    :param polyline: An encoded polyline
    :type polyline: string

    :rtype: list of dicts with lat/lng keys
    """
    points = []
    index = lat = lng = 0
    while index < len(polyline):
        result = 1
        shift = 0
        while True:
            b = ord(polyline[index]) - 63 - 1
            index += 1
            result += b << shift
            shift += 5
            if b < 31:
                break
        lat += ~result >> 1 if result & 1 != 0 else result >> 1
        result = 1
        shift = 0
        while True:
            b = ord(polyline[index]) - 63 - 1
            index += 1
            result += b << shift
            shift += 5
            if b < 31:
                break
        lng += ~(result >> 1) if result & 1 != 0 else result >> 1
        points.append({'lat': lat * 1e-05, 'lng': lng * 1e-05})
    return points


def get_official_service_name(service_model):
    """Generate the official name of an KSYUN Service

    :param service_model: The service model representing the service
    """
    official_name = service_model.metadata.get('serviceFullName')
    short_name = service_model.metadata.get('serviceAbbreviation', '')
    if short_name.startswith('Amazon'):
        short_name = short_name[7:]
    if short_name.startswith('AWS'):
        short_name = short_name[4:]
    if short_name and short_name.lower() not in official_name.lower():
        official_name += ' ({0})'.format(short_name)
    return official_name


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.stages.UDFTransformer'


def string_to_num(s: str):
    """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


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

        :param context: security 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:`VolumeConnector` objects
        :raises: InvalidParameterValue if sort_key does not exist
        """
    db_connectors = cls.dbapi.get_volume_connector_list(limit=limit, marker
        =marker, sort_key=sort_key, sort_dir=sort_dir)
    return cls._from_db_object_list(context, db_connectors)


def get_node_cost(graph, node, cost_dict):
    """
        get cost of input node along
        If parent node cost is not calculated, return 0.
        This node calculate again in the loop by DAG structure.
    """
    cost = 0
    ancestors = graph.successors(node)
    if len(ancestors) == 0:
        return 1
    for ancestor in ancestors:
        try:
            cost += cost_dict[ancestor] / len(graph.predecessors(ancestor))
        except KeyError:
            return 0
    return cost


@classmethod
def _from_dict(cls, _dict):
    """Initialize a QueryResultMetadata object from a json dictionary."""
    args = {}
    if 'score' in _dict:
        args['score'] = _dict.get('score')
    else:
        raise ValueError(
            "Required property 'score' not present in QueryResultMetadata JSON"
            )
    if 'confidence' in _dict:
        args['confidence'] = _dict.get('confidence')
    else:
        raise ValueError(
            "Required property 'confidence' not present in QueryResultMetadata JSON"
            )
    return cls(**args)


def two_pt_parabola(pt1, pt2):
    """
    Given two points, gives us the coefficients for a parabola.
    args:
        pt1: The first point.
        pt2: The second point.
    """
    [x1, y1] = pt1 * 1.0
    [x2, y2] = pt2 * 1.0
    a = (y2 - y1) / (x2 - x1) ** 2
    c = y1 + a * x1 * x1
    b = -2 * a * x1
    return [a, b, c]


@classmethod
def generate_filename(cls, modifier: str=None) ->str:
    """
        Generates the configuration filename with an optional modification string.

        :param modifier: String to modify default filename with.
        :return: The generated filepath string.
        """
    name = cls._NAME.lower()
    if modifier:
        name += f'-{modifier}'
    filename = f'{name}.{cls._CONFIG_FILE_EXTENSION.lower()}'
    return filename


def _round_to_next_multiple(n, m):
    """
    Round up the the next multiple.

    :param n: The number to round up.
    :param m: The multiple.
    :return: The rounded number
    """
    return n if n % m == 0 else n + m - n % m


def proportional_abundance(weblog_tmp, field):
    """
    Calculate proportion of each sub-field in field columns
    """
    weblog_tmp = weblog_tmp.copy(deep=True)
    if weblog_tmp.shape[0] == 0:
        raise AssertionError('Empty weblog.')
    histogram = weblog_tmp[field].value_counts()
    pa_df = histogram / histogram.values.sum()
    if abs(1.0 - pa_df.values.sum()) > 1e-08:
        raise AssertionError(
            'ERROR: Proportional abundance distribution does not sum up to one.'
            )
    return pa_df.values, list(pa_df.index)


@staticmethod
def _compare_get_request_with_dict(response, firewall_dict):
    """
        Helper method to compare the json response for getting the firewall policy with the request parameters
        :param response: response from the get method
        :param firewall_dict: dictionary of request parameters for firewall policy
        :return: changed: Boolean that returns true if there are differences between
                          the response parameters and the playbook parameters
        """
    changed = False
    response_dest_account_alias = response.get('destinationAccount')
    response_enabled = response.get('enabled')
    response_source = response.get('source')
    response_dest = response.get('destination')
    response_ports = response.get('ports')
    request_dest_account_alias = firewall_dict.get('destination_account_alias')
    request_enabled = firewall_dict.get('enabled')
    if request_enabled is None:
        request_enabled = True
    request_source = firewall_dict.get('source')
    request_dest = firewall_dict.get('destination')
    request_ports = firewall_dict.get('ports')
    if (response_dest_account_alias and str(response_dest_account_alias) !=
        str(request_dest_account_alias) or response_enabled !=
        request_enabled or response_source and response_source !=
        request_source or response_dest and response_dest != request_dest or
        response_ports and response_ports != request_ports):
        changed = True
    return changed


@staticmethod
def _directive_del_attribute(directive_body):
    """Directive for :py:meth:`del_attribute`"""
    instance, attribute_name = directive_body
    return delattr(instance, attribute_name)


def _getstatus(args):
    """Execute bash command returning exit status."""
    import subprocess
    return subprocess.call(args, executable='bash', shell=True, stderr=
        subprocess.PIPE, stdout=subprocess.PIPE)


def animation_step():
    """Step through animation by position

    """
    pass


@classmethod
def command_exists(cls, name):
    """
        returns True if the command exists
        :param name:
        :return:
        """
    return cls.which(name) is not None


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

        :param TeamFolderChangeStatusDetails val:
        :rtype: EventDetails
        """
    return cls('team_folder_change_status_details', val)


def disable_ra(module, array):
    """Disable Remote Assist"""
    changed = False
    if array.get_remote_assist_status()['status'] == 'enabled':
        try:
            array.disable_remote_assist()
            changed = True
        except Exception:
            module.fail_json(msg='Disabling Remote Assist failed')
    module.exit_json(changed=changed)


@staticmethod
def assemble_api_url(domain, operators, protocol='https'):
    """Assemble the requests api url."""
    return '{}://{}{}'.format(protocol, domain, operators)


def isNumber(x):
    """Returns true if x is an int of a float"""
    return type(x) in [int, float]


def getIcon(item):
    """
        deprecated for Plone > 5.0 see
        https://github.com/plone/Products.CMFPlone/issues/1151
        Returns an object which implements the IContentIcon interface and
        provides the informations necessary to render an icon. The item
        parameter needs to be adaptable to IContentIcon. Icons can be disabled
        globally or just for anonymous users with the icon_visibility property
        in site_properties.
        """


def queue_test(warn=True):
    """Check that this batch system can be used.

    Parameters
    ----------
    warn : bool
        log a warning on fail

    Returns
    -------
    batch_system_functional : bool
    """
    log_level = 'error' if warn else 'debug'
    pass


def start_namespace(namespace):
    """
    Basic mechanism to prevent conflicts for string types for URDF and SDF
    @note Does not handle nesting!
    """
    global value_type_prefix
    value_type_prefix = namespace + '.'


def check_data_1d(x, y):
    """
    Performs consistency checks on the data passed into make_film_1d.

    These checks are only done when both x and y arguments are passed into the
    function.

    Parameters
    ----------

    x : array_like,
        Array specifying the x axis.
    y : array_like
        Two dimensional array assumed to be of the form y(t, x). This specifies
        the values to be plotted as a function of time.
    """
    x_s = x.shape
    y_s = y.shape
    if len(x_s) != 1:
        raise IndexError('x must be one dimensional.')
    if len(y_s) != 2:
        raise IndexError('y must be two dimensional.')
    if x_s[0] != y_s[1]:
        raise ValueError('x and y must have the same length: {0}, {1}'.
            format(x_s[0], y_s[1]))


def to_int_action(toks):
    """Convert first token to integer"""
    return int(toks[0])


def add_2(a):
    """add integer two to a number

    Parameters
    ----------
    a : float
        the number that needs to be added to

    Returns
    -------
    a+2 : float
        the result

    Notes
    -----
    Uses the built-in "+" operator
    """
    return a + 2


def abbr(abbreviation='', fullWord=''):
    """
    *Get HTML5 Abbreviation*

    **Key Arguments:**
        - ``abbreviation`` -- the abbreviation
        - ``fullWord`` -- the full word

    **Return:**
        - abbr
    """
    abbr = (
        '<abbr title="%(fullWord)s" class="initialism">%(abbreviation)s</abbr>'
         % locals())
    return abbr


def assign_get_users_permission(setup_context):
    """Assign the 'plone.restapi: Access Plone user information' permission
       to Managers by default.
    """
    setup_context.runImportStepFromProfile(
        'profile-plone.restapi.upgrades:0004', 'rolemap', run_dependencies=
        False, purge_old=False)


def write_pagination_headers(data, offset, limit, response, uripath,
    resource_name):
    """Add pagination headers to the bottle response.

    See docs in :func:`paginated`.
    """
    items = data.get('results') or data.get('data') or {}
    count = len(items)
    try:
        total = int(data['collection-count'])
    except (ValueError, TypeError, KeyError):
        total = None
    if total is None and offset == 0 and (limit is None or limit > len(items)):
        total = count
    response.set_header('Content-Range', '%s %d-%d/%s' % (resource_name,
        offset, offset + max(count - 1, 0), total if total is not None else
        '*'))
    partial = False
    if offset:
        partial = True
    elif total is None and count == limit:
        partial = True
    elif total > count:
        partial = True
    if partial:
        uripath = uripath.strip('/')
        response.status = 206
        if total is None or offset + limit < total - 1:
            nextfmt = '</%s?limit=%d&offset=%d>; rel="next"; title="Next page"'
            response.add_header('Link', nextfmt % (uripath, limit, offset +
                limit))
        if offset > 0 and offset - limit >= 0:
            prevfmt = (
                '</%s?limit=%d&offset=%d>; rel="previous"; title="Previous page"'
                )
            response.add_header('Link', prevfmt % (uripath, limit, offset -
                limit))
        if offset > 0:
            firstfmt = '</%s?limit=%d>; rel="first"; title="First page"'
            response.add_header('Link', firstfmt % (uripath, limit))
        if total is not None and limit and limit < total:
            lastfmt = '</%s?offset=%d>; rel="last"; title="Last page"'
            if limit and total % limit:
                last_offset = total - total % limit
            else:
                last_offset = total - limit
            response.add_header('Link', lastfmt % (uripath, last_offset))


@classmethod
def reset(cls):
    """ Reset the class to have no subtypes. """
    cls.subtype_id = 0
    cls.subtypes = []


def keyframe_clear_button(all: bool=True):
    """Clear all keyframes on the currently active property

    :param all: All, Clear keyframes from all elements of the array
    :type all: bool
    """
    pass


def service_model(service):
    """Produce the model for a service"""
    return {'name': service.name, 'admin': service.admin, 'url': service.
        url, 'prefix': service.server.base_url if service.server else '',
        'command': service.command, 'pid': service.proc.pid if service.proc
         else 0, 'info': service.info}


def __is_the_base_context_manager_class(cls):
    """
        Return whether `cls` is `ContextManager`.

        It's an ugly method, but unfortunately it's necessary because at one
        point we want to test if a class is `ContextManager` before
        `ContextManager` is defined in this module.
        """
    return (cls.__name__ == 'ContextManager' and cls.__module__ ==
        'python_toolbox.context_management.context_manager' and cls.mro() ==
        [cls, object])


def get_data_codewords(bits, codeword_size):
    """ Get codewords stream from data bits sequence
    Bit stuffing and padding are used to avoid all-zero and all-ones codewords

    :param bits: input data bits
    :param codeword_size: codeword size in bits
    :return: data codewords
    """
    codewords = []
    sub_bits = ''
    for bit in bits:
        sub_bits += bit
        if len(sub_bits) == codeword_size - 1 and sub_bits.find('1') < 0:
            sub_bits += '1'
        if len(sub_bits) == codeword_size - 1 and sub_bits.find('0') < 0:
            sub_bits += '0'
        if len(sub_bits) >= codeword_size:
            codewords.append(int(sub_bits, 2))
            sub_bits = ''
    if sub_bits:
        sub_bits = sub_bits.ljust(codeword_size, '1')
        if sub_bits.find('0') < 0:
            sub_bits = sub_bits[:-1] + '0'
        codewords.append(int(sub_bits, 2))
    return codewords


@classmethod
def paragraphs(cls, n: int) ->str:
    """ Returns a string of n paragraphs """
    paragraphs = [cls.paragraph() for i in range(n)]
    return '\n\n'.join(paragraphs)


def normalize_none_str(string_or_none):
    """Returns '' IFF given value is None, passthrough otherwise.

    This function normalizes None to the empty string to facilitate
    string concatenation when a variable could be None.
    """
    return '' if string_or_none is None else string_or_none


def pregenerator(request, elements, kw):
    """
    Route pregenerator that set the current matched route application and table
    segments as defaults for generating urls.
    """
    if 'application' not in kw:
        kw['application'] = request.matchdict.get('application', 'default')
    if 'table' not in kw:
        kw['table'] = request.matchdict.get('table', None)
    return elements, kw


def refresh_certs(realm):
    """
    :param django_keycloak.models.Realm realm:
    :rtype django_keycloak.models.Realm
    """
    realm.certs = realm.client.openid_api_client.certs()
    realm.save(update_fields=['_certs'])
    return realm


def nspath_eval(xpath, namespaces):
    """ Return an etree friendly xpath """
    out = []
    for chunks in xpath.split('/'):
        namespace, element = chunks.split(':')
        out.append('{%s}%s' % (namespaces[namespace], element))
    return '/'.join(out)


def quote_ident(value: str) ->str:
    """Quote a PostgreSQL identifier (object name, etc)"""
    return '"{}"'.format(value.replace('"', '""'))


@classmethod
def GetHasherNamesFromString(cls, hasher_names_string):
    """Retrieves a list of a hasher names from a comma separated string.

    Takes a string of comma separated hasher names transforms it to a list of
    hasher names.

    Args:
      hasher_names_string (str): comma separated names of hashers to enable,
          the string 'all' to enable all hashers or 'none' to disable all
          hashers.

    Returns:
      list[str]: names of valid hashers from the string, or an empty list if no
          valid names are found.
    """
    hasher_names = []
    if not hasher_names_string or hasher_names_string.strip() == 'none':
        return hasher_names
    if hasher_names_string.strip() == 'all':
        return cls.GetHasherNames()
    for hasher_name in hasher_names_string.split(','):
        hasher_name = hasher_name.strip()
        if not hasher_name:
            continue
        hasher_name = hasher_name.lower()
        if hasher_name in cls._hasher_classes:
            hasher_names.append(hasher_name)
    return hasher_names


def keys():
    """ Return an iterable sequence of object names present in the folder.

        Respect ``order``, if set.
        """


def test():
    """
    >>> # replace a single tag
    >>> content = { 'pattern1': ['a']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern1')
    'a'

    >>> # replace a tag
    >>> content = { 'pattern2': ['a'], 'pattern1': ['<#pattern2#>']}
    >>> bw = BlurbWriter(content)

    >>> bw.write('pattern2')
    'a'
    >>> bw.write('pattern1')
    'a'

    >>> # to lowercasee
    >>> content = { 'pattern2': ['AA'], 'pattern1': ['<#~,pattern2#>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'AA'
    >>> bw.write('pattern1')
    'aa'

    >>> # white space to underscore
    >>> content = { 'pattern2': ['A A'], 'pattern1': ['<#_,pattern2#>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'A A'
    >>> bw.write('pattern1')
    'A_A'

    >>> # remove nonletters
    >>> content = { 'pattern2': ['A. A-'], 'pattern1': ['<#@,pattern2#>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'A. A-'
    >>> bw.write('pattern1')
    'AA'

    >>> # white space to underscore and first cap
    >>> content = { 'pattern2': ['a a'], 'pattern1': ['<#^_,pattern2#>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'a a'
    >>> bw.write('pattern1')
    'A_a'

    >>> # make title case
    >>> content = { 'pattern2': ['aa aa'], 'pattern1': ['<#^^,pattern2#>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'aa aa'
    >>> bw.write('pattern1')
    'Aa Aa'

    >>> # make allcaps
    >>> content = { 'pattern2': ['aa aa'], 'pattern1': ['<#^^^,pattern2#>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'aa aa'
    >>> bw.write('pattern1')
    'AA AA'

    >>> # generate a random number
    >>> content = { 'pattern1': ['<-randint(1, 20)->']}
    >>> bw = BlurbWriter(content)
    >>> result = bw.write('pattern1')
    >>> assert 1 <= int(result) <= 20

    >>> # detect spinning because of a malformed tag
    >>> content = { 'pattern2': ['a'], 'pattern1': ['<#pattern2>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'a'
    >>> bw.write('pattern1')
    '<#pattern2>'

    >>> # replace a tag, variable
    >>> # '<#_aname=name#><#_aname#>’s
    >>> content = { 'pattern2': ['a'], 'pattern1': ['<#varName=pattern2#>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'a'
    >>> bw.write('pattern1')
    ''

    >>> # replace a tag, whitespace
    >>> content = { 'pattern2': ['a'], 'pattern1': ['<#    pattern2    #>']}
    >>> bw = BlurbWriter(content)
    >>> bw.write('pattern2')
    'a'
    >>> bw.write('pattern1')
    'a'

    # >>> # prefix an / a article for a result based on consonant / vowel
    # >>> content = { 'pattern2': ['a'], 'pattern1': ['<#article, pattern2#>'],  'pattern4': ['b'], 'pattern3': ['<#article, pattern4#>']}
    # >>> bw = BlurbWriter(content)
    # >>> bw.write('pattern1')
    # 'an a'
    # >>> bw.write('pattern3')
    # 'a b'

    # >>> # replace a nested tag
    # >>> content = { 'pattern2': ['pattern'], 'pattern1': ['<#<#pattern2#>3#>'], 'pattern3': ['b']}
    # >>> bw = BlurbWriter(content)
    # >>> bw.write('pattern1')
    # 'b'

    # >>> # capitalisation of first character
    # >>> content = { 'pattern1': ['<#^,pattern2#>'], 'pattern2': ['aa aa']}
    # >>> bw = BlurbWriter(content)
    # >>> bw.write('pattern1')
    # 'Aa aa'

    # >>> # unicode content
    # >>> content = { 'pattern1': ['üößé']}
    # >>> bw = BlurbWriter(content)
    # >>> bw.write('pattern1')
    # 'üößé'

    # # not sure if that is the right way

    # >>> # replace a tag
    # >>> content = { 'pattern2': ['a'], 'pattern1': ['<#pattern2#>']}
    # >>> bw = BlurbWriter(content, debug=True)
    # >>> bw.write('pattern2')
    # pattern2
    # 'a'
    # >>> bw.write('pattern1')
    # pattern1
    # pattern2
    # 'a'
    """


def disableUnsaveMath():
    """
    Disable the fast-math and associative-math flags in the c++ compiler.
    """
    from . import config
    flags = config.cxxflags
    for flag in ('-ffast-math', '-fassociative-math'):
        if flag in flags:
            flags.remove(flag)


def rescue_walk(algns1, algns2, max_molecule_size):
    """
    Rescue a single ligation that appears as a walk.

    Checks if a molecule with three alignments could be formed via a single
    ligation between two fragments, where one fragment was so long that it
    got sequenced on both sides.

    Uses three criteria:
    a) the 3'-end alignment on one side maps to the same chromosome as the
    alignment fully covering the other side (i.e. the linear alignment)
    b) the two alignments point towards each other on the chromosome
    c) the distance between the outer ends of the two alignments is below
    the specified threshold.

    Alternatively, a single ligation get rescued when the 3' sub-alignment
    maps to multiple locations or no locations at all.

    In the case of a successful rescue, tags the 3' sub-alignment with
    type='X' and the linear alignment on the other side with type='R'.

    Returns
    -------
    linear_side : int
        If the case of a successful rescue, returns the index of the side
        with a linear alignment.

    """
    n_algns1 = len(algns1)
    n_algns2 = len(algns2)
    if n_algns1 <= 1 and n_algns2 <= 1:
        return None
    if not (n_algns1 == 1 and n_algns2 == 2 or n_algns1 == 2 and n_algns2 == 1
        ):
        return None
    first_read_is_chimeric = n_algns1 > 1
    chim5_algn = algns1[0] if first_read_is_chimeric else algns2[0]
    chim3_algn = algns1[1] if first_read_is_chimeric else algns2[1]
    linear_algn = algns2[0] if first_read_is_chimeric else algns1[0]
    if not (linear_algn['is_mapped'] and linear_algn['is_unique']):
        return None
    can_rescue = True
    if chim3_algn['is_mapped'] and chim5_algn['is_unique']:
        can_rescue &= chim3_algn['chrom'] == linear_algn['chrom']
        can_rescue &= chim3_algn['strand'] != linear_algn['strand']
        if linear_algn['strand'] == '+':
            can_rescue &= linear_algn['pos5'] < chim3_algn['pos5']
        else:
            can_rescue &= linear_algn['pos5'] > chim3_algn['pos5']
        if linear_algn['strand'] == '+':
            molecule_size = chim3_algn['pos5'] - linear_algn['pos5'
                ] + chim3_algn['dist_to_5'] + linear_algn['dist_to_5']
        else:
            molecule_size = linear_algn['pos5'] - chim3_algn['pos5'
                ] + chim3_algn['dist_to_5'] + linear_algn['dist_to_5']
        can_rescue &= molecule_size <= max_molecule_size
    if can_rescue:
        if first_read_is_chimeric:
            algns1[1]['type'] = 'X'
            algns2[0]['type'] = 'R'
            return 2
        else:
            algns1[0]['type'] = 'R'
            algns2[1]['type'] = 'X'
            return 1
    else:
        return None


@classmethod
def words(cls, value, separator=None) ->list:
    """
        Words, `['such', 'as', 'this']`
        """
    if not separator:
        separator = ' '
    return value.split(separator)


@classmethod
def _python_value_to_header_str(cls, value):
    """
        Convert Python value to header string for __add__/__radd__.
        """
    if isinstance(value, str):
        return value
    if hasattr(value, 'items'):
        if value == {}:
            value = []
        else:
            value_list = []
            for media_range, item in value.items():
                if isinstance(item, (float, int)):
                    value_list.append((media_range, item, ''))
                else:
                    value_list.append((media_range, item[0], item[1]))
            value = sorted(value_list, key=lambda item: item[1], reverse=True)
    if isinstance(value, (tuple, list)):
        header_elements = []
        for item in value:
            if isinstance(item, (tuple, list)):
                item = cls._iterable_to_header_element(iterable=item)
            header_elements.append(item)
        header_str = ', '.join(header_elements)
    else:
        header_str = str(value)
    return header_str


def raiser(exp, *args, **kwargs):
    """
    Utility for raising exceptions

    Useful in one-liners

    For example::

        >>> a = lambda x: not x and raiser(ValueError, 'error message')
        >>> _ = a(True)
        >>> _ = a(False)
        Traceback (most recent call last):
        ...
        ValueError: error message
    """
    raise exp(*args, **kwargs)


@classmethod
def post_process(cls, db, **kwargs):
    """
        Post-process processing method.  This method is a placeholder
        that may be overridden in children...
        @see: stop_time.py or route.py
        """
    pass


@staticmethod
def gsql(query, bindings=None, dry_run=False):
    """Run Tigergraph query in interpreted mode and return transformed Plottable

        :param query: Code to run
        :type query: String.
        :param bindings: Mapping defining names of returned 'edges' and/or 'nodes', defaults to @@nodeList and @@edgeList
        :type bindings: Optional dictionary.
        :param dry_run: Return target URL without running
        :type dry_run: Bool, defaults to False
        :returns: Plotter.
        :rtype: Plotter.

        **Example: Minimal**
                ::

                    import graphistry
                    tg = graphistry.tigergraph()
                    tg.gsql(""\"
INTERPRET QUERY () FOR GRAPH Storage {

    OrAccum<BOOL> @@stop;
    ListAccum<EDGE> @@edgeList;
    SetAccum<vertex> @@set;

    @@set += to_vertex("61921", "Pool");

    Start = @@set;

    while Start.size() > 0 and @@stop == false do

      Start = select t from Start:s-(:e)-:t
      where e.goUpper == TRUE
      accum @@edgeList += e
      having t.type != "Service";
    end;

    print @@edgeList;
  }
                    ""\").plot()

       **Example: Full**
                ::

                    import graphistry
                    tg = graphistry.tigergraph()
                    tg.gsql(""\"
INTERPRET QUERY () FOR GRAPH Storage {

    OrAccum<BOOL> @@stop;
    ListAccum<EDGE> @@edgeList;
    SetAccum<vertex> @@set;

    @@set += to_vertex("61921", "Pool");

    Start = @@set;

    while Start.size() > 0 and @@stop == false do

      Start = select t from Start:s-(:e)-:t
      where e.goUpper == TRUE
      accum @@edgeList += e
      having t.type != "Service";
    end;

    print @@my_edge_list;
  }
                    ""\", {'edges': 'my_edge_list'}).plot()
        """
    from . import plotter
    return plotter.Plotter().gsql(query, bindings, dry_run)


def plot_2D_lines(df, columns, limits):
    """Plot multiple columms of a pandas dataframe on a line graph.

    Args:
    df      (dataframe): pandas dataframe to plot, must contain x,y and z for now
    columns      (list): list containing xmin,xmax,ymin,ymax,zmin,zmax

    Returns:
    bool: list of pandas dataframes containing 3D tracks.
    """
    if type(columns) is list:
        ax = df.plot(y=columns[0], use_index=True)
        for i in range(len(columns) - 1):
            df.plot(y=columns[i + 1], ax=ax, use_index=True)


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


def pca(pArray, iComponents=1):
    """
	Input: N x D matrix
	Output: D x N matrix

	"""
    from sklearn.decomposition import PCA
    pPCA = PCA(n_components=iComponents)
    pcs = pPCA.fit_transform(pArray.T).T
    loadings = pPCA.components_
    return pcs[0], pPCA.explained_variance_ratio_[0], loadings[0]


def move(library, session, source_space, source_offset, source_width,
    destination_space, destination_offset, destination_width, length):
    """Moves a block of data.

    Corresponds to viMove function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session.
    :param source_space: Specifies the address space of the source.
    :param source_offset: Offset of the starting address or register from which to read.
    :param source_width: Specifies the data width of the source.
    :param destination_space: Specifies the address space of the destination.
    :param destination_offset: Offset of the starting address or register to which to write.
    :param destination_width: Specifies the data width of the destination.
    :param length: Number of elements to transfer, where the data width of the elements to transfer
                   is identical to the source data width.
    :return: return value of the library call.
    :rtype: :class:`pyvisa.constants.StatusCode`
    """
    return library.viMove(session, source_space, source_offset,
        source_width, destination_space, destination_offset,
        destination_width, length)


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


def fill_queue(queue_fill, any_list):
    """
    Takes element from a list and populates a queue with those elements.

    :param queue_fill: The queue to be filled.
    :param any_list:   List containing the elements.
    """
    for elem in any_list:
        queue_fill.put(elem)


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

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


def _sorter_fnc(x):
    """sorter function for py_sort"""
    if x is None:
        return str('')
    else:
        return str(x)


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 split_filename(filename):
    """
    Pass in a standard style rpm fullname

    Return a name, version, release, epoch, arch, e.g.::
        foo-1.0-1.i386.rpm returns foo, 1.0, 1, i386
        1:bar-9-123a.ia64.rpm returns bar, 9, 123a, 1, ia64
    """
    if filename[-4:] == '.rpm':
        filename = filename[:-4]
    arch_index = filename.rfind('.')
    arch = filename[arch_index + 1:]
    rel_index = filename[:arch_index].rfind('-')
    rel = filename[rel_index + 1:arch_index]
    ver_index = filename[:rel_index].rfind('-')
    ver = filename[ver_index + 1:rel_index]
    epoch_index = filename.find(':')
    if epoch_index == -1:
        epoch = ''
    else:
        epoch = filename[:epoch_index]
    name = filename[epoch_index + 1:ver_index]
    return name, ver, rel, epoch, arch


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


def str_is_float(value):
    """Test if a string can be parsed into a float.

    :returns: True or False

    """
    try:
        _ = float(value)
        return True
    except ValueError:
        return False


def axes_handler(new_axis):
    """New axis handler

	This function is a base-level function used by most other plotting functions to set the current Axes instance
	to ax and returns the old Axes instance to be later reverted.

	Parameters
	----------
	new_axis : Axes object
		The new Axes instance to be set as the current axis.

	Returns
	-------
	curr_axis : Axes object
		The previous Axes instance.
	"""
    from matplotlib.pyplot import gca, sca
    curr_axis = gca()
    sca(new_axis)
    return curr_axis


def interspike_time(spike_array):
    """Determine number of timesteps between all consecutive spikes.

    :param spike_array: 1 dimensional spike array

    :return: array with the time between all consecutive spikes.
    """
    spike_indices = (spike_array > 0).nonzero()
    interspike_times = []
    for idx in range(len(spike_indices) - 1):
        inter_time = spike_indices[idx + 1] - spike_indices[idx]
        interspike_times.append(inter_time)
    return interspike_times


def _indent(text, amount):
    """Indent a multiline string by some number of spaces.

    Parameters
    ----------
    text: str
        The text to be indented
    amount: int
        The number of spaces to indent the text

    Returns
    -------
    indented_text

    """
    indentation = amount * ' '
    return indentation + ('\n' + indentation).join(text.split('\n'))


def abort_if_false(ctx, param, value):
    """Abort command if value is False."""
    if not value:
        ctx.abort()


def is_approved():
    """Check whether there exists an approved version.
        """


def valid_float_value(value):
    """
    Returns True if the value can be successfully cast into a float

    :param value: (Any) the value to check
    :return: (bool)
    """
    try:
        float(value)
        return True
    except TypeError:
        return False


def first(iterable, default=None):
    """Return the first element of an iterable or the next element of a generator; or default."""
    try:
        return iterable[0]
    except IndexError:
        return default
    except TypeError:
        return next(iterable, default)


def isnan(x):
    """
    Check if something is NaN.

    >>> import numpy as np
    >>> isnan(np.NaN)
    True

    >>> isnan(0)
    False

    :param object x: Any object
    :return: True if x is NaN
    :rtype: bool
    """
    return x != x


def expm1(data=None, out=None, name=None, **kwargs):
    """Returns ``exp(x) - 1`` computed element-wise on the input.

    This function provides greater precision than ``exp(x) - 1`` for small values of ``x``.

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

       - expm1(default) = default
       - expm1(row_sparse) = row_sparse
       - expm1(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_logexp.cc:L224

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

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

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


@classmethod
def from_file(cls, target, *args, **kwargs):
    """Create a new GpgInfo object from the given file.

        See GpgInfo.from_sequence.
        """
    with open(target, 'rb') as target_file:
        return cls.from_sequence(target_file, *args, **kwargs)


@classmethod
def from_eeprom(cls, eeprom):
    """Construct description from EEPROM"""
    self = cls()
    self.describe(eeprom)
    return self


def check_delete_option(args):
    """Checks if the --delete option (to be deprecated) is used and changes
       its syntax to the corresponding subcommand

    """
    try:
        delete_index = args.index('--delete')
        args[0] = 'delete'
        del args[delete_index]
    except ValueError:
        pass
    return args


def p_proc_firstarg(t):
    """proc_firstarg : type_specifier
                     | VOID"""


def readDict(dic):
    """Function to decode dictionary"""
    out = ''
    for k, v in dic.items():
        out += '%s = %s\n' % (k, v)
    return out


def charset_to_int(s, charset):
    """ Turn a string into a non-negative integer.
    """
    output = 0
    for char in s:
        output = output * len(charset) + charset.index(char)
    return output


def not_binary(content_type):
    """Decide if something is content we'd like to treat as a string."""
    return content_type.startswith('text/') or content_type.endswith('+xml'
        ) or content_type.endswith('+json'
        ) or content_type == 'application/javascript' or content_type.startswith(
        'application/json') or content_type.startswith('application/xml')


def species_level(prediction):
    """Is this prediction at species level.

    Returns True for a binomial name (at least one space), False for genus
    only or no prediction.
    """
    assert ';' not in prediction, prediction
    return prediction and ' ' in prediction


def resize_columns(worksheet, amino_acids_col, pos_col):
    """
    Resizes amino acid and mutant position columns in the Excel sheet so that they don't
    have to be expanded.
    """
    worksheet.set_column('%s:%s' % (amino_acids_col, amino_acids_col), 40)
    worksheet.set_column('%s:%s' % (pos_col, pos_col), 12)


def __iter__():
    """Iterate over revision numbers for this file."""


@classmethod
def find_module(cls, fullname, path=None):
    """find the module on sys.path or 'path' based on sys.path_hooks and
        sys.path_importer_cache.

        This method is deprecated.  Use find_spec() instead.

        """
    spec = cls.find_spec(fullname, path)
    if spec is None:
        return None
    return spec.loader


def filter_images_by_size(images, min_size, max_size=None):
    """
    usefull to find only high-resolution photos and kicking out
    thumbnails and junk on the fly
    """
    pass


def sort_by_username(user):
    """Sort students by their username"""
    return user['username']


def getCodec():
    """Clients should return the codec name [1]_ and error handling scheme [2]_,
        used when decoding into unicode.

        :rtype: tuple(codec, errors)

        .. [1] http://docs.python.org/library/codecs.html#standard-encodings
        .. [2] https://docs.python.org/2/library/codecs.html#codec-base-classes
        """
    pass


def get_source_locations(sources):
    """
    Returns a list of source URLs and refs, currently for
    git, tar and patch sources.

    :sources A list of BuildStream Sources
    """
    source_locations = []
    for source in sources:
        if source.get_kind() in ['git']:
            url = source.translate_url(source.mirror.url, alias_override=
                None, primary=source.mirror.primary)
            source_locations.append({'type': source.get_kind(), 'url': url,
                'commit': source.mirror.ref})
        if source.get_kind() in ['git_tag']:
            url = source.translate_url(source.mirror.url, alias_override=
                None, primary=source.mirror.primary)
            source_locations.append({'type': 'git', 'x-bst-kind': source.
                get_kind(), 'url': url, 'commit': source.mirror.ref})
        if source.get_kind() in ['patch']:
            patch = source.path.rpartition('/')[2]
            source_locations.append({'type': source.get_kind(), 'path': patch})
        if source.get_kind() in ['tar', 'zip']:
            source_locations.append({'type': 'archive', 'url': source.url,
                'sha256': source.ref})
    return source_locations


@staticmethod
def _fix_encoding(var):
    """ Strip input string from non unicode symbols

            Parameters
            ----------
            var: str
                input string which can contain non unicode symbols

            Returns
            -------
                str, only unicode symbols

            Examples
            --------
                >>> Opendap._fix_encoding(u'åsnes')
                'snes
                >>> Opendap._fix_encoding('asnes')
                'asnes'
        """
    return str(var.encode('ascii', 'ignore').decode())


@classmethod
def create(cls, filename, title='', feedurl=''):
    """Create a new feed with filename."""
    with open(filename, 'w') as f:
        f.write(cls.INITIAL.substitute({'title': title, 'feedurl': feedurl,
            'uuid': cls.new_uuid(), 'now': cls.now()}))
    return cls(filename)


def ModifyCluster(r, **kwargs):
    """
    Modifies cluster parameters.

    More details for parameters can be found in the RAPI documentation.

    @rtype: int
    @return: job id
    """
    return r.request('put', '/2/modify', content=kwargs)


def primitive_nurbs_surface_torus_add(radius: float=1.0, view_align: bool=
    False, enter_editmode: bool=False, location: float=(0.0, 0.0, 0.0),
    rotation: float=(0.0, 0.0, 0.0), layers: bool=(False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False, False)):
    """Construct a Nurbs surface Torus

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


def col_scrubf(df, col_name, which, count=1, dest=False):
    """ Removes characters from the front of the entries in DataFrame for a column
    Parameters:
    df - DataFrame
        DataFrame to operate on
    col_name - string
        Name of column to scrub
    which - boolean array
        Boolean array that determines which elements to scrub, where True means scrub
    count - integer, default 1
        amount of characters to scrub
    dest - bool, default False
        Whether to apply the result to the DataFrame or return it.
        True is apply, False is return.
    """
    if dest:
        df.loc[which, col_name] = df.loc[which, col_name].str[count:]
    else:
        new_col = df[col_name].copy()
        new_col[which] = df.loc[which, col_name].str[count:]
        return new_col


@classmethod
def create_token_from_tok(cls, token, name, data):
    """
        Create a token from another token and use this token
        for the position of the to-be-created token (line, column, end_column).
        """
    tree = cls('dummy', [token])
    return tree.create_token(name, data)


def _translate_gcc_doc(s):
    """
    Map lines describing architectures from
    https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/x86-Options.html#x86-Options
    to list of flags in /proc/cpuinfo

    >>> flags = _translate_gcc_doc('Intel Core 2 CPU with 64-bit extensions, '
    ... 'MMX, SSE, SSE2, SSE3 and SSSE3 instruction set support.')
    >>> sorted(flags)
    ['lm', 'mmx', 'pni', 'sse', 'sse2', 'ssse3']
    """
    flags = set(str(s).split('with', 1)[1].split('instruction set', 1)[0].
        rstrip('.').replace(',', ' ').replace('and', ' ').replace(
        '64-bit extensions', 'lm').replace('.', '_').lower().split())
    for gcc, linux in [('bmi', 'bmi1'), ('adcx', 'adx'), ('pclmul',
        'pclmulqdq'), ('rdrnd', 'rdrand'), ('prefetchw', '3dnowprefetch'),
        ('sha', 'sha_ni'), ('sse3', 'pni'), ('xsaves', None)]:
        if gcc in flags:
            flags.remove(gcc)
            if linux:
                flags.add(linux)
    return flags


def clean_day(t):
    """Set everything less significant than day to 0"""
    return t.replace(hour=0, minute=0, second=0, microsecond=0)


def _del(isamAppliance, uuid):
    """
    Remove all UUIDs - should be everything pertaining to an advanced tuning parameter "key"

    :param isamAppliance:
    :param uuid:
    :return:
    """
    ret_obj = isamAppliance.create_return_object()
    ret_obj['data'] = []
    for u in uuid:
        r = isamAppliance.invoke_delete(
            'Deleting existing advanced tuning parameter',
            '/core/adv_params/{0}'.format(u))
        ret_obj['changed'] = ret_obj['changed'] or r['changed']
        ret_obj['data'].append(r['data'])
        ret_obj['warnings'].extend(r['warnings'])
        ret_obj['rc'] += r['rc']
    return ret_obj


def KK_RC8(w, Rs, R_values, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    return Rs + R_values[0] / (1 + w * 1.0j * t_values[0]) + R_values[1] / (
        1 + w * 1.0j * t_values[1]) + R_values[2] / (1 + w * 1.0j * t_values[2]
        ) + R_values[3] / (1 + w * 1.0j * t_values[3]) + R_values[4] / (1 +
        w * 1.0j * t_values[4]) + R_values[5] / (1 + w * 1.0j * t_values[5]
        ) + R_values[6] / (1 + w * 1.0j * t_values[6]) + R_values[7] / (1 +
        w * 1.0j * t_values[7])


def _passthrough_scorer(estimator, *args, **kwargs):
    """Function that wraps estimator.score"""
    return estimator.score(*args, **kwargs)


def reset_global_registry():
    """Clear the global instance of the registry."""
    global registry
    registry = None


def clean():
    """Remove all sessions.
        """


def constraint_remove():
    """Remove Rigid Body Constraint from Object

    """
    pass


@staticmethod
def make(ssh_command):
    """Factory function. Given a command as invoked over SSH (and preserved
        in SSH_ORIGINAL_COMMAND when run as authorized_keys command), return a
        handler if the command looks ok, else return None.
        """
    raise NotImplementedError


@staticmethod
def fft(a):
    """
        Automatically carry out the forward fast Fourier transform.
        """
    raise NotImplementedError


def is_recursive(json_structure):
    """Check whether a given JSON-like structure is recursive."""
    seen_ids = set()
    worklist = [json_structure]
    while worklist:
        this = worklist.pop()
        if not isinstance(this, (dict, list, tuple)):
            continue
        this_id = id(this)
        if this_id in seen_ids:
            return True
        seen_ids.add(this_id)
        if isinstance(this, dict):
            worklist.extend(this.values())
        else:
            worklist.extend(this)
    return False


def _proxies_dict(proxy):
    """Makes a proxy dict appropriate to pass to requests."""
    if not proxy:
        return None
    return {'http': proxy, 'https': proxy}


def aps11_f(x, n):
    """Rational function with a zero at x=1/n and a pole at x=0"""
    return (n * x - 1) / ((n - 1) * x)


def tell():
    """Return the current position, measured in bytes."""


def is_fp_closed(obj):
    """
    Checks whether a given file-like object is closed.

    :param obj:
        The file-like object to check.
    """
    try:
        return obj.closed
    except AttributeError:
        pass
    try:
        return obj.fp is None
    except AttributeError:
        pass
    raise ValueError('Unable to determine whether fp is closed.')


def decimal_to_hex(number):
    """
        This function calculates the hex of the given decimal number
        :param number: decimal number in string or integer format
        :return : string of the equivalent hex number

        Algo:
        1. Divide the decimal number by 16. Treat the division as an integer division.
        2. Write down the remainder (in hexadecimal).
        3. Divide the result again by 16. Treat the division as an integer division.
        4. Repeat step 2 and 3 until result is 0.
        5. The hex value is the digit sequence of the remainders from the last to first.
    """
    if isinstance(number, str):
        number = int(number)
    hexadec = []
    hex_equivalents = {(10): 'A', (11): 'B', (12): 'C', (13): 'D', (14):
        'E', (15): 'F'}
    while number >= 1:
        remainder = number % 16
        if remainder < 10:
            hexadec.append(remainder)
        elif remainder >= 10:
            hexadec.append(hex_equivalents[remainder])
        number = number // 16
    return ''.join(map(str, hexadec[::-1]))


@staticmethod
def concat_url(endpoint, url):
    """Concatenate endpoint and final URL.

        E.g., "http://keystone/v2.0/" and "/tokens" are concatenated to
        "http://keystone/v2.0/tokens".

        :param endpoint: the base URL
        :param url: the final URL
        """
    return '%s/%s' % (endpoint.rstrip('/'), url.strip('/'))


def _plural(num):
    """Return 's' if plural.
    """
    if num == 1:
        s = ''
    else:
        s = 's'
    return s


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

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

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

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

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


def add_rectangles(rectangle1, rectangle2):
    """Add two bounds or coordinate rectangles"""
    return rectangle1[0] + rectangle2[0], rectangle1[1] + rectangle2[1
        ], rectangle1[2] + rectangle2[2], rectangle1[3] + rectangle2[3]


def process():
    """ process the contents of the queue, i.e. start indexing;
            returns the number of processed queue items """


def unlink():
    """Unlink active text data-block

    """
    pass


def _repr_pairs(dump, tag, sequence, flow_style=None):
    """
    This is the same code as BaseRepresenter.represent_sequence(),
    but the value passed to dump.represent_data() in the loop is a
    dictionary instead of a tuple.

    Source: https://gist.github.com/weaver/317164
    License: Unspecified
    """
    import yaml
    value = []
    node = yaml.SequenceNode(tag, value, flow_style=flow_style)
    if dump.alias_key is not None:
        dump.represented_objects[dump.alias_key] = node
    best_style = True
    for key, val in sequence:
        item = dump.represent_data({key: val})
        if not (isinstance(item, yaml.ScalarNode) and not item.style):
            best_style = False
        value.append(item)
    if flow_style is None:
        if dump.default_flow_style is not None:
            node.flow_style = dump.default_flow_style
        else:
            node.flow_style = best_style
    return node


def get_all(isdsAppliance, check_mode=False, force=False):
    """
    Get all rsyslog objects
    """
    return isdsAppliance.invoke_get('Get all rsyslog objects',
        '/rsp_rsyslog_objs')


@classmethod
def get_label(cls):
    """
        return the next label
        """
    code = cls.last_label
    cls.last_label += 1
    if code < 26:
        label = chr(97 + code)
    elif code < 26 * 26:
        label = chr(96 + code // 26) + chr(97 + code % 26)
    else:
        a = code % 26
        b = code // 26
        label = chr(96 + b // 26) + chr(97 + b % 26) + chr(97 + a)
    return label, code


def f_is_subset(f1, f2):
    """ Check if f1 is subset of f2 """
    f1_data = set(open(f1).readlines())
    f2_data = set(open(f2).readlines())
    return f1_data.issubset(f2_data)


def successfully_imported_pycalphad():
    """
    Checks if pycalphad is installed.
    If not, warns the user that pycalphad-dependent features cannot be used
    Also tells the user how to install it (if the user has Anaconda)
    """
    try:
        import pycalphad as pyc
    except ImportError:
        print('The feature you are trying to use requires pycalphad')
        print(
            "In Anaconda, use 'conda install -c pycalphad -c conda-forge pycalphad' to install it"
            )
        return False
    return True


def make_signal_header(label, dimension='uV', sample_rate=256, physical_min
    =-200, physical_max=200, digital_min=-32768, digital_max=32767,
    transducer='', prefiler=''):
    """
    A convenience function that creates a signal header for a given signal.
    This can be used to create a list of signal headers that is used by
    pyedflib to create an edf. With this, different sampling frequencies
    can be indicated.

    Parameters
    ----------
    label : str
        the name of the channel.
    dimension : str, optional
        dimension, eg mV. The default is 'uV'.
    sample_rate : int, optional
        sampling frequency. The default is 256.
    physical_min : float, optional
        minimum value in dimension. The default is -200.
    physical_max : float, optional
        maximum value in dimension. The default is 200.
    digital_min : int, optional
        digital minimum of the ADC. The default is -32768.
    digital_max : int, optional
        digital maximum of the ADC. The default is 32767.
    transducer : str, optional
        electrode type that was used. The default is ''.
    prefiler : str, optional
        filtering and sampling method. The default is ''.

    Returns
    -------
    signal_header : dict
        a signal header that can be used to save a channel to an EDF.

    """
    signal_header = {'label': label, 'dimension': dimension, 'sample_rate':
        sample_rate, 'physical_min': physical_min, 'physical_max':
        physical_max, 'digital_min': digital_min, 'digital_max':
        digital_max, 'transducer': transducer, 'prefilter': prefiler}
    return signal_header


def broadcast_div(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Returns element-wise division of the input arrays with broadcasting.

    Example::

       x = [[ 6.,  6.,  6.],
            [ 6.,  6.,  6.]]

       y = [[ 2.],
            [ 3.]]

       broadcast_div(x, y) = [[ 3.,  3.,  3.],
                              [ 2.,  2.,  2.]]

    Supported sparse operations:

       broadcast_div(csr, dense(1D)) = csr

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_basic.cc:L187

    Parameters
    ----------
    lhs : NDArray
        First input to the function
    rhs : NDArray
        Second input to the function

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

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


def p_common_scalar_lnumber(p):
    """common_scalar : LNUMBER"""
    if p[1].startswith('0x'):
        p[0] = int(p[1], 16)
    elif p[1].startswith('0b'):
        p[0] = int(p[1], 2)
    elif p[1].startswith('0'):
        p[0] = int(p[1], 8)
    else:
        p[0] = int(p[1])


def _is_probably_task_error(error):
    """Used to identify task errors."""
    return 'subprocess failed' in error.get('hadoop_error', {}).get('message',
        '')


def offset(acqu, proc):
    """
    computes the offset from Bruker to spike
    """
    try:
        ppmPointUn = float(proc['$OFFSET'])
        ppmWidth = float(acqu['$SW_h']) / float(acqu['$SFO1'])
        calibrationOffset = float(ppmPointUn - ppmWidth) * float(acqu['$SFO1'])
    except:
        calibrationOffset = 0.0
    return calibrationOffset


def _straceback():
    """Returns a string with the traceback."""
    import traceback
    return traceback.format_exc()


def split_iterable(iterable, nchunks):
    """Return generator yielding lists derived from the iterable.

    :param iterable: an interable
    :param nchunks: number of chunks the iterable should be split into
    :returns: generator yielding lists from the iterable
    """
    num_items = len(iterable)
    chunk_size = num_items // nchunks
    left_over_items = num_items % nchunks
    index = 0
    for n in range(nchunks, 0, -1):
        chunk = []
        for i in range(chunk_size):
            chunk.append(iterable[index])
            index += 1
        if n <= left_over_items:
            chunk.append(iterable[index])
            index += 1
        yield chunk


def project_or_object(project=None, basecamp_object=None, section_name=None):
    """
    The purpose of this function is to provide a Project ID and Object ID given certain kinds of information or to raise
    the appropriate error if the information given isn't enough.

    Given a project object or ID and/or basecamp_object or ID, determines if the ID for both can be found.
    If `project` is an object and `section_name` is given, the ID of the `basecamp_object` can be determined by
    searching the Project object's `dock` list.

    If a `basecamp_object` is given, the Project ID can be found by looking at its "bucket" dictionary.

    If `project` is an int (the Project ID), then `basecamp_object` cannot be None and vice versa. The other variable
    must also be an int or the object.

    :param project:         a Project object or ID. Optional if `basecamp_object` is an Object
    :type project:          basecampy3.endpoints.projects.Project|int

    :param basecamp_object: a Basecamp Object object or ID. Optional if Project is an Object, the BasecampObject to
                                find is a type that appears in a Project's "dock", and `section_name` is specified.
    :type basecamp_object:  basecampy3.endpoints._base.BasecampObject|int

    :param section_name:    the "name" of the section on a project's "dock". Optional if `basecamp_object` is an object
                                or both `project` and `basecamp_object` are IDs
    :type section_name:     str

    :return:                a tuple where the first element is the Project's ID and the second element is the
                                Basecamp Object's ID
    :rtype:                 (int, int)
    """
    if project is None and basecamp_object is None:
        raise ValueError('At least one parameter must be given')
    if project is None:
        project_id = basecamp_object.bucket['id']
        object_id = int(basecamp_object)
    elif basecamp_object is None:
        if section_name is None:
            raise ValueError(
                "To find an object's ID with only a Project given, you must specify the section's name as it appears in the Project's dock. (i.e. todoset, chat, schedule, vault, inbox, message_board)"
                )
        for section in project.dock:
            if section['name'] == section_name:
                object_id = section['id']
                break
        else:
            msg = (
                "{project} does not have '{section}' in its dock. Does this project not use {section}?"
                .format(project=str(project), section=section_name))
            ex = AttributeError(msg)
            raise ex
        project_id = int(project)
    else:
        project_id = int(project)
        object_id = int(basecamp_object)
    return project_id, object_id


def validate_zoom(zoom):
    """
    Assert zoom value is positive integer.

    Returns
    -------
    zoom

    Raises
    ------
    TypeError if type is invalid.
    """
    if any([not isinstance(zoom, int), zoom < 0]):
        raise TypeError('zoom must be a positive integer: %s' % zoom)
    return zoom


def import_symbol(full_symbol_name):
    """ Imports a symbol (e.g. class, variable, etc) from a dot separated name.
        Can be used to create a class whose type is only known at run-time.

        The full_symbol_name must contain packages and module,
        e.g.: 'argos.plugins.rti.ncdf.NcdfFileRti'

        If the module doesn't exist an ImportError is raised.
        If the class doesn't exist an AttributeError is raised.
    """
    parts = full_symbol_name.rsplit('.', 1)
    if len(parts) == 2:
        module_name, symbol_name = parts
        module_name = str(module_name)
        symbol_name = str(symbol_name)
        module = __import__(module_name, fromlist=[symbol_name])
        cls = getattr(module, symbol_name)
        return cls
    elif len(parts) == 1:
        raise ImportError('full_symbol_name should contain a module')
    else:
        assert False, 'Bug: parts should have 1 or elements: {}'.format(parts)


def _setup(app_obj):
    """
        The _setup function is called during application initialization and
        must 'setup' the handler object making it ready for the framework
        or the application to make further calls to it.

        :param app_obj: The application object.
        :returns: None

        """


def group_edit(exit: bool=False):
    """Edit node group

    :param exit: Exit
    :type exit: bool
    """
    pass


def add_table_suffix(table, suffix):
    """Helper to deal with backticks when adding table suffix"""
    table = str(table)
    if table.endswith('`'):
        table = table.rstrip('`') + suffix + '`'
    else:
        table = table + suffix
    return table


def get_block_boundaries(schedule):
    """
    Return a dictionary mapping indices of
    :class:`loopy.schedule.BlockBeginItem`s to
    :class:`loopy.schedule.BlockEndItem`s and vice versa.
    """
    from loopy.schedule import BeginBlockItem, EndBlockItem
    block_bounds = {}
    active_blocks = []
    for idx, sched_item in enumerate(schedule):
        if isinstance(sched_item, BeginBlockItem):
            active_blocks.append(idx)
        elif isinstance(sched_item, EndBlockItem):
            start = active_blocks.pop()
            block_bounds[start] = idx
            block_bounds[idx] = start
    return block_bounds


def timer(start, end):
    """
    This function calcualtes the elapsed time between the start of the function until the end of this.
    :param: float: starting time.
    :param: float: ending time.
    :return: str: time elapsed.
    """
    hours, rem = divmod(end - start, 3600)
    minutes, seconds = divmod(rem, 60)
    return '{:0>2}:{:0>2}:{:05.2f}'.format(int(hours), int(minutes), seconds)


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    if not client_message.read_bool():
        parameters['response'] = to_object(client_message.read_data())
    return parameters


@classmethod
def forTestCase(cls, testCase, specification=None):
    """
        Creates a registry for this test case.

        Immediately starts this registry and schedules it to be cleaned up.
        """
    if specification is None:
        specification = testCase.mockSpecification
    registry = cls(specification)
    registry.start()
    testCase.addCleanup(registry.stop)
    return registry


def str2list(string: str, type_func) ->list:
    """ Takes a Python list-formatted string and returns a list of elements of type type_func """
    return list(map(type_func, string.strip('()[]').split(',')))


def _get_return_value_name_from_line(line_str):
    """
    Get the return value name from the target line string.

    Parameters
    ----------
    line_str : str
        Target line string. e.g., 'price : int'

    Returns
    -------
    return_value_name : str
        Return value name. If colon character not exists in
        line string, a blank string will be set.
    """
    colon_exists = ':' in line_str
    if colon_exists:
        return_value_name = line_str.split(':')[0]
    else:
        return_value_name = ''
    return_value_name = return_value_name.strip()
    return return_value_name


def get_id_by_name(api, search_name):
    """
    calls 'get_all' on the given API with a search name and returns the ID of the entity retrieved, if any, None otherwise
    :param api: api to search
    :param search_name: name to test for
    :return ID of entity matching search_name, None otherwise
    """
    entities = api.get_all(q='name==' + "'" + search_name + "'").content
    if entities:
        return entities[0].id
    return


def progress_time(total_time, elapsed=0, prefix='', suffix='', decimals=1,
    length=100, fill='█'):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals
                                  in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
    """
    filled_length = int(length * elapsed // total_time)
    bar = fill * filled_length + '-' * (length - filled_length)
    print('\r{prefix} |{bar}| {left} {suffix}'.format(prefix=round(elapsed),
        bar=bar, left=round(total_time - elapsed), suffix=suffix), end='\r')


def sft32kgm3(density_slft3):
    """Convert density from slugs/ft^3 to kg/m^3"""
    return density_slft3 / 0.00194032


@classmethod
def getQtDesignerPluginInfo(cls):
    """Returns pertinent information in order to be able to build a valid
        QtDesigner widget plugin

        :return: (dict) a map with pertinent designer information"""
    return {'module': 'taurus.qt.qtgui.qwt5', 'group': 'Taurus Display',
        'icon': 'designer:qwtplot.png', 'container': False}


def FormatValue(val, maxdigits=None):
    """Format a float to fit in at most ``maxdigits[0]`` spaces with maxdigits[1] after decimal.
    Note that this code has been hacked from FormatSigFigs and may have unused sections.

    :param float val: number to be formatted.

    :param list maxdigits: the number of digits, places after decimal and 'f' or 'g' to be used for display of the
      number (defaults to [10,2,'f']).

    :returns: a string with <= maxdigits characters (usually).
    """
    if 'str' in str(type(val)) and (val == '?' or val == '.'):
        return val
    if maxdigits is None:
        digits = [10, 2, 'f']
    else:
        digits = list(maxdigits)
    if len(digits) == 2:
        digits.append('f')
    if not val:
        digits[2] = 'f'
    fmt = '{:' + str(digits[0]) + '.' + str(digits[1]) + digits[2] + '}'
    string = fmt.format(float(val)).strip()
    if len(string) <= digits[0]:
        if ':' in string:
            string = str(val)
        if digits[1] > 0:
            string = string.rstrip('0')
            if string[-1] == '.':
                string += '0'
        return string
    if val < 0:
        digits[0] -= 1
    decimals = digits[0] - digits[1]
    if abs(val) > 1e+99:
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], digits[0] - 6) + '}'
    elif abs(val) > 1000000000.0:
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], digits[0] - 5) + '}'
    elif abs(val) < 10 ** (4 - decimals):
        decimals = min(digits[0] - 5, digits[1])
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], decimals) + '}'
    elif abs(val) >= 10 ** (decimals - 1):
        decimals = max(0, digits[0] - 5)
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], decimals) + '}'
    elif abs(val) < 1:
        decimals = min(digits[0] - 3, digits[1])
        fmt = '{' + ':{:d}.{:d}f'.format(digits[0], decimals) + '}'
    else:
        decimals = digits[0] - 6
        fmt = '{' + ':{:d}.{:d}g'.format(digits[0], decimals) + '}'
    try:
        return fmt.format(float(val)).strip()
    except ValueError:
        print('FormatValue Error with val,maxdigits,fmt= %f %d %s' % (val,
            maxdigits, fmt))
        return str(val)


def del_field(key, obj):
    """
    Remove field from dictionary.

    :param key: path to field in dictionary
    :type key: str

    :param obj: dictionary used for search
    :type obj: dict
    """
    val = obj
    subkeys = key.split('.')
    for subkey in subkeys[:-1]:
        if subkey not in val:
            return
        val = val[subkey]
    del val[subkeys[-1]]


@staticmethod
def density_conditions(weight=0, link_density=0.0):
    """
        Evaluates conditions about density of links
        :param weight: tag's weight
        :param link_density: link density indicator
        :return: flag if conditions are True or False
        """
    return (weight < 25 and link_density > 0.2 or weight >= 25 and
        link_density > 0.5)


def get_current_canvas():
    """ Proxy for context.get_current_canvas to avoud circular import.
    This function replaces itself with the real function the first
    time it is called. (Bah)
    """
    from .context import get_current_canvas
    globals()['get_current_canvas'] = get_current_canvas
    return get_current_canvas()


def calculate_duration(start, end, unfinished_reason):
    """
	Calculates the duration between two timestamps. If 'end' is None (thereby
	yielding the calculation impossible) then 'unfinished_reason' is returned.
	"""
    if start is None or end is None:
        return unfinished_reason
    else:
        return end - start


def _extract_user_from_email(raw_username):
    """
    Usernames come from the globus provider in the form:
    username@login_authority.com
    """
    if not raw_username:
        return None
    return raw_username.split('@')[0]


def package_root(varmap):
    """Return correct directory for the root package.

    The "root" package is the one where modules which do not
    belong to a package are located (see the distutils docs).
    This function should not need to be called directly in
    your actual setup script, but it can be useful for testing.
    Note that it looks for a ``package_root`` setup var, which
    can be used as a shortcut if your "root" package is not in
    the standard place (which is your setup script directory),
    rather than having to declare a ``package_dir`` dictionary
    with a ``''`` key.
    """
    try:
        return varmap['package_dir']['']
    except KeyError:
        try:
            result = varmap['package_root']
        except KeyError:
            return '.'
        else:
            dirmap = varmap.setdefault('package_dir', {})
            if '' not in dirmap:
                dirmap[''] = result
            return result


def butlast(seq):
    """Iterates over all elements of the sequence but last."""
    it = iter(seq)
    try:
        prev = next(it)
    except StopIteration:
        pass
    else:
        for item in it:
            yield prev
            prev = item


def aux_paral_f_ns(x):
    """
    Auxiliary function needed in parallel propagate
    """
    os, rg, dp, rb = x
    os.ray_add(rb)
    os.propagate_ray_ns(rg, dp)
    return os


def select_linked_pick(extend: bool=False):
    """Select a chain of linked strips nearest to the mouse pointer

    :param extend: Extend, Extend the selection
    :type extend: bool
    """
    pass


def name(obj):
    """Try to find some reasonable name for the object."""
    return getattr(obj, 'name', 0) or getattr(obj, '__name__', 0) or getattr(
        getattr(obj, '__class__', 0), '__name__', 0) or str(obj)


def CheckFormatString(pattern, *arguments):
    """
    Checks if the given format string (for instance, "%.g") is valid for the given arguments.
    :param pattern: a string in "%" format
    :param arguments: the arguments to check against
    :raises ValueError:
        if the format is invalid.
    """
    try:
        pattern % arguments
    except (TypeError, ValueError):
        raise ValueError('%r is not a valid format string.' % pattern)


def handle_extensions(extensions):
    """
    Organize multiple extensions that are separated with commas or passed by
    using --extension/-e multiple times.

    For example: running 'django-admin makemessages -e js,txt -e xhtml -a'
    would result in an extension list: ['.js', '.txt', '.xhtml']

    >>> handle_extensions(['.html', 'html,js,py,py,py,.py', 'py,.py'])
    {'.html', '.js', '.py'}
    >>> handle_extensions(['.html, txt,.tpl'])
    {'.html', '.tpl', '.txt'}
    """
    ext_list = []
    for ext in extensions:
        ext_list.extend(ext.replace(' ', '').split(','))
    for i, ext in enumerate(ext_list):
        if not ext.startswith('.'):
            ext_list[i] = '.%s' % ext_list[i]
    return set(ext_list)


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

    The ".dev0" means dirty.

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


@staticmethod
def assert_element_tag(el, expected_tag):
    """Method to assert that the tag of an element is as expected.

        :param el: element
        :rtype el: str
        :param expected_tag: expected tag
        :type expected_tag: str
        """
    if expected_tag:
        assert el.tag == expected_tag, 'Element should have tag {}, but has tag: {}.'.format(
            expected_tag, el.tag)


def squared_error(a, b):
    """Computes the element-wise squared difference between two tensors.

    .. math:: L = (p - t)^2

    Parameters
    ----------
    a, b : Theano tensor
        The tensors to compute the squared difference between.

    Returns
    -------
    Theano tensor
        An expression for the item-wise squared difference.

    Notes
    -----
    This is the loss function of choice for many regression problems
    or auto-encoders with linear output units.
    """
    return (a - b) ** 2


def dice_loss(output, target, ignore_index=None):
    """
    output : NxCxHxW Variable
    target :  NxHxW LongTensor
    ignore_index : int index to ignore from loss
    """
    encoded_target = output.detach() * 0
    if ignore_index is not None:
        mask = target == ignore_index
        target = target.clone()
        target[mask] = 0
        encoded_target.scatter_(1, target.unsqueeze(1), 1)
        mask = mask.unsqueeze(1).expand_as(encoded_target)
        encoded_target[mask] = 0
    else:
        encoded_target.scatter_(1, target.unsqueeze(1), 1)
    numerator = 2 * (output * encoded_target).sum(0).sum(1).sum(1)
    denominator = output + encoded_target
    if ignore_index is not None:
        denominator[mask] = 0
    denominator = denominator.sum(0).sum(1).sum(1)
    loss = 1 - numerator / denominator
    return loss.sum() / loss.size(0)


def answer_question(talker, quest):
    """
  given the json string quest as input containing a question
  in English, ended with '?', to be parsed with json.loads,
  it returns a list of answers about he document,
  as a json string that can be parsed with with json.loads
  to a list of lists of words
  """
    return talker.answer_question(quest)


@classmethod
def from_dict(cls, d):
    """
        Construct a new `UpdateByQuery` instance from a raw dict containing the search
        body. Useful when migrating from raw dictionaries.

        Example::

            ubq = UpdateByQuery.from_dict({
                "query": {
                    "bool": {
                        "must": [...]
                    }
                },
                "script": {...}
            })
            ubq = ubq.filter('term', published=True)
        """
    u = cls()
    u.update_from_dict(d)
    return u


def do_code_hilite(md, what='all'):
    """
    "inverse" mode for source code highlighting:
    the file contains mainly code and md is within docstrings
    what in  all, code, doc, mod
    """
    if what not in ('all', 'code', 'doc', 'mod'):
        what = 'all'
    code_mode, md_mode = 1, 2
    blocks, block, mode = [], [], code_mode
    blocks.append([mode, block])
    lines = ('\n' + md).splitlines()
    mdstart = '\x01'
    while lines:
        line = lines.pop(0)
        if mode == code_mode:
            if line.rstrip() in ('"""_', "'''_", '/*_'):
                mdstart = line.rstrip()[:-1]
                mode = md_mode
                block = []
                if mdstart == '/*':
                    mdstart = '*/'
                blocks.append([md_mode, block])
                continue
        elif line.rstrip() == mdstart:
            if what == 'doc':
                break
            mode = code_mode
            block = []
            blocks.append([code_mode, block])
            continue
        if mode == code_mode:
            if what in ('all', 'code'):
                block.append(line)
        elif what != 'code':
            block.append(line)
    out = []
    for mode, block in blocks:
        b = '\n'.join(block)
        if not b:
            continue
        if mode == code_mode:
            out.append('```\n%s\n```' % b)
        else:
            out.append('\n'.join(block))
    return '\n'.join(out)


def parse_conf(lines):
    """
    A simple configuration file parser.
    this parser supports comments and multiple values assigned to one key. One
    possible gotcha is that every item will be returned as a list.

    >>> parse_conf(["q 1, 2, 3", "d   w", "# doesn't do anything"])
    {"q": ["1", "2", "3"], "d": ["w"]}

    AUTHORS:
    v0.2.0+             --> pydsigner
    """
    dt = {}
    for L in lines:
        if L.startswith('#'):
            continue
        p = L.split(None, 1)
        dt[p[0]] = p[1].split(', ')
    return dt


@classmethod
def reset_state(cls):
    """Remove memory of the shared state."""
    cls.class_state = None


def merge_dicts(x, y):
    """A function to merge two dictionaries, making it easier for us to make modality specific queries
    for dwi images (since they have variable extensions due to having an nii.gz, bval, and bvec file)

    Parameters
    ----------
    x : dict
        dictionary you want merged with y
    y : dict
        dictionary you want merged with x

    Returns
    -------
    dict
        combined dictionary with {x content,y content}
    """
    z = x.copy()
    z.update(y)
    return z


@staticmethod
def _unsubscribe(sub_id):
    """Stop listening to a queue or a broadcast
        :param sub_id: ID for this subscription in the transport layer
        """
    raise NotImplementedError('Transport interface not implemented')


def is_int_like(val):
    """Check if a value looks like an int."""
    try:
        return str(int(val)) == str(val)
    except Exception:
        return False


def get_catkin_cmake_args_completer_choices():
    """Get completer choices for CMake arguments for catkin packages."""
    return [' -DCATKIN_ENABLE_TESTING={flag}'.format_map(locals()) for flag in
        ('OFF', 'ON')] + [' -DCATKIN_SKIP_TESTING={flag}'.format_map(locals
        ()) for flag in ('OFF', 'ON')] + [' -DSETUPTOOLS_DEB_LAYOUT={flag}'
        .format_map(locals()) for flag in ('OFF', 'ON')]


def select_circle(x: int=0, y: int=0, radius: int=1, gesture_mode: int=0):
    """Select items using circle selection

    :param x: X
    :type x: int
    :param y: Y
    :type y: int
    :param radius: Radius
    :type radius: int
    :param gesture_mode: Event Type
    :type gesture_mode: int
    """
    pass


def is_not_false(*args) ->bool:
    """If all item in args is True, return True."""
    for item in args:
        if not item:
            return False
    return True


def _split_path(path):
    """split a path return by the api

    return
        - the sentinel:
        - the rest of the path as a list.
        - the original path stripped of / for normalisation.
    """
    path = path.strip('/')
    list_path = path.split('/')
    sentinel = list_path.pop(0)
    return sentinel, list_path, path


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


def filter_value(old: float, new: float, factor: float) ->float:
    """ Linearly interpolate between two float values. """
    r_factor: float = 1 - factor
    return old * r_factor + new * factor


def get_element_attribute_value(xml, element_name, attribute_name):
    """Returns the attribute value of the given attribute name from the
        given element name
        """


def standard(target, mol_weight='pore.molecular_weight', molar_density=
    'pore.molar_density'):
    """
    Calculates the mass density from the molecular weight and molar density

    Parameters
    ----------
    target : OpenPNM Object
        The object for which these values are being calculated.  This
        controls the length of the calculated array, and also provides
        access to other necessary thermofluid properties.

    mol_weight : string
        The dictionary key containing the molecular weight values (kg/mol)

    molar_density : string
        The dictionary key containing the molar density values (mol/m3)

    Returns
    -------
    value : NumPy ndarray
        Array containing density values (kg/m3)

    """
    MW = target[mol_weight]
    rho = target[molar_density]
    value = rho * MW
    return value


@staticmethod
def _populate_dictionary(theta, dictionary_in):
    """Populate the dictionary of free parameters."""
    dictionary = dictionary_in.copy()
    for key in dictionary.keys():
        if isinstance(dictionary[key], int):
            if not isinstance(dictionary[key], bool):
                dictionary[key] = theta[dictionary[key]]
    return dictionary


def SizeBenefitMat(t):
    """Maturity benefit per policy"""
    return 0