@classmethod
def can_skip_password(cls, auth_ctx, user) ->bool:
    """ 账号验证后，是否可以跳过密码过程 """
    return False


@staticmethod
def _get_subject_mapping(subject):
    """
        Get the Jira value mapping for the subject field.

        :param subject: Issue subject
        :return: Jira value mapping for the subject
        """
    return subject


def scaleImg(width, height, img, keepRatio=False):
    """Scale image to given width and height if keep aspect ratio is True
    """
    ignoreAspectMark = '!' if keepRatio is False else ''
    transformStr = '{}{}x{}'.format(ignoreAspectMark, width, height)
    print('Scale to {}'.format(transformStr))
    img.transform(transformStr)
    return img


def is_stack_already_exists_exception(ex):
    """Check whether given exception is "stack already exist"
    Exception class is dynamiclly generated in botocore.
    """
    return ex.__class__.__name__ == 'AlreadyExistsException'


@classmethod
def is_yaml_tag_supported(cls, yaml_tag):
    """
        Implementing classes should return True if they are able to decode yaml objects with this yaml tag.
        Default implementation relies on class attribute `__yaml_tag_suffix__` if provided, either manually or through
        the `@yaml_info` decorator.

        :param yaml_tag:
        :return:
        """
    if hasattr(cls, '__yaml_tag_suffix__'
        ) and cls.__yaml_tag_suffix__ is not None:
        if '__yaml_tag_suffix__' in cls.__dict__:
            return cls.__yaml_tag_suffix__ == yaml_tag
        else:
            raise TypeError(
                '`__yaml_tag_suffix__` field is not redefined by class {}, cannot inherit from YamlAbleproperly.'
                .format(cls))
    else:
        raise NotImplementedError(
            "class {} does not seem to have a non-None '__yaml_tag_suffix__' field. You can either create one manually or by decorating your class with @yaml_info. Alternately you should override the 'is_yaml_tag_supported' method from YamlAble."
            .format(cls))


def dissolve_verts(use_face_split: bool=False, use_boundary_tear: bool=False):
    """Dissolve verts, merge edges and faces

    :param use_face_split: Face Split, Split off face corners to maintain surrounding geometry
    :type use_face_split: bool
    :param use_boundary_tear: Tear Boundary, Split off face corners instead of merging faces
    :type use_boundary_tear: bool
    """
    pass


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

        :param ShowcasePermanentlyDeletedDetails val:
        :rtype: EventDetails
        """
    return cls('showcase_permanently_deleted_details', val)


@staticmethod
def run_final(pathfmt, status):
    """Postprocessor finalization after all files have been downloaded"""


@classmethod
def get_all_by(cls, **kw):
    """
        Shorthand to retrieve data by using filters.
        """
    return cls.query.filter_by(**kw).all()


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


@classmethod
def _from_et(cls, root, parent):
    """
        Create a :class:`Via` from a :code:`via` element.

        :param root: The element tree tree to parse.
        :param parent: :class:`EagleFilePart` that should hold the resulting :class:`EagleFilePart`
        :rtype: :class:`Via`
        """
    n = cls()
    n._init_from_et(root, parent)
    return n


def convertbits(data, frombits, tobits, pad=True):
    """General power-of-2 base conversion."""
    acc = 0
    bits = 0
    ret = []
    maxv = (1 << tobits) - 1
    max_acc = (1 << frombits + tobits - 1) - 1
    for value in data:
        if value < 0 or value >> frombits:
            return None
        acc = (acc << frombits | value) & max_acc
        bits += frombits
        while bits >= tobits:
            bits -= tobits
            ret.append(acc >> bits & maxv)
    if pad:
        if bits:
            ret.append(acc << tobits - bits & maxv)
    elif bits >= frombits or acc << tobits - bits & maxv:
        return None
    return ret


def _split_on_first_equal(line, val='='):
    """Split a line based on first occurrence of " ="

    Parameters
    ----------
    line: str
        string to split
    split: str
        split based on this. Can be multiple characters.
    >>> _split_on_first_equal("this = abc = 1")
    ('this', 'abc = 1')
    """
    l = line.split(' {} '.format(val))
    if l[0].endswith(' {}'.format(val)):
        l[0] = l[0].replace(' {}'.format(val), '')
    return l[0], ' {} '.format(val).join(l[1:])


@staticmethod
def format_user_output(user_id, command_id, message_code, msg_str=None):
    """Formats a string to send to users."""
    msg_str = '' if msg_str is None else ' ' + msg_str
    return f'{user_id} {command_id:d} {message_code:s}{msg_str:s}'


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

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

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


def cos(data=None, name=None, attr=None, out=None, **kwargs):
    """Computes the element-wise cosine of the input array.

    The input should be in radians (:math:`2\\pi` rad equals 360 degrees).

    .. math::
       cos([0, \\pi/4, \\pi/2]) = [1, 0.707, 0]

    The storage type of ``cos`` output is always dense

    Defined in src/operator/tensor/elemwise_unary_op_trig.cc:L90

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

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

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


def line_length(line, tab_width):
    """Calculate the length of a line taking TABs into account.

    :param str line: line of code
    :param int tab_width: tab width

    :returns: The length of the line
    :rtype: int

    """
    length = 0
    for i in line:
        if i == '\t':
            length = (length + tab_width) // tab_width * tab_width
        else:
            length += 1
    return length


def _set_labels(ax, label_format, pos_columns):
    """This sets axes labels according to a label format and position column
    names. Applicable to 2D and 3D plotting.

    Parameters
    ----------
    ax : Axes object
        The axes object on which the plot will be called
    label_format : string
        Format that is compatible with ''.format (e.g.: '{} px')
    pos_columns : list of strings
        List of column names in x, y(, z) order.

    Returns
    -------
    None
    """
    ax.set_xlabel(label_format.format(pos_columns[0]))
    ax.set_ylabel(label_format.format(pos_columns[1]))
    if hasattr(ax, 'set_zlabel') and len(pos_columns) > 2:
        ax.set_zlabel(label_format.format(pos_columns[2]))


def get_pk(row: 'md_table.Table', as_tuple: bool=True):
    """
    Gets the primary key for a Table row.

    :param row: The :class:`.Table` instance to extract the PK from.
    :param as_tuple: Should this PK always be returned as a tuple?
    """
    pk = row.primary_key
    if as_tuple and not isinstance(pk, tuple):
        return pk,
    return pk


def unit_to_kilounit(measure):
    """
    Convert measures in whole units to thousands of units.

    Parameters
    ----------
    measure : array_like
        The measure(s) to be converted

    Returns
    -------
    out : float or :py:class:`numpy.ndarray`
        The converted measure(s)

    Raises
    ------
    TypeError
        If ``measure`` cannot be converted to a :py:class:`numpy.ndarray`

    Examples
    --------
    >>> unit_to_kilounit(1) == 1. / 1000
    True
    """
    return measure / 1000.0


def hasSiblings():
    """Returns True if this mmeber has siblings False otherwise."""


def remove_cols(df, cols):
    """Safely remove columns from dict."""
    for key in cols:
        try:
            del df[key]
        except KeyError:
            pass
    return df


def weightedIntersection(c1, c2, weight1=1, weight2=1):
    """Compute the weighted intersection of c1 and c2.

        If c1 and c2 are None, the output is (0, None).

        If c1 is None and c2 is not None, the output is (weight2, c2).

        If c1 is not None and c2 is None, the output is (weight1, c1).

        Else, and hereafter, c1 is not None and c2 is not None.

        If c1 and c2 are both sets, the output is the sum of the weights
        and the (unweighted) intersection of the sets.

        Else the output is 1 and a Bucket whose keys are the intersection of
        c1 and c2's keys, and whose values are::

          v1*weight1 + v2*weight2

          where:

            v1 is 1        if c1 is a set
                  c1[key]  if c1 is a mapping

            v2 is 1        if c2 is a set
                  c2[key]  if c2 is a mapping

        Note that c1 and c2 must be collections.
        """


def last_update_for(record):
    """Returns the last update timestamp for the given record,
       if available, otherwise False
    """
    if record._model._log_access:
        record_log = record.perm_read()[0]
        return record_log.get('write_date') or record_log.get('create_date'
            ) or False
    return False


@classmethod
def from_file(cls, filepath):
    """Initialize the object from a netcdf_ file"""
    return cls(filepath)


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


@classmethod
def colour(cls, *args):
    """Combines all args into string. Should pass colour modifiers in first followed by the string. Does not need reset sequence at the end."""
    return ''.join(args) + cls.reset


def set_device_mac(run_command_fn, dev_name, mac_address, netns_name=None):
    """Set device MAC address"""
    if netns_name:
        command_prefix = 'ip netns exec %s ' % netns_name
    else:
        command_prefix = ''
    run_command_fn('%s ip link set %s address %s' % (command_prefix,
        dev_name, mac_address), run_as_root=True)


def toggle_xray():
    """Undocumented contribute <https://developer.blender.org/T51061>

    """
    pass


def brightness(rrggbb):
    """ W3C brightness definition
        input:
            hexadecimal color in the format:
            #RRGGBB
        output: value between 0 and 1
    """
    print(rrggbb)
    rr = int(rrggbb[1:3], 16) / int('FF', 16)
    gg = int(rrggbb[3:5], 16) / int('FF', 16)
    bb = int(rrggbb[5:7], 16) / int('FF', 16)
    return (rr * 299.0 + gg * 587.0 + bb * 114.0) / 1000.0


def is_int(str_val):
    """
    Check if str_val is int type
    :param str_val: str
    :return: bool
    """
    if str_val.startswith('-') and str_val[1:].isdigit():
        return True
    elif str_val.isdigit():
        return True
    else:
        return False


def GetAtomFracByID(pId, parmDict, AtLookup, indx):
    """default doc string

    :param type name: description

    :returns: type name: description

    """
    pfx = str(pId) + '::Afrac:'
    Frac = []
    for ind in indx:
        name = pfx + str(AtLookup[ind])
        Frac.append(parmDict[name])
    return Frac


def dumps_etree(pid, record, **kwargs):
    """Dump MARC21 compatible record.

    :param pid: The :class:`invenio_pidstore.models.PersistentIdentifier`
        instance.
    :param record: The :class:`invenio_records.api.Record` instance.
    :returns: A LXML Element instance.
    """
    from dojson.contrib.to_marc21 import to_marc21
    from dojson.contrib.to_marc21.utils import dumps_etree
    return dumps_etree(to_marc21.do(record['_source']), **kwargs)


def make_wget(urls):
    """Download multiple URLs with `wget`

  Parameters
  ----------
  urls : list
    A list of URLs to download from
  """
    return 'wget -c {}'.format(' '.join(urls))


