def psi_selection(residue):
    """AtomGroup corresponding to the psi protein backbone dihedral
        N-CA-C-N'.

        Returns
        -------
        AtomGroup
            4-atom selection in the correct order. If no N' found in the
            following residue (by resid) then this method returns ``None``.
        """
    sel_str = 'segid {} and resid {} and name N'.format(residue.segment.
        segid, residue.resid + 1)
    sel = residue.atoms.select_atoms('name N', 'name CA', 'name C'
        ) + residue.universe.select_atoms(sel_str)
    if len(sel) == 4:
        return sel
    else:
        return None


@staticmethod
def _compute_back_link(back_indicator, project):
    """
        Based on a simple indicator, compute URL for anchor BACK.
        """
    if back_indicator is None:
        back_page_link = None
    elif back_indicator == 'burst':
        back_page_link = '/burst'
    elif back_indicator == 'operations':
        back_page_link = '/project/viewoperations/' + str(project.id)
    else:
        back_page_link = '/project/editstructure/' + str(project.id)
    return back_page_link


def agg_data(data_strs):
    """
    Auxiliary function that aggregates data of a job to a single byte string
    """
    ranges = []
    pos = 0
    for datum in data_strs:
        datum_len = len(datum)
        ranges.append((pos, pos + datum_len - 1))
        pos += datum_len
    return b''.join(data_strs), ranges


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

        :param TeamSelectiveSyncPolicyChangedType val:
        :rtype: EventType
        """
    return cls('team_selective_sync_policy_changed', val)


def close():
    """
        Close all pooled connections and disable the pool.
        """
    pass


@classmethod
def fromString(cls, theString):
    """Generate an instance of the embeddable from the provided string.
        """
    raise NotImplementedError()


def select_previous():
    """Select control points preceding already selected ones along the curves

    """
    pass


def sing(phonemes: str, pitch: int=64, speed: int=72, mouth: int=128,
    throat: int=128) ->None:
    """
    Sing the phonemes contained in the string phonemes. Changing the pitch
    and duration of the note is described below. Override the optional pitch,
    speed, mouth and throat settings to change the timbre (quality) of the voice.
    """


def anovadict(res):
    """update regression results dictionary with ANOVA specific statistics

    not checked for completeness
    """
    ad = {}
    ad.update(res.__dict__)
    anova_attr = ['df_model', 'df_resid', 'ess', 'ssr', 'uncentered_tss',
        'mse_model', 'mse_resid', 'mse_total', 'fvalue', 'f_pvalue', 'rsquared'
        ]
    for key in anova_attr:
        ad[key] = getattr(res, key)
    ad['nobs'] = res.model.nobs
    ad['ssmwithmean'] = res.uncentered_tss - res.ssr
    return ad


def _reldiff(a, b):
    """
    Computes the relative difference of two floating-point numbers

    rel = abs(a-b)/min(abs(a), abs(b))

    If a == 0 and b == 0, then 0.0 is returned
    Otherwise if a or b is 0.0, inf is returned.
    """
    a = float(a)
    b = float(b)
    aa = abs(a)
    ba = abs(b)
    if a == 0.0 and b == 0.0:
        return 0.0
    elif a == 0 or b == 0.0:
        return float('inf')
    return abs(a - b) / min(aa, ba)


def _unauthorized(code, handler):
    """ Return a HTTP error  """
    handler.set_status(code)
    handler._transforms = []
    handler.write('Unauthorized' if code == 401 else 'Forbidden')
    handler.finish()
    return False


def modifier_move_up(modifier: str=''):
    """Move modifier up in the stack

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


def up():
    """
        Migrate Hello World
    """
    print('Hello World')


def compare_dicts(d1, d2):
    """Use simple comparison"""
    return dict(d1) == dict(d2)


def set_level(verbose_output=False):
    """Set the output level for the application.
    If ``verbose_output`` is False then the application does not print
    informational messages to stdout; only results or fatal errors are printed
    to stdout.
    """
    global _VERBOSE
    _VERBOSE = verbose_output


@classmethod
def _from_dict(cls, _dict):
    """Initialize a CategoriesResult object from a json dictionary."""
    args = {}
    if 'label' in _dict:
        args['label'] = _dict.get('label')
    if 'score' in _dict:
        args['score'] = _dict.get('score')
    return cls(**args)


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

        :param SsoAddLogoutUrlType val:
        :rtype: EventType
        """
    return cls('sso_add_logout_url', val)


def get_short_title():
    """Return the short title of the content object. If there is
        no short title, when the title is returned. If there is no
        title, when the identifier is returned.
        """


def load_ndarray(arr):
    """ Load a numpy array """
    return arr


def identity_filter(data):
    """Return data iterator without any processing"""
    return iter(data)


def select_link_viewer(NODE_OT_select=None, NODE_OT_link_viewer=None):
    """Select node and link it to a viewer node

    :param NODE_OT_select: Select, Select the node under the cursor
    :param NODE_OT_link_viewer: Link to Viewer Node, Link to viewer node
    """
    pass


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 eyedropper_id():
    """Sample a data-block from the 3D View to store in a property

    """
    pass


def to_text(string):
    """Ensure that the string is text."""
    if callable(getattr(string, 'decode', None)):
        return string.decode('utf-8')
    return string


@staticmethod
def p_string_list(p):
    """string_list : STRING
                       | STRING string_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def unstandardize(data, mus_sigs):
    """
    Applies the inverse transformation to return to original data.

    Args
    ----
      data: pandas DataFrame with zero mean and std of one.
      mus_sigs: tuple where first value is the mean used for the standardization and
                second value is the respective standard deviaion.

    Returns
    -------
      data: pandas DataFrame with mean and std given by input ``mus_sigs``
    """
    mu, sig = mus_sigs
    data = data * sig + mu
    return data


def setparents(p1, p2):
    """Set the parent nodes of the working directory."""


def zero_insert(input_string):
    """
    Get a string as input if input is one digit add a zero.

    :param input_string: input digit az string
    :type input_string: str
    :return: modified output as str
    """
    if len(input_string) == 1:
        return '0' + input_string
    return input_string


def get_game_session_log_url(GameSessionId=None):
    """
    Retrieves the location of stored game session logs for a specified game session. When a game session is terminated, Amazon GameLift automatically stores the logs in Amazon S3. Use this URL to download the logs.
    See also: AWS API Documentation

    :example: response = client.get_game_session_log_url(
        GameSessionId='string'
    )

    :type GameSessionId: string
    :param GameSessionId: [REQUIRED]
            Unique identifier for the game session to get logs for.

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

    """
    pass


def plot_smt(x, force_sum, moment_sum, show=True):
    """plots the shear, moment, torque plots"""
    import matplotlib.pyplot as plt
    plt.close()
    fig = plt.figure(1)
    ax = fig.gca()
    ax.plot(x, force_sum[:, (0)], '-*')
    ax.set_xlabel('X')
    ax.set_ylabel('Axial')
    ax.grid(True)
    fig = plt.figure(2)
    ax = fig.gca()
    ax.plot(x, force_sum[:, (1)], '-*')
    ax.set_xlabel('X')
    ax.set_ylabel('Shear Y')
    ax.grid(True)
    fig = plt.figure(3)
    ax = fig.gca()
    ax.plot(x, force_sum[:, (2)], '-*')
    ax.set_xlabel('X')
    ax.set_ylabel('Shear Z')
    ax.grid(True)
    fig = plt.figure(4)
    ax = fig.gca()
    ax.plot(x, moment_sum[:, (0)], '-*')
    ax.set_xlabel('X')
    ax.set_ylabel('Torque')
    ax.grid(True)
    fig = plt.figure(5)
    ax = fig.gca()
    ax.plot(x, moment_sum[:, (1)], '-*')
    ax.set_xlabel('X')
    ax.set_ylabel('Moment Y')
    ax.grid(True)
    fig = plt.figure(6)
    ax = fig.gca()
    ax.plot(x, moment_sum[:, (2)], '-*')
    ax.set_xlabel('X')
    ax.set_ylabel('Moment Z')
    ax.grid(True)
    if show:
        plt.show()


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

        :param FileDeleteCommentType val:
        :rtype: EventType
        """
    return cls('file_delete_comment', val)


def _tzoffset2rfc822zone(seconds):
    """Takes an offset, such as from _tzoffset(), and returns an rfc822
       compliant zone specification. Please note that the result of
       _tzoffset() is the negative of what time.localzone and time.altzone is.
    """
    return '%+03d%02d' % divmod(seconds // 60, 60)


def isfilename(name):
    """
    returns True if name looks like a Mediawiki filename
    """
    if name[0].isalnum() and name[-3:].isalpha():
        return True
    return False


@classmethod
def to_url_args(cls, *args):
    """Return first arg's url_field attribute."""
    url_field = cls.get_url_field()
    return [getattr(args[0], url_field)]


def relabel_nodes(graph, mapping):
    """Relabel graph nodes inplace given a mapping.

    Similar to networkx.relabel.relabel_nodes:
    https://networkx.github.io/documentation/development/_modules/networkx/relabel.html

    Parameters
    ----------
    graph : regraph.Graph
    mapping: dict
        A dictionary with keys being old node ids and their values
        being new id's of the respective nodes.

    Raises
    ------
    ReGraphError
        If new id's do not define a set of distinct node id's.

    """
    graph.relabel_nodes(mapping)
    return


def str2bool(v):
    """
    argparse does not support True or False in python
    """
    return v.lower() in ('true', 't', '1')


def version_from_versioneer():
    """Return a version string based on the git repo, conforming to PEP440"""
    try:
        from .versioneer_version import get_versions
        version_info = get_versions()
        if version_info['error'] is None:
            return version_info['version']
        return None
    except:
        return None


def simplifyWord(word):
    """
    Perform cancellations in a word.

    Input word should be a list of integers;
        [1, 1, -2] means x_1^2 x_2^{-1}

    """
    not_stuck = True
    while not_stuck:
        not_stuck = False
        prev = None
        new_word = []
        for x in word:
            if prev == -x:
                prev = None
                not_stuck = True
            else:
                if prev is not None:
                    new_word.append(prev)
                prev = x
        if prev is not None:
            new_word.append(prev)
        word = new_word
    return word


def scaleto100(value):
    """Scale the input value from 0-255 to 0-100."""
    if 0 < value < 3:
        return 1
    return max(0, min(100, value * 100.0 / 255.0))


def capture_group(s):
    """
    Places parentheses around s to form a capure group (a tagged piece of
    a regular expression), unless it is already a capture group.
    """
    return s if s.startswith('(') and s.endswith(')') else '(%s)' % s


def x_rad_raw_to_attenuation_image_filter(*args, **kwargs):
    """Procedural interface for XRadRawToAttenuationImageFilter"""
    import itk
    instance = itk.XRadRawToAttenuationImageFilter.New(*args, **kwargs)
    return instance.__internal_call__()


def get_segment_generator(segmentation):
    """Time-driven segment generator"""
    t = yield
    for segment in segmentation:
        T = segment.end
        while True:
            if T > t:
                t = yield
                continue
            t = yield T
            break


def extract_ace(archive, compression, cmd, verbosity, interactive, outdir):
    """Extract an ACE archive."""
    cmdlist = [cmd, 'x']
    if not outdir.endswith('/'):
        outdir += '/'
    cmdlist.extend([archive, outdir])
    return cmdlist


