def trace_realign_region(row, read_cigar, read_start):
    """
    The function is used to trace the rdp and ci at the border of realign region and return a dict
    """
    realn_start_t = read_cigar.trace_ci_rdp(start_ci=(0, 0), start_pos=
        read_start, end_pos=row['realign_start'], start_rdp=0)
    if not realn_start_t[2]:
        raise Exception('Error: cannot trace to the realign border', row)
    realn_end_t = read_cigar.trace_ci_rdp(start_ci=realn_start_t[0],
        start_pos=row['realign_start'], end_pos=row['realign_end'],
        start_rdp=realn_start_t[1])
    if not realn_end_t[2]:
        raise Exception('Error: cannot trace to the realign border', row)
    return {'realign_start_ci': realn_start_t[0], 'realign_end_ci':
        realn_end_t[0], 'realign_start_rdp': realn_start_t[1],
        'realign_end_rdp': realn_end_t[1]}


def get_gcp_stats():
    """Retrieve stats, such as function timings."""
    from cloudaux.gcp.decorators import _GCP_STATS
    return _GCP_STATS


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 stream_succeeded(stream):
    """stream has succeeded"""


def pdmerge_respeta_tz(func_merge, tz_ant=None, *args, **kwargs):
    """
    Programación defensiva por issue: pandas BUG (a veces, el index pierde el tz):
        - issue #7795: concat of objects with the same timezone get reset to UTC;
        - issue #10567: DataFrame combine_first() loses timezone information for datetime columns
            https://github.com/pydata/pandas/issues/10567
    :param tz_ant: TZ de referencia para establecerlo al final si se ha perdido en la operación
    :param func_merge: puntero a función que realiza la operación de merge / join / combine / etc.
    :param args: argumentos para func_merge
    :param kwargs: argumentos para func_merge
    :return: dataframe_merged con TZ anterior
    """
    df_merged = func_merge(*args, **kwargs)
    if tz_ant is not None and tz_ant != df_merged.index.tz:
        df_merged.index = df_merged.index.tz_convert(tz_ant)
    return df_merged


def create_link(url, title):
    """ Create a link for slack payload. """
    if not url:
        return title
    return '<{url}|{title}>'.format(url=url, title=title)


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


@staticmethod
def resolve(config, config_as_default=False):
    """
        Resolves an "options" configuration section from component configuration parameters.

        :param config: configuration parameters

        :param config_as_default: (optional) When set true the method returns the entire parameter
                                  set when "options" section is not found. Default: false

        :return: configuration parameters from "options" section
        """
    options = config.get_section('options')
    if len(options) == 0 and config_as_default:
        options = config
    return options


def extrude_edges_move(MESH_OT_extrude_edges_indiv=None,
    TRANSFORM_OT_translate=None):
    """Extrude edges and move result

    :param MESH_OT_extrude_edges_indiv: Extrude Only Edges, Extrude individual edges only
    :param TRANSFORM_OT_translate: Translate, Translate (move) selected items
    """
    pass


def pg_rollback(dbh):
    """Rollback a transaction"""
    dbh.rollback()


def _prod(iterable):
    """
    Product of a list of numbers.
    Faster than np.prod for short lists like array shapes.
    """
    product = 1
    for x in iterable:
        product *= x
    return product


def uniq(lst):
    """Build a list with uniques consecutive elements in the argument.

        >>> uniq([1,1,2,2,2,3])
        [1,2,3]
        >>> uniq([0,1,1,2,3,3,3])
        [0,1,2,3]
    """
    assert len(lst) > 0
    uniq = [lst[0]]
    for i in range(1, len(lst)):
        if lst[i] != lst[i - 1]:
            uniq.append(lst[i])
    return uniq


def _get_container_root(container_name=None):
    """ /container_name/ """
    return '/{}/'.format(container_name) if container_name else '/'


def apl(node, x, function):
    """ Evaluates a function on the symbol x at run time.

            Parameters
            ----------
            function : callable or string.
                if a string is provided for the evaluation, x is the variable.
                if a function is provided, it shall be function(x)

        """
    if hasattr(function, '__call__'):
        return dict(y=function(x))
    else:
        from builtins import eval
        return dict(y=eval(function, dict(x=x)))


@classmethod
def highlight(cls, msec=2000):
    """Draws QLabels indexing each Viewport. These indices can be used to
        with :method:`get` to return a corresponding Viewport object."""
    for viewport in cls.iter():
        if viewport.widget.isVisible():
            viewport.highlight(msec)


@classmethod
def create_from_import(cls, data):
    """
        Create a new instance of the model based on data that comes from the Zou
        API.
        """
    if 'type' in data:
        del data['type']
    previous_data = cls.get(data['id'])
    if previous_data is None:
        return cls.create(**data)
    else:
        previous_data.update(data)
        return previous_data


@classmethod
def get_or_create(cls, kwargs=None, **filtered_arguments):
    """
        This will retrieve the item from the database for the parameters that
        are not none and are required by __init__
        If it is not in the database then it will create it.
        If it is in the database then it will update it with
        values that are not None
        :param kwargs:             dict of the parameters that
                                   don't have to be unique
        :param filtered_arguments: dict of the parameters that
                                   need to be unique
        :return:                   obj of the model created or updated
        """
    instance = cls.query.filter_by(**filtered_arguments).first()
    if not instance:
        kwargs = kwargs or {}
        kwargs.update(filtered_arguments)
        instance = cls(**kwargs)
    elif kwargs:
        for k in kwargs:
            try:
                if kwargs[k] is not None and kwargs[k] != getattr(instance,
                    k, kwargs[k]):
                    setattr(instance, k, kwargs[k])
            except Exception as e:
                setattr(instance, k, kwargs[k])
    return instance


def _capitalize(name: str):
    """ Capitalize the first letter of the name, e.g. for use as an ASP variable """
    return name.capitalize()


def list_aliases(FunctionName=None, FunctionVersion=None, Marker=None,
    MaxItems=None):
    """
    Returns list of aliases created for a Lambda function. For each alias, the response includes information such as the alias ARN, description, alias name, and the function version to which it points. For more information, see Introduction to AWS Lambda Aliases .
    This requires permission for the lambda:ListAliases action.
    See also: AWS API Documentation

    Examples
    This operation retrieves a Lambda function's aliases
    Expected Output:

    :example: response = client.list_aliases(
        FunctionName='string',
        FunctionVersion='string',
        Marker='string',
        MaxItems=123
    )

    :type FunctionName: string
    :param FunctionName: [REQUIRED]
            Lambda function name for which the alias is created. Note that the length constraint applies only to the ARN. If you specify only the function name, it is limited to 64 characters in length.

    :type FunctionVersion: string
    :param FunctionVersion: If you specify this optional parameter, the API returns only the aliases that are pointing to the specific Lambda function version, otherwise the API returns all of the aliases created for the Lambda function.

    :type Marker: string
    :param Marker: Optional string. An opaque pagination token returned from a previous ListAliases operation. If present, indicates where to continue the listing.

    :type MaxItems: integer
    :param MaxItems: Optional integer. Specifies the maximum number of aliases to return in response. This parameter value must be greater than 0.

    :rtype: dict
    :return: {
        'NextMarker': 'string',
        'Aliases': [
            {
                'AliasArn': 'string',
                'Name': 'string',
                'FunctionVersion': 'string',
                'Description': 'string'
            },
        ]
    }

    """
    pass


@staticmethod
def _get_test_callable_name(test):
    """
        Get the name of the test callable from the test.

        :param test:
            The test that has raised an error or succeeded
        :type test:
            :class:`nose.case.Test` or :class:`pytest.Item`
        :return:
            The name of the test callable that is being run by the test
        :rtype:
            `unicode`
        """
    raise NotImplementedError


def calculate_temperature_equivalent(temperatures):
    """
    Calculates the temperature equivalent from a series of average daily temperatures
    according to the formula: 0.6 * tempDay0 + 0.3 * tempDay-1 + 0.1 * tempDay-2

    Parameters
    ----------
    series : Pandas Series

    Returns
    -------
    Pandas Series
    """
    ret = 0.6 * temperatures + 0.3 * temperatures.shift(1
        ) + 0.1 * temperatures.shift(2)
    ret.name = 'temp_equivalent'
    return ret


@classmethod
def get_certbot_paths(cls, domain):
    """Returns a tuple of paths for files (certificates_chain, private_key)
        from Certbot https://certbot.eff.org

        Those paths can be used to pass into Socket initializer.

        .. note:: If files not found empty strings are returned.

        :param str domain: Domain name to get filepaths for.

        :rtype: tuple[str, str]

        """
    from pathlib import Path
    certs_root = Path('/etc/letsencrypt/live/')
    certs_chain = certs_root / domain / 'fullchain.pem'
    certs_private = certs_root / domain / 'privkey.pem'
    if certs_chain.exists() and certs_private.exists():
        return str(certs_chain), str(certs_private)
    return '', ''


def int_from_rgb(rgb):
    """Return an int in the range [0, 0xffffff] converted from an RGB tuple."""
    return (round(rgb[0] * 255) << 16) + (round(rgb[1] * 255) << 8) + round(
        rgb[2] * 255)


def resource_from_cache_prefix(resource, cache):
    """
    Combine the resource name with the cache prefix (if any)
    """
    if getattr(cache, 'key_prefix', None):
        name = '{} {}'.format(resource, cache.key_prefix)
    else:
        name = resource
    return name.lower()


@classmethod
def _create(cls, model_class, *args, **kwargs):
    """Create an instance of the model, and save it to the database."""
    if cls._meta.django_get_or_create:
        return cls._get_or_create(model_class, *args, **kwargs)
    manager = cls._get_manager(model_class)
    return manager.create(*args, **kwargs)


def lock():
    """Lock the active strip so that it can’t be transformed

    """
    pass


def save_obj_(obj, request):
    """
        django接收request参数, 单表保存
        param: obj, django models object
        param: request, django request
    """
    fields = obj._meta.fields
    for field in fields:
        field_name = field.name
        value = request.POST.get(field_name, '')
        if value:
            obj.__setattr__(field_name, value)
        else:
            value = request.FILES.get(field_name, '')
            if value:
                obj.__setattr__(field_name, value)
    obj.save()


@classmethod
def from_app_role(cls, url, path, role_id, secret_id):
    """Constructor: use AppRole authentication to read secrets from a Vault path

        See https://www.vaultproject.io/docs/auth/approle.html

        Args:
            url: Vault url
            path: Vault path where secrets are stored
            role_id: Vault RoleID
            secret_id: Vault SecretID
        """
    token = cls._fetch_app_role_token(url, role_id, secret_id)
    source_dict = cls._fetch_secrets(url, path, token)
    return cls(source_dict, url, path, token)