def _F_O2(lbda_mu=0.3):
    """Depolarisation factor of O2 for Rayleigh scattering cross section

    Taken from `Bates 1984 <http://www.sciencedirect.com/science/article/pii/
    0032063384901028>`_

    Parameters
    ----------
    lbda_mu : float or ndarray
        wavelength in micrometers

    Returns
    -------
    float or ndarray
        depolarisation factor of O2

    """
    return 1.096 + 0.001385 / lbda_mu ** 2 + 0.0001448 / lbda_mu ** 4


def _is_internal_frame(frame):
    """Signal whether the frame is an internal CPython implementation detail."""
    filename = frame.f_code.co_filename
    return 'importlib' in filename and '_bootstrap' in filename


def get_residues_with_H(struc):
    """ Get residues containing Hydrogen atoms
    """
    resh_list = []
    for res in struc.get_residues():
        has_h = 0
        for atm in res.get_atoms():
            if atm.element == 'H':
                has_h += 1
        if has_h:
            resh_list.append({'r': res, 'n_h': has_h})
    return resh_list


def multicall():
    """multiple calls at once (boxcarring)"""


def IvyGetApplicationHost(client):
    """
    Equivalent to ``client.fqdn``. IP address is stored under ``client.ip``,
    and port number under ``client.port``

    :param client: an :py:class:`ivy.ivy.IvyClient` object,  as returned by
      :py:func:`IvyGetApplication()`
    """
    return client.fqdn


def any_next_words_form_swear_word(cur_word, words_indices, censor_words):
    """
    Return True, and the end index of the word in the text,
    if any word formed in words_indices is in `CENSOR_WORDSET`.
    """
    full_word = cur_word.lower()
    full_word_with_separators = cur_word.lower()
    for index in iter(range(0, len(words_indices), 2)):
        single_word, end_index = words_indices[index]
        word_with_separators, _ = words_indices[index + 1]
        if single_word == '':
            continue
        full_word = '%s%s' % (full_word, single_word.lower())
        full_word_with_separators = '%s%s' % (full_word_with_separators,
            word_with_separators.lower())
        if (full_word in censor_words or full_word_with_separators in
            censor_words):
            return True, end_index
    return False, -1


@classmethod
def deserialize(cls, doc):
    """Take the deserializer to validate the document."""
    if cls.__objective__ is not None:
        return cls.__objective__.deserialize(doc)
    return doc.copy()


def compatible_encode_method(bytesorstring, encoding='utf-8', erraction=
    'ignore'):
    """When Py2 str.encode is called, it often means bytes.encode in Py3.

     This does either.
     """
    if isinstance(bytesorstring, str):
        return bytesorstring
    assert isinstance(bytesorstring, bytes), str(type(bytesorstring))
    return bytesorstring.decode(encoding, erraction)


@classmethod
def run_hooks(cls, hook_type, *args, **kwargs):
    """Run all hooks of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param **args: args to be passed to every hook function
        :param **kwargs: kwargs to be passed to every hook function
        """
    hook_funcs = cls._hooks_map.get(hook_type) or []
    for hook_func in hook_funcs:
        hook_func(*args, **kwargs)


def set_sigma(cfg, msh):
    """ Set sigmax and sigmaz for PMLs. """
    try:
        cfg.sigmax = float(cfg.sigmax)
    except ValueError:
        D = msh.x[msh.Npml] - msh.x[0]
        cfg.sigmax = 8 * cfg.c0 * (cfg.alpha + 1) / D
    try:
        cfg.sigmaz = float(cfg.sigmaz)
    except ValueError:
        D = msh.z[msh.Npml] - msh.z[0]
        cfg.sigmaz = 8 * cfg.c0 * (cfg.alpha + 1) / D


def __call__():
    """ Return `True`, if context is indexable and `False`otherwise
        """


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

        :param EmmErrorDetails val:
        :rtype: EventDetails
        """
    return cls('emm_error_details', val)


def l_widget(widget):
    """
    Dummy function to be used in the Roxygen documentation

    Description:
        Helper function to ensure that a widget path is associated with a
        loon widget.

    Args:
        widget: widget path name as a string
    Returns:
        widget path name as a string
    @namespace loon.l_widget
    """
    if not isinstance(widget, str):
        widget = widget.plot
    return widget


def environments_command_parser(parent_parser, **kwargs):
    """sets up the argument parser for the environments command"""
    parser = parent_parser.add_parser('environments', description=
        'List all environments in the control-repository of the currently selected profile.'
        , help='list all environments of the selected profile')
    return parser


def stash(create_new: bool=True):
    """Store this action in the NLA stack as a non-contributing strip for later use

    :param create_new: Create New Action, Create a new action once the existing one has been safely stored
    :type create_new: bool
    """
    pass


@classmethod
def as_bounding(cls, points):
    """Construct a Rect as the bounds of a sequence of points.

        :param points: An iterable of the points to bound.

        """
    xs, ys = zip(*points)
    l, r = min(xs), max(xs)
    b, t = min(ys), max(ys)
    return cls(l, r, b, t)


def sortHKLd(HKLd, ifreverse, ifdup, ifSS=False):
    """sort reflection list on d-spacing; can sort in either order

    :param HKLd: a list of [h,k,l,d,...];
    :param ifreverse: True for largest d first
    :param ifdup: True if duplicate d-spacings allowed
    :return: sorted reflection list
    """
    T = []
    N = 3
    if ifSS:
        N = 4
    for i, H in enumerate(HKLd):
        if ifdup:
            T.append((H[N], i))
        else:
            T.append(H[N])
    D = dict(zip(T, HKLd))
    T.sort()
    if ifreverse:
        T.reverse()
    X = []
    okey = ''
    for key in T:
        if key != okey:
            X.append(D[key])
        okey = key
    return X


def mult(x, y):
    """
    Multiply two intergers together
    :param x: first interger
    :param y: second integer
    :return: the result of the arithmetic operation
    """
    return x * y


def get_querystring_for_page(request, page_number, querystring_key,
    default_number=1):
    """Return a querystring pointing to *page_number*."""
    querydict = request.GET.copy()
    querydict[querystring_key] = page_number
    if page_number == default_number:
        del querydict[querystring_key]
    if 'querystring_key' in querydict:
        del querydict['querystring_key']
    if querydict:
        return '?' + querydict.urlencode()
    return ''


def poke_8(library, session, address, data):
    """Write an 8-bit value from the specified address.

    Corresponds to viPoke8 function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session.
    :param address: Source address to read the value.
    :param data: value to be written to the bus.
    :return: Data read from bus.
    :return: return value of the library call.
    :rtype: :class:`pyvisa.constants.StatusCode`
    """
    return library.viPoke8(session, address, data)


def strip_suffix(s, suffix):
    """Strip a suffix from a string, if present."""
    return s[:-len(suffix)] if s.endswith(suffix) and suffix else s


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

        :param AppUnlinkUserType val:
        :rtype: EventType
        """
    return cls('app_unlink_user', val)


def p_line_atom(p):
    """line_atom : plugin_expr NEWLINE"""
    p[0] = p[1]


def srama_velocity_2000(chnl, trise):
    """
    Function srama_velocity_2000

    This function computes the mean velocity and corresponding error for a
    given channel rise time. The rise time shall be given in micro seconds and
    the returned dictionary, that contains the computed values are given in
    km/s. The functions are determined by [2].

    Parameters
    ----------
    chnl : str
        Requested channel calibration function. Available options:
            'cat_qc'
            'cat_qi'
            'iid_qt'
            'iid_qi'

    trise : int, float
        Rise time value.
        Physical Quantity: microseconds

    Returns
    -------
    out : dictionary
        Dictionary with the mean and error velocity named as the keys 'mean'
        and 'err', respectively. If trise is a list or an array, the values
        in the dictionary have the same shape as the input.

        Pysical Quantity: 'mean' : km/s
                          'err'  : km/s

    Notes:
    ------
    All three functions are defined within a certain rise time and amplitude
    domain. However, these values were not provided by [1]. Srama 2017 (priv.
    comm.) suggests to have signals with an amplitude of at least 10 fC (for
    each channel). The rise times and resulting velocities should  be handled
    with care. Extremely low velocities (< 2 - 5 km/s) and high paces
    (> 60 km/s) are mostly likely outside the definition range. Since no exact
    values are provided, no DefinitionRangeError raises.

    References
    ----------
    [2] R. Srama. Vom Cosmic-Dust-Analyzer zur Modellbeschreibung
        wissenschaftlicher Raumsonden. PhD thesis, Technische Universität
        München, 2000

    Examples
    --------
    >>> srama_velocity_2000(chnl='cat_qc', trise=10)
    {'err': 1.5547057674885145, 'mean': 3.109411534977029}

    >>> srama_velocity_2000('cat_qc', trise=0.0)
    ZeroDivisionError: 0.0 cannot be raised to a negative power

    Negative rise times lead to complex number, that has no technical or
    physical meaning.

    >>> srama_velocity_2000('cat_qc', trise=-1)
    {'err': (0.8369516379290977-2.514825174937663j),
     'mean': (1.6739032758581953-5.029650349875326j)}

    """
    chnl = chnl.lower()
    x_10ns = trise * 100.0
    mean_vel_cat_qc = (lambda x_10ns: 5.35 + 1674270.0 * x_10ns ** -2.71 -
        0.002253 * x_10ns)
    mean_vel_cat_qi = (lambda x_10ns: 3.535 + 18024000.0 * x_10ns ** -2.22 -
        0.00127 * x_10ns)
    mean_vel_iid_qt = (lambda x_10ns: 9.22 + 1.87 * 10.0 ** 5.0 * x_10ns **
        -1.26 - 1.45 * 10.0 ** -3.0 * x_10ns)
    mean_vel_iid_qi = (lambda x_10ns: 11.3 + 3.58 * 10.0 ** 5.0 * x_10ns **
        -1.35 - 2.21 * 10.0 ** -3.0 * x_10ns)
    _vel_cal = {'cat_qc': {'mean_func': mean_vel_cat_qc, 'err_fac': 0.5},
        'cat_qi': {'mean_func': mean_vel_cat_qi, 'err_fac': 0.6}, 'iid_qt':
        {'mean_func': mean_vel_iid_qt, 'err_fac': 0.64}, 'iid_qi': {
        'mean_func': mean_vel_iid_qi, 'err_fac': 0.6}}
    mean_vel = _vel_cal[chnl]['mean_func'](x_10ns)
    err_vel = _vel_cal[chnl]['err_fac'] * mean_vel
    return {'mean': mean_vel, 'err': err_vel}


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


