def _get_field_length(bit_config):
    """
    Determine length of iso8583 style field

    :param bit_config: dictionary of bit config data
    :return: length of field
    """
    length_size = 0
    if bit_config['field_type'] == 'LLVAR':
        length_size = 2
    elif bit_config['field_type'] == 'LLLVAR':
        length_size = 3
    return length_size


def _render_rows(options, pkgs, arches):
    """Build rows for tabular data output."""
    for pkg in sorted(pkgs):
        keywords = set(pkg.keywords)
        row = [pkg.fullver]
        for arch in arches:
            if arch in keywords:
                line = '+'
            elif f'~{arch}' in keywords:
                line = '~'
            elif f'-{arch}' in keywords:
                line = '-'
            elif '-*' in keywords:
                line = '*'
            else:
                line = 'o'
            row.append(options.colormap(line))
        row.extend([pkg.eapi, pkg.fullslot, pkg.repo.repo_id])
        yield row


@classmethod
def setup(cls, **kwargs):
    """Set up the storage system for memcached-based sessions.

        This should only be called once per process; this will be done
        automatically when using sessions.init (as the built-in Tool does).
        """
    for k, v in kwargs.items():
        setattr(cls, k, v)
    import memcache
    cls.cache = memcache.Client(cls.servers)


@staticmethod
def margins_func(widget_item):
    """ Get the margins for the given widget item.

        """
    m = widget_item.widget().contentsMargins()
    return m.top(), m.right(), m.bottom(), m.left()


@staticmethod
def item(index):
    """Provides a reference to an item"""
    if not index.isValid():
        return None
    return index.internalPointer()


def search_sub_exp(ope, op1, op2, com, sub_dict):
    """
    search if an expression a op b was already translated to clause constraints
    @param ope: operator (string)
    @param op1: left operand (literal)
    @param op2: right operand (literal)
    @param com: bool - true if operator is commutative
    @param sub_dict:directory of sub expressions
    """
    key = ope + '#' + op1.code_name() + '#' + op2.code_name()
    try:
        val_var = sub_dict[key]
        return val_var
    except KeyError:
        if com:
            key = ope + '#' + op2.code_name() + '#' + op1.code_name()
            try:
                val_var = sub_dict[key]
                return val_var
            except KeyError:
                return None
        else:
            return None


def _copy_file_obj(source, destination, callback, length=16 * 1024):
    """Modified version of shutil.copyfileobj with callback"""
    while True:
        buf = source.read(length)
        if not buf:
            break
        destination.write(buf)
        callback(len(buf))


@classmethod
def processQ(cls):
    """Pop functions from the parsing queue one by one and execute them"""
    while len(cls.parsingQ) > 0:
        cls.parsingQ.pop()()


def supportsUndo():
    """Return True, indicating that the storage supports undo.
        """


def bone_distance(obj, bone1, bone2):
    """ Returns the distance between two bones.

    """
    vec = obj.data.bones[bone1].head - obj.data.bones[bone2].head
    return vec.length


def get_exception_message(ex):
    """Build exception message with details.
    """
    template = '{0}: {1!r}'
    return template.format(type(ex).__name__, ex.args)


def nb_per_chunk(item_size, item_dim, chunk_size):
    """Return the number of items that can be stored in one chunk.

    :param int item_size: Size of an item's scalar componant in
        Bytes (e.g. for np.float64 this is 8)

    :param int item_dim: Items dimension (length of the second axis)

    :param float chunk_size: The size of a chunk given in MBytes.

    """
    size = chunk_size * 10.0 ** 6
    ratio = int(round(size / (item_size * item_dim)))
    return max(10, ratio)


def close(library, session):
    """Closes the specified session, event, or find list.

    Corresponds to viClose function of the VISA library.

    :param library: the visa library wrapped by ctypes.
    :param session: Unique logical identifier to a session, event, or find list.
    :return: return value of the library call.
    :rtype: :class:`pyvisa.constants.StatusCode`
    """
    return library.viClose(session)


def cmd_list_users(omni_app, realm_or_store):
    """
    Usage: omni list-users <realm-or-store>

    Shows a list of users in a realm or store.

    Options:

      -h, --help  Show this help message.
    """
    try:
        return sorted(omni_app.get_realm_or_store(realm_or_store).usernames())
    except KeyError:
        return '{}: invalid realm/store'.format(realm_or_store)


def normalize(dfy):
    """Center around mean zero and standardize deviation."""
    centered = dfy - dfy.mean().tolist()[0]
    return centered / float(dfy.std().tolist()[0])


def __is_type(obj: any) ->bool:
    """
    Checks if obj is Python class.
    Args:
        obj (any): object to check

    Returns (bool): indicator of obj is class

    """
    return obj is type


@staticmethod
def generate(config, spec):
    """Produce file block segments for packaging files."""
    for file_ in config.file_extras.files:
        if file_.file_type is not None:
            if file_.file_type_option is not None:
                file_directive = '%{1}({2}) /{0}'.format(file_.dest, file_.
                    file_type, file_.file_type_option)
            else:
                file_directive = '%{1} /{0}'.format(file_.dest, file_.file_type
                    )
        else:
            file_directive = '/{0}'.format(file_.dest)
        spec.blocks.install.append('mkdir -p "%{{buildroot}}/%(dirname {0})"'
            .format(file_.dest))
        spec.blocks.install.append('cp -R %{{SOURCE0}}/{0} %{{buildroot}}/{1}'
            .format(file_.src, file_.dest))
        spec.blocks.files.append(file_directive)
        spec.blocks.post.append(
            'chown -R %{{file_permissions_user}}:%{{file_permissions_group}} /{0}'
            .format(file_.dest))
    return spec


def as_bytes(value):
    """
    Returns value as bytes
    """
    if not isinstance(value, bytes):
        return value.encode('UTF-8')
    return value


def trim_leading(scores, threshold):
    """
    Trim low quality bases from the 5'-end of the sequence
    """
    threshold = abs(threshold)
    position = 0
    for position, basescore in enumerate(scores):
        if basescore >= threshold:
            break
    return position, 0


def createTerm(context, source, value, title, token, request):
    """Create and return a term object."""


def edge_reduction(initial_edge, final_edge, poweredge, _):
    """Compute edge reduction (percentage)"""
    try:
        edge = initial_edge
        poweredge = final_edge + poweredge
        return (edge - poweredge) / edge * 100
    except ZeroDivisionError:
        return 100.0


@classmethod
def get_alias(cls, item_id):
    """Returns item alias by ID.

        :param int item_id: Item ID.
        :rtype: str
        """
    return cls.aliases.get(item_id)


def __matches(s1, s2, ngrams_fn, n=3):
    """
        Returns the n-grams that match between two sequences

        See also: SequenceMatcher.get_matching_blocks

        Args:
            s1: a string
            s2: another string
            n: an int for the n in n-gram

        Returns:
            set:
    """
    ngrams1, ngrams2 = set(ngrams_fn(s1, n=n)), set(ngrams_fn(s2, n=n))
    return ngrams1.intersection(ngrams2)


@staticmethod
def from_dict(input_dict, data=None):
    """
        Instantiate an object of a derived class using the information
        in input_dict (built by the to_dict method of the derived class).
        More specifically, after reading the derived class from input_dict,
        it calls the method _build_from_input_dict of the derived class.
        Note: This method should not be overrided in the derived class. In case
        it is needed, please override _build_from_input_dict instate.

        :param dict input_dict: Dictionary with all the information needed to
           instantiate the object.
        """
    import copy
    input_dict = copy.deepcopy(input_dict)
    model_class = input_dict.pop('class')
    input_dict['name'] = str(input_dict['name'])
    import GPy
    model_class = eval(model_class)
    return model_class._build_from_input_dict(input_dict, data)


def stabilize_2d_add():
    """Add selected tracks to 2D translation stabilization

    """
    pass


def promote(content_view_version, environment_id, force=False):
    """Call ``content_view_version.promote(…)``.

    :param content_view_version: A ``nailgun.entities.ContentViewVersion``
        object.
    :param environment_id: An environment ID.
    :param force: Whether to force the promotion or not. Only needed if
        promoting to a lifecycle environment that is not the next in order
        of sequence.
    :returns: Whatever ``nailgun.entities.ContentViewVersion.promote`` returns.

    """
    data = {u'environment_id': environment_id, u'force': True if force else
        False}
    return content_view_version.promote(data=data)


def result(obj):
    """Results are stored on the nodes in the workflow at run time. This
    function can be used to get at a result of a node in a workflow after
    run time. This is not a recommended way of getting at results, but can
    help with debugging."""
    return obj.__result__()


def scale_size(size, sizer):
    """Scales a size tuple based on a sizer tuple.

    A sizer is just a size tuple that specifies only width or height.
    """
    if not any(sizer):
        return size
    size_new = list(sizer)
    i = size_new.index(None)
    j = i * -1 + 1
    size_new[i] = size_new[j] * size[i] // size[j]
    return tuple(size_new)


@classmethod
def get(cls, func):
    """Create an authenticate object with a GET method

        Arguments:
            func: a function to decorate

        """
    return cls(func, method='GET')


def on_key_event(text):
    """ Print the current text. """
    print('Current text:', text)


def print_usage():
    """Prints the usage for the CLI command."""
    print('Usage: testdocker {init}')
    exit(1)


def print_error_message(obj, msg):
    """Indicates there's an error and invalidates the input from that textbox"""
    obj.setStyleSheet('color: red;')
    print('[ Error ] ', msg)
    obj.valid = False


def _join_alignments(align_dict):
    """
    Take a dictionary of multiple sequence alignments, and join according to
    dictionary key order (generally position in sequence).

    Args:
        align_dict (dict): A dictionary containing single-site multiple sequence
            alignment objects accessed by position in original alignment.

    Returns:
        MultipleSequenceAlignment: A multiple sequence alignment object
            containing all polymorphic sites.
    """
    output = None
    for key in sorted(align_dict):
        if not output:
            output = align_dict[key]
        else:
            output = output + align_dict[key]
    return output


def _extract_errors(log_interpretation):
    """Extract all errors from *log_interpretation*, in no particular order."""
    errors = []
    for log_type in ('step', 'history', 'task'):
        errors.extend(log_interpretation.get(log_type, {}).get('errors') or ())
    return errors


@classmethod
def get_default(cls):
    """Get default selective run function.

        :return: default instance that will be used if user did not provided configuration
        """
    return cls(cls._DEFAULT_FUNCTION_NAME, cls._DEFAULT_IMPORT_PATH)


@classmethod
def fetch(cls, obj, keys):
    """
        fetches the value corresponding to keys from obj
        """
    current = obj
    for key in keys.split('.'):
        if type(current) == list:
            try:
                key = int(key)
            except TypeError:
                raise cls.Missing(key)
        try:
            current = current[key]
        except (IndexError, KeyError, TypeError) as ex:
            raise cls.Missing(key)
    return current


def items(_):
    """ Return (unsorted) list or dict_items object for all configuration's key-value pairs.
    >>> from configr import Configr
    >>> c = Configr("X", data = {1: 1, 2: 2, "c": "c"})
    >>> print(sorted(c.items()))
    [('1', 1), ('2', 2), ('c', 'c')]
    """
    return _.__map.items()