def num_objects(df, obj_frequencies):
    """Total number of unique object appearances over all frames."""
    del df
    return obj_frequencies.sum()


def _applySpecial_VolumeOpts_overrideDataRange(args, overlayList,
    displayCtx, target):
    """Applies the :attr:`.VolumeOpts.overrideDataRange` option.

    If the ``overrideDataRange`` command line argument has been provided,
    we need to set the :attr:`.VolumeOpts.enableOverrideDataRange` property.
    """
    target.enableOverrideDataRange = True
    return True


def gapped_lines(data, x, y, type='mean_sd', offset=0.2, ax=None,
    line_color='black', gap_width_percent=1, **kwargs):
    """
    Convenience function to plot the standard devations as vertical
    errorbars. The mean is a gap defined by negative space.

    This style is inspired by Edward Tufte's redesign of the boxplot.
    See The Visual Display of Quantitative Information (1983), pp.128-130.

    Keywords
    --------
    data: pandas DataFrame.
        This DataFrame should be in 'long' format.

    x, y: string.
        x and y columns to be plotted.

    type: ['mean_sd', 'median_quartiles'], default 'mean_sd'
        Plots the summary statistics for each group. If 'mean_sd', then the
        mean and standard deviation of each group is plotted as a gapped line.
        If 'median_quantiles', then the median and 25th and 75th percentiles of
        each group is plotted instead.

    offset: float (default 0.3) or iterable.
        Give a single float (that will be used as the x-offset of all
        gapped lines), or an iterable containing the list of x-offsets.

    line_color: string (matplotlib color, default "black") or iterable of
        matplotlib colors.

        The color of the vertical line indicating the stadard deviations.

    gap_width_percent: float, default 5
        The width of the gap in the line (indicating the central measure),
        expressed as a percentage of the y-span of the axes.

    ax: matplotlib Axes object, default None
        If a matplotlib Axes object is specified, the gapped lines will be
        plotted in order on this axes. If None, the current axes (plt.gca())
        is used.

    kwargs: dict, default None
        Dictionary with kwargs passed to matplotlib.lines.Line2D
    """
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import matplotlib.lines as mlines
    if gap_width_percent < 0 or gap_width_percent > 100:
        raise ValueError('`gap_width_percent` must be between 0 and 100.')
    if ax is None:
        ax = plt.gca()
    ax_ylims = ax.get_ylim()
    ax_yspan = np.abs(ax_ylims[1] - ax_ylims[0])
    gap_width = ax_yspan * gap_width_percent / 100
    keys = kwargs.keys()
    if 'clip_on' not in keys:
        kwargs['clip_on'] = False
    if 'zorder' not in keys:
        kwargs['zorder'] = 5
    if 'lw' not in keys:
        kwargs['lw'] = 2.0
    if isinstance(data[x].dtype, pd.CategoricalDtype):
        group_order = pd.unique(data[x]).categories
    else:
        group_order = pd.unique(data[x])
    means = data.groupby(x)[y].mean().reindex(index=group_order)
    sd = data.groupby(x)[y].std().reindex(index=group_order)
    lower_sd = means - sd
    upper_sd = means + sd
    if (lower_sd < ax_ylims[0]).any() or (upper_sd > ax_ylims[1]).any():
        kwargs['clip_on'] = True
    medians = data.groupby(x)[y].median().reindex(index=group_order)
    quantiles = data.groupby(x)[y].quantile([0.25, 0.75]).unstack().reindex(
        index=group_order)
    lower_quartiles = quantiles[0.25]
    upper_quartiles = quantiles[0.75]
    if type == 'mean_sd':
        central_measures = means
        lows = lower_sd
        highs = upper_sd
    elif type == 'median_quartiles':
        central_measures = medians
        lows = lower_quartiles
        highs = upper_quartiles
    n_groups = len(central_measures)
    if isinstance(line_color, str):
        custom_palette = np.repeat(line_color, n_groups)
    else:
        if len(line_color) != n_groups:
            err1 = '{} groups are being plotted, but '.format(n_groups)
            err2 = '{} colors(s) were supplied in `line_color`.'.format(len
                (line_color))
            raise ValueError(err1 + err2)
        custom_palette = line_color
    try:
        len_offset = len(offset)
    except TypeError:
        offset = np.repeat(offset, n_groups)
        len_offset = len(offset)
    if len_offset != n_groups:
        err1 = '{} groups are being plotted, but '.format(n_groups)
        err2 = '{} offset(s) were supplied in `offset`.'.format(len_offset)
        raise ValueError(err1 + err2)
    kwargs['zorder'] = kwargs['zorder']
    for xpos, central_measure in enumerate(central_measures):
        kwargs['color'] = custom_palette[xpos]
        _xpos = xpos + offset[xpos]
        low = lows[xpos]
        low_to_mean = mlines.Line2D([_xpos, _xpos], [low, central_measure -
            gap_width], **kwargs)
        ax.add_line(low_to_mean)
        high = highs[xpos]
        mean_to_high = mlines.Line2D([_xpos, _xpos], [central_measure +
            gap_width, high], **kwargs)
        ax.add_line(mean_to_high)


def _load_node_models():
    """
    Loading files containing nodes declaration
    """
    import pineapple_nodes.nodes


@classmethod
def _id_from_data(cls, data):
    """
        Extract stripe id from stripe field data
        :param data:
        :return:
        """
    if isinstance(data, str):
        id_ = data
    elif data:
        id_ = data.get('id')
    else:
        id_ = None
    return id_


@classmethod
def rawToFields(cls, raw={}):
    """
        Convert the raw properties of an API response into class fields.  Override to process additional values.

        Args:
            raw (dict): raw object, as provided by the API

        Returns:
            dict: a collection of fields, with keys matching :attr:`attrs`
        """
    return {}


def intensity(c, i):
    """Compute a new alpha given a 0-0xFF intensity"""
    return [c[0], c[1], c[2], c[3] * i >> 8]


def getTimeDistFromFlight(flight):
    """
	Given a flight profile, returns the total time, ground distance and flight distance of that flight profile

	Parameters
	----------
	flight: flight dataframe
		A flight profile to be calculated.

	Returns
	-------
	time: float
		Total time of this flight.
	groundDistance: float
		Total ground distance of this flight.
	flightDistance: float
		Total flight distance of this flight.
	"""
    time = flight['pathEndTimeSec'].max()
    groundDistance = flight['accuGroundDistance'].max()
    flightDistance = flight['accuFlightDistance'].max()
    return [time, groundDistance, flightDistance]


def gen_deps(objects_with_dependencies, dep_types):
    """
    Generate a dictionary name -> dependencies for the objects
    passed as parameters (projects or packages).
    """
    res = dict()
    for object_with_dependencies in objects_with_dependencies:
        deps = set()
        if 'build' in dep_types:
            deps.update(object_with_dependencies.build_depends)
        if 'runtime' in dep_types:
            deps.update(object_with_dependencies.run_depends)
        if 'test' in dep_types:
            deps.update(object_with_dependencies.test_depends)
        res[object_with_dependencies.name] = deps
    return res


@staticmethod
def format_sizeof(num, suffix=''):
    """
        Formats a number (greater than unity) with SI Order of Magnitude
        prefixes.

        Parameters
        ----------
        num  : float
            Number ( >= 1) to format.
        suffix  : str, optional
            Post-postfix [default: ''].

        Returns
        -------
        out  : str
            Number with Order of Magnitude SI unit postfix.
        """
    for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
        if abs(num) < 999.95:
            if abs(num) < 99.95:
                if abs(num) < 9.995:
                    return '{0:1.2f}'.format(num) + unit + suffix
                return '{0:2.1f}'.format(num) + unit + suffix
            return '{0:3.0f}'.format(num) + unit + suffix
        num /= 1000.0
    return '{0:3.1f}Y'.format(num) + suffix


def nextURL():
    """Return the URL to be displayed after the add operation.

        This can be relative to the view's context.

        The default implementation returns `self.context.nextURL()`,
        i.e. it delegates to the `IAdding` view.
        """


@classmethod
def compute_info(cls, val):
    """
        Compute the new information for this provider

        The computed value should be returned and will then be accessible directly as cls.INFO.
        This information will be printed by the client when describing this metadata provider

        Parameters
        ----------
        val : str
            Provider specific information used in computing the new information. For example, this
            can be a path.

        Returns
        -------
        str :
            Value to be set to INFO
        """
    return ''


@staticmethod
def isUnixsockLocation(location):
    """determine if a location string is for a Unix domain socket"""
    return location.startswith('./u:')


def allowance(browser):
    """
    Our image diffs below give some false alarms of diffs... The values
    below are rmsdiff values for 100%-same ImageChops histograms (i.e.,
    ImageChops' bounding box method showed no difference), and for
    trivial rendering differences, e.g., a pixel within a button gradient
    differing, or rendered text differing very slightly, we add a slight
    allowance.
    """
    margin = 1.001
    margins = {'default': 572.4334022399462 * margin, 'chrome':
        572.4334022399462 * margin, 'firefox': 957.864291014 * margin}
    try:
        return margins[browser]
    except KeyError:
        return margins['default']


def _test():
    """
    >>> text = "Line\\\\nLong Line\\\\\\nVery long line and...\\nHere \\n\\n \\n\\n \\n \\\\n"
    >>> for i in range(1, 80):
    ...     if not join_long_lines(break_long_lines(text, i)) == text:
    ...         raise Exception("Test failure")
    """
    pass


def positive_int(value):
    """Custom `int` that must be positive."""
    value = int(value)
    if value < 1:
        raise TypeError
    return value


@staticmethod
def firstNonSpaceIndex(text):
    """Provides a pos (0-based of a first non-space char in the text"""
    lStripped = text.lstrip()
    if lStripped:
        return len(text) - len(lStripped)
    return None


@classmethod
def from_subdir(cls, container, info_obj):
    """Create from subdirectory info object."""
    return cls(container, info_obj['subdir'], obj_type=cls.type_cls.SUBDIR)


def get_rad_from_try_data(try_data):
    """
    Returns direct and diffuse radiation of TRY datasets

    Parameters
    ----------
    try_data : numpy array
        Numpy array with TRY data

    Returns
    -------
    tuple_rad : tuple (of arrays)
        Tuple holding direct and diffuse radiation arrays
        (q_direct, q_diffuse) in W/m^2
    """
    nb_rows = 8760
    q_direct = try_data[0:nb_rows, (13)]
    q_diffuse = try_data[0:nb_rows, (14)]
    return q_direct, q_diffuse


def get_fields_from_model(model_class):
    """Returns all fields, including inherited fields but ignoring M2M fields."""
    return model_class._meta.fields


def remove_env_bin_from_path(env, env_bin_dir):
    """
    Remove bin directory of the current environment from PATH
    """
    return env.replace(env_bin_dir + ':', '')


def image_cuda():
    """ Run grid and image with rfgpu
    TODO: update to use rfgpu
    """
    pass


def octetFromIP(ip, n):
    """Returns the nth octet (0-indexed) of the given ip string"""
    return ip.split('.')[n]


def variable_string(dimension, symbol):
    """ This method generate dinamic variables from a number (dimension) in a string"""
    iteration = 1
    variable = ''
    while iteration <= dimension:
        variable = variable + '{}{} '.format(symbol, iteration)
        iteration = iteration + 1
    return variable[0:len(variable) - 1]