def height_from_height_elbow(segment_length):
    """
    Calculates body height based on the height of the elbows from the ground

    args:
        segment_length (float): height of the elbows

    Returns:
        float: total body height
    """
    if segment_length <= 0:
        raise ValueError('segment_length must be > 0')
    return segment_length / 0.63


def smartAppend(table, name, value):
    """
	helper function for apppending in a dictionary
	"""
    if name not in list(table.keys()):
        table[name] = []
    table[name].append(value)


def _identity(x):
    """Perform a simple identity function."""
    return x


def neg_imag(data):
    """
    Negate imaginary data
    """
    data.imag = -data.imag
    return data


@staticmethod
def explode(s):
    """ Preprocess sample for vectorizers
        :param s: Sample instance
        :return:
        """
    raise NotImplementedError


def check_stability_of_rearticulated_pitch(counterpoint_continuation:
    'LineElement', movement: int, **kwargs) ->bool:
    """
    Check that a pitch to be rearticulated (repeated) is stable.

    :param counterpoint_continuation:
        current continuation of counterpoint line
    :param movement:
        melodic interval (in scale degrees) for line continuation
    :return:
        indicator whether a continuation is in accordance with the rule
    """
    if movement != 0:
        return True
    return counterpoint_continuation.scale_element.is_from_tonic_triad


@classmethod
def from_excel(cls, filename: str) ->dict:
    """Constructs a dictionary of sections, keyed by the section.ids, from an Excel workbook."""
    xls = cls.get_xls(filename)
    sections = cls.from_df(xls['sections'])
    return sections


def diff(prev_snapshot, next_snapshot):
    """Return a dict containing changes between two snapshots."""
    changes = {}
    for path in (set(prev_snapshot.keys()) | set(next_snapshot.keys())):
        if path in prev_snapshot and path not in next_snapshot:
            changes[path] = 'Deleted'
        elif path not in prev_snapshot and path in next_snapshot:
            changes[path] = 'Created'
        else:
            prev_mtime = prev_snapshot[path]
            next_mtime = next_snapshot[path]
            if next_mtime > prev_mtime:
                changes[path] = 'Changed'
    return changes


def parse_slice(ds_slice):
    """
    Parse dataset slice

    Parameters
    ----------
    ds_slice : tuple | int | slice | list
        Slice to extract from dataset

    Returns
    -------
    ds_slice : tuple
        slice for axis (0, 1)
    """
    if not isinstance(ds_slice, tuple):
        ds_slice = ds_slice,
    return ds_slice


def set_bit(v, index, x):
    """Set the index:th bit of v to 1 if x is trur, else to 0, and return the new value."""
    mask = 1 << index
    v &= ~mask
    if x:
        v |= mask
    return v


def styles_de_polices(cls):
    """retourne le dictionnaire des styles de polices tortue disponibles"""
    return cls._styles_de_polices


def p_bloqueE(p):
    """bloqueE : estatuto bloqueE
               | empty
    """


def parse_zipcode(zipcode):
    """
    Take a zipcode and returns a split out zipcode and the +4 for the post office.

    :param zipcode: Zipcode
    :return: zipcode, zipcodeplus
    """
    zipcode = str(zipcode)
    plus = None
    if len(str(zipcode)) == 9:
        try:
            plus = int(zipcode[5:])
        except ValueError:
            plus = 0
        zipcode = zipcode[:5]
    try:
        zipcode = int(zipcode)
    except ValueError:
        return None, None
    return zipcode, plus


def p_semi_stmt_list(p):
    """semi_stmt_list : SEMI simple_stmt stmt_list"""
    p[0] = p[2] + p[3]


def eoy(date, offset=0):
    """
    Returns the end of the year at a given offset
    """
    return type(date)(date.year + offset, 12, 31)


def remove_list_redundancies(l):
    """
    Used instead of list(set(l)) to maintain order
    Keeps the last occurance of each element
    """
    reversed_result = []
    used = set()
    for x in reversed(l):
        if x not in used:
            reversed_result.append(x)
            used.add(x)
    reversed_result.reverse()
    return reversed_result


def array_reverse_order_changed_locations(move):
    """Aid function for delta evaluation.

    Works with the array_swap move type.
    This function returns the locations who would have an altered evaluation
    value due to the move.

    Parameters
    ----------
    move : tuple of int
        A tuple of 2 ints that represents a single unique move.

    Returns
    -------
    range
        A range containing the locations that would have an altered evaluation
        value due to the move.

    Examples
    --------
    Some simple examples to demonstrate the behaviour:

    .. doctest::

        >>> from lclpy.evaluation.deltaeval.delta_qap \\
        ...     import array_reverse_order_changed_locations \\
        ...         as changed_locations
        ... # tests
        >>> changed_locations((4, 5))
        range(4, 6)
        >>> changed_locations((4, 9))
        range(4, 10)
        >>> changed_locations((0, 8))
        range(0, 9)

    """
    return range(move[0], move[1] + 1)


def let(namespace, **args):
    """allows local variable assignment, and macro blocks"""
    namespace.update(args)
    return ''


def set_pythranize_at_import(value=True):
    """Control the "pythranize_at_import" mode"""
    global _PYTHRANIZE_AT_IMPORT
    _PYTHRANIZE_AT_IMPORT = value


def convert_logs(apps, schema_editor):
    """
    Adds a unit to users who have imperial units in the profile
    """
    WorkoutLog = apps.get_model('manager', 'WorkoutLog')
    UserProfile = apps.get_model('core', 'UserProfile')
    for profile in UserProfile.objects.filter(weight_unit='lb'):
        WorkoutLog.objects.filter(user=profile.user).update(weight_unit=2)


@classmethod
def create_explorer(cls, *args, **kwargs):
    """
        Creates and shows and ObjectExplorer window.

        The *args and **kwargs will be passed to the ObjectExplorer constructor

        A (class attribute) reference to the browser window is kept to prevent
        it from being garbage-collected.
        """
    object_explorer = cls(*args, **kwargs)
    object_explorer.exec_()
    return object_explorer


def cat_group(dfx, kpix, n_group=10):
    """
    Category Reduction for Categorical Variables

    Args
    ----

    dfx : dataframe
        The inputs data dataframe.

    kpix : string
        The column of the feature.

    n_group : int, optional (default = 10)
        The number of top category values to be remained, other category values will be put into "Other".

    Returns
    -------
    The transformed categorical feature value list.
    """
    if dfx[kpix].nunique() > n_group:
        top = dfx[kpix].isin(dfx[kpix].value_counts().index[:n_group])
        dfx.loc[~top, kpix] = 'Other'
        return dfx[kpix].values
    else:
        return dfx[kpix].values


def get_service_type(f):
    """Retrieves service type from function."""
    return getattr(f, 'service_type', None)


def getDiscoItems(requestor, target, nodeIdentifier=''):
    """
        Get contained items for this entity, node.

        @param requestor: The entity the request originated from.
        @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param target: The target entity to which the request is made.
        @type target: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: The optional identifier of the node at this
                               entity to retrieve the identify and features of.
                               The default is C{''}, meaning the root node.
        @type nodeIdentifier: C{unicode}
        """


def biblio_hooks(biblio):
    """
    Part to correct part of the scrobbled tracks for example some with a wrong artist or title
    This part is really specific to my library but can be adapted if needed
    """
    for titre in biblio['-m-']:
        if titre in biblio['m']:
            biblio['m'][titre]['playcount'] += biblio['-m-'][titre]['playcount'
                ]
        else:
            biblio['m'][titre] = {}
            biblio['m'][titre]['playcount'] = biblio['-m-'][titre]['playcount']
            biblio['m'][titre]['time'] = biblio['-m-'][titre]['time']
    for titre in biblio['arthur h']:
        if titre == 'mystic rhumba':
            biblio['arthur h']['mystic rumba'] = biblio['arthur h'][titre]
            break
    return biblio


def cx2x(cx, e):
    """Transform from *x* index value to *x* index value, using the
    *e.css('cw')* (column width) as column measure."""
    if cx is None:
        x = 0
    else:
        x = e.parent.pl + cx * (e.css('cw', 0) + e.gw)
    return x


def psi_Ca_MgOH_HCO3_HMW84(T, P):
    """c-c'-a: calcium magnesium-hydroxide bicarbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@staticmethod
def decompress(tensor, ctx):
    """Decompress the tensor with the given context."""
    pass


def _handle_column_list(spec, property_name):
    """Convert ColumnList to a dictionary."""
    return {property_name: spec}


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

        :param PaperDocMentionType val:
        :rtype: EventType
        """
    return cls('paper_doc_mention', val)


def delete_till_end_of_line(text):
    """delete till beginning of line"""
    if text.find('\n') == -1:
        return ''
    return text[text.find('\n'):]


@classmethod
def find_model(cls, name):
    """Find subclass model by name."""
    sub_model = cls.registry.get(name)
    if sub_model and issubclass(sub_model, cls):
        return sub_model
    return None


def get_tracklengths_stats():
    """Return statistics of the model track length distribution."""
    stDev = 0.0
    skewness = 0.0
    kurtosis = 0.0
    mean = 0.0
    stderror = 0.0
    return {'Mean Track Length': mean, 'Standard Deviation': stDev,
        'Standard Error': stderror, 'Skewness': skewness, 'Kurtosis': kurtosis}


def cross(environment, book, row, sheet_source, column_source, column_key):
    """
    Returns a single value from a column from a different dataset, matching by the key.
    """
    a = book.sheets[sheet_source]
    return environment.copy(a.get(**{column_key: row[column_key]})[
        column_source])


def _prod(iterable):
    """
    Product of a list of numbers.
    Faster than np.prod for short lists like array shapes.
    """
    product = 1
    for x in iterable:
        product *= x
    return product


def update_package_data(distribution):
    """update build_py options to get package_data changes"""
    build_py = distribution.get_command_obj('build_py')
    build_py.finalize_options()


def get_rates(fluxes, metabolite):
    """ Calculate the rates of the individual reactions

    Parameters
    ----------
    fluxes: dict or pandas.Series
    metabolite: GEMEditor.model.classes.cobra.Metabolite

    Returns
    -------
    rates: dict,
        Partial rates of the individual reactions
    """
    rates = dict()
    for reaction in metabolite.reactions:
        rates[reaction] = float(fluxes[reaction.id] * reaction.metabolites[
            metabolite])
    return rates


def foreground_acc(inp, targ, bkg_idx=0, axis=1):
    """Computes non-background accuracy for multiclass segmentation"""
    targ = targ.squeeze(1)
    mask = targ != bkg_idx
    return (inp.argmax(dim=axis)[mask] == targ[mask]).float().mean()


def filetypes():
    """Get supported text filetypes for workspace import."""
    return {'ini': 'Nemoa Workspace Description'}