def indent_string(content, indent):
    """ Utility function to indent a string by given levels """
    return ''.join(['\t'] * indent) + content


def add_functions_to_class(cls, funcs):
    """Add functions as methods of a class.

    Parameters
    ----------
    cls : class
        A class.
    funcs : dict
        Dictionary of function names and instances.
    """
    for name, func in funcs.items():
        setattr(cls, name, func)


def avg(vals, count=None):
    """ Returns the average value

    Args:
        vals: List of numbers to calculate average from.
        count: Int of total count that vals was part of.

    Returns:
        Float average value throughout a count.
    """
    sum = 0
    for v in vals:
        sum += v
    if count is None:
        count = len(vals)
    return float(sum) / count


@classmethod
def register_property_set_type(cls, name, group_yaml_type, estimator_type):
    """(class method) Register new property set type.

        Parameters
        ----------
        name : str
            Name of new property set type.
        group_yaml_type : str
            Name of property set type in the YAML type namespace.
        estimator_type : class
            The provided class is instantiated when an estimate is to be made
            for a particular set of groups.  The constructor should accept the
            following parameters:

                library : :class:`GroupLibrary`
                    library which is to be used to estimate these properties.
                groups : mapping
                    Map from :class:`Group` to int or float specifying counts
                    of each group in the chemical structure.
        """
    if name in cls._property_set_group_yaml_types:
        raise KeyError('Property set %r already registered.' % name)
    cls._property_set_group_yaml_types[name] = group_yaml_type
    cls._property_set_estimator_types[name] = estimator_type


def describe_maintenance_windows(Filters=None, MaxResults=None, NextToken=None
    ):
    """
    Retrieves the Maintenance Windows in an AWS account.
    See also: AWS API Documentation

    :example: response = client.describe_maintenance_windows(
        Filters=[
            {
                'Key': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        MaxResults=123,
        NextToken='string'
    )

    :type Filters: list
    :param Filters: Optional filters used to narrow down the scope of the returned Maintenance Windows. Supported filter keys are Name and Enabled.
            (dict) --Filter used in the request.
            Key (string) --The name of the filter.
            Values (list) --The filter values.
            (string) --

    :type MaxResults: integer
    :param MaxResults: The maximum number of items to return for this call. The call also returns a token that you can specify in a subsequent call to get the next set of results.

    :type NextToken: string
    :param NextToken: The token for the next set of items to return. (You received this token from a previous call.)

    :rtype: dict
    :return: {
        'WindowIdentities': [
            {
                'WindowId': 'string',
                'Name': 'string',
                'Enabled': True|False,
                'Duration': 123,
                'Cutoff': 123
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def _param_sweep_helper(args):
    """
    helper for fitting many models on some data
    """
    model, sequences = args
    model.fit(sequences)
    return model


def isbytestring(obj):
    """Determine if obj is a byte :class:`bytes`

    In python2 this is equivalent to isinstance(obj, str).  In python3 it
    checks whether the object is an instance of bytes or bytearray.

    :arg obj: Object to test
    :returns: True if the object is a byte :class:`bytes`.  Otherwise, False.

    .. versionadded:: Kitchen: 1.2.0, API kitchen.text 2.2.0
    """
    if isinstance(obj, (bytes, bytearray)):
        return True
    return False


@classmethod
def check_args(cls, config, options, args, parser, package_file=None):
    """
        Override in subclass if required.
        """
    if not args:
        parser.error('no input files specified')
    if not (package_file or options.package_file):
        parser.error('no package file specified')
    if not options.entry_point_process:
        parser.error('no entry point process specified')


@classmethod
def list(cls, context, limit=None, marker=None, sort_key=None, sort_dir=None):
    """Return a list of VolumeTarget objects.

        :param context: security context
        :param limit: maximum number of resources to return in a single result
        :param marker: pagination marker for large data sets
        :param sort_key: column to sort results by
        :param sort_dir: direction to sort. "asc" or "desc".
        :returns: a list of :class:`VolumeTarget` objects
        :raises: InvalidParameterValue if sort_key does not exist
        """
    db_targets = cls.dbapi.get_volume_target_list(limit=limit, marker=
        marker, sort_key=sort_key, sort_dir=sort_dir)
    return cls._from_db_object_list(context, db_targets)


def parseTerms(text):
    """Pass the text through the pipeline.

        Return a list of words, normalized by the pipeline
        (e.g. stopwords removed, case normalized etc.).
        """


def withParentAndName(parent, name):
    """
        Return a new object that is a copy of this object, but
        being located at the given parent and name.
        """


@classmethod
def from_http_response(cls, resp):
    """
        Build a ``Response`` from the provided ``HTTPResponse`` object.

        This function will call `.read()` to consume the body of the ``HTTPResponse`` object.

        :param resp: ``HTTPResponse`` object to build the ``Response`` from
        :type resp: ``HTTPResponse``
        :rtype: ``Response``
        :returns: A new ``Response``
        """
    return cls(status=resp.status, body=resp.read(), reason=getattr(resp,
        'reason', None), msg=getattr(resp, 'msg', None))


def create_smtp(module, array):
    """Set SMTP settings"""
    changed = True
    current_smtp = array.get_smtp()
    if not module.check_mode:
        if module.params['sender_domain'] and current_smtp['sender_domain'
            ] != module.params['sender_domain']:
            try:
                array.set_smtp(sender_domain=module.params['sender_domain'])
                changed_sender = True
            except Exception:
                module.fail_json(msg='Set SMTP sender domain failed.')
        else:
            changed_sender = False
        if module.params['relay_host'] and current_smtp['relay_host'
            ] != module.params['relay_host']:
            try:
                array.set_smtp(relay_host=module.params['relay_host'])
                changed_relay = True
            except Exception:
                module.fail_json(msg='Set SMTP relay host failed.')
        else:
            changed_relay = False
        if module.params['user']:
            try:
                array.set_smtp(user_name=module.params['user'], password=
                    module.params['password'])
                changed_creds = True
            except Exception:
                module.fail_json(msg='Set SMTP username/password failed.')
        else:
            changed_creds = False
        changed = bool(changed_sender or changed_relay or changed_creds)
    module.exit_json(changed=changed)


@staticmethod
def _postprocessing(pattern):
    """Add additional formatting to the option.

        :param pattern:
        :type pattern: string

        :return:
        :rtype:
        """
    return pattern


def l_to_q(l):
    """
    Convert liters to quarts US
    """
    return l * 1.056688


def draw_line(labels, pt0, pt1, value=1):
    """Draw a line between two points

    pt0, pt1 are in i,j format which is the reverse of x,y format
    Uses the Bresenham algorithm
    Some code transcribed from http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
    """
    y0, x0 = pt0
    y1, x1 = pt1
    diff_y = abs(y1 - y0)
    diff_x = abs(x1 - x0)
    x = x0
    y = y0
    labels[y, x] = value
    step_x = x1 > x0 and 1 or -1
    step_y = y1 > y0 and 1 or -1
    if diff_y > diff_x:
        remainder = diff_x * 2 - diff_y
        while y != y1:
            if remainder >= 0:
                x += step_x
                remainder -= diff_y * 2
            y += step_y
            remainder += diff_x * 2
            labels[y, x] = value
    else:
        remainder = diff_y * 2 - diff_x
        while x != x1:
            if remainder >= 0:
                y += step_y
                remainder -= diff_x * 2
            x += step_x
            remainder += diff_y * 2
            labels[y, x] = value


def _get_exon_cds(exon_cdna_seq, cdna_coding_start, cdna_coding_end,
    first_exon, last_exon):
    """
    Return the CDS of the exon.

    This function takes the cDNA sequence of the exon and the
    coding start and end coordinates to cut the sequence and
    return the coding sequence (CDS) of the exon.
    """
    cdna_len = len(exon_cdna_seq)
    cds_len = cdna_coding_end - cdna_coding_start + 1
    if cds_len == cdna_len:
        return exon_cdna_seq
    if first_exon:
        return exon_cdna_seq[-cds_len:]
    if last_exon:
        return exon_cdna_seq[:cds_len]
    raise ValueError('exon has {} bases instead of {}'.format(cdna_len,
        cds_len))


def explore(df, key):
    """Function to explore a dictionary that is THREE levels deep and return the data sitting at
    the end of key.

    Parameters
    ----------
    df : dict
        Dictionary that you want to search through.

    Examples
    ---------
    Consider a dictionary that has `df['layer']['cloud']['w0'] = [0,0,0]`

    >>>explore(df, 'w0')
    [0,0,0]
    """
    check = [False, True, True]
    if df.get(key) is None:
        for i in df.keys():
            try:
                if df[i].get(key) is None:
                    for ii in df[i].keys():
                        try:
                            if df[i][ii].get(key) is not None:
                                return df[i][ii].get(key)
                        except AttributeError:
                            check[2] = False
                else:
                    return df[i].get(key)
            except AttributeError:
                check[1] = False
    elif df.get(key) is not None:
        return df.get(key)
    if True not in check:
        raise Exception(
            'The key that was entered cloud not be found within three layers of the specified dictionary'
            )


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

        :param PaperApiCursorError val:
        :rtype: ListUsersCursorError
        """
    return cls('cursor_error', val)


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_bool()
    return parameters


def MigrateInstance(r, instance, mode=None, cleanup=None):
    """
    Migrates an instance.

    @type instance: string
    @param instance: Instance name
    @type mode: string
    @param mode: Migration mode
    @type cleanup: bool
    @param cleanup: Whether to clean up a previously failed migration
    """
    body = {}
    if mode is not None:
        body['mode'] = mode
    if cleanup is not None:
        body['cleanup'] = cleanup
    return r.request('put', '/2/instances/%s/migrate' % instance, content=body)


def dispatch(source, tag, buffer):
    """Dispatch on source for tag with buffer

    Find the attribute or key tag[0] of source,
    then call it with (tag, buffer)
    """
    try:
        function = getattr(source, tag[0])
    except AttributeError:
        try:
            function = source[tag[0]]
        except:
            raise AttributeError(
                'No processing function for tag "%s" in object %s! Check the parser definition!'
                 % (tag[0], repr(source)))
    return function(tag, buffer)


def get(name):
    """Get an operation given a name

        :param name: name of the operation
        :returns: the operation
        :rtype operation: an object implementing :class:`IPaymentOperation`
        """


def enumarg(enum, arg):
    """Return enum member from its name or value.

    >>> enumarg(TIFF.PHOTOMETRIC, 2)
    <PHOTOMETRIC.RGB: 2>
    >>> enumarg(TIFF.PHOTOMETRIC, 'RGB')
    <PHOTOMETRIC.RGB: 2>

    """
    try:
        return enum(arg)
    except Exception:
        try:
            return enum[arg.upper()]
        except Exception:
            raise ValueError(f'invalid argument {arg}')


def get_bit(byte, bit):
    """ Get bit value from byte """
    return byte >> bit & 1


