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 latent_heat_lambda(air_temperature):
    """
    Function to calculate the latent heat of vapourisation,
    lambda, from air temperature. Source: J. Bringfelt. Test of a forest
    evapotranspiration model. Meteorology and Climatology Reports 52,
    SMHI, Norrkopping, Sweden, 1986.

    Input:
        - air_temperature: (array of) air temperature [Celsius]

    Output:
        - L: (array of) lambda [J kg-1 K-1]

    Examples:
        >>> latent_heat_lambda(25)
        >>> 2440883.8804624998
        >>> t=[10, 20, 30]
        >>> latent_heat_lambda(t)
        >>> array([ 2476387.3842125,  2452718.3817125,  2429049.3792125])

    Parameters
    ----------
    air_temperature

    Returns
    -------
    ndarray
    """
    return 4185.5 * (751.78 - 0.5655 * (air_temperature + 273.15))


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

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

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


def on_mouse_released():
    """
    The mouse release event handler.

    You can redefine this function to handle the mouse release event.
    """
    pass


def save_parameters_to_file(dataset, filename):
    """Save best-fit parameters to file."""
    header = '#comp   ion   redshift               b (km/s)       log(N/cm^-2)'
    with open(filename, 'w') as output:
        output.write(header + '\n')
        for ion in sorted(dataset.components.keys()):
            for i in range(len(dataset.components[ion])):
                z = dataset.best_fit['z%i_%s' % (i, ion)]
                logN = dataset.best_fit['logN%i_%s' % (i, ion)]
                b = dataset.best_fit['b%i_%s' % (i, ion)]
                par_tuple = (i, ion, z.value, z.stderr, b.value, b.stderr,
                    logN.value, logN.stderr)
                line_fmt = '%3i  %7s  %.6f %.6f    %6.2f %6.2f    %.3f %.3f'
                output.write(line_fmt % par_tuple + '\n')
            output.write('\n')
        output.write('\n\n# Python script version:\n')
        output.write(
            '# The commands below can be copied directly to a script.\n')
        z_sys = dataset.redshift
        output.write('# dataset.redshift = %.6f.\n' % z_sys)
        for ion in dataset.components.keys():
            for i in range(len(dataset.components[ion])):
                z = dataset.best_fit['z%i_%s' % (i, ion)]
                logN = dataset.best_fit['logN%i_%s' % (i, ion)]
                b = dataset.best_fit['b%i_%s' % (i, ion)]
                vel_value = (z.value - z_sys) / (z_sys + 1) * 299792.458
                par_tuple = ion, vel_value, b.value, logN.value
                line_fmt = (
                    "# dataset.add_component_velocity('%s', %.1f, %.1f, %.1f)")
                output.write(line_fmt % par_tuple + '\n')
            output.write('\n')


def get_global_components():
    """Return the global site manager.

        This function should never fail and always return an object that
        provides `IGlobalSiteManager`.
        """


def array2geotiff(data, filename, nodata=-9999, transform=None, extents=None):
    """
    Write a geotiff file called "filename" from the numpy array "data".
    Input:
        data: A 2D numpy array with shape (nx,ny)
        filename: The filename of the output geotiff
        nodata:  The nodata value of the array (defaults to -9999)
        transform (optional): Either a 3x2 numpy array describing
            an affine transformation to georeference the geotiff
            with, or an object that has a transform attribute
            containing such an array (e.g. a geoprobe.volume object)
        extents (optional): Either a 2-tuple of the coords of the
            lower left corner of "data" (xmin, ymin) or an object
            with xmin, xmax, ymin, ymax attributes (e.g. a geoprobe
            volume object). This overrides the x and y offsets in
            "transform". If transform is not given, it is ignored.
            Note that if you're using a horizon object as input to
            "extents", you'll need to call volume.model2world on
            horizon.xmin & ymin, as a horizon's coordinates are
            stored in model (inline, crossline) space.
    """
    try:
        import osgeo.gdal as gdal
    except ImportError:
        raise ImportError(
            'Gdal not found! To use horizon.toGeotiff, gdal and the python bindings to gdal must be installed'
            )
    if transform is not None:
        try:
            transform = transform.transform
        except AttributeError:
            pass
    if extents is not None:
        try:
            xmin, ymin = extents
        except:
            try:
                xmin, ymin = extents.xmin, extents.ymin
            except AttributeError:
                raise ValueError(
                    'Extents must be either a 2-tuple of xmin,ymin or an object with xmin,ymin properities'
                    )
    else:
        xmin, ymin = 0, 0
    if filename[-4:] in ['.tif', 'tiff']:
        format = 'GTiff'
    elif filename[-3:] == 'img':
        format = 'HFA'
    else:
        format = 'GTiff'
        filename += '.tif'
    ysize, xsize = data.shape
    driver = gdal.GetDriverByName(format)
    dataset = driver.Create(filename, xsize, ysize, 1, gdal.GDT_Float32)
    if transform is not None:
        dataset.SetGeoTransform([xmin, transform[0, 0], transform[0, 1],
            ymin, transform[1, 0], transform[1, 1]])
    dataset.GetRasterBand(1).SetNoDataValue(nodata)
    dataset.GetRasterBand(1).WriteArray(data)


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


def stride_parser(lines):
    """Parses stride output. Returns a ``full_id:{data}`` dictionary.

    The parser does not currently support the following (useful) options:

        - hydrogen bond assignments (-h)
        - contact order calculation (-k)

    The returned data is a dictionary with the following keys:
        'STRIDE_SS': secondary structure,
        'STRIDE_PHI': phi angle,
        'STRIDE_PSI': psi angle,
        'STRIDE_ASA': accessible surface area
    """
    data = {}
    for line in lines:
        if line.startswith('ASG'):
            res_name = line[5:8]
            chain_id = line[9]
            if chain_id == '-':
                chain_id = ' '
            try:
                res_id = int(float(line[10:15]))
                res_ic = ' '
            except ValueError:
                res_id = int(float(line[10:14]))
                res_ic = line[14]
            ss_code = line[24]
            phi = float(line[43:49])
            psi = float(line[53:59])
            asa = float(line[62:69])
            data[None, None, chain_id, (res_name, res_id, res_ic), None] = {
                'STRIDE_SS': ss_code, 'STRIDE_PHI': phi, 'STRIDE_PSI': psi,
                'STRIDE_ASA': asa}
    return data


def describe_stored_iscsi_volumes(VolumeARNs=None):
    """
    Returns the description of the gateway volumes specified in the request. The list of gateway volumes in the request must be from one gateway. In the response Amazon Storage Gateway returns volume information sorted by volume ARNs. This operation is only supported in stored volume gateway architecture.
    See also: AWS API Documentation

    Examples
    Returns the description of the gateway volumes specified in the request belonging to the same gateway.
    Expected Output:

    :example: response = client.describe_stored_iscsi_volumes(
        VolumeARNs=[
            'string',
        ]
    )

    :type VolumeARNs: list
    :param VolumeARNs: [REQUIRED]
            An array of strings where each string represents the Amazon Resource Name (ARN) of a stored volume. All of the specified stored volumes must from the same gateway. Use ListVolumes to get volume ARNs for a gateway.
            (string) --

    :rtype: dict
    :return: {
        'StorediSCSIVolumes': [
            {
                'VolumeARN': 'string',
                'VolumeId': 'string',
                'VolumeType': 'string',
                'VolumeStatus': 'string',
                'VolumeSizeInBytes': 123,
                'VolumeProgress': 123.0,
                'VolumeDiskId': 'string',
                'SourceSnapshotId': 'string',
                'PreservedExistingData': True|False,
                'VolumeiSCSIAttributes': {
                    'TargetARN': 'string',
                    'NetworkInterfaceId': 'string',
                    'NetworkInterfacePort': 123,
                    'LunNumber': 123,
                    'ChapEnabled': True|False
                },
                'CreatedDate': datetime(2015, 1, 1)
            },
        ]
    }

    """
    pass


def corner_extent(ul, ll, ur, lr):
    """Get min/max extent based on corner coord
    """
    xmin = min(ul[0], ll[0], ur[0], lr[0])
    xmax = max(ul[0], ll[0], ur[0], lr[0])
    ymin = min(ul[1], ll[1], ur[1], lr[1])
    ymax = max(ul[1], ll[1], ur[1], lr[1])
    extent = [xmin, ymin, xmax, ymax]
    return extent


def list_typed_link_facet_names(SchemaArn=None, NextToken=None, MaxResults=None
    ):
    """
    Returns a paginated list of TypedLink facet names for a particular schema. For more information, see Typed link .
    See also: AWS API Documentation

    :example: response = client.list_typed_link_facet_names(
        SchemaArn='string',
        NextToken='string',
        MaxResults=123
    )

    :type SchemaArn: string
    :param SchemaArn: [REQUIRED]
            The Amazon Resource Name (ARN) that is associated with the schema. For more information, see arns .

    :type NextToken: string
    :param NextToken: The pagination token.

    :type MaxResults: integer
    :param MaxResults: The maximum number of results to retrieve.

    :rtype: dict
    :return: {
        'FacetNames': [
            'string',
        ],
        'NextToken': 'string'
    }

    :returns:
    (string) --

    """
    pass


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


def parse_doc(doc):
    """
    Parse docstrings to dict, it should look like:
      key: value
    """
    if not doc:
        return {}
    out = {}
    for s in doc.split('\n'):
        s = s.strip().split(':', maxsplit=1)
        if len(s) == 2:
            out[s[0]] = s[1]
    return out


@staticmethod
def json_converter(obj):
    """
        Returns the representation string (repr()) for objects that can't be
        converted to JSON
        """
    return str(obj)


def remove_constant_features(sfm):
    """
    Remove features that are constant across all samples
    """
    x_not_equal_to_1st_row = sfm._x != sfm._x[0]
    non_const_f_bool_ind = x_not_equal_to_1st_row.sum(axis=0) >= 1
    return sfm.ind_x(selected_f_inds=non_const_f_bool_ind)


def to_fahrenheit(celsius):
    """Convert celsius to fahrenheit."""
    return int(round(celsius * 9 / 5 + 32, 0))