def filter_process_by_name(name):
    """Filter process by process name."""
    if name in ['cp', 'tee', 'date', 'Null', 'recon-all']:
        return True
    return False


def get_item_properties(item, fields, mixed_case_fields=None, formatters=None):
    """Return a tuple containing the item properties.

    :param item: a single item resource (e.g. Server, Tenant, etc)
    :param fields: tuple of strings with the desired field names
    :param mixed_case_fields: tuple of field names to preserve case
    :param formatters: dictionary mapping field names to callables
       to format the values
    """
    row = []
    if mixed_case_fields is None:
        mixed_case_fields = []
    if formatters is None:
        formatters = {}
    for field in fields:
        if field in formatters:
            row.append(formatters[field](item))
        else:
            if field in mixed_case_fields:
                field_name = field.replace(' ', '_')
            else:
                field_name = field.lower().replace(' ', '_')
            if not hasattr(item, field_name) and isinstance(item, dict):
                data = item[field_name]
            else:
                data = getattr(item, field_name, '')
            if data is None:
                data = ''
            row.append(data)
    return tuple(row)


def restore_from_trash(modeladmin, request, queryset):
    """
    Restores all objects in a query.
    """
    del modeladmin, request
    for item in queryset.all():
        item.restore()


def ode1():
    """
    First order ode from Learning Scipy for Numerical and Scientific computing
    """
    import numpy
    from scipy.integrate import ode
    f = lambda t, y: -20 * y
    actual_solution = lambda t: numpy.exp(-20 * t)
    dt = 0.1
    solver = ode(f).set_integrator('dop853')
    solver.set_initial_value(1, 0)
    while solver.successful() and solver.t <= 1 + dt:
        print(solver.t, solver.y, actual_solution(solver.t))
        solver.integrate(solver.t + dt)


@classmethod
def get_business_non_required_fields(cls):
    """
        get ``set`` of ``non required fields`` for
        :attr:`BUSINESS_TYPE`.

        Returns:
            ``set`` of fields
        """
    return cls.get_non_required_fields()


@staticmethod
def exists(request_handler, name) ->bool:
    """Check whether a report with the name (case sensitive) exists

        :param request_handler: :class:`fineract.handlers.RequestHandler`
        :param name: Report name
        :return: bool
        """
    data = request_handler.make_request('GET', '/reports')
    for item in data:
        if item['reportName'] == name:
            return True
    return False


def parse_version(*args, **kwargs):
    """
    Package resources is a very slow load
    """
    import pkg_resources
    return pkg_resources.parse_version(*args, **kwargs)


@classmethod
def visible_to(klass, user):
    """
        Predicate function to determine whether this list is meaningfully
        visible to this USER
        """
    if len(list(klass.get_member_lists_for_user(user))) > 1:
        return True
    return False


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


def __iter__():
    """iterate over the values that should be returned as the result.

        See IHTTPResponse.setResult.
        """


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 handle_log(log_iter, handler):
    """Call a handler for each item in a log, discarding the return value"""
    for item in log_iter:
        handler(item)


def is_unibipartite(graph):
    """Internal function that returns whether the given graph is a uni-directional
    bipartite graph.

    Parameters
    ----------
    graph : GraphIndex
        Input graph

    Returns
    -------
    bool
        True if the graph is a uni-bipartite.
    """
    src, dst, _ = graph.edges()
    return set(src.tonumpy()).isdisjoint(set(dst.tonumpy()))


def set_code(code):
    """
        Tell the wormhole to use a specific code, either copied from a
        wormhole that used ``allocate_code``, or created out-of-band by
        humans (and given to ``set_code`` on both wormholes).

        Any Deferreds returned by ``get_code()`` will be fired as soon as
        this is called.  Only one of generate_code/set_code/input_code may be
        used.

        :return: None
        """


def get_resource_type(policy):
    """
    Return resource type of the policy.
    :param policy: Policy structure.
    :return: Resource type used in policy (database, tag, path).
    """
    if policy['policyType'] != 0:
        raise AttributeError(
            'PolicyType must be 0 to support option expandHiveResourceToHdfs. Policy: {}'
            .format(policy['name']))
    resources = policy['resources']
    if 'database' in resources:
        return 'database'
    if 'tag' in resources:
        return 'tag'
    if 'path' in resources:
        return 'path'
    return 'unknown'


def last_arg_byref(args):
    """Returns the last C argument's value by reference."""
    return args[-1]._obj.value


def gettext_noop(msgid):
    """
    No-operation gettext implementation.

    :param msgid:
        The message not to translate
    :returns:
        msgid itself

    This function should be used (typically aliased as ``N_`` to mark strings
    that don't require translation at the place where they are defined but will
    be translated later on. This is just a hint to the message extraction
    system.
    """
    return msgid


def copy_files(files, dest, copy_or_move):
    """
    Copy a list of files to a directory

    Parameters
    ----------
    files : list of str
        List of paths of files to be copied
    dest : str
        Name of dirctory to which files should be copied
    """
    for f in files:
        copy_or_move(f, dest)


def gelqf(A=None, name=None, attr=None, out=None, **kwargs):
    """LQ factorization for general matrix.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, we compute the LQ factorization (LAPACK *gelqf*, followed by *orglq*). *A*
    must have shape *(x, y)* with *x <= y*, and must have full rank *=x*. The LQ
    factorization consists of *L* with shape *(x, x)* and *Q* with shape *(x, y)*, so
    that:

       *A* = *L* \\* *Q*

    Here, *L* is lower triangular (upper triangle equal to zero) with nonzero diagonal,
    and *Q* is row-orthonormal, meaning that

       *Q* \\* *Q*\\ :sup:`T`

    is equal to the identity matrix of shape *(x, x)*.

    If *n>2*, *gelqf* is performed separately on the trailing two dimensions for all
    inputs (batch mode).

    .. note:: The operator supports float32 and float64 data types only.

    Examples::

       Single LQ factorization
       A = [[1., 2., 3.], [4., 5., 6.]]
       Q, L = gelqf(A)
       Q = [[-0.26726124, -0.53452248, -0.80178373],
            [0.87287156, 0.21821789, -0.43643578]]
       L = [[-3.74165739, 0.],
            [-8.55235974, 1.96396101]]

       Batch LQ factorization
       A = [[[1., 2., 3.], [4., 5., 6.]],
            [[7., 8., 9.], [10., 11., 12.]]]
       Q, L = gelqf(A)
       Q = [[[-0.26726124, -0.53452248, -0.80178373],
             [0.87287156, 0.21821789, -0.43643578]],
            [[-0.50257071, -0.57436653, -0.64616234],
             [0.7620735, 0.05862104, -0.64483142]]]
       L = [[[-3.74165739, 0.],
             [-8.55235974, 1.96396101]],
            [[-13.92838828, 0.],
             [-19.09768702, 0.52758934]]]

    Defined in src/operator/tensor/la_op.cc:L798

    Parameters
    ----------
    A : Symbol
        Tensor of input matrices to be factorized

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

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


def draw3d(atom, **kwargs):
    """ Draw a 3D viewer with this atom highlighted (Jupyter only).

    Args:
        width (int): width of viewer in pixels
        height (int): height of viewer in pixels

    Returns:
        mdt.GeometryViewer: viewer object
    """
    return atom.molecule.draw3d(highlight_atoms=[atom], **kwargs)


def getXMLInteger(elem, tag):
    """
    Return the text within the named tag as an integer.

    Raises an exception if the tag cannot be found or if its textual
    value cannot be converted to an integer.

    Parameters
    ----------

    - elem: the element to search within
    - tag: the name of the tag to look for

    """
    e = elem.find(tag)
    if e is None:
        raise ValueError('Missing %s in %s' % (tag, elem))
    return int(e.text.strip())


def sqlite_sql_search(basedir, sqlstatement, lcclist=None,
    fail_if_sql_invalid=True, incoming_userid=2, incoming_role='anonymous',
    raiseonfail=False, censor_searchargs=False):
    """This runs an arbitrary SQL statement search.

    basedir is the directory where lcc-index.sqlite is located.

    ftsquerystr is string to query against the FTS indexed columns. this is in
    the usual FTS syntax:

    https://www.sqlite.org/fts5.html#full_text_query_syntax

    columns is a list that specifies which columns to return after the query is
    complete.

    conditions is a string in SQL format that applies extra conditions to
    the where statement. This will be parsed and if it contains any non-allowed
    keywords, conditions will be disabled.

   FIXME: this will require an sql parser to do it right.

    """


def int_cast_or_len(i):
    """
  >>> int_cast_or_len(range(10))
  10
  >>> int_cast_or_len('90 foo')
  6
  >>> int_cast_or_len('90')
  90

  """
    try:
        return int(i)
    except ValueError:
        return len(i)
    except TypeError:
        return len(i)


def uniform_mass_mc_eta_log_prior(M_c, eta):
    """
    If :math:`p(m_1, m_2)` is unformly distributed (subject to
    :math:`m_i \\geq m_{\\mathrm{min}}` and
    :math:`m_1 + m_2 \\leq M_{\\mathrm{max}}`), then that implies

    .. math::
       p(\\mathcal{M}_{\\mathrm{c}}, \\eta) =
       \\frac{4}{(M_{\\mathrm{max}} - m_{\\mathrm{min}})^2}
       \\frac{\\mathcal{M}_{\\mathrm{c}}}{\\eta^{6/5} \\sqrt{1 - 4\\eta}}

    This evaluates that function, in the log, neglecting the constant factor
    dealing with the lower and upper mass cutoffs.
    """
    import numpy
    return numpy.log(M_c) - 1.2 * numpy.log(eta) - 0.5 * numpy.log(1.0 -
        4.0 * eta)


def addAgent(agent):
    """Add a new agent to the sandbox."""


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

        :param GroupDeleteType val:
        :rtype: EventType
        """
    return cls('group_delete', val)


def check_mongo(uri=None):
    """Check if mongo db is available in the uri provided"""
    from pymongo import MongoClient
    from pymongo.errors import ServerSelectionTimeoutError
    uri = 'mongodb://localhost:27019' if uri is None else uri
    client = MongoClient(uri, serverSelectionTimeoutMS=300)
    try:
        client.server_info()
        found_database = True
    except ServerSelectionTimeoutError:
        found_database = False
    return found_database


def is_source(seq):
    """Sequence is a Source, if and only if its type is Source."""
    from . import source
    return isinstance(seq, source.Source)


def is_nested_dict(item):
    """ Check if item provides a nested dictionary"""
    item = next(iter(item.values()))
    return isinstance(item, dict)