def writeVelocityStructure(temp, model):
    """Velocity component."""
    temp.append('void velocity(double x, double y,')
    temp.append('double z, double *velocity) {\n\n')
    temp.append('\tif (sqrt(x*x + y*y + z*z) == 0.0){\n')
    temp.append('\t\tvelocity[0] = 0.0;\n')
    temp.append('\t\tvelocity[1] = 0.0;\n')
    temp.append('\t\tvelocity[2] = 0.0;\n')
    temp.append('\t\t return;\n')
    temp.append('\t}\n\n')
    temp.append('\tdouble velo;\n')
    if model.mstar is not None:
        temp.append('\tvelo = sqrt(6.67e-11 * %.3f' % model.mstar)
        temp.append(' * 1.989e30 / sqrt(x*x + y*y + z*z));\n')
    else:
        temp.append('\tvelo = findvalue(x, y, z, vrot);\n')
    temp.append('\tvelocity[0] = velo * sin(atan2(y,x));\n')
    temp.append('\tvelocity[1] = velo * cos(atan2(y,x));\n')
    temp.append('\tvelocity[2] = 0.0;\n')
    temp.append('\n}\n\n\n')
    return


def resize_to(img, targ_sz: int, use_min: bool=False):
    """Size to resize to, to hit `targ_sz` at same aspect ratio, in PIL coords (i.e w*h)"""
    w, h = img.size
    min_sz = (min if use_min else max)(w, h)
    ratio = targ_sz / min_sz
    return int(w * ratio), int(h * ratio)


def vector_maths(wvs, pwords=None, nwords=None, n=1):
    """ Perform word vector maths

    Parameters
    ----------
    wvs : :obj:`gensim.model`
        Trained word vector model
    pwords : :obj:`list`
        list of positive words
    nwords : :obj:`list`
        list of negative words
    n  : :obj:`int`
        Number of close words to return.

    Returns
    -------
        most_similar : :obj:`list`
            list of most similar words and their distance
    """
    most_similar = wvs.wv.most_similar(positive=pwords, negative=nwords, topn=n
        )
    return most_similar


def info_travel_dist(n_maxpool, conv=3):
    """
    n_maxpool: number of 2x downsampling steps
    conv: the width of the convolution kernel (e.g. "3" for standard 3x3 kernel.)
    returns: the info travel distance == the amount of width that is lost in a patch / 2
        i.e. the distance from the pixel at the center of a maxpool grid to the edge of
        the grid.
    """
    conv2 = 2 * (conv - 1)
    width = 0
    for i in range(n_maxpool):
        width -= conv2
        width /= 2
    width -= conv2
    for i in range(n_maxpool):
        width *= 2
        width -= conv2
    return int(-width / 2)


@classmethod
def get__by__id(cls, dbSession, id, id_column='id'):
    """classmethod. gets an item by an id column named 'id'.  id column can be overriden"""
    if not hasattr(cls, id_column) and hasattr(cls, '__table_pkey__'):
        id_column = cls.__table_pkey__
    id_col = getattr(cls, id_column)
    if isinstance(id, (list, tuple)):
        return dbSession.query(cls).filter(id_col.in_(id)).all()
    else:
        id_dict = {id_column: id}
        return dbSession.query(cls).filter_by(**id_dict).first()


@classmethod
def read_chunk(cls, opc_sync: bool, context: str) ->'IoTransferEventArgs':
    """Creates new IoTransferEventArgs of read string

		:param opc_sync: defines if the command is OPC-synchronised
		:param context: SCPI query. It is truncated to maximum of 100 characters.
		:return: IoTransferEventArgs object of a read string operation."""
    return cls(True, opc_sync, None, context)


def is_somatic(var):
    """
    Return whether the variant is somatically acquired
    """
    return var.INFO.get('SOMATIC')


def rectangle_aabb(matrix, pos_x, pos_y, width, height):
    """Apply a transformation matrix to an axis-aligned rectangle
    and return its axis-aligned bounding box as ``(x, y, width, height)``

    """
    transform_point = matrix.transform_point
    x1, y1 = transform_point(pos_x, pos_y)
    x2, y2 = transform_point(pos_x + width, pos_y)
    x3, y3 = transform_point(pos_x, pos_y + height)
    x4, y4 = transform_point(pos_x + width, pos_y + height)
    box_x1 = min(x1, x2, x3, x4)
    box_y1 = min(y1, y2, y3, y4)
    box_x2 = max(x1, x2, x3, x4)
    box_y2 = max(y1, y2, y3, y4)
    return box_x1, box_y1, box_x2 - box_x1, box_y2 - box_y1


def plural(count):
    """Return s is count is > 1

    Args:
        count(int): number of occurences
    Returns:
        str: '' or 's'
    Example:
        >>> plural(3)
        's'
    """
    if count == 1:
        return ''
    else:
        return 's'


def ipython_shell_namespace():
    """
    get the IPython shell's namespace dictionary (or empty if not found)
    """
    try:
        from IPython import get_ipython
        ns = get_ipython().user_ns
    except AttributeError as _exc:
        ns = {}
    return ns


@classmethod
def request(cls, method, url, headers, params, data, timeout, proxies,
    verify, max_retries):
    """
        Main method to be implemented by HTTP clients.

        The returned data structure has the following fields:
        * `content`: string containing the response from the server
        * `status_code`: HTTP status code returned by the server

        Can raise the following exceptions:
        * `ClientError`: server cannot be contacted
        * `HttpTimeout`: connection timed out
        * `HTTPError`: unexpected HTTP response code
        """
    raise NotImplementedError(u'Must be implemented by HTTPClient subclasses.')


def PolsRenewal(t):
    """Number of policies: Renewal policies"""
    return 0


def serializeXML(handler):
    """Serialize current value for the given XML handler. This return a
        list of value that will be integrated in the XML.
        """


def p_record_list_multi(p):
    """record_list : ID COLON expr COMMA record_list"""
    p[0] = [(p[1], p[3])] + p[5]


def pretty_str_time(dt):
    """Get a pretty string for the given datetime object.

    Parameters
    ----------
    dt : :obj:`datetime`
        A datetime object to format.

    Returns
    -------
    :obj:`str`
        The `datetime` formatted as {year}_{month}_{day}_{hour}_{minute}.
    """
    return '{0}_{1}_{2}_{3}:{4}'.format(dt.year, dt.month, dt.day, dt.hour,
        dt.minute)


@classmethod
def _get_final_length(cls, l):
    """
        Returns the total length of the deepest lists inside ``ŀ``.

        :arg list l: A nested list.
        :returns: The total length of the deepest lists inside ``l``.
        :rtype: int

        >>> TableDict._get_final_length([['a', [1, 2, 3]], ['b', [4, 5]]])
        5
        """
    total = 0
    for item in l:
        if isinstance(item, (list, tuple)):
            header, group = item
            total += cls._get_final_length(group)
        else:
            total += 1
    return total


def align_down(value, round_to):
    """
    Rounds value down to provided alignment
    """
    return value // round_to * round_to


@classmethod
def product(cls, new_name, *keys):
    """Return a new Key that has the union of dimensions on *keys*.

        Dimensions are ordered by their first appearance:

        1. First, the dimensions of the first of the *keys*.
        2. Next, any additional dimensions in the second of the *keys* that
           were not already added in step 1.
        3. etc.

        Parameters
        ----------
        new_name : str
            Name for the new Key. The names of *keys* are discarded.
        """
    base_dims = list(keys[0].dims)
    new_dims = []
    for key in keys[1:]:
        new_dims.extend(set(key.dims) - set(base_dims) - set(new_dims))
    return cls(new_name, base_dims + new_dims)


def smart_setter(obj):
    """Returns a smart setter for `obj`.

    If `obj` is a mutable mapping, it returns the ``.__setitem__()`` method
    bound to the object `obj`, otherwise it returns a partial of ``setattr``
    on `obj`.

    .. versionadded:: 1.8.2

    """
    from xotl.tools.future.functools import partial
    from xotl.tools.future.collections import MutableMapping
    if isinstance(obj, MutableMapping):
        return obj.__setitem__
    else:
        return partial(setattr, obj)


@staticmethod
def str_timedelta(seconds):
    """
        Stringify a timedelta from seconds in form x h x min x s
        :param seconds: number of seconds
        :type seconds: int

        :return: timedelta from seconds in form x h x min x s
        :rtype: str
        """
    hour_minute = ''
    if seconds > 3600:
        hour_minute += str(int(seconds / 3600.0)) + ' h '
    if seconds > 60:
        hour_minute += str(int(seconds / 60) % 60) + ' min '
    return hour_minute + str(seconds % 60) + ' s'


@classmethod
def search(cls, charset, s, start=0):
    """ search for set of char in given charset (list) within s starting from start """
    for i, c in enumerate(s):
        if c in charset and i >= start:
            return i, c
    return -1, 0


def get_method(cls, name):
    """ python3 doesn't need the __func__ to get the func of the
        method.
    """
    method = getattr(cls, name)
    if hasattr(method, '__func__'):
        method = method.__func__
    return method


def __call__(toplevel, register):
    """Given the top-level object that is being copied, return the
        version of the adapted object that should be used in the new copy.

        Raising ResumeCopy means that you are foregoing the hook: the
        adapted object will continue to be recursively copied as usual.

        If you need to have a post-copy actions executed, register a
        callable with ``register``.  This callable must take a single
        argument: a callable that, given an object from the original,
        returns the equivalent in the copy.

        See README.txt for more explanation.
        """


def metrics_docs(obj_name: str) ->str:
    """
    Return a link to the documentation entry for the Glean SDK metric of the
    requested type.
    """
    base_url = 'https://mozilla.github.io/glean/book/user/metrics/{}.html'
    fixedup_name = obj_name
    if obj_name.startswith('labeled_'):
        fixedup_name += 's'
    return base_url.format(fixedup_name)


def object_as_camera():
    """Set the active object as the active camera for this view or scene

    """
    pass


def p_opt_if_exists_empty(p):
    """opt_IF_EXISTS : """
    p[0] = False


def Linear(x, a, b):
    """First-order polynomial

    Inputs:
    -------
        ``x``: independent variable
        ``a``: slope
        ``b``: offset

    Formula:
    --------
        ``a*x+b``
    """
    return a * x + b


def _get_next(request):
    """
    The part that's the least straightforward about views in this module is how they
    determine their redirects after they have finished computation.

    In short, they will try and determine the next place to go in the following order:

    1. If there is a variable named ``next`` in the *POST* parameters, the view will
    redirect to that variable's value.
    2. If there is a variable named ``next`` in the *GET* parameters, the view will
    redirect to that variable's value.
    3. If Django can determine the previous page from the HTTP headers, the view will
    redirect to that previous page.
    """
    next = request.POST.get('next', request.GET.get('next', request.META.
        get('HTTP_REFERER', None)))
    if not next:
        next = request.path
    return next


def dummy_func_to_demonstrate_docstring_modification(grid, some_arg):
    """A dummy function to demonstrate automated docstring changes.

    Parameters
    ----------
    grid : ModelGrid
        A Landlab modelgrid.
    some_arg : whatever
        A dummy argument.

    Examples
    --------
    ...
    """
    pass


def sortGlyphs(glyphlist):
    """
    Sort glyphs in a way that glyphs from the exceptionList, or glyphs starting
    with 'uni' names do not get to be key (first) glyphs.  An infinite loop is
    avoided, in case there are only glyphs matching above mentioned properties.
    """
    exceptionList = 'dotlessi dotlessj kgreenlandic ae oe AE OE uhorn'.split()
    glyphs = sorted(glyphlist)
    for i in range(len(glyphs)):
        if glyphs[0] in exceptionList or glyphs[0].startswith('uni'):
            glyphs.insert(len(glyphs), glyphs.pop(0))
        else:
            continue
    return glyphs