@classmethod
def raw_buoy_data(cls, buoy, data_type='txt'):
    """Retrieve the raw buoy data contents from NDBC.

        Parameters
        ----------
        buoy : str
            Name of buoy

        data_type : str
            Type of data requested, must be one of
            'txt' standard meteorological data
            'drift' meteorological data from drifting buoys and limited moored buoy data
            mainly from international partners
            'cwind' continuous winds data (10 minute average)
            'spec' spectral wave summaries
            'data_spec' raw spectral wave data
            'swdir' spectral wave data (alpha1)
            'swdir2' spectral wave data (alpha2)
            'swr1' spectral wave data (r1)
            'swr2' spectral wave data (r2)
            'adcp' acoustic doppler current profiler
            'ocean' oceanographic data
            'tide' tide data
            'srad' solar radiation data
            'dart' water column height
            'supl' supplemental measurements data
            'rain' hourly rain data

        Returns
        -------
        Raw data string

        """
    endpoint = cls()
    resp = endpoint.get_path('data/realtime2/{}.{}'.format(buoy, data_type))
    return resp.text


@classmethod
def get_carrier_methods_for_domain(cls):
    """
        Return the list of carrier methods that can be used for
        address validation
        """
    return []


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

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

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


def _split(f, s, a_p='', a_s='', b_p='', b_s='', reverse=False):
    """Split string on a symbol and return two string, first possible empty"""
    splitted = f.split(s)
    if len(splitted) == 1:
        a, b = '', splitted[0]
        if reverse:
            b, a = a, b
    else:
        a, b = splitted
    if a:
        a = '%s%s%s' % (a_p, a, a_s)
    if b:
        b = '%s%s%s' % (b_p, b, b_s)
    return a, b


@classmethod
def from_httplib(ResponseCls, r, **response_kw):
    """
        Given an :class:`httplib.HTTPResponse` instance ``r``, return a
        corresponding :class:`urllib3.response.HTTPResponse` object.

        Remaining parameters are passed to the HTTPResponse constructor, along
        with ``original_response=r``.
        """
    headers = {}
    for k, v in r.getheaders():
        k = k.lower()
        has_value = headers.get(k)
        if has_value:
            v = ', '.join([has_value, v])
        headers[k] = v
    strict = getattr(r, 'strict', 0)
    return ResponseCls(body=r, headers=headers, status=r.status, version=r.
        version, reason=r.reason, strict=strict, original_response=r, **
        response_kw)


def evaluate(me):
    """
evaluate this expression to a number with
variables taking their primal values.
"""
    return me.up.linearize(me.m)


def preloaded_multi_sgd_update(*data, **kwargs):
    """Update function for Stochastic Gradient Descent (SDG) optimizer.

    It updates the weights using::

     weight = weight - learning_rate * (gradient + wd * weight)

    Defined in src/operator/contrib/preloaded_multi_sgd.cc:L42

    Parameters
    ----------
    data : NDArray[]
        Weights, gradients, learning rates and weight decays
    rescale_grad : float, optional, default=1
        Rescale gradient to grad = rescale_grad*grad.
    clip_gradient : float, optional, default=-1
        Clip gradient to the range of [-clip_gradient, clip_gradient] If clip_gradient <= 0, gradient clipping is turned off. grad = max(min(grad, clip_gradient), -clip_gradient).
    num_weights : int, optional, default='1'
        Number of updated weights.

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

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


def resolutionComplete():
    """
        Resolution has completed; no further addresses will be relayed to
        L{IResolutionReceiver.addressResolved}.
        """


def print_project_policies_rejection(policy_dict):
    """ Prints the the policy and corresponding rejected resources from projects"""
    output = ''
    for policy in policy_dict:
        output += 'Rejected by Policy ' + '"' + policy + '":\n'
        for node in policy_dict[policy]:
            output += '\t* ' + node.resource.displayName
            licenses = node.resource.licenses
            if licenses is not None:
                license_output = ' ('
                for lice in licenses:
                    license_output += lice + ', '
                output += license_output[:-2] + ') \n'
    return output


def nodeType():
    """Return the node type.

        This is one of 'AND', 'OR', 'NOT', 'ATOM', 'PHRASE' or 'GLOB'.
        """


def tag_SPLT(lst):
    """ Assign new index and tag 'SPLT-' to every part of a split token."""
    if len(lst) > 9:
        inc = round(1 / len(lst), 2)
    else:
        inc = 0.1
    ind = lst[0]
    out = {}
    for i in range(1, len(lst)):
        out.update({(ind + inc * i): (lst[i], 'SPLT-')})
    return out


@classmethod
def create_from_lambda_arn(cls, client, lambda_arn):
    """Create a LogRetriever from a client and lambda arn.

        :type client: botocore.client.Logs
        :param client: A ``logs`` client.

        :type lambda_arn: str
        :param lambda_arn: The ARN of the lambda function.

        :return: An instance of ``LogRetriever``.

        """
    lambda_name = lambda_arn.split(':')[6]
    log_group_name = '/aws/lambda/%s' % lambda_name
    return cls(client, log_group_name)


def __new__(cls, *args, **kwargs):
    """Bypass Table.__new__."""
    return object.__new__(cls)


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


def decode_http_header(raw):
    """
    Decode a raw HTTP header into a unicode string. RFC 2616 specifies that
    they should be latin1-encoded (a.k.a. iso-8859-1). If the passed-in value
    is None, return an empty unicode string.

    :param raw:
        Raw HTTP header string.
    :type raw:
        string (non-unicode)
    :returns:
        Decoded HTTP header.
    :rtype:
        unicode string
    """
    if raw:
        return raw.decode('iso-8859-1', 'replace')
    else:
        return u''


@staticmethod
def get_rule_kwargs(data):
    """Extract the keyword arguments necessary to create a new instance
        for this class.
        """
    kwargs = dict()
    try:
        kwargs['score'] = list(map(float, data['score'].strip().split()))
    except KeyError:
        pass
    try:
        kwargs['desc'] = data['describe'].strip()
    except KeyError:
        pass
    try:
        kwargs['priority'] = data['priority'].strip()
    except KeyError:
        pass
    try:
        if data['tflags']:
            kwargs['tflags'] = []
        for flag in data['tflags']:
            kwargs['tflags'].append(flag.strip())
    except KeyError:
        pass
    return kwargs


def abort_multipart_upload(Bucket=None, Key=None, UploadId=None,
    RequestPayer=None):
    """
    Aborts a multipart upload.
    To verify that all parts have been removed, so you don't get charged for the part storage, you should call the List Parts operation and ensure the parts list is empty.
    See also: AWS API Documentation

    :example: response = client.abort_multipart_upload(
        Bucket='string',
        Key='string',
        UploadId='string',
        RequestPayer='requester'
    )

    :type Bucket: string
    :param Bucket: [REQUIRED]

    :type Key: string
    :param Key: [REQUIRED]

    :type UploadId: string
    :param UploadId: [REQUIRED]

    :type RequestPayer: string
    :param RequestPayer: Confirms that the requester knows that she or he will be charged for the request. Bucket owners need not specify this parameter in their requests. Documentation on downloading objects from requester pays buckets can be found at http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html

    :rtype: dict
    :return: {
        'RequestCharged': 'requester'
    }

    :returns:
    (dict) --
    RequestCharged (string) -- If present, indicates that the requester was successfully charged for the request.

    """
    pass


def getTaggedValue(tag):
    """Returns the value associated with `tag`.

        Raise a `KeyError` of the tag isn't set.
        """


def get_homopol_run(var):
    """
    Return the largest contiguous homopolymer run of the variant allele,
    or None if it isn't present in the VCF.
    """
    return var.INFO.get('HRun')


def properties_root_device_name(properties):
    """Get root device name from image meta data.
    If it isn't specified, return None.
    """
    root_device_name = None
    for bdm in properties.get('mappings', []):
        if bdm['virtual'] == 'root':
            root_device_name = bdm['device']
    if 'root_device_name' in properties:
        root_device_name = properties['root_device_name']
    return root_device_name


def duplicate():
    """Duplicate selected control points and segments between them

    """
    pass


def get_initiator_from_call_stack(call_stack):
    """Return the bottom element of the call stack."""
    if call_stack and type(call_stack) == str:
        return call_stack.strip().split('\n')[-1]
    else:
        return ''


def psi_H_CO3_HSO4_HMW84(T, P):
    """c-a-a': hydrogen carbonate bisulfate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@staticmethod
def str2bytes(ss):
    """
        Converts a string to a sequence of byte values.
        """
    return bytes(ss)


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

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

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


def client_point_of_execution_f() ->str:
    """
    The idea is to separate details of the endpoint and transmitting the request.
    ``status_code`` handling could be placed or called here
    """
    py_code = f"""
    def _add_auth_header(self, headers=None):
        ""\" adds the preconfigured authorization header ""\"
        if headers is None:
            headers = dict()
        headers[self.AUTH_HEADER_NAME] = f'{{self.AUTH_PREFIX}}{{self.API_TOKEN}}'
        return headers

    def _do_call(self, method=None, url=None, headers=None, fields=None, body=None, **kwargs):
        ""\"
        A way to separate each resource from the actual request dispatching point
        Response is assumed to be json by default. any other mapping can be hooked here.

        Use ``pass_through = True`` to receive the untouched response object

        Args:
            method (str): HTTP-Method
            url (str): endpoint
            headers (dict): each key:value pair represents one header field:value. Don't nest!
            fields (dict):  each key:value pair will be urlencoded and passed as query string. Don't nest!
            body (dict): will be encoded to JSON and bytes afterwards
                         You can get a urlencoding by setting
                         'Content-Type': 'application/x-www-form-urlencoded'

        ""\"

        headers = self._add_auth_header(headers)
        if body is not None and method in ['POST', 'PUT', 'PATCH']:
            if 'Content-Type' not in headers:
                headers['Content-Type'] = 'application/json'
                r = self.http.request(
                        method=method,
                        url=url,
                        body=self._encode(body),
                        headers=headers
                    )
            else:
                if headers['Content-Type'] == 'application/x-www-form-urlencoded':
                    r = self.http.urlopen(
                            method,
                            url,
                            body=self._encode(body, 'url'),
                            headers=headers
                    )
                elif headers['Content-Type'] == 'application/json':
                    r = self.http.request(
                            method=method,
                            url=url,
                            body=self._encode(body),
                            headers=headers
                    )
                else:
                    msg = f''' The Content-Type header was set to {{headers['Content-Type']}}\\n
                    However, anything else than 'application/json' or 'application/x-www-form-urlencoded'\\n
                    is not accounted for in the client.\\n If you would like to add it look for:\\n\\n
                    client_point_of_execution_f to build the logic\\n
                    client_encoding_decoding_point_f for handling encoding\\n\\n
                    -1 (negative one) was returned to avoid a RunTimeError'''
                    warnings.warn(msg)
                    return -1
        else:
            r = self.http.request_encode_url(
                    method=method,
                    url=url,
                    headers=headers,
                    fields=fields
            )
        if kwargs.get('pass_through'):
            return r

        if r.status == 200:
            if len(r.data) > 0:
                return self._decode(r.data)
            else:
                return r.status
        elif r.status == 401:
            self.refresh_the_login()
            return 401
        else:
            return -1
    """
    return py_code