def _import(subs, shared):
    """Configure the `doorstop import` subparser."""
    info = 'import an existing document or item'
    sub = subs.add_parser('import', description=info.capitalize() + '.',
        help=info, **shared)
    sub.add_argument('path', nargs='?', help=
        'path to previously exported document file')
    sub.add_argument('prefix', nargs='?', help='prefix of document for import')
    group = sub.add_mutually_exclusive_group()
    group.add_argument('-d', '--document', nargs=2, metavar='ARG', help=
        'import an existing document by: PREFIX PATH')
    group.add_argument('-i', '--item', nargs=2, metavar='ARG', help=
        'import an existing item by: PREFIX UID')
    sub.add_argument('-p', '--parent', metavar='PREFIX', help=
        'parent document prefix for imported document')
    sub.add_argument('-a', '--attrs', metavar='DICT', help=
        'dictionary of item attributes to import')
    sub.add_argument('-m', '--map', metavar='DICT', help=
        'dictionary of custom item attribute names')


def safe_revision_id(unicode_or_utf8_string):
    """Revision ids should now be utf8, but at one point they were unicode.

    :param unicode_or_utf8_string: A possibly Unicode revision_id. (can also be
        utf8 or None).
    :return: None or a utf8 revision id.
    """
    if (unicode_or_utf8_string is None or unicode_or_utf8_string.__class__ ==
        bytes):
        return unicode_or_utf8_string
    raise TypeError(
        'Unicode revision ids are no longer supported. Revision id generators should be creating utf8 revision ids.'
        )


@classmethod
def Find(cls, setting_matcher, port_path=None, serial=None, timeout_ms=None):
    """Gets the first device that matches according to the keyword args."""
    if port_path:
        device_matcher = cls.PortPathMatcher(port_path)
        usb_info = port_path
    elif serial:
        device_matcher = cls.SerialMatcher(serial)
        usb_info = serial
    else:
        device_matcher = None
        usb_info = 'first'
    return cls.FindFirst(setting_matcher, device_matcher, usb_info=usb_info,
        timeout_ms=timeout_ms)


def add_feather_vertex_slide(MASK_OT_add_feather_vertex=None,
    MASK_OT_slide_point=None):
    """Add new vertex to feather and slide it

    :param MASK_OT_add_feather_vertex: Add Feather Vertex, Add vertex to feather
    :param MASK_OT_slide_point: Slide Point, Slide control points
    """
    pass


def writeSTAR(filename, starDict):
    """Writes a STAR file from a dictionary containing data
    such as that parsed from a Relion STAR file.

    :arg filename: a filename
        The .star extension can be omitted.

    :arg dictionary: a dictionary in STAR format
        This should have nested entries starting with data blocks then loops/tables then
        field names and finally data.
    """
    star = open(filename, 'w')
    for dataBlockKey in starDict:
        star.write('\ndata_' + dataBlockKey + '\n')
        for loopNumber in starDict[dataBlockKey]:
            star.write('\nloop_\n')
            for fieldNumber in starDict[dataBlockKey][loopNumber]['fields']:
                star.write('_' + starDict[dataBlockKey][loopNumber][
                    'fields'][fieldNumber] + '\n')
            for dataItemNumber in starDict[dataBlockKey][loopNumber]['data']:
                for fieldNumber in starDict[dataBlockKey][loopNumber]['fields'
                    ]:
                    currentField = starDict[dataBlockKey][loopNumber]['fields'
                        ][fieldNumber]
                    star.write(starDict[dataBlockKey][loopNumber]['data'][
                        dataItemNumber][currentField] + ' ')
                star.write('\n')
    star.close()
    return


def split_codons(sequence, reading_frame_offset=0, reading_frame_direction=1):
    """
    Returns a list of 3-character strings representing codons extracted from a sequence of DNA characters
    at a specified offset (0,1,2) and direction (-1 or 1)
    """
    assert reading_frame_offset in (0, 1, 2)
    assert reading_frame_direction in (-1, 1)
    codons = []
    num_codons = int((len(sequence) - reading_frame_offset) / 3)
    for codon in range(num_codons):
        codons.append(sequence[codon * 3 + reading_frame_offset:(codon + 1) *
            3 + reading_frame_offset])
    return codons


def find(fetcher):
    """find/discover info about the content"""
    find_results = fetcher.find()
    return find_results


@staticmethod
def construct_public_ip_id(subscription_id, resource_group_name, public_ip_name
    ):
    """construct public ip id"""
    return (
        '/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Network/publicIPAddresses/{}'
        .format(subscription_id, resource_group_name, public_ip_name))


def subscription_delete(transport, request, queue_name, subscription_id):
    """Deletes the subscription

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    :param queue_name: Queue reference name.
    :type queue_name: `six.text_type`
    :param subscription_id: ID of subscription.
    :type subscription_id: `six.text_type`
    """
    request.operation = 'subscription_delete'
    request.params['queue_name'] = queue_name
    request.params['subscription_id'] = subscription_id
    transport.send(request)


def padded_data(data: bytes, start: int, stop: int) ->bytes:
    """Return the data between the start and stop index.

    The data is treated as padded with an infinite amount of null bytes before index 0.
    """
    assert start <= stop
    if start <= stop <= 0:
        return b'\x00' * (stop - start)
    if 0 <= start <= stop:
        return data[start:stop]
    return b'\x00' * (0 - start) + data[0:stop]


def i_base_ka(sb_mva, vbll_kv):
    """Returns the base current based on the base power and voltage.

    Args:
        sb_mva: Base power in MVA.
        vbll_kv: Base voltage in kV.

    Returns:
        Base current in kA.
    """
    sb_mva = float(sb_mva)
    vbll_kv = float(vbll_kv)
    return sb_mva / (vbll_kv * 3 ** 0.5)


def richest_ids(ids: dict, top=100) ->dict:
    """
    Given a dictionary with IDs and number of entries,
    return top X IDs with largest numbers.

    :param ids: dictionary with IDs and entry counts
    :param top: how many do you want (descending order)? Enter 0 for full sorted list
    :return: ordered subset of IDs
    """
    if top == 0:
        top = len(ids)
    rich_selection = dict(sorted(ids.items(), key=lambda t: t[1], reverse=
        True)[:top])
    return rich_selection


def set_URL_scheme_handler(url_scheme, bundle_identifier):
    """Set handler for given URL scheme."""
    return


def draw(fontid: int, text: str):
    """Draw text in the current context.

    :param fontid: The id of the typeface as returned by blf.load(), for default font use 0.
    :type fontid: int
    :param text: the text to draw.
    :type text: str
    """
    pass


def list_from_file(filename, offset=0, separator=' ', max_num=-1):
    """
    Load a text file and parse the content as a list of tuples or strings.

    Args:
        filename (str): name of the file to be loaded
        offset (int, optional): the offset of lines
        separator (str or None, optional): the separator to be used to parse
            tuples. If None, each line would be treated as a string.
        max_num (int, optional): the maximum number of lines to be read

    Returns:
        out_list (list[str]): A list of strings.
    """
    out_list, count = [], 0
    with open(filename, 'r') as f:
        for _ in range(offset):
            f.readline()
        for line in f:
            if max_num >= 0 and count >= max_num:
                break
            line = line.rstrip('\n')
            if separator is not None:
                line = tuple(line.split(separator))
            out_list.append(line)
            count += 1
    return out_list


def get_request_type(handler_input):
    """Return the type of the input request.

    The method retrieves the request ``type`` of the input request. More
    information about the different request types are mentioned here :
    https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#request-body-parameters

    :param handler_input: The handler input instance that is generally
        passed in the sdk's request and exception components
    :type handler_input: ask_sdk_core.handler_input.HandlerInput
    :return: Type value of the input request
    :rtype: str
    """
    return handler_input.request_envelope.request.object_type


def set_axes_color(ax, color):
    """Set the axes, tick marks, etc of `ax` to mpl color `color`. Also,
    "doegreen" has special significance as the color associated with the
    US department of energy."""
    if color == 'doegreen':
        color = 33 / 255, 99 / 255, 50 / 255
    ax.spines['bottom'].set_color(color)
    ax.spines['top'].set_color(color)
    ax.spines['right'].set_color(color)
    ax.spines['left'].set_color(color)
    ax.tick_params(axis='x', colors=color)
    ax.tick_params(axis='y', colors=color)
    ax.yaxis.label.set_color(color)
    ax.xaxis.label.set_color(color)


def add_marker_slide(CLIP_OT_add_marker=None, TRANSFORM_OT_translate=None):
    """Add new marker and slide it with mouse until mouse button release

    :param CLIP_OT_add_marker: Add Marker, Place new marker at specified location
    :param TRANSFORM_OT_translate: Translate, Translate (move) selected items
    """
    pass


@staticmethod
def __check_file(directory, fname, read=True, write=False):
    """
        Verifies that a file exists in the specified directory and has the requested permissions.

        :param directory: directory to look in for the file.
        :type directory: str.
        :param fname: file name to check.
        :type fname: str.
        :param read: check to see if file is readable (default: True).
        :type read: bool.
        :param write: check to see if the file is writable (default: False).
        :type write: bool.
        :return: True if file exists with expected permissions, else False.
        :rtype: bool.
        """
    __full_name = directory + '/' + fname
    if read and write:
        __mode = 'r+'
    elif read:
        __mode = 'r'
    elif write:
        __mode = 'w'
    else:
        return False
    try:
        __fp = open(__full_name, mode=__mode)
        __fp.close()
    except IOError:
        return False
    return True


def getverb(tok):
    """Finds the associated verb from a given noun token.
        tok: reference to a token of a doc which is
            being navigated.
    """
    if tok.dep_ == 'nsubj' and tok.head.pos_ == 'VERB':
        return tok.head
    else:
        None


@classmethod
def from_idtag(cls, tag):
    """Parse idtag into `class`:Month.
        """
    y = int(tag[1:5])
    m = int(tag[5:])
    return cls(year=y, month=m)


@classmethod
def from_golix(cls, golix_obj):
    """ Convert the golix object to a lightweight representation.
        """
    return cls(ghid=golix_obj.ghid, author=golix_obj.debinder, target=
        golix_obj.target)


def is_naive(dt):
    """
    Determines if a given datetime.datetime is naive.
    The concept is defined in Python's docs:
    http://docs.python.org/library/datetime.html#datetime.tzinfo
    Assuming value.tzinfo is either None or a proper datetime.tzinfo,
    value.utcoffset() implements the appropriate logic.
    """
    return dt.utcoffset() is None


def theta_Na_Sr_MP98(T, P):
    """c-c': sodium strontium [MP98]."""
    theta = 0.07
    valid = T == 298.15
    return theta, valid