def percent(decimals=1):
    """A formatter to display a float as a percentage with a given number of decimals.

    Args:
        decimals: The number of decimals to display.

    Returns:
        A formatter function f returning f(a), being variable 'a' displayed as a percentage.
        Please note the formatter function will multiply the float by 100 to get a percentage.

    """
    return lambda a: '{:+.{prec}f}%'.format(100.0 * a, prec=decimals)


def p_non_empty_member_modifiers(p):
    """non_empty_member_modifiers : non_empty_member_modifiers member_modifier
                                  | member_modifier"""
    if len(p) == 3:
        p[0] = p[1] + [p[2]]
    else:
        p[0] = [p[1]]


def check_sink_place_presence(net):
    """
    Check if there is a unique sink place with empty connections

    Parameters
    -------------
    net
        Petri net

    Returns
    -------------
    place
        Unique source place (or None otherwise)
    """
    count_empty_output = 0
    unique_sink = None
    for place in net.places:
        if len(place.out_arcs) == 0:
            count_empty_output = count_empty_output + 1
            unique_sink = place
    if count_empty_output == 1:
        return unique_sink
    return None


def default_introspection_processing_hook(introspection_response, client,
    id_token):
    """
    Hook to customise the returned data from the token introspection endpoint
    :param introspection_response:
    :param client:
    :param id_token:
    :return:
    """
    return introspection_response


def simple_container_get_preferred_size(container, components=None):
    """ Returns the size (width,height) that is preferred for this component.

    Overrides PlotComponent.
    """
    if container.fixed_preferred_size is not None:
        return container.fixed_preferred_size
    if container.resizable == '':
        return container.outer_bounds
    if components is None:
        components = container.components
    fit_components = getattr(container, 'fit_components', '')
    no_visible_components = True
    max_width = 0.0
    max_height = 0.0
    if fit_components != '':
        for component in components:
            if not container._should_layout(component):
                continue
            no_visible_components = False
            pref_size = None
            if 'h' in fit_components:
                pref_size = component.get_preferred_size()
                if pref_size[0] > max_width:
                    max_width = pref_size[0]
            if 'v' in fit_components:
                if pref_size is None:
                    pref_size = component.get_preferred_size()
                if pref_size[1] > max_height:
                    max_height = pref_size[1]
    if 'h' not in fit_components:
        max_width = container.width
    if no_visible_components or max_width == 0:
        max_width = container.default_size[0]
    if 'v' not in fit_components:
        max_height = container.height
    if no_visible_components or max_height == 0:
        max_height = container.default_size[1]
    container._cached_preferred_size = (max_width + container.hpadding,
        max_height + container.vpadding)
    return container._cached_preferred_size


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


def get_migrate_snapshot_name(volume):
    """Return name for snapshot that will be used to migrate the volume."""
    return 'cinder-migrate-snapshot-%(id)s' % volume


def yn_input(text, yes='yes', no='no', default='yes'):
    """Asks a yes/no question and return the answer."""
    suffix = ' [%s/%s] ' % (yes[0].upper(), no[0])
    while True:
        ans = input(text + suffix).lower()
        if ans in (yes, no):
            return ans
        elif not ans:
            return default
        elif ans[0] == yes[0]:
            return yes
        elif ans[0] == no[0]:
            return no
        text = '    - please enter %r or %r' % (yes, no)


def bytes_to_proto(bytes_data, proto_constructor):
    """ Converts a bytes array back to a proto object """
    proto = proto_constructor()
    proto.ParseFromString(bytes_data)
    return proto


def letter_dict(text):
    """
    letter count dictionary
    """
    text = text.lower()
    replacements = {'á': 'a', 'é': 'e', 'í': 'i', 'ó': 'o', 'ú': 'u', 'ü': 'u'}
    for i, j in replacements.items():
        text = text.replace(i, j)
    letterlist = list(filter(None, map(lambda c: c if c.isalpha() else '',
        text)))
    letterdict = dict()
    for letter in letterlist:
        letterdict[letter] = letterdict.get(letter, 0) + 1
    return letterdict


def get_distinct_elements(items, key=None):
    """
    去除序列中的重复元素，使得剩下的元素仍然保持顺序不变，对于不可哈希的对象，需要指定 key ，说明去重元素

    :param:
        * items: (list) 需要去重的列表
        * key: (hook函数) 指定一个函数，用来将序列中的元素转换成可哈希类型

    :return:
        * result: (generator) 去重后的结果的生成器

    举例如下::

        print('--- remove_duplicate_elements demo---')
        list_demo = remove_duplicate_elements([1, 5, 2, 1, 9, 1, 5, 10])
        print(list(list_demo))
        list2 = [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
        dict_demo1 = remove_duplicate_elements(list2, key=lambda d: (d['x'], d['y']))
        print(list(dict_demo1))
        dict_demo2 = remove_duplicate_elements(list2, key=lambda d: d['x'])
        print(list(dict_demo2))
        dict_demo3 = remove_duplicate_elements(list2, key=lambda d: d['y'])
        print(list(dict_demo3))
        print('---')

    执行结果::

        --- remove_duplicate_elements demo---
        [1, 5, 2, 9, 10]
        [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
        [{'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
        [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
        ---

    """
    seen = set()
    for item in items:
        val = item if key is None else key(item)
        if val not in seen:
            yield item
            seen.add(val)


def read_snapgene(file_path):
    """
    Read a snapgene (.dna) file
    :param file_path: path to .dna file
    :return: dict with file contents
    """
    pass


@classmethod
def disable(cls):
    """Disables storage tracking, prevents storage events from being sent to the client.
        """
    return cls.build_send_payload('disable', {}), None


def load_module(path):
    """Return a reference to the module with the specified path

    Path should be given in dotted notation and be fully qualified.  That
    is it should look like path.to.module.

    """
    return __import__(path, globals(), locals(), [''])


def dic2hyperheader(dic):
    """
    Convert a Python dictionary into a hypercomplex block header list.

    Does not repack status from bit flags.
    """
    head = [0] * 9
    head[0] = dic['s_spare1']
    head[1] = dic['status']
    head[2] = dic['s_spare2']
    head[3] = dic['s_spare3']
    head[4] = dic['l_spare1']
    head[5] = dic['lpval1']
    head[6] = dic['rpval1']
    head[7] = dic['f_spare1']
    head[8] = dic['f_spare2']
    return head


def convert_py_to_cpp_namespace_code(python_namespace):
    """Convert a Python namespace to C++ namespace code.

    Parameters
    ----------
    python_namespace : `str`
        A string describing a Python namespace. For example,
        ``'lsst.example'``.

    Returns
    -------
    cpp_namespace_code : `str`
        C++ namespace code block. For example, ``'lsst.example'`` becomes:

        .. code-block:: cpp

           namespace lsst { example {

           }} // lsst::example

    Notes
    -----
    Use this filter in a Cookiecutter template like this::

        {{ 'lsst.example' | convert_py_to_cpp_namespace_code }}
    """
    name = python_namespace.replace('.', '::')
    namespace_parts = python_namespace.split('.')
    opening = 'namespace ' + ' { '.join(namespace_parts) + ' {\n'
    closing = '}' * len(namespace_parts) + ' // {}'.format(name)
    return '\n'.join((opening, closing))


def _is_mosaic(dicom_input):
    """
    Use this function to detect if a dicom series is a siemens 4d dataset
    NOTE: Only the first slice will be checked so you can only provide an already sorted dicom directory
    (containing one series)
    """
    if type(dicom_input) is list and type(dicom_input[0]) is list:
        header = dicom_input[0][0]
    else:
        header = dicom_input[0]
    if 'ImageType' not in header or 'MOSAIC' not in header.ImageType:
        return False
    if 'AcquisitionMatrix' not in header or header.AcquisitionMatrix is None:
        return False
    return True


def remove_borders(axes, left=False, bottom=False, right=True, top=True):
    """Remove chart junk from matplotlib plots.

    Parameters
    ----------
    axes : iterable
        An iterable containing plt.gca()
        or plt.subplot() objects, e.g. [plt.gca()].
    left : bool (default: `False`)
        Hide left axis spine if True.
    bottom : bool (default: `False`)
        Hide bottom axis spine if True.
    right : bool (default: `True`)
        Hide right axis spine if True.
    top : bool (default: `True`)
        Hide top axis spine if True.

    Examples
    -----------
    For usage examples, please see
    http://rasbt.github.io/mlxtend/user_guide/plotting/remove_chartjunk/

    """
    for ax in axes:
        ax.spines['top'].set_visible(not top)
        ax.spines['right'].set_visible(not right)
        ax.spines['bottom'].set_visible(not bottom)
        ax.spines['left'].set_visible(not left)
        if bottom:
            ax.tick_params(bottom='off', labelbottom='off')
        if top:
            ax.tick_params(top='off')
        if left:
            ax.tick_params(left='off', labelleft='off')
        if right:
            ax.tick_params(right='off')


ttwidgets//ttwidgets - Copy (2).pyfile:/ttwidgets - Copy (2).py:function:quote/quote

def quote(s):
    """Ensure that any string S with white space is enclosed in quotes."""
    if isinstance(s, str):
        if ' ' in s or len(s.split()) > 1:
            start, end = s[0], s[-1]
            if start != end or start not in ('"', "'"):
                q1s, q1d, q3s, q3d = "'", '"', 3 * "'", 3 * '"'
                if q1d not in s:
                    s = q1d + s + q1d
                elif q1s not in s:
                    s = q1s + s + q1s
                elif q3d not in s:
                    s = q3d + s + q3d
                elif q3s not in s:
                    s = q3s + s + q3s
    return s


def compute_sub_mask(outer_mask, outer_rect, inner_rect):
    """ Given a mask and sub-mask coordinates, extracts the sub-mask. No doubt numpy could do this in one line. :)
        outer_rect is the coords for the mask, and inner_rect is the sub-coordinates - contained entirely
        inside the outer_rect, nothing outside.
    """
    tl_x = inner_rect.tl_x - outer_rect.tl_x
    tl_y = inner_rect.tl_y - outer_rect.tl_y
    outer_width = outer_rect.width
    outer_height = outer_rect.height
    width = inner_rect.width
    height = inner_rect.height
    if width == outer_width and height == outer_height:
        return outer_mask
    inner_mask = []
    for y in range(height):
        for x in range(width):
            new_x = x + tl_x
            new_y = y + tl_y
            pixel_loc = new_x + new_y * outer_width
            new_pixel = outer_mask[pixel_loc]
            inner_mask.append(new_pixel)
    return inner_mask


def generate_sub_sub_headline(text):
    """
    Genera la cabecer para los subsubtitulos formateados en ``.rst``

    :param str text: texto para el que generar la cabecera
    :return: cabecera para el texto
    :rtype: str

    .. code-block:: python

        >> generate_sub_sub_headline('Welcome')
        '***********'

    """
    return '*' * (len(text) + 6)