@classmethod
def from_ModelBunch(cls, model_bunch, raw_data, metric, shap='tree',
    index_column=None, permutation_cv=None, na_fill=-999, **kwargs):
    """create an ExplainerBunch from a ModelBunch. A ModelBunch is a class
        containing a model, data transformer, target name and used columns, with
        both a .transform() and a .predict() method.

        Assumes model is tree based.

        :param model_bunch: ModelBunch
        :type model_bunch: [type]
        :param raw_data: raw input data that will be transformed
        :type raw_data: pd.DataFrame
        :param metric: metric with which to evaluate permutation importances
        :type metric: metric function or str
        :param index_column: column that will be used for idxs, defaults to None
        :type index_column: str, optional
        :param permutation_cv: [description], defaults to None
        :type permutation_cv: [type], optional
        :param na_fill: [description], defaults to -999
        :type na_fill: int, optional
        :return: ExplainerBunch instance
        """
    assert not index_column or index_column in raw_data.columns, f'{index_column} not in raw_data!'
    X, y = model_bunch.transform(raw_data)
    cats = raw_data.select_dtypes(include='object').columns.tolist()
    if index_column is not None:
        idxs = raw_data[index_column].astype(str).values.tolist()
    else:
        idxs = None
    return cls(model_bunch.model, X, y, metric=metric, shap=shap, cats=cats,
        idxs=idxs, permutation_cv=permutation_cv, na_fill=na_fill, **kwargs)


def bin2bytes(x):
    """Convert an array of bits (MSB first) into a string of characters."""
    bits = []
    bits.extend(x)
    bits.reverse()
    i = 0
    out = b''
    multi = 1
    ttl = 0
    for b in bits:
        i += 1
        ttl += b * multi
        multi *= 2
        if i == 8:
            i = 0
            out += bytes([ttl])
            multi = 1
            ttl = 0
    if multi > 1:
        out += bytes([ttl])
    out = bytearray(out)
    out.reverse()
    out = bytes(out)
    return out


def contract_size(data, value, _idx):
    """
    Multiply the profit in the trades report by the Contract Size.

    For example, the profit is multiplied by 10 contract size.
    """
    if isinstance(value, int):
        return data.assign(contracts=value)
    else:
        raise ValueError('Contract sizes must of Int type')


def parallel_total_density_range_tag_from_parallel_total_density_range(
    parallel_total_density_range):
    """Generate a parallel_total_density_range tag, to customize phase names based on the range of values in total     density that are allowed for the non-linear search in the parallel direction.

    This changes the phase name 'phase_name' as follows:

    parallel_total_density_range = None -> phase_name
    parallel_total_density_range = (0, 10) -> phase_name_parallel_total_density_range_(0,10)
    parallel_total_density_range = (20, 60) -> phase_name_parallel_total_density_range_(20,60)
    """
    if parallel_total_density_range == None:
        return ''
    else:
        x0 = str(parallel_total_density_range[0])
        x1 = str(parallel_total_density_range[1])
        return '_par_range_(' + x0 + ',' + x1 + ')'


def get_htdocs_dirs():
    """Return a list of directories with static resources (such as style
        sheets, images, etc.)

        Each item in the list must be a `(prefix, abspath)` tuple. The
        `prefix` part defines the path in the URL that requests to these
        resources are prefixed with.

        The `abspath` is the absolute path to the directory containing the
        resources on the local file system.
        """


def delete_application(applicationName=None):
    """
    Deletes an application.
    See also: AWS API Documentation

    :example: response = client.delete_application(
        applicationName='string'
    )

    :type applicationName: string
    :param applicationName: [REQUIRED]
            The name of an AWS CodeDeploy application associated with the applicable IAM user or AWS account.

    """
    pass


@staticmethod
def decompress(tensor, ctx):
    """Upcasts the tensor to the initialization dtype."""
    tensor_decompressed = tensor
    dtype = ctx
    if dtype.is_floating_point:
        tensor_decompressed = tensor.type(dtype)
    return tensor_decompressed


@classmethod
def step(Class, length, origin=1):
    """
        Create a discretization of the Heaviside step function.

        :param length: the length of the resulting vector
        :type length: a positive integer
        :param origin: the position of the origin
        :type origin: an integer
        :returns: a vector ``[0, 0, ..., 0, 1, 1, ..., 1]`` with exactly
            ``max(0, min(length, origin))`` zeros
        :rtype: a vector of the specified length
        :raises: :class:`AssertionError` if `length` is not positive

        .. seealso::
            :attr:`tensors.tensor.Tensor.shape`
        """
    raise NotImplementedError


def getterChain(*getters):
    """
    Create a getter chain, this means that the first getter will be invoked and the object returned will passed on as
    an object to the next getter so fort and so on. If one getter return None then the chain stops.

    @param getters: attributes[callable(object)]
        The getters to be invoked in a chain.
    """
    assert getters, 'At least a getter is required'
    if __debug__:
        for getter in getters:
            assert callable(getter), 'Invalid getter %s' % getter

    def getter(obj):
        for getter in getters:
            obj = getter(obj)
            if obj is None:
                break
        return obj
    return getter


def duplicates_removed(it, already_seen=()):
    """
    Returns a list with duplicates removed from the iterable `it`.

    Order is preserved.
    """
    lst = []
    seen = set()
    for i in it:
        if i in seen or i in already_seen:
            continue
        lst.append(i)
        seen.add(i)
    return lst


def _amplify(ui_mat, alpha=1.0):
    """Exponentially amplify values of similarity matrix"""
    if alpha == 1.0:
        return ui_mat
    for i, w in enumerate(ui_mat.data):
        ui_mat.data[i] = w ** alpha if w > 0 else -(-w) ** alpha
    return ui_mat


def format_ordinal(n):
    """
    Format an ordinal, like 1st, 2nd, 3rd...

    Not tested with large numbers of negative numbers!
    """
    if 10 <= n % 100 < 20:
        return str(n) + 'th'
    else:
        return str(n) + {(1): 'st', (2): 'nd', (3): 'rd'}.get(n % 10, 'th')


def file_name(fp, **kwargs):
    """
    Return The complete name of a file with the extension but without folder location
    """
    return fp.rpartition('/')[2]