@classmethod
def get_field_handler_from_fullname(cls, fullname):
    """
        Given a fullname, e.g. 'Device.host', 'Author.name',
        this function returns the handler.FieldHandler.

        @type name: str
        @param name: e.g. 'address', or 'name'
        """
    thecls, alias = cls.get_class_from_fullname(fullname)
    return thecls.get_field_handler_from_alias(alias)


@classmethod
def match(cls, value):
    """Lookup appropriate handler based on value (a type)"""
    key = '%s.%s' % (value.__module__, value.__name__)
    for plugin in cls.registry:
        set = getattr(plugin, 'check', ())
        if set and key in set:
            return plugin
    return None


def normalize_i18n(x):
    """
    Normalize accepted lang codes to ISO format.

    Also check if language codes are valid.
    """
    if x is None:
        return None
    return x.replace('-', '_')


def str_is_num16(a_str):
    """通过int(a_str, 16)测试字符串数字是否是16进制"""
    try:
        int(a_str, 16)
        return True
    except:
        return False


def convert_pair(fixedvarindex, pair):
    """ Convert pair variable to pair for a secondary covariance matrix """
    if pair.__class__ == int:
        pair = [pair]
        pair2 = [None]
    else:
        pair2 = [None, None]
    if fixedvarindex != None:
        for ii, pp in enumerate(pair):
            if pp > fixedvarindex + 1:
                pair2[ii] = pp - 1
            else:
                pair2[ii] = pp
    return pair2


@classmethod
def from_string(cls, str_value):
    """
        Deserializes a member from string.
        :param str_value: serialized form
        :return: enum member or None if not found
        """
    for m in cls:
        if m.value == str_value:
            return m
    else:
        return None


def pkginfo_unicode(pkg_info, field):
    """Hack to coax Unicode out of an email Message() - Python 3.3+"""
    text = pkg_info[field]
    field = field.lower()
    if not isinstance(text, str):
        for item in pkg_info.raw_items():
            if item[0].lower() == field:
                text = item[1].encode('ascii', 'surrogateescape').decode(
                    'utf-8')
                break
    return text


def df_corr_ols(data, y, destructive=False):
    """1-by-1 correlation with OLS for categorical values as strings.

    Takes in a single column DataFrame where some columns are string
    values of categories. Then performs an OLS test individually on
    values of column returning an ordinal category representation (the greater
    the value, the higher the correlation coefficient.)

    data : dataframe
        A Pandas dataframe with the data
    y : str
        The prediction variable.
    destructive : bool
        If set to True, will make changes directly to the dataframe which
        may be useful with very large dataframes instead of making a copy.

    """
    import wrangle as wr
    import warnings
    warnings.simplefilter('ignore')
    if destructive is False:
        data = data.copy(deep=True)
    for col in data.columns:
        try:
            wr.col_corr_ols(data, col, y, destructive=True)
        except ValueError:
            pass
    return data


def select_mirror(only_active: bool=False, extend: bool=False):
    """Mirror the bone selection

    :param only_active: Active Only, Only operate on the active bone
    :type only_active: bool
    :param extend: Extend, Extend the selection
    :type extend: bool
    """
    pass


@classmethod
def calculate_offset(cls, position):
    """
        Returns a tuple containing (x, y, z) of the given position on this
        container, without calibration.  (Relative coordinates.)
        """
    return cls.coordinates(position)


@classmethod
def register_notification_objects(cls):
    """Register previously decorated notification as normal ovos.

        This is not intended for production use but only for testing and
        document generation purposes.
        """
    for notification_cls in cls.notification_classes:
        cls.register(notification_cls)


def _private_key_filename(file_prefix):
    """
    Construct the name of a file for use in storing a private key.

    :param str file_prefix: base file name for the private key (without the
        extension)
    :return: private key filename
    :rtype: str
    """
    return file_prefix + '.key'


def _x_orientation_rep_dict(x_orientation):
    """Create replacement dict based on x_orientation."""
    if x_orientation.lower() == 'east' or x_orientation.lower() == 'e':
        return {'x': 'e', 'y': 'n'}
    elif x_orientation.lower() == 'north' or x_orientation.lower() == 'n':
        return {'x': 'n', 'y': 'e'}
    else:
        raise ValueError('x_orientation not recognized.')


def item_to_dict(p_item):
    """ convert pocket item to universal dict """
    out = {'url': p_item.get('resolved_url') or p_item.get('given_url'),
        'title': p_item.get('resolved_title') or p_item.get('given_title'),
        'tags': sorted(p_item.get('tags', {}).keys()), 'timestamp': int(
        p_item.get('time_updated'))}
    return out


@classmethod
def from_bin(cls, value):
    """Initialize a new network from binary notation."""
    value = value.lstrip('b')
    if len(value) == 32:
        return cls(int(value, 2))
    elif len(value) == 128:
        return cls(int(value, 2))
    else:
        return ValueError('%r: invalid binary notation' % (value,))


@classmethod
def get_key(cls, name):
    """
        This method creates a Redis key in which instance with given name will be saved.

        :param name: name of object for which a key is to be made.
        :returns: key used in Redis for given name.
        """
    return name


def fil_remove_status_value(all_status, value):
    """filter parsed status by status[value]"""
    for status in all_status:
        if status['value'] != value:
            yield status


def DISTINCT(src_column):
    """
  Builtin distinct values for groupby. Returns a list of distinct values.

  >>> sf.groupby("user",
  ...       {'rating_distinct':gl.aggregate.DISTINCT('rating')})

  """
    return '__builtin__distinct__', [src_column]


def cols_to_strip_commas(df, columns):
    """Strip commas from selected dataframe columns.

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

    Returns:
        Original dataframe with converted column data.
    """
    for col in columns:
        df[col] = df[col].str.replace(',', '')
    return df


@staticmethod
def _distance_matrix(data, i, metric, cache, matrix):
    """
        Function to calculate distance from the ith sequence of the ith row to the remaining entries in the same row
        :param data: list with all sequences
        :param i: int that indicates the matrix row being processed
        :param metric: function that takes two string and calculates distance
        :param cache: either a Manager or Cache object to cache results
        :param matrix: either a Manager or Cache object to store results in a matrix
        :return: None
        """
    row = []
    seq_1 = data[i]
    for j, seq_2 in enumerate(data):
        if i == j:
            row.append(0)
            continue
        keys = '{}-{}'.format(i, j), '{}-{}'.format(j, i)
        if keys[0] not in cache or keys[1] not in cache:
            cache['{}-{}'.format(i, j)] = metric(seq_1, seq_2)
        if keys[0] in cache:
            row.append(cache[keys[0]])
        elif keys[1] in cache:
            row.append(cache[keys[0]])
        else:
            raise ValueError('Bug in row {} and column {}'.format(i, j))
    matrix[i] = row


def compare_bounds(b0, b1):
    """
    Function that compares two bounds with each other. Returns the max bound.

    Parameters
    ----------
    b0 : tuple
        tuple of xmin, ymin, xmax, ymax
    b1 : tuple
        tuple of xmin, ymin, xmax, ymax

    Returns
    -------
    tuple
        min of mins and max of maxs
    """
    if len(b0) and len(b1):
        bounds = min(b0[0], b1[0]), min(b0[1], b1[1]), max(b0[2], b1[2]), max(
            b0[3], b1[3])
    elif len(b0) and not len(b1):
        bounds = b0
    elif not len(b0) and len(b1):
        bounds = b1
    else:
        bounds = []
    return bounds


def pairwise_squared_distance(x):
    """
    x : (n_samples, n_points, dims)
    return : (n_samples, n_points, n_points)
    """
    x2s = (x * x).sum(-1, keepdim=True)
    return x2s + x2s.transpose(-1, -2) - 2 * x @ x.transpose(-1, -2)


def validate_hydro_approximate_momenta(initial_conditions, values):
    """
    Validate azimuthal momentum equation
    """
    return 1 - 2 * initial_conditions.a_0 * values.B_θ * values.deriv.B_φ / (
        values.ρ * values.v_r * values.v_φ)


def get_types(input_types, args, kwargs):
    """Extract the types of args, kwargs, optional kwargs and output.

    Parameters
    ----------
    input_types : list
        List of inputs' input_types, including for optional inputs.
    args : tuple
        Args of a function.
    kwargs : dict
        Kwargs of a function.

    Returns
    -------
    args_types : list
        Types of args.
    kwargs_types : list
        Types of kwargs.
    opt_kwargs_types : list
        Types of optional kwargs.
    is_scal : bool
        Boolean determining if the output is a scalar.
    """
    len_args = len(args)
    len_kwargs = len(kwargs)
    len_total = len_args + len_kwargs
    args_types = input_types[:len_args]
    kwargs_types = input_types[len_args:len_total]
    opt_kwargs_types = []
    is_scal = True
    if len(input_types) > len_total:
        opt_kwargs_types = input_types[len_total:]
        last_input_type = input_types[-1]
        if 'output_' in last_input_type:
            if last_input_type != 'output_scalar':
                is_scal = False
                opt_kwargs_types = input_types[len_total:-1]
    return args_types, kwargs_types, opt_kwargs_types, is_scal


def clearhistory():
    """
    @api {post} /music/search/gethistory 获取搜索记录
    @apiVersion 1.0.0
    @apiGroup Search
    @apiDescription 获取搜索记录

    @apiParam (Headers) {string} token 令牌
    @apiParam (Headers) {String} device_token 设备令牌
    @apiParam (Headers) {String} content_type 内容类型
    @apiParam (Headers) {String} timestamp 时间戳

    """


def resource_file_format(value):
    """Space-separated resource references in filename=blobsource format."""
    try:
        file_name, blob_source = value.split('=', 1)
    except ValueError:
        message = (
            'Incorrectly formatted resource reference. Argument values should be in the format filename=blobsource'
            )
        raise ValueError(message)
    return {'file_path': file_name, 'blob_source': blob_source}


def get_client_ip(request):
    """Get client's ip address."""
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip_address = x_forwarded_for.split(',')[0]
    else:
        ip_address = request.META.get('REMOTE_ADDR')
    return ip_address


def evaluator_options_from_eval_config(eval_config):
    """Produces a dictionary of evaluation options for each eval metric.

  Args:
    eval_config: An `eval_pb2.EvalConfig`.

  Returns:
    evaluator_options: A dictionary of metric names (see
      EVAL_METRICS_CLASS_DICT) to `DetectionEvaluator` initialization
      keyword arguments. For example:
      evalator_options = {
        'coco_detection_metrics': {'include_metrics_per_category': True}
      }
  """
    eval_metric_fn_keys = eval_config.metrics_set
    evaluator_options = {}
    for eval_metric_fn_key in eval_metric_fn_keys:
        if eval_metric_fn_key in ('coco_detection_metrics', 'coco_mask_metrics'
            ):
            evaluator_options[eval_metric_fn_key] = {
                'include_metrics_per_category': eval_config.
                include_metrics_per_category}
        elif eval_metric_fn_key == 'precision_at_recall_detection_metrics':
            evaluator_options[eval_metric_fn_key] = {'recall_lower_bound':
                eval_config.recall_lower_bound, 'recall_upper_bound':
                eval_config.recall_upper_bound}
    return evaluator_options