def distance(a, b):
    """Compute the distance between a and b.

    This is based on Damerau-Levenshtein distance, but we modify the cost
    of some edits, like insertion or removal of '_', or capitalisation changes.

    """
    d = {}
    la = len(a)
    lb = len(b)
    for i in range(la + 1):
        d[i, 0] = i
    for j in range(1, lb + 1):
        d[0, j] = j
    for i, ca in enumerate(a, start=1):
        for j, cb in enumerate(b, start=1):
            cost = int(ca != cb)
            if ca.lower() == cb.lower():
                subst_cost = 0
            else:
                subst_cost = 1.25 * cost
            insertion_cost = 0.7 if cb == '_' else 1.0
            deletion_cost = 0.7 if ca == '_' else 1.0
            d[i, j] = min(d[i - 1, j] + deletion_cost, d[i, j - 1] +
                insertion_cost, d[i - 1, j - 1] + subst_cost)
            if i > 1 and j > 1 and ca == b[j - 2] and a[i - 2] == cb:
                d[i, j] = min(d[i, j], d[i - 2, j - 2] + cost)
    return d[la, lb]


def hub_listener_stacks(state=False):
    """Toggles whether or not the hub records the stack when clients register
    listeners on file descriptors.  This can be useful when trying to figure
    out what the hub is up to at any given moment.  To inspect the stacks
    of the current listeners, call :func:`format_hub_listeners` at critical
    junctures in the application logic.
    """
    from eventlet import hubs
    hubs.get_hub().set_debug_listeners(state)


def check_ext(f_name, ext):
    """Check the extension for a file name, and add if missing.

    Parameters
    ----------
    f_name : str
        The name of the file.
    ext : str
        The extension to check and add.

    Returns
    -------
    str
        File name with the extenion added.
    """
    return f_name + ext if not f_name.endswith(ext) else f_name


@staticmethod
def get_shebang_fix() ->str:
    """FIX: the shebang in python files."""
    return '#!/usr/bin/env python'


@classmethod
def get(cls, client, server_name):
    """Get a cluster member by name."""
    response = client.api.cluster.members[server_name].get()
    return cls(client, **response.json()['metadata'])


def status_codes_by_date_chart():
    """Chart for status codes by date."""
    return {'chart': {'type': 'area', 'zoomType': 'x'}, 'title': {'text':
        None}, 'xAxis': {'type': 'datetime'}, 'yAxis': {'title': {'text':
        None}}, 'legend': {'enabled': True}, 'tooltip': {'shared': True},
        'plotOptions': {'area': {'lineWidth': 1, 'marker': {'lineWidth': 1}}}}


def on() ->None:
    """Turns the radio on. This needs to be explicitly called since the radio
    draws power and takes up memory that you may otherwise need.
    """


def isunauthenticated(f):
    """Decorator to mark authentication-non-required.

    Checks to see if the function is marked as not requiring authentication
    with the @unauthenticated decorator. Returns True if decorator is
    set to True, False otherwise.
    """
    return getattr(f, 'unauthenticated', False)


def get_user_from_context(context):
    """
    Get the user instance from the template context, if possible.

    If the context does not contain a `request` or `user` attribute,
    `None` is returned.
    """
    try:
        return context['user']
    except KeyError:
        pass
    try:
        request = context['request']
        return request.user
    except (KeyError, AttributeError):
        pass
    return None


@classmethod
def subsystems(cls):
    """Returns all subsystem types used by all tasks, in no particular order.

        :API: public
        """
    ret = set()
    for goal in cls.all():
        ret.update(goal.subsystems())
    return ret


def p_arith_expr_1(p):
    """arith_expr : term"""
    p[0] = p[1]


def PRIN(val):
    """PartialRetractionIn"""
    return val


def add_arguments(parser):
    """Allows notifiers to add additional command line arguments.

        :type parser: :class:`argparse.ArgumentParser`
        """


def keying_set_add():
    """Add a new (empty) Keying Set to the active Scene

    """
    pass


@staticmethod
def cancel(data, *args, **kwargs):
    """
        returns True if it was cancelled successfully, else False
        :param data: requests.response() obj
        :param args:
        :param kwargs:
        :return: bool
        """
    return data


def get_facts(device):
    """
    Gathers facts from a <file-show/> RPC on the '/etc/hosts.junos' file.
    """
    iri_hostname = None
    iri_ip = None
    rsp = device.rpc.file_show(filename='/etc/hosts.junos', normalize=False)
    if rsp is not None:
        hosts_file_content = rsp.findtext('.', default='')
        if hosts_file_content is not None:
            for line in hosts_file_content.splitlines():
                line, _, _ = line.partition('#')
                components = line.split(None)
                if len(components) > 1:
                    ip = components[0]
                    hosts = components[1:]
                    if iri_hostname is None:
                        iri_hostname = {}
                    if iri_ip is None:
                        iri_ip = {}
                    if ip in iri_hostname:
                        iri_hostname[ip] += hosts
                    else:
                        iri_hostname[ip] = hosts
                    for host in hosts:
                        if host in iri_ip:
                            iri_ip[host].append(ip)
                        else:
                            iri_ip[host] = [ip]
                    for host in hosts:
                        if '%d' in host:
                            octets = ip.split('.', 3)
                            for count in range(255):
                                t_ip = octets[0] + '.' + octets[1] + '.' + str(
                                    count) + '.' + octets[3]
                                t_host = host.replace('%d', str(count))
                                if t_ip in iri_hostname:
                                    iri_hostname[t_ip].append(t_host)
                                else:
                                    iri_hostname[t_ip] = [t_host]
                                if t_host in iri_ip:
                                    iri_ip[t_host].append(t_ip)
                                else:
                                    iri_ip[t_host] = [t_ip]
    return {'_iri_hostname': iri_hostname, '_iri_ip': iri_ip}


def run_module(module, serialize_queue, batch):
    """
    Helper function which simply runs a PeTaL module on data from batch and puts the result in serialize_queue.

    :param module: An instantiated PeTaL module, i.e. `WikipediaArticleModule()`
    :param serialize_queue: The stream of data to be written to disk, and later processed
    :param batch: The data on which this module depends
    """
    module.log.log('Initiated ', module.name, ' run_module() in scheduler')
    if batch is None:
        module.log.log('Backbone run ', module.name)
        gen = module.process()
    else:
        module.log.log('Batched returning run with ', module.name)
        gen = module.process_batch(batch)
    if gen is not None:
        for transaction in gen:
            module.log.log(transaction)
            serialize_queue.put(transaction)
    module.log.log('Finished queueing transactions from ', module.name)


def isint(str):
    """ Is the given string an integer

    >>> isint(str('1234'))
    1
    >>> isint(str('11a'))
    0
    """
    ok = 1
    if not str:
        return 0
    try:
        int(str)
    except ValueError:
        ok = 0
    except TypeError:
        ok = 0
    return ok


def reset_cluster_parameter_group(ParameterGroupName=None,
    ResetAllParameters=None, Parameters=None):
    """
    Sets one or more parameters of the specified parameter group to their default values and sets the source values of the parameters to "engine-default". To reset the entire parameter group specify the ResetAllParameters parameter. For parameter changes to take effect you must reboot any associated clusters.
    See also: AWS API Documentation

    :example: response = client.reset_cluster_parameter_group(
        ParameterGroupName='string',
        ResetAllParameters=True|False,
        Parameters=[
            {
                'ParameterName': 'string',
                'ParameterValue': 'string',
                'Description': 'string',
                'Source': 'string',
                'DataType': 'string',
                'AllowedValues': 'string',
                'ApplyType': 'static'|'dynamic',
                'IsModifiable': True|False,
                'MinimumEngineVersion': 'string'
            },
        ]
    )

    :type ParameterGroupName: string
    :param ParameterGroupName: [REQUIRED]
            The name of the cluster parameter group to be reset.

    :type ResetAllParameters: boolean
    :param ResetAllParameters: If true , all parameters in the specified parameter group will be reset to their default values.
            Default: true

    :type Parameters: list
    :param Parameters: An array of names of parameters to be reset. If ResetAllParameters option is not used, then at least one parameter name must be supplied.
            Constraints: A maximum of 20 parameters can be reset in a single request.
            (dict) --Describes a parameter in a cluster parameter group.
            ParameterName (string) --The name of the parameter.
            ParameterValue (string) --The value of the parameter.
            Description (string) --A description of the parameter.
            Source (string) --The source of the parameter value, such as 'engine-default' or 'user'.
            DataType (string) --The data type of the parameter.
            AllowedValues (string) --The valid range of values for the parameter.
            ApplyType (string) --Specifies how to apply the WLM configuration parameter. Some properties can be applied dynamically, while other properties require that any associated clusters be rebooted for the configuration changes to be applied. For more information about parameters and parameter groups, go to Amazon Redshift Parameter Groups in the Amazon Redshift Cluster Management Guide .
            IsModifiable (boolean) --If true , the parameter can be modified. Some parameters have security or operational implications that prevent them from being changed.
            MinimumEngineVersion (string) --The earliest engine version to which the parameter can apply.

    :rtype: dict
    :return: {
        'ParameterGroupName': 'string',
        'ParameterGroupStatus': 'string'
    }

    """
    pass


def sortXY(X, Y):
    """returns the sorted (x, Y(x)) sorted on X"""
    D = {}
    for x, y in zip(X, Y):
        D[x] = y
    xsorted = sorted(D.keys())
    return xsorted, [D[x] for x in xsorted]


def describe_users(OrganizationId=None, UserIds=None, Query=None, Include=
    None, Order=None, Sort=None, Marker=None, Limit=None, Fields=None):
    """
    Describes the specified users. You can describe all users or filter the results (for example, by status or organization).
    By default, Amazon WorkDocs returns the first 24 active or pending users. If there are more results, the response includes a marker that you can use to request the next set of results.
    See also: AWS API Documentation

    :example: response = client.describe_users(
        OrganizationId='string',
        UserIds='string',
        Query='string',
        Include='ALL'|'ACTIVE_PENDING',
        Order='ASCENDING'|'DESCENDING',
        Sort='USER_NAME'|'FULL_NAME'|'STORAGE_LIMIT'|'USER_STATUS'|'STORAGE_USED',
        Marker='string',
        Limit=123,
        Fields='string'
    )

    :type OrganizationId: string
    :param OrganizationId: The ID of the organization.

    :type UserIds: string
    :param UserIds: The IDs of the users.

    :type Query: string
    :param Query: A query to filter users by user name.

    :type Include: string
    :param Include: The state of the users. Specify 'ALL' to include inactive users.

    :type Order: string
    :param Order: The order for the results.

    :type Sort: string
    :param Sort: The sorting criteria.

    :type Marker: string
    :param Marker: The marker for the next set of results. (You received this marker from a previous call.)

    :type Limit: integer
    :param Limit: The maximum number of items to return.

    :type Fields: string
    :param Fields: A comma-separated list of values. Specify 'STORAGE_METADATA' to include the user storage quota and utilization information.

    :rtype: dict
    :return: {
        'Users': [
            {
                'Id': 'string',
                'Username': 'string',
                'EmailAddress': 'string',
                'GivenName': 'string',
                'Surname': 'string',
                'OrganizationId': 'string',
                'RootFolderId': 'string',
                'RecycleBinFolderId': 'string',
                'Status': 'ACTIVE'|'INACTIVE'|'PENDING',
                'Type': 'USER'|'ADMIN',
                'CreatedTimestamp': datetime(2015, 1, 1),
                'ModifiedTimestamp': datetime(2015, 1, 1),
                'TimeZoneId': 'string',
                'Locale': 'en'|'fr'|'ko'|'de'|'es'|'ja'|'ru'|'zh_CN'|'zh_TW'|'pt_BR'|'default',
                'Storage': {
                    'StorageUtilizedInBytes': 123,
                    'StorageRule': {
                        'StorageAllocatedInBytes': 123,
                        'StorageType': 'UNLIMITED'|'QUOTA'
                    }
                }
            },
        ],
        'TotalNumberOfUsers': 123,
        'Marker': 'string'
    }

    """
    pass


