def get_edge_attrs(source_id, targe_id, node_label, edge_label, attrs_var):
    """Query for retreiving edge's attributes."""
    query = (
        "MATCH (n:{} {{ id: '{}' }})-[rel:{}]->(m:{} {{ id: '{}' }}) \n".
        format(node_label, source_id, edge_label, node_label, targe_id) +
        """RETURN properties(rel) as {}
""".format(attrs_var))
    return query


def _check_parameters(animal_types=None, size=None, gender=None, age=None,
    coat=None, status=None, distance=None, sort=None, limit=None):
    """
    Internal function for checking the passed parameters against valid options available in the Petfinder API.

    Parameters
    ----------
    animal_type : {'dog', 'cat', 'rabbit', 'small-furry', 'horse', 'bird', 'scales-fins-other', 'barnyard'}, str, optional
        String representing desired animal type to search. Must be one of 'dog', 'cat', 'rabbit', 'small-furry',
        'horse', 'bird', 'scales-fins-other', or 'barnyard'.
    size: {'small', 'medium', 'large', 'xlarge'}, str, tuple or list of str, optional
        String or tuple or list of strings of desired animal sizes to return. The specified size(s) must be one
        of 'small', 'medium', 'large', or 'xlarge'.
    gender: {'male', 'female', 'unknown'} str, tuple or list of str, optional
        String or tuple or list of strings representing animal genders to return. Must be of 'male', 'female',
        or 'unknown'.
    age : {'baby', 'young', 'adult', 'senior'} str, tuple or list of str, optional
        String or tuple or list of strings specifying animal age(s) to return from search. Must be of 'baby',
        'young', 'adult', 'senior'.
    coat : {'short', 'medium', 'long', 'wire', 'hairless', 'curly'}, str, tuple or list of str, optional
        Desired coat(s) to return. Must be of 'short', 'medium', 'long', 'wire', 'hairless', or 'curly'.
    status : {'adoptable', 'adopted', 'found'} str, optional
        Animal status to filter search results. Must be one of 'adoptable', 'adopted', or 'found'.
    distance : int, optional
        Returns results within the distance of the specified location. If not given, defaults to 100 miles.
        Maximum distance range is 500 miles.
    sort : {'recent', '-recent', 'distance', '-distance'}, optional
            Sorts by specified attribute. Leading dashes represents a reverse-order sort. Must be one of 'recent',
            '-recent', 'distance', or '-distance'.
    limit : int, default 20
        Number of results to return per page. Defaults to 20 results and cannot exceed 100 results per page.

    Raises
    ------
    ValueError

    Returns
    -------
    None
        If :code:`ValueError` is not raised, the function returns :code:`None` which signifies the passed API
        parameters are valid.

    """
    _animal_types = ('dog', 'cat', 'rabbit', 'small-furry', 'horse', 'bird',
        'scales-fins-other', 'barnyard')
    _sizes = 'small', 'medium', 'large', 'xlarge'
    _genders = 'male', 'female', 'unknown'
    _ages = 'baby', 'young', 'adult', 'senior'
    _coats = 'short', 'medium', 'long', 'wire', 'hairless', 'curly'
    _status = 'adoptable', 'adopted', 'found'
    _sort = 'recent', '-recent', 'distance', '-distance'
    incorrect_values = {}
    if animal_types is not None and animal_types not in _animal_types:
        incorrect_values['animal_types'] = (
            'animal types {types} is not valid. Animal types must of the following: {animal_types}'
            .format(types=animal_types, animal_types=_animal_types))
    if size is not None:
        if isinstance(size, str):
            size = [size]
        diff = set(size).difference(_sizes)
        if len(diff) > 0:
            incorrect_values['size'] = (
                'sizes {sizes} are not valid. Sizes must be of the following: {size_list}'
                .format(sizes=diff, size_list=_sizes))
    if gender is not None:
        if isinstance(gender, str):
            gender = [gender]
        diff = set(gender).difference(_genders)
        if len(diff) > 0:
            incorrect_values['gender'] = (
                'genders {genders} are not valid. Genders must be of the following: {gender_list}'
                .format(genders=diff, gender_list=_genders))
    if age is not None:
        if isinstance(age, str):
            age = [age]
        diff = set(age).difference(_ages)
        if len(diff) > 0:
            incorrect_values['age'] = (
                'ages {age} are not valid. Ages must be of the following: {ages_list}'
                .format(age=diff, ages_list=_ages))
    if coat is not None:
        if isinstance(coat, str):
            coat = [coat]
        diff = set(coat).difference(_coats)
        if len(diff) > 0:
            incorrect_values['coat'] = (
                'coats {coats} are not valid. Coats must be of the following: {coat_list}'
                .format(coats=diff, coat_list=_coats))
    if status is not None and status not in _status:
        incorrect_values['status'] = (
            'animal status {status} is not valid. Status must be of the following: {statuses}'
            .format(status=status, statuses=_status))
    if sort is not None and sort not in _sort:
        incorrect_values['sort'
            ] = 'sort order {sort} must be one of: {sort_list}'.format(sort
            =sort, sort_list=_sort)
    if distance is not None:
        if not 0 <= int(distance) <= 500:
            incorrect_values['distance'
                ] = 'distance cannot be greater than 500 or less than 0.'
    if limit is not None:
        if int(limit) > 100:
            incorrect_values['limit'
                ] = 'results per page cannot be greater than 100'
    if len(incorrect_values) > 0:
        errors = ''
        for k, v in incorrect_values.items():
            errors = errors + v + '\n'
        raise ValueError(errors)
    return None


def full_name(func):
    """Return full name of `func` by adding the module and function name."""
    try:
        name = func.__qualname__
    except AttributeError:
        name = func.__name__
    return func.__module__ + '.' + name


def _n(num_or_tuple):
    """Get value from number or one-elt tuple/list."""
    try:
        num = num_or_tuple[0]
    except TypeError:
        num = num_or_tuple
    return num


@staticmethod
def p_source_optional_list(p):
    """source_optional_list : source_optional
                                | source_optional source_optional_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


@classmethod
def value_channel_layout(cls, data):
    """Returns a string"""
    info = cls.get_element(data, 'ChannelLayout')
    return info, info or 'null'


def check_duplicate_stats(stats1, stats2, threshold=0.01):
    """
    Checks two lists of paired statistics for duplicates and returns a list of
    the pairs that agree within to <1%.

    INPUTS:
    STATS1 : List of first statistical metric, e.g. Standard Deviations
    STATS2 : List of second statistical metric, e.g. Centered Root Mean Square Difference

    OUTPUTS:
    DUPLICATES : List of tuples of paired statistics that are duplicates. The list contains
                 the index locations of the pairs of statistics followed by their values
                 as 2-tuples.

    Author: Peter A. Rochford
        Symplectic, LLC
        www.thesymplectic.com
        prochford@thesymplectic.com

    Created on Apr 23, 2017
    """
    if threshold < 1e-07:
        raise ValueError('threshold value must be positive: ' + str(threshold))
    if len(stats1) == 0:
        raise ValueError('Argument stats1 is empty list!')
    elif len(stats2) == 0:
        raise ValueError('Argument stats2 is empty list!')
    if len(stats1) != len(stats2):
        raise ValueError(
            'Arguments stats1 and stats2 have different list lengths.\n' +
            'len(stats1) = ' + str(len(stats1)) + ' != len(stats2) = ' +
            str(len(stats2)))
    duplicates = []
    n = len(stats1)
    for i in range(n):
        for j in range(i + 1, n):
            diff1 = abs((stats1[i] - stats1[j]) / stats1[i])
            diff2 = abs((stats2[i] - stats2[j]) / stats2[i])
            if diff1 < threshold and diff2 < threshold:
                duplicates.append((i, j, (stats1[i], stats2[i]), (stats1[j],
                    stats2[j])))
    return duplicates


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 addon_keymap_unregister(keymap_data):
    """Unregister a set of keymaps for addons.

    """
    pass


def dbh_transducer(path, contenttype, extension, roottag, nsurl):
    """ Generic XML Handler - Returns xml_generic for all XML files """
    if extension == 'tdb':
        return 'db_transducer'
    else:
        return False


def render(item):
    """renders result field for an item
        """


def close():
    """Close this connection."""


def _dec2bin(val, maxbits=8):
    """
    A decimal to binary converter. Returns bits in a list.
    """
    retval = []
    for i in range(maxbits - 1, -1, -1):
        bit = int(val / 2 ** i)
        val = val % 2 ** i
        retval.append(bit)
    return retval


def set_tty_aware():
    """Makes all interactions here tty aware.  This means that if either
    stdout or stderr are directed to something other than a tty,
    colorization will not be added."""
    global TTY_AWARE
    TTY_AWARE = True


def users():
    """ Returns a list of users providing :py:class:`IUser`
        """


def immediate(function):
    """    Function decorator used to tag Forth methods that will be executed
    immediately even when in compile mode.
    """
    function.forth_immediate = True
    return function


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


@classmethod
def determine_rest_verb(cls, http_method, pk):
    """ Return the REST operation associated with the given HTTP method.

        This is part of the `RestEndpoint` class because this way it becomes
        customisable by subclasses.

        :param str|unicode http_method:
            The HTTP method used for the request.
        :param str|int pk:
            The primary key extracted from the URL template.
        :return str|unicode:
            The REST verb associated with that request. This is also the name
            of the method on `RestResource` that will be called by the endpoint.
        """
    if http_method == 'GET':
        return 'query' if not pk else 'get'
    elif http_method == 'POST' and not pk:
        return 'create'
    elif http_method == 'PUT' and pk:
        return 'update'
    elif http_method == 'DELETE' and pk:
        return 'delete'
    elif http_method == 'OPTIONS':
        return 'options'
    elif http_method == 'HEAD':
        return 'head'
    else:
        return None


def globalPortletCategories(placeless=False):
    """Get global portlet key-value pairs, in order.

        When rendered, a portlet manger (column) will be filled first by
        contextual portlets (if the context and/or its parents provide
        ILocalPortletAssignable), and then by global portlets. Global portlet
        assignments may include portlets per user, per group, or per content
        type.

        This function should return a tuple of tuples where each inner tuple
        contains a category such as 'user' or 'group' and the key to use in
        this category.

        For example, if the current content object is a 'Document', the current
        user is 'fred' and he is a member of 'group1' and 'group2', this may
        be:

        (('content_type', 'Documment'),
         ('user', 'fred',),
         ('group', 'group1',),
         ('group', 'group2',),)

        In this case, all contextual portlets may be rendered first, followed
        by all global portlets in the content_type category assigned to
        'Document', followed by user portlets for 'fred' and group portlets for
        'group1' and then 'group2'.

        If ``placeless`` is True, the categories should only include those
        which are independent of the specific location. In this case, that
        may mean that the 'content_type' category is excluded.
        """


def build_m(df_data, dimension1, binary=True, filter_col=None, filter_val=None
    ):
    """
    Build matrix binary M by computing the RCA of every instance of dimension 1

    :param df_data: (Dataframe) each row is a instance of dimension1 in a YEAR, other columns are functions.
    :param dimension1: (string) first dimension of the problem (name of the column in df_data)
    :param year: (int) year of interest
    :param binary : (bool) True to get M matrix, False to get RCA matrix
    :return: (Dataframe) Matrix M
    """
    if filter_col:
        df_nat = df_data[df_data[filter_col] == filter_val]
        df_cp = df_nat.groupby(by=[dimension1, filter_col]).sum()
    else:
        df_nat = df_data
        df_cp = df_nat.groupby(by=[dimension1]).sum()
    df_nat = df_cp.sum(axis=1)
    df_num = df_cp.astype(float).div(df_nat, axis=0).astype(float)
    df_prod = df_cp.sum(axis=0)
    df_tot = df_prod.sum()
    df_denum = df_prod / df_tot
    if filter_col:
        df = df_num.div(df_denum).reset_index().drop(filter_col, 1).set_index(
            dimension1)
    else:
        df = df_num.div(df_denum).reset_index().set_index(dimension1)
    if binary:
        df = df.apply(lambda x: x > 1).astype(int)
    return df


def auth_url():
    """Return the HP Cloud Auth URL"""
    return 'https://region-a.geo-1.identity.hpcloudsvc.com:35357/v2.0'


def sort(items, formatter, start, stop, sorters):
    """Return a list of items in sorted order.

        Formatter is passed to aid calculation of sort parameters.  Start and
        stop are passed in order to provide a hint as to the range needed, if
        the algorithm can optimize.  Sorters are a list of zero or more
        sub-sort callables with the same signature which may be used if
        desired to sub-sort values with equivalent sort values according
        to this column.

        The original items sequence should not be mutated."""


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

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

        """
    return '<module {!r} (built-in)>'.format(module.__name__)