def update_last_ip(device, request):
    """
    updates ``last_ip`` if necessary
    """
    ip = request.META.get('REMOTE_ADDR')
    management_ip = request.GET.get('management_ip')
    changed = False
    if device.last_ip != ip:
        device.last_ip = ip
        changed = True
    if device.management_ip != management_ip:
        device.management_ip = management_ip
        changed = True
    if changed:
        device.save()


def authenticateWithUsernameAndPassword(username, password):
    """
        Check the username and password against local accounts.

        Returns a tuple of (result, token).
        `result` is `True` if credentials are accepted, False otherwise.
        `token` is None on Unix system and a token handler on Windows.
        """


def localview(frame_selected: bool=True):
    """Toggle display of selected object(s) separately and centered in view

    :param frame_selected: Frame Selected, Move the view to frame the selected objects
    :type frame_selected: bool
    """
    pass


def terminate_job(jobId=None, reason=None):
    """
    Terminates jobs in a job queue. Jobs that are in the STARTING or RUNNING state are terminated, which causes them to transition to FAILED . Jobs that have not progressed to the STARTING state are cancelled.
    See also: AWS API Documentation

    Examples
    This example terminates a job with the specified job ID.
    Expected Output:

    :example: response = client.terminate_job(
        jobId='string',
        reason='string'
    )

    :type jobId: string
    :param jobId: [REQUIRED]
            Job IDs to be terminated. Up to 100 jobs can be specified.

    :type reason: string
    :param reason: [REQUIRED]
            A message to attach to the job that explains the reason for cancelling it. This message is returned by future DescribeJobs operations on the job. This message is also recorded in the AWS Batch activity logs.

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


def _py_expand_short(subsequence, sequence, max_l_dist):
    """Straightforward implementation of partial match expansion."""
    subseq_len = len(subsequence)
    if subseq_len == 0:
        return 0, 0
    scores = list(range(1, subseq_len + 1))
    min_score = subseq_len
    min_score_idx = -1
    for seq_index, char in enumerate(sequence):
        a = seq_index
        c = a + 1
        for subseq_index in range(subseq_len):
            b = scores[subseq_index]
            c = scores[subseq_index] = min(a + (char != subsequence[
                subseq_index]), b + 1, c + 1)
            a = b
        if c <= min_score:
            min_score = c
            min_score_idx = seq_index
        elif min(scores) >= min_score:
            break
    return (min_score, min_score_idx + 1) if min_score <= max_l_dist else (None
        , None)


@classmethod
def get_table_names(cls, inspector, schema):
    """Need to consider foreign tables for PostgreSQL"""
    tables = inspector.get_table_names(schema)
    tables.extend(inspector.get_foreign_table_names(schema))
    return sorted(tables)


def list_to_singleton(args, cls):
    """
    For attributes that are listed as singletons but have values that are
    lists. Replace the list with the first element in the list.

    :param args: The attribute,value pairs as a dictionary
    :param cls: A class instance that can be used to get information about
        the value types for specific attributes.
    :return: A modified attribute,values dictionary
    """
    ci = cls()
    res = {}
    for key, val in args.items():
        if isinstance(val, list):
            try:
                _typ = ci.c_param[key][0]
            except KeyError:
                res[key] = val
            else:
                if isinstance(_typ, list):
                    res[key] = val
                else:
                    res[key] = val[0]
        else:
            res[key] = val
    return res


def _coalesce(*values):
    """
    Return first non-none value.
    Return None if all values are None, or there are no values passed in.

    >>> _coalesce(1, 2)
    1
    >>> _coalesce(None, 2, 3)
    2
    >>> _coalesce(None, None, 3, None, 5)
    3
    """
    for v in values:
        if v is not None:
            return v
    return None


def replace_repetitive_column_names(column_name, buildings):
    """
    Returns column_name _unless_ it's one of a few special cases (building names, PIPE names, NODE names, srf names)
    :param str column_name: the name of the column
    :return: column_name or similar (for repetitive column names)
    """
    if column_name.startswith('srf'):
        column_name = 'srf0'
    if column_name.startswith('PIPE'):
        column_name = 'PIPE0'
    if column_name.startswith('NODE'):
        column_name = 'NODE0'
    if column_name in buildings:
        column_name = buildings[0]
    return column_name


def event_receiver(event_type, details):
    """This is the callback that (in this example) doesn't do much..."""
    print("Recieved event '%s'" % event_type)
    print('Details = %s' % details)


@classmethod
def find_model(cls, name):
    """Find subclass model by name."""
    sub_model = cls.registry.get(name)
    if sub_model and issubclass(sub_model, cls):
        return sub_model
    return None


def d2arcs(d):
    """Convert degrees into arcseconds."""
    return d * 3600.0


def create_domain_entry(domainName=None, domainEntry=None):
    """
    Creates one of the following entry records associated with the domain: A record, CNAME record, TXT record, or MX record.
    See also: AWS API Documentation

    :example: response = client.create_domain_entry(
        domainName='string',
        domainEntry={
            'id': 'string',
            'name': 'string',
            'target': 'string',
            'type': 'string',
            'options': {
                'string': 'string'
            }
        }
    )

    :type domainName: string
    :param domainName: [REQUIRED]
            The domain name (e.g., example.com ) for which you want to create the domain entry.

    :type domainEntry: dict
    :param domainEntry: [REQUIRED]
            An array of key-value pairs containing information about the domain entry request.
            id (string) --The ID of the domain recordset entry.
            name (string) --The name of the domain.
            target (string) --The target AWS name server (e.g., ns-111.awsdns-22.com. ).
            type (string) --The type of domain entry (e.g., SOA or NS ).
            options (dict) --The options for the domain entry.
            (string) --
            (string) --

    :rtype: dict
    :return: {
        'operation': {
            'id': 'string',
            'resourceName': 'string',
            'resourceType': 'Instance'|'StaticIp'|'KeyPair'|'InstanceSnapshot'|'Domain'|'PeeredVpc',
            'createdAt': datetime(2015, 1, 1),
            'location': {
                'availabilityZone': 'string',
                'regionName': 'us-east-1'|'us-west-1'|'us-west-2'|'eu-west-1'|'eu-central-1'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'ap-northeast-2'
            },
            'isTerminal': True|False,
            'operationDetails': 'string',
            'operationType': 'DeleteInstance'|'CreateInstance'|'StopInstance'|'StartInstance'|'RebootInstance'|'OpenInstancePublicPorts'|'PutInstancePublicPorts'|'CloseInstancePublicPorts'|'AllocateStaticIp'|'ReleaseStaticIp'|'AttachStaticIp'|'DetachStaticIp'|'UpdateDomainEntry'|'DeleteDomainEntry'|'CreateDomain'|'DeleteDomain'|'CreateInstanceSnapshot'|'DeleteInstanceSnapshot'|'CreateInstancesFromSnapshot',
            'status': 'NotStarted'|'Started'|'Failed'|'Completed',
            'statusChangedAt': datetime(2015, 1, 1),
            'errorCode': 'string',
            'errorDetails': 'string'
        }
    }

    """
    pass


def _validate_names(names):
    """
    Raise ValueError if the `names` parameter contains duplicates.

    Parameters
    ----------
    names : array-like or None
        An array containing a list of the names used for the output DataFrame.

    Raises
    ------
    ValueError
        If names are not unique.
    """
    if names is not None:
        if len(names) != len(set(names)):
            raise ValueError('Duplicate names are not allowed.')


def to_bytes(maybe_bytestring):
    """
    Encode string to bytes.

    Convenience function to do a simple encode('utf-8') if the input is not
    already bytes. Returns the data unmodified if the input is bytes.
    """
    if isinstance(maybe_bytestring, bytes):
        return maybe_bytestring
    else:
        return maybe_bytestring.encode('utf-8')


def make_readable_title(infos):
    """
    Creates a readable title based on the test information.
    """
    sp = [infos['model']]
    if 'problem' in infos:
        sp.append('[{}]'.format(infos['problem']))
    if 'scenario' in infos:
        sp.append('[{}]'.format(infos['scenario']))
    if 'N' in infos:
        sp.append('N={}'.format(infos['N']))
    if 'nf' in infos:
        sp.append('nf={}'.format(infos['nf']))
    if 'opset' in infos:
        sp.append('ops={}'.format(infos['opset']))
    if 'double' in infos:
        if infos['double']:
            sp.append('x64')
    if 'opt' in infos:
        sp.append('[{}]'.format(infos['opt']))
    if 'profile' in infos:
        sp.append('by {}'.format(infos['profile']))
    return ' '.join(sp)


@classmethod
def roots(cls):
    """Get all roots, nodes without parents"""
    return cls.tree.roots()


@staticmethod
def read(reader, _index):
    """
        Reads Zserio varint16 type from the bit stream.

        :param reader: Bit stream from which to read.
        :param _index: Not used.
        """
    return reader.readVarInt16()


def k_row_lengths(ptn, k):
    """ Given a partition, return it's `k`-row-shape.

    This is equivalent to taking the `k`-boundary of the partition and then returning the row-shape of that.  We do *not* discard rows of length 0.  (Section 2.2 of [mem]_)

    EXAMPLES::

        sage: k_row_lengths(Partition([6, 1]), 2)
        [2, 1]

        sage: k_row_lengths(Partition([4, 4, 4, 3, 2]), 2)
        [0, 1, 1, 1, 2]

    ..  SEEALSO::

        :meth:`k_column_lengths`, :meth:`k_boundary`, :meth:`SkewPartition.row_lengths`, :meth:`SkewPartition.column_lengths`
    """
    return ptn.k_boundary(k).row_lengths()


def boto_exception(err):
    """generic error message handler"""
    if hasattr(err, 'error_message'):
        error = err.error_message
    elif hasattr(err, 'message'):
        error = err.message
    else:
        error = '%s: %s' % (Exception, err)
    return error


def set_page_path_collation(apps, schema_editor):
    """
    Treebeard's path comparison logic can fail on certain locales such as sk_SK, which
    sort numbers after letters. To avoid this, we explicitly set the collation for the
    'path' column to the (non-locale-specific) 'C' collation.

    See: https://groups.google.com/d/msg/wagtail/q0leyuCnYWI/I9uDvVlyBAAJ
    """
    if schema_editor.connection.vendor == 'postgresql':
        schema_editor.execute(
            """
            ALTER TABLE wagtailcore_page ALTER COLUMN path TYPE VARCHAR(255) COLLATE "C"
        """
            )


def __init__(A):
    """ServiceLevelCode - a model defined in Swagger"""
    A.discriminator = None


@classmethod
def can_represent(cls, identifier):
    """
        Determines whether this data plugin can represent the given identifier

        :param identifier: Data Identifier. This could be a url, or a filepath
            or a uuid etc.
        :type identifier: string

        :return: bool
        """
    return False