@classmethod
def add(cls, **kwargs):
    """Add key=value pairs. Existing values wil be overwritten."""
    return cls(lambda data: {**data, **kwargs})


def swap(seq, pos1, pos2):
    """Return a new sequence with segments at position pos1 and pos2 swapped.

    pos1, pos2 are both of the form (start1, end1), (start2, end2)
    """
    (start1, end1), (start2, end2) = sorted([pos1, pos2])
    return seq[:start1] + seq[start2:end2] + seq[end1:start2] + seq[start1:end1
        ] + seq[end2:]


def reply(zelf, *args, **kwargs):
    """ send reply to origin. """
    if 'outer' in zelf:
        zelf.outer.write(str(args[0]) + '\n')
        zelf.outer.flush()
        return
    if 'channel' in zelf:
        zelf.say(zelf.channel, args[0])
    else:
        zelf.say(zelf.origin, args[0])


@classmethod
def object_type_name(cls):
    """
        Returns the complete type name with module as prefix.
        """
    return '%s.%s' % (cls.__module__, cls.__name__)


def _rehydrate_skeleton_class(skeleton_class, class_dict):
    """Put attributes from `class_dict` back on `skeleton_class`.

    See CloudPickler.save_dynamic_class for more info.
    """
    registry = None
    for attrname, attr in class_dict.items():
        if attrname == '_abc_impl':
            registry = attr
        else:
            setattr(skeleton_class, attrname, attr)
    if registry is not None:
        for subclass in registry:
            skeleton_class.register(subclass)
    return skeleton_class


@staticmethod
def get_user_command_id(command=None, user_id=None, command_id=None):
    """Returns commander_id, command_id based on user-supplied information.

        Parameters
        ----------
        command : Command
            User command; used as a default for ``user_id`` and
            ``command_id``.
        user_id : int
            If `None` then use ``command.user_id``.
        command_id : int
            If `None` then use ``command.command_id``.

        Returns
        -------
        user_id, command_id : `tuple`
            The commander ID and the command ID, parsed from the inputs. If
            they cannot be determined, returns zeros.

        """
    user_id = user_id or (command.commander_id if command else 0)
    command_id = command_id or (command.command_id if command else 0)
    return user_id, command_id


def RANGE(start, end, step=None):
    """
    Generates the sequence from the specified starting number by successively
    incrementing the starting number by the specified step value up to but not including the end point.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/range/
    for more details
    :param start: An integer (or valid expression) that specifies the start of the sequence.
    :param end: An integer (or valid expression) that specifies the exclusive upper limit of the sequence.
    :param step: An integer (or valid expression) that specifies the increment value.
    :return: Aggregation operator
    """
    return {'$range': [start, end, step]} if step is not None else {'$range':
        [start, end]}


def rank_recommender(phylo_dist: float, taxonomic_rank_pfit: list):
    """
    Determines the rank depth (for example Class == 2) a taxonomic lineage should be truncated to
     based on which rank distance range (in taxonomic_rank_intervals) phylo_dist falls into

    :param phylo_dist: Float representing the branch distance from the nearest node
    :param taxonomic_rank_pfit: Dictionary with rank keys (e.g. Class) and distance ranges (min, max) as values
    :return: int
    """
    if not taxonomic_rank_pfit:
        return 7
    slope, intercept = taxonomic_rank_pfit
    depth = int(round(phylo_dist * slope + intercept))
    return depth


def get_last_idx(iterable, func):
    """
    获取最后一个符合条件数据的数组索引
    :param iterable:
    :param func:
    :return:
    """
    count = len(iterable)
    for n in range(count - 1, -1, -1):
        if func(iterable[n]):
            return n
    return None


@classmethod
def load(cls, **kwargs):
    """Instantiate and load the cassette stored at the specified path."""
    new_cassette = cls(**kwargs)
    new_cassette._load()
    return new_cassette


def Mc_M_eta(M, eta):
    """
    Computes the chirp mass (Mc) from the total mass and
    symmetric-mass-ratio
    input: M, eta
    output: Mc
    """
    return M * eta ** (3.0 / 5.0)


def replace_line_magic(source, magic, template='{line}'):
    """
    Given a cell's source, replace line magics using a formatting
    template, where {line} is the string that follows the magic.
    """
    filtered = []
    for line in source.splitlines():
        if line.strip().startswith(magic):
            substitution = template.format(line=line.replace(magic, ''))
            filtered.append(substitution)
        else:
            filtered.append(line)
    return '\n'.join(filtered)


def thermal_time_constant_at_rated_load(C, P, dTOr):
    """ Returns the average oil time constant in minutes (for rated load)
    As per IEEE C57.91-2011
    C = Thermal capacity of oil
    P = Supplied losses (in W) at the load considered
    OilRise = The average oil temperature rise above ambient temperature
    in K at the load considered
    """
    tau = C * dTOr * 60 / P
    return tau


def is_user_context(context):
    """Indicate if the request context is a normal user."""
    if not context:
        return False
    if context.is_admin:
        return False
    if not context.user or not context.project:
        return False
    return True


def is_localized(value):
    """
    Determine if a given datetime.datetime is aware.
    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 value.utcoffset() is not None


def paste_tracks():
    """Paste tracks from clipboard

    """
    pass


def get_tols(method, tol):
    """
    quick function to set the tolerances as a dictionary depending on the method being used
    :param method: str: method to use
    :param tol: tolerance as a float
    :return:
    """
    if method in ['leastsq', 'least_squares']:
        tols = {'ftol': tol, 'xtol': tol}
    else:
        tols = {'ftol': tol}
    return tols


@staticmethod
def precision(y, y_pred):
    """compute precision"""
    TP = (y[y == 1] == y_pred[y == 1]).sum()
    FP = (y[y == 0] != y_pred[y == 0]).sum()
    if TP + FP == 0:
        return 0
    return TP / float(TP + FP)


def pruneScope(target_scope, our_scope):
    """pruneScope(list A, list B) -> list