def import_geotiff(file_path):
    """
    Import a GeoTIFF to a numpy array and prints
    information of the Coordinate Reference System (CRS).

    **Requires `osgeo`.**

    Args:
        file_path : str
            path to the GeoTIFF

    Returns:
        data : 2D array
        extent : tuple
            bounding box in the projection of the GeoTIFF
            e.g. [xmin, xmax, ymin, ymax]
    """
    from osgeo import gdal, osr
    gtiff = gdal.Open(file_path)
    data = gtiff.ReadAsArray()
    gt = gtiff.GetGeoTransform()
    gtproj = gtiff.GetProjection()
    inproj = osr.SpatialReference()
    inproj.ImportFromWkt(gtproj)
    gtextent = gt[0], gt[0] + gtiff.RasterXSize * gt[1], gt[3], gt[3
        ] + gtiff.RasterYSize * gt[5]
    print(inproj)
    gtiff = None
    return data, gtextent


def manage_addLFBIndex(context, indexid, extra=None, REQUEST=None, RESPONSE
    =None, URL3=None):
    """Add a DateRecurringIndex
    """
    return context.manage_addIndex(indexid, 'LanguageFallbackIndex', extra=
        extra, REQUEST=REQUEST, RESPONSE=RESPONSE, URL1=URL3)


def get_digit_list(alist: [str], from_index: int) ->([str], [str]):
    """
    Returns a list of items removed from a given list of strings
    that are all digits from 'from_index' until hitting a non-digit item
    """
    ret = []
    alist.pop(from_index)
    while len(alist) > from_index and alist[from_index].isdigit():
        ret.append(alist.pop(from_index))
    return alist, ret


def date_adapter(obj, request):
    """Format the fields.Date to return String

    ::

        from pyramid.renderers import JSON
        from datetime import date
        json_renderer = JSON()
        json_renderer.add_adapter(date, date_adapter)
        config.add_renderer('json', json_renderer)

    :param obj: datetime obj
    :rtype: str, isoformat datetime
    """
    return obj.isoformat()


@staticmethod
def _contains_vars(data):
    """
        returns True if the data contains a variable pattern
        """
    if isinstance(data, str):
        for marker in ('{%', '{{', '{#'):
            if marker in data:
                return True
    return False


def get_canonical_web_scale(scale=None):
    """returns (width, height) of web image
        """


def parse_AHF_file(filename, pars, sep=None):
    """
    Parse an AHF log or parameter file.
    """
    npars = len(pars.keys())
    vals = {}
    f = open(filename, 'r')
    for line in f.readlines():
        line = line.strip()
        if line is None:
            break
        if len(vals.keys()) == npars:
            break
        for par in pars:
            key = pars[par]
            if key in vals:
                continue
            if line.startswith('%s ' % par):
                val = float(line.split(sep)[1])
                vals[key] = val
    f.close()
    if len(vals) < npars:
        raise RuntimeError('%s missing these parameters: %s.' % (filename,
            ', '.join(set(pars.values()).difference(vals))))
    return vals


def create_subcomm(comm, ranks):
    """Create a communicator for a set of ranks."""
    group = comm.Get_group()
    subgroup = group.Incl(ranks)
    subcomm = comm.Create(subgroup)
    subgroup.Free()
    group.Free()
    return subcomm


def reset_entity_threshold():
    """Resets the entity threshold
    """
    global ENTITY_THRESHOLD
    ENTITY_THRESHOLD = 500000.0


def hasGroup(segments, group):
    """
        Return True if file at `segments` has group in ACL.
        """


def execute(func, handler, args, kwargs):
    """
    Wrap the handler ``_execute`` method to trace incoming requests,
    extracting the context from the headers, if available.
    """
    tracing = handler.settings.get('opentracing_tracing')
    if tracing._trace_all:
        attrs = handler.settings.get('opentracing_traced_attributes', [])
        tracing._apply_tracing(handler, attrs)
    return func(*args, **kwargs)


@staticmethod
def set_policy(bucket):
    """Set bucket policy to be readable by everyone publically."""
    policy = (
        """
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Sid": "PublicReadGetObject",
                        "Effect": "Allow",
                        "Principal": "*",
                        "Action": "s3:GetObject",
                        "Resource": "arn:aws:s3:::%s/*"
                    }
                ]
            }
            """
         % bucket.name)
    policy = policy.strip()
    pol = bucket.Policy()
    pol.put(Policy=policy)


def _draw_text(ctx, text, align_point=0.0, size=1.0, rgba=(0.0, 0.0, 0.0, 1.0)
    ):
    """
	Draw the desired text centered vertically around (0,0) horizontally
	"align_point" along the text's width.
	"""
    ctx.save()
    ctx.select_font_face('Sans')
    ctx.set_source_rgba(*rgba)
    ctx.set_font_size(size)
    x, y, w, h, _w, _h = ctx.text_extents(text)
    ctx.move_to(-x + (1.0 - w) * align_point, -y - size / 2)
    ctx.show_text(text)
    ctx.restore()


def set_normals_from_faces(keep_sharp: bool=False):
    """Set the custom normals from the selected faces ones

    :param keep_sharp: Keep Sharp Edges, Do not set sharp edges to face
    :type keep_sharp: bool
    """
    pass


@staticmethod
def formatdict(data, key, value, fmt, sep):
    """convert dict or key-value pairs to appropriate dict format"""
    return dict(data)


def line_filter_is_partial(line):
    """return one of the valid filter operators after a partial `where -filter-` statement"""
    l = line.split()
    if len(l) > 1:
        if l[-2] == 'where':
            return True


def set_snapshot_state(harn, snapshot_state):
    """
        Sets harness state based on a previous snapshot.

        This can be overrided for specific applications.  In this case,
        it is the users responsibility to ensure that this handles all relevant
        items returned by `harn.get_snapshot_state`.

        Args:
            snapshot_state (dict): information corresponding to
        """
    if 'epoch' in snapshot_state:
        harn.epoch = snapshot_state['epoch'] + 1
    if '_prev_iter_idxs' in snapshot_state:
        harn._prev_iter_idxs = snapshot_state['_prev_iter_idxs']
    if 'model_state_dict' in snapshot_state:
        harn.model.load_state_dict(snapshot_state['model_state_dict'])
        harn.debug('loaded model_state_dict')
    if 'monitor_state_dict' in snapshot_state:
        patience = harn.monitor.patience
        max_epoch = harn.monitor.max_epoch
        harn.monitor.load_state_dict(snapshot_state['monitor_state_dict'])
        harn.monitor.patience = patience
        harn.monitor.max_epoch = max_epoch
        harn.debug('loaded monitor_state_dict')
    if 'optimizer_state_dict' in snapshot_state:
        harn.optimizer.load_state_dict(snapshot_state['optimizer_state_dict'])
        harn.optimizer.zero_grad()
        harn.debug('loaded optimizer_state_dict')
    if 'scheduler_state_dict' in snapshot_state:
        harn.scheduler.load_state_dict(snapshot_state['optimizer_state_dict'])
        harn.debug('loaded scheduler_state_dict')
    if harn.scheduler:
        if getattr(harn.scheduler, '__batchaware__', False):
            harn.scheduler.reset_epoch(epoch=harn.epoch)
        elif harn.scheduler.__class__.__name__ == 'ReduceLROnPlateau':
            pass
        elif getattr(harn.scheduler, '__netharn_redesign__', False):
            harn.scheduler.step(epoch=harn.epoch)
        else:
            harn.scheduler.step(epoch=harn.epoch - 1)


@staticmethod
def isCombining(char):
    """
        Checks whether a character is a combining character

        @param   char:chr  The character to test
        @return  :bool     Whether the character is a combining character
        """
    o = ord(char)
    if 768 <= o and o <= 879:
        return True
    if 8400 <= o and o <= 8447:
        return True
    if 7616 <= o and o <= 7679:
        return True
    if 65056 <= o and o <= 65071:
        return True
    return False


@staticmethod
def calc_range(network, broadcast):
    """
        Calculate the range of addresses in the subnet.
        :param network: network address
        :param broadcast: broadcast address
        :return: range of addresses in subnet
        """
    return network + ' - ' + broadcast