@classmethod
def next_text_version(cls, text):
    """Method which returns next number from the string.

        From string ``build10s`` it returns 11.

        :param str text: Line to search in.
        :return: Next number
        :rtype: int
        """
    return 1 + cls.parse_text_version(text)


def config_emptysection(config, section):
    """
    Create empty configuration section.

    :param config: Configuration dictionary.
    :type config: configparser.ConfigParser

    :param section: Section of ini file to return.
    :type section: str
    """
    if not config.has_section(section):
        config[section] = {}
    return config


@staticmethod
def _setupBoundary(diagonals, freeSurf):
    """
        Function to set up boundary regions for the Seismic FDFD problem
        using the 9-point finite-difference stencil from OMEGA/FULLWV.

        Args:
            diagonals (dict): The diagonal vectors, indexed by appropriate string keys
            freeSurf (tuple): Determines which free-surface conditions are active

        The diagonals are modified in-place.
        """
    keys = list(diagonals.keys())
    pickDiag = lambda x: -1.0 if freeSurf[x] else 1.0
    for key in keys:
        if key is 'BE':
            diagonals[key][:, (0)] = pickDiag(3)
        else:
            diagonals[key][:, (0)] = 0.0
    for key in keys:
        if key is 'BE':
            diagonals[key][:, (-1)] = pickDiag(1)
        else:
            diagonals[key][:, (-1)] = 0.0
    for key in keys:
        if key is 'BE':
            diagonals[key][(0), :] = pickDiag(0)
        else:
            diagonals[key][(0), :] = 0.0
    for key in keys:
        if key is 'BE':
            diagonals[key][(-1), :] = pickDiag(2)
        else:
            diagonals[key][(-1), :] = 0.0


def google_has_height(style):
    """check if the style of the element has the 'height' attribute explicitly defined"""
    if 'height' in style:
        return True
    return False


@staticmethod
def get_proto_fields():
    """ Returns the proto fields used by this algorithm """
    raise NotImplementedError()


@classmethod
def from_fasta(cls, filename, dissolve_length_one_stems=False):
    """
        Return a list of BulgeGraphs from a fasta file.
        """
    with open(filename) as f:
        fasta_text = f.read()
    return cls.from_fasta_text(fasta_text, dissolve_length_one_stems)


def getFields():
    """Return a list of fields to be added to the schema."""


def concept_is_bad(uri):
    """
    Skip concepts that are unlikely to be useful.

    A concept containing too many underscores is probably a long, overly
    specific phrase, possibly mis-parsed. A concept with a colon is probably
    detritus from a wiki.
    """
    return ':' in uri or uri.count('_') >= 3 or uri.startswith('/a/'
        ) or uri.count('/') <= 2


def _siftdown_max(heap, startpos, pos):
    """Maxheap variant of _siftdown"""
    newitem = heap[pos]
    while pos > startpos:
        parentpos = pos - 1 >> 1
        parent = heap[parentpos]
        if parent < newitem:
            heap[pos] = parent
            pos = parentpos
            continue
        break
    heap[pos] = newitem


@classmethod
def from_selector_string(cls, selector_string: str):
    """
        construct the selectors from string

        input:
            - selector string
        """
    selectors = selector_string.split(',')
    return cls(selectors)


def check_dangling_end(read, dangling_sequences):
    """
    given a pysam read object, this function
    checks if a forward read starts with
    the dangling sequence or if a reverse
    read ends with the dangling sequence.
    """
    ds = dangling_sequences
    if 'pat_forw' not in ds or 'pat_rev' not in ds:
        return False
    if not read.is_reverse and read.seq.upper().startswith(ds['pat_forw']):
        return True
    if read.is_reverse and read.seq.upper().endswith(ds['pat_rev']):
        return True
    return False


@classmethod
def find_by_username(cls, username):
    """
        Class function that is called by a process and is looking for the user in the
        database based on the username, and if it finds it, it creates an object of this
        user and returns it
        """
    user = cls.query.filter_by(username=username).first()
    return user


def _colorize(heatmap, colormap):
    """
    Apply the ``colormap`` function to a grayscale
    rank 2 ``heatmap`` array (with float values in interval [0, 1]).
    Returns an RGBA rank 3 array with float values in range [0, 1].
    """
    heatmap = colormap(heatmap)
    return heatmap


def _undefined_op(node):
    """Default case for undefined or free (in terms of FLOPs) operations

    :param node_string: an onnx node

    :return: always 0
    :rtype: `int`
    """
    return 0


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 get_target(module, array):
    """Return target or None"""
    try:
        return array.get_offload(module.params['name'])
    except Exception:
        return None


def pretty_string(value):
    """Reformats any data-type to a formatted string for printing."""
    if value is None:
        value = 'None'
    elif isinstance(value, float):
        value = str(round(value, 2))
    elif isinstance(value, str):
        value = value.replace('_', ' ')
        if value.islower():
            value = value.title()
    else:
        value = str(value)
    return value


def is_tepid(G):
    """
    A Game is tepid if it is numberish, but not a number; that is, it differs from a number by an
    infinitesimal amount.

    Parameters
    ----------
    G : Game
        The Game of interest.

    Returns
    -------
    tepid : bool
        Whether the Game is tepid or not.
    """
    return G.is_numberish and not G.is_number


def get_id(schema):
    """
    Originally ID was `id` and since v7 it's `$id`.
    """
    return schema.get('$id', schema.get('id', ''))


def _name(named):
    """
    Get the name out of an object.  This varies based on the type of the input:
       * the "name" of a string is itself
       * the "name" of None is itself
       * the "name" of an object with a property named name is that property -
         as long as it's a string
       * otherwise, we raise a ValueError
    """
    if isinstance(named, str) or named is None:
        return named
    elif hasattr(named, 'name') and isinstance(named.name, str):
        return named.name
    else:
        msg = "Can't interpret {} as a name or a configuration object"
        raise ValueError(msg.format(named))


@classmethod
def from_date(cls, d):
    """ Abstract class method.

        For instance, ``Month.from_date(datetime.date(2012, 6, 6))`` returns a ``Month(2012, 6)``."""
    raise NotImplementedError


@classmethod
def _create(cls, model_class, *args, **kwargs):
    """Create an instance of the model_class.
        Customization point, will be called once the full set of args and kwargs
        has been computed.

        Args:
            model_class (type): the class for which an instance should be
                created
            args (tuple): arguments to use when creating the class
            kwargs (dict): keyword arguments to use when creating the class
        """
    obj = cls._build(model_class, *args, **kwargs)
    obj.commit()
    return obj


def wavedec_keys(level):
    """Subband keys corresponding to a wavedec decomposition."""
    approx = ''
    coeffs = {}
    for lev in range(level):
        for k in ['a', 'd']:
            coeffs[approx + k] = None
        approx = 'a' * (lev + 1)
        if lev < level - 1:
            coeffs.pop(approx)
    return list(coeffs.keys())


@classmethod
def set_total_count(cls, count):
    """Set protected member _total_count"""
    cls._total_count = count


def validate():
    """Validate the address type, True if valid, else False."""


def default_filter(src, dst):
    """The default progress/filter callback; returns True for all files"""
    return dst


def _do_publish(c):
    """Internal function"""
    m = c._userdata.pop()
    if type(m) is dict:
        topic = m['topic']
        try:
            payload = m['payload']
        except KeyError:
            payload = None
        try:
            qos = m['qos']
        except KeyError:
            qos = 0
        try:
            retain = m['retain']
        except KeyError:
            retain = False
    elif type(m) is tuple:
        topic, payload, qos, retain = m
    else:
        raise ValueError('message must be a dict or a tuple')
    c.publish(topic, payload, qos, retain)


def transaction_entries(root):
    """ Yields the transaction entries from the given Camt.053 or Camt.054
    xml. This works because for our purposes the entries of those two formats
    are identical.

    """
    for entry in root.xpath('/Document/BkToCstmrStmt/Stmt/Ntry'):
        yield entry
    for entry in root.xpath('/Document/BkToCstmrDbtCdtNtfctn/Ntfctn/Ntry'):
        yield entry


def copy_object(source_store, source_name, target_store, target_name=None,
    create=False, replace=False):
    """Convenience method that copies object data from source store to target
    store. `source_object` and `target_object` should be object names within
    the respective stores. If `target_name` is not specified, then
    `source_name` is used."""
    target_name = target_name or source_name
    source = source_store.get_object(source_name)
    if create:
        if not replace and target_store.exists(target_name):
            raise Exception(
                'Target object already exists. Use reaplce=True to delete the object object and create replacement'
                )
        target = target_store.create(target_name, source.fields, replace=
            True, from_obj=source)
    else:
        target = target_store.get_object(target_name)
        target.append_from(source)
        target.flush()
    return target


def set_resources_path(resources_path):
    """
        Set the path to the Indic NLP Resources directory
    """
    global INDIC_RESOURCES_PATH
    INDIC_RESOURCES_PATH = resources_path


def faces_shade_flat():
    """Display faces flat

    """
    pass


@classmethod
def get_refseq_category_string(cls, category):
    """Get the NCBI string for a refseq category."""
    return cls._REFSEQ_CATEGORIES[category]


def add_space(string, symbol=' ', direction='all'):
    """
    Add a placeholder to the string
    :params direction: support left or right or all.
    """
    if direction == 'left':
        return '{}{}'.format(symbol, string)
    elif direction == 'right':
        return '{}{}'.format(string, symbol)
    return '{}{}{}'.format(symbol, string, symbol)


def full_to_half(s):
    """
    Convert full-width character to half-width one
    """
    n = []
    for char in s:
        num = ord(char)
        if num == 12288:
            num = 32
        elif 65281 <= num <= 65374:
            num -= 65248
        char = chr(num)
        n.append(char)
    return ''.join(n)


def _do_get_features_list(featurestore_metadata, online):
    """
    Gets a list of all features in a featurestore

    Args:
        :featurestore_metadata: metadata of the featurestore
        :online: flag whether to filter the featuregroups that have online serving enabled

    Returns:
        A list of names of the features in this featurestore
    """
    featuregroups = featurestore_metadata.featuregroups.values()
    if online:
        featuregroups = list(filter(lambda fg: fg.is_online(), featuregroups))
    features = []
    for fg in featuregroups:
        features.extend(fg.features)
    features = list(map(lambda f: f.name, features))
    return features