def is_term(uri):
    """
    >>> is_term('/c/sv/kostym')
    True
    >>> is_term('/x/en/ify')
    True
    >>> is_term('/a/[/r/RelatedTo/,/c/en/cake/,/c/en/flavor/]')
    False
    """
    return uri.startswith('/c/') or uri.startswith('/x/')


def deregister_target_from_maintenance_window(WindowId=None, WindowTargetId
    =None):
    """
    Removes a target from a Maintenance Window.
    See also: AWS API Documentation

    :example: response = client.deregister_target_from_maintenance_window(
        WindowId='string',
        WindowTargetId='string'
    )

    :type WindowId: string
    :param WindowId: [REQUIRED]
            The ID of the Maintenance Window the target should be removed from.

    :type WindowTargetId: string
    :param WindowTargetId: [REQUIRED]
            The ID of the target definition to remove.

    :rtype: dict
    :return: {
        'WindowId': 'string',
        'WindowTargetId': 'string'
    }

    """
    pass


def find_duplicates_in_array(array):
    """Runs through the array and returns the elements that contain
    more than one duplicate

    Args:
        array: The array to check for duplicates.

    Returns:
        Array of the elements that are duplicates. Returns empty list if
        there are no duplicates.
    """
    duplicates = []
    non_duplicates = []
    if len(array) != len(set(array)):
        for item in array:
            if item not in non_duplicates:
                non_duplicates.append(item)
            elif item in non_duplicates and item not in duplicates:
                duplicates.append(item)
    return duplicates


def get_avi_resp_code(respCode):
    """
    This function used for getting appropriate response code for avi.
    :param respCode: response code
    :return: returns list of unique responses.
    """
    avi_resp_codes = []
    codes = respCode.split(' ')
    for code in codes:
        if code < 200:
            avi_resp_codes.append({'code': 'HTTP_1XX'})
        elif code < 300:
            avi_resp_codes.append({'code': 'HTTP_2XX'})
        elif code < 400:
            avi_resp_codes.append({'code': 'HTTP_3XX'})
        elif code < 500:
            avi_resp_codes.append({'code': 'HTTP_4XX'})
        elif code < 600:
            avi_resp_codes.append({'code': 'HTTP_5XX'})
    return list(set(avi_resp_codes))


def full_messages(msgs):
    """A generator that transforms each message by calling its
    get_full_message() method.  Used for IMAP messages since they don't really
    have their content by default.
    """
    for x in msgs:
        yield x.get_full_message()


def is_table_included(table, names):
    """Determines if the table is included by reference in the names.

    A table can be named by its component or its model (using the short-name
    or a full python path).

    eg. 'package.models.SomeModel' or 'package:SomeModel' or 'package'
        would all include 'SomeModel'.
    """
    if not names:
        return True
    model, component = table.class_, table.class_._component
    if component in names:
        return True
    model_name = '%s.%s' % (model.__module__, model.__name__)
    if model_name in names:
        return True
    short_name = '%s:%s' % (component, model.__name__)
    if short_name in names:
        return True
    return False


def delete_obsolete_perms(apps, schema_editor):
    """Delete obsolete permissions from the database."""
    Permission = apps.get_model('auth', 'Permission')
    Permission.objects.filter(codename__in=['add_collection', 'add_entity',
        'download_collection', 'download_entity', 'download_data']).delete()


def split_hour_minute(time):
    """Split hour/minute into components."""
    stripped = time.strip().rstrip('?:!.,;')
    hourminute = stripped.split(':')
    if len(hourminute) > 1:
        hour = int(hourminute[0])
        minute = int(hourminute[1])
    else:
        hour = int(hourminute[0])
        minute = 0
    return hour, minute


@classmethod
def __gql_load__(cls, data):
    """Load a scalar instance from GraphQL"""
    raise NotImplementedError(
        'GraphQL deserialization is not defined for this scalar')


def ppsize(num):
    """pretty-print filesize.
    http://blogmag.net/blog/read/38/Print_human_readable_file_size"""
    for x in ['bytes', 'KiB', 'MiB', 'GiB', 'TB']:
        if num < 1024.0:
            return '%3.2f %s' % (num, x)
        num /= 1024.0


@classmethod
def from_token(cls, token: str=None):
    """
        Starts a bot from a token object.

        :param token: The token to use for the bot.
        """
    bot = cls(token)
    return bot.run()


@classmethod
def make_on_lane(cls, road, lane_index, longitudinal, velocity=0):
    """
            Create a vehicle on a given lane at a longitudinal position.

        :param road: the road where the vehicle is driving
        :param lane_index: index of the lane where the vehicle is located
        :param longitudinal: longitudinal position along the lane
        :param velocity: initial velocity in [m/s]
        :return: A vehicle with at the specified position
        """
    lane = road.network.get_lane(lane_index)
    return cls(road, lane.position(longitudinal, 0), lane.heading_at(
        longitudinal), velocity)


def _get_from_cache(cache, lock, key):
    """ Returns the value for the specified key from the cache.
    Locks the lock before doing anything. Returns None if key not in cache """
    lock.acquire()
    ret = None
    if key in cache:
        ret = cache[key]
    lock.release()
    return ret


@classmethod
def _java_is_subclass(cls, obj, class_name):
    """Given a deserialized JavaObject as returned by the javaobj library,
        determine whether it's a subclass of the given class name.
        """
    clazz = obj.get_class()
    while clazz:
        if clazz.name == class_name:
            return True
        clazz = clazz.superclass
    return False


@staticmethod
def _reproject(wcs1, wcs2, x, y):
    """
        Perform the forward transformation of ``wcs1`` followed by the
        inverse transformation of ``wcs2``.

        Parameters
        ----------
        wcs1, wcs2 : WCS objects
            World coordinate system (WCS) transformations that support
            the `astropy shared interface for WCS
            <https://docs.astropy.org/en/stable/wcs/wcsapi.html>`_ (e.g.
            `astropy.wcs.WCS`, `gwcs.wcs.WCS`).

        Returns
        -------
        x, y:  float or array-like of float
            The pixel coordinates.
        """
    try:
        skycoord = wcs1.pixel_to_world(x, y)
        return wcs2.world_to_pixel(skycoord)
    except AttributeError:
        raise ValueError(
            'Input wcs objects do not support the shared WCS interface.')


def transitions(content, from_state=None):
    """ Return the available transition ids for the given object
        (from_state defaults to the object's current state)"""


def order_preserving_single_index_shift(arr, index, new_index):
    """Moves a list element to a new index while preserving order.

    Parameters
    ---------
    arr : list
        The list in which to shift an element.
    index : int
        The index of the element to shift.
    new_index : int
        The index to which to shift the element.

    Returns
    -------
    list
        The list with the element shifted.

    Example
    -------
    >>> arr = ['a', 'b', 'c', 'd']
    >>> order_preserving_single_index_shift(arr, 2, 0)
    ['c', 'a', 'b', 'd']
    >>> order_preserving_single_index_shift(arr, 2, 3)
    ['a', 'b', 'd', 'c']
    """
    if new_index == 0:
        return [arr[index]] + arr[0:index] + arr[index + 1:]
    if new_index == len(arr) - 1:
        return arr[0:index] + arr[index + 1:] + [arr[index]]
    if index < new_index:
        return arr[0:index] + arr[index + 1:new_index + 1] + [arr[index]
            ] + arr[new_index + 1:]
    if new_index <= index:
        return arr[0:new_index] + [arr[index]] + arr[new_index:index] + arr[
            index + 1:]


def configure(conf):
    """Finds the ar program and sets the default flags in ``conf.env.ARFLAGS``"""
    conf.find_program('ar', var='AR')
    conf.add_os_flags('ARFLAGS')
    if not conf.env.ARFLAGS:
        conf.env.ARFLAGS = ['rcs']


def _shuffle(data=None, out=None, name=None, **kwargs):
    """Randomly shuffle the elements.

    This shuffles the array along the first axis.
    The order of the elements in each subarray does not change.
    For example, if a 2D array is given, the order of the rows randomly changes,
    but the order of the elements in each row does not change.

    Parameters
    ----------
    data : NDArray
        Data to be shuffled.

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

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


def alternate(seq):
    """
    Splits *seq*, placing alternating values into the returned iterables
    """
    return seq[::2], seq[1::2]


@classmethod
def finalize_output(cls):
    """
        Things that should be done only once to the output directory AFTER
        rendering occurs (i.e. writing end of config file, setting up
        permissions, calling an external "deploy" method, finalizing an
        atomic deploy, etc.)

        Management command calls this once after iterating over all
        renderer instances.
        """
    pass


def convert_short_channel_id_to_channel_id(blockheight, transaction, output):
    """
    Converts short channel id (blockheight:transaction:output) to a long integer channel id.

    :param blockheight:
    :param transaction: Number of transaction in the block.
    :param output: Number of output in the transaction.
    :return: channel id: Encoded integer number representing the channel,
     can be decoded by :func:`lib.conversion.extract_short_channel_id_from_string`.
    """
    return blockheight << 40 | transaction << 16 | output


def XMLescape(txt):
    """Returns provided string with symbols & < > " replaced by their respective XML entities."""
    return txt.replace('&', '&').replace('<', '<').replace('>', '>'
        ).replace('"', '"').replace('\x0c', '').replace('\x1b', '')


def format_arg_value(arg_val):
    """ Return a string representing a (name, value) pair.

    >>> format_arg_value(('x', (1, 2, 3)))
    'x=(1, 2, 3)'
    """
    arg, val = arg_val
    return '%s=%r' % (arg, val)


def lsquare_of_sums(inlist):
    """
Adds the values in the passed list, squares the sum, and returns
the result.

Usage:   lsquare_of_sums(inlist)
Returns: sum(inlist[i])**2
"""
    s = sum(inlist)
    return float(s) * s


@staticmethod
def on_first_connection():
    """
        Called when the client is connected for the first time
        """
    pass


def getitem_via_pathlist(ol, pathlist):
    """
        from elist.elist import *
        y = ['a',['b',["bb"]],'c']
        y[1][1]
        getitem_via_pathlist(y,[1,1])
    """
    this = ol
    for i in range(0, pathlist.__len__()):
        key = pathlist[i]
        this = this.__getitem__(key)
    return this


@classmethod
def validate_params(cls, parser, params):
    """Проверка параметров."""
    if params.backend is None:
        parser.error('the following arguments are required: Back-end')