def update_rest_api(restApiId=None, patchOperations=None):
    """
    Changes information about the specified API.
    See also: AWS API Documentation

    :example: response = client.update_rest_api(
        restApiId='string',
        patchOperations=[
            {
                'op': 'add'|'remove'|'replace'|'move'|'copy'|'test',
                'path': 'string',
                'value': 'string',
                'from': 'string'
            },
        ]
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            The ID of the RestApi you want to update.

    :type patchOperations: list
    :param patchOperations: A list of update operations to be applied to the specified resource and in the order specified in this list.
            (dict) -- A single patch operation to apply to the specified resource. Please refer to http://tools.ietf.org/html/rfc6902#section-4 for an explanation of how each operation is used.
            op (string) --An update operation to be performed with this PATCH request. The valid value can be 'add', 'remove', or 'replace'. Not all valid operations are supported for a given resource. Support of the operations depends on specific operational contexts. Attempts to apply an unsupported operation on a resource will return an error message.
            path (string) --The op operation's target, as identified by a JSON Pointer value that references a location within the targeted resource. For example, if the target resource has an updateable property of {'name':'value'} , the path for this property is /name . If the name property value is a JSON object (e.g., {'name': {'child/name': 'child-value'}} ), the path for the child/name property will be /name/child~1name . Any slash ('/') character appearing in path names must be escaped with '~1', as shown in the example above. Each op operation can have only one path associated with it.
            value (string) --The new target value of the update operation. When using AWS CLI to update a property of a JSON value, enclose the JSON object with a pair of single quotes in a Linux shell, e.g., '{'a': ...}'. In a Windows shell, see Using JSON for Parameters .
            from (string) --Not supported.

    :rtype: dict
    :return: {
        'id': 'string',
        'name': 'string',
        'description': 'string',
        'createdDate': datetime(2015, 1, 1),
        'version': 'string',
        'warnings': [
            'string',
        ],
        'binaryMediaTypes': [
            'string',
        ]
    }

    :returns:
    (string) --

    """
    pass


@classmethod
def from_array(cls, array, **kwargs):
    """Create VRT from numpy array with dataset wih one band but without georeference.

        Parameters
        ----------
        array : numpy.ndarray
            array with data
        **kwargs : dict
            arguments for VRT()

        Returns
        -------
        vrt : VRT

        """
    vrt = cls.__new__(cls)
    vrt._init_from_array(array, **kwargs)
    return vrt


def describe_maintenance_start_time(GatewayARN=None):
    """
    Returns your gateway's weekly maintenance start time including the day and time of the week. Note that values are in terms of the gateway's time zone.
    See also: AWS API Documentation

    Examples
    Returns your gateway's weekly maintenance start time including the day and time of the week.
    Expected Output:

    :example: response = client.describe_maintenance_start_time(
        GatewayARN='string'
    )

    :type GatewayARN: string
    :param GatewayARN: [REQUIRED]
            The Amazon Resource Name (ARN) of the gateway. Use the ListGateways operation to return a list of gateways for your account and region.

    :rtype: dict
    :return: {
        'GatewayARN': 'string',
        'HourOfDay': 123,
        'MinuteOfHour': 123,
        'DayOfWeek': 123,
        'Timezone': 'string'
    }

    """
    pass


def str_to_flt(text):
    """
    Convect string to float.

    :param text: (str) String chunk
    :return: (float) or original input string.
    """
    try:
        return float(text) if text[0].isnumeric() else text
    except ValueError:
        return text