def dictElement(element, prefix=None, number_multiples=False):
    """Returns a dictionary built from the children of *element*, which must be
    a :class:`xml.etree.ElementTree.Element` instance. Keys of the dictionary
    are *tag* of children without the *prefix*, or namespace. Values depend on
    the content of the child. If a child does not have any children, its text
    attribute is the value. If a child has children, then the child is the
    value.
    """
    dict_ = {}
    length = False
    if isinstance(prefix, str):
        length = len(prefix)
    prev_tag = ''
    for child in element:
        tag = child.tag
        if length and tag.startswith(prefix):
            tag = tag[length:]
        if tag != prev_tag:
            prev_tag = tag
            i = 0
        else:
            i += 1
        if number_multiples:
            tag = tag + '{:>4}'.format(str(i))
        if len(child) == 0:
            if child.text is None:
                dict_[tag] = child.items()
            else:
                dict_[tag] = child.text
        else:
            dict_[tag] = child
    return dict_


def getHtmlOfUrl(url, **kwargs):
    """
    获取url对应的html文档，根据需要替换该方法
    """
    import requests
    res = requests.get(url, **kwargs)
    if res.status_code > 400:
        raise Exception(res.status_code)
    if res.cookies and 'cookies' in kwargs and type(kwargs['cookies']) == dict:
        kwargs['cookies'].update(res.cookies.get_dict())
    return res.text


def viz_b(body):
    """Create HTML b for graphviz"""
    return '<B>{}</B>'.format(body)


def _send_n_create_rq(event):
    """Logging handler when an N-CREATE-RQ is sent.

    Parameters
    ----------
    event : events.Event
        The evt.EVT_DIMSE_SENT event that occurred.
    """
    pass


def maybe_wrapped(wrapper, driver, el):
    """Optionally wrap el with wrapper."""
    if wrapper is None:
        return el
    else:
        return wrapper(driver=driver, el=el)


@classmethod
def setup_parameters(cls, params):
    """Inheritable hook for defining parameters.
        Called at site startup once for each actor using this model.

        It receives a `dict` object `params` and is alloed to update that
        `dict`, which will be used to fill the actor's `parameters`.

        See also :meth:`get_simple_parameters`.

        """
    pass


def delete_device_pool(arn=None):
    """
    Deletes a device pool given the pool ARN. Does not allow deletion of curated pools owned by the system.
    See also: AWS API Documentation

    Examples
    The following example deletes a specific device pool.
    Expected Output:

    :example: response = client.delete_device_pool(
        arn='string'
    )

    :type arn: string
    :param arn: [REQUIRED]
            Represents the Amazon Resource Name (ARN) of the Device Farm device pool you wish to delete.

    :rtype: dict
    :return: {}

    """
    pass


def select_more(use_face_step: bool=True):
    """Select more vertices, edges or faces connected to initial selection

    :param use_face_step: Face Step, Connected faces (instead of edges)
    :type use_face_step: bool
    """
    pass


def lighthen(color):
    """
	Used to slightly lighten a specified color
	"""
    return min(255, color[0] + 7), min(255, color[1] + 7), min(255, color[2
        ] + 7), 255


def add_csv_args(pyset, csv_path, column):
    """add csv with column mapped from cli arguments"""
    pyset.add_csv(csv_path, list(map(int, column.split(','))))


def multiplie_vecteur(v, f):
    """
    Multiplie un vecteur par un scalaire.
    """
    return v[0] * f, v[1] * f


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

        :param IntegrationDisconnectedDetails val:
        :rtype: EventDetails
        """
    return cls('integration_disconnected_details', val)


def s(o, prop, val, overwrite=False):
    """
    helper to set a coordinate attribute if it isn't already defined,
    unless we really want to.
    """
    if overwrite or o.get(prop) is None:
        o.set(prop, str(val))


@staticmethod
def perform(program):
    """
        # Perform routing
        Route to the app provided in the CLI's first argument
        """
    app_name = program.cli_args.app
    app = program.get_app(app_name)
    if not app:
        raise Exception(f'Unable to locate app "{app_name}"')
    app_method = getattr(program, f'run_{app_name}', None)
    if callable(app_method):
        return app_method(app)
    else:
        program.app_lifecycle(app=app)


def bounding_box(bw, bh, w, h):
    """
    Returns a tuple (new_width, new_height) which has the property
    that it fits within box_width and box_height and has (close to)
    the same aspect ratio as the original size
    """
    new_width, new_height = w, h
    if bw and new_width > bw:
        new_width = bw
        new_height = new_width / (w / h)
    if bh and new_height > bh:
        new_height = bh
        new_width = new_height * (w / h)
    return new_width, new_height


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


def SHORTER(fragment):
    """Sort shorter passages first."""
    return len(fragment)


def select_linked_from():
    """Select nodes linked from the selected ones

    """
    pass


def decode_parameter(data):
    """Decode a single parameter."""


def disconnect(ssh_session):
    """
    Disconnect from a ssh session
    The arguments are:
    	ssh_session:                  ssh session, it is return by connect()
    Returns:
    	True:                         Always
    """
    ssh_session.disconnect()
    return True


def all_paths_nodes(paths, steps, keep_last=True):
    """Get all possible anonymous walks of length up to steps,
	using node labels

	"""
    new_paths = []
    last_step_paths = [[0]]
    for i in range(1, steps + 1):
        current_step_paths = []
        for j in range(i + 1):
            for walks in last_step_paths:
                if j <= max(walks) + 1:
                    new_paths.append(walks + [j])
                    current_step_paths.append(walks + [j])
        last_step_paths = current_step_paths
    if keep_last:
        new_paths = last_step_paths
    paths[steps] = new_paths
    return new_paths


@staticmethod
def filter_with_english_letters(buf):
    """
        Returns a copy of ``buf`` that retains only the sequences of English
        alphabet and high byte characters that are not between <> characters.
        Also retains English alphabet and high byte characters immediately
        before occurrences of >.

        This filter can be applied to all scripts which contain both English
        characters and extended ASCII characters, but is currently only used by
        ``Latin1Prober``.
        """
    filtered = bytearray()
    in_tag = False
    prev = 0
    for curr in range(len(buf)):
        buf_char = buf[curr:curr + 1]
        if buf_char == b'>':
            in_tag = False
        elif buf_char == b'<':
            in_tag = True
        if buf_char < b'\x80' and not buf_char.isalpha():
            if curr > prev and not in_tag:
                filtered.extend(buf[prev:curr])
                filtered.extend(b' ')
            prev = curr + 1
    if not in_tag:
        filtered.extend(buf[prev:])
    return filtered


def deserializeValue(value):
    """Convert real string -> native type.

        Must always return a valid value for the given field.
        """


def _combine_string(string, args=None):
    """
    Combines a template string with the passed arguments
    """
    if args is None:
        return string
    return string % args


def chat_command(username, parameters):
    """
        Handle a command from the chat interface.

        :param str username: username of player
        :param list parameters: additional parameters passed to the command

        :returns: a generator object or other iterable yielding lines
        """


@staticmethod
def is_batch():
    """
        Returns whether DCC is being executed in batch mode or not
        :return: bool
        """
    return False


def datetimetostr(dt):
    """Return a RFC3339 date-time string corresponding to the given
    datetime object."""
    if dt.utcoffset() is not None:
        return dt.isoformat()
    else:
        return '%sZ' % dt.isoformat()


def load_10X_zip(filename, sparse=True, gene_labels='symbol',
    allow_duplicates=None):
    """magic.io is deprecated. Please use scprep.io instead.
       Read more at http://scprep.readthedocs.io/
    """
    raise RuntimeError(
        'magic.io is deprecated. Please use scprep.io instead. Read more at http://scprep.readthedocs.io'
        , FutureWarning)


def region_scale():
    """Scale selected area

    """
    pass


def get_sha1(contents: bytes) ->str:
    """ Returns an hexdigest (string) """
    from zuper_commons.types import check_isinstance
    import hashlib
    check_isinstance(contents, bytes)
    m = hashlib.sha1()
    m.update(contents)
    s = m.hexdigest()
    check_isinstance(s, str)
    return s


def calculate_waterfall(in_queue, out_queue):
    """
    Convenience function for calculating the vertical binning of each frame of an image. It needs an input and output queue,
    the first one holds the images while the latter accumulates the 1D arrays. The second queue has to be consumed by another
    process, either for saving or for displaying.

    :param in_queue:
    :type in_queue:
    :param out_queue:
    :type out_queue:
    :return:
    :rtype:
    """
    pass


def indent_char2int(indent):
    """Convert a character indent into a number of spaces that should be used.
    Tabs are set to be equivalent to 4 spaces.

    Args:
        indent (str): String indent.

    Returns:
        int: Number of whitespaces that is equivalent to the provided string.

    """
    if isinstance(indent, str):
        indent = len(indent.replace('\t', '    '))
    return indent


def identify_degenerate_nests(nest_spec):
    """
    Identify the nests within nest_spec that are degenerate, i.e. those nests
    with only a single alternative within the nest.

    Parameters
    ----------
    nest_spec : OrderedDict.
        Keys are strings that define the name of the nests. Values are lists
        of alternative ids, denoting which alternatives belong to which nests.
        Each alternative id must only be associated with a single nest!

    Returns
    -------
    list.
        Will contain the positions in the list of keys from `nest_spec` that
        are degenerate.
    """
    degenerate_positions = []
    for pos, key in enumerate(nest_spec):
        if len(nest_spec[key]) == 1:
            degenerate_positions.append(pos)
    return degenerate_positions


def extract_capabilities(text):
    """Extract a capabilities list from a string, if present.

    :param text: String to extract from
    :return: Tuple with text with capabilities removed and list of capabilities
    """
    if b'\x00' not in text:
        return text, []
    text, capabilities = text.rstrip().split(b'\x00')
    return text, capabilities.strip().split(b' ')


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

        :param PaperDocChangeSubscriptionDetails val:
        :rtype: EventDetails
        """
    return cls('paper_doc_change_subscription_details', val)


@classmethod
def blue(cls, string, auto=False):
    """Color-code entire string.

        :param str string: String to colorize.
        :param bool auto: Enable auto-color (dark/light terminal).

        :return: Class instance for colorized string.
        :rtype: Color
        """
    return cls.colorize('blue', string, auto=auto)


@classmethod
def get_asset_and_components(cls, session, asset_key):
    """Get information about individual asset & its components
        Component may be a PSU that belongs to a server or PDU outlets

        Args:
            session: database session
            asset_key(int): query by key

        Returns:
            dict: asset details with it's 'labels' and components as 'children' (sorted by key)
        """
    results = session.run(
        """
            MATCH (n:Asset { key: $key }) OPTIONAL MATCH (n)-[:HAS_COMPONENT]->(c)
            RETURN n as asset, labels(n) as labels, collect(c) as children
            """
        , key=int(asset_key))
    record = results.single()
    asset = dict(record['asset'])
    asset['labels'] = record['labels']
    children = []
    if record['children']:
        children = sorted(list(map(lambda x: x['key'], record['children'])))
    asset['children'] = children
    return asset


@classmethod
def from_query_result(cls, columns, point_list):
    """creates an instance of Content from pieces of an influxdb query

        :param columns: the list of column names (keys)
        :type columns: [str, ]

        :param point_list: the list of associated instance values for the columns
        :type point_list: [type, ]

        :return: a new instance of Content
        :rtype: BaseContent
        """
    raise NotImplementedError