def convertTimeToTimeString(time):
    """
    Convert a time (float) to string --- [hh:mm:ss.ssss]
    """
    hours = int(time // (60 * 60))
    if hours > 23 or hours < 0:
        return ''
    time -= hours * 60 * 60
    minutes = int(time // 60)
    time -= minutes * 60
    seconds = time
    timeStr = '[{:02d}:{:02d}:{:07.4f}]'.format(hours, minutes, seconds)
    return timeStr


def convert_suffix(value, suffixes=('d', 'h', 'm', 's'), ratios=(24, 60, 60
    ), delimiter=':'):
    """Converts a base value into a human readable format with the given suffixes and ratios.

    Parameters
    ----------
    value : int or float
        value to be converted
    suffixes : list of str
        suffixes for each subdivision (eg. ['days', 'hours', 'minutes', 'seconds'])
    ratios : list of int
        the relative period of each subdivision (eg. 24 hours in 1 day, 60 minutes in 1 hour,
        60 seconds in 1 minute -> [24, 60, 60])
    delimiter : str
        string to use between each subdivision

    Returns
    -------
    str
        returns string with the subdivision values and suffixes joined together

    Examples
    --------

    >>> convert_suffix(3661, suffixes=['d', 'h', 'm', 's'], ratios=[24, 60, 60], delimiter=':')
    '0d:1h:1m1.00s'

    """
    tValue = value
    outputValues = []
    for i in ratios[::-1]:
        outputValues.append(int(tValue % i))
        tValue = (tValue - tValue % i) // i
    outputValues.append(tValue)
    ret_string = delimiter.join(['{}{}'.format(int(i[0]), i[1]) for i in
        zip(outputValues[::-1][:-1], suffixes[:-1])])
    ret_string = ret_string + '{:.2f}{}'.format(outputValues[0], suffixes[-1])
    return ret_string


@classmethod
def get_real_child_model(cls, data):
    """Returns the real base class specified by the discriminator"""
    discriminator_value = data[cls.json_discriminator_key]
    return cls.discriminator_value_class_map.get(discriminator_value)


def hide_socket_toggle():
    """Toggle unused node socket display

    """
    pass


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

    The ".dev0" means dirty.

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


def change_weibo_header(uri, headers, body):
    """Since weibo is a rubbish server, it does not follow the standard,
    we need to change the authorization header for it."""
    auth = headers.get('Authorization')
    if auth:
        auth = auth.replace('Bearer', 'OAuth2')
        headers['Authorization'] = auth
    return uri, headers, body


def scale_units(out_unit, in_unit):
    """Deprecated function, moved to pysat.utils._core"""
    import warnings
    from pysat import utils
    warnings.warn(' '.join(['utils.computational_form is deprecated, use',
        'pysat.ssnl.computational_form instead']), DeprecationWarning,
        stacklevel=2)
    unit_scale = utils.scale_units(out_unit, in_unit)
    return unit_scale


def _distributeCells(numCellsPop):
    """ distribute cells across compute nodes using round-robin"""
    from .. import sim
    hostCells = {}
    for i in range(sim.nhosts):
        hostCells[i] = []
    for i in range(numCellsPop):
        hostCells[sim.nextHost].append(i)
        sim.nextHost += 1
        if sim.nextHost >= sim.nhosts:
            sim.nextHost = 0
    if sim.cfg.verbose:
        print(
            'Distributed population of %i cells on %s hosts: %s, next: %s' %
            (numCellsPop, sim.nhosts, hostCells, sim.nextHost))
    return hostCells


def txt2lon(lontxt):
    """txt2lat: input txt: N52'14'13.5 or N52"""
    try:
        lon = float(lontxt)
    except:
        txt = lontxt.upper().replace('E', '').replace('W', '-')
        neg = txt.count('-') > 0
        if txt.count("'") > 0 or txt.count('"') or txt.count(chr(176)) > 0:
            txt = txt.replace('"', "'").replace(chr(176), "'")
            degs = txt.split("'")
            div = 1
            lon = 0.0
            if neg:
                f = -1.0
            else:
                f = 1.0
            for xtxt in degs:
                if len(xtxt) > 0.0:
                    try:
                        lon = lon + f * abs(float(xtxt)) / float(div)
                    except:
                        print('txt2lon value error:', lontxt)
                        return 0.0
                div = div * 60
        else:
            try:
                neg = txt.count('-') > 0
                if neg:
                    f = -1.0
                else:
                    f = 1.0
                lon = f * abs(float(txt))
            except:
                print('txt2lon value error:', lontxt)
                return 0.0
    return lon


def select_more():
    """Select vertex directly linked to already selected ones

    """
    pass


@classmethod
def from_boto_dict(cls, listener) ->'ELBListener':
    """
        Instantiates a `ELBListener` object from the dictionary returned
        by boto3.
        """
    protocol = listener['Protocol']
    load_balancer_port = listener['LoadBalancerPort']
    instance_protocol = listener['InstanceProtocol']
    instance_port = listener['InstancePort']
    ssl_certificate_id = listener.get('SSLCertificateId')
    return cls(protocol, load_balancer_port, instance_protocol,
        instance_port, ssl_certificate_id)


def ellipse(h=250, v=250, x0=400, y0=400, size=(1024, 1360), theta=0):
    """
    returns array with 'size' with an ellipse centered at x0,y0 with diameters h(horizontal) and v(vertical) tilted at theta degrees. The h-horizontal and v-vertical is accurate only if theta is zero degrees.

    Parameters
    ----------
    h : float
        diameter of horizontal(zero degrees) axis of the ellipse
    v : float
        diameter of vertical(zero degrees) axis of the ellipse
    x0 : float
        x-coordinate of the center of the ellipse
    y0 : float
        y-coordinate of the center of the ellipse
    size : tuple
        size of the output image Default: 1024,1360
    theta : float
        angle of rotation in degrees. Default: 0

    Returns
    -------
    mask : numpy array
        numpy array with 'size'

    Examples
    --------
    the example of usage. To draw an ellise center at (1115,659) with horizontal diameter of 52 pixels and vertical diameter of 56 pixels.

    >>> e = draw_an_ellipsoid(h = 52, v = 56, x0 = 1115, y0 = 659
    """
    from astropy.modeling.functional_models import Ellipse2D
    from astropy.coordinates import Angle
    from numpy import mgrid
    Ellipse = Ellipse2D
    theta = Angle(theta, 'deg')
    e = Ellipse2D(amplitude=1, x_0=x0, y_0=y0, a=h / 2, b=v / 2, theta=
        theta.radian)
    y, x = mgrid[0:size[0], 0:size[1]]
    return e(x, y)


@staticmethod
def printable(data):
    """
        Replace unprintable characters with dots.

        @type  data: str
        @param data: Binary data.

        @rtype:  str
        @return: Printable text.
        """
    result = ''
    for c in data:
        if 32 < ord(c) < 128:
            result += c
        else:
            result += '.'
    return result


def types():
    """The portal_types tool
        """


def build_attributes(attributes, obj):
    """Build the Attribute list for the given object."""
    for attr in attributes:
        yield {'name': attr[0], 'object': getattr(attr[2], attr[0]),
            'defining_class': attr[2]}


def socket_recvall(socket, length, bufsize=4096):
    """A helper method to read of bytes from a socket to a maximum length"""
    data = b''
    while len(data) < length:
        data += socket.recv(bufsize)
    return data


def test_curses():
    """
    Check if the system ncurses linked with python has unicode capabilities.
    """
    import curses
    if hasattr(curses, 'unget_wch'):
        return True
    print(
        """ERROR: The current python executable is linked with a ncurses version that has no unicode capabilities.

This could mean that:
    - python was built on a system where readline is linked against libncurses and not libncursesw
    - python was built without ncursesw headers available

Please file a bug for your distribution or fix that on your system and then recompile python.
Poezio is currently unable to read your input or draw its interface properly, so it will now exit."""
        )
    return False


def get_attribute_checker(operator, attribute, value=''):
    """
    Takes an operator, attribute and optional value; returns a function that
    will return True for elements that match that combination.
    """
    return {'=': lambda el: el.get(attribute) == value, '~': lambda el:
        value in el.get(attribute, '').split(), '^': lambda el: el.get(
        attribute, '').startswith(value), '$': lambda el: el.get(attribute,
        '').endswith(value), '*': lambda el: value in el.get(attribute, ''),
        '|': lambda el: el.get(attribute, '') == value or el.get(attribute,
        '').startswith('%s-' % value)}.get(operator, lambda el: el.has_attr
        (attribute))


def time_to_dec_hour(parsedtime):
    """
    Calculate the decimal hour from a datetime object

    Parameters
    -----------
    parsedtime: datetime object

    Returns
    --------
    decimal hour: float
        time in decimal hours
    """
    return (parsedtime.hour + parsedtime.minute / 60.0 + parsedtime.second /
        60.0 ** 2)


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


def _boolean(value):
    """
    Map a boolean-like value to a Python bool instance.
    """
    try:
        return bool(int(value))
    except ValueError:
        pass
    value = value.lower()
    if value in ['true', 'yes']:
        return True
    elif value in ['false', 'no']:
        return False
    raise ValueError('Unrecognised boolean-like value %r' % value)


def __setitem__(key, value):
    """Set a new item in the mapping."""


def refresh_all():
    """Refresh the sequencer editor

    """
    pass


def split_first(s, delims):
    """
    Given a string and an iterable of delimiters, split on the first found
    delimiter. Return two split parts and the matched delimiter.

    If not found, then the first part is the full input string.

    Example::

        >>> split_first('foo/bar?baz', '?/=')
        ('foo', 'bar?baz', '/')
        >>> split_first('foo/bar?baz', '123')
        ('foo/bar?baz', '', None)

    Scales linearly with number of delims. Not ideal for large number of delims.
    """
    min_idx = None
    min_delim = None
    for d in delims:
        idx = s.find(d)
        if idx < 0:
            continue
        if min_idx is None or idx < min_idx:
            min_idx = idx
            min_delim = d
    if min_idx is None or min_idx < 0:
        return s, '', None
    return s[:min_idx], s[min_idx + 1:], min_delim


def navigate():
    """Interactively navigate around the scene (uses the mode (walk/fly) preference)

    """
    pass


def remove(content):
    """Remove a content from the order list, if needed.
        """


@classmethod
def at(cls, client, base_url=None):
    """
        Returns an object of type `cls` (must be a subclass of Client)
        at the same base URL as `client` or at the given `base_url`.
        Copies the session (and thus the authentication details) of `client`.
        """
    if base_url is None:
        base_url = client.base_url
    return cls(server=client.server, base_url=base_url, session=client.session)


def ismbox(path):
    """ Open path and check that its first line begins with "From ".
  """
    fp = None
    try:
        fp = open(path)
        from_ = fp.read(5)
    except IOError:
        if fp is not None:
            fp.close()
        return False
    else:
        fp.close()
        return from_ == 'From '


@classmethod
def get_event(cls, session):
    """
        not yet fully implemented
        """
    urls = cls._get_subscription_urls()
    for url in urls:
        if not session.has_events(url):
            continue
        event = session.get_event(url)
        for class_name in cls._get_apic_classes():
            if class_name in event['imdata'][0]:
                break
        if class_name == 'fabricLooseNode' or class_name == 'compHv':
            attributes = event['imdata'][0][class_name]['attributes']
            status = str(attributes['status'])
            dn = str(attributes['dn'])
            if status == 'created':
                name = str(attributes['name'])
            else:
                name = cls._get_name_from_dn(dn)
            obj = cls(name, parent=None)
            if url == '/api/class/fabricLooseNode.json?subscription=yes':
                obj._populate_physical_from_attributes(attributes)
            elif url == '/api/class/compHv.json?subscription=yes':
                obj._populate_virtual_from_attributes(attributes)
            obj._get_system_info(session)
            if status == 'deleted':
                obj.mark_as_deleted()
            return obj
        return


def isheadertag(tag):
    """Determine if tag is a header """
    return len(tag) == 2 and tag[0] == 'h' and tag[1].isdigit()


def getvector(wordvecs, term):
    """
    Retrieve the vector for a term
    Parameters are a pair of lists, wordvecs[0] - the terms, wordvecs[1] - the vectors
    """
    if term in wordvecs[0]:
        index = wordvecs[0].index(term)
        return wordvecs[1][index]
    else:
        return None


def eulerian_tour_undirected(graph):
    """Eulerian tour on an undirected graph

       :param graph: directed graph in listlist format, cannot be listdict
       :assumes: graph is eulerian
       :returns: eulerian cycle as a vertex list
       :complexity: `O(|V|+|E|)`
    """
    P = []
    Q = [0]
    R = []
    succ = [0] * len(graph)
    seen = [set() for _ in graph]
    while Q:
        node = Q.pop()
        P.append(node)
        while succ[node] < len(graph[node]):
            neighbor = graph[node][succ[node]]
            succ[node] += 1
            if neighbor not in seen[node]:
                seen[neighbor].add(node)
                R.append(neighbor)
                node = neighbor
        while R:
            Q.append(R.pop())
    return P


def _make_url(raw, sig, quick=True):
    """ Return usable url. Set quick=False to disable ratebypass override. """
    if quick and 'ratebypass=' not in raw:
        raw += '&ratebypass=yes'
    if 'signature=' not in raw:
        if sig is None:
            raise IOError('Error retrieving url')
        raw += '&signature=' + sig
    return raw


def getAllRowElements(rowname, elements):
    """
    Function purpose: help-function to get all row elements for a specific string

    Input: rowname, elements

    Output: array values
    """
    for idx, val in enumerate(elements[0]):
        if rowname in val:
            indexOf = idx
            values = []
            for x in elements:
                if x[indexOf] != rowname:
                    values.append(x[indexOf])
            return values


def storage_factory(klass, location, base_url):
    """
    This factory returns an instance of the storage class provided.
    args:

    * klass: must be inherit from ``django.core.files.storage.Storage``
    * location: is a string representing the PATH similar to MEDIA_ROOT
    * base_url: is a string representing the URL similar to MEDIA_URL
    """
    return klass(location=location, base_url=base_url)


@staticmethod
def info_request():
    """
        Get a refund info request instance

        :return: The request object that can be configured
        :rtype: paynlsdk2.api.refund.info.Request
        """
    from paynlsdk2.api.refund.info import Request
    return Request()


def format_span_id(span_id: int) ->str:
    """Format the span id according to b3 specification."""
    return format(span_id, '016x')


def passthrough(value):
    """Pass through value for no conversion."""
    return value


@classmethod
def create_with_dst_resource_provisioning(cls, cli, src_resource_id,
    dst_resource_config, max_time_out_of_sync, name=None, remote_system=
    None, src_spa_interface=None, src_spb_interface=None, dst_spa_interface
    =None, dst_spb_interface=None, dst_resource_element_configs=None,
    auto_initiate=None, hourly_snap_replication_policy=None,
    daily_snap_replication_policy=None, replicate_existing_snaps=None,
    no_async_snap_replication=None):
    """
        Create a replication session along with destination resource
        provisioning.

        :param cli: the rest cli.
        :param src_resource_id: id of the replication source, could be
            lun/fs/cg.
        :param dst_resource_config: `UnityResourceConfig` object. The user
            chosen config for destination resource provisioning. `pool_id` and
            `size` are required for creation.
        :param max_time_out_of_sync: maximum time to wait before syncing the
            source and destination. Value `-1` means the automatic sync is not
            performed. `0` means it is a sync replication.
        :param name: name of the replication.
        :param remote_system: `UnityRemoteSystem` object. The remote system to
            which the replication is being configured. When not specified, it
            defaults to local system.
        :param src_spa_interface: `UnityRemoteInterface` object. The
            replication interface for source SPA.
        :param src_spb_interface: `UnityRemoteInterface` object. The
            replication interface for source SPB.
        :param dst_spa_interface: `UnityRemoteInterface` object. The
            replication interface for destination SPA.
        :param dst_spb_interface: `UnityRemoteInterface` object. The
            replication interface for destination SPB.
        :param dst_resource_element_configs: List of `UnityResourceConfig`
            objects. The user chose config for each of the member element of
            the destination resource.
        :param auto_initiate: indicates whether to perform the first
            replication sync automatically.
            True - perform the first replication sync automatically.
            False - perform the first replication sync manually.
        :param hourly_snap_replication_policy: `UnitySnapReplicationPolicy`
            object. The policy for replicating hourly scheduled snaps of the
            source resource.
        :param daily_snap_replication_policy: `UnitySnapReplicationPolicy`
            object. The policy for replicating daily scheduled snaps of the
            source resource.
        :param replicate_existing_snaps: indicates whether or not to replicate
            snapshots already existing on the resource.
        :param no_async_snap_replication: whether or not snap replication is
            enabled in asynchronous replication session. When enabled, snap
            replication is controlled by snap replication policy setting or
            user action.
        :return: the newly created replication session.
        """
    req_body = cli.make_body(srcResourceId=src_resource_id,
        dstResourceConfig=dst_resource_config, maxTimeOutOfSync=
        max_time_out_of_sync, name=name, remoteSystem=remote_system,
        srcSPAInterface=src_spa_interface, srcSPBInterface=
        src_spb_interface, dstSPAInterface=dst_spa_interface,
        dstSPBInterface=dst_spb_interface, dstResourceElementConfigs=
        dst_resource_element_configs, autoInitiate=auto_initiate,
        hourlySnapReplicationPolicy=hourly_snap_replication_policy,
        dailySnapReplicationPolicy=daily_snap_replication_policy,
        replicateExistingSnaps=replicate_existing_snaps,
        noAsyncSnapReplication=no_async_snap_replication)
    resp = cli.type_action(cls().resource_class,
        'createReplicationSessionWDestResProvisioning', **req_body)
    resp.raise_if_err()
    session_resp = resp.first_content['id']
    return cls.get(cli, _id=session_resp['id'])


@classmethod
def map_create_multipart_upload_params(cls, request_params, cli_params):
    """Map CLI params to CreateMultipartUpload request params"""
    cls._set_general_object_params(request_params, cli_params)
    cls._set_sse_request_params(request_params, cli_params)
    cls._set_sse_c_request_params(request_params, cli_params)
    cls._set_metadata_params(request_params, cli_params)
    cls._set_request_payer_param(request_params, cli_params)


def finding_ori(rrnas_in, in_seq_len):
    """
    Finds the positions for Ori based on rRNAs
    Input:
    :param rrnas_in:    List of rRNA genes from RNAmmer
    :param in_seq_len:  Length of the input FASTA sequence
    :param linear:      Specifies if the chromosome is linear
    :return: Positions for Ori based on rRNAs
    """
    """List for storing the interval coordinates"""
    shift = list()
    for i in range(len(rrnas_in)):
        if i == len(rrnas_in) - 1:
            if rrnas_in[i][2] != rrnas_in[0][2]:
                shift.append(i)
        elif rrnas_in[i][2] != rrnas_in[i + 1][2]:
            shift.append(i)
    if len(shift) != 2:
        return [0, 0]
    elif len(shift) == 2:
        if rrnas_in[shift[0]][2] == -1:
            ori_start = rrnas_in[shift[0]][1]
            ori_end = rrnas_in[shift[0] + 1][0]
            return [ori_start, ori_end]
        elif rrnas_in[shift[1]][2] == -1:
            if shift[1] == len(rrnas_in) - 1:
                ori_start = rrnas_in[shift[1]][1]
                ori_end = rrnas_in[0][0]
                return [ori_start, ori_end]
            else:
                ori_start = rrnas_in[shift[1]][1]
                ori_end = rrnas_in[shift[1] + 1][0]
                return [ori_start, ori_end]


def find_first_index(l, x):
    """Returns the first index of element x within the list l."""
    for idx in range(len(l)):
        if l[idx] == x:
            return idx
    raise ValueError("'{}' is not in list".format(x))


@classmethod
def from_files(cls, files, **kwargs):
    """Construct a config parser from a set of files.

        Args:
            files (list): One or more files that options should be read from in
                the order they should be loaded.
            **kwargs: Additional keyword arguments are passed to the class
                constructor.

        Returns:
           YggConfigParser: Config parser with information loaded from the
               provided files.

        """
    out = cls(files=files, **kwargs)
    out.reload()
    return out


def truncate(message: str, max_length: int=128, split_ratio: float=0.8) ->str:
    """ Truncates the message if it is longer than max_length. It will be split at the
    'split_ratio' point, where the remaining last half is added on. """
    if max_length == 0 or len(message) <= max_length:
        return message
    split_index_start = int(max_length * split_ratio)
    split_index_end = max_length - split_index_start
    message_segments = [message[:split_index_start], message[-split_index_end:]
        ]
    return ' ... '.join(message_segments)


def get_client_ip_address(request):
    """Returns the IP address of the host which sent the
    request initally.
    """
    ips = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get(
        'REMOTE_ADDR'))
    if ips is None:
        return ''
    elif not hasattr(ips, 'split'):
        return ips
    else:
        return ips.split(',')[0].strip()


@staticmethod
def _get_parent_dn(dn):
    """
        Gets the dn of the parent object
        Meant to be overridden by inheriting classes.
        Raises exception if not overridden.

        :returns: string containing dn
        """
    return dn.split('/lb-')[0]


def table2csv(tabledata, fq_outfilename, header, encoding, exporter):
    """Write table to CSV."""
    delimiter = ';'
    quotechar = '"'
    exporter(tabledata, fq_outfilename, header, encoding, delimiter, quotechar)


def squeeze(input, dim):
    """Remove the given dimension of size 1.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    dim : int
        The dimension to be squeezed.

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


def __singleton_key__(cls, *args, **kwargs):
    """Convert the construction arguments into a normalized representation that
        uniquely identifies this singleton.
        """
    raise NotImplementedError


def psi_Na_CO3_Cl_HMW84(T, P):
    """c-a-a': sodium carbonate chloride [HMW84]."""
    psi = 0.0085
    valid = T == 298.15
    return psi, valid


def after_pack(oid_int, tid_int):
    """
        Called after an object state has been removed by packing.

        Removes the corresponding blob file.
        """


def get_full_controls(parser):
    """
    Returns a comprehensive listing of of all game command words
    """
    descs = []
    ret = ''
    for cmd in parser.iterate():
        text = cmd.help_text()
        if text and text not in descs:
            ret += '\n' + text
            descs.append(text)
    return ret


def AddPlotterPoints(*args, **kwargs):
    """ Stub Anduin function."""
    print('AddPlotterPoints', args, kwargs)


def libsbol_rule_1(sbol_obj, arg):
    """Print a test message"""
    print('Testing internal validation rules')


def dummy_ngettext(singular, plural, n):
    """
    Mimic ``ngettext()`` function. This is a passthrough function with the
    same signature as ``ngettext()``. It can be used to simulate translation
    for applications that are untranslated, without the overhead of calling the
    real ``ngettext()``.

    This function returns the verbatim singular message if ``n`` is 1,
    otherwise the verbatim plural message.

    :param singular:    singular message string
    :param plural:      plural message string
    :param n:           count
    :returns:           unmodified singular or plural message
    """
    if n == 1:
        return singular
    return plural


@classmethod
def value_match(cls, pattern, value):
    """Determine whether the value matches the pattern. Both
        arguments are strings.
        """
    raise NotImplementedError()


def list_targets_for_policy(PolicyId=None, NextToken=None, MaxResults=None):
    """
    Lists all the roots, OUs, and accounts to which the specified policy is attached.
    This operation can be called only from the organization's master account.
    See also: AWS API Documentation

    :example: response = client.list_targets_for_policy(
        PolicyId='string',
        NextToken='string',
        MaxResults=123
    )

    :type PolicyId: string
    :param PolicyId: [REQUIRED]
            The unique identifier (ID) of the policy for which you want to know its attachments.
            The regex pattern for a policy ID string requires 'p-' followed by from 8 to 128 lower-case letters or digits.

    :type NextToken: string
    :param NextToken: Use this parameter if you receive a NextToken response in a previous request that indicates that there is more output available. Set it to the value of the previous call's NextToken response to indicate where the output should continue from.

    :type MaxResults: integer
    :param MaxResults: (Optional) Use this to limit the number of results you want included in the response. If you do not include this parameter, it defaults to a value that is specific to the operation. If additional items exist beyond the maximum you specify, the NextToken response element is present and has a value (is not null). Include that value as the NextToken request parameter in the next call to the operation to get the next part of the results. Note that Organizations might return fewer results than the maximum even when there are more results available. You should check NextToken after every operation to ensure that you receive all of the results.

    :rtype: dict
    :return: {
        'Targets': [
            {
                'TargetId': 'string',
                'Arn': 'string',
                'Name': 'string',
                'Type': 'ACCOUNT'|'ORGANIZATIONAL_UNIT'|'ROOT'
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    Root: a string that begins with "r-" followed by from 4 to 32 lower-case letters or digits.
    Account: a string that consists of exactly 12 digits.
    Organizational unit (OU): a string that begins with "ou-" followed by from 4 to 32 lower-case letters or digits (the ID of the root that the OU is in) followed by a second "-" dash and from 8 to 32 additional lower-case letters or digits.

    """
    pass


def _get_ram_usage():
    """Get memory info."""
    with open('/proc/meminfo') as fp:
        m = fp.read().split()
        idx1 = m.index('MemTotal:')
        idx2 = m.index('MemFree:')
        idx3 = m.index('Buffers:')
        idx4 = m.index('Cached:')
        total = int(m[idx1 + 1])
        avail = int(m[idx2 + 1]) + int(m[idx3 + 1]) + int(m[idx4 + 1])
    return {'total': total * 1024, 'used': (total - avail) * 1024}


@staticmethod
def get_connection_type():
    """
        This is needed so the build system knows what
        connection type this connection is considered.
        return::str The socket type of this connection.
        """
    return 'replyer'


@classmethod
def update_current_department_user_by_data(cls, user_code_list,
    current_org_code, department_id, operation):
    """
        将当前用户添加进此部门或移出此部门
        :return:
        """
    if operation == 'remove':
        cls.objects(user_code__in=user_code_list, org_role__org_code=
            current_org_code).update(__raw__={'$pull': {
            'org_role.$.department_id': department_id}})
    else:
        cls.objects(user_code__in=user_code_list, org_role__org_code=
            current_org_code).update(__raw__={'$push': {
            'org_role.$.department_id': department_id}})


@staticmethod
def get_max(features, max_key=lambda x: x, **_kwargs):
    """
        Returns native max of given sequence of features.

        :param collections.Iterable[Feature] features:
            sequence of features
        :param lambda max_key:
        :param _kwargs:
        :return:
        """
    m = max(features, key=max_key)
    return m


def __new__(cls, *args, **kwargs):
    """Capture creation args when instantiating"""
    from dask.base import tokenize
    o = object.__new__(cls)
    o._captured_init_args = args
    o._captured_init_kwargs = kwargs
    o.__dict__['_tok'] = tokenize(o.__getstate__())
    return o


def intr(n):
    """Returns a correctly rounded integer"""
    return int(round(n))


def makeTidyAtomLabel(name, element):
    """
    Returns a 'tidier' atom label for printing the new pdbfile
    """
    if len(name) > 4:
        label = name[0:4]
    elif len(name) == 4:
        label = name
    elif len(element) == 1:
        label = ' %-3s' % name
    else:
        label = '%-4s' % name
    return label


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_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def deleteTag(tag):
    """Delete a new tag from the content"""


@staticmethod
def _update_dist(distance_matrix, global_linkage, local_linkage_tr,
    global_elements, criterion=None):
    """
        Updates the general distance matrix to take the new clusters into account

        Replaces the elements added to the new clusters with these clusters as elements.
        Requires the recalculation of the distance matrix to determine the distance from
        new clusters to other elements.

        A criterion function may be given for calculation of the new distances from a new cluster to other
        elements based on the distances of elements included in a cluster. The default method is the weighted
        average of distances based on the number of atoms in each of the two elements.

        :param distance_matrix: (pd.dataframe) Previous distance matrix
        :param global_linkage: (np.array) Global linkage object that includes new clusters
        :param local_linkage_tr: (np.array) Local linkage object transformed (global names of elements and atoms count)
        :param global_elements: (list) Global list with names of all elements
        :param criterion: (function) Function to apply to a dataframe of distances to adjust them
        :return: (np.array) Updated distance matrix
        """
    num_atoms = len(global_elements) - global_linkage.shape[0]
    new_items = global_elements[-local_linkage_tr.shape[0]:]
    for i in range(local_linkage_tr.shape[0]):
        elem_1, elem_2 = global_elements[int(local_linkage_tr[i, 0])
            ], global_elements[int(local_linkage_tr[i, 1])]
        if criterion is None:
            if local_linkage_tr[i, 0] < num_atoms:
                elem_1_weight = 1
            else:
                elem_1_weight = global_linkage[int(local_linkage_tr[i, 0]) -
                    num_atoms, 3]
            if local_linkage_tr[i, 1] < num_atoms:
                elem_2_weight = 1
            else:
                elem_2_weight = global_linkage[int(local_linkage_tr[i, 1]) -
                    num_atoms, 3]
            dist_vector = (distance_matrix[elem_1] * elem_1_weight +
                distance_matrix[elem_2] * elem_2_weight) / (elem_1_weight +
                elem_2_weight)
        else:
            dist_vector = criterion(distance_matrix[[elem_1, elem_2]], axis=1)
        distance_matrix[new_items[i]] = dist_vector
        distance_matrix.loc[new_items[i]] = dist_vector
        distance_matrix.loc[new_items[i], new_items[i]] = 0
        distance_matrix = distance_matrix.drop([elem_1, elem_2], axis=0)
        distance_matrix = distance_matrix.drop([elem_1, elem_2], axis=1)
    return distance_matrix


def Preview(request):
    """
    A preview is called by ``Field types`` management module.

    :param request: Pyramid request object
    :rtype: Html snippet
    """


def median_from_dict(total, count):
    """
    total is the number of requests made
    count is a dict {response_time: count}
    """
    pos = (total - 1) / 2
    for k in sorted(count.keys()):
        if pos < count[k]:
            return k
        pos -= count[k]


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


def GrossPremTable():
    """Gross premium table"""
    return None


@classmethod
def copy(cls, arr):
    """Creates a new SharedNDArray that is a copy of the given ndarray.

        Args:
            arr: The ndarray to copy.

        Returns:
            A new SharedNDArray object with the given ndarray's shape and data type and a copy of
            its data.

        Raises:
            SharedNDArrayError: if an error occurs.
        """
    new_shm = cls.zeros_like(arr)
    new_shm.array[:] = arr
    return new_shm


@classmethod
def fromkeys(cls, iterable, value=None):
    """ T.fromkeys(S[,v]) -> New tree with keys from S and values equal to v.

        v defaults to None.
        """
    tree = cls()
    for key in iterable:
        tree.insert(key, value)
    return tree


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 get_legal_form(legal_form):
    """
    http://wwwinfo.mfcr.cz/ares/aresPrFor.html.cz

    :type legal_form: dict
    :rtype: unicode
    """
    if legal_form:
        return legal_form.get('D:KPF', None)
    return None


def airspeed_voltage(VFR_HUD, ratio=None):
    """back-calculate the voltage the airspeed sensor must have seen"""
    from . import mavutil
    mav = mavutil.mavfile_global
    if ratio is None:
        ratio = 1.9936
    if 'ARSPD_RATIO' in mav.params:
        used_ratio = mav.params['ARSPD_RATIO']
    else:
        used_ratio = ratio
    if 'ARSPD_OFFSET' in mav.params:
        offset = mav.params['ARSPD_OFFSET']
    else:
        return -1
    airspeed_pressure = pow(VFR_HUD.airspeed, 2) / used_ratio
    raw = airspeed_pressure + offset
    SCALING_OLD_CALIBRATION = 204.8
    voltage = 5.0 * raw / 4096
    return voltage


def pk_list_to_dict(pk_list):
    """ convert list of multi pk to dict

    ['id', 1, 'id2', 22, 'foo', 'bar'] -> {'foo': 'bar', 'id2': 22, 'id': 1}
    """
    if pk_list and len(pk_list) % 2 == 0:
        return dict(zip(pk_list[::2], pk_list[1::2]))
    return None


def _load_pretrained_weights(new_layer, previous_layer):
    """Load pretrained weights based on number of input channels"""
    n_in = getattr(new_layer, 'in_channels')
    if n_in == 1:
        new_layer.weight.data = previous_layer.weight.data.sum(dim=1,
            keepdim=True)
    elif n_in == 2:
        new_layer.weight.data = previous_layer.weight.data[:, :2] * 1.5
    else:
        new_layer.weight.data[:, :3] = previous_layer.weight.data
        new_layer.weight.data[:, 3:].zero_()


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

        :returns: this backend does not support items resuming
        """
    return False


def interpolate(xa, ya, queryPoints):
    """
    A cubic spline interpolation on a given set of points (x,y)
    Recalculates everything on every call which is far from efficient but does the job for now
    should eventually be replaced by an external helper class
    """
    n = len(xa)
    u, y2 = [0] * n, [0] * n
    for i in range(1, n - 1):
        wx = xa[i + 1] - xa[i - 1]
        sig = (xa[i] - xa[i - 1]) / wx
        p = sig * y2[i - 1] + 2.0
        y2[i] = (sig - 1.0) / p
        ddydx = (ya[i + 1] - ya[i]) / (xa[i + 1] - xa[i]) - (ya[i] - ya[i - 1]
            ) / (xa[i] - xa[i - 1])
        u[i] = (6.0 * ddydx / wx - sig * u[i - 1]) / p
    y2[n - 1] = 0
    for i in range(n - 2, -1, -1):
        y2[i] = y2[i] * y2[i + 1] + u[i]
    results = [0] * n
    for i in range(len(queryPoints)):
        klo = 0
        khi = n - 1
        while khi - klo > 1:
            k = khi + klo >> 1
            if xa[k] > queryPoints[i]:
                khi = k
            else:
                klo = k
        h = xa[khi] - xa[klo]
        a = (xa[khi] - queryPoints[i]) / h
        b = (queryPoints[i] - xa[klo]) / h
        results[i] = a * ya[klo] + b * ya[khi] + ((a * a * a - a) * y2[klo] +
            (b * b * b - b) * y2[khi]) * (h * h) / 6.0
    return results


@classmethod
def normalized(cls, other):
    """Creates a new normalized vector"""
    return cls(other.x / other.mag, other.y / other.mag, other.z / other.mag)


def is_file_supported(suffix: str) ->bool:
    """
    Check a path to be supported by safitty (only YAML or JSON)

    Args:
        suffix (str): path extension

    Returns:
        bool: File is YAML or JSON
    """
    return suffix in ['.json', '.yml', '.yaml']


def _f2s(v):
    """convert float to string without scientific notation"""
    s, sep, e = str(v).partition('e')
    a, sep, b = s.partition('.')
    pos = len(a) + int(e or 0)
    s = (a + b).rstrip('0')
    if pos >= len(s):
        return s.ljust(pos, '0')
    elif pos <= 0:
        return '0.' + '0' * -pos + s
    else:
        return s[:pos] + '.' + s[pos:]


def reset_visits(nodes):
    """ Resets the visitor counter in a set of nodes
    :param nodes: GraphNodes
    :return:
    """
    for node in nodes:
        node.visits = 0


def _remove_lines(part, title=True, empty=False, sep=False):
    """
    remove unneeded lines of part string

    Args:
        part (str): part in report file
        title (bool): if title should be removed
        empty (bool): if empty lines should be removed
        sep (bool):  if separator should be removed

    Returns:
        str: converted part
    """
    lines = part.split('\n')
    remove_lines = list()
    for no, line in enumerate(lines):
        if title:
            if no == 0 or no == len(lines) - 1:
                continue
            if '***' in lines[no + 1] and '***' in lines[no - 1]:
                remove_lines.append(no - 1)
                remove_lines.append(no)
                remove_lines.append(no + 1)
        if empty:
            if len(line.strip()) == 0:
                remove_lines.append(no)
        if sep:
            if len(line.replace('-', '').strip()) == 0:
                remove_lines.append(no)
    new_lines = lines
    for r in sorted(remove_lines, reverse=True):
        new_lines.pop(r)
    return '\n'.join(new_lines)


@staticmethod
def get_legend_handler(legend_handler_map, orig_handle):
    """
        Return a legend handler from *legend_handler_map* that
        corresponds to *orig_handler*.

        *legend_handler_map* should be a dictionary object (that is
        returned by the get_legend_handler_map method).

        It first checks if the *orig_handle* itself is a key in the
        *legend_handler_map* and return the associated value.
        Otherwise, it checks for each of the classes in its
        method-resolution-order. If no matching key is found, it
        returns ``None``.
        """
    try:
        return legend_handler_map[orig_handle]
    except (TypeError, KeyError):
        pass
    for handle_type in type(orig_handle).mro():
        try:
            return legend_handler_map[handle_type]
        except KeyError:
            pass
    return None


def theta_Cl_HPO4_HFM89(T, P):
    """a-a': chloride hydrogen-phosphate [HFM89]."""
    theta = -0.105
    valid = T == 298.15
    return theta, valid


def _is_metadata_of(group: 'Node', parent_group: 'Node') ->bool:
    """Check if a given group is a metadata group for a given parent_group."""
    if group._v_depth <= parent_group._v_depth:
        return False
    current = group
    while current._v_depth > 1:
        parent = current._v_parent
        if parent == parent_group and current._v_name == 'meta':
            return True
        current = current._v_parent
    return False


@classmethod
def dark_orange(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0xa84300``."""
    return cls(11027200)


def asyncreq(proxy, handler, *args):
    """Performs an asynchronous request on the given proxy object.
    Not intended to be invoked directly.

    :param proxy: the proxy on which to issue the request
    :param handler: the request handler (one of the ``HANDLE_XXX`` members of
                    ``rpyc.protocol.consts``)
    :param args: arguments to the handler

    :returns: an :class:`~rpyc.core.async_.AsyncResult` representing
              the operation
    """
    conn = object.__getattribute__(proxy, '____conn__')
    return conn.async_request(handler, proxy, *args)


def irshift(a, b):
    """Same as a >>= b."""
    a >>= b
    return a


def collection_delete(hierarchy: bool=False):
    """Delete selected collections

    :param hierarchy: Hierarchy, Delete child objects and collections
    :type hierarchy: bool
    """
    pass


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

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

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


def is_transform(obj):
    """Verfy if a object is a ``transform-like`` object.

    Args:
        obj: Object to be determined.

    Returns:
        bool: True for ``transform-like`` object, false otherwise.

    """
    return hasattr(obj, '__call__')


@conf
def scc_common_flags(conf):
    """
	Flags required for executing the sun C compiler
	"""
    v = conf.env
    v.CC_SRC_F = []
    v.CC_TGT_F = ['-c', '-o', '']
    if not v.LINK_CC:
        v.LINK_CC = v.CC
    v.CCLNK_SRC_F = ''
    v.CCLNK_TGT_F = ['-o', '']
    v.CPPPATH_ST = '-I%s'
    v.DEFINES_ST = '-D%s'
    v.LIB_ST = '-l%s'
    v.LIBPATH_ST = '-L%s'
    v.STLIB_ST = '-l%s'
    v.STLIBPATH_ST = '-L%s'
    v.SONAME_ST = '-Wl,-h,%s'
    v.SHLIB_MARKER = '-Bdynamic'
    v.STLIB_MARKER = '-Bstatic'
    v.cprogram_PATTERN = '%s'
    v.CFLAGS_cshlib = ['-xcode=pic32', '-DPIC']
    v.LINKFLAGS_cshlib = ['-G']
    v.cshlib_PATTERN = 'lib%s.so'
    v.LINKFLAGS_cstlib = ['-Bstatic']
    v.cstlib_PATTERN = 'lib%s.a'


@staticmethod
def _linear_transformation(data, multiplier, offset):
    """
        Given data, a multiplier and the offset, return the
        data transformed with those values by:

        data' = data * multiplier + offset

        Parameter:

            data (array-like):
               Array of numerical values, either int or float
            multiplier (float, int or None):
               Number to multiply the data with. None is taken
               as an implicit 1.0
            offset (float, int or None):
               Number of offset the values with. None is taken
               as an implicit 0.0

        Returns:

            scaled_data (array-like):
               Result scaled.
        """
    if multiplier is None:
        multiplier = 1
    if offset is None:
        offset = 0
    return data * multiplier + offset


def get_query_criterions_from_request(request):
    """
    Turn request parameters into a dict where keys are attributes to filter and
    values are values to filter.
    """
    criterions = {}
    for key, value in request.args.items():
        if key not in ['page']:
            criterions[key] = value
    return criterions


@staticmethod
def decode(data):
    """
        Defines the underlying format used during traces or services encoding.
        This method must be implemented and should only be used by the internal functions.
        """
    raise NotImplementedError


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


def write_to_file(name: str, data: str, mode: str='w') ->None:
    """Writes data to filename."""
    with open(name, mode) as file:
        file.write(data)


def _is_pyspark_step_type(step_type):
    """Does the given step type indicate that it uses Spark and Python?"""
    return step_type in ('spark', 'spark_script')


def find_lca(tree):
    """
    Given a tree produced by 'find_tree', find the first node with multiple
    children, OR the only leaf in the tree.  Return (lineage_tup, reason),
    where 'reason' is the number of children of the returned node, i.e.e
    0 if it's a leaf and > 1 if it's an internal node.
    """
    node = tree
    lineage = []
    while 1:
        if len(node) == 1:
            lineage_tup = next(iter(node.keys()))
            lineage.append(lineage_tup)
            node = node[lineage_tup]
        elif len(node) == 0:
            return tuple(lineage), 0
        else:
            return tuple(lineage), len(node)


def loginfo(message):
    """
    Prefixes '[INFO]' to the message.

    :param message str: message to log.
    """
    print('[INFO ] ' + message)


def _windows_covers(windows, rrtype):
    """
    Check to see if an NSECx windows list covers a type.

    :param list windows: An NSEC or NSEC3 windows list.
    :param int rrtype: The dns.rdatatype to test.
    :return: True if the windows covers the type; False if not.
    """
    window = rrtype // 256
    for win in windows:
        if win[0] == window:
            bitmap = win[1]
            offset = rrtype % 256
            byte = offset // 8
            if bitmap and len(bitmap) >= byte + 1:
                bit = offset % 8
                return bool(bitmap[byte] & 128 >> bit)
    return False


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

        :param TeamMergeRequestReminderShownToSecondaryTeamType val:
        :rtype: EventType
        """
    return cls('team_merge_request_reminder_shown_to_secondary_team', val)


@staticmethod
def _get_name_and_temp(device_record):
    """
            get device name (without /dev part, to save space on bar)
            and temperature (in °C) as tuple
        """
    device_name = device_record[0].split('/')[-1]
    device_temp = device_record[2]
    return device_name, device_temp


@classmethod
def get_games(cls):
    """Get games for which this block is supported."""
    return list(cls._games.keys())


def as_variable_key(key):
    """Returns ``key`` as a tuple of the form
    ``('process_name', 'var_name')``.

    If ``key`` is given as a string, then process name and variable
    name must be separated unambiguously by '__' (double underscore)
    and must not be empty.

    """
    key_tuple = None
    if isinstance(key, tuple) and len(key) == 2:
        key_tuple = key
    elif isinstance(key, str):
        key_split = key.split('__')
        if len(key_split) == 2:
            p_name, var_name = key_split
            if p_name and var_name:
                key_tuple = p_name, var_name
    if key_tuple is None:
        raise ValueError(f'{key!r} is not a valid input variable key')
    return key_tuple


def _normalize(data):
    """
	Helper function to normalize data between [0.0, 100.0].
	This is based on largest value found. If the values for individual terms
	are not summed across terms, then this is the largest value among all terms
	as well.
	"""
    maxVal = 0.0
    for i, line in enumerate(data):
        for j in range(1, len(line)):
            if line[j] > maxVal:
                maxVal = line[j]
    trend = []
    for line in data:
        newLine = []
        newLine.append(line[0])
        for j in range(1, len(line)):
            norm = line[j] * 100
            norm /= maxVal
            norm = round(norm, 3)
            newLine.append(norm)
        trend.append(newLine)
    return trend


def constant_time_compare(val1: bytes, val2: bytes):
    """ Returns `True` if the two strings are equal, `False` otherwise.

    The time taken is independent of the number of characters that match.

    (Borrowed from `Django <http://djangoproject.org/>`_)
    """
    if len(val1) != len(val2):
        return False
    result = 0
    for x, y in zip(val1, val2):
        result |= x ^ y
    return result == 0


def create_queue(QueueName=None, Attributes=None):
    """
    Creates a new standard or FIFO queue. You can pass one or more attributes in the request. Keep the following caveats in mind:
    To successfully create a new queue, you must provide a queue name that adheres to the limits related to queues and is unique within the scope of your queues.
    To get the queue URL, use the ``  GetQueueUrl `` action. ``  GetQueueUrl `` requires only the QueueName parameter. be aware of existing queue names:
    See also: AWS API Documentation

    Examples
    The following operation creates an SQS queue named MyQueue.
    Expected Output:

    :example: response = client.create_queue(
        QueueName='string',
        Attributes={
            'string': 'string'
        }
    )

    :type QueueName: string
    :param QueueName: [REQUIRED]
            The name of the new queue. The following limits apply to this name:
            A queue name can have up to 80 characters.
            Valid values: alphanumeric characters, hyphens (- ), and underscores (_ ).
            A FIFO queue name must end with the .fifo suffix.
            Queue names are case-sensitive.

    :type Attributes: dict
    :param Attributes: A map of attributes with their corresponding values.
            The following lists the names, descriptions, and values of the special request parameters that the CreateQueue action uses:
            DelaySeconds - The length of time, in seconds, for which the delivery of all messages in the queue is delayed. Valid values: An integer from 0 to 900 seconds (15 minutes). The default is 0 (zero).
            MaximumMessageSize - The limit of how many bytes a message can contain before Amazon SQS rejects it. Valid values: An integer from 1,024 bytes (1 KiB) to 262,144 bytes (256 KiB). The default is 262,144 (256 KiB).
            MessageRetentionPeriod - The length of time, in seconds, for which Amazon SQS retains a message. Valid values: An integer from 60 seconds (1 minute) to 1,209,600 seconds (14 days). The default is 345,600 (4 days).
            Policy - The queue's policy. A valid AWS policy. For more information about policy structure, see Overview of AWS IAM Policies in the Amazon IAM User Guide .
            ReceiveMessageWaitTimeSeconds - The length of time, in seconds, for which a `` ReceiveMessage `` action waits for a message to arrive. Valid values: An integer from 0 to 20 (seconds). The default is 0 (zero).
            RedrivePolicy - The parameters for the dead letter queue functionality of the source queue. For more information about the redrive policy and dead letter queues, see Using Amazon SQS Dead Letter Queues in the Amazon SQS Developer Guide .
            Note
            The dead letter queue of a FIFO queue must also be a FIFO queue. Similarly, the dead letter queue of a standard queue must also be a standard queue.
            VisibilityTimeout - The visibility timeout for the queue. Valid values: An integer from 0 to 43,200 (12 hours). The default is 30. For more information about the visibility timeout, see Visibility Timeout in the Amazon SQS Developer Guide .
            The following attributes apply only to server-side-encryption :
            KmsMasterKeyId - The ID of an AWS-managed customer master key (CMK) for Amazon SQS or a custom CMK. For more information, see Key Terms . While the alias of the AWS-managed CMK for Amazon SQS is always alias/aws/sqs , the alias of a custom CMK can, for example, be alias/aws/sqs . For more examples, see KeyId in the AWS Key Management Service API Reference .
            KmsDataKeyReusePeriodSeconds - The length of time, in seconds, for which Amazon SQS can reuse a data key to encrypt or decrypt messages before calling AWS KMS again. An integer representing seconds, between 60 seconds (1 minute) and 86,400 seconds (24 hours). The default is 300 (5 minutes). A shorter time period provides better security but results in more calls to KMS which incur charges after Free Tier. For more information, see How Does the Data Key Reuse Period Work? .
            The following attributes apply only to FIFO (first-in-first-out) queues :
            FifoQueue - Designates a queue as FIFO. Valid values: true , false . You can provide this attribute only during queue creation. You can't change it for an existing queue. When you set this attribute, you must also provide the MessageGroupId for your messages explicitly. For more information, see FIFO Queue Logic in the Amazon SQS Developer Guide .
            ContentBasedDeduplication - Enables content-based deduplication. Valid values: true , false . For more information, see Exactly-Once Processing in the Amazon SQS Developer Guide .
            Every message must have a unique MessageDeduplicationId ,
            You may provide a MessageDeduplicationId explicitly.
            If you aren't able to provide a MessageDeduplicationId and you enable ContentBasedDeduplication for your queue, Amazon SQS uses a SHA-256 hash to generate the MessageDeduplicationId using the body of the message (but not the attributes of the message).
            If you don't provide a MessageDeduplicationId and the queue doesn't have ContentBasedDeduplication set, the action fails with an error.
            If the queue has ContentBasedDeduplication set, your MessageDeduplicationId overrides the generated one.
            When ContentBasedDeduplication is in effect, messages with identical content sent within the deduplication interval are treated as duplicates and only one copy of the message is delivered.
            If you send one message with ContentBasedDeduplication enabled and then another message with a MessageDeduplicationId that is the same as the one generated for the first MessageDeduplicationId , the two messages are treated as duplicates and only one copy of the message is delivered.
            Any other valid special request parameters (such as the following) are ignored:
            ApproximateNumberOfMessages
            ApproximateNumberOfMessagesDelayed
            ApproximateNumberOfMessagesNotVisible
            CreatedTimestamp
            LastModifiedTimestamp
            QueueArn
            (string) --
            (string) --

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

    :returns:
    If you don't provide a value for an attribute, the queue is created with the default value for the attribute.
    If you delete a queue, you must wait at least 60 seconds before creating a queue with the same name.

    """
    pass


def _has_attr(device, key, value):
    """
    Returns True if the udev Device has the attribute 'key' set to 'value'.
    """
    attrs = device.attributes
    return key in attrs.keys() and attrs[key] == value


def single_or(seq, default, cond=None):
    """Extract a single item from a sequence matching condition `cond`

    Returns `default` if no item is found.

    Raises IndexError if there is more than one item matching the condition.
    """
    if cond is None:
        cond = lambda x: True
    NOMATCH = object()
    result = NOMATCH
    for x in seq:
        if not cond(x):
            continue
        if result is not NOMATCH:
            raise IndexError('Multiple items found')
        result = x
    if result is NOMATCH:
        result = default
    return result


def expand_prefix(prefix):
    """Expand prefix string by adding a trailing period if needed.

    expandPrefix(p) should be used instead of p+'.' in most contexts.
    """
    if prefix and not prefix.endswith('.'):
        return prefix + '.'
    return prefix


def configure_sagemaker(graph):
    """
    Instantiates all the necessary sagemaker factories.

    """
    graph.use('active_bundle', 'active_evaluation',
        'bundle_and_dependencies_loader', 'bundle_and_dependencies_trainer',
        'random', 'training_initializers')


def list_groups(api, instance='', fields='', **params):
    """List all the groups of an instance. If no instance is provided , fetch the customer groups ( = platform feeds in lumapps)

    Args:
        api: the ApiClient instance to use for requests
        instance: the instance id
        fields: the fields to be returned
        ``**params``: optional  dictionary of search parameters as defined in https://api.lumapps.com/docs/feed/list

    Yields:
        a Lumapps Feed resource
    """
    if not params:
        params = dict()
    if instance != '':
        params['instance'] = instance
    if fields != '':
        params['fields'] = fields
    if not params.get('body', None):
        params['body'] = {}
    return api.iter_call('feed', 'search', **params)


@classmethod
def type_ordinal(cls, version_byte):
    """
        Extracts the type ordinal from the version byte of a serialized HLL.

        :param byte version_byte: the version byte of the serialized HLL
        :returns: the type ordinal of the serialized HLL
        :rtype: int
        """
    return version_byte & cls.NIBBLE_MASK


def get_default_params(dim: int) ->dict:
    """
        Returns the default parameters of the JADE Differential Evolution Algorithm.
        :param dim: Size of the problem (or individual).
        :type dim: int
        :return: Dict with the default parameters of the JADE Differential
        Evolution Algorithm.
        :rtype dict
        """
    pop_size = 10 * dim
    return {'max_evals': 10000 * dim, 'individual_size': dim, 'callback':
        None, 'population_size': pop_size, 'c': 0.1, 'p': max(0.05, 3 /
        pop_size), 'seed': None}


def is_first_date_lower(year, month, day, year_end, month_end, day_end):
    """
    Checks 2 dates and confirms which one is the lower one
    """
    if year < year_end:
        return True
    elif year > year_end:
        return False
    elif not (month and month_end):
        return None
    elif month < month_end:
        return True
    elif month > month_end:
        return False
    elif not (day and day_end):
        return None
    elif day < day_end:
        return True
    elif day > day_end:
        return False
    else:
        return 'Equal'


def strip_headers(headers):
    """
    Strips the headers attached to the instance of any header beginning
    with a colon that ``hyper`` doesn't understand. This method logs at
    warning level about the deleted headers, for discoverability.
    """
    for name in list(headers.keys()):
        if name.startswith(b':'):
            del headers[name]


def get_dates(df, date_column):
    """Converts a given date to various formats and returns an updated dataframe.

    Args:
        df: Pandas dataframe.
        columns: List of columns to transform.

    Returns:
        Original dataframe with additional date columns.
    """
    df['day'] = df[date_column].dt.strftime('%d')
    df['month'] = df[date_column].dt.strftime('%m')
    df['year'] = df[date_column].dt.strftime('%Y')
    df['year_month'] = df[date_column].dt.strftime('%Y%m')
    df['week_number'] = df[date_column].dt.strftime('%U')
    df['day_number'] = df[date_column].dt.strftime('%j')
    df['day_name'] = df[date_column].dt.strftime('%A')
    df['month_name'] = df[date_column].dt.strftime('%B')
    df['mysql_date'] = df[date_column].dt.strftime('%Y-%d-%m')
    return df


def time_dst(distance, speed):
    """Usage: time_dst(distance traveled, speed of object)"""
    return distance / speed


def _inject_mutations_2D(phi, dt, xx, yy, theta0, frozen1, frozen2, nomut1,
    nomut2):
    """
    Inject novel mutations for a timestep.
    """
    if not frozen1 and not nomut1:
        phi[1, 0] += dt / xx[1] * theta0 / 2 * 4 / ((xx[2] - xx[0]) * yy[1])
    if not frozen2 and not nomut2:
        phi[0, 1] += dt / yy[1] * theta0 / 2 * 4 / ((yy[2] - yy[0]) * xx[1])
    return phi


def normalize_port_no(port_no):
    """Normalize port number value to int or string."""
    if isinstance(port_no, int):
        return port_no
    if isinstance(port_no, str):
        try:
            return int(port_no, 0)
        except ValueError:
            return port_no.upper()
    raise ValueError('Invalid port_no: %r' % port_no)


@classmethod
def _get_fetch_all_method(cls):
    """
        Fetch method for the all objects
        :return:
        """
    return cls.fetch_all_api_method or f'{cls._get_name_plural()}.list'