def eyedropper_id():
    """Sample a data-block from the 3D View to store in a property

    """
    pass


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

        :param LockFileResult val:
        :rtype: LockFileResultEntry
        """
    return cls('success', val)


def hide_axis_ticks(params):
    """SHide axis ticks at top, bottom, left or right

    Args:
        params (dict): plotting parameter dictionary

    Returns:
        same as input
    """
    for panel_id, p in params['local'].items():
        obj_axis = params['internal']['canvas']['axes'][panel_id]
        for k in ['x', 'y']:
            attr = 'get_{}axis'.format(k)
            ax = getattr(obj_axis, attr)()
            for m in ['major', 'minor']:
                if k == 'x':
                    ax.set_tick_params(which=m, top=p['tick'][m]['show'][
                        'top'], bottom=p['tick'][m]['show']['bottom'])
                else:
                    ax.set_tick_params(which=m, left=p['tick'][m]['show'][
                        'left'], right=p['tick'][m]['show']['right'])
    return params


def binom_interval(success, total, confint=0.95):
    """
    Compute two-sided binomial confidence interval in Python. Based on R's binom.test.
    """
    from scipy.stats import beta
    quantile = (1 - confint) / 2.0
    lower = beta.ppf(quantile, success, total - success + 1)
    upper = beta.ppf(1 - quantile, success + 1, total - success)
    return lower, upper


@staticmethod
def can_handle_route(routing_key):
    """ Check if the consumer can handle the given routing key.

            .. note:: the default implementation will handle all routes.

            :param str routing_key: the routing key
        """
    return True


def humanizeBytes(size, precision=2):
    """
    Determine the *human readable* value of bytes on 1024 base (1KB=1024B).
    """
    s = ['B ', 'KB', 'MB', 'GB', 'TB']
    x = len(s)
    p = 0
    while size > 1024 and p < x:
        p += 1
        size = size / 1024.0
    return '%.*f %s' % (precision, size, s[p])


def import_attribute(name):
    """
        Import attribute using string reference.

        :param name:
            String reference.

        Raises ImportError or AttributeError if module or attribute do not exist.

        Example::

            import_attribute('a.b.c.foo')

    """
    path, attr = name.rsplit('.', 1)
    module = __import__(path, globals(), locals(), [attr])
    return getattr(module, attr)


def diagonal(a: tuple, b: tuple):
    """
	Diagonal distance
	On a square grid that allows 8 directions of movement.

	:param a: tuple  Start node position
	:param b: tuple  End node position
	:return: float
	"""
    ax, ay, bx, by = a[0], a[1], b[0], b[1]
    dx = abs(ax - bx)
    dy = abs(ay - by)
    return (dx + dy) * min(dx, dy)


def get_instance_access(FleetId=None, InstanceId=None):
    """
    Requests remote access to a fleet instance. Remote access is useful for debugging, gathering benchmarking data, or watching activity in real time.
    Access requires credentials that match the operating system of the instance. For a Windows instance, Amazon GameLift returns a user name and password as strings for use with a Windows Remote Desktop client. For a Linux instance, Amazon GameLift returns a user name and RSA private key, also as strings, for use with an SSH client. The private key must be saved in the proper format to a .pem file before using. If you're making this request using the AWS CLI, saving the secret can be handled as part of the GetInstanceAccess request. (See the example later in this topic). For more information on remote access, see Remotely Accessing an Instance .
    To request access to a specific instance, specify the IDs of the instance and the fleet it belongs to. If successful, an  InstanceAccess object is returned containing the instance's IP address and a set of credentials.
    See also: AWS API Documentation

    :example: response = client.get_instance_access(
        FleetId='string',
        InstanceId='string'
    )

    :type FleetId: string
    :param FleetId: [REQUIRED]
            Unique identifier for a fleet that contains the instance you want access to. The fleet can be in any of the following statuses: ACTIVATING , ACTIVE , or ERROR . Fleets with an ERROR status may be accessible for a short time before they are deleted.

    :type InstanceId: string
    :param InstanceId: [REQUIRED]
            Unique identifier for an instance you want to get access to. You can access an instance in any status.

    :rtype: dict
    :return: {
        'InstanceAccess': {
            'FleetId': 'string',
            'InstanceId': 'string',
            'IpAddress': 'string',
            'OperatingSystem': 'WINDOWS_2012'|'AMAZON_LINUX',
            'Credentials': {
                'UserName': 'string',
                'Secret': 'string'
            }
        }
    }

    """
    pass


def parse_note(note):
    """
    Currently just makes sure that the input is a string.
    """
    print('Parsing note...')
    parsed_note = str(note)
    return parsed_note


@staticmethod
def get_non_index_reads(summary):
    """
        Pick-out the reads which are not index reads

        :param summary: a Interop read summary object to parse the read numbers from
        :returns: all reads which are not index reads
        """
    non_index_reads = []
    for read_nbr in range(summary.size()):
        if not summary.at(read_nbr).read().is_index():
            non_index_reads.append(read_nbr)
    return non_index_reads


def _set_global_sender(sender):
    """ [For testing] Function to set global sender directly
    """
    global _global_sender
    _global_sender = sender


def sortM20(cells):
    """needs a doc string"""
    T = []
    for i, M in enumerate(cells):
        T.append((M[0], i))
    D = dict(zip(T, cells))
    T.sort()
    T.reverse()
    X = []
    for key in T:
        X.append(D[key])
    return X


@classmethod
def delete_expired_users(cls):
    """
        Remove expired instances of ``RegistrationProfile`` and their
        associated ``User``s.

        Accounts to be deleted are identified by searching for
        instances of ``RegistrationProfile`` with expired activation
        keys, and then checking to see if their associated ``User``
        instances have the field ``is_active`` set to ``False``; any
        ``User`` who is both inactive and has an expired activation
        key will be deleted.

        It is recommended that this method be executed regularly as
        part of your routine site maintenance; this application
        provides a custom management command which will call this
        method, accessible as ``manage.py cleanupregistration``.

        Regularly clearing out accounts which have never been
        activated serves two useful purposes:

        1. It alleviates the ocasional need to reset a
           ``RegistrationProfile`` and/or re-send an activation email
           when a user does not receive or does not act upon the
           initial activation email; since the account will be
           deleted, the user will be able to simply re-register and
           receive a new activation key.

        2. It prevents the possibility of a malicious user registering
           one or more accounts and never activating them (thus
           denying the use of those usernames to anyone else); since
           those accounts will be deleted, the usernames will become
           available for use again.

        If you have a troublesome ``User`` and wish to disable their
        account while keeping it in the database, simply delete the
        associated ``RegistrationProfile``; an inactive ``User`` which
        does not have an associated ``RegistrationProfile`` will not
        be deleted.

        """
    for profile in cls.objects():
        if profile.activation_key_expired() and not profile.is_active:
            profile.delete()


def previewrange_set(xmin: int=0, xmax: int=0, ymin: int=0, ymax: int=0):
    """Interactively define frame range used for playback

    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    """
    pass


def _needleman_wunsch_backward_pass(n_x, n_y, s, f, gap_score):
    """
    Compute the backward pass of the Needleman Wunsch algorithm.

    Args:
        n_x, n_y (int): The lengths of the sequences to be aligned.
        s (array): Match/mismatch similarity matrix.
        f (array): Forward pass alignment matrix.
        gap_score (numeric): Score for a insertion/deletion.

    Returns:
        alignment (list of tuples): The aligned sequence, as a list of pairs of indices.
    """
    alignment = []
    i = n_x
    j = n_y
    while i > 0 or j > 0:
        if i > 0 and j > 0 and f[i][j] == f[i - 1][j - 1] + s[i - 1][j - 1]:
            alignment.append((i - 1, j - 1))
            i = i - 1
            j = j - 1
        elif i > 0 and f[i][j] == f[i - 1][j] + gap_score:
            alignment.append((i - 1, None))
            i = i - 1
        else:
            alignment.append((None, j - 1))
            j = j - 1
    alignment = alignment[::-1]
    return alignment


def geom(start=1, factor=2):
    """
    iterator to generate geometric series
    :param start: start number
    :param factor: constant factor to apply
    :return: geometric series, e.g. geom(16, 0.5) -> 16 8 4 2 1 0.5 ...
    """
    n = start
    while True:
        yield n
        n *= factor


def check_dims(arr, nd):
    """
    Check if numpy array has specific number of dimensions

    Parameters
    ----------
        arr: numpy.ndarray
            Input array for dimension checking

        nd: int
            Number of dimensions to check against
    """
    if not arr.ndim == nd:
        raise Exception('%r has %r dimensions. Must have %r' % (arr, arr.
            ndim, nd))


def _calculate_exit_status(args, output):
    """
    Build the exit status for the program.

    This will be non-zero if any errors were outputted, or if --fatal-warnings
    was passed and any warnings were outputted. Otherwise it will be zero.
    """
    outputted_errors = False
    outputted_warnings = False
    for _, level, _, _ in output:
        if level in ['backwards-compatibility', 'parser']:
            outputted_errors = True
        elif level in ['forwards-compatibility']:
            outputted_warnings = True
    if outputted_errors or args.fatal_warnings and outputted_warnings:
        return len(output)
    return 0


def email(message_type, plaintext_body, reply_to, sender_address,
    sender_name, subject, html_body=None, variable_defaults=None):
    """
    Required platform override when email in ua.device_types.
    Specifies content of the email being sent. All other notification
    fields are not used in the email if included.

    See https://docs.urbanairship.com/api/ua/#schemas%2femailoverrideobject
        for additional caveats.

    :param message_type: Required. One of transactional or commercial.
    :param plaintext_body: Required. The plain text body of the email. May include
        variable substitution fields for use with create and send inline templates.
    :param reply_to: Required. The reply-to address.
    :param sender_address: Required. The email address of the sender.
        The domain of the email must be enabled in the email
        provider at the delivery tier.
    :param sender_name: Required. The common name of the email sender.
    :param subject: Required. The subject line of the email. May include variable
        substitution fields for use with create and send inline templates.
    :param html_body: Optional. The HTML content of the email.
    :param variable_details: Required for CreateAndSendPush with inline templates.
        a list of dicts of default values for inline template variables.
    """
    if message_type not in ('transactional', 'commercial'):
        raise ValueError(
            'message_type must be either transactional or commercial')
    payload = {}
    payload['message_type'] = message_type
    payload['reply_to'] = reply_to
    payload['sender_address'] = sender_address
    payload['sender_name'] = sender_name
    alert_payload = {'subject': subject, 'plaintext_body': plaintext_body}
    if html_body is not None:
        alert_payload['html_body'] = html_body
    if variable_defaults is not None:
        payload['template'] = {'variable_defaults': variable_defaults,
            'fields': alert_payload}
    else:
        payload.update(alert_payload)
    return payload


def check_range(value, a, b, strict=False):
    """Check that a value lies in a given range

    :param value: value to test
    :param a: lower bound
    :param b: upper bound
    :return: nothing

    .. doctest::

        >>> from easydev.tools import check_range
        >>> check_range(1,0, 2)

    """
    if strict is True:
        if value <= a:
            raise ValueError(' {} must be greater (or equal) than {}'.
                format(value, a))
        if value >= b:
            raise ValueError(' {} must be less (or less) than {}'.format(
                value, b))
    elif strict is False:
        if value < a:
            raise ValueError(' {} must be greater than {}'.format(value, a))
        if value > b:
            raise ValueError(' {} must be less than {}'.format(value, b))


def apple_deployment_target_env(os_, os_version):
    """environment variable name which controls deployment target"""
    env_name = {'Macos': 'MACOSX_DEPLOYMENT_TARGET', 'iOS':
        'IOS_DEPLOYMENT_TARGET', 'watchOS': 'WATCHOS_DEPLOYMENT_TARGET',
        'tvOS': 'TVOS_DEPLOYMENT_TARGET'}.get(str(os_))
    if not env_name:
        return {}
    return {env_name: os_version}


def cat(filename):
    """Given filename, print its text contents."""
    f = open(filename, 'r')
    out = f.read()
    f.close()
    return out


def set_file(stream, content_type=None, content_encoding=None):
    """Re-upload data for this file object. It will change the
        ``content_type`` and ``content_encoding``, however id, title,
        etc. will not change. If ``content_type`` is None, it will be
        detected with ``content_encoding``, if possible.
        """


@classmethod
def left_merge(cls, multicolor1, multicolor2):
    """ Updates first supplied :class:`Multicolor` instance with information from second supplied :class:`Multicolor` instance.

        Works as proxy to respective call to private static method :meth:`Multicolor._Multicolor__left_merge` for purposes of inheritance compatibility.

        Accounts for subclassing.

        :param multicolor1: instance to update information in
        :type multicolor1: :class:`Multicolor`
        :param multicolor2: instance to use information for update from
        :type multicolor2: :class:`Multicolor`
        :return: updated first supplied :class:`Multicolor` instance
        :rtype: :class:`Multicolor`
        """
    return cls.__left_merge(multicolor1, multicolor2)


def get_start_datetime():
    """Returns start_datetime
        """


@classmethod
def fromtime(cls, time):
    """
        Build a daytime from a datetime.time- or datetime.datetime-object.

        Args:
            time:   datetime.time- or datetime.datetime-object

        Returns a daytime.
        """
    return cls(hour=time.hour, minute=time.minute, second=time.second,
        microsecond=time.microsecond)


def interpret_number(bb, context=None):
    """Convert a raw Number value to the integer it represents.

    This is a little more lenient than the SGF spec: it permits arbitrary
    leading and trailing whitespace, and ignores spaces anywhere inside the
    data.

    From Python 3.6 on, it also permits 'grouping' underscores between
    numerals.

    """
    return int(bb.replace(b' ', b''), 10)


def selection_collision(selections, poolsize):
    """
	Calculate the probability that two random values selected from an arbitrary
	sized pool of unique values will be equal. This is commonly known as the
	"Birthday Problem".

	:param int selections: The number of random selections.
	:param int poolsize: The number of unique random values in the pool to choose from.
	:rtype: float
	:return: The chance that a collision will occur as a percentage.
	"""
    probability = 100.0
    poolsize = float(poolsize)
    for i in range(selections):
        probability = probability * (poolsize - i) / poolsize
    probability = 100.0 - probability
    return probability


@classmethod
def from_dict(cls, assocdict):
    """Init an association from an association dict."""
    return cls(assocdict[cls._keyattr()], assocdict[cls._valueattr()])


def extrude_faces_indiv(mirror: bool=False):
    """Extrude individual faces only

    :param mirror: Mirror Editing
    :type mirror: bool
    """
    pass


@classmethod
def stat_float_times(cls, newvalue=None):
    """Determine whether a file's time stamps are reported as floats
        or ints.

        Calling without arguments returns the current value.
        The value is shared by all instances of FakeOsModule.

        Args:
            newvalue: If `True`, mtime, ctime, atime are reported as floats.
                Otherwise, they are returned as ints (rounding down).
        """
    if newvalue is not None:
        cls._stat_float_times = bool(newvalue)
    return cls._stat_float_times


def human_check(string):
    """
    The API is actually terribly unreliable at providing information on
    whether an entity is human or corporate. What is consistent is that
    companies are provided in UPPER CASE and humans provided in the format
    "SURNAME, Othernames". This takes advantage of this to identify if a
    record is human.
    """
    for i in string:
        if i.islower():
            return 'Individual'
    return 'Corporate'


def set_interface(dev, bInterfaceNumber, bAlternateSetting):
    """Set the alternate setting of the interface.

    dev is the Device object to which the request will be
    sent to.
    """
    dev.set_interface_altsetting(bInterfaceNumber, bAlternateSetting)


@classmethod
def _read_instruction_from_relative_instructions(cls, relative_instructions):
    """Returns ReadInstruction obj initialized with relative_instructions."""
    result = cls.__new__(cls)
    result._init(relative_instructions)
    return result


def reverse_elements(seq):
    """Reverse the elements of a sequence."""
    for elt in seq:
        yield elt[::-1]


def _analyse_tree_h(tree):
    """
    Extract information from a tree in a
    HistGradientBoosting.
    """
    info = {}
    info['leave_count'] = tree.get_n_leaf_nodes()
    info['node_count'] = len(tree.nodes)
    info['max_depth'] = tree.get_max_depth()
    return info


def normalize_scheme(scheme):
    """Normalize scheme part of the url.

    Params:
        scheme : string : url scheme, e.g., 'https'

    Returns:
        string : normalized scheme data.

    """
    return scheme.lower()


@classmethod
def hascreds(cls, config):
    """Determine if the given configuration has proper credentials
        Parameters
        ----------
        cls : class
            A Session class.
        config : dict
            GDAL configuration as a dict.
        Returns
        -------
        bool
        """
    return 'SWIFT_STORAGE_URL' in config and 'SWIFT_AUTH_TOKEN' in config


def to_hass_level(level):
    """Convert the given Lutron (0.0-100.0) light level to Home Assistant (0-255)."""
    return int(level * 255 / 100)


def __new__(cls, password_string: str):
    """
        The __new__ method is called when a new object is being instantiated from the class. In this case we use it to
        modify the construction logic of the str parent class to implement custom logic:
        When the string already is a hash, it will be set as the value of the string. If it is detected, that the given
        string is still a plain text password though, it will first be hashed.

        CHANGELOG

        Added 08.06.2019

        Changed 09.06.2019
        Added the distinction between the string already being a hash or a plain text password.

        :param password_string:
        :return:
        """
    if cls.is_hash(password_string):
        password_hash = password_string
    else:
        password_hash = cls.PASSWORD_HASHER.hash(password_string)
    return str.__new__(cls, password_hash)


def update_filter(index, key, value, metadata):
    """Update an arbitrary filter key-value pair in a list of filters."""
    metadata['reportMetadata']['reportFilters'][index][key] = value


@staticmethod
def exit_error(error_msg):
    """Prints error message and exits"""
    print()
    print(error_msg)
    exit()


def update_namespace(D, *attributes):
    """ Add arbitrary attributes to a :class: `Namespace <argparse.Namespace>`.

    ==========  ================================================================
    D           argparse.Namespace; the namespace holding the data and
                metadata. The format is the same as what is returned by a
                dataloader.
    attributes  tuples or len(2) lists; (name, value) pairs of the attributes
                to add. Where `name` is a str and value any python object.
    ==========  ================================================================
    """
    for name, attribute in attributes:
        D.__dict__.update({name: attribute})


@classmethod
def from_mutable_ptr(cls, ptr):
    """Create a new instance from a mutable pointer"""
    new = cls.__new__(cls)
    super(cls, new).__init__(ptr, is_const=False)
    return new


def fib(n):
    """Fibonacci example function

    Args:
      n (int): integer

    Returns:
      int: n-th Fibonacci number
    """
    assert n > 0
    a, b = 1, 1
    for i in range(n - 1):
        a, b = b, a + b
    return a


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


def get_all_connections():
    """Return a frozenset of (nodeid, service_name, rref) tuples, one for
        each active connection we've established to a remote service. This is
        mostly useful for unit tests that need to wait until a certain number
        of connections have been made."""


@classmethod
def get_trays_list(cls):
    """
        Method for fetching info about trays (if backward delivery is ordered).

        :example:
            ``Common.get_trays_list()``
        :return:
            dictionary with info about trays
        :rtype:
            dict
        """
    req = cls.send(method='getTraysList')
    return req


def _get_db_subnet_group_arn(region, current_aws_account_id,
    db_subnet_group_name):
    """
    Return an ARN for the DB subnet group name by concatenating the account name and region.
    This is done to avoid another AWS API call since the describe_db_instances boto call does not return the DB subnet
    group ARN.
    Form is arn:aws:rds:{region}:{account-id}:subgrp:{subnet-group-name}
    as per https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
    """
    return (
        f'arn:aws:rds:{region}:{current_aws_account_id}:subgrp:{db_subnet_group_name}'
        )


def collide_circle(left, right):
    """detect collision between two sprites using circles

    pygame.sprite.collide_circle(left, right): return bool

    Tests for collision between two sprites by testing whether two circles
    centered on the sprites overlap. If the sprites have a "radius" attribute,
    then that radius is used to create the circle; otherwise, a circle is
    created that is big enough to completely enclose the sprite's rect as
    given by the "rect" attribute. This function is intended to be passed as
    a collided callback function to the *collide functions. Sprites must have a
    "rect" and an optional "radius" attribute.

    New in pygame 1.8.0

    """
    xdistance = left.rect.centerx - right.rect.centerx
    ydistance = left.rect.centery - right.rect.centery
    distancesquared = xdistance ** 2 + ydistance ** 2
    if hasattr(left, 'radius'):
        leftradius = left.radius
    else:
        leftrect = left.rect
        leftradius = 0.5 * (leftrect.width ** 2 + leftrect.height ** 2) ** 0.5
        setattr(left, 'radius', leftradius)
    if hasattr(right, 'radius'):
        rightradius = right.radius
    else:
        rightrect = right.rect
        rightradius = 0.5 * (rightrect.width ** 2 + rightrect.height ** 2
            ) ** 0.5
        setattr(right, 'radius', rightradius)
    return distancesquared <= (leftradius + rightradius) ** 2


def html_escape(text):
    """Escape &, < and >."""
    return text.replace('&', '&').replace('<', '<').replace('>', '>')


def refine_markers(backwards: bool=False):
    """Refine selected markers positions by running the tracker from track’s reference to current frame

    :param backwards: Backwards, Do backwards tracking
    :type backwards: bool
    """
    pass


def is_readonly():
    """Return False if this URI be used to modify the data. Return True
        if this URI cannot be used to modify the data."""


def setenv(environ, key, value, enc='UTF-8'):
    """
    Set the named ``key`` to ``value`` in the WSGI environ dict ``environ``.
    Value must be a byte ``str`` and will be encoded according
    to the rules in PEP-3333.
    """
    environ[key] = value.decode('ISO-8859-1')


def queuedb_row_factory(cursor, row):
    """
    Dict row factory
    """
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d


def split_tool_tag(tag: str) ->(str, str):
    """Split tool tag into tool name and tool version"""
    tag_split = tag.split(':', maxsplit=2)
    return tag_split[0], tag_split[1] if len(tag_split) > 1 else 'latest'


def isiterable(arg):
    """Check if a variable is iterable and not a string"""
    return hasattr(arg, '__iter__') and not isinstance(arg, str)


def theta_OH_SO4_HMW84(T, P):
    """a-a': hydroxide sulfate [HMW84]."""
    theta = -0.013
    valid = T == 298.15
    return theta, valid