Given two lists of strings (scoped names), return a copy of list A
with any prefix it shares with B removed.

  e.g. pruneScope(['A', 'B', 'C', 'D'], ['A', 'B', 'D']) -> ['C', 'D']"""
    if not our_scope:
        return target_scope
    tscope = target_scope[:]
    i = 0
    while len(tscope) > 0 and i < len(our_scope) and tscope[0] == our_scope[i]:
        del tscope[0]
        i = i + 1
    return tscope


def convert(x_s):
    """
    This function converts the raw hokuyo data into meters.

    :param x_s: scaled data
    :return: float64 -- distance in meters
    """
    scaling = 0.005
    offset = -100.0
    x = x_s * scaling + offset
    return x


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

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


def license_info() ->dict:
    """
    Return feature license info, similar to version.license_info().
    """
    return {}


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


def goodness_of_fit(lm):
    """
    Measures goodness of fit by first checking if the distribution of the residuals are normal using Shapiro Wilk test.
    After normal distribution is proven, checks heteroskedacity by using Goldfield Quandt test.
    In some cases residuals variance increases with increasing input (heteroskedacity)
    This method checks if the variance is equal for all residuals afterwards.

    Parameters:
    regressor: output of the regression classifier of statsmodels

    Output:
    displays results

    """
    import statsmodels.stats.diagnostic as smsdia
    from scipy.stats import shapiro
    stat, p = shapiro(lm.resid)
    print('Statistics = %.3f\n\nP-Value = %.3f\n' % (stat, p))
    alpha = 0.05
    if p > alpha:
        print('Distribution is Gaussian')
        test = smsdia.het_goldfeldquandt(lm.resid, lm.model.exog)
        print('F Statistics = %.3f\n\nP-Value = %.3f\n' % (test[0], test[1]))
        alpha = 0.05
        if test[1] > alpha:
            print('Regression is homoscedastic')
        else:
            print('Regression is heteroskedastic')
    else:
        print('Sample does not look Gaussian (reject H0)')


def moveToCompletedForNoWQJobs(reqmgrSvc, wfStatusDict, logger):
    """
    Handle the case when request is aborted/rejected before elements are created in GQ
    """
    statusTransition = {'aborted': ['aborted-completed']}
    for status, nextStatusList in statusTransition.items():
        requests = reqmgrSvc.getRequestByStatus([status], detail=False)
        count = 0
        for wf in requests:
            if wf not in wfStatusDict:
                for nextStatus in nextStatusList:
                    reqmgrSvc.updateRequestStatus(wf, nextStatus)
                    count += 1
        logger.info('Total aborted-completed: %d', count)
    return


def divide(n, iterable):
    """Divide the elements from *iterable* into *n* parts, maintaining
    order.

        >>> group_1, group_2 = divide(2, [1, 2, 3, 4, 5, 6])
        >>> list(group_1)
        [1, 2, 3]
        >>> list(group_2)
        [4, 5, 6]

    If the length of *iterable* is not evenly divisible by *n*, then the
    length of the returned iterables will not be identical:

        >>> children = divide(3, [1, 2, 3, 4, 5, 6, 7])
        >>> [list(c) for c in children]
        [[1, 2, 3], [4, 5], [6, 7]]

    If the length of the iterable is smaller than n, then the last returned
    iterables will be empty:

        >>> children = divide(5, [1, 2, 3])
        >>> [list(c) for c in children]
        [[1], [2], [3], [], []]

    This function will exhaust the iterable before returning and may require
    significant storage. If order is not important, see :func:`distribute`,
    which does not first pull the iterable into memory.

    """
    if n < 1:
        raise ValueError('n must be at least 1')
    try:
        iterable[:0]
    except TypeError:
        seq = tuple(iterable)
    else:
        seq = iterable
    q, r = divmod(len(seq), n)
    ret = []
    stop = 0
    for i in range(1, n + 1):
        start = stop
        stop += q + 1 if i <= r else q
        ret.append(iter(seq[start:stop]))
    return ret


def olecf_header_pad_size(node=None, parent=None, attr_index=None, rawdata=
    None, new_value=None, **kwargs):
    """Size getter for the getting the byte size of the header padding."""
    if new_value is None:
        if 'sector_shift' in kwargs:
            return max(0, (1 << kwargs['sector_shift']) - 512)
        try:
            return max(0, (1 << parent.header.sector_shift) - 512)
        except AttributeError:
            return 0


def new():
    """Add a new material

    """
    pass


@classmethod
def tool_jar_entry_from_products(cls, products, key, scope):
    """Get a ClasspathEntry for the jar for the tool previously registered under key in the
        given scope.

        :param products: The products of the current pants run.
        :type products: :class:`pants.goal.products.Products`
        :param string key: The key the tool configuration was registered under.
        :param string scope: The scope the tool configuration was registered under.
        :returns: A single jar path.
        :rtype: string
        :raises: `JvmToolMixin.InvalidToolClasspath` when the tool classpath is not composed of exactly
                 one jar.
        """
    classpath = cls.tool_classpath_entries_from_products(products, key, scope)
    if len(classpath) != 1:
        params = dict(tool=key, scope=scope, count=len(classpath),
            classpath='\n\t'.join(classpath))
        raise cls.InvalidToolClasspath(
            """Expected tool {tool} in scope {scope} to resolve to one jar, instead found {count}:
	{classpath}"""
            .format(**params))
    return classpath[0]


def p_variable(p):
    """variable : '@' '@' STRING"""
    p[0] = p[3]


def default_motion_cor_2_v1_0_5():
    """
    Content of MotionCor2 version 1.0.5.

    Arguments:
    None

    Return:
    Content items as list
    """
    items = [['WIDGETS MAIN', '5', int, '', 'PLAIN', '', ''], [
        'WIDGETS ADVANCED', '5', int, '', 'PLAIN', '', ''], ['WIDGETS RARE',
        '5', int, '', 'PLAIN', '', ''], ['-FmDose', '0', float, '', 'PLAIN',
        'Main',
        'Frame dose in e/A^2. If not specified, dose weighting will be skipped.'
        ], ['-PixSize', '0', float, '', 'PLAIN', 'Main',
        'Pixel size in A of input stack in angstrom. If not specified, dose weighting will be skipped.'
        ], ['-kV', '300', float, '', 'PLAIN', 'Main',
        'High tension in kV needed for dose weighting.  Default is 300.'],
        ['-Patch', '0 0 0', [int, int, int], '', 'PLAIN', 'Main',
        '1. It follows by  number of patches in x and y dimensions, and overlapping in percentage of adjacent patches.  2. The default values are 0 0 0, meaning only full-frame based alignment is performed.'
        ], ['-Bft', '100', float, '', 'PLAIN', 'Main',
        'B-Factor for alignment, default 100.'], ['-Throw', '0', int, '',
        'PLAIN', 'Main', 'Throw initial number of frames, default is 0'], [
        '-Trunc', '0', int, '', 'PLAIN', 'Main',
        'Truncate last number of frames, default is 0'], ['-Gain', '', str,
        '', 'FILE', 'Main',
        'MRC file that stores the gain reference. If not specified, MRC extended header will be visited to look for gain reference.'
        ], ['-RotGain', '0', int, '', 'PLAIN', 'Main',
        'Rotate gain reference counter-clockwise.  0 - no rotation, default, 1 - rotate 90 degree, 2 - rotate 180 degree, 3 - rotate 270 degree.'
        ], ['-FlipGain', '0', int, '', 'PLAIN', 'Main',
        'Flip gain reference after gain rotation.  0 - no flipping, default, 1 - flip upside down, 2 - flip left right.'
        ], ['-MaskCent', '0 0', [float, float], '', 'PLAIN', 'Advanced',
        'Center of subarea that will be used for alignement, default 0 0 corresponding to the frame center.'
        ], ['-MaskSize', '1 1', [float, float], '', 'PLAIN', 'Advanced',
        'The size of subarea that will be used for alignment, default 1.0 1.0 corresponding full size.'
        ], ['-Iter', '7', int, '', 'PLAIN', 'Advanced',
        'Maximum iterations for iterative alignment, default 5 iterations.'
        ], ['-Tol', '0.5', float, '', 'PLAIN', 'Advanced',
        'Tolerance for iterative alignment, default 0.5 pixel.'], [
        '-PhaseOnly', '0', int, '', 'PLAIN', 'Advanced',
        'Only phase is used in cross correlation.  default is 0, i.e., false.'
        ], ['-StackZ', '0', int, '', 'PLAIN', 'Advanced',
        'Number of frames per stack. If not specified, it will be loaded from MRC header.'
        ], ['-FtBin', '1', float, '', 'PLAIN', 'Advanced',
        'Binning performed in Fourier space, default 1.0.'], ['-InitDose',
        '0', float, '', 'PLAIN', 'Advanced',
        'Initial dose received before stack is acquired'], ['-Group', '1',
        int, '', 'PLAIN', 'Advanced',
        'Group every specified number of frames by adding them together. The alignment is then performed on the summed frames. By default, no grouping is performed.'
        ], ['-FmRef', '-1', int, '', 'PLAIN', 'Advanced',
        'Specify which frame to be the reference to which all other frames are aligned. By default (-1) the the central frame is chosen. The central frame is at N/2 based upon zero indexing where N is the number of frames that will be summed, i.e., not including the frames thrown away.'
        ], ['-DefectFile', '', str, '', 'FILE', 'Advanced',
        '1. Defect file that stores entries of defects on camera.  2. Each entry corresponds to a rectangular region in image.  The pixels in such a region are replaced by neighboring good pixel values.  3. Each entry contains 4 integers x, y, w, h representing the x, y coordinates, width, and heights, respectively.'
        ], ['-Dark', '', str, '', 'FILE', 'Advanced',
        '1. MRC file that stores the dark reference. If not specified, dark subtraction will be skipped.  2. If -RotGain and/or -FlipGain is specified, the dark reference will also be rotated and/or flipped.'
        ], ['-Tilt', '0 0', [float, float], '', 'PLAIN', 'Advanced',
        'Specify the starting angle and the step angle of tilt series. They are required for dose weighting. If not given, dose weighting will be disabled.'
        ], ['-Mag', '1 1 0', [float, float, float], '', 'PLAIN', 'Advanced',
        '1. Correct anisotropic magnification by stretching image along the major axis, the axis where the lower magificantion is detected.  2. Three inputs are needed including magnifications along major and minor axes and the angle of the major axis relative to the image x-axis in degree.  3. By default no correction is performed.'
        ], ['-InFmMotion', '0', int, '', 'PLAIN', 'Advanced',
        '1. 1 - Account for in-frame motion.  0 - Do not account for in-frame motion.'
        ], ['-Crop', '0 0', [int, int], '', 'PLAIN', 'Advanced',
        '1. Crop the loaded frames to the given size.  2. By default the original size is loaded.'
        ], ['-Gpu', '0', [int] * 99, '', 'PLAIN', 'Advanced',
        ' GPU IDs. Default 0.  For multiple GPUs, separate IDs by space.  For example, -Gpu 0 1 2 3 specifies 4 GPUs.'
        ], ['Split Gpu?', ['True', 'False'], bool, '', 'COMBO', 'Advanced',
        'NOT A CRYOLO OPTION. Split the gpu values specified in --Gpu to be able to run mutliple crYOLO jobs in parallel.'
        ], ['dose cutoff', '4', float, '', 'PLAIN', 'Advanced',
        'NOT A MOTIONCOR OPTION. Used to create the Relion3 bayesian polishing files.'
        ]]
    return items


@staticmethod
def _parse_candidate(candidate):
    """Parse filter candidates so that you can use None, True, False."""
    val = candidate
    if candidate is None:
        val = 'null'
    elif candidate is True:
        val = '1'
    elif candidate is False:
        val = '0'
    return val


def setDeprecationLevel(warning=1, exception=None):
    """
    Set the deprecation level for SQLObject.  Low levels are more
    actively being deprecated.  Any warning at a level at or below
    ``warning`` will give a warning.  Any warning at a level at or
    below ``exception`` will give an exception.  You can use a higher
    ``exception`` level for tests to help upgrade your code.  ``None``
    for either value means never warn or raise exceptions.

    The levels currently mean:

      1) Deprecated in current version.  Will be removed in next version.

      2) Planned to deprecate in next version, remove later.

      3) Planned to deprecate sometime, remove sometime much later.

    As the SQLObject versions progress, the deprecation level of
    specific features will go down, indicating the advancing nature of
    the feature's doom.  We'll try to keep features at 1 for a major
    revision.

    As time continues there may be a level 0, which will give a useful
    error message (better than ``AttributeError``) but where the
    feature has been fully removed.
    """
    global warnings_level, exception_level
    warnings_level = warning
    exception_level = exception


def split():
    """Split off selected bones from connected unselected bones

    """
    pass


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


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


@staticmethod
def get_cost():
    """Return cost of stage."""
    raise NotImplementedError


def trace_nuts(csv, extras='', skip=0, n_col=4):
    """Trace plots of NUTS state, along with other model parameters.
    """
    from pylab import subplot, plot, gca, title, grid, xticks
    if isinstance(csv, dict):
        csv = [csv]
    if isinstance(extras, str):
        extras = extras.split()
    n_nuts_params = 7
    n_subplots = len(extras) + n_nuts_params
    n_row = n_subplots // n_col + 1
    for csvi in csv:
        i = 1
        for key in csvi.keys():
            if key.endswith('__') or key in extras:
                subplot(n_row, n_col, i)
                plot(csvi[key][skip:], alpha=0.5)
                if key in ('stepsize__',):
                    gca().set_yscale('log')
                title(key)
                grid(1)
                if i < n_subplots - n_col:
                    xticks(xticks()[0], [])
                i += 1


def cov(input):
    """Returns a covariance matrix for the given input matrix."""
    mu = input.mean(dim=0)
    normalized = input - mu
    x = normalized.t().mm(normalized)
    x.div_(input.shape[0])
    return x


@staticmethod
def conj(x, *args, **kwargs):
    """WARNING: IDENTITY FUNCTION (does nothing)

            This backend currently does not support complex tensors
        """
    return x


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

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

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


def correct_gear_box_torque_in(gear_box_torque_out, gear_box_torque_in,
    gear, gear_box_ratios):
    """
    Corrects the torque when the gear box ratio is equal to 1.

    :param gear_box_torque_out:
        Torque gear_box [N*m].
    :type gear_box_torque_out: float

    :param gear_box_torque_in:
        Torque required [N*m].
    :type gear_box_torque_in: float

    :param gear:
        Gear [-].
    :type gear: int

    :param gear_box_ratios:
        Gear box ratios [-].
    :type gear_box_ratios: dict[int | float]

    :return:
        Corrected torque required [N*m].
    :rtype: float
    """
    gbr = gear_box_ratios
    if gbr is None or gear is None:
        return gear_box_torque_in
    return gear_box_torque_out if gbr.get(gear, 0) == 1 else gear_box_torque_in


def is_tool(name):
    """Check whether `name` is on PATH and marked as executable."""
    from shutil import which
    return which(name) is not None


@staticmethod
def p_project_optional_list(p):
    """project_optional_list : project_optional
                                 | project_optional project_optional_list """
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def isclassmethod(arguments):
    """Return whether an argument list corresponds to a classmethod."""
    return len(arguments) > 0 and arguments[0].name == 'cls'


@classmethod
def dark_red(cls):
    """A factory method that returns a :class:`Colour` with a value of ``0x992d22``."""
    return cls(10038562)


def delete_analysis_scheme(DomainName=None, AnalysisSchemeName=None):
    """
    Deletes an analysis scheme. For more information, see Configuring Analysis Schemes in the Amazon CloudSearch Developer Guide .
    See also: AWS API Documentation

    :example: response = client.delete_analysis_scheme(
        DomainName='string',
        AnalysisSchemeName='string'
    )

    :type DomainName: string
    :param DomainName: [REQUIRED]
            A string that represents the name of a domain. Domain names are unique across the domains owned by an account within an AWS region. Domain names start with a letter or number and can contain the following characters: a-z (lowercase), 0-9, and - (hyphen).

    :type AnalysisSchemeName: string
    :param AnalysisSchemeName: [REQUIRED]
            The name of the analysis scheme you want to delete.

    :rtype: dict
    :return: {
        'AnalysisScheme': {
            'Options': {
                'AnalysisSchemeName': 'string',
                'AnalysisSchemeLanguage': 'ar'|'bg'|'ca'|'cs'|'da'|'de'|'el'|'en'|'es'|'eu'|'fa'|'fi'|'fr'|'ga'|'gl'|'he'|'hi'|'hu'|'hy'|'id'|'it'|'ja'|'ko'|'lv'|'mul'|'nl'|'no'|'pt'|'ro'|'ru'|'sv'|'th'|'tr'|'zh-Hans'|'zh-Hant',
                'AnalysisOptions': {
                    'Synonyms': 'string',
                    'Stopwords': 'string',
                    'StemmingDictionary': 'string',
                    'JapaneseTokenizationDictionary': 'string',
                    'AlgorithmicStemming': 'none'|'minimal'|'light'|'full'
                }
            },
            'Status': {
                'CreationDate': datetime(2015, 1, 1),
                'UpdateDate': datetime(2015, 1, 1),
                'UpdateVersion': 123,
                'State': 'RequiresIndexDocuments'|'Processing'|'Active'|'FailedToValidate',
                'PendingDeletion': True|False
            }
        }
    }

    :returns:
    RequiresIndexDocuments : the option's latest value will not be deployed until  IndexDocuments has been called and indexing is complete.
    Processing : the option's latest value is in the process of being activated.
    Active : the option's latest value is completely deployed.
    FailedToValidate : the option value is not compatible with the domain's data and cannot be used to index the data. You must either modify the option value or update or remove the incompatible documents.

    """
    pass


def __contains__(relationship):
    """returns whether the relationship is in the index"""


@classmethod
def teardown_aio_support(cls):
    """
        HELP: maybe add a wait_aio_support_teardown method?
        """
    cls.aioqueue.close()
    cls.worker_task.cancel()
    cls.has_aio_support = False
    cls.aioqueue = None


def append_slash(url):
    """Make sure we append a slash at the end of the URL otherwise we
    have issues with urljoin Example:
    >>> urlparse.urljoin('http://www.example.com/api/v3', 'user/1/')
    'http://www.example.com/api/user/1/'
    """
    if url and not url.endswith('/'):
        url = '{0}/'.format(url)
    return url


@staticmethod
def get_urlvariables():
    """ Method returns url variables: /real_http_code/request_type/return_type

        :return: variables for url, string
        """
    return '/true/json/json'


@staticmethod
def system_uptime():
    """
        returns system uptime in seconds
        """
    from datetime import timedelta
    with open('/proc/uptime', 'r') as f:
        uptime_seconds = float(f.readline().split()[0])
        uptime_string = str(timedelta(seconds=uptime_seconds))
    return uptime_seconds


def load_dictionary(file_name=None):
    """ Return a set of uppercase words from file, splitting on \\n."""
    dict_name = file_name or 'dictionary.txt'
    dict_words = set()
    with open(dict_name) as fo:
        for word in fo.read().split('\n'):
            dict_words.add(word.upper())
    return dict_words


def isint(s):
    """
    Функция, которая возращает True, если  строка является целым числом, и False в ином случае.
    Parameters
    ----------
    s (str) : строка с целым числом.

    Returns
    -------
    (boolean) True, если  строка является целым числом, и False в ином случае.
    """
    if isinstance(s, str):
        try:
            s = int(s)
            return True
        except:
            return False
    else:
        return False


def Nu_McAdams(Re, Pr):
    """Calculates internal convection Nusselt number for turbulent vertical
    upward flow in a pipe under supercritical conditions according to [1]_.

    Found in [2]_ to fit the enhanced heat transfer regime with a MAD of 10.3%
    which was better than and of the other reviewed correlations.

    .. math::
        Nu_b = 0.0243Re_b^{0.8}Pr_b^{0.4}

    Parameters
    ----------
    Re : float
        Reynolds number with bulk fluid properties, [-]
    Pr : float
        Prandtl number with bulk fluid properties, [-]

    Returns
    -------
    Nu : float
        Nusselt number with bulk fluid properties, [-]

    Notes
    -----
    This has also been one of the forms of the Dittus-Boelter correlations.
    Claimed to fit data for high pressures and low heat fluxes.

    Examples
    --------
    >>> Nu_McAdams(1E5, 1.2)
    261.3838629346147

    References
    ----------
    .. [1] Mac Adams, William H. Heat Transmission. New York and London, 1942.
    .. [2] Chen, Weiwei, Xiande Fang, Yu Xu, and Xianghui Su. "An Assessment of
       Correlations of Forced Convection Heat Transfer to Water at
       Supercritical Pressure." Annals of Nuclear Energy 76 (February 2015):
       451-60. doi:10.1016/j.anucene.2014.10.027.
    """
    return 0.0243 * Re ** 0.8 * Pr ** 0.4


def phonenumbers(s):
    """Clean phonenumbers by removing all non-numbers (except +).

    Parameters
    ----------
    s: pandas.Series
        A Series to clean.

    Returns
    -------
    pandas.Series
        A Series with cleaned phonenumbers.

    """
    s = s.astype(object).str.replace('[^0-9+]+', '')
    return s


def delete_xss_match_set(XssMatchSetId=None, ChangeToken=None):
    """
    Permanently deletes an  XssMatchSet . You can't delete an XssMatchSet if it's still used in any Rules or if it still contains any  XssMatchTuple objects.
    If you just want to remove an XssMatchSet from a Rule , use  UpdateRule .
    To permanently delete an XssMatchSet from AWS WAF, perform the following steps:
    See also: AWS API Documentation

    Examples
    The following example deletes an XSS match set with the ID example1ds3t-46da-4fdb-b8d5-abc321j569j5.
    Expected Output:

    :example: response = client.delete_xss_match_set(
        XssMatchSetId='string',
        ChangeToken='string'
    )

    :type XssMatchSetId: string
    :param XssMatchSetId: [REQUIRED]
            The XssMatchSetId of the XssMatchSet that you want to delete. XssMatchSetId is returned by CreateXssMatchSet and by ListXssMatchSets .

    :type ChangeToken: string
    :param ChangeToken: [REQUIRED]
            The value returned by the most recent call to GetChangeToken .

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

    :returns:
    XssMatchSetId (string) -- [REQUIRED]
    The XssMatchSetId of the  XssMatchSet that you want to delete. XssMatchSetId is returned by  CreateXssMatchSet and by  ListXssMatchSets .

    ChangeToken (string) -- [REQUIRED]
    The value returned by the most recent call to  GetChangeToken .

    """
    pass


def _size_of_ndarray(ndarray_obj):
    """
    Return the size of a Numpy ndarray's internal storage.

    Doesn't yet handle views into other arrays.
    """
    return ndarray_obj.nbytes


@staticmethod
def _sparse_token(sparse):
    """
        Returns the numerical CDF value for sparseness.
        """
    sparses = {'no_sparse': 0, 'pad_sparse': 1, 'prev_sparse': 2}
    try:
        return sparses[sparse.lower()]
    except Exception:
        return 0


def join():
    """Join selected objects into active object

    """
    pass


def is_channel_valid(channel):
    """
    Verify if a channel string is valid.
    For now a valid channel is a channel in which:
    - It is not None
    - It is not an empty string

    Parameters
    ----------
    channel : str
        The channel value

    Returns
    -------
    valid : bool
        Returns True if the channel is valid, False otherwise.
    """
    return channel is not None and channel != ''


@classmethod
def put_unique(cls, item, **kwargs):
    """Put a single item into the table for this model, with a unique attribute constraint on the hash key

        :param dict item: The item to put into the table
        :param \\*\\*kwargs: All other kwargs are passed through to the put_unique method on the table
        """
    return cls.Table.put_unique(cls.Schema.dynamorm_validate(item), **kwargs)


def delete_bucket_lifecycle(Bucket=None):
    """
    Deletes the lifecycle configuration from the bucket.
    See also: AWS API Documentation

    :example: response = client.delete_bucket_lifecycle(
        Bucket='string'
    )

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

    """
    pass


def print_report(result_in):
    """Print time code, title, url and tags."""
    if result_in[0]:
        print('Time Codes: ' + ' '.join(result_in[0][:]))
    if result_in[1]:
        print('Titles: ' + ' '.join(result_in[1]))
    if result_in[2]:
        print('YouTube URL: ' + result_in[2])
    if result_in[3]:
        print('Tags: ' + ' '.join(result_in[3]))


def connectUNIXDatagram(address, protocol, maxPacketSize=8192, mode=438,
    bindAddress=None):
    """
        Connect a client protocol to a datagram UNIX socket.

        @param address: a path to a unix socket on the filesystem.

        @param protocol: a L{twisted.internet.protocol.ConnectedDatagramProtocol} instance

        @param maxPacketSize: maximum packet size to accept

        @param mode: The mode (B{not} umask) to set on the unix socket.  See
            platform specific documentation for information about how this
            might affect connection attempts.
        @type mode: C{int}

        @param bindAddress: address to bind to

        @return: An object which provides L{IConnector}.
        """


@staticmethod
def _resolve_param_duplicates(values, param_defn, _in):
    """ Resolve cases where query parameters are provided multiple times.
            The default behavior is to use the first-defined value.
            For example, if the query string is '?a=1,2,3&a=4,5,6' the value of
            `a` would be "1,2,3".
            However, if 'collectionFormat' is 'multi' then the duplicate values
            are concatenated together and `a` would be "1,2,3,4,5,6".
        """
    if param_defn.get('collectionFormat') == 'multi':
        return ','.join(values)
    return values[0]


def get_parameter_names(parameters):
    """Convert the parameter string supplied by the user into a list of parameter names.

    :param list parameters: The comma separated string of parameter names
    """
    return parameters.replace(' ', '').split(',')


def limit(vmin, vmax, npeaks):
    """
    Fixed limits, vmin to vmax for all peaks.
    """
    return [(vmin, vmax)] * npeaks


@classmethod
def _test_scheme_nosalt(cls, scheme):
    """
            Test if the scheme need no salt or raise BadScheme

            :param bytes scheme: A scheme
            :raises BadScheme: if ``scheme` require a salt
        """
    if scheme not in cls.schemes_nosalt:
        cls._raise_bad_scheme(scheme, cls.schemes_nosalt,
            'The scheme %r is only valid with a salt. Valide schemes without salt are %s.'
            )


@classmethod
def get_roles(cls, login):
    """Return the roles of an user

        :param login: str, login attribute of the user
        :rtype: list of str (name of the roles)
        """
    roles = [login]
    user = cls.query().filter(cls.login == login).one_or_none()
    if user:
        for role in user.roles:
            roles.extend(role.roles_name)
    return list(set(roles))