@classmethod
def from_response(cls, user, response):
    """Construct a BaseNode from a response dict."""
    args = {'user': user, 'json': response, 'type': response.get('type'),
        'id': response.get('_id'), 'is_active': response.get('is_active'),
        'permission': response.get('allowed'), 'nickname': response['info']
        .get('nickname'), 'name_on_account': response['info'].get(
        'name_on_account'), 'bank_long_name': response['info'].get(
        'bank_long_name'), 'bank_name': response['info'].get('bank_name'),
        'account_type': response['info'].get('type'), 'account_class':
        response['info'].get('class'), 'account_number': response['info'].
        get('account_num'), 'routing_number': response['info'].get(
        'routing_num'), 'account_id': response['info'].get('account_id'),
        'address': response['info'].get('address'), 'swift': response[
        'info'].get('swift'), 'ifsc': response['info'].get('ifsc'),
        'payee_name': response['info'].get('payee_name'), 'document_id':
        response['info'].get('document_id'), 'network': response['info'].
        get('network'), 'interchange_type': response['info'].get('type'),
        'card_hash': response['info'].get('card_hash'), 'is_international':
        response['info'].get('is_international'), 'card_type': response[
        'info'].get('card_type')}
    if response['info'].get('correspondent_info'):
        info = response['info']['correspondent_info']
        args['correspondent_swift'] = info.get('swift')
        args['correspondent_bank_name'] = info.get('bank_name')
        args['correspondent_routing_number'] = info.get('routing_num')
        args['correspondent_address'] = info.get('address')
    if response['info'].get('match_info'):
        match_info = response['info']['match_info']
        args['email_match'] = match_info.get('email_match')
        args['name_match'] = match_info.get('name_match')
        args['phonenumber_match'] = match_info.get('phonenumber_match')
    if response['info'].get('balance'):
        info = response['info']['balance']
        args['balance'] = info.get('amount')
        args['currency'] = info.get('currency')
    if response.get('extra'):
        info = response['extra']
        args['supp_id'] = info.get('supp_id')
        args['gateway_restricted'] = info.get('gateway_restricted')
    if response['info'].get('payee_address'):
        info = response['info']['payee_address']
        args['address_street'] = info.get('address_street')
        args['address_city'] = info.get('address_city')
        args['address_subdivision'] = info.get('address_subdivision')
        args['address_country_code'] = info.get('address_country_code')
        args['address_postal_code'] = info.get('address_postal_code')
    if response['info'].get('preferences'):
        info = response['info']['preferences']
        args['allow_foreign_transactions'] = info.get(
            'allow_foreign_transactions')
        args['atm_withdrawal_limit'] = info.get('atm_withdrawal_limit')
        args['max_pin_attempts'] = info.get('max_pin_attempts')
        args['pos_withdrawal_limit'] = info.get('pos_withdrawal_limit')
        args['security_alerts'] = info.get('security_alerts')
    return cls(**args)


def MakeWindow(imgsrc, xpos, ypos, window_size):
    """returns window of given size taken at position on image"""
    imgsrc = imgsrc[xpos:xpos + window_size, ypos:ypos + window_size]
    return imgsrc


def ensure_hashtag(text):
    """Ensure that `text` begins with '#'."""
    if len(text) is 0:
        return '#' + text
    if text[0] == '#':
        return text
    return '#' + text


def process_alert(file_name):
    """
    A function that removes the alerts property from the FireEye alert and transform the data into a JSON ready format
    :param file_name:
    :return:
    """
    processed_line = open(file_name, 'r').read()
    char_pos = processed_line.find('}')
    new_line = '{' + processed_line[char_pos + 2:]
    return new_line


def create_from(recurring_event, datetime):
    """Create an instance with data from the recurring event but for ...

        ... `datetime`.
        """


@staticmethod
def _mutate_label(label: str) ->str:
    """
        Redshift only supports lowercase column names and aliases.

        :param label: Expected expression label
        :return: Conditionally mutated label
        """
    return label.lower()


def get_bytes_per_data_block(header):
    """Calculates the number of bytes in each 60-sample datablock."""
    if header['version']['major'] == 1:
        num_samples_per_data_block = 60
    else:
        num_samples_per_data_block = 128
    bytes_per_block = num_samples_per_data_block * 4
    bytes_per_block = (bytes_per_block + num_samples_per_data_block * 2 *
        header['num_amplifier_channels'])
    bytes_per_block = (bytes_per_block + num_samples_per_data_block / 4 * 2 *
        header['num_aux_input_channels'])
    bytes_per_block = bytes_per_block + 1 * 2 * header[
        'num_supply_voltage_channels']
    bytes_per_block = (bytes_per_block + num_samples_per_data_block * 2 *
        header['num_board_adc_channels'])
    if header['num_board_dig_in_channels'] > 0:
        bytes_per_block = bytes_per_block + num_samples_per_data_block * 2
    if header['num_board_dig_out_channels'] > 0:
        bytes_per_block = bytes_per_block + num_samples_per_data_block * 2
    if header['num_temp_sensor_channels'] > 0:
        bytes_per_block = bytes_per_block + 1 * 2 * header[
            'num_temp_sensor_channels']
    return bytes_per_block


def getargs(args):
    """return the value for arguments in <args>

        For version 1 transports, returns a list of values in the same
        order they appear in ``args``. For version 2 transports, returns
        a dict mapping argument name to value.
        """


def progress_bar(progress):
    """
    Creates a simple progress bar.

    [#########_] 90%

    :param progress: (float) Percentage.
    """
    n = int(progress / 10)
    print('\r[{0}{1}] {2}%'.format('#' * n, '_' * (10 - n), progress), end='')


def split_arg(s, sep, default=''):
    """
    split str s in two at first sep, returning empty string as second result if no sep
    """
    r = s.split(sep, 2)
    r = list(map(str.strip, r))
    arg = r[0]
    if len(r) == 1:
        val = default
    else:
        val = r[1]
        val = {'true': True, 'false': False}.get(val.lower(), val)
    return arg, val


def patch_func(replacement, target_mod, func_name):
    """
    Patch func_name in target_mod with replacement

    Important - original must be resolved by name to avoid
    patching an already patched function.
    """
    original = getattr(target_mod, func_name)
    vars(replacement).setdefault('unpatched', original)
    setattr(target_mod, func_name, replacement)


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

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

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


@classmethod
def to_dict(cls, acl):
    """ transform an ACL to a dict """
    return {'perms': acl.perms, 'id': {'scheme': acl.id.scheme, 'id': acl.
        id.id}}


def points_joined(axis_mapping, point, next_point):
    """Check for axes that need to move within the space between points"""
    for axis_name in axis_mapping:
        if point.upper[axis_name] != next_point.lower[axis_name]:
            return False
    return True


def strip_first_word(line):
    """return everything after the first space on the line from the spec data file"""
    pos = line.find(' ')
    val = line[pos:]
    return val.strip()