def count(lbls, wntarget):
    """
    Count the number of line transitions with wavenumber smaller than wntarget.

    Parameters
    ----------
    lbls: List of lbl objects
    wntarget: Float
        The target wavenumber.

    Returns
    -------
    nwave: Integer
        The number of transitions with wavenumber smaller than wntarget.
    """
    nwave = 0
    for lbl in lbls:
        nwave += lbl.bs(wntarget, 0, lbl.nlines - 1)
    return nwave


def get_running(trip):
    """
    Return True if trip is running else False
    :param trip: Object
    :return: trip['running']
    """
    return trip['running']


def checkGroupEffectsValidity(columnsForZ, columnEffects):
    """On input user request removal of columnsForZ
    Here we confimr if they all exist in the current data set. If not
    reduce columnsForZ to include only valid effects. Print out a message
    NOTE: always convert to and return uppercase for comparisons and subsequent analysis
    """
    upperColumnsForZ = list()
    for effect in columnsForZ:
        upperColumnsForZ.append(effect)
    newList = list(set(upperColumnsForZ) & set(columnEffects))
    if newList.sort() != upperColumnsForZ.sort():
        print(
            'Input group list has been reduced based on preestablished possible effects'
            )
        print('Size on data effects is ' + str(len(columnsForZ)) +
            ' new removal list is of size ' + str(len(newList)))
        print('New removal list is ' + str(newList))
    return newList


def lambd_tris_Na_GT17simopt(T, P):
    """n-c: tris sodium [GT17simopt]."""
    lambd = 0.0158
    valid = T == 298.15
    return lambd, valid


def plot_polynomial(expr):
    """Plots the polynomial using the functions written in
    plotting module which in turn uses matplotlib backend.

    Parameter
    =========

    expr: Denotes a polynomial(SymPy expression)
    """
    from sympy.plotting.plot import plot3d, plot
    gens = expr.free_symbols
    if len(gens) == 2:
        plot3d(expr)
    else:
        plot(expr)


def logged_in(session):
    """Checks that the user is logged in within the session.

    :param session: http session
    :type session: aiohttp.ClientSession
    :return: True if user is logged in else False
    :rtype: bool
    """
    return 'csrftoken' in session.cookie_jar.filter_cookies(
        'https://users.premierleague.com/')


def default_locale_negotiator(request):
    """ The default :term:`locale negotiator`.  Returns a locale name
    or ``None``.

    - First, the negotiator looks for the ``_LOCALE_`` attribute of
      the request object (possibly set by a view or a listener for an
      :term:`event`). If the attribute exists and it is not ``None``,
      its value will be used.

    - Then it looks for the ``request.params['_LOCALE_']`` value.

    - Then it looks for the ``request.cookies['_LOCALE_']`` value.

    - Finally, the negotiator returns ``None`` if the locale could not
      be determined via any of the previous checks (when a locale
      negotiator returns ``None``, it signifies that the
      :term:`default locale name` should be used.)
    """
    name = '_LOCALE_'
    locale_name = getattr(request, name, None)
    if locale_name is None:
        locale_name = request.params.get(name)
        if locale_name is None:
            locale_name = request.cookies.get(name)
    return locale_name


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


@classmethod
def abulk(cls, x):
    """
        calculate the bulk (relaxed) lattice parameter of the alloy
        """
    return cls.aSi + (0.2 * x + 0.027 * x ** 2)


def read_file(path):
    """Read contents of file at given path as bytes."""
    with open(path, 'rb') as f:
        return f.read()


@classmethod
def get_by_uuid(cls, context, uuid):
    """Find a DB Device_profile and return an Obj Device_profile."""
    db_devprof = cls.dbapi.device_profile_get_by_uuid(context, uuid)
    obj_devprof = cls._from_db_object(cls(context), db_devprof)
    return obj_devprof


def maximals(A, le=lambda x, y: x <= y):
    """ Find the maximal element(s) of a partially ordered sequence"""
    r = []
    for x in A:
        for a in A:
            if le(x, a) and not le(a, x):
                break
        else:
            for a in r:
                if le(x, a):
                    break
            else:
                r.append(x)
    return r


def pretty_print(experiment, dataset, results):
    """Print the results of running the causal suite on data from an experiment.

    Parameters
    ----------
        experiment: `whynot.dynamics.DynamicsExperiment` or `whynot.framework.GenericExperiment`
            Experiment object used to generate the causal dataset
        dataset: `whynot.framework.Dataset`
            Dataset object passed to the causal suite.
        results:    dict
            Dictionary of results returned running `whynot.causal_suite` on the dataset

    """
    print('Name: ', experiment.name)
    print('Description: ', experiment.description)
    for method, estimate in results.items():
        print(f'Method: {method:<25} \t\t Estimate: {estimate.ate:2.2e}')
    print(f"{' ':<30} \t\t\t Ground Truth: {dataset.sate:2.2e}")


def plot_expected_limit_bands(axis, bands):
    """Add the expected limit bands to a plot

    Parameters
    ----------

    axis : `matplotlib.Axes`
        The axes we are adding the bands to

    bands : dict
        Dictionary with the bands

    """
    masses = bands['masses']
    axis.fill_between(masses, bands['q02'], bands['q97'], color='yellow')
    axis.fill_between(masses, bands['q16'], bands['q84'], color='green')
    axis.plot(masses, bands['median'], color='gray')


@staticmethod
def p_value_table_list_optional(p):
    """value_table_list_optional : empty
                                     | value_table_list"""
    p[0] = p[1]


def check_dir(path):
    """Check if a path exists, create if not"""
    from pathlib import Path
    if Path(path).exists():
        return True
    else:
        Path(path).mkdir(parents=True)
        return False


def glPushClientAttrib(mask):
    """Push the client attribute stack

    :param mask: Specifies a mask that indicates which attributes to save.
    """
    pass


def imf_salpeter(x):
    """ Computes a Salpeter IMF

    Keywords
    ----------
    x : numpy vector
      masses

    Returns
    -------
    imf : numpy vector
      unformalized IMF
    """
    return x ** -2.35


@task
def get_tasks():
    """Get all paver-defined tasks."""
    from paver.tasks import environment
    for task in environment.get_tasks():
        print(task.shortname)


def _get_reporoot():
    """Returns the absolute path to the repo root directory on the current
    system.
    """
    from os import path
    import aflow
    apath = path.abspath(aflow.__file__)
    return path.dirname(path.dirname(apath))


def is_empty(ref):
    """True if ref is a value ref with None value"""
    return ref.type == 'value' and ref.action.value is None


def randomize_transform(random_seed: int=0, use_delta: bool=False, use_loc:
    bool=True, loc: float=(0.0, 0.0, 0.0), use_rot: bool=True, rot: float=(
    0.0, 0.0, 0.0), use_scale: bool=True, scale_even: bool=False, scale:
    float=(1.0, 1.0, 1.0)):
    """Randomize objects loc/rot/scale

    :param random_seed: Random Seed, Seed value for the random generator
    :type random_seed: int
    :param use_delta: Transform Delta, Randomize delta transform values instead of regular transform
    :type use_delta: bool
    :param use_loc: Randomize Location, Randomize the location values
    :type use_loc: bool
    :param loc: Location, Maximum distance the objects can spread over each axis
    :type loc: float
    :param use_rot: Randomize Rotation, Randomize the rotation values
    :type use_rot: bool
    :param rot: Rotation, Maximum rotation over each axis
    :type rot: float
    :param use_scale: Randomize Scale, Randomize the scale values
    :type use_scale: bool
    :param scale_even: Scale Even, Use the same scale value for all axis
    :type scale_even: bool
    :param scale: Scale, Maximum scale randomization over each axis
    :type scale: float
    """
    pass