def __call__(coords):
    """Find matching points.

        Parameters
        ----------
        B : array_like(Number, shape=(n, k))
            Represents `n` points of `k` dimensions. These points are assigned
            to the previously defined reference coordinates.

        Returns
        -------
        pairs : np.ndarray(int, shape=(m, 2))
            Indices of assigned points. For two point sets `A`, `B` and each
            row `(a, b)` in `pairs` `A[a, :]` is assigned to `B[b, :]`

        """
    raise NotImplementedError()


def _test():
    """
       >>> x = css(color='red', background='blue')
       >>> x
       color:red;background:blue
       >>> x.border = 'none'
       >>> y = css(background='blue', color='red')
       >>> y.border = 'none'
       >>> x == y
       True
       >>> a = css()
        >>> a['font-weight'] = 'bold'
        >>> a
        font-weight:bold
        >>> a.text_align = 'right'
        >>> a
        font-weight:bold;text-align:right
    """
    import doctest
    doctest.testmod()


def trunc(data=None, out=None, name=None, **kwargs):
    """Return the element-wise truncated value of the input.

    The truncated value of the scalar x is the nearest integer i which is closer to
    zero than x is. In short, the fractional part of the signed number x is discarded.

    Example::

       trunc([-2.1, -1.9, 1.5, 1.9, 2.1]) = [-2., -1.,  1.,  1.,  2.]

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

       - trunc(default) = default
       - trunc(row_sparse) = row_sparse
       - trunc(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_basic.cc:L857

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

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

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


def updateProp(prop_manager, prop_dict):
    """Provided a PropertyManager and a property dict of {id, value,
    type}, set or update that property as applicable.

    Doesn't deal with existing properties changing type.
    """
    id = prop_dict['id']
    value = prop_dict['value']
    type = prop_dict['type']
    if type in ('selection', 'multiple selection'):
        value = prop_dict['select_variable']
    if prop_manager.hasProperty(id):
        prop_manager._updateProperty(id, value)
    else:
        prop_manager._setProperty(id, value, type)
    if type in ('selection', 'multiple selection'):
        prop_manager._updateProperty(id, prop_dict['value'])


@staticmethod
def run_service(service, done):
    """Service start wrapper.

        :param service: service to run
        :param done: event to wait on until a shutdown is triggered
        :returns: None

        """
    service.start()
    done.wait()


def getSlice(properties=None, **kw):
    """
        getSlice(properties=None [,Axis<Number>=n|Axis<Number>=[i1,i2,..,ix]])

        Return the resulting cells from a MDX statement.
        The result is presented as an array of arrays of arrays of...
        depending on amount of axes in the MDX.
        You can carve out slices you need by listing the indices of the axes
        you are interested in.

        Examples:

        result.getSlice() # return all
        result.getSlice(Axis0=3) # carve out the 4th column
        result.getSlice(Axis0=3, SlicerAxis=0) # same as above, SlicerAxis is ignored
        result.getSlice(Axis1=[1,2]) # return the data sliced at the 2nd and 3rd row
        result.getSlice(Axis0=3, Axis1=[1,2]) # return the data sliced at the 2nd and
                                                3rd row in addition to the 4th column

        If you do not want the whole cell returned but just a single property of it
        (like the Value) name that property in the property parameter:

        # from all the cells just get me the Value property
        result.getSlice(properties="Value")
        # from all the cells just get me the Value property
        result.getSlice(properties=["Value", "FmtValue"])

        """


@classmethod
def calc_strain_ratio(cls, mag):
    """Compute the effective strain ratio using Idriss and Sun (1992).

        Parameters
        ----------
        mag: float
            Magnitude of the input motion.

        Returns
        -------
        strain_ratio : float
            Effective strain ratio

        References
        ----------
        .. [1] Idriss, I. M., & Sun, J. I. (1992). SHAKE91: A computer program
            for conducting equivalent linear seismic response analyses of
            horizontally layered soil deposits. Center for Geotechnical
            Modeling, Department of Civil and Environmental Engineering,
            University of California, Davis, CA.
        """
    return (mag - 1) / 10


def icons_visible():
    """Returns True if icons should be shown or False otherwise.
        """


def genColours(cmap, cmapResolution, invert, alpha, gamma=1):
    """Generate an array containing ``cmapResolution`` colours from the given
    colour map object/function.
    """
    import numpy as np
    import matplotlib.cm as cm
    ncols = cmapResolution
    cmap = cm.get_cmap(cmap)
    idxs = np.linspace(0.0, 1.0, ncols)
    if gamma != 1:
        idxs = idxs ** gamma
    if invert:
        idxs = idxs[::-1]
    cmap = cmap(idxs)
    cmap[:, (3)] = alpha
    return np.dstack((cmap, cmap)).transpose((2, 0, 1))


@staticmethod
def _sort_db_actions(db_actions):
    """Sort ActiveAction items by two fields

        score - primary, ascending
        created_at - secondary, descending
        """
    return sorted(db_actions, key=lambda action: (-action.score, action.
        created_at), reverse=False)


@staticmethod
def _get_brother_of(node, parent):
    """Returns the brother node of "node", whose parent is "parent\""""
    if parent.left is not None and parent.left.key == node.key:
        return parent.right
    return parent.left


def rename_headers(msg, old, new):
    """Rename all occurances of a message header in a Message object.

    msg is an email.message.Message object.

    old is name of the header to rename.

    new is the new name of the header
    """
    if old in msg:
        for pair in msg._headers:
            if pair[0].lower() == old.lower():
                index = msg._headers.index(pair)
                msg._headers[index] = new, '%s' % pair[1]


@classmethod
def extract_root_meta(cls, serializer, resource):
    """
        Calls a `get_root_meta` function on a serializer, if it exists.
        """
    many = False
    if hasattr(serializer, 'child'):
        many = True
        serializer = serializer.child
    data = {}
    if getattr(serializer, 'get_root_meta', None):
        json_api_meta = serializer.get_root_meta(resource, many)
        assert isinstance(json_api_meta, dict
            ), 'get_root_meta must return a dict'
        data.update(json_api_meta)
    return data


@staticmethod
def _tile_slice(ipix, tile_width, n_tiles_in_row):
    """Compute the 2-dim slice in the allsky ``data`` for a given tile."""
    w = tile_width
    row_idx, col_idx = divmod(ipix, n_tiles_in_row)
    return [slice(row_idx * w, (row_idx + 1) * w), slice(col_idx * w, (
        col_idx + 1) * w)]


def storage_account_id(cmd, namespace):
    """Validate storage account name"""
    from azure.cli.core.profiles import ResourceType
    from azure.cli.core.commands.client_factory import get_mgmt_service_client
    if namespace.storage_account and not (
        '/providers/Microsoft.ClassicStorage/storageAccounts/' in namespace
        .storage_account or '/providers/Microsoft.Storage/storageAccounts/' in
        namespace.storage_account):
        storage_client = get_mgmt_service_client(cmd.cli_ctx, ResourceType.
            MGMT_STORAGE)
        acc = storage_client.storage_accounts.get_properties(namespace.
            resource_group_name, namespace.storage_account)
        if not acc:
            raise ValueError(
                "Storage account named '{}' not found in the resource group '{}'."
                .format(namespace.storage_account, namespace.
                resource_group_name))
        namespace.storage_account = acc.id


@classmethod
def get_non_optional_settings(cls):
    """
        Retrieves the minimal set of settings that need to be defined in order
        to use this object.

        :return: a dictionary of needed settings as keys and help texts as
                 values
        """
    return cls.get_metadata().non_optional_params


def _simple_warn(msg, category=UserWarning, *args, **kwargs):
    """Show a simple warning of the form <type>: <warning message>."""
    print('{categ}: {msg}'.format(categ=category.__name__, msg=msg))


def get_single_keyword(tokens):
    """If ``values`` is a 1-element list of keywords, return its name.

    Otherwise return ``None``.

    """
    if len(tokens) == 1:
        token = tokens[0]
        if token.type == 'ident':
            return token.lower_value


def theta_Ba_Na_PK74(T, P):
    """c-c': barium sodium [PK74]."""
    theta = -0.003
    valid = T == 298.15
    return theta, valid


def pad_fields(row, widths):
    """Pads fields of the given row, so each field lines up nicely with the
    others.

    """
    widths = list(map(lambda w: ' %-' + str(w) + 's ', widths))
    new_row = []
    for i in range(len(row)):
        col = row[i]
        col = widths[i] % col.strip()
        new_row.append(col)
    return new_row


def _my_hash(arg_list):
    """Simple helper hash function"""
    res = 0
    for arg in arg_list:
        res = res * 31 + hash(arg)
    return res


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

        :param MemberChangeEmailDetails val:
        :rtype: EventDetails
        """
    return cls('member_change_email_details', val)


def walk():
    """Interactively walk around the scene

    """
    pass


@staticmethod
def _is_indirect_jump(_, sim_successors):
    """
        Determine if this SimIRSB has an indirect jump as its exit
        """
    if sim_successors.artifacts['irsb_direct_next']:
        return False
    default_jumpkind = sim_successors.artifacts['irsb_default_jumpkind']
    if default_jumpkind not in ('Ijk_Call', 'Ijk_Boring', 'Ijk_InvalICache'):
        return False
    return True


def process_in_out_queues(func, q_in, q_out):
    """Iterate through a Queue, call, ``func`, and Queue the result

    Parameters
    ----------
    func : `callable`
        any function that can take an element of the input `Queue` as
        the only argument

    q_in : `multiprocessing.queue.Queue`
        the input `Queue`

    q_out : `multiprocessing.queue.Queue`
        the output `Queue`

    Notes
    -----
    To close the input `Queue`, add ``(None, None)` as the last item
    """
    while True:
        idx, arg = q_in.get()
        if idx is None:
            break
        q_out.put((idx, func(arg)))


@classmethod
def from_config_dict(cls, config_dict, **extra_kwargs):
    """
        Convert a dictionary, checking for invalid keys, that can be
        safely passed as kwargs. Checks only for the presence of options
        (keys), not their types. Converts dashes to underscores in
        option names.

        Considers optional arguments to cls.__init__() optional options,
        and required arguments to cls.__init__() required options.
        Rejects options also found in extra_kwargs.
        """
    if isinstance(config_dict, cls):
        return config_dict
    required_args, optional_args = cls._find_args(extra_kwargs)
    kwargs = {}
    for raw_key in config_dict:
        key = cls._to_field(raw_key)
        if key not in required_args + optional_args:
            raise ValueError("Unknown config key `{}'".format(raw_key))
        kwargs[key] = config_dict[raw_key]
    for key in required_args:
        if key not in kwargs:
            raw_key = cls._to_config(key)
            raise ValueError("Missing required config key `{}'".format(raw_key)
                )
    kwargs.update(extra_kwargs)
    return cls(**kwargs)


def p_preprocessor_line_line(p):
    """ preproc_line : _LINE INTEGER
    """
    p.lexer.lineno = int(p[2]) + p.lexer.lineno - p.lineno(2)


def whoami(args):
    """This method prints the logged username"""
    import getpass
    print(getpass.getuser())


def all_keys_not_none(d: dict, required: list):
    """
    Check all values for given keys is not None
    :param d:
    :param required:
    :return:
    """
    passed = 0
    for r in required:
        v = d.get(r)
        if v is not None:
            passed += 1
    return len(required) == passed


def rfind_string_in_file(mmFile, filePath, targetString):
    """wrapper that raises error if no substr can be found
    finds the last occurrence of a substring in memory mapped file"""
    location = mmFile.rfind(targetString.encode(encoding='utf-8'))
    if location == -1:
        s = 'It seems "{:s}" was not present in the file\n' + """"{:s}"