def delete_parameter():
    """delete a parameter in a collection."""
    pass


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


def duplicate_move_keep_inputs(NODE_OT_duplicate=None,
    NODE_OT_translate_attach=None):
    """Duplicate selected nodes keeping input links and move them

    :param NODE_OT_duplicate: Duplicate Nodes, Duplicate selected nodes
    :param NODE_OT_translate_attach: Move and Attach, Move nodes and attach to frame
    """
    pass


@classmethod
def create(cls, root, schema):
    """
        Create an object based on the root tag name.

        @param root: An XML root element.
        @type root: L{Element}
        @param schema: A schema object.
        @type schema: L{schema.Schema}
        @return: The created object.
        @rtype: L{SchemaObject}

        """
    fn = cls.tags.get(root.name)
    if fn is not None:
        return fn(schema, root)


@classmethod
def beliefs(cls):
    """
        Not applicable for gliders
        """
    return {}


def replace_d(s):
    """Replaces fortran-style 'D' with 'E"""
    s = s.replace('D', 'E')
    s = s.replace('d', 'e')
    return s


def coord_bsa(domain, betas, theta=3.0, dmax=5.0, ths=0, thq=0.5, smin=0,
    afname=None):
    """ main function for  performing bsa on a dataset
    where bsa =  nipy.labs.spatial_models.bayesian_structural_analysis

    Parameters
    ----------
    domain: image instance,
          referential- and domain-defining image
    betas: array of shape (nbnodes, subjects),
           the multi-subject statistical maps
    theta: float, optional
           first level threshold
    dmax: float>0, optional
          expected cluster std in the common space in units of coord
    ths: int, >=0), optional
         representatitivity threshold
    thq: float, optional,
         posterior significance threshold should be in [0,1]
    smin: int, optional,
          minimal size of the regions to validate them
    afname: string, optional
            path where intermediate results cam be pickled

    Returns
    -------
    afcoord array of shape(number_of_regions,3):
            coordinate of the found landmark regions
    """
    from ..spatial_models.bayesian_structural_analysis import compute_BSA_quick
    crmap, AF, BF, p = compute_BSA_quick(domain, betas, dmax, thq, smin,
        ths, theta, verbose=0)
    if AF is None:
        return None
    if afname is not None:
        import pickle
        pickle.dump(AF, afname)
    afcoord = AF.discrete_to_roi_features('position')
    return afcoord


def _testDigestPointPen():
    """
    >>> pen = DigestPointPen()
    >>> pen.beginPath("abc123")
    >>> pen.getDigest()
    (('beginPath', 'abc123'),)
    >>> pen.addPoint((10, 10), "move", True)
    >>> pen.addPoint((-10, 100), "line", False)
    >>> pen.endPath()
    >>> pen.getDigest()
    (('beginPath', 'abc123'), ((10, 10), 'move', True, None), ((-10, 100), 'line', False, None), 'endPath')
    >>> pen.getDigestPointsOnly()  # https://github.com/robofab-developers/fontPens/issues/8
    ((-10, 100), (10, 10))
    >>> pen.beginPath()
    >>> pen.addPoint((100, 100), 'line')
    >>> pen.addPoint((100, 10), 'line')
    >>> pen.addPoint((10, 10), 'line')
    >>> pen.endPath()
    >>> pen.getDigest()
    (('beginPath', 'abc123'), ((10, 10), 'move', True, None), ((-10, 100), 'line', False, None), 'endPath', ('beginPath', None), ((100, 100), 'line', False, None), ((100, 10), 'line', False, None), ((10, 10), 'line', False, None), 'endPath')
    >>> pen.getDigestPointsOnly()
    ((-10, 100), (10, 10), (10, 10), (100, 10), (100, 100))
    """


@staticmethod
def _get_value(json_data: dict, key: str) ->str:
    """
        Gets a key value from a given JSON.

        As Steam's JSON data is inconsistent, it might very well miss some of
        the things that are usually present in other apps. Hence, we simply
        set the value to None instead of reporting the problem, as this is
        (albeit rare) expected occurrence.

        :param json_data: dictionary which is to be inspected for a key-value.
        :param key: dictionary key for which the value should be returned.
        :return: value corresponding to a key.
        """
    try:
        value = json_data[key]
    except KeyError:
        value = None
    return value


def round2nearestN(x, N=1):
    """Round number :math:`x` to nearest :math:`N`.

    Parameters
    ----------
    x : int or float
        number to round.
    N : int or float
        number to round :math:`x` to.

    Returns
    -------
    int or float
        :math:`x` rounded to nearest :math:`N`.

    """
    if isinstance(N, int):
        return int(N * round(float(x) / N))
    else:
        return N * round(float(x) / N)


def vertex_weight_normalize_active_vertex():
    """Normalize active vertex’s weights

    """
    pass


def set_dimension(tensor, axis, value):
    """Set the length of a tensor along the specified dimension.

  Args:
    tensor: Tensor to define shape of.
    axis: Dimension to set the static shape for.
    value: Integer holding the length.

  Raises:
    ValueError: When the tensor already has a different length specified.
  """
    shape = tensor.shape.as_list()
    if shape[axis] not in (value, None):
        message = 'Cannot set dimension {} of tensor {} to {}; is already {}.'
        raise ValueError(message.format(axis, tensor.name, value, shape[axis]))
    shape[axis] = value
    tensor.set_shape(shape)


def quote_str(obj):
    """
    Adds extra quotes to a string. If the argument is not a string it is
    returned unmodified

    :param obj: Object
    :type  obj: any

    :rtype: Same as argument

    For example:

        >>> import putil.misc
        >>> putil.misc.quote_str(5)
        5
        >>> putil.misc.quote_str('Hello!')
        '"Hello!"'
        >>> putil.misc.quote_str('He said "hello!"')
        '\\'He said "hello!"\\''
    """
    if not isinstance(obj, str):
        return obj
    else:
        return "'{obj}'".format(obj=obj) if '"' in obj else '"{obj}"'.format(
            obj=obj)


def write(data):
    """Write a chunk of data to the file. See Python documentation for
        :class:`io.RawIOBase` for details.
        """


@staticmethod
def vertex_count(pos=None, **kwargs):
    """Take the output of validate() as input."""
    return pos.shape[0] * 2


def append(key, value):
    """
        Дописать в конец значения ключа еще один элемент.
        Работает только над  существующими ключами, если ключ
        не существует, будет возвращена ошибка C{KeyError}.

        @param key: ключ
        @type key: C{str}
        @param value: дописываемое значение
        @return: Deferred о завершении операции
        @rtype: C{twisted.internet.Deferred}
        """


@classmethod
def fetch(cls, client, _id):
    """
        fetch by instrument id
        """
    return cls.fetch_list(client, [_id])[0]


def numToString(num, numDigits):
    """
        Given a number returns its string format with the specified length, adding '0' if necessary

        @param num: A number (int)
        @param numDigits: Length of the output string (int)
        @return: A tuple (status,statusContent), where statusContent is a number in string format in case status = 0 or an error in case status = -1
    """
    if not isinstance(num, int):
        return -1, 'Bad number'
    strNum = str(num)
    if numDigits < len(strNum):
        return -1, 'Bad digit number'
    for i in range(numDigits - len(strNum)):
        strNum = '0' + strNum
    return 0, strNum


def tic():
    """Start a stopwatch timer"""
    import time
    global TICTOC_START_TIME
    TICTOC_START_TIME = time.time()


def transform_login(config):
    """
    Parse login data as dict. Called from load_from_file and
    also can be used when collecting information from other
    sources as well.

    :param dict data: data representing the valid key/value pairs
           from smcrc
    :return: dict dict of settings that can be sent into session.login
    """
    verify = True
    if config.pop('smc_ssl', None):
        scheme = 'https'
        verify = config.pop('ssl_cert_file', None)
        if config.pop('verify_ssl', None):
            if not verify:
                verify = False
        else:
            verify = False
    else:
        scheme = 'http'
        config.pop('verify_ssl', None)
        config.pop('ssl_cert_file', None)
        verify = False
    transformed = {}
    url = '{}://{}:{}'.format(scheme, config.pop('smc_address', None),
        config.pop('smc_port', None))
    timeout = config.pop('timeout', None)
    if timeout:
        try:
            timeout = int(timeout)
        except ValueError:
            timeout = None
    api_version = config.pop('api_version', None)
    if api_version:
        try:
            float(api_version)
        except ValueError:
            api_version = None
    transformed.update(url=url, api_key=config.pop('smc_apikey', None),
        api_version=api_version, verify=verify, timeout=timeout, domain=
        config.pop('domain', None))
    if config:
        transformed.update(kwargs=config)
    return transformed


def execute(need_active: bool=False):
    """Execute selected file

    :param need_active: Need Active, Only execute if there’s an active selected file in the file list
    :type need_active: bool
    """
    pass


def url_scheme_is_secure(url):
    """Check if the URL is one that requires SSL/TLS."""
    scheme, _dest = url.split('://')
    return scheme == 'elks'


def clamp_phase(phase):
    """
    Returns phase with all values mapped to between +/- 180 degrees.
    """
    return (phase + 180.0) % 360.0 - 180.0


def _glsl_mix(controls=None):
    """Generate a GLSL template function from a given interpolation patterns
    and control points."""
    assert (controls[0], controls[-1]) == (0.0, 1.0)
    ncolors = len(controls)
    assert ncolors >= 2
    if ncolors == 2:
        s = '    return mix($color_0, $color_1, t);\n'
    else:
        s = ''
        for i in range(ncolors - 1):
            if i == 0:
                ifs = 'if (t < %.6f)' % controls[i + 1]
            elif i == ncolors - 2:
                ifs = 'else'
            else:
                ifs = 'else if (t < %.6f)' % controls[i + 1]
            adj_t = '(t - %s) / %s' % (controls[i], controls[i + 1] -
                controls[i])
            s += '%s {\n    return mix($color_%d, $color_%d, %s);\n} ' % (ifs,
                i, i + 1, adj_t)
    return 'vec4 colormap(float t) {\n%s\n}' % s


def normals_make_consistent(calc_length: bool=False):
    """Recalculate the direction of selected handles

    :param calc_length: Length, Recalculate handle length
    :type calc_length: bool
    """
    pass


def _get_empty_dep_frame():
    """
    Creates an empty departement entry

    :returns: an empty departement entry.
    :rtype: dict

    """
    return {'id': [], 'nom': [], 'geometry': []}


def _bytes_to_unicode(obj):
    """
    Convert a non-`bytes` type object into a unicode string.

    :param obj: the object to convert
    :return: If the supplied `obj` is of type `bytes`, decode it into a unicode
        string. If the `obj` is anything else (including None), the original
        `obj` is returned. If the object is converted into a unicode string,
        the type would be `unicode` for Python 2.x or `str` for Python 3.x.
    """
    return obj.decode() if isinstance(obj, bytes) else obj


def ds_IsEmpty(ds):
    """Check to see if dataset is empty after warp
    """
    out = False
    b = ds.GetRasterBand(1)
    try:
        mm = b.ComputeRasterMinMax()
        if mm[0] == mm[1]:
            ndv = b.GetNoDataValue()
            if ndv is None:
                out = True
            elif mm[0] == ndv:
                out = True
    except Exception:
        out = True
    return out