def open_index(elastic_client, index):
    """
    Given an Elastic client and and index, attempt to open the index
    :param elastic_client: Elastic client
    :param index: Index which is to be opened
    :return: Response from Elastic
    """
    response = elastic_client.indices.open(index=index)
    if response is None:
        raise Exception('Problem occurred opening index. Index: {}'.format(
            index))
    return response


def pagerank(graph, damping_factor=0.85, max_iterations=100, min_delta=1e-05):
    """
    Compute and return the PageRank in an directed graph.

    @type  graph: digraph
    @param graph: Digraph.

    @type  damping_factor: number
    @param damping_factor: PageRank dumping factor.

    @type  max_iterations: number
    @param max_iterations: Maximum number of iterations.

    @type  min_delta: number
    @param min_delta: Smallest variation required to have a new iteration.

    @rtype:  Dict
    @return: Dict containing all the nodes PageRank.
    """
    nodes = graph.nodes()
    graph_size = len(nodes)
    if graph_size == 0:
        return {}
    min_value = (1.0 - damping_factor) / graph_size
    pagerank = dict.fromkeys(nodes, 1.0 / graph_size)
    for i in range(max_iterations):
        diff = 0
        for node in nodes:
            rank = min_value
            for referring_page in graph.incidents(node):
                rank += damping_factor * pagerank[referring_page] / len(graph
                    .neighbors(referring_page))
            diff += abs(pagerank[node] - rank)
            pagerank[node] = rank
        if diff < min_delta:
            break
    return pagerank


def is_pkr_path(path):
    """Check environments files to deduce if path is a usable pkr path"""
    from pkr.environment import ENV_FOLDER
    return path.is_dir() and len(list(path.glob('{}/*/env.yml'.format(
        ENV_FOLDER)))) > 0


def get_cut_spike_count(filename):
    """Reads through the cut file and returns the number of spikes in the file"""
    num_spikes = None
    with open(filename, 'rb') as f:
        for line in f:
            if 'data_start' in str(line):
                break
            elif 'Exact_cut_for' in str(line):
                num_spikes = int(line.decode(encoding='UTF-8').split(
                    'spikes: ')[1])
    return num_spikes


def create_nat_gateway(SubnetId=None, AllocationId=None, ClientToken=None):
    """
    Creates a NAT gateway in the specified subnet. A NAT gateway can be used to enable instances in a private subnet to connect to the Internet. This action creates a network interface in the specified subnet with a private IP address from the IP address range of the subnet. For more information, see NAT Gateways in the Amazon Virtual Private Cloud User Guide .
    See also: AWS API Documentation

    Examples
    This example creates a NAT gateway in subnet subnet-1a2b3c4d and associates an Elastic IP address with the allocation ID eipalloc-37fc1a52 with the NAT gateway.
    Expected Output:

    :example: response = client.create_nat_gateway(
        SubnetId='string',
        AllocationId='string',
        ClientToken='string'
    )

    :type SubnetId: string
    :param SubnetId: [REQUIRED]
            The subnet in which to create the NAT gateway.

    :type AllocationId: string
    :param AllocationId: [REQUIRED]
            The allocation ID of an Elastic IP address to associate with the NAT gateway. If the Elastic IP address is associated with another resource, you must first disassociate it.

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

    :rtype: dict
    :return: {
        'NatGateway': {
            'VpcId': 'string',
            'SubnetId': 'string',
            'NatGatewayId': 'string',
            'CreateTime': datetime(2015, 1, 1),
            'DeleteTime': datetime(2015, 1, 1),
            'NatGatewayAddresses': [
                {
                    'PublicIp': 'string',
                    'AllocationId': 'string',
                    'PrivateIp': 'string',
                    'NetworkInterfaceId': 'string'
                },
            ],
            'State': 'pending'|'failed'|'available'|'deleting'|'deleted',
            'FailureCode': 'string',
            'FailureMessage': 'string',
            'ProvisionedBandwidth': {
                'Provisioned': 'string',
                'Requested': 'string',
                'RequestTime': datetime(2015, 1, 1),
                'ProvisionTime': datetime(2015, 1, 1),
                'Status': 'string'
            }
        },
        'ClientToken': 'string'
    }

    :returns:
    pending : The NAT gateway is being created and is not ready to process traffic.
    failed : The NAT gateway could not be created. Check the failureCode and failureMessage fields for the reason.
    available : The NAT gateway is able to process traffic. This status remains until you delete the NAT gateway, and does not indicate the health of the NAT gateway.
    deleting : The NAT gateway is in the process of being terminated and may still be processing traffic.
    deleted : The NAT gateway has been terminated and is no longer processing traffic.

    """
    pass


def get_position_value(price, size):
    """Returns the value of your position. This is the amountof money
    you must set into BUY order or which you get when doing a SELL order.

    :price: Current price you want to buy/sell.
    :size: How many do you want to buy/sell
    :returns: Value of your position.
    """
    return price * size


@classmethod
def realname(cls):
    """Return real name of an object class"""
    return cls.__module__ + '.' + cls.__name__


def get_stratplots_widgets(mainwindow=None):
    """Get the :class:`StraditizerWidgets` from the psyplot GUI mainwindow"""
    if mainwindow is None:
        from psyplot_gui.main import mainwindow
    if mainwindow is None:
        raise NotImplementedError('Not running in interactive psyplot GUI!')
    try:
        stratplots = mainwindow.plugins[
            'psy_strat.strat_widget:StratPlotsWidget:stratplots']
    except KeyError:
        raise KeyError('psy_strat not implemented as a GUI plugin!')
    return stratplots


def distribute_evenly(items, num_buckets):
    """
    Distribute items as evenly as possible into N buckets.
    """
    out = [[] for _ in range(num_buckets)]
    for index, item in enumerate(items):
        out[index % num_buckets].append(item)
    return out


@classmethod
def get_or_create(cls, defaults={}, **kwargs):
    """
        A port of functionality from the Django ORM. Defaults can be passed in
        if creating a new document is necessary. Keyword args are used to
        lookup the document. Returns a tuple of (object, created), where object
        is the retrieved or created object and created is a boolean specifying
        whether a new object was created.
        """
    result = cls.c.find_one(kwargs)
    if not result:
        created = True
        result = kwargs
        result.update(defaults)
        cls.update(result, result, upsert=True)
        result = cls.c.find_one(kwargs)
        instance = cls(**result)
    else:
        created = False
        instance = cls(**result)
    return instance, created


def quart_interp(h_1, h_2, h_3, h_4):
    """
    Speed up for frequent operations
    """
    return 0.25 * (h_1 + h_2 + h_3 + h_4)


def count(items):
    """count(items) -> dict of counts of each item

    Count the number of times each item appears in a list of data.
    Adapted from BioPython.
    """
    c = {}
    for i in items:
        c[i] = c.get(i, 0) + 1
    return c


def getInterpolationType(value):
    """
    Returns one of ['lin-lin', 'log-lin', 'lin-log', 'log-log'] following
    the convention:
                  0 or 2, linear in x and y         -> returns lin-lin
                  3, logarithmic in x, linear in y  -> returns log-lin
                  4, linear in x, logarithmic in y  -> returns lin-log
                  5, logarithmic in x and y         -> returns log-log
    """
    if value in [0, 2]:
        return 'lin-lin'
    if value == 3:
        return 'log-lin'
    if value == 4:
        return 'lin-log'
    if value == 5:
        return 'log-log'
    raise ValueError('Invalid interpolation flag')


@classmethod
def config(cls, verbose=None, display_on=None):
    """
        (classmethod) espressomaker.Espresso.config(verbose = Espreso.verbose,
        display_on = Espresso.display_on)

        Method to modify and return the Espresso class settings.

        Inputs:
            verbose = Bool. Default state is None, which means default is the Espresso.config() setting.
            display_on = Bool. Default state is None, which means default is the Espresso.config() setting.

        Returns:
            Str. Contains Espresso class-level settings.

        """
    if verbose == None:
        pass
    else:
        assert isinstance(verbose, bool
            ), '"verbose" setting must be bool (True/False).'
        cls._verbose_set = verbose
    if display_on == None:
        pass
    else:
        assert isinstance(display_on, bool
            ), '"display_on" setting must be bool (True/False).'
        cls._display_on_set = display_on
    return 'Espresso(verbose = {}, display_on = {})'.format(cls.
        _verbose_set, cls._display_on_set)


def R_moistAir(q):
    """
    Calculates the gas constant for umid air from the specific humidity q

    Parameters
    ----------
    q: float
        the specific humidity in g(water)/g(air)

    Returns
    -------
    R_air: float
        the specific gas constant for humid air in J/(g*K)
    """
    from .constants import R_spec
    return q * R_spec['h2o'] + (1.0 - q) * R_spec['dry_air']


def pytest_benchmark_update_commit_info(config, commit_info):
    """
    To add something into the commit_info, like the commit message do something like this:

    .. sourcecode:: python

        def pytest_benchmark_update_commit_info(config, commit_info):
            commit_info['message'] = subprocess.check_output(['git', 'log', '-1', '--pretty=%B']).strip()
    """
    pass


@classmethod
def Trans(cls, dx, dy):
    """Returns affine transformation for translation by `dx`, `dy`."""
    return cls(1, 0, dx, 0, 1, dy)


def classname(cls):
    """Create the class name str for __repr__"""
    return '.'.join([cls.__class__.__module__, cls.__class__.__name__])


def common_edges(graph1, graph2):
    """Return a list of all edges that occur both in graph1 and
    graph2.

    """
    edges = []
    for edge in graph2.edges():
        if graph1.contains_edge(edge):
            edges.append((edge, graph1.get_edge(*edge)))
    return edges


def get_default(word_index, bit_index, bit_length, default=None):
    """Return the default value from a header keyword.

    Since it is called with the full description, it just returns
    the last item, defaulted to `None`.
    """
    return default


def num_from_str(s):
    """Return a num computed from a string."""
    try:
        return int(s)
    except ValueError:
        try:
            return float(s)
        except ValueError:
            raise ValueError('Can not convert the string into a numeric value.'
                )


def not_found(start_response):
    """Called if Url not found."""
    start_response('404 Not Found', [('Content-Type', 'text/plain')])
    return [b'Error 404: Not Found']


@classmethod
def get_frame_cls(cls):
    """Return the `Frame` class for the blueprint"""
    return cls._frame_cls