Check that the previous calculation didn't fail"""
        raise Exception(s.format(targetString, filePath))
    return location


@staticmethod
def pad(data, *args, **kwargs):
    """Pads data with given padding.

        :returns: Padded data.
        :rtype: list

        """
    raise NotImplementedError()


def get_weighting_all_to_one(base_data, settings):
    """
    Return a weighting vector which 'normalizes' all data points to one
    """
    errors = 1.0 / base_data
    return errors


def total_seconds(td):
    """Python 2.6 compatability"""
    if hasattr(td, 'total_seconds'):
        return td.total_seconds()
    ms = td.microseconds
    secs = td.seconds + td.days * 24 * 3600
    return (ms + secs * 10 ** 6) / 10 ** 6


def remove_getdisplay(field_name):
    """
    for string 'get_FIELD_NAME_display' return 'FIELD_NAME'
    """
    str_ini = 'get_'
    str_end = '_display'
    if str_ini == field_name[0:len(str_ini)] and str_end == field_name[-1 *
        len(str_end):]:
        field_name = field_name[len(str_ini):-1 * len(str_end)]
    return field_name


@classmethod
def list_dirs(cls, directory):
    """Return the list of all directory objects in the directory."""
    return cls.list_directory_content(directory, element_type='dirs')


def open_csv(filename):
    """ Open a light curve file in csv format and extract from it flux time
    series.

    Parameters
    ----------
    filename : str
        file name of the ascii file containing the photometry

    Returns
    -------
    filename : str
        The filename serves as a unique identifier for the object
    photometry : Astropy table
        Columns are named after the file header and contain time, flux
    """
    photometry = ascii.read(filename, format='csv')
    return filename, photometry


def cheat(value):
    """If `False`, disables the ability to see what is inside a qubit"""
    if value in (False, True):
        global _cheat
        _cheat = value


def list_jobs_by_pipeline(PipelineId=None, Ascending=None, PageToken=None):
    """
    The ListJobsByPipeline operation gets a list of the jobs currently in a pipeline.
    Elastic Transcoder returns all of the jobs currently in the specified pipeline. The response body contains one element for each job that satisfies the search criteria.
    See also: AWS API Documentation

    :example: response = client.list_jobs_by_pipeline(
        PipelineId='string',
        Ascending='string',
        PageToken='string'
    )

    :type PipelineId: string
    :param PipelineId: [REQUIRED]
            The ID of the pipeline for which you want to get job information.

    :type Ascending: string
    :param Ascending: To list jobs in chronological order by the date and time that they were submitted, enter true . To list jobs in reverse chronological order, enter false .

    :type PageToken: string
    :param PageToken: When Elastic Transcoder returns more than one page of results, use pageToken in subsequent GET requests to get each successive page of results.

    :rtype: dict
    :return: {
        'Jobs': [
            {
                'Id': 'string',
                'Arn': 'string',
                'PipelineId': 'string',
                'Input': {
                    'Key': 'string',
                    'FrameRate': 'string',
                    'Resolution': 'string',
                    'AspectRatio': 'string',
                    'Interlaced': 'string',
                    'Container': 'string',
                    'Encryption': {
                        'Mode': 'string',
                        'Key': 'string',
                        'KeyMd5': 'string',
                        'InitializationVector': 'string'
                    },
                    'TimeSpan': {
                        'StartTime': 'string',
                        'Duration': 'string'
                    },
                    'InputCaptions': {
                        'MergePolicy': 'string',
                        'CaptionSources': [
                            {
                                'Key': 'string',
                                'Language': 'string',
                                'TimeOffset': 'string',
                                'Label': 'string',
                                'Encryption': {
                                    'Mode': 'string',
                                    'Key': 'string',
                                    'KeyMd5': 'string',
                                    'InitializationVector': 'string'
                                }
                            },
                        ]
                    },
                    'DetectedProperties': {
                        'Width': 123,
                        'Height': 123,
                        'FrameRate': 'string',
                        'FileSize': 123,
                        'DurationMillis': 123
                    }
                },
                'Inputs': [
                    {
                        'Key': 'string',
                        'FrameRate': 'string',
                        'Resolution': 'string',
                        'AspectRatio': 'string',
                        'Interlaced': 'string',
                        'Container': 'string',
                        'Encryption': {
                            'Mode': 'string',
                            'Key': 'string',
                            'KeyMd5': 'string',
                            'InitializationVector': 'string'
                        },
                        'TimeSpan': {
                            'StartTime': 'string',
                            'Duration': 'string'
                        },
                        'InputCaptions': {
                            'MergePolicy': 'string',
                            'CaptionSources': [
                                {
                                    'Key': 'string',
                                    'Language': 'string',
                                    'TimeOffset': 'string',
                                    'Label': 'string',
                                    'Encryption': {
                                        'Mode': 'string',
                                        'Key': 'string',
                                        'KeyMd5': 'string',
                                        'InitializationVector': 'string'
                                    }
                                },
                            ]
                        },
                        'DetectedProperties': {
                            'Width': 123,
                            'Height': 123,
                            'FrameRate': 'string',
                            'FileSize': 123,
                            'DurationMillis': 123
                        }
                    },
                ],
                'Output': {
                    'Id': 'string',
                    'Key': 'string',
                    'ThumbnailPattern': 'string',
                    'ThumbnailEncryption': {
                        'Mode': 'string',
                        'Key': 'string',
                        'KeyMd5': 'string',
                        'InitializationVector': 'string'
                    },
                    'Rotate': 'string',
                    'PresetId': 'string',
                    'SegmentDuration': 'string',
                    'Status': 'string',
                    'StatusDetail': 'string',
                    'Duration': 123,
                    'Width': 123,
                    'Height': 123,
                    'FrameRate': 'string',
                    'FileSize': 123,
                    'DurationMillis': 123,
                    'Watermarks': [
                        {
                            'PresetWatermarkId': 'string',
                            'InputKey': 'string',
                            'Encryption': {
                                'Mode': 'string',
                                'Key': 'string',
                                'KeyMd5': 'string',
                                'InitializationVector': 'string'
                            }
                        },
                    ],
                    'AlbumArt': {
                        'MergePolicy': 'string',
                        'Artwork': [
                            {
                                'InputKey': 'string',
                                'MaxWidth': 'string',
                                'MaxHeight': 'string',
                                'SizingPolicy': 'string',
                                'PaddingPolicy': 'string',
                                'AlbumArtFormat': 'string',
                                'Encryption': {
                                    'Mode': 'string',
                                    'Key': 'string',
                                    'KeyMd5': 'string',
                                    'InitializationVector': 'string'
                                }
                            },
                        ]
                    },
                    'Composition': [
                        {
                            'TimeSpan': {
                                'StartTime': 'string',
                                'Duration': 'string'
                            }
                        },
                    ],
                    'Captions': {
                        'MergePolicy': 'string',
                        'CaptionSources': [
                            {
                                'Key': 'string',
                                'Language': 'string',
                                'TimeOffset': 'string',
                                'Label': 'string',
                                'Encryption': {
                                    'Mode': 'string',
                                    'Key': 'string',
                                    'KeyMd5': 'string',
                                    'InitializationVector': 'string'
                                }
                            },
                        ],
                        'CaptionFormats': [
                            {
                                'Format': 'string',
                                'Pattern': 'string',
                                'Encryption': {
                                    'Mode': 'string',
                                    'Key': 'string',
                                    'KeyMd5': 'string',
                                    'InitializationVector': 'string'
                                }
                            },
                        ]
                    },
                    'Encryption': {
                        'Mode': 'string',
                        'Key': 'string',
                        'KeyMd5': 'string',
                        'InitializationVector': 'string'
                    },
                    'AppliedColorSpaceConversion': 'string'
                },
                'Outputs': [
                    {
                        'Id': 'string',
                        'Key': 'string',
                        'ThumbnailPattern': 'string',
                        'ThumbnailEncryption': {
                            'Mode': 'string',
                            'Key': 'string',
                            'KeyMd5': 'string',
                            'InitializationVector': 'string'
                        },
                        'Rotate': 'string',
                        'PresetId': 'string',
                        'SegmentDuration': 'string',
                        'Status': 'string',
                        'StatusDetail': 'string',
                        'Duration': 123,
                        'Width': 123,
                        'Height': 123,
                        'FrameRate': 'string',
                        'FileSize': 123,
                        'DurationMillis': 123,
                        'Watermarks': [
                            {
                                'PresetWatermarkId': 'string',
                                'InputKey': 'string',
                                'Encryption': {
                                    'Mode': 'string',
                                    'Key': 'string',
                                    'KeyMd5': 'string',
                                    'InitializationVector': 'string'
                                }
                            },
                        ],
                        'AlbumArt': {
                            'MergePolicy': 'string',
                            'Artwork': [
                                {
                                    'InputKey': 'string',
                                    'MaxWidth': 'string',
                                    'MaxHeight': 'string',
                                    'SizingPolicy': 'string',
                                    'PaddingPolicy': 'string',
                                    'AlbumArtFormat': 'string',
                                    'Encryption': {
                                        'Mode': 'string',
                                        'Key': 'string',
                                        'KeyMd5': 'string',
                                        'InitializationVector': 'string'
                                    }
                                },
                            ]
                        },
                        'Composition': [
                            {
                                'TimeSpan': {
                                    'StartTime': 'string',
                                    'Duration': 'string'
                                }
                            },
                        ],
                        'Captions': {
                            'MergePolicy': 'string',
                            'CaptionSources': [
                                {
                                    'Key': 'string',
                                    'Language': 'string',
                                    'TimeOffset': 'string',
                                    'Label': 'string',
                                    'Encryption': {
                                        'Mode': 'string',
                                        'Key': 'string',
                                        'KeyMd5': 'string',
                                        'InitializationVector': 'string'
                                    }
                                },
                            ],
                            'CaptionFormats': [
                                {
                                    'Format': 'string',
                                    'Pattern': 'string',
                                    'Encryption': {
                                        'Mode': 'string',
                                        'Key': 'string',
                                        'KeyMd5': 'string',
                                        'InitializationVector': 'string'
                                    }
                                },
                            ]
                        },
                        'Encryption': {
                            'Mode': 'string',
                            'Key': 'string',
                            'KeyMd5': 'string',
                            'InitializationVector': 'string'
                        },
                        'AppliedColorSpaceConversion': 'string'
                    },
                ],
                'OutputKeyPrefix': 'string',
                'Playlists': [
                    {
                        'Name': 'string',
                        'Format': 'string',
                        'OutputKeys': [
                            'string',
                        ],
                        'HlsContentProtection': {
                            'Method': 'string',
                            'Key': 'string',
                            'KeyMd5': 'string',
                            'InitializationVector': 'string',
                            'LicenseAcquisitionUrl': 'string',
                            'KeyStoragePolicy': 'string'
                        },
                        'PlayReadyDrm': {
                            'Format': 'string',
                            'Key': 'string',
                            'KeyMd5': 'string',
                            'KeyId': 'string',
                            'InitializationVector': 'string',
                            'LicenseAcquisitionUrl': 'string'
                        },
                        'Status': 'string',
                        'StatusDetail': 'string'
                    },
                ],
                'Status': 'string',
                'UserMetadata': {
                    'string': 'string'
                },
                'Timing': {
                    'SubmitTimeMillis': 123,
                    'StartTimeMillis': 123,
                    'FinishTimeMillis': 123
                }
            },
        ],
        'NextPageToken': 'string'
    }

    :returns:
    S3: Amazon S3 creates and manages the keys used for encrypting your files.
    S3-AWS-KMS: Amazon S3 calls the Amazon Key Management Service, which creates and manages the keys that are used for encrypting your files. If you specify S3-AWS-KMS and you don't want to use the default key, you must add the AWS-KMS key that you want to use to your pipeline.
    AES-CBC-PKCS7: A padded cipher-block mode of operation originally used for HLS files.
    AES-CTR: AES Counter Mode.
    AES-GCM: AES Galois Counter Mode, a mode of operation that is an authenticated encryption format, meaning that a file, key, or initialization vector that has been tampered with fails the decryption process.

    """
    pass