def get_value_from_packet_for_layer_field(packet, layer, field):
    """
        Gets the value from the packet for the specified 'layer' and 'field'

        Args:
            packet: The packet where you'll be retrieving the value from
            layer: The layer that contains the field
            field: The field that contains the value

        Returns:
            the value at packet[layer][key] or None
            or None, if any of the arguments are None
    """
    if not packet or not layer or not field:
        return None
    for current_layer in packet.layers:
        if layer == current_layer.__dict__['_layer_name'
            ] and current_layer.__dict__['_all_fields']:
            return current_layer.__dict__['_all_fields'][field]
    return None


def seams_from_islands(mark_seams: bool=True, mark_sharp: bool=False):
    """Set mesh seams according to island setup in the UV editor

    :param mark_seams: Mark Seams, Mark boundary edges as seams
    :type mark_seams: bool
    :param mark_sharp: Mark Sharp, Mark boundary edges as sharp
    :type mark_sharp: bool
    """
    pass


def bar_generator(obj_axis, left, width, height, bottom, x_errors, y_errors,
    p_bars, p_errors):
    """Return a bar object
    Generate a matplotlib.container.BarContainer object

    Args:
        obj_axis (object): a matplotlib axis object
        left (ndarray): the left positions of the rectangles
        width (ndarray): the width of rectangles
        height (ndarray): the height of the rectangles
        bottom (ndarray): the bottom of the rectangles
        x_errors (ndarray): errors along x
        y_errors (ndarray): errors along y
        p_bars (dict): parameters for the bar plot
        p_errors (dict): parameters for the error bars

    Returns:
        a matplotlib.container.BarContainer object
    """
    error_bar_properties = {'capsize': p_errors['cap']['size'], 'capthick':
        p_errors['cap']['thickness'], 'elinewidth': p_errors['line'][
        'width'], 'ecolor': p_errors['color']['edge'], 'errorevery':
        p_errors['resample_window_size']}
    return obj_axis.bar(left=left, width=width, height=height, bottom=
        bottom, xerr=x_errors, yerr=y_errors, color=p_bars['color']['face'],
        edgecolor=p_bars['color']['edge'], linewidth=p_bars['line']['width'
        ], orientation=p_bars['orientation'], align=p_bars['align'], alpha=
        p_bars['opacity'], error_kw=error_bar_properties)


@classmethod
def get_exchange_name(cls):
    """
        Get exchange name
        :return: Exchange name string
        """
    return 'BTCC_Future'


def alpha(algorithm_returns, treasury_return, benchmark_returns, beta):
    """
    http://en.wikipedia.org/wiki/Alpha_(investment)
    Args:
        algorithm_period_return (float):
            Return percentage from algorithm period.
        treasury_period_return (float):
            Return percentage for treasury period.
        benchmark_period_return (float):
            Return percentage for benchmark period.
        beta (float):
            beta value for the same period as all other values
    Returns:
        float. The alpha of the algorithm.
    """
    return algorithm_returns - (treasury_return + beta * (benchmark_returns -
        treasury_return))


def delete_table(TableName=None):
    """
    The DeleteTable operation deletes a table and all of its items. After a DeleteTable request, the specified table is in the DELETING state until DynamoDB completes the deletion. If the table is in the ACTIVE state, you can delete it. If a table is in CREATING or UPDATING states, then DynamoDB returns a ResourceInUseException . If the specified table does not exist, DynamoDB returns a ResourceNotFoundException . If table is already in the DELETING state, no error is returned.
    When you delete a table, any indexes on that table are also deleted.
    If you have DynamoDB Streams enabled on the table, then the corresponding stream on that table goes into the DISABLED state, and the stream is automatically deleted after 24 hours.
    Use the DescribeTable action to check the status of the table.
    See also: AWS API Documentation

    Examples
    This example deletes the Music table.
    Expected Output:

    :example: response = client.delete_table(
        TableName='string'
    )

    :type TableName: string
    :param TableName: [REQUIRED]
            The name of the table to delete.

    :rtype: dict
    :return: {
        'TableDescription': {
            'AttributeDefinitions': [
                {
                    'AttributeName': 'string',
                    'AttributeType': 'S'|'N'|'B'
                },
            ],
            'TableName': 'string',
            'KeySchema': [
                {
                    'AttributeName': 'string',
                    'KeyType': 'HASH'|'RANGE'
                },
            ],
            'TableStatus': 'CREATING'|'UPDATING'|'DELETING'|'ACTIVE',
            'CreationDateTime': datetime(2015, 1, 1),
            'ProvisionedThroughput': {
                'LastIncreaseDateTime': datetime(2015, 1, 1),
                'LastDecreaseDateTime': datetime(2015, 1, 1),
                'NumberOfDecreasesToday': 123,
                'ReadCapacityUnits': 123,
                'WriteCapacityUnits': 123
            },
            'TableSizeBytes': 123,
            'ItemCount': 123,
            'TableArn': 'string',
            'LocalSecondaryIndexes': [
                {
                    'IndexName': 'string',
                    'KeySchema': [
                        {
                            'AttributeName': 'string',
                            'KeyType': 'HASH'|'RANGE'
                        },
                    ],
                    'Projection': {
                        'ProjectionType': 'ALL'|'KEYS_ONLY'|'INCLUDE',
                        'NonKeyAttributes': [
                            'string',
                        ]
                    },
                    'IndexSizeBytes': 123,
                    'ItemCount': 123,
                    'IndexArn': 'string'
                },
            ],
            'GlobalSecondaryIndexes': [
                {
                    'IndexName': 'string',
                    'KeySchema': [
                        {
                            'AttributeName': 'string',
                            'KeyType': 'HASH'|'RANGE'
                        },
                    ],
                    'Projection': {
                        'ProjectionType': 'ALL'|'KEYS_ONLY'|'INCLUDE',
                        'NonKeyAttributes': [
                            'string',
                        ]
                    },
                    'IndexStatus': 'CREATING'|'UPDATING'|'DELETING'|'ACTIVE',
                    'Backfilling': True|False,
                    'ProvisionedThroughput': {
                        'LastIncreaseDateTime': datetime(2015, 1, 1),
                        'LastDecreaseDateTime': datetime(2015, 1, 1),
                        'NumberOfDecreasesToday': 123,
                        'ReadCapacityUnits': 123,
                        'WriteCapacityUnits': 123
                    },
                    'IndexSizeBytes': 123,
                    'ItemCount': 123,
                    'IndexArn': 'string'
                },
            ],
            'StreamSpecification': {
                'StreamEnabled': True|False,
                'StreamViewType': 'NEW_IMAGE'|'OLD_IMAGE'|'NEW_AND_OLD_IMAGES'|'KEYS_ONLY'
            },
            'LatestStreamLabel': 'string',
            'LatestStreamArn': 'string'
        }
    }

    :returns:
    S - the attribute is of type String
    N - the attribute is of type Number
    B - the attribute is of type Binary

    """
    pass


def read_flat_parameters(fname):
    """Read flat channel rejection parameters from .cov or .ave config file."""
    with open(fname, 'r') as f:
        lines = f.readlines()
    reject_names = ['gradFlat', 'magFlat', 'eegFlat', 'eogFlat', 'ecgFlat']
    reject_pynames = ['grad', 'mag', 'eeg', 'eog', 'ecg']
    flat = dict()
    for line in lines:
        words = line.split()
        if words[0] in reject_names:
            flat[reject_pynames[reject_names.index(words[0])]] = float(words[1]
                )
    return flat


def get_output_group(building_name, mapping):
    """
	Gets output tags for a specified building

	Arguments
		building_name -- the name of the building

	Returns
		output_group -- list of opc_tags, in the order specified by mapping.json, corresponding to the outputs of the specified building
	"""
    return mapping[building_name]['Outputs']


def _is_subclass(type_, class_or_tuple):
    """Determine if the type is a subclass of the given class or classes.

    This takes __origin__ classes into consideration and does not raise.

    Args:
        type_: The type that may be a subclass.
        class_or_tuple: A type or a tuple containing multiple types of which
            type_ may be a subclass.

    Returns:
        A boolean indicating whether the given type is a subclass of the
    """
    try:
        return issubclass(type_, class_or_tuple)
    except (TypeError, AttributeError):
        pass
    if hasattr(type_, '__origin__') and type_.__origin__:
        try:
            return issubclass(type_.__origin__, class_or_tuple)
        except (TypeError, AttributeError):
            pass
    return False


@classmethod
def can_be_used(cls):
    """
        Indicates whether or not this tool can be executed now. Useful when you
        need to check for certain environmental conditions (e.g., Python
        version, dependency availability, etc).

        Unless overridden, always returns ``True``.

        :rtype: bool
        """
    return True


def scott_rule_of_thumb(n_samples, dimension):
    """
    Scott's rule of thumb.

    .. math::

       \\left ( \\frac{1}{n} \\right ) ^{\\frac{1}{d+4}}

    (see also scipy.stats.kde.gaussian_kde.scotts_factor)
    """
    return n_samples ** (-1.0 / (dimension + 4))


def keep_file(filepath):
    """Decide if we keep the filepath, solely by exlcusion of end of path

    This is primarily to avoid keeping .pyc files

    >>> keep_file('/foo.pyc')
    False

    """
    ignoredpathendings = ['.pyc']
    for ending in ignoredpathendings:
        if filepath.endswith(ending):
            return False
    return True


def debug_iis(model):
    """
    Performs reduction to an Irreducible Inconsistent Subsystem (IIS)

    :param model:
    :return:
    """
    out_c = list()
    out_v = list()
    if model.solver.__class__.__module__ == 'optlang.gurobi_interface':
        model.solver.problem.computeIIS()
        print('# Constraints:')
        for c in model.solver.problem.getConstrs():
            if c.IISConstr:
                out_c.append(c)
                print('%s' % c.constrName)
        print('# Variables:')
        for v in model.solver.problem.getVars():
            if v.IISUB != 0 or v.IISLB != 0:
                out_v.append(v)
                print('{}: IISLB = {}, IISUB = {}, (original bounds {}, {})'
                    .format(v.VarName, v.IISLB, v.IISUB, v.LB, v.UB))
    elif model.solver.__class__.__module__ == 'optlang.cplex_interface':
        model.solver.problem.conflict.refine(model.solver.problem.conflict.
            all_constraints())
    else:
        model.logger.error('Not implemented for solver {}'.format(model.solver)
            )
    return out_c, out_v


def serialise_none(b, context=None):
    """Serialise a None value.

    Ignores its parameter.

    """
    return b''


@staticmethod
def _binary(x, l):
    """
        Generates the binary representation of a certain length L as a tuple for a specific positive integer X.

        Parameters:
            x: Integer -> The number for which the binary representation should be generated.
            l: Integer -> Length of the binary representation.
        Return value: Binary representation of the number.
        Return type: Tuple of zeros and ones
        """
    binary = list(map(int, bin(x)[bin(x).find('b') + 1:]))
    if len(binary) < l:
        binary = [0] * (l - len(binary)) + binary
    return tuple(binary)


def unpack_meta(*inputs, **kwinputs):
    """Update ``kwinputs`` with keys and values from its ``meta`` dictionary."""
    if 'meta' in kwinputs:
        new_kwinputs = kwinputs['meta'].copy()
        new_kwinputs.update(kwinputs)
        kwinputs = new_kwinputs
    return inputs, kwinputs