def fibo(max_value=None):
    """Generator for fibonaccial decay.

    Args:
        max_value: The maximum value to yield. Once the value in the
             true fibonacci sequence exceeds this, the value
             of max_value will forever after be yielded.
    """
    a = 1
    b = 1
    while True:
        if max_value is None or a < max_value:
            yield a
            a, b = b, a + b
        else:
            yield max_value


def getPulseHeightRange(hdr, segment):
    """Get the pulse height range that was used for PHACORR.

    Parameters
    ----------
    hdr: pyfits Header object
        Extension header of corrtag, counts, flt, etc.

    segment: str
        Segment name ("FUVA" or "FUVB")

    Returns
    -------
    str, or None if keyword(s) are missing or less than 0
        "ll_hh", where ll is the lower limit and hh is the upper limit
    """
    if segment[:3] != 'FUV':
        return None
    key_low = 'PHALOWR' + segment[-1]
    low = hdr.get(key_low, -1)
    key_high = 'PHAUPPR' + segment[-1]
    high = hdr.get(key_high, -1)
    if low < 0:
        low = None
    if high < 0:
        high = None
    if low is None or high is None:
        return None
    return '%2d_%2d' % (low, high)


def is_bilby_json_file(path):
    """Determine if the results file is a bilby json results file

    Parameters
    ----------
    path: str
        path to the results file
    """
    import json
    with open(path, 'r') as f:
        data = json.load(f)
    try:
        if 'bilby' in data['version']:
            return True
        else:
            return False
    except Exception:
        return False


@staticmethod
def tab(g):
    """A token which will increase the indent depth by the default amount
        if added to the stream."""
    g.indent_depth += g.default_indent


def choice_selection_unicode(metadata):
    """given a MetaData object, returns a choice selection Unicode string"""
    if metadata is not None:
        if metadata.album_name is not None:
            if metadata.catalog is not None:
                return u'{album} (catalog #: {catalog})'.format(album=
                    metadata.album_name, catalog=metadata.catalog)
            else:
                return metadata.album_name
        elif metadata.catalog is not None:
            return u'catalog #: {catalog}'.format(catalog=metadata.catalog)
        else:
            return u''
    else:
        return u''


def _dotted_dict_to_nested_dicts(dotted_dict, delimiter_nested='.'):
    """Convert dotted keys in the state point dict to a nested dict.

    :param dotted_dict: A mapping with dots/delimiter_nested in its keys, e.g. {'a.b': 'c'}.
    :param delimiter_nested: A string delimiter between keys, defaults to '.'.
    :returns: A mapping instance with nested dicts, e.g. {'a': {'b': 'c'}}.
    """
    nested_dict = dict()
    for key, value in dotted_dict.items():
        tokens = key.split(delimiter_nested)
        if len(tokens) > 1:
            tmp = nested_dict.setdefault(tokens[0], dict())
            for token in tokens[1:-1]:
                tmp = tmp.setdefault(token, dict())
            tmp[tokens[-1]] = value
        else:
            nested_dict[tokens[0]] = value
    return nested_dict


def get_attachment_links(scenario_json):
    """get links to static scenario results"""
    attachment_links = {}
    for result in scenario_json['result_set']:
        if result['attachment_url']:
            result_name = result['result_type']['name']
            attachment_links[result_name] = result['attachment_url']
    if attachment_links:
        return attachment_links
    else:
        return None


def ensure_step_position(step, order_index):
    """Ensure step contains a position definition."""
    if 'position' not in step:
        step['position'] = {'left': 10 * order_index, 'top': 10 * order_index}


def union(*dictionaries):
    """

    union of all entries in all of the dictionaries in the order provided where
    the last value of a given key in the provided dictionaries, will be the
    value that is in the resulting dictionary.

    Examples:
    --------
    > union({'a': 1}, {'a': 2})
    {'a': 2}

    > union({'a': 1}, {'b': 2})
    {'a': 1, 'b': 2}

    """
    result = {}
    for dictionary in dictionaries:
        result.update(dictionary)
    return result


def get_resampled_wcs(wcs, factor, downsampled):
    """
    Get resampled WCS object.
    """
    wcs = wcs.deepcopy()
    if not downsampled:
        factor = 1.0 / factor
    wcs.wcs.cdelt *= factor
    wcs.wcs.crpix = (wcs.wcs.crpix - 0.5) / factor + 0.5
    return wcs


def group_ungroup():
    """Ungroup selected nodes

    """
    pass


def get_sort_params(input_params, default_key='created_at', default_dir='desc'
    ):
    """Retrieves sort keys/directions parameters.

    Processes the parameters to create a list of sort keys and sort directions
    that correspond to the 'sort_key' and 'sort_dir' parameter values. These
    sorting parameters can be specified multiple times in order to generate
    the list of sort keys and directions.

    The input parameters are not modified.

    :param input_params: webob.multidict of request parameters (from
                         masakari.wsgi.Request.params)
    :param default_key: default sort key value, added to the list if no
                        'sort_key' parameters are supplied
    :param default_dir: default sort dir value, added to the list if no
                        'sort_dir' parameters are supplied
    :returns: list of sort keys, list of sort dirs
    """
    params = input_params.copy()
    sort_keys = []
    sort_dirs = []
    while 'sort_key' in params:
        sort_keys.append(params.pop('sort_key').strip())
    while 'sort_dir' in params:
        sort_dirs.append(params.pop('sort_dir').strip())
    if len(sort_keys) == 0 and default_key:
        sort_keys.append(default_key)
    if len(sort_dirs) == 0 and default_dir:
        sort_dirs.append(default_dir)
    return sort_keys, sort_dirs


def get_profile_parser(api, opts):
    """ Get user profile description
    _ print JSONObject profile description
    _ print JSONObject profile's list description

    :param api: API Rest api object
    :param opts: command-line parser opts
    :type opts: Namespace object with opts attribute
    """
    assert opts.list or opts.name is not None
    if opts.list:
        profile_dict = api.get_profiles(opts.archi)
    else:
        profile_dict = api.get_profile(opts.name)
    return profile_dict


def stabilize_2d_rotation_remove():
    """Remove selected track from rotation stabilization

    """
    pass


def lcs(str1, str2):
    """return the lenth of lcs of [str1] and [str2]"""
    len1, len2 = len(str1), len(str2)
    if len1 == 0 or len2 == 0:
        return 0
    dpf = []
    for i in range(len1 + 1):
        lis = []
        for j in range(len2 + 1):
            lis.append(0)
        dpf.append(lis)
    for i in range(1, len1 + 1):
        for j in range(1, len2 + 1):
            if str1[i - 1] == str2[j - 1]:
                dpf[i][j] = dpf[i - 1][j - 1] + 1
            else:
                dpf[i][j] = max(dpf[i][j - 1], dpf[i - 1][j])
    return dpf[len1][len2]


@classmethod
def load(cls, payload):
    """Return a new Request object from a payload.
        """
    digest = payload[1]
    func = payload[2]['func']
    args = payload[3]['args']
    kwargs = payload[3]['kwargs']
    request = cls(func, *args, digest=digest, **kwargs)
    return request


def parse(pathToXMLFile, ignoreRemoteSongs=True):
    """Main method for constructor a Library object"""
    from . import parser
    return parser.Parser().parse(pathToXMLFile, ignoreRemoteSongs)


def PolsAnnuity(t):
    """Number of policies: Annuity"""
    return 0


def preset_add(name: str='', remove_active: bool=False, use_focal_length:
    bool=False):
    """Add or remove a Camera Preset

    :param name: Name, Name of the preset, used to make the path name
    :type name: str
    :param remove_active: remove_active
    :type remove_active: bool
    :param use_focal_length: Include Focal Length, Include focal length into the preset
    :type use_focal_length: bool
    """
    pass


@classmethod
def get_singleton(cls, annotators=None, **options):
    """
        Get or create a corenlp parser with the given annotator and options
        Note: multiple parsers with the same annotator and different options
              are not supported.
        """
    if annotators is not None:
        annotators = tuple(annotators)
    if annotators not in cls._singletons:
        cls._singletons[annotators] = cls(annotators, **options)
    return cls._singletons[annotators]


def dict_to_obs(obs_dict):
    """
    Convert an observation dict into a raw array if the
    original observation space was not a Dict space.
    """
    if set(obs_dict.keys()) == {None}:
        return obs_dict[None]
    return obs_dict


def name():
    """
        Получить имя атрибута.

        @return: имя атрибута
        @rtype: C{str}
        """


def mag_to_flux(catalog, mag_col, zeropoint=27.0, update=True):
    """
    Convert AB magnitude into HSC image flux unit.
    """
    flux = 10.0 ** ((zeropoint - catalog[mag_col]) / 2.5)
    if update:
        flux_col = mag_col.replace('mag', 'flux')
        if flux_col in catalog.colnames:
            catalog.remove_column(flux_col)
        catalog.add_column(data=flux, name=flux_col)
        return catalog
    return flux


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


def _get_load_commands(lines):
    """yields each load command from the output of otool -l"""
    a = 1
    for ln, line in enumerate(lines):
        if line.startswith('Load command'):
            if a < ln:
                yield lines[a:ln]
            a = ln
    yield lines[a:]


def prepare_metadata(metadata):
    """prepare a key/value list of metadata for the request. The metadata
       object that comes in is only parsed one level.
    """
    pairs = {'metadata': {'items': [{'key': 'client', 'value': 'sregistry'}]}}
    for key, val in metadata.items():
        if not isinstance(val, dict) and not isinstance(val, list):
            pairs['metadata']['items'].append({'key': key, 'value': val})
        elif isinstance(val, dict):
            for k, v in val.items():
                if not isinstance(v, dict) and not isinstance(v, list):
                    pairs['metadata']['items'].append({'key': k, 'value': v})
    return pairs


def _merge_subexon_columns(subexons_df):
    """Create the SubexonID/SubexonIDCluster of the merged subexons."""
    merged_id = ''
    merged_protein = ''
    merged_dna = ''
    for index in range(1, subexons_df.shape[0]):
        rowi = subexons_df.iloc[(index - 1), :]
        rowj = subexons_df.iloc[(index), :]
        if not merged_id:
            merged_id = rowi['SubexonIDCluster'] + '_' + rowj[
                'SubexonIDCluster'].split('_')[-1]
        else:
            merged_id = merged_id + '_' + rowj['SubexonIDCluster'].split('_')[
                -1]
        if not merged_protein:
            merged_protein = rowi['SubexonProteinSequence'] + rowj[
                'SubexonProteinSequence']
        else:
            merged_protein = merged_protein + rowj['SubexonProteinSequence']
        if not merged_dna:
            merged_dna = rowi['SubexonSequence'] + rowj['SubexonSequence']
        else:
            merged_dna = merged_dna + rowj['SubexonSequence']
    return merged_id, merged_dna, merged_protein