def Float(text):
    """A floating-point number."""
    return float(text)


def assign(obj):
    """Merge objects /*from1, from2, from3, ...*/)"""
    raise NotImplementedError
    return obj


@classmethod
def get_model(cls):
    """Get the model object for this instance, loading it if it's not already loaded."""
    if cls.model is None:
        cls.model = None
    return cls.model


def pretty_const(value):
    """Make a constant pretty for printing in GUI"""
    words = value.split('_')
    pretty = words[0].capitalize()
    for word in words[1:]:
        pretty += ' ' + word.lower()
    return pretty


def is_full_connection(domain):
    """
    Domain is "fully connected" if any https endpoint is fully connected.
    """
    https, httpswww = domain.https, domain.httpswww
    return https.https_full_connection or httpswww.https_full_connection


@classmethod
def load_from_options_getter(cls, getter, **kwargs):
    """Load a plugin from a getter function returning appropriate values.

        To handle cases other than the provided CONF and CLI loading you can
        specify a custom loader function that will be queried for the option
        value.

        The getter is a function that takes one value, an
        :py:class:`oslo_config.cfg.Opt` and returns a value to load with.

        :param getter: A function that returns a value for the given opt.
        :type getter: callable

        :returns: An authentication Plugin.
        :rtype: :py:class:`keystoneclient.auth.BaseAuthPlugin`
        """
    plugin_opts = cls.get_options()
    for opt in plugin_opts:
        val = getter(opt)
        if val is not None:
            val = opt.type(val)
        kwargs.setdefault(opt.dest, val)
    return cls.load_from_options(**kwargs)


def line_coeff_from_segment(point_a, point_b):
    """Given a line segment (two points), find the slope (m) and y-intercept (b) of line y=mx+b

    Parameters
    ----------
    point_a : tuple
        coordinates of the first point

    point_b : tuple
        coordinates of the second point

    Return
    ------
    m : float
        the line's slope

    b : float
        the line's y-intercept

    Examples
    --------
    Find the slope and y-intercept of a line defined by points (8, 3) and (-1, 10)

    .. code-block:: python

        import cloudburst as cb
        (m, b) = cb.line_coeff_from_segment((8, 3), (-1, 10))
        print("line: y={}x+{}".format(m, b))
    """
    m = (point_b[1] - point_a[1]) / (point_b[0] - point_a[0])
    b = point_a[1] - m * point_a[0]
    return m, b


def has_get(value):
    """Return whether the value is a wrapped getter descriptor."""
    return value is not None and value.has_get


def describe_attack(AttackId=None):
    """
    Describes the details of a DDoS attack.
    See also: AWS API Documentation

    :example: response = client.describe_attack(
        AttackId='string'
    )

    :type AttackId: string
    :param AttackId: [REQUIRED]
            The unique identifier (ID) for the attack that to be described.

    :rtype: dict
    :return: {
        'Attack': {
            'AttackId': 'string',
            'ResourceArn': 'string',
            'SubResources': [
                {
                    'Type': 'IP'|'URL',
                    'Id': 'string',
                    'AttackVectors': [
                        {
                            'VectorType': 'string',
                            'VectorCounters': [
                                {
                                    'Name': 'string',
                                    'Max': 123.0,
                                    'Average': 123.0,
                                    'Sum': 123.0,
                                    'N': 123,
                                    'Unit': 'string'
                                },
                            ]
                        },
                    ],
                    'Counters': [
                        {
                            'Name': 'string',
                            'Max': 123.0,
                            'Average': 123.0,
                            'Sum': 123.0,
                            'N': 123,
                            'Unit': 'string'
                        },
                    ]
                },
            ],
            'StartTime': datetime(2015, 1, 1),
            'EndTime': datetime(2015, 1, 1),
            'AttackCounters': [
                {
                    'Name': 'string',
                    'Max': 123.0,
                    'Average': 123.0,
                    'Sum': 123.0,
                    'N': 123,
                    'Unit': 'string'
                },
            ],
            'Mitigations': [
                {
                    'MitigationName': 'string'
                },
            ]
        }
    }

    """
    pass


def vertex_group_select():
    """Select all the vertices assigned to the active vertex group

    """
    pass


def do_nothing2(image):
    """Explanation of the finalize function for method *_pull* in class
    *COGEF*.

    Parameters
    ----------
    image: Atoms object
        Configuration after the optimization.

    """
    pass


@staticmethod
def pull(image):
    """
		Returns the `docker pull` command to pull an image from a remote registry
		"""
    return ['docker', 'pull', image]


def _handle_remotes(config, only_remotes, add_remotes, remove_remotes):
    """ Manages remotes.
    """
    if only_remotes is not None:
        for remote in config.remotes:
            config.remove_remote(remote.host, remote.port)
        for remote in only_remotes:
            config.set_remote(remote.host, remote.port, remote.tls)
    else:
        for remote in add_remotes:
            config.set_remote(remote.host, remote.port, remote.tls)
        for remote in remove_remotes:
            config.remove_remote(remote.host, remote.port)


def mean(values):
    """Calculate the mean.

    Parameters
    ----------
    values : list
        Values to find the mean of

    Returns
    -------
    out : float
        The mean
    """
    return sum(values) / float(len(values)) if len(values) > 0 else 0.0


def import_items(import_file, item_create_func, item_add_func,
    allow_fabricator=False, quiet=False):
    """
    Imports items from `import_file`.  `item_create_func` should point to
    a function used to create the item appropriately, and `item_add_func`
    should point to a function used to actually add the item into the
    appropriate container.  If `allow_fabricator` is `False` (the default),
    this routine will refuse to import Fabricators, or any item which
    can't be decoded (in case it's a Fabricator).  If `quiet` is `True`,
    only error/warning output will be shown.
    """
    if not quiet:
        print(' - Importing items from {}'.format(import_file))
    added_count = 0
    with open(import_file) as df:
        for line in df:
            itemline = line.strip()
            if itemline.lower().startswith('bl3(') and itemline.endswith(')'):
                new_item = item_create_func(itemline)
                if not allow_fabricator:
                    if not new_item.eng_name:
                        print(
                            '   - NOTICE: Skipping unknown item import because --allow-fabricator is not set'
                            )
                        continue
                    if new_item.balance_short.lower(
                        ) == 'balance_eridian_fabricator':
                        print(
                            '   - NOTICE: Skipping Fabricator import because --allow-fabricator is not set'
                            )
                        continue
                item_add_func(new_item)
                if not quiet:
                    if new_item.eng_name:
                        print('   + {} ({})'.format(new_item.eng_name,
                            new_item.get_level_eng()))
                    else:
                        print('   + unknown item')
                added_count += 1
    if not quiet:
        print('   - Added Item Count: {}'.format(added_count))


def to_bool(value):
    """ Converts value to a bool """
    return value.lower() in ['true', 'yes', 'on']


def StripUnicode(string, subs='.'):
    """Strip non-ASCII characters from strings

    :param str string: string to strip Unicode characters from
    :param str subs: character(s) to place into string in place of each
      Unicode character. Defaults to '.'

    :returns: a new string with only ASCII characters
    """
    s = ''
    for c in string:
        if ord(c) < 128:
            s += c
        else:
            s += subs
    return s.encode('ascii', 'replace')


def iter_without_duplicates(it, key=lambda x: x):
    """Yields non-repeating items from `iter`.

    `key` has the same meaning as in `delete_duplicates`:func:.

    The difference between this function and `iter_delete_duplicates`:func: is
    that we ensure the same item (as per `key`) is produced only once; while
    `iter_delete_duplicates`:func: only remove consecutive repeating items.

    Example:

      >>> list(iter_without_duplicates('AAAaBBBA', key=lambda x: x.lower()))
      ['A', 'B']

    """
    done = set()
    for what in it:
        k = key(what)
        if k not in done:
            yield what
            done.add(k)


def validate_jhove(filename, jhove='jhove', ignore=('More than 50 IFDs',)):
    """Validate TIFF file using jhove -m TIFF-hul.

    Raise ValueError if jhove outputs an error message unless the message
    contains one of the strings in 'ignore'.

    JHOVE does not support bigtiff or more than 50 IFDs.

    See `JHOVE TIFF-hul Module <http://jhove.sourceforge.net/tiff-hul.html>`_

    """
    import subprocess
    out = subprocess.check_output([jhove, filename, '-m', 'TIFF-hul'])
    if b'ErrorMessage: ' in out:
        for line in out.splitlines():
            line = line.strip()
            if line.startswith(b'ErrorMessage: '):
                error = line[14:].decode('utf8')
                for i in ignore:
                    if i in error:
                        break
                else:
                    raise ValueError(error)
                break