def locale_explode(locale):
    """For non-complete locales, missing elements will be None.

    :param locale: The ISO locale string to explode.
    :return:  A tuple (language, country, variant, language_country, language@variant).
    """
    pass


@classmethod
def arrow_cl(cls, arrow1, arrow2):
    """Left to Right arrow composition

        This expressions means: maybe cast the string as an int, then
        maybe add 1

        >>> from fp.monads.maybe import Maybe, Just
        >>> from fp import p
        >>> maybe_int = p(Maybe.catch, int)
        >>> string_to_plus = Maybe.arrow_cl(maybe_int, lambda x: Just(x+1))
        >>> string_to_plus("1")
        Just(2)

        >>> string_to_plus("a")
        Nothing
        """
    return lambda x: arrow1(x).bind(arrow2)


@classmethod
def register_fallback(cls, container):
    """Set the Container fallback format"""
    cls.fallback_container = container


def cleanOptions(options):
    """
    Takes an options dict and returns a tuple containing the daemonize boolean,
    the reload boolean, and the parsed list of cleaned options as would be
    expected to be passed to hx
    """
    _reload = options.pop('reload')
    dev = options.pop('dev')
    opts = []
    store_true = ['--nocache', '--global_cache', '--quiet', '--loud']
    store_false = []
    for key, value in options.items():
        key = '--' + key
        if key in store_true and value or key in store_false and not value:
            opts += [key]
        elif value:
            opts += [key, str(value)]
    return _reload, opts


def _compare_lists(*args):
    """
    Compare two or more lists. Return True if all equals.
    """
    if not args:
        return True
    compared_item = set(args[0])
    for item in args[1:]:
        if compared_item != set(item):
            return False
    return True


def quote(s):
    """
    Ensure that primary key values do not confuse the admin URLs by escaping
    any '/', '_' and ':' and similarly problematic characters.
    Similar to urllib.parse.quote(), except that the quoting is slightly
    different so that it doesn't get automatically unquoted by the Web browser.
    """
    if not isinstance(s, str):
        return s
    res = list(s)
    for i in range(len(res)):
        c = res[i]
        if c in ':/_#?;@&=+$,"[]<>%\n\\':
            res[i] = '_%02X' % ord(c)
    return ''.join(res)


def count_elems(path):
    """Count elements in a path and return a dictionary keyed with label"""
    res = dict()
    for n in path:
        res[n] = res.get(n, 0) + 1
    return res


def ctx3(**kw):
    """swap to three-armed context"""


def _as_bytes(s):
    """ Used to ensure string is treated as bytes

    The output

    Args:
        s (str): string to convert to bytes

    Returns:
        byte-encoded string

    Example:
        >>> str(_as_bytes('Hello, World').decode()) # Duck typing to check for byte-type object
        'Hello, World'

    """
    if isinstance(s, bytes):
        return s
    return bytes(s, encoding='latin_1')


def round_half_to_even(n):
    """

        >>> round_half_to_even(3)
        3
        >>> round_half_to_even(3.2)
        3
        >>> round_half_to_even(3.5)
        4
        >>> round_half_to_even(3.7)
        4
        >>> round_half_to_even(4)
        4
        >>> round_half_to_even(4.2)
        4
        >>> round_half_to_even(4.5)
        4
        >>> round_half_to_even(4.7)
        5

    :param n:
    :return:
    """
    ten_n = 10 * n
    if ten_n == int(ten_n) and ten_n % 10 == 5:
        up = int(n + 0.5)
        down = int(n - 0.5)
        return up if up % 2 == 0 else down
    else:
        return int(round(n))


def build_relabel_dict(x):
    """Relabel the input ids to continuous ids that starts from zero.

    The new id follows the order of the given node id list.

    Parameters
    ----------
    x : list
      The input ids.

    Returns
    -------
    relabel_dict : dict
      Dict from old id to new id.
    """
    relabel_dict = {}
    for i, v in enumerate(x):
        relabel_dict[v] = i
    return relabel_dict


def serpentine_y(x, y, matrix):
    """Every other column is indexed in reverse."""
    if x % 2:
        return x, matrix.rows - 1 - y
    return x, y


def synchrotron_cooling_constant(B):
    """
    Compute the characteristic cooling constant for synchrotron cooling

    Define a factor that is dependent on the magnetic field B.
    The cooling time of an electron at energy gamma is
    DT = 6 * pi * me*c / (sigma_T B^2 gamma)
    DT = (1.29234E-9 B^2 gamma)^-1 seconds
    DT = (cool * gamma)^-1 seconds
    where B is in Gauss.

    """
    bulk_gamma = 300.0
    const_factor = 1.29234e-09
    C0 = const_factor * B ** 2
    return C0


def _uniquify(labels):
    """
    Takes a list of strings, and makes it unique by appending _1, _2, etc to duplicates
    In-Place

    :param labels: Input list of strings
    :return: None, modification is in-place
    """
    count_dict = dict()
    for label in labels:
        if label not in count_dict:
            count_dict.update({label: 0})
        count_dict[label] = count_dict[label] + 1
    for i in range(len(labels))[::-1]:
        if count_dict[label] > 1:
            labels[i] = labels[i] + '_' + str(count_dict[label])
            count_dict[label] = count_dict[label] - 1


def get_user_from_cname(cname):
    """
    Get user name from the cname.
    :param cname:
    :return:
    """
    if cname is None:
        return None
    return cname.split('/', 1)[0]


def genattr(elems):
    """ Function that generates a list with the childnodes of a xml element  """
    d = []
    for e in elems[0].childNodes:
        if e.nodeType == e.ELEMENT_NODE:
            d.append(e)
    return d


@classmethod
def _get_atr(cls, df, window=None):
    """ Average True Range

        The average true range is an N-day smoothed moving average (SMMA) of
        the true range values.  Default to 14 days.
        https://en.wikipedia.org/wiki/Average_true_range

        :param df: data
        :return: None
        """
    if window is None:
        window = cls.ATR_SMMA
        column_name = 'atr'
    else:
        window = int(window)
        column_name = 'atr_{}'.format(window)
    tr_smma_column = 'tr_{}_smma'.format(window)
    df[column_name] = df[tr_smma_column]
    cls._drop_columns(df, [tr_smma_column])


def path_shift(script_name, path_info, shift=1):
    """ Shift path fragments from PATH_INFO to SCRIPT_NAME and vice versa.

        :return: The modified paths.
        :param script_name: The SCRIPT_NAME path.
        :param script_name: The PATH_INFO path.
        :param shift: The number of path fragments to shift. May be negative to
          change the shift direction. (default: 1)
    """
    if shift == 0:
        return script_name, path_info
    pathlist = path_info.strip('/').split('/')
    scriptlist = script_name.strip('/').split('/')
    if pathlist and pathlist[0] == '':
        pathlist = []
    if scriptlist and scriptlist[0] == '':
        scriptlist = []
    if shift > 0 and shift <= len(pathlist):
        moved = pathlist[:shift]
        scriptlist = scriptlist + moved
        pathlist = pathlist[shift:]
    elif shift < 0 and shift >= -len(scriptlist):
        moved = scriptlist[shift:]
        pathlist = moved + pathlist
        scriptlist = scriptlist[:shift]
    else:
        empty = 'SCRIPT_NAME' if shift < 0 else 'PATH_INFO'
        raise AssertionError('Cannot shift. Nothing left from %s' % empty)
    new_script_name = '/' + '/'.join(scriptlist)
    new_path_info = '/' + '/'.join(pathlist)
    if path_info.endswith('/') and pathlist:
        new_path_info += '/'
    return new_script_name, new_path_info


def graph_is_connected(edges, players):
    """
    Test if the set of edges defines a graph in which each player is connected
    to at least one other player. This function does not test if the graph is
    fully connected in the sense that each node is reachable from every other
    node.

    Parameters:
    -----------
    edges : a list of 2 tuples
    players : a list of player names

    Returns:
    --------
    boolean : True if the graph is connected as specified above.
    """
    player_indices = set(range(len(players)))
    node_indices = set()
    for edge in edges:
        for node in edge:
            node_indices.add(node)
    return player_indices == node_indices


def dotted_name(cls):
    """Dotted name for a class.

    Example: ``my.module.MyClass``.

    :param cls: the class to generate a dotted name for.
    :return: a dotted name to the class.
    """
    return '%s.%s' % (cls.__module__, cls.__name__)


def to_indra_statements(graph):
    """Export this graph as a list of INDRA statements using the :py:class:`indra.sources.pybel.PybelProcessor`.

    :param pybel.BELGraph graph: A BEL graph
    :rtype: list[indra.statements.Statement]
    """
    from indra.sources.bel import process_pybel_graph
    pbp = process_pybel_graph(graph)
    return pbp.statements


def GetTargetCBVs(model):
    """
  Returns the design matrix of CBVs for the given target.

  :param model: An instance of the :py:obj:`everest` model for the target

  """
    raise NotImplementedError('This mission is not yet supported.')


def available():
    """Return a boolean indicating whether the action is available
        """


def axis_conversion_ensure(operator: 'bpy.types.Operator', forward_attr:
    str, up_attr: str) ->bool:
    """Function to ensure an operator has valid axis conversion settings, intended to be used from bpy.types.Operator.check.

    :param operator: the operator to access axis attributes from.
    :type operator: 'bpy.types.Operator'
    :param forward_attr: attribute storing the forward axis
    :type forward_attr: str
    :param up_attr: attribute storing the up axis
    :type up_attr: str
    :return:  True if the value was modified.
    """
    pass


def p_gcl_or(t):
    """gcl_expr : gcl_expr OP_OR gcl_expr"""
    t[0] = 'Or', t[1], t[3]


def hide_fields_in_newer_versions(obj):
    """This method hides fields that were added in newer API versions.

    Certain node fields were introduced at certain API versions.
    These fields are only made available when the request's API version
    matches or exceeds the versions when these fields were introduced.
    """
    pass


def install_conda_target(conda_target, conda_context, skip_environment=False):
    """
    Install specified target into a its own environment.

    Return the process exit code (i.e. 0 in case of success).
    """
    if not skip_environment:
        create_args = ['--name', conda_target.install_environment,
            conda_target.package_specifier]
        return conda_context.exec_create(create_args)
    else:
        return conda_context.exec_install([conda_target.package_specifier])


def _set_plengthday(params, name: str, index: int, value: float):
    """Adjust the Parameters.plength_day parameter"""
    if index is not None:
        raise IndexError('You cannot index the lengthday')
    params.plength_day = value


def stringified_dict_contains_value(key, value, str_dict):
    """Checks if dict in for of string like "{'test': 5}" contains
    key/value pair. This works faster, then creating actual dict
    from string since this operation is called for each task in case
    of kwargs search."""
    value = str(value)
    try:
        key_index = str_dict.index(key) + len(key) + 3
    except ValueError:
        return False
    try:
        comma_index = str_dict.index(',', key_index)
    except ValueError:
        comma_index = str_dict.index('}', key_index)
    return str(value) == str_dict[key_index:comma_index].strip('"\'')


def peek_indentation(stream):
    """
    Counts but doesn't actually read indentation level on new line, returning the count or None if line is blank
    """
    indentation = 0
    while True:
        ch = stream.text[stream.ptr + indentation]
        if ch == '\n':
            return None
        if not ch.isspace():
            return indentation
        indentation += 1