def _define_enum(enum, prefix):
    """Returns an OAS object corresponding to a protobuf enum"""
    def_name = '.'.join(prefix + (enum.name,))
    return def_name, {'type': 'string', 'enum': enum.enums}


def crps(y_true, y_pred):
    """

    Continuous Ranked Probability Score

    Parameters
    ----------
    y_true: numpy.ndarray
        Targets
    y_pred: numpy.ndarray
        Class predictions (0 or 1 values only)

    Returns
    ------
    score: float
        Continuous Ranked Probability Score score

    References
    ----------
    .. [1] https://www.kaggle.com/wiki/ContinuousRankedProbabilityScore
    .. [2] http://journals.ametsoc.org/doi/pdf/10.1175/1520-0434%282000%29015%3C0559%3ADOTCRP%3E2.0.CO%3B2

    """


def _get_file_descriptor(obj):
    """ Get the file descriptor, if the object has one.

        :param obj: The object expected to be a file-like object.
        :return: The file descriptor iff the file supports it; otherwise
            ``None``.

        The object may be a non-file object. It may also be a
        file-like object with no support for a file descriptor. In
        either case, return ``None``.
        """
    file_descriptor = None
    if hasattr(obj, 'fileno'):
        try:
            file_descriptor = obj.fileno()
        except ValueError:
            pass
    return file_descriptor


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 strplural(n, name, nonumber=False, s=''):
    """
    Returns the plural or singular of a string

    Parameters
    ----------
    n : integer
        The plural or singular is based on this number.
    name : string
        String for which a plural is requested.
    nonumber : boolean
        If true, don't prepend the number.
    s : string
        String to be appended if n > 0

    Examples
    --------
    >>> strplural(0, 'cat')
    'no cat'
    >>> strplural(1, 'cat')
    '1 cat'
    >>> strplural(2, 'cat')
    '2 cats'
    >>> strplural(2, 'cat', nonumber=True)
    'cats'
    >>> animals = ['cat', 'dog']
    >>> strplural(len(animals), 'animal', s=': ') + ', '.join(animals)
    '2 animals: cat, dog'
    >>> strplural(0, 'animal', s=':')
    'no animal'

    """
    if n == 0:
        return ('' if nonumber else 'no ') + name
    elif n == 1:
        return ('' if nonumber else '1 ') + name + s
    else:
        return ('' if nonumber else str(n) + ' ') + name + 's' + s


def xwt(wcoefs1, wcoefs2):
    """Cross wavelet transform for 2 sets of coefficients"""
    return wcoefs1 * wcoefs2.conjugate()


@classmethod
def getVariables(class_, tool):
    """Returns Javascript variables storing translated texts used in forms
           and popups."""
    r = ['var wrongTextInput="%s none";' % tool.config.ui.wrongTextColor]
    for label in class_.variables:
        r.append('var %s="%s";' % (label, tool.translate(label)))
    return '<script>%s</script>' % '\n'.join(r)


def typed_input(prompt1, constructor, prompt2=None, default=None):
    """Get input and convert it to a given type.
       prompt1 should be an initial prompt for the user
       constructor should be a callable that converts a string
         to a value of the desired type or raises ValueError
       prompt2, if provided, should be a second prompt to use when
         the user provides an unacceptable value
       default, if provided, should be a default value to use when the
         user provides no input
    """
    if not prompt2:
        prompt2 = prompt1
    prompt = prompt1
    val = None
    while val is None:
        try:
            s = input(prompt)
            if not s and default is not None:
                val = default
            else:
                val = constructor(s)
        except ValueError:
            prompt = prompt2
            continue
    return val


def flops_tanh(module, input, output):
    """FLOPs estimation for `torch.nn.Tanh`"""
    return input.numel() * 6


def append_mids(mids1, mids2):
    """used when we have two lists of mids. Joins these two """
    for i in range(len(mids2[0])):
        emu = mids2[0][i]
        mid = mids2[1][i]
        if not emu in mids1[0]:
            mids1[0].append(emu)
            mids1[1].append(mid)
    return mids1


def get_limit():
    """
    Canned response for limits for servers. Returns only the absolute limits
    """
    return {'limits': {'absolute': {'maxServerMeta': 40, 'maxPersonality':
        5, 'totalPrivateNetworksUsed': 0, 'maxImageMeta': 40,
        'maxPersonalitySize': 1000, 'maxSecurityGroupRules': -1,
        'maxTotalKeypairs': 100, 'totalCoresUsed': 5, 'totalRAMUsed': 2560,
        'totalInstancesUsed': 5, 'maxSecurityGroups': -1,
        'totalFloatingIpsUsed': 0, 'maxTotalCores': -1,
        'totalSecurityGroupsUsed': 0, 'maxTotalPrivateNetworks': 3,
        'maxTotalFloatingIps': -1, 'maxTotalInstances': 200,
        'maxTotalRAMSize': 256000}}}


def _taper_stream(tr, taper_buffer):
    """ Taper the stream, return new stream """
    start = tr.stats.starttime
    end = tr.stats.endtime
    dur = end - start
    buffer = taper_buffer
    tr.taper(type='hann', max_percentage=0.05, max_length=dur * buffer)
    return tr


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

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


def str_list_from_data(data):
    """Turn data into a str generator."""
    for line in data.split('\n'):
        yield line


def ndo_double(data, n):
    """mimic of gmx_fio_ndo_double in gromacs"""
    return [data.unpack_double() for i in range(n)]


def calculate_expected_value(DataFrame, predicted_variable,
    probability_variable, ev_variable='EV'):
    """
    ev = predicted_value * probability

    Parameters
    ----------
    DataFrame:
    predicted_variable:
    probability_variable:

    Returns
    -------
    DataFrame

    """
    DataFrame[ev_variable] = DataFrame[predicted_variable] * DataFrame[
        probability_variable]
    return DataFrame


def set_messaging_procedures(s_gui_flag):
    """
	2017_05_31. This def was added in order to
	control the GUI messaging, and limit it to
	the processes that call def mymain from
	the GUI-based program.  Console based calls
	will have the flag set to "False."
	"""
    global ACTIVATE_GUI_MESSAGING
    if s_gui_flag == 'True':
        global GUIERR
        global GUIINFO
        ACTIVATE_GUI_MESSAGING = True
        from agestrucne.pgguiutilities import PGGUIErrorMessage
        from agestrucne.pgguiutilities import PGGUIInfoMessage
        GUIERR = PGGUIErrorMessage
        GUIINFO = PGGUIInfoMessage
    elif s_gui_flag == 'False':
        ACTIVATE_GUI_MESSAGING = False
    else:
        s_msg = ('In pgdriveneestimator, def set_messaging_procedures, ' +
            'the program found an unknown value for the ' +
            'flag that indicates whether to use GUI ' + 'messaging: ' +
            s_gui_flag + '.')
        raise Exception(s_msg)
    return


def _isProcessRunningOnWindows(pid):
    """
    Enumerates active processes as seen under windows Task Manager on Win
    NT/2k/XP using PSAPI.dll (new api for processes) and using ctypes.Use it as
    you please.

    Based on information from
    http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q175030&ID=KB;EN-US;Q175030

    By Eric Koome email ekoome@yahoo.com
    license GPL

    (adapted from code found at
    http://code.activestate.com/recipes/305279-getting-process-information-on-windows/)
    """
    from ctypes import windll, c_ulong, sizeof, byref
    psapi = windll.psapi
    arr = c_ulong * 256
    list_of_pids = arr()
    cb = sizeof(list_of_pids)
    cb_needed = c_ulong()
    psapi.EnumProcesses(byref(list_of_pids), cb, byref(cb_needed))
    number_of_pids = int(cb_needed.value / sizeof(c_ulong()))
    pid_list = list(list_of_pids)[:number_of_pids]
    return int(pid) in pid_list


def upcase(string):
    """Return an uppercase version of the string.

    Used for the type argument in argparse/
    """
    return string.upper()


def get_related_model_fields(model, rel, is_foreign_key):
    """通过model下rel对象获取相关字段或关联属性"""
    if (is_foreign_key and rel.field.model._meta.concrete_model == model.
        _meta.concrete_model):
        return rel.field, rel.get_related_field()
    return rel.get_related_field(), rel.field


def get_route_name(route):
    """Returns route name."""
    name = route.split('/', 1)[-1]
    return name


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 coerce_single_line_str(value):
    """
    Multiline strings have two options:

        1. Preserve new lines with the back slash:

            value = ""\"A new value                 and something else                 to boot.
            ""\"

            A new value
            and something else
            to boot.

        2. Preserve left spacing with the pipe:

            value = ""\"A new value                 |   it's true.""\"

           A new value
              it's true.

    """


def accept_lit(char, buf, pos):
    """Accept a literal character at the current buffer position."""
    if pos >= len(buf) or buf[pos] != char:
        return None, pos
    return char, pos + 1


def parse_boolean(element):
    """parser for vRa data of boolean type

    Args:
        element (dict): vRa data

    Returns:
        tuple: key, value of vRa data
    """
    return element['key'], bool(element['value']['value'])


def _remove_items(items, text):
    """Remove each item from the text."""
    for item in items:
        text = text.replace(item, ' ')
    return text


def delete_tags(ResourceId=None, TagKeys=None):
    """
    Deletes tags from a WorkSpace.
    See also: AWS API Documentation

    :example: response = client.delete_tags(
        ResourceId='string',
        TagKeys=[
            'string',
        ]
    )

    :type ResourceId: string
    :param ResourceId: [REQUIRED]
            The resource ID of the request.

    :type TagKeys: list
    :param TagKeys: [REQUIRED]
            The tag keys of the request.
            (string) --

    :rtype: dict
    :return: {}

    """
    pass


def allow_memory_usage_verifications():
    """
    Should memory usage verifications be performed?

    :return: boolean.
    """
    return False


@staticmethod
def trades(data, *args, **kwargs):
    """
        Returns list of trades in format [ts, price, size, side]
        ex.:
            [['1480941692', '0.014', '10', 'sell'],
            ['1480941690', '0.013', '0.66', 'buy'],
            ['1480941688', '0.012', '3', 'buy']]
        :param data: requests.response() obj
        :param args:
        :param kwargs:
        :return: list
        """
    return data


def update_buffers_with_data(data, buffers, byte_pattern, channel_indexes):
    """
    Updates buffers with information from data. Returns nothing, modifies
    buffers in-place.
    """
    trimmed_pattern = byte_pattern[0:len(data)]
    for i in channel_indexes:
        buf = buffers[i]
        buf.buffer = data[trimmed_pattern == i]
        buf.buffer.dtype = buf.channel.dtype
        old_slice = buf.channel_slice
        buf.channel_slice = slice(old_slice.stop, old_slice.stop + len(buf.
            buffer))


def stop_rt_server(serverp):
    """ Stops our own instance of the server. """
    if serverp is not None:
        serverp.terminate()