def parse_version(v):
    """
    Parses a version string into its component parts. String is expected to follow the
    pattern "0.1.1.dev0", which would be parsed into (0, 1, 1, 0). The first two
    components are required. The third is set to 0 if missing, and the fourth to None.

    Parameters
    ----------
    v : str
        Version string using syntax described above.

    Returns
    -------
    tuple with format (int, int, int, int or None)

    """
    v4 = None
    if 'dev' in v:
        v4 = int(v.split('dev')[1])
        v = v.split('dev')[0]
        if v[-1] == '.':
            v = v[:-1]
    v = v.split('.')
    v3 = 0
    if len(v) == 3:
        v3 = int(v[2])
    v2 = int(v[1])
    v1 = int(v[0])
    return v1, v2, v3, v4


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

        :returns: this backend supports items resuming
        """
    return True


def channels_rename():
    """Rename animation channel under mouse

    """
    pass


def normalize_account_id(account_id):
    """
    Normalize account ID to make it possible to use normal string
    comparisons between different account IDs

    :return: Normalized account ID
    :rtype: str
    """
    return account_id.replace('nano_', 'xrb_')


def yesish(value):
    """Typecast booleanish environment variables to :py:class:`bool`.

    :param string value: An environment variable value.
    :returns: :py:class:`True` if ``value`` is ``1``, ``true``, or ``yes``
        (case-insensitive); :py:class:`False` otherwise.
    """
    if isinstance(value, bool):
        return value
    return value.lower() in ('1', 'true', 'yes')


def checkPermission(permission, object):
    """Return whether security context allows permission on object.

        :param str permission: A permission name
        :param object: The object being accessed according to the permission
        :return: Whether the access is allowed or not.
        :rtype: bool
        """


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


def fbx_mat_properties_from_texture(tex):
    """
    Returns a set of FBX metarial properties that are affected by the given texture.
    Quite obviously, this is a fuzzy and far-from-perfect mapping! Amounts of influence are completely lost, e.g.
    Note tex is actually expected to be a texture slot.
    """
    blend_to_fbx = ('diffuse', 'diffuse', b'DiffuseFactor'), ('color_diffuse',
        'diffuse_color', b'DiffuseColor'), ('alpha', 'alpha',
        b'TransparencyFactor'), ('diffuse', 'diffuse', b'TransparentColor'), (
        'emit', 'emit', b'EmissiveFactor'), ('diffuse', 'diffuse',
        b'EmissiveColor'), ('ambient', 'ambient', b'AmbientFactor'), ('normal',
        'normal', b'NormalMap'), ('specular', 'specular', b'SpecularFactor'), (
        'color_spec', 'specular_color', b'SpecularColor'), ('hardness',
        'hardness', b'Shininess'), ('hardness', 'hardness',
        b'ShininessExponent'), ('mirror', 'mirror', b'ReflectionColor'), (
        'raymir', 'raymir', b'ReflectionFactor')
    tex_fbx_props = set()
    for use_map_name, name_factor, fbx_prop_name in blend_to_fbx:
        if getattr(tex, 'use_map_' + use_map_name):
            tex_fbx_props.add(fbx_prop_name)
    return tex_fbx_props


def id_stub(id):
    """Returns a short version of id, used for sorting objects into subdirectories. """
    return id[:2]


def affine_to_list(affine_obj):
    """Convert a :class:`affine.Affine` instance to a list for Shapely."""
    return [affine_obj.a, affine_obj.b, affine_obj.d, affine_obj.e,
        affine_obj.xoff, affine_obj.yoff]


@staticmethod
def to_rankine(newton):
    """ Convert newton to rankine """
    return newton * 60 / 11 + 491.67


@classmethod
def import_it(cls):
    """
        Performs the import only once.
        """
    if not cls in cls._FEATURES:
        try:
            cls._FEATURES[cls] = cls._import_it()
        except ImportError:
            raise cls.Error(cls._import_error_message(), cls.Error.
                UNSATISFIED_IMPORT_REQ)
    return cls._FEATURES[cls]


def get_int(val):
    """Attempts to convert the string given into the correct integer"""
    if val.isdigit():
        return int(val)
    elif val.endswith('h'):
        return int(val[:-1], 16)
    elif val.endswith('o'):
        return int(val[:-1], 8)
    elif val.endswith('b'):
        return int(val[:-1], 2)


def _neighbour_list(graph, separator, secondary, attributes):
    """
    Generate a string containing the neighbour list of the graph as well as a
    dict containing the notifiers as key and the associated values.
    @todo: speed this up!
    """
    lst_neighbours = list(graph.adjacency_matrix().tolil().rows)
    for v1 in range(graph.node_nb()):
        for i, v2 in enumerate(lst_neighbours[v1]):
            str_edge = str(v2)
            eattr = graph.get_edge_attributes((v1, v2))
            for attr in attributes:
                str_edge += '{}{}'.format(secondary, eattr[attr])
            lst_neighbours[v1][i] = str_edge
        lst_neighbours[v1] = '{}{}{}'.format(v1, separator, separator.join(
            lst_neighbours[v1]))
    str_neighbours = '\n'.join(lst_neighbours)
    return str_neighbours


def word_preprocessing(word, ignore_non_alnumspc=True, ignore_space=True,
    ignore_numeric=True, ignore_case=True):
    """
	Function for word preprocessing
	|
	| Argument
	| | word: a string to be processed
	|
	| Parameter
	| | ignore_non_alnumspc: whether to remove all non alpha/numeric/space characters
	| | ignore_space: whether to remove all spaces
	| | ignore_numeric: whether to remove all numeric characters
	| | ignore_case: whether to convert all alpha characters to lower case
	|
	| Output
	| | processed string (type: str)
	"""
    if ignore_non_alnumspc:
        word = ''.join(filter(lambda x: x.isalnum() or x.isspace(), word))
    if ignore_space:
        word = ''.join(filter(lambda x: not x.isspace(), word))
    if ignore_numeric:
        word = ''.join(filter(lambda x: not x.isnumeric(), word))
    if ignore_case:
        word = word.lower()
    return word


def repeat(n):
    """
        repeat incoming things `n` times

        @param n: number of times to repeat
        """


def zoom_border(xmin: int=0, xmax: int=0, ymin: int=0, ymax: int=0,
    wait_for_input: bool=True, zoom_out: bool=False):
    """Zoom in the view to the nearest object contained in the border

    :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
    :param wait_for_input: Wait for Input
    :type wait_for_input: bool
    :param zoom_out: Zoom Out
    :type zoom_out: bool
    """
    pass


def validate_smearing(parameters, smearing=None):
    """Validate smearing parameters and update the parameters input node accordingly.

    :param parameters: the Dict node that will be used in the inputs
    :param smearing: a tuple of a string and float corresponding to type of smearing and the degauss value
    :raises ValueError: if the input is invalid
    """
    if not any(smearing):
        return
    valid_smearing_types = {'gaussian': ['gaussian', 'gauss'],
        'methfessel-paxton': ['methfessel-paxton', 'm-p', 'mp'],
        'marzari-vanderbilt': ['marzari-vanderbilt', 'cold', 'm-v', 'mv'],
        'fermi-dirac': ['fermi-dirac', 'f-d', 'fd']}
    for _, options in valid_smearing_types.items():
        if smearing[0] in options:
            break
    else:
        raise ValueError('the smearing type "{}" is invalid, choose from {}'
            .format(smearing[0], ', '.join(list(valid_smearing_types.keys()))))
    if not isinstance(smearing[1], float):
        raise ValueError('the smearing value should be a float')
    parameters['SYSTEM']['occupations'] = 'smearing'
    parameters['SYSTEM']['smearing'] = smearing[0]
    parameters['SYSTEM']['degauss'] = smearing[1]


@classmethod
def _from_dict(cls, _dict):
    """Initialize a DocCounts object from a json dictionary."""
    args = {}
    if 'total' in _dict:
        args['total'] = _dict.get('total')
    if 'pending' in _dict:
        args['pending'] = _dict.get('pending')
    if 'successful' in _dict:
        args['successful'] = _dict.get('successful')
    if 'failed' in _dict:
        args['failed'] = _dict.get('failed')
    return cls(**args)


def fromcstring(value):
    """Converts string returned from C library"""
    return value


def set_fd_cloexec(fd):
    """Set a Unix file descriptor's FD_CLOEXEC flag.  Do nothing if platform
    support for this is not available.
    """
    try:
        import fcntl
        old = fcntl.fcntl(fd, fcntl.F_GETFD)
        fcntl.fcntl(fd, fcntl.F_SETFD, old | fcntl.FD_CLOEXEC)
    except (ImportError, AttributeError):
        pass


def implements(*interfaces):
    """Can be used in the class definiton of `Component` subclasses to
    declare the extension points that are extended.
    Can also be used for normal classes to declare them implementing
    `API`s.
    """
    import sys
    frame = sys._getframe(1)
    locals_ = frame.f_locals
    assert locals_ is not frame.f_globals and '__module__' in locals_, 'implements() can only be used in a class definition'
    locals_.setdefault('_implements', []).extend(interfaces)


@classmethod
def register(cls, name, style):
    """
        Register a new style.
        """
    if not issubclass(style, cls._Base):
        raise ValueError('%s must be a subclass of %s' % (style, cls._Base))
    cls._style_list[name] = style


def isnotification(request):
    """
    Tests if the given request is a notification

    :param request: A request dictionary
    :return: True if the request is a notification
    """
    if 'id' not in request:
        return True
    if request['id'] is None:
        return True
    return False


@classmethod
def can_translate(cls, header, filename=None):
    """Indicate whether this translation class can translate the
        supplied header.

        Checks the INSTRUME and FILTER headers.

        Parameters
        ----------
        header : `dict`-like
            Header to convert to standardized form.
        filename : `str`, optional
            Name of file being translated.

        Returns
        -------
        can : `bool`
            `True` if the header is recognized by this class. `False`
            otherwise.
        """
    if 'INSTRUME' in header:
        via_instrume = super().can_translate(header, filename=filename)
        if via_instrume:
            return via_instrume
    if cls.is_keyword_defined(header, 'FILTER') and 'DECam' in header['FILTER'
        ]:
        return True
    return False


@staticmethod
def _align(columns, text_align):
    """ This private method it's in charge of aligning text of a table.

        - notes: more information about `text_align`

        :param columns: it is the number of columns.
        :param text_align: it is a string giving information about the alignment that is wanted.  text_align can take
                           the following parameters: ``'center'``, ``'right'`` and ``'left'``.
        :return: returns a string of type ``'| :---: | :---: | :---: |'``.
        :type columns: int
        :type text_align: str
        :rtype: str

        .. note:
        """
    column_align_string = ''
    if text_align == 'center':
        column_align_string = '|' + ''.join([' :---: |' for _ in range(
            columns)])
    elif text_align == 'left':
        column_align_string = '|' + ''.join([' :--- |' for _ in range(columns)]
            )
    elif text_align == 'right':
        column_align_string = '|' + ''.join([' ---: |' for _ in range(columns)]
            )
    return column_align_string


def output_colored(code, text, is_bold=False):
    """
    Create function to output with color sequence
    """
    if is_bold:
        code = '1;%s' % code
    return '\x1b[%sm%s\x1b[0m' % (code, text)


def do_dr(r, t):
    """
    Spatial derivative of the Boltzmann transformation.

    Returns the partial derivative :math:`\\partial o/\\partial r` evaluated at
    (`r`, `t`).

    Parameters
    ----------
    r : float or numpy.ndarray
        Location(s). If a `numpy.ndarray`, it must have a shape broadcastable
        with `t`.
    t : float or numpy.ndarray
        Time(s). If a `numpy.ndarray`, it must have a shape broadcastable with
        `r`. Values must be positive.

    Returns
    -------
    do_dr : float or numpy.ndarray
        The return is a float if both `r` and `t` are floats. Otherwise it is a
        `numpy.ndarray` of the shape that results from broadcasting `r` and
        `t`.

    See also
    --------
    o
    do_dt
    """
    return 1 / t ** 0.5


def _found_in_block(tx, sha_hash, block_number):
    """
    Check if the transaction can be found in the blockchain
    :param sakia.data.entities.Transaction tx: the transaction
    :param str sha_hash: The transaction sha_hash found in history
    :param int block_number: The block_number where the tx was found
    :return: True if the transaction was found
    :rtype: bool
    """
    if sha_hash == tx.sha_hash:
        return True


def from_url(url, db=None, **kwargs):
    """
    Returns an active Redis client generated from the given database URL.

    Will attempt to extract the database id from the path url fragment, if
    none is provided.
    """
    from redis.client import Redis
    return Redis.from_url(url, db, **kwargs)


def mid(x):
    """
    Midpoints of a given array

    :param x: array with dimension bigger 1
    :return: all the midpoints as numpy array (shape: x.size -1)
    """
    return (x[:-1] + x[1:]) / 2.0


def _convert_argmin(builder, node, graph, err):
    """
    convert to CoreML ArgMin Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L4988
    """
    axis = node.attrs.get('axis', 0)
    keepdims = node.attrs.get('keepdims', True)
    builder.add_argmin(name=node.name, input_name=node.inputs[0],
        output_name=node.outputs[0], axis=axis, keepdims=keepdims)


def get_navigation_items(req):
    """Should return an iterable object over the list of navigation items
        to add, each being a tuple in the form (category, name, text).

        The category determines the location of the navigation item and
        can be `mainnav` or `metanav`. The name is a unique identifier that
        must match the string returned by get_active_navigation_item.
        The text is typically a link element with text that corresponds
        to the desired label for the navigation item, and an href.
        """


def readline_iterator(f):
    """iterate over a file by only using the file object's readline method"""
    have_newline = False
    while True:
        line = f.readline()
        if not line:
            if have_newline:
                yield ''
            return
        if line.endswith('\n'):
            have_newline = True
        else:
            have_newline = False
        yield line


def transform_coordinates(x, y, epsg_in, epsg_out):
    """
    Transform between any coordinate system.

    **Requires `pyproj`** - install using pip.

    Args:
        x : float / 1D array
            x coordinates (may be in degrees or metres/eastings)
        y : float / 1D array
            y coordinates (may be in degrees or metres/northings)
        epsg_in : int
            CRS of x and y coordinates
        epsg_out : int
            CRS of output

    Returns:
        x_out : float / list of floats
            x coordinates projected in `epsg_out`
        y_out : float / list of floats
            y coordinates projected in `epsg_out`
    """
    import pyproj
    proj_in = pyproj.Proj('+init=EPSG:' + str(epsg_in))
    proj_out = pyproj.Proj('+init=EPSG:' + str(epsg_out))
    return pyproj.transform(proj_in, proj_out, x, y)


@classmethod
def _get_namespace_keyword(cls) ->str:
    """Get the keyword to use as the reference BEL namespace."""
    return cls.identifiers_namespace or cls.module_name.upper()


@classmethod
def make_tag(cls, prefix='Tag'):
    """Return a tuple with a single element: a tag string.

        Uses the given prefix and a unique id as a suffix.

        prefix: string

        returns: string
        """
    cls.nextid += 1
    tag = '%s%d' % (prefix, cls.nextid)
    return tag,