def end_task(params):
    """
    Terminates, if needed, the context (to save all data remaining in the batch) and the prefetch. It also prints
    the statistics of the StorageObjs if desired.
    Args:
        params: a list of objects (Blocks, StorageObjs, strings, ints, ...)
    """
    pass


def get_model_var_scope(module_scope, model_name):
    """ Assembly Module Scope Name and model scope name
  """
    model_var_scope = module_scope + '_' + model_name
    return model_var_scope


def _get_reason(cluster_or_step):
    """Get state change reason message."""
    return cluster_or_step['Status']['StateChangeReason'].get('Message', '')


def describe_vtl_devices(GatewayARN=None, VTLDeviceARNs=None, Marker=None,
    Limit=None):
    """
    Returns a description of virtual tape library (VTL) devices for the specified tape gateway. In the response, AWS Storage Gateway returns VTL device information.
    This operation is only supported in the tape gateway architecture.
    See also: AWS API Documentation

    Examples
    Returns a description of virtual tape library (VTL) devices for the specified gateway.
    Expected Output:

    :example: response = client.describe_vtl_devices(
        GatewayARN='string',
        VTLDeviceARNs=[
            'string',
        ],
        Marker='string',
        Limit=123
    )

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

    :type VTLDeviceARNs: list
    :param VTLDeviceARNs: An array of strings, where each string represents the Amazon Resource Name (ARN) of a VTL device.
            Note
            All of the specified VTL devices must be from the same gateway. If no VTL devices are specified, the result will contain all devices on the specified gateway.
            (string) --

    :type Marker: string
    :param Marker: An opaque string that indicates the position at which to begin describing the VTL devices.

    :type Limit: integer
    :param Limit: Specifies that the number of VTL devices described be limited to the specified number.

    :rtype: dict
    :return: {
        'GatewayARN': 'string',
        'VTLDevices': [
            {
                'VTLDeviceARN': 'string',
                'VTLDeviceType': 'string',
                'VTLDeviceVendor': 'string',
                'VTLDeviceProductIdentifier': 'string',
                'DeviceiSCSIAttributes': {
                    'TargetARN': 'string',
                    'NetworkInterfaceId': 'string',
                    'NetworkInterfacePort': 123,
                    'ChapEnabled': True|False
                }
            },
        ],
        'Marker': 'string'
    }

    """
    pass


def is_orderer_tls_true(opts):
    """Check if tls is enabled for orderer
        Args:
            opts (dict): Nephos options dict.

        Returns:
            bool: return true if tls is enabled for orderer and false otherwise
    """
    if 'tls' in opts['ordering']:
        return opts['ordering']['tls']['enable'] == 'true'
    return False


def _process_sort_string(sort_string):
    """Returns a list of tuples: (sort condition, reverse sort)"""
    cmp = []
    for attrname in sort_string.split(','):
        attrname = attrname.strip()
        rev = False
        if attrname.endswith('+'):
            attrname = attrname[:-1]
        elif attrname.endswith('-'):
            attrname = attrname[:-1]
            rev = True
        cmp.append((attrname, rev))
    return cmp


@staticmethod
def precision_conf(conf):
    """compute precision"""
    TN, FP, FN, TP = conf
    if TP + FP == 0:
        return float('nan')
    return TP / float(TP + FP)


def max_days_in_month(year, month):
    """
    Determines the number of days of a specific month in a specific year.
    """
    if month in (1, 3, 5, 7, 8, 10, 12):
        return 31
    if month in (4, 6, 9, 11):
        return 30
    if year % 400 == 0 or year % 100 != 0 and year % 4 == 0:
        return 29
    return 28


def offset_component_to_direction_string(coordinate_id: int, value: int) ->str:
    """Translates numerical offset to string notation.

    x offsets are labeled with east 'E' and 'W',
    y offsets with north 'N' and 'S' and
    z offsets with top 'T' and bottom 'B'
    If the absolute value of the offset is bigger than 1, this number is prefixed.

    Args:
        coordinate_id: integer 0, 1 or 2 standing for x,y and z
        value: integer offset

    Examples:
        >>> offset_component_to_direction_string(0, 1)
        'E'
        >>> offset_component_to_direction_string(1, 2)
        '2N'
    """
    assert 0 <= coordinate_id < 3, 'Works only for at most 3D arrays'
    name_components = ('W', 'E'), ('S', 'N'), ('B', 'T')
    if value == 0:
        result = ''
    elif value < 0:
        result = name_components[coordinate_id][0]
    else:
        result = name_components[coordinate_id][1]
    if abs(value) > 1:
        result = '%d%s' % (abs(value), result)
    return result


def assign_demo_info(files, demo_info):
    """
	Creates a list where each DemoInfo object in demo_info is sitting next
	to its file. If a file does not have a relevant entry in demo_info,
	it will have None matched up instead.

	files : List of file names ["abc.dem", "def.dem", ...]
	demo_info : List of DemoInfo instances.
	"""
    assigned_dat = [None for _ in files]
    for i, file in enumerate(files):
        for j in demo_info:
            if j.demo_name == file:
                assigned_dat[i] = j
    return assigned_dat


def _print_removed_output(original, new, function):
    """
    function printing the output of functions that tag datapoints.

    Parameters
    ----------
    original : int
        original length of the dataset
    new : int
        length of the new dataset
    function : str
        info on the function used to filter the data

    """
    print(str(original - new) +
        ' values detected and tagged as filtered by function ' + function)


def grid_configure_query(widget, command, index, option=None):
    """Hack of Tkinter.py Misc method _grid_configure for option queries.

    widget.grid_rowconfigure(1, 'pad') and similar do not work at Python 2.6
    because the self.tk.call(...) for the query, in _grid_configure, returns
    an int (maybe a double for width?) rather than a str; at least when
    Tk/Tcl 8.5 is used.

    This function can handle 'weight', 'pad', 'minsize', 'uniform', and
    'all', option queries for columnconfigure and rowconfigure commands.

    Queries on 'uniform' work in the genuine function.

    """
    if option is None:
        res = widget.tk.call('grid', command, widget._w, index)
        words = widget.tk.splitlist(res)
        dict = {}
        for i in range(0, len(words), 2):
            key = words[i][1:]
            value = words[i + 1]
            if key == 'uniform':
                if not value:
                    value = None
            elif value == '':
                value = None
            dict[key] = value
        return dict
    else:
        res = widget.tk.call(('grid', command, widget._w, index, ''.join((
            '-', option.rstrip('_').lstrip('-')))))
        if option == 'uniform':
            if not res:
                res = None
        elif res == '':
            res = None
        return res


def findnone(vec):
    """return the index of the first occurence of item in vec"""
    for i in range(len(vec)):
        if vec[i] is None:
            return i
    return -1


def get_notes_and_rests(part):
    """
    Given a part, extracts a flattened list of all notes in the part
    part - the part to extract
    """
    return list(part.recurse().notesAndRests)


def white(string):
    """foreground color to white"""
    return '\x1b[37m' + string + '\x1b[0m'


def bC_Na_HCO3_HMW84(T, P):
    """c-a: sodium bicarbonate [HMW84]."""
    b0 = 0.0277
    b1 = 0.0411
    b2 = 0.0
    C0 = 0
    C1 = 0
    alph1 = 2
    alph2 = -9
    omega = -9
    valid = T == 298.15
    return b0, b1, b2, C0, C1, alph1, alph2, omega, valid


@classmethod
def translate_int(cls, val):
    """Default behavior for translation"""
    return cls.translate_raw_str(val)


@classmethod
def is_binary_payload(cls) ->bool:
    """True if payload is not JSON."""
    return True


def is_iter_non_string(obj):
    """test if object is a list or tuple"""
    if isinstance(obj, list) or isinstance(obj, tuple):
        return True
    return False


def _is_positive_row(start, end, feature_start, feature_end, threshold):
    """
    Determine if a feature annotation overlaps enough with a query
    region to meet a minimal overlap threshold and be considered a
    positive example of said feature.

    Parameters
    ----------
    start : int
        The 0-based start coordinate of the query region.
    end : int
        One past the last coordinate of the query region.
    feature_start : int
        The 0-based start coordinate of the feature.
    feature_end : int
        One past the last coordinate of the feature.
    threshold : float
        The minimum fraction of the query region that a feature must
        overlap with to be considered positive.

    Returns
    -------
    bool
        `True` if the feature is a positive example and meets the
        overlap threshold. Otherwise `False`.

    """
    overlap_start = max(feature_start, start)
    overlap_end = min(feature_end, end)
    min_overlap_needed = int((end - start) * threshold - 1)
    if min_overlap_needed < 0:
        min_overlap_needed = 0
    if overlap_end - overlap_start > min_overlap_needed:
        return True
    else:
        return False


@classmethod
def _segment(cls, segment):
    """
        Returns a property capable of setting and getting a segment.
        """
    return property(fget=lambda x: cls._get_segment(x, segment), fset=lambda
        x, v: cls._set_segment(x, segment, v))


def object_sort_key(obj):
    """
    Define a predictable sort ordering for Kubernetes objects.

    This should be the same ordering that Kubernetes itself imposes.
    """
    return getattr(obj.metadata, 'namespace', None), obj.metadata.name


def __contains__(username):
    """Does user exist in site for user login name"""


def bytes_to_int(be_bytes):
    """Interprets a big-endian sequence of bytes as an integer"""
    return int.from_bytes(be_bytes, 'big')


def get_code_title(xml) ->str:
    """
    Provide "title" identifier for the :class:`Code` XML.

    :returns:
        the contents of an XML ``title`` element that
        describes the ``Code``, if any. Otherwise
        returns a descriptive name that may not exactly
        appear in the XML.
    """
    uslm_title = xml.find('title')
    if uslm_title:
        return uslm_title.text
    cal_title = xml.h3
    if cal_title:
        code_name = cal_title.b.text.split(' - ')[0]
        return f'California {code_name}'
    cfr_title = xml.CFRGRANULE.FDSYS.CFRTITLE
    if cfr_title:
        return f'Code of Federal Regulations Title {cfr_title.text}'
    raise NotImplementedError


def xor_bytes(input_bytes, key_bytes):
    """XOR input bytes, repeating the XOR key as necessary."""
    result = []
    for i, inb in enumerate(input_bytes):
        result.append(inb ^ key_bytes[i % len(key_bytes)])
    return bytes(result)