def split(path):
    """Split a path into (head, tail) pair.

    This function splits a path into a pair (head, tail) where 'tail' is
    the last pathname component and 'head' is all preceding components.

    Arguments:
        path (str): Path to split

    Returns:
        (str, str): a tuple containing the head and the tail of the path.

    Example:
        >>> split("foo/bar")
        ('foo', 'bar')
        >>> split("foo/bar/baz")
        ('foo/bar', 'baz')
        >>> split("/foo/bar/baz")
        ('/foo/bar', 'baz')

    """
    if '/' not in path:
        return '', path
    split = path.rsplit('/', 1)
    return split[0] or '/', split[1]


def are_pairwise_disjoint(it, raise_error=False):
    """
    Determines whether a collection of elements are pairwise disjoint.

    :param it: iterable of elements
    :param raise_error: if a (descriptive) error shall be raised in case the
    elements iterables are not disjoint
    :return: true if all elements are pairwise disjoint

    >>> are_pairwise_disjoint([[1,2,3], [4,5,6], [7,8]])
    True
    >>> are_pairwise_disjoint([[1,2,3], [1,5]])
    False

    """
    all_elements = set()
    for i, l in enumerate(it):
        s = set(l)
        if all_elements.isdisjoint(s):
            all_elements = all_elements.union(s)
        else:
            if raise_error:
                raise ValueError(
                    'Set at index {} is not disjoint withprevious sets. Common entries are {}'
                    .format(i, all_elements.intersection(s)))
            return False
    return True


@classmethod
def get_code_color(cls, code):
    """ Retrieve the HTTP status code color

            :param code: The code to retrieve the color from.
        """
    color = 255
    if code in range(200, 299):
        color = 77
    elif code in range(300, 399):
        color = 169
    elif code in range(400, 499):
        color = 215
    elif code in range(500, 599):
        color = 9
    return color


def validate_setup(transactions):
    """ First two transactions must set rate & days. """
    if not transactions:
        return True
    try:
        first, second = transactions[:2]
    except ValueError:
        print(
            'Error: vacationrc file must have both initial days and rates entries'
            )
        return False
    parts1, parts2 = first.split(), second.split()
    if parts1[0] != parts2[0]:
        print('Error: First two entries in vacationrc must have the same date')
        return False
    if 'rate' not in (parts1[1], parts2[1]) or 'days' not in (parts1[1],
        parts2[1]):
        print('Error: First two entries in vacationrc must set days and rate')
        return False
    return True


def field_in_level(field, level):
    """
    true if field is in level, false otherwise
    """
    return True if field in level else False


def bibtex_substring(string, start, length):
    """
    Return a substring of the given length, starting from the given position.

    start and length are 1-based. If start is < 0, it is counted from the end
    of the string. If start is 0, an empty string is returned.

    >>> print(bibtex_substring('abcdef', 1, 3))
    abc
    >>> print(bibtex_substring('abcdef', 2, 3))
    bcd
    >>> print(bibtex_substring('abcdef', 2, 1000))
    bcdef
    >>> print(bibtex_substring('abcdef', 0, 1000))
    <BLANKLINE>
    >>> print(bibtex_substring('abcdef', -1, 1))
    f
    >>> print(bibtex_substring('abcdef', -1, 2))
    ef
    >>> print(bibtex_substring('abcdef', -2, 3))
    cde
    >>> print(bibtex_substring('abcdef', -2, 1000))
    abcde
    """
    if start > 0:
        start0 = start - 1
        end0 = start0 + length
    elif start < 0:
        end0 = len(string) + start + 1
        start0 = end0 - length
    else:
        return u''
    return string[start0:end0]


def p_common_scalar_dnumber(p):
    """common_scalar : DNUMBER"""
    p[0] = float(p[1])


@staticmethod
def count_jailed(model):
    """
        Helper method to count jailed agents.
        """
    count = 0
    for agent in model.schedule.agents:
        if agent.breed == 'citizen' and agent.jail_sentence:
            count += 1
    return count


def judge_direction(left_result, left_percent, right_result, right_percent):
    """
    根据左/右眼的九宫位置, 左/右眼用于判断眼球位置的有效的像素占总数的比例,给出双眼方向判定
    :param left_result: 左眼的九宫位置
    :param left_percent: 左眼用于判断眼球位置的有效的像素占总数的比例
    :param right_result: 右眼的九宫位置
    :param right_percent: 右眼用于判断眼球位置的有效的像素占总数的比例
    :return: 给出最终的双眼方向, 一个结果
    """
    if (left_result == 4) & (right_result != 4) | (right_result == 4) & (
        left_result != 4):
        return right_result if left_result == 4 else left_result
    elif (left_result == 1) & ((right_result == 0) | (right_result == 2)) | (
        right_result == 1) & ((left_result == 0) | (left_result == 2)):
        return right_result if left_result == 1 else left_result
    elif (left_result == 7) & ((right_result == 6) | (right_result == 8)) | (
        right_result == 7) & ((left_result == 6) | (left_result == 8)):
        return right_result if left_result == 7 else left_result
    elif (left_result == 3) & ((right_result == 0) | (right_result == 6)) | (
        right_result == 3) & ((left_result == 0) | (left_result == 6)):
        return right_result if left_result == 3 else left_result
    elif (left_result == 5) & ((right_result == 2) | (right_result == 8)) | (
        right_result == 5) & ((left_result == 2) | (left_result == 8)):
        return right_result if left_result == 7 else left_result
    else:
        return right_result if left_percent < right_percent else left_result


def bC_Mg_CO3_HMW84(T, P):
    """c-a: magnesium carbonate [HMW84]."""
    b0 = 0.0
    b1 = 0.0
    b2 = 0.0
    C0 = 0
    C1 = 0
    alph1 = 1.4
    alph2 = -9
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


def i_to_white(i, normalize=False):
    """Convert a number between 0.0 and 1.0 to a shade of white.

    Parameters
    ----------
    i : float
        A number between 0.0 and 1.0.
    normalize : bool, optional
        Normalize the resulting RGB values.
        Default is to return integer values ranging from 0 to 255.

    Returns
    -------
    tuple
        The RGB values of the color corresponding to the provided number.
        If `normalize` is true, the RGB values are normalized to values between 0.0 and 1.0.
        If `normalize` is false, the RGB values are integers between 0 and 255.

    Examples
    --------
    >>> i_to_white(1.0)
    (255, 255, 255)
    >>> i_to_white(0.0)
    (0, 0, 0)
    """
    i = max(i, 0.0)
    i = min(i, 1.0)
    rgb = min(i * 255, 255)
    if not normalize:
        return int(rgb), int(rgb), int(rgb)
    rgb = rgb / 255
    return rgb, rgb, rgb


def decrypt(key, data):
    """Returns the decrypted data"""


def list(condition=(), order=''):
    """return a list of data records satisfying *condition* ordered by *order*.

    *condition* is a sequences of tuples *field*, *value*, *op*
    (with *op* optional, defaulting to `=`).

    *order* is a blank separated sequence of field names, optionally with suffix
    `+` (default: order increasing) or `-` (order descreasing).

    *order* is combined with the default ordering.
    """


def _get_split_size(split_size):
    """Convert human-readable bytes to machine-readable bytes."""
    if isinstance(split_size, str):
        exp = dict(MB=20, GB=30).get(split_size[-2:], None)
        if exp is None:
            raise ValueError('split_size has to end with either"MB" or "GB"')
        split_size = int(float(split_size[:-2]) * 2 ** exp)
    if split_size > 2147483648:
        raise ValueError('split_size cannot be larger than 2GB')
    return split_size


def py_str(x):
    """convert c string back to python string"""
    return x.decode('utf-8')


def dropout_mask(x, size, prob):
    """
    We pass size in so that we get broadcasting along the sequence dimension
    in RNNDropout.
    """
    return x.new(*size).bernoulli_(1 - prob).div_(1 - prob)


def move_dates(apps, schema_editor):
    """Move dates to models."""
    Domain = apps.get_model('admin', 'Domain')
    DomainAlias = apps.get_model('admin', 'DomainAlias')
    Mailbox = apps.get_model('admin', 'Mailbox')
    Alias = apps.get_model('admin', 'Alias')
    for model in [Domain, DomainAlias, Mailbox, Alias]:
        for instance in model.objects.all():
            instance.creation = instance.dates.creation
            instance.last_modification = instance.dates.last_modification
            instance.save()


def get_lomb_frequency(lomb_model, i):
    """Get the ith frequency from a fitted Lomb-Scargle model."""
    return lomb_model['freq_fits'][i - 1]['freq']


def redir_path_to_dest(path: str):
    """ Convert a path fragment to a redirection destination """
    if path.startswith('/'):
        return path
    return '/' + path


def is_prime(num):
    """Checks that given number is prime or not. Returns a boolean value."""
    for n in range(2, num // 2):
        if num % n is 0:
            return False
    return True


def __getitem__(name):
    """Return the named instance"""


@staticmethod
def p_new_symbols_list(p):
    """new_symbols_list : new_symbols_value
                            | new_symbols_value new_symbols_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def condv(key, dic, default='None'):
    """Helper Function to handle missing keys"""
    try:
        val = dic[key]
        if type(val) == list:
            if not val:
                return ''
            if len(val) == 1:
                return val[0]
            else:
                return ';'.join(val)
        else:
            return dic[key]
    except:
        return default


@classmethod
def get_object_values(cls, obj, ignoreCase=False):
    """Get the values specified for an Object's properties as a set."""
    values = set()
    for attrname, typed_field in obj.properties.typed_fields_with_attrnames:
        if typed_field.comparable:
            val = getattr(obj.properties, attrname)
            if val is not None:
                cls.get_typedfield_values(val, attrname, values, ignoreCase)
    return values


def textbox_add():
    """Add a new text box

    """
    pass


@classmethod
def arraySize(cls, value, typeCode=None):
    """Given a data-value, calculate dimensions for the array"""
    dims = 1
    for base in cls.types(value):
        length = getattr(base, '_length_', None)
        if length is not None:
            dims *= length
    return dims


def _get_boolean_elements():
    """
    Returns sets of elements recognisable as booleans
    """
    true_set = {'True', 'true', 'TRUE', 'tru', 1, 't', 'T', '1', float(1),
        True, 'yes', 'Yes', 'YES', 'Y', 'y'}
    false_set = {'False', 'false', 'FALSE', 'fals', 0, 'f', 'F', '0', float
        (0), False, 'no', 'No', 'NO', 'N', 'n'}
    return true_set, false_set


def Clip(a, b, c):
    """
    Clips the value in `a` based on the extremes `b` and `c`.

    :param `a`: the value to analyze;
    :param `b`: a minimum value;
    :param `c`: a maximum value.
    """
    return (a < b and [b] or [(a > c and [c] or [a])[0]])[0]


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


def select_circle(x: int=0, y: int=0, radius: int=1, gesture_mode: int=0):
    """Use circle selection to select nodes

    :param x: X
    :type x: int
    :param y: Y
    :type y: int
    :param radius: Radius
    :type radius: int
    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    """
    pass


def str_to_utf8(x):
    """ Do it before saving/output to external printer """
    return x.encode('utf-8')


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