def execution_time(result):
    """Return the execution time of a query."""
    avail = result.summary().result_available_after
    cons = result.summary().result_consumed_after
    return avail + cons


def _float_to_int(value):
    """
    Function which rounds and ceils value, written to negate
    float representation inaccuracies, (e.g. to have 2.3 / 0.1
    at 23, not 22)
    """
    return int(round(value, 9))


def add_MRUs(ordered_keys_and_values, return_count_only=False):
    """
        Add as many of the key/value pairs in *ordered_keys_and_values* as possible,
        without evicting any existing items.

        Returns the entries that were added, unless *return_count_only* is given,
        in which case it returns the count added instead. (This can save memory
        if the entries are not actually needed.)
        """


def getInputValue():
    """Return value suitable for the widget's field.

        The widget must return a value that can be legally assigned to
        its bound field or otherwise raise ``WidgetInputError``.

        The return value is not affected by `setRenderedValue()`.
        """


def _hits_overlap(a, b, threshold=0.2):
    """Return True if Domain overlap is greater than threshold * domain size.

    The specified domains typically should share no overlap, tending to be discrete with
    inter-domain gaps. Subsequently, the default threshold is set low. However, it is
    not 0, as to accomodate SOME level of overlap.

    Parameters
    ----------
    a : Domain
        First Domain object.
    b : Domain
        Second Domain object.
    threshold : int
        Minimum percentage to classify two Domains as overlapping. By default,
        `threshold` is set to 0.9, i.e. two Domains are considered as overlapping if
        the total amount of overlap is greater than 90% of either Domain hit.

    Returns
    -------
    bool
        True if Domain overlap exceeds threshold, False if not.
    """
    start, end = max(a.start, b.start), min(a.end, b.end)
    overlap = max(0, end - start)
    a_threshold = threshold * (a.end - a.start)
    b_threshold = threshold * (b.end - b.start)
    return overlap >= a_threshold or overlap >= b_threshold


def dropSpans(spans, text):
    """
    Drop from text the blocks identified in :param spans:, possibly nested.
    """
    spans.sort()
    res = ''
    offset = 0
    for s, e in spans:
        if offset <= s:
            if offset < s:
                res += text[offset:s]
            offset = e
    res += text[offset:]
    return res


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

    The ".dev0" means dirty.

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


def getDefaultPage():
    """Returns the id of the default page for the adapted object.
        """


def face_map_remove():
    """Remove a face map from the active object

    """
    pass


def fromSuccessResponse(cls, success_response):
    """Create a C{L{Response}} object from a successful OpenID
        library response
        (C{L{openid.consumer.consumer.SuccessResponse}}) response
        message

        @param success_response: A SuccessResponse from consumer.complete()
        @type success_response: C{L{openid.consumer.consumer.SuccessResponse}}

        @rtype: Response or None
        @returns: A provider authentication policy response from the
            data that was supplied with the C{id_res} response or None
            if the provider sent no signed PAPE response arguments.
        """
    self = cls()
    args = success_response.getSignedNS(self.ns_uri)
    is_openid1 = success_response.isOpenID1()
    if args is not None:
        self.parseExtensionArgs(args, is_openid1)
        return self
    else:
        return None


def _full_class_name(obj):
    """
    Returns the full name of the class of the given object

    :param obj: Any Python object
    :return: The full name of the class of the object (if possible)
    """
    module = obj.__class__.__module__
    if module is None or module == str.__class__.__module__:
        return obj.__class__.__name__
    return module + '.' + obj.__class__.__name__


@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 get_default_shaders():
    """
    Returns a list of default Maya shaders
    :return: list(str)
    """
    return ['particleCloud1', 'shaderGlow1', 'defaultColorMgtGlobals',
        'lambert1']


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


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


@classmethod
def get_saved_search(cls, tree):
    """
        Add availability to use saved searches. For ex. you can save it in database and get it here.
        """
    return None


def no(a, b):
    """
    Функция для отсутсвия нормализации
    """
    return 1


def get_ticket_comments(session, ticket_id, return_type=None, **kwargs):
    """
    Gets all comments associated with the provided support ticket for the
    VPSA.

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

    :type ticket_id: int
    :param ticket_id: The support ticket 'id' value as returned by
        get_all_tickets.  For example: '28125'.  Required.

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

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    if ticket_id < 1:
        raise ValueError(
            'The ticket ID should be a positive integer ("{0}" was passed).'
            .format(ticket_id))
    path = '/api/tickets/{0}/comments.json'.format(ticket_id)
    return session.get_api(path=path, return_type=return_type, **kwargs)


def set_rigid_link(osi, r_node, c_node, rtype):
    """
    Create a multi-point constraint between nodes.

    Parameters
    ----------
    r_node: Node
        Master node
    c_node: Node
        Slave node
    rtype: str
        Either 'bar' or 'beam'

    Returns
    -------

    """
    op_type = 'rigidLink'
    parameters = [rtype, r_node.tag, c_node.tag]
    osi.to_process(op_type, parameters)


def getInfFromSeqID(seq_id):
    """
    Return sequencer id, run id, flowcell id and position of the sequence on the sequencer flowcell.

    :param sequence: The ID of the sequence provided by the sequencer.
    :type sequence: str
    :return: The sequencer id, run id, flowcell id and position of the sequence on the sequencer flowcell.
    :rtype: dict
    """
    sequencer_id, run_id, flowcell_id, lane_id, tile_id, x_pos, y_pos = (seq_id
        .split(':'))
    return {'sequencer_id': sequencer_id, 'run_id': run_id, 'flowcell_id':
        flowcell_id, 'lane_id': int(lane_id), 'tile_id': int(tile_id),
        'x_pos': int(x_pos), 'y_pos': int(y_pos)}


@classmethod
def get_annotated_list_qs(cls, qs):
    """
        Gets an annotated list from a queryset.
        """
    result, info = [], {}
    start_depth, prev_depth = None, None
    for node in qs:
        depth = node.get_depth()
        if start_depth is None:
            start_depth = depth
        open = depth and (prev_depth is None or depth > prev_depth)
        if prev_depth is not None and depth < prev_depth:
            info['close'] = list(range(0, prev_depth - depth))
        info = {'open': open, 'close': [], 'level': depth - start_depth}
        result.append((node, info))
        prev_depth = depth
    if start_depth and start_depth > 0:
        info['close'] = list(range(0, prev_depth - start_depth + 1))
    return result


def process_args(args):
    """Process console arguments"""
    input = {}
    if 'Burndown' in args.all:
        input['activity'] = 'Burndown Exit'
    else:
        print('Say somethin then')
    return input


def readable_join(items, conjunction='or'):
    """
    Returns an oxford-comma-joined string with "or."

    E.g., ['thing1', 'thing2', 'thing3'] becomes "thing1, thing2, or thing3".
    """
    if not items:
        return None
    count = len(items)
    if count == 1:
        s = items[0]
    elif count == 2:
        template = u' {} '.format(conjunction)
        s = template.join(items)
    else:
        s = u'{}, {} {}'.format(u', '.join(items[:-1]), conjunction, items[-1])
    return s


def normalize_pep440(**kwd):
    """ Normalize the version.

        >>> normalize_pep440(**parse_pep440('1.2.3.4.rc5.post.dev'))
        '1.2.3.4rc5'
    """
    normalized = '.'.join(map(str, kwd['release']))
    if 'pre_release' in kwd:
        normalized += '%s%s' % kwd['pre_release']
    if 'post_release' in kwd:
        normalized += '.post' + str(kwd['post_release'])
    if 'dev_release' in kwd:
        normalized += '.dev' + str(kwd['dev_release'])
    if 'epoch' in kwd:
        normalized = '{}!{}'.format(kwd['epoch'], normalized)
    return normalized


def buildParameter(name, value):
    """Constructs a named parameter in our syntax of NAME:VALUE."""
    return '{n}:{v}'.format(n=name, v=value)


def get_user_profile_url(user):
    """Return project user's github profile url."""
    return 'https://github.com/{}'.format(user)


def interpolate(shift: float=0.0):
    """Interpolate grease pencil strokes between frames

    :param shift: Shift, Bias factor for which frame has more influence on the interpolated strokes
    :type shift: float
    """
    pass


def separate_into_groups(dependency_relationships):
    """ Split into sorted logical groups. """
    projects = list()
    projects_bad = list()
    packages = list()
    packages_bad = list()
    for dep in dependency_relationships:
        if dep.is_package:
            if dep.is_known:
                packages.append(dep.path)
            elif not dep.is_known:
                packages_bad.append(dep.to_name)
        elif dep.is_known:
            projects.append(dep.path)
        elif not dep.is_known:
            projects_bad.append(dep.to_name)
    projects = sorted(set(projects))
    projects_bad = sorted(set(projects_bad))
    packages = sorted(set(packages))
    packages_bad = sorted(set(packages_bad))
    return projects, projects_bad, packages, packages_bad


def is_greater_than(field, notgreaterthanthis):
    """Validates that a field length is not greater than the notgreaterthanthis value.

    Args:
        field:str
        notgreaterthanthis: int
    Returns:
        returns Boolean
    """
    if len(field) > notgreaterthanthis:
        return False
    else:
        return True


def gcm(a, b):
    """Find greatest common multiple of (a,b).
    """
    m = min(a, b)
    for i in range(m, 0, -1):
        if a % i == 0 and b % i == 0:
            return i


def gen_first_n(it, n=10):
    """Return up to the first @n elements of input sequence @it."""
    i = 1
    for el in it:
        if i >= n:
            it.close()
        i += 1
        yield el


def best_charset(text):
    """
    Find the most human-readable and/or conventional encoding for unicode text.

    Prefers `us-ascii` or `iso-8859-1` and falls back to `utf-8`.
    """
    if isinstance(text, bytes):
        text = text.decode('ascii')
    for charset in ('us-ascii', 'iso-8859-1', 'utf-8'):
        try:
            encoded = text.encode(charset)
        except UnicodeError:
            pass
        else:
            return charset, encoded


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 waitOutput(out, err):
    """Wait for any output."""
    return out


def get_export_diff(result_list):
    """Get dictionary of diffs for exports

    :params
    result_list: output from query_exports()
    :return: a dictionary with added and removed packages
    """
    set1 = set(result_list[0])
    set2 = set(result_list[1])
    diff1 = set1 - set2
    diff2 = set2 - set1
    changed = []
    added = []
    removed = []
    for i in diff1:
        added.append(i)
    for i in diff2:
        removed.append(i)
    return {'added': added, 'removed': removed}


def _validate_fields(mappings, tables):
    """Validate that the field names detected match the mapping"""
    pass