def sorted_brle_gather_1d(brle_data, ordered_indices):
    """
    Gather brle_data at ordered_indices.

    This is equivalent to `brle_to_dense(brle_data)[ordered_indices]` but
    avoids the decoding.

    Parameters
    ----------
    raw_data: iterable of run-length-encoded data.
    ordered_indices: iterable of ints in ascending order.

    Returns
    ----------
    `raw_data` iterable of values at the dense indices, same length as
    ordered indices.
    """
    data_iter = iter(brle_data)
    index_iter = iter(ordered_indices)
    index = next(index_iter)
    start = 0
    value = True
    while True:
        while start <= index:
            try:
                value = not value
                start += next(data_iter)
            except StopIteration:
                raise IndexError(
                    'Index %d out of range of raw_values length %d' % (
                    index, start))
        try:
            while index < start:
                yield value
                index = next(index_iter)
        except StopIteration:
            break


@staticmethod
def _read_c_string(fp, ptr):
    """Read a NULL-terminated C string from fp at ptr"""
    fp.seek(ptr)
    chunk = fp.read(50)
    chunks = [chunk]
    while chunk.find(b'\x00') == -1:
        chunk = fp.read(50)
        if not chunk or len(chunks) > 10:
            break
        chunks.append(chunk)
    data = b''.join(chunks)
    return data[:data.find(b'\x00')]


def _bits_to_float(bits, lower=-90.0, middle=0.0, upper=90.0):
    """Convert GeoHash bits to a float."""
    for i in bits:
        if i:
            lower = middle
        else:
            upper = middle
        middle = (upper + lower) / 2
    return middle


def apply_unaryop(unaop, inp, out):
    """Apply unary operator *unaop* to *inp* and store to *out*.

    """
    args = inp.cffi_view, out.cffi_view
    unaop(*args)


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

    :param type name: description

    :returns: type name: description

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


def getRates(order):
    """
        given an order object, return a set of shipping method rate objects
        for available shipping options, on error raises an exception.
        """


def isatty(s):
    """Workaround for outputstreams that don't implement isatty
     (specifically vtkPythonStdStreamCaptureHelper)
     """
    try:
        return s.isatty
    except AttributeError:
        return False


@classmethod
def _meta_get(cls, key, default=None):
    """Get value corresponding to key in meta data."""
    cls._meta_is_inited()
    return cls._meta.get(key, default)


def norm_ws(s):
    """Normalize whitespace in the given string."""
    return ' '.join(s.strip().split())


@classmethod
def add_tagging(cls, task_instance):
    """
        Blank function for tagging.
        """


def _translate_int(exp, length):
    """ Given an integer index, return a 3-tuple
        (start, count, step)
        for hyperslab selection
    """
    if exp < 0:
        exp = length + exp
    if not 0 <= exp < length:
        raise ValueError('Index (%s) out of range (0-%s)' % (exp, length - 1))
    return exp, 1, 1


def clearstatus(repo):
    """Remove the status files"""
    tr = repo.currenttransaction()
    if tr:
        tr.removefilegenerator(b'rebasestate')
    repo.vfs.unlinkpath(b'rebasestate', ignoremissing=True)


@staticmethod
def globals_dict():
    """
        Return a dictionary that will be added to the globals dictionary
        when executing calculations.
        """
    return {}


def drop(n, coll):
    """
    Returns a generator of all but the first ``n`` items in ``coll``.
    """
    if coll is None:
        return
    for i, e in enumerate(coll):
        if i >= n:
            yield e


def get_full_name(element):
    """Returns a tuple with (namespace, local_name) for the given element."""
    return element.namespaceURI, element.localName


def _cache_descriptor(descriptor, descritor_cache):
    """De-reference and cache a RunStop document

    The de-referenced Document is cached against the
    ObjectId and the uid -> ObjectID mapping is stored.

    Parameters
    ----------
    descriptor : dict
        raw pymongo dictionary. This is expected to have
        an entry `_id` with the ObjectId used by mongo.

    Returns
    -------
    descriptor : dict
        Document instance for this EventDescriptor document.
        The ObjectId has been stripped.
    """
    descriptor = dict(descriptor)
    oid = descriptor.pop('_id', None)
    try:
        descriptor['run_start']
    except KeyError:
        descriptor['run_start'] = descriptor.pop('run_start_id')
    descritor_cache[descriptor['uid']] = descriptor
    if oid is not None:
        descritor_cache[oid] = descriptor
    return descriptor


@classmethod
def fromfile(cls, fh, memmap=True, valid=True, verify=True):
    """Read a frame from a filehandle, possible mapping the payload.

        Parameters
        ----------
        fh : filehandle
            To read header from.
        memmap : bool, optional
            If `True` (default), use `~numpy.memmap` to map the payload.
            If `False`, just read it from disk.
        valid : bool, optional
            Whether the data are valid (default: `True`). Note that this cannot
            be inferred from the header or payload itself.  If `False`, any
            data read will be set to ``cls.fill_value``.
        verify : bool, optional
            Whether to do basic verification of integrity.  Default: `True`.
        """
    header = cls._header_class.fromfile(fh, verify=verify)
    payload = cls._payload_class.fromfile(fh, header=header, memmap=memmap)
    return cls(header, payload, valid=valid, verify=verify)


def _to_seconds(td):
    """Convert a timedelta to seconds"""
    return td.seconds + td.days * 24 * 60 * 60


def offload(filename):
    """Offloads a file.

    .. warning:: Currently not implemented.

    :param filename:

    :rtype: bytes|str

    :raises ValueError: If unable to offload.
    """


@staticmethod
def query(dbversion=None):
    """Returns query to fetch Rule instances from the catalogs"""
    return """
            SELECT nspname AS schema, relname AS table, rulename AS name,
                   split_part('select,update,insert,delete', ',',
                       ev_type::int - 48) AS event, is_instead AS instead,
                   pg_get_ruledef(r.oid) AS definition,
                   obj_description(r.oid, 'pg_rewrite') AS description, r.oid
            FROM pg_rewrite r JOIN pg_class c ON (ev_class = c.oid)
                 JOIN pg_namespace n ON (relnamespace = n.oid)
            WHERE relkind = 'r'
              AND (nspname != 'pg_catalog' AND nspname != 'information_schema')
            ORDER BY nspname, relname, rulename"""


def classify_dwell(last_trip, trip):
    """
    Count the time spent at known locations by tallying the intervals between labeled points.

    :param `py:class:Trip` last_trip: An itinerum-tripkit trip object for the trip immediately prior to the provided `trip`
    :param `py:class:Trip` trip:      An itinerum-tripkit trip object
    """
    end_location = None
    for p in last_trip.points[-5:]:
        if p.label:
            end_location = p.label
            break
    start_location = None
    for p in trip.points[:5]:
        if p.label:
            start_location = p.label
            break
    if end_location and end_location == start_location:
        return end_location


def out_condition_edges(graph, branch_node):
    """Follow the condition edges leading out from a branch node, returning a tuple
    (then_edge, else_edge) where each edge is a tuple (node, dest_node, edge_data).
    """
    then_edge = else_edge = None
    for edge in graph.out_edges(branch_node, data=True):
        data = edge[2]
        if data['condition'] == True:
            then_edge = edge
        elif data['condition'] == False:
            else_edge = edge
    assert then_edge and else_edge
    return then_edge, else_edge


def _merge(arr, temp, left, mid, right):
    """
    Merges two sorted arrays and calculates the inversion count.

    Helper function for calculating inversions. This method is
    for internal use only.
    """
    i = k = left
    j = mid
    inv_count = 0
    while i < mid and j <= right:
        if arr[i] < arr[j]:
            temp[k] = arr[i]
            k += 1
            i += 1
        else:
            temp[k] = arr[j]
            k += 1
            j += 1
            inv_count += mid - i
    while i < mid:
        temp[k] = arr[i]
        k += 1
        i += 1
    if j <= right:
        k += right - j + 1
        j += right - j + 1
        arr[left:k + 1] = temp[left:k + 1]
    else:
        arr[left:right + 1] = temp[left:right + 1]
    return inv_count


def print_header(npart, niter, tol_type, tlevels, priors):
    """print header to screen
        Input:
        npart - number of particles
        niter - number of iterations
        tol_type - decreasing tolerance level setting
        tlevels - max/min threshold levels
        priors - priors for parameters
        """
    print('\t \t')
    print(
        '\t ########################     astroABC     ########################\t'
        )
    print('\t \t')
    print('\t Npart=%d \t numt=%d \t tol=[%.4f,%.4f] %s' % (npart, niter,
        tlevels[0], tlevels[1], tol_type))
    print('\t Priors=', priors)


def compute_generator_steps(idx, sampling_step, batch_size):
    """Computes the number of steps for Keras.models.fit_generator.

    :param idx: int tuple - (start_row, end_row) : start and end rows; one of train_val_split() results
    :param sampling_step: int - step of the sliding time window.
    :param batch_size: int - batch size for mini-batch gradient descent.
    :return: int - number of samples yielded by the generator in one epoch
    """
    nb_indices = idx[1] - idx[0]
    nb_indiv_samples = nb_indices // sampling_step + min(nb_indices %
        sampling_step, 1)
    nb_batches = nb_indiv_samples // batch_size + min(nb_indiv_samples %
        batch_size, 1)
    return nb_batches


def is_dynamic_uri(uri):
    """ Determine whether `uri` is a dynamic uri or not.

    Assumes a dynamic uri is one that ends with '}' which is a Pyramid
    way to define dynamic parts in uri.

    :param uri: URI as a string.
    """
    return uri.strip('/').endswith('}')


def get_size_of_best_version():
    """Find the size of the version that would be returned by
        get_best_readable_version().

        I return a Deferred that fires with an integer. If no version
        is recoverable, the Deferred will errback with an
        UnrecoverableFileError.
        """


def spec_to_group_name(spec):
    """Return a name that can be used as a NuSMV identifier, based on spec."""
    return 'spec' + str(spec).replace(' ', '_').replace(',', '_').replace('&',
        'and').replace('|', 'or').replace('<', '').replace('>', '').replace('~'
        , '').replace("'", '').replace('=', '').replace('(', '').replace(')',
        '').replace('[', '').replace(']', '').replace('!', '')


def delete_elements(bdf_model, element_types_to_save=None):
    """early version of way to delete specific element cards"""
    eids_to_delete = set()
    if element_types_to_save:
        for eid, element in bdf_model.elements.items():
            etype = element.type
            if etype not in element_types_to_save:
                eids_to_delete.add(eid)
                bdf_model._type_to_id_map[etype].remove(eid)
    for eid in eids_to_delete:
        del bdf_model.elements[eid]


@classmethod
def isDist(kls, dist):
    """Is the text a valid distance measure?"""
    return kls.distre.match(dist) is not None


def searchResults(**searchterms):
    """Return iterator over results."""


def getMyIP():
    """ Get current IP address of the PC

    Returns
    ----------

    ip : string
        Current IP

    """
    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('8.8.8.8', 80))
    cw_ip = s.getsockname()[0]
    s.close()
    return str(cw_ip)


def check_attachment_permission(action, username, resource, perm):
    """Return the usual `True`/`False`/`None` security policy
           decision appropriate for the requested action on an
           attachment.

            :param action: one of ATTACHMENT_VIEW, ATTACHMENT_CREATE,
                                  ATTACHMENT_DELETE
            :param username: the user string
            :param resource: the `~trac.resource.Resource` for the
                             attachment. Note that when
                             ATTACHMENT_CREATE is checked, the
                             resource ``.id`` will be `None`.
            :param perm: the permission cache for that username and resource
            """


@classmethod
def from_date(cls, d):
    """Create a Month from the date ``d``.
        """
    return cls(year=d.year, month=d.month)


def unpack_stream_descriptor(desc):
    """
    Returns dicts for tags and annotations found in supplied stream
    """
    tags = {}
    for tag in desc.tags:
        tags[tag.key] = tag.val.value
    anns = {}
    for ann in desc.annotations:
        anns[ann.key] = ann.val.value
    return tags, anns


def in_colab():
    """Check if the code is running in Google Colaboratory"""
    try:
        from google import colab
        return True
    except:
        return False


@staticmethod
def get_series_resistance(g, b):
    """g : conductance (S)
b : susceptance (S)
return series resistance Rs (ohm) if not infinite"""
    if g == 0 and b == 0:
        return None
    return g / (g * g + b * b)


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


def keywords_first(keywords):
    """ Returns a sort key which preferrs values matching the given keywords
    before other values which are sorted alphabetically.

    """
    assert hasattr(keywords, 'index')

    def sort_key(v):
        try:
            return keywords.index(v) - len(keywords), ''
        except ValueError:
            return 0, v


def subjects_in_tree(study, sheets):
    """Check if the subjects are present in the tree structure template"""
    tree_sheet = sheets[study.tree_sheet_name]
    column_numbers = tree_sheet['Column number']
    subjects_in_tree = 1 in column_numbers.tolist()
    return subjects_in_tree


def increase_flux(reaction, ref_value, value):
    """
    lb                           0                           ub
    |--------------------------- ' ---------------------------|
                <- - -|----------'
                                 '----------|- - - ->

    Parameters
    ----------
    reaction: cobra.Reaction
        The reaction to over-express.
    ref_value: float
        The flux value to come from.
    value: float
        The flux value to achieve.

    """
    if abs(value) < abs(ref_value):
        raise ValueError(
            "'value' is lower than 'ref_value', this is increase_flux (%f < %f)"
             % (value, ref_value))
    if value > 0:
        reaction.lower_bound = value
    elif value < 0:
        reaction.upper_bound = value
    else:
        reaction.knock_out()


def _extract_user_from_email(raw_username):
    """
    Usernames come from the globus provider in the form:
    username@login_authority.com
    """
    if not raw_username:
        return None
    return raw_username.split('@')[0]


def _move(m, dest, src, count):
    """move count bytes from src to dest

    The file pointer is left at the end of dest.
    """
    m.seek(src)
    buf = m.read(count)
    m.seek(dest)
    m.write(buf)


def roteParser(line, frame, time, value, ref1, ref2, ref3, extra):
    """
    R-OTE sample line ---
        1.00,[17:25:39.3415],2737.8,3897.32,675.3,892.12
    """
    part = line.split(',')
    frame.append(part[0])
    time.append(part[1])
    value.append(part[2])
    if len(part) >= 4:
        if part[3]:
            ref1.append(part[3])
    if len(part) >= 5:
        if part[4]:
            ref2.append(part[4])
    if len(part) >= 6:
        if part[5]:
            ref3.append(part[5])


def ignore_case_get(args, key, def_val=''):
    """
    get the value of key
    """
    if not key:
        return def_val
    if key in args:
        return args[key]
    for old_key in args:
        if old_key.upper() == key.upper():
            return args[old_key]
    return def_val


def read_filterwheel(fname):
    """Read a single definition from a filterwheel file."""
    result = {}
    with open(fname, 'r') as f:
        for line in f:
            words = line.split()
            if len(words) not in (2, 3):
                raise Exception('illegal line in filterwheel file')
            result[words[0]] = words[-1]
    return result


def reveal_metaelems(select: bool=True):
    """Reveal all hidden metaelements

    :param select: Select
    :type select: bool
    """
    pass


def qpm_to_bpm(quarter_note_tempo, numerator, denominator):
    """Converts from quarter notes per minute to beats per minute.

    Parameters
    ----------
    quarter_note_tempo : float
        Quarter note tempo.
    numerator : int
        Numerator of time signature.
    denominator : int
        Denominator of time signature.

    Returns
    -------
    bpm : float
        Tempo in beats per minute.
    """
    if not (isinstance(quarter_note_tempo, (int, float)) and
        quarter_note_tempo > 0):
        raise ValueError(
            'Quarter notes per minute must be an int or float greater than 0, but {} was supplied'
            .format(quarter_note_tempo))
    if not (isinstance(numerator, int) and numerator > 0):
        raise ValueError(
            'Time signature numerator must be an int greater than 0, but {} was supplied.'
            .format(numerator))
    if not (isinstance(denominator, int) and denominator > 0):
        raise ValueError(
            'Time signature denominator must be an int greater than 0, but {} was supplied.'
            .format(denominator))
    if denominator in [1, 2, 4, 8, 16, 32]:
        if numerator == 3:
            return quarter_note_tempo * denominator / 4.0
        elif numerator % 3 == 0:
            return quarter_note_tempo / 3.0 * denominator / 4.0
        else:
            return quarter_note_tempo * denominator / 4.0
    else:
        return quarter_note_tempo


def generate_post_data(results=None, page=None, pagtok=None, children=0):
    """
    Creates the post data for a POST request. Mainly for pagination and
    limiting results.

    :param results: the number of results to return.
    :param page: the page number; used to calculate start = page * results.
    :param pagtok: a page token string for pagination in search.
    :param children: number of apps under each collection (used only when
                     scraping a top-level category's collections).
    :return: a dictionary of post data.
    """
    data = {'ipf': 1, 'xhr': 1}
    if children:
        data['numChildren'] = children
    if results is not None:
        if page is not None:
            start = 0 if page <= 0 else results * page
            data['start'] = start
        data['num'] = results
    if pagtok is not None:
        data['pagTok'] = pagtok
    return data


def slim_frame_data(frames, frame_allowance=25):
    """
    Removes various excess metadata from middle frames which go beyond
    ``frame_allowance``.

    Returns ``frames``.
    """
    frames_len = 0
    app_frames = []
    system_frames = []
    for frame in frames:
        frames_len += 1
        if frame.get('in_app'):
            app_frames.append(frame)
        else:
            system_frames.append(frame)
    if frames_len <= frame_allowance:
        return frames
    remaining = frames_len - frame_allowance
    app_count = len(app_frames)
    system_allowance = max(frame_allowance - app_count, 0)
    if system_allowance:
        half_max = int(system_allowance / 2)
        for frame in system_frames[half_max:-half_max]:
            frame.pop('vars', None)
            frame.pop('pre_context', None)
            frame.pop('post_context', None)
            remaining -= 1
    else:
        for frame in system_frames:
            frame.pop('vars', None)
            frame.pop('pre_context', None)
            frame.pop('post_context', None)
            remaining -= 1
    if remaining:
        app_allowance = app_count - remaining
        half_max = int(app_allowance / 2)
        for frame in app_frames[half_max:-half_max]:
            frame.pop('vars', None)
            frame.pop('pre_context', None)
            frame.pop('post_context', None)
    return frames


@staticmethod
def p_value_descriptions_for(p):
    """value_descriptions_for : value_descriptions_for_signal
                                  | value_descriptions_for_env_var"""
    p[0] = p[1]


def get_vocabs(datasets):
    """Build vocabulary from an iterable of datasets objects

    Args:
        datasets: a list of dataset objects

    Returns:
        a set of all the words in the dataset

    """
    print('Building vocab...')
    vocab_words = set()
    vocab_tags = set()
    for dataset in datasets:
        for words, tags in dataset:
            vocab_words.update(words)
            vocab_tags.update(tags)
    print('- done. {} tokens'.format(len(vocab_words)))
    return vocab_words, vocab_tags


def print_entity_info(structure):
    """Prints information about unique entities (molecules) in a structure
    """
    print('*** ENTITY DATA ***')
    for i, e in enumerate(structure.entity_list):
        print(f"entity type            : {i} {e['type']}")
        print(f"entity description     : {i} {e['description']}")
        print(f"entity sequence        : {i} {e['sequence']}")
    print('\n')


@classmethod
def __delete_one(cls, query, db=None):
    """Wrapper of delete_one()

        returns:
            deleted_count (int): # of deleted documents
        """
    __db = db if db else cls.__db
    result = __db[cls.__collection__].delete_one(query)
    return result.deleted_count


def inpgen_dict_set_mesh(inpgendict, mesh):
    """
    params: python dict, used for inpgen parameterdata node
    params: mesh either as returned by kpointsdata or tuple of 3 integers

    returns: python dict, used for inpgen parameterdata node
    """
    if len(mesh) == 2:
        kmesh = mesh[0]
    elif len(mesh) == 3:
        kmesh = mesh
    kpt_dict = inpgendict.get('kpt', {})
    kpt_dict['div1'] = kmesh[0]
    kpt_dict['div2'] = kmesh[1]
    kpt_dict['div3'] = kmesh[2]
    inpgendict_new = inpgendict
    inpgendict_new['kpt'] = kpt_dict
    return inpgendict_new


def _never(*args):
    """Returns False for all step numbers."""
    del args
    return False


@classmethod
def fromFile(cls, memoryMapping, aFile):
    """
            aFile must be able to read().
        """
    return cls(aFile, memoryMapping.start, memoryMapping.end, memoryMapping
        .permissions, memoryMapping.offset, memoryMapping.major_device,
        memoryMapping.minor_device, memoryMapping.inode, memoryMapping.pathname
        )


def CreateID():
    """Generate a packet ID.

    :return: packet ID
    :rtype:  8 bit integer
    """
    global CurrentID
    CurrentID = (CurrentID + 1) % 256
    return CurrentID


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    ll = []
    for i in range(0, len(l), n):
        ll.append(l[i:i + n])
    return ll


@classmethod
def sort(cls, runs, order_by_list):
    """Sorts a set of runs based on their natural ordering and an overriding set of order_bys.
        Runs are naturally ordered first by start time descending, then by run id for tie-breaking.
        """
    runs = sorted(runs, key=lambda run: (-run.info.start_time, run.info.
        run_uuid))
    if not order_by_list:
        return runs
    for order_by_clause in reversed(order_by_list):
        key_type, key, ascending = cls.parse_order_by(order_by_clause)
        runs = sorted(runs, key=lambda run: cls._get_value_for_sort(run,
            key_type, key, ascending), reverse=not ascending)
    return runs


@staticmethod
def find_minimum_ticks_required(tick_duration, periodicities):
    """Find the minimum number of ticks required to execute all jobs
        at once."""
    ticks = 1
    for periodicity in reversed(sorted(periodicities)):
        if ticks % periodicity != 0:
            ticks *= int(periodicity / tick_duration)
    return ticks


def message(pargs, *args):
    """Unless flag '--silent' was used, print the arguments."""
    if pargs.silent:
        return
    print(*args)


def write_json(output, source, show_headers=True, show_tags=True,
    use_objects=False):
    """Serialize a dataset to JSON."""
    for line in source.gen_json(show_headers, show_tags, use_objects):
        output.write(line)


def call(func_name, *args):
    """Performs an [RPC] function call with the given arguments.

    .. warning:: Bytes are returned for Python 3.

    :param str|unicode func_name: Function name to call
        with optional address (if @-syntax is used).

    :param list[str|bytes] args:

    :rtype: bytes|str
    """


def gethostname():
    """Return hostname of local host (as string)"""
    import socket
    return socket.gethostname()


def compliance_check_item_value(report_item, compliance_check_item_name):
    """
    Function returns value of given compliance check item e.g. cm:compliance-check-name
    :param report_item: particular report item for scanned host
    :param compliance_check_item_name: exact compliance check item name for scanned host
    :return: value of given compliance check item name
    """
    compliance_check_item_content_value = None
    compliance = report_item.find('compliance')
    if compliance is not None:
        if compliance.text == 'true':
            compliance_check_item_content = report_item.find(
                compliance_check_item_name, namespaces={'cm':
                'http://www.nessus.org/cm'})
            if compliance_check_item_content is not None:
                compliance_check_item_content_value = (
                    compliance_check_item_content.text)
    return compliance_check_item_content_value


def gettext(nodelist):
    """gets text from a simple XML object"""
    rc = []
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
            rc.append(node.data)
    return ''.join(rc)


def _process_get_modules_wmi():
    """Return the list of processes as tuples (pid, exe_path)"""
    from win32com.client import GetObject
    _wmi = GetObject('winmgmts:')
    modules = []
    processes = _wmi.ExecQuery('Select * from win32_process')
    for p in processes:
        if isinstance(p.ProcessId, int):
            modules.append((p.ProcessId, p.ExecutablePath, p.CommandLine))
    return modules


def get_preferred_sparse_format():
    """Get the preferred sparse matrix format supported by the backend.

    Different backends have their preferred backend. This info is useful when
    constructing a sparse matrix.

    Returns
    -------
    string
        the name of the preferred sparse matrix format.
    """
    pass


def slot_copy():
    """Copy the material texture settings and nodes

    """
    pass


def make_virtual_offset(block_start_offset, within_block_offset):
    """Compute a BGZF virtual offset from block start and within block offsets.
    The BAM indexing scheme records read positions using a 64 bit
    'virtual offset', comprising in C terms:
    block_start_offset << 16 | within_block_offset
    Here block_start_offset is the file offset of the BGZF block
    start (unsigned integer using up to 64-16 = 48 bits), and
    within_block_offset within the (decompressed) block (unsigned
    16 bit integer).
    >>> make_virtual_offset(0, 0)
    0
    >>> make_virtual_offset(0, 1)
    1
    >>> make_virtual_offset(0, 2**16 - 1)
    65535
    >>> make_virtual_offset(0, 2**16)
    Traceback (most recent call last):
    ...
    ValueError: Require 0 <= within_block_offset < 2**16, got 65536
    >>> 65536 == make_virtual_offset(1, 0)
    True
    >>> 65537 == make_virtual_offset(1, 1)
    True
    >>> 131071 == make_virtual_offset(1, 2**16 - 1)
    True
    >>> 6553600000 == make_virtual_offset(100000, 0)
    True
    >>> 6553600001 == make_virtual_offset(100000, 1)
    True
    >>> 6553600010 == make_virtual_offset(100000, 10)
    True
    >>> make_virtual_offset(2**48, 0)
    Traceback (most recent call last):
    ...
    ValueError: Require 0 <= block_start_offset < 2**48, got 281474976710656
    """
    if within_block_offset < 0 or within_block_offset >= 65536:
        raise ValueError('Require 0 <= within_block_offset < 2**16, got %i' %
            within_block_offset)
    if block_start_offset < 0 or block_start_offset >= 281474976710656:
        raise ValueError('Require 0 <= block_start_offset < 2**48, got %i' %
            block_start_offset)
    return block_start_offset << 16 | within_block_offset


def textplot(cflo):
    """Text plot of a cashflow.

    >>> cflo = cashflow(const_value=[-10, 5, 0, 20] * 3, start='2000Q1', freq='Q')
    >>> textplot(cflo)# doctest: +NORMALIZE_WHITESPACE
    time      value +------------------+------------------+
    2000Q1   -10.00           **********
    2000Q2     5.00                    *****
    2000Q3     0.00                    *
    2000Q4    20.00                    ********************
    2001Q1   -10.00           **********
    2001Q2     5.00                    *****
    2001Q3     0.00                    *
    2001Q4    20.00                    ********************
    2002Q1   -10.00           **********
    2002Q2     5.00                    *****
    2002Q3     0.00                    *
    2002Q4    20.00                    ********************

    """
    timeid = cflo.index.to_series().astype(str)
    len_timeid = len(timeid[-1].__repr__())
    fmt_timeid = '{:<' + '{:d}'.format(len_timeid) + 's}'
    len_number = 0
    for value in cflo:
        len_number = max(len_number, len('{:1.2f}'.format(value)))
    fmt_number = ' {:' + '{:d}'.format(len_number) + '.2f}'
    fmt_header = ' {:>' + '{:d}'.format(len_number) + 's}'
    maxval = max(abs(cflo))
    width = 20
    txt = []
    txtrow = fmt_timeid.format('time') + fmt_header.format('value')
    txtrow += ' +' + '-' * (width - 2) + '+' + '-' * (width - 2) + '+'
    txt.append(txtrow)
    for value, timeid in zip(cflo, cflo.index.to_series().astype(str)):
        txtrow = fmt_timeid.format(timeid.__str__())
        txtrow += fmt_number.format(value)
        xlim = int(width * abs(value / maxval))
        if value < 0:
            txtrow += ' ' + ' ' * (width - xlim) + '*' * xlim
        elif value > 0:
            txtrow += ' ' + ' ' * (width - 1) + '*' * xlim
        else:
            txtrow += ' ' + ' ' * (width - 1) + '*'
        txt.append(txtrow)
    print('\n'.join(txt))


@classmethod
def _ready_to_input(cls, title: str):
    """Check if user ready to input."""
    while True:
        ready = input(f'\nЕсли готовы ввести {title}, введите [Y]: ')
        if ready.lower() == 'y':
            break


def rerange(image, old_min, old_max, new_min, new_max, dtype):
    """
    Return image with values in new range.

    Note: The default range of images is [0, 255] and most image
    processing functions expect this range and will fail otherwise.
    However, as input to neural networks re-ranged images, e.g [-1, +1]
    are sometimes needed.

    >>> import numpy as np
    >>> image = np.array([[0, 255], [255, 0]])
    >>> rerange(image, 0, 255, -1, +1, 'float32')
    array([[-1.,  1.],
           [ 1., -1.]], dtype=float32)

    :param numpy.array image: Should be a numpy array of an image.
    :param int|float old_min: Current minimum value of image, e.g. 0
    :param int|float old_max: Current maximum value of image, e.g. 255
    :param int|float new_min: New minimum, e.g. -1.0
    :param int|float new_max: New maximum, e.g. +1.0
    :param numpy datatype dtype: Data type of output image,
           e.g. float32' or np.uint8
    :return: Image with values in new range.
    """
    image = image.astype('float32')
    old_range, new_range = old_max - old_min, new_max - new_min
    image = (image - old_min) / old_range * new_range + new_min
    return image.astype(dtype)


def has_user_interest(cnx, user, entity):
    """return true if the user is currently interested in the entity"""
    return bool(cnx.execute(
        'Any X WHERE U interested_in X, U eid %(u)s, X eid %(x)s', {'u':
        user.eid, 'x': entity.eid}))


def get_record_pairs(dataset1: 'Dataset', dataset2: 'Dataset'=None, block:
    'Block'=None, ground_truth: 'GroundTruth'=None):
    """
    Generate pairs to compare.

    Args:
        dataset1 (Dataset): dataset 1.
        dataset2 (Dataset, optional): dataset 2. If it's not provided, it will be a de-duplication task.
        block (Block, optional): Block.
        ground_truth (GroundTruth, optional): Ground truth.
    """
    if block and not ground_truth:
        if not dataset2:
            for _, id1, id2 in block.pairwise(dataset1.id):
                yield dataset1.get_record(id1), dataset1.get_record(id2)
        else:
            for _, id1, id2 in block.pairwise(dataset1.id, dataset2.id):
                yield dataset1.get_record(id1), dataset2.get_record(id2)
    elif ground_truth and not block:
        if not dataset2:
            for id1, id2, label in ground_truth:
                yield dataset1.get_record(id1), dataset1.get_record(id2)
        else:
            for id1, id2, label in ground_truth:
                yield dataset1.get_record(id1), dataset2.get_record(id2)
    elif ground_truth and block:
        if not dataset2:
            for _, id1, id2 in block.pairwise(dataset1.id):
                if ground_truth.is_member(id1, id2):
                    yield dataset1.get_record(id1), dataset1.get_record(id2)
        else:
            for _, id1, id2 in block.pairwise(dataset1.id, dataset2.id):
                if ground_truth.is_member(id1, id2):
                    yield dataset1.get_record(id1), dataset2.get_record(id2)
    elif not dataset2:
        skip_offset = 0
        for r1 in dataset1:
            for offset, r2 in enumerate(dataset1):
                if offset < skip_offset:
                    continue
                if r1.id == r2.id:
                    continue
                yield r1, r2
            skip_offset += 1
    else:
        for r1 in dataset1:
            for r2 in dataset2:
                yield r1, r2


def __getitem__(path):
    """Returns the binary node value for a path in the manifest.

        Raises ``KeyError`` if the path does not exist in the manifest.

        Equivalent to ``self.find(path)[0]``.
        """


def select(*names):
    """Select fields with given names in order

        Return a new `IFormFields` that is a selection from the original
        `IFormFields` that has the named fields in the specified order.
        """


def _recv_sigint(signum, stack):
    """
    handler function to receive and process a SIGINT

    """
    raise KeyboardInterrupt


@staticmethod
def header_offset(chunk_x: int, chunk_z: int) ->int:
    """
        Returns the byte offset for given chunk in the header

        Parameters
        ----------
        chunk_x
            Chunk's X value
        chunk_z
            Chunk's Z value
        """
    return 4 * (chunk_x % 32 + chunk_z % 32 * 32)


@classmethod
def creating(cls, callback):
    """
        Register a creating model event with the dispatcher.

        :type callback: callable
        """
    cls._register_model_event('creating', callback)


def suppress_output_after_render(app, out_text):
    """
    This is a ``post_render`` hook that suppresses console output again after
    rendering, only if the ``JsonOutputHandler`` is triggered via command
    line.

    :param app: The application object.

    """
    if not hasattr(app.pargs, 'output_handler_override'):
        return
    elif app.pargs.output_handler_override == 'json':
        app._suppress_output()


def receive_progress_info():
    """
    Get progress info from optimization algorithm.
    :return:
    """
    print('hi')


def _pretty_relative_time(time_diff_secs):
    """Originally from: https://stackoverflow.com/questions/1551382/user-friendly-time-format-in-python
    Each tuple in the sequence gives the name of a unit, and the number of
    previous units which go into it.
    """
    weeks_per_month = 365.242 / 12 / 7
    intervals = [('minute', 60), ('hour', 60), ('day', 24), ('week', 7), (
        'month', weeks_per_month), ('year', 12)]
    unit, number = 'second', abs(time_diff_secs)
    for new_unit, ratio in intervals:
        new_number = float(number) / ratio
        if new_number < 2:
            break
        unit, number = new_unit, new_number
    shown_num = int(number)
    return '{} {}'.format(shown_num, unit + ('' if shown_num == 1 else 's'))


def get(name, default=None):
    """Return the named instance if we contain it, else default"""


@classmethod
def parse(cls, fp, data_objects=None, close=True):
    """
            Parses the file 'fp' using one of the parsers in this group.
            'fp' should preferably be a filename (str), but can be a file-like
            object. Take care to open the file in the correct mode when passing
            a file-like object.
        """
    filename, fp, close = cls._get_file(fp, close=close)
    parser = cls.get_parser(filename, fp=fp)
    return parser.parse(fp, data_objects=data_objects, close=close)


def _silent_idx(x, y):
    """
    Given a list x and an object y, returns the index of y in x. Otherwise
    return a None without raising any exceptions.
    >>> _silent_idx([1,2,3,4], 2)
    1
    >>> _silent_idx([1,2,3,4], 5)
    """
    if y in x:
        return x.index(y)
    else:
        return None


@staticmethod
def _get_file_format_info(format_name, table_type, table_name):
    """ returns file extension + dict of required parameters for
        Table.write"""
    if format_name == 'fits':
        return 'fits.gz', dict()
    elif format_name == 'ecsv':
        return 'ecsv.txt', dict(format='ascii.ecsv')
    elif format_name == 'hdf5':
        return 'h5', dict(path='/' + table_type + '/' + table_name)
    else:
        raise NameError('format not supported')


@staticmethod
def write_target_references(context, cmake_file):
    """
        Write target references on given CMakeLists.txt file

        :param context: current context
        :type context: Context
        :param cmake_file: CMakeLists.txt IO wrapper
        :type cmake_file: _io.TextIOWrapper
        """
    deps_to_write = []
    targets_dependencies_set = set()
    for reference in context.target_references:
        targets_dependencies_set.add(reference)
        deps_to_write.append(reference)
    for sln_dep in context.sln_deps:
        if sln_dep not in targets_dependencies_set:
            targets_dependencies_set.add(sln_dep)
            deps_to_write.append(sln_dep)
    if deps_to_write:
        cmake_file.write('add_dependencies(${PROJECT_NAME}\n')
        for dep in deps_to_write:
            cmake_file.write('    {}\n'.format(dep))
        cmake_file.write(')\n\n')


def is_pattern(s):
    """Return True if a string contains Unix wildcard pattern characters.
    """
    return not set('*?[{').intersection(set(s)) == set()


def add_str_if_not_exist(new_str, existing_str_lst):
    """Will return True if the new string provided is not already in the list of strings."""
    addthis = True
    for fail2txt in existing_str_lst:
        if new_str.text in fail2txt:
            addthis = False
    return addthis


@staticmethod
def max_run(_b, _x):
    """Determine the length of the maximum run of b's in vector x.

        Parameters
        ----------
        b: int
            Integer for counting.

        x: array
            Vector of integers.

        Returns
        -------
        max: int
            Length of maximum run of b's.
        """
    _max = 0
    run = 0
    for i in _x:
        if i == _b:
            run += 1
        else:
            if run > _max:
                _max = run
            run = 0
    if _x[-1] == _b and run > _max:
        _max = run
    return _max


def is_equal(x, y, tolerance=1e-06):
    """
    Checks if 2 float values are equal withing a given tolerance
    :param x: float, first float value to compare
    :param y: float, second float value to compare
    :param tolerance: float, comparison tolerance
    :return: bool
    """
    return abs(x - y) < tolerance


def K2degC(value):
    """float: temperature: Kelvin to Celcius."""
    return value - 273.15


def create_rolling_update_desc(rolling_upgrade_mode, force_restart,
    replica_set_check_timeout, failure_action, health_check_wait,
    health_check_stable, health_check_retry, upgrade_timeout,
    upgrade_domain_timeout):
    """Create an update description for an upgrade rolling mode"""
    from azure.servicefabric.models import RollingUpgradeUpdateDescription
    return RollingUpgradeUpdateDescription(rolling_upgrade_mode=
        rolling_upgrade_mode, force_restart=force_restart,
        replica_set_check_timeout_in_milliseconds=replica_set_check_timeout,
        failure_action=failure_action,
        health_check_wait_duration_in_milliseconds=health_check_wait,
        health_check_stable_duration_in_milliseconds=health_check_stable,
        health_check_retry_timeout_in_milliseconds=health_check_retry,
        upgrade_domain_timeout_in_milliseconds=upgrade_domain_timeout,
        upgrade_timeout_in_milliseconds=upgrade_timeout)


def combined(*dicts):
    """
    Combine multiple dicts.

    >>> (combined({'a': 'foo'}, {'b': 'bar'})
    ...  == {'a': 'foo', 'b': 'bar'})
    True
    """
    result = {}
    for d in dicts:
        result.update(d)
    return result


def _fastq_head(buf, end=None):
    """
    Search for the end of the last complete *two* FASTQ records in buf[:end].

    Two FASTQ records are required to ensure that read pairs in interleaved
    paired-end data are not split.
    """
    linebreaks = buf.count(b'\n', 0, end)
    right = end
    for _ in range(linebreaks % 8 + 1):
        right = buf.rfind(b'\n', 0, right)
    return right + 1


def pick_datatype(counts):
    """
    If the underlying records are ONLY of type `integer`, `number`,
    or `date-time`, then return that datatype.

    If the underlying records are of type `integer` and `number` only,
    return `number`.

    Otherwise return `string`.
    """
    to_return = 'string'
    if counts.get('date-time', 0) > 0:
        return 'date-time'
    if len(counts) == 1:
        if counts.get('integer', 0) > 0:
            to_return = 'integer'
        elif counts.get('number', 0) > 0:
            to_return = 'number'
    elif len(counts) == 2 and counts.get('integer', 0) > 0 and counts.get(
        'number', 0) > 0:
        to_return = 'number'
    return to_return


def _delete_trailing_number(line):
    """Deletes trailing number from a line.

    WARNING: does not preserve internal whitespace when a number is removed!
    (converts each whitespace run to a single space). Returns the original
    line if it didn't end in a number.
    """
    pieces = line.split()
    try:
        int(pieces[-1])
        return ' '.join(pieces[:-1])
    except ValueError:
        return line


@staticmethod
def split_url(url: str):
    """Explode a Git remote URL into FS-friendly pieces."""
    if url.endswith('.git'):
        url = url[:-4]
    return url[url.find('://') + 3:].split('/')


def modify_luna_client(ClientArn=None, Certificate=None):
    """
    Modifies the certificate used by the client.
    This action can potentially start a workflow to install the new certificate on the client's HSMs.
    See also: AWS API Documentation

    :example: response = client.modify_luna_client(
        ClientArn='string',
        Certificate='string'
    )

    :type ClientArn: string
    :param ClientArn: [REQUIRED]
            The ARN of the client.

    :type Certificate: string
    :param Certificate: [REQUIRED]
            The new certificate for the client.

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

    """
    pass


def log_info(info):
    """Styling for a block info log statement"""
    if info != '':
        print(' + %s' % info)


def conditional(**kwargs):
    """A wrapper around :func:`django.views.decorators.http.condition` that
    works for methods (i.e. class-based views).
    """
    from django.views.decorators.http import condition
    from django.utils.decorators import method_decorator
    return method_decorator(condition(**kwargs))


def axis_slice(a, start=None, stop=None, step=None, axis=-1):
    """Take a slice along axis 'axis' from 'a'.

    Parameters
    ----------
    a : numpy.ndarray
        The array to be sliced.
    start, stop, step : int or None
        The slice parameters.
    axis : int, optional
        The axis of `a` to be sliced.

    Examples
    --------
    >>> a = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    >>> axis_slice(a, start=0, stop=1, axis=1)
    array([[1],
           [4],
           [7]])
    >>> axis_slice(a, start=1, axis=0)
    array([[4, 5, 6],
           [7, 8, 9]])

    Notes
    -----
    The keyword arguments start, stop and step are used by calling
    slice(start, stop, step).  This implies axis_slice() does not
    handle its arguments the exacty the same as indexing.  To select
    a single index k, for example, use
        axis_slice(a, start=k, stop=k+1)
    In this case, the length of the axis 'axis' in the result will
    be 1; the trivial dimension is not removed. (Use numpy.squeeze()
    to remove trivial axes.)
    """
    a_slice = [slice(None)] * a.ndim
    a_slice[axis] = slice(start, stop, step)
    b = a[a_slice]
    return b


def removeSystemEventTrigger(triggerID):
    """
        Removes a trigger added with addSystemEventTrigger.

        @param triggerID: a value returned from addSystemEventTrigger.

        @raise KeyError: If there is no system event trigger for the given
            C{triggerID}.

        @raise ValueError: If there is no system event trigger for the given
            C{triggerID}.

        @raise TypeError: If there is no system event trigger for the given
            C{triggerID}.
        """


def _quokka_normalize_extract(extract):
    """Generate a normalized rectangle for the standard quokka image.

    Parameters
    ----------
    extract : 'square' or tuple of number or imgaug.augmentables.bbs.BoundingBox or imgaug.augmentables.bbs.BoundingBoxesOnImage
        Unnormalized representation of the image subarea to be extracted.

            * If ``str`` ``square``, then a squared area
              ``(x: 0 to max 643, y: 0 to max 643)`` will be extracted from
              the image.
            * If a ``tuple``, then expected to contain four ``number`` s
              denoting ``(x1, y1, x2, y2)``.
            * If a :class:`~imgaug.augmentables.bbs.BoundingBox`, then that
              bounding box's area will be extracted from the image.
            * If a :class:`~imgaug.augmentables.bbs.BoundingBoxesOnImage`,
              then expected to contain exactly one bounding box and a shape
              matching the full image dimensions (i.e. ``(643, 960, *)``).
              Then the one bounding box will be used similar to
              ``BoundingBox`` above.

    Returns
    -------
    imgaug.augmentables.bbs.BoundingBox
        Normalized representation of the area to extract from the standard
        quokka image.

    """
    from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage
    if extract == 'square':
        bb = BoundingBox(x1=0, y1=0, x2=643, y2=643)
    elif isinstance(extract, tuple) and len(extract) == 4:
        bb = BoundingBox(x1=extract[0], y1=extract[1], x2=extract[2], y2=
            extract[3])
    elif isinstance(extract, BoundingBox):
        bb = extract
    elif isinstance(extract, BoundingBoxesOnImage):
        assert len(extract.bounding_boxes
            ) == 1, 'Provided BoundingBoxesOnImage instance may currently only contain a single bounding box.'
        assert extract.shape[0:2] == (643, 960
            ), 'Expected BoundingBoxesOnImage instance on an image of shape (643, 960, ?). Got shape %s.' % (
            extract.shape,)
        bb = extract.bounding_boxes[0]
    else:
        raise Exception(
            "Expected 'square' or tuple of four entries or BoundingBox or BoundingBoxesOnImage for parameter 'extract', got %s."
             % (type(extract),))
    return bb


def shell_strip_comment(cmd):
    """ hi # testing => hi"""
    if '#' in cmd:
        return cmd.split('#', 1)[0]
    else:
        return cmd


def escape(s, sep):
    """Escape unescapes separators and backslashes in strings.

    """
    return s.replace('\\', '\\\\').replace(sep, '\\' + sep)


def calc_field_size(field_type, length):
    """
    Рассчитывает размер данных поля

    :param field_type: Тип поля
    :type field_type: string
    :param length: Длина поля
    :type length: int
    :return: Длина поля в байтах
    :rtype: int
    """
    if field_type == 'B':
        return length
    elif field_type == 'L':
        return 1
    elif field_type == 'N':
        return length // 2 + 1
    elif field_type == 'NC':
        return length * 2
    elif field_type == 'NVC':
        return length * 2 + 2
    elif field_type == 'RV':
        return 16
    elif field_type == 'NT':
        return 8
    elif field_type == 'I':
        return 8
    elif field_type == 'DT':
        return 7
    else:
        raise ValueError('Unknown field type')


def s3_path_to_bucket_key(s3_path):
    """
    Splits out s3 file path to bucket key combination
    """
    return s3_path.replace('s3://', '').split('/', 1)


def convertWCS(inwcs, drizwcs):
    """ Copy WCSObject WCS into Drizzle compatible array."""
    drizwcs[0] = inwcs.crpix[0]
    drizwcs[1] = inwcs.crval[0]
    drizwcs[2] = inwcs.crpix[1]
    drizwcs[3] = inwcs.crval[1]
    drizwcs[4] = inwcs.cd[0][0]
    drizwcs[5] = inwcs.cd[1][0]
    drizwcs[6] = inwcs.cd[0][1]
    drizwcs[7] = inwcs.cd[1][1]
    return drizwcs


def stripped(jid):
    """ strip trailing part of a JID, the part after the / """
    try:
        return str(jid).split('/')[0]
    except:
        return str(jid)


def context_scale_float(data_path: str='', value: float=1.0):
    """Scale a float context value

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param value: Value, Assign value
    :type value: float
    """
    pass


def is_track_header(line):
    """Returns if the line is a header line used in genome tracks/browsers."""
    line = line.strip()
    if line.startswith('#') or line.startswith('track') or line.startswith(
        'browser'):
        return True
    else:
        return False


def prettyPrintDictionary(d):
    """Pretty print a dictionary as simple keys and values"""
    maxKeyLength = 0
    maxValueLength = 0
    for key, value in list(d.items()):
        maxKeyLength = max(maxKeyLength, len(key))
        maxValueLength = max(maxValueLength, len(key))
    for key in sorted(d.keys()):
        print(('%' + str(maxKeyLength) + 's : %-' + str(maxValueLength) +
            's') % (key, d[key]))


def is_float(potential_float: str) ->bool:
    """
    Check if potential_float is a valid float.

    Returns
    -------
    is_float : bool

    Examples
    --------
    >>> is_float('123')
    True
    >>> is_float('1234567890123456789')
    True
    >>> is_float('0')
    True
    >>> is_float('-123')
    True
    >>> is_float('123.45')
    True
    >>> is_float('a')
    False
    >>> is_float('0x8')
    False
    """
    try:
        float(potential_float)
        return True
    except ValueError:
        return False


def format_prefix(prefix):
    """
    Format url path prefix, ensure '/' in the begining.
    """
    prefix = '' if prefix is None else prefix
    prefix = prefix if prefix.startswith('/') else '/%s' % prefix
    return prefix


def add_verbosity_argument(parser, default=0):
    """Add a verbosity argument to parser.

    Note:
      The argument is '-v' or '--verbosity'.
      Add multiple '-v' arguments, e.g. '-vv' or '-vvv' to
      increase the level of verbosity.

    Args:
      parser: A argparse object.
      default: The default level, defaults to 0.
    """
    parser.add_argument('-v', '--verbosity', help='Set level of verbosity.',
        action='count', default=default)


def count_records(fpath):
    """Quickly count headers in FASTA file.

    Args:
        fpath (str): path to input FASTA file.

    Returns:
        int: number of headers (lines starting with ">")
    """
    rc = 0
    with open(fpath, 'r') as IH:
        for line in IH:
            if '>' == line[0]:
                rc += 1
    return rc


def generate_new_ids(species, old_Ntot, new_Ntot):
    """
    If `species` is tracked, then generate new ids, between the
    indices `old_Ntot` and `new_Ntot` of the particle ID arrays

    (This is performed either on GPU or CPU.)
    """
    if species.tracker is not None:
        if species.use_cuda:
            species.tracker.generate_new_ids_gpu(old_Ntot, new_Ntot)
        else:
            species.tracker.id[old_Ntot:new_Ntot
                ] = species.tracker.generate_new_ids(new_Ntot - old_Ntot)


def Description():
    """ Return the DCMI Description element (resource summary).

        o Result is a natural language description of this object.

        o Permission:  View
        """


def skip_redundant(iterable, skipset=None):
    """Redundant items are repeated items or items in the original skipset."""
    if skipset is None:
        skipset = set()
    for item in iterable:
        if item not in skipset:
            skipset.add(item)
            yield item


def unshape_data(data):
    """
    Return 1D version of data.
    """
    return data.flatten()


def upper(series):
    """Test that the data items are all uppercase."""
    return series.str.isupper()


def _compute_size(start, stop, step):
    """Algorithm adapted from cpython rangeobject.c
    """
    if step > 0:
        lo = start
        hi = stop
    else:
        lo = stop
        hi = start
        step = -step
    if lo >= hi:
        return 0
    return (hi - lo - 1) // step + 1


def readFile(path):
    """Returns the contents of the file identified by the given path.

        Raises IOError if the file cannot be read.
        """


@staticmethod
def t_FUNCTION(tok):
    """[_a-zA-Z][_a-zA-Z0-9]{2,}\\("""
    tok.value = tok.type, tok.value[:-1]
    return tok


def bech32_polymod(values):
    """Internal function that computes the Bech32 checksum."""
    generator = [996825010, 642813549, 513874426, 1027748829, 705979059]
    chk = 1
    for value in values:
        top = chk >> 25
        chk = (chk & 33554431) << 5 ^ value
        for i in range(5):
            chk ^= generator[i] if top >> i & 1 else 0
    return chk


def __num_clusters(config, args, ratios):
    """override number of clusters either on the command line or through
    the config file"""
    try:
        num_clusters = config.getint('General', 'num_clusters')
    except:
        num_clusters = args.numclusters
    if num_clusters is None:
        return int(round(ratios.num_rows * args.clusters_per_row / 20.0))
    else:
        return num_clusters


def __lshift__(return_spec, argument_spec):
    """
<<This is about to change, does not work as one may expected.
Nov 19 2005. >>>

Return a 'mapping' set, which may be used for specification and test
purposes. It implements the syntax:

        return_spec << argument_spec

The elements of the set returned are the callable objects that return
values in return_spec, when called with arguments according to
argument_spec. The return_spec may be any kind of sets that can test
for element containment. The argument_spec may be a set or a tuple. If
it is a set, it should be able to generate some examples, to allow the
mapping to be tested.  When argument_spec is a set, the mapping will
have a single argument. Any number of arguments may be specified using
an argument_spec which is a tuple.  The arguments are then specified
with sets, that should be able to generate examples. Special features
of the mapping such as optional arguments may be specified in the same
way as when using the 'mapping' function in the Spec.py module.

"""
    return return_spec.fam.c_lshift(return_spec, argument_spec)


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

        :param LookupError val:
        :rtype: RelocationError
        """
    return cls('from_lookup', val)


def bytes2bin(bites, sz=8):
    """Accepts a string of ``bytes`` (chars) and returns an array of bits
    representing the bytes in big endian byte order. An optional max ``sz`` for
    each byte (default 8 bits/byte) which can  be used to mask out higher
    bits."""
    if sz < 1 or sz > 8:
        raise ValueError(f'Invalid sz value: {sz}')
    retval = []
    for b in [bytes([b]) for b in bites]:
        bits = []
        b = ord(b)
        while b > 0:
            bits.append(b & 1)
            b >>= 1
        if len(bits) < sz:
            bits.extend([0] * (sz - len(bits)))
        elif len(bits) > sz:
            bits = bits[:sz]
        bits.reverse()
        retval.extend(bits)
    return retval


def assign_to_cluster(observation, cluster_centers):
    """ Assign an observation to a cluster.

    Input:
        observation (array):
        cluster_centers (pd.DataFrame):
    Returns:
        index (int): Cluster assignment for the observation.
    """
    return (cluster_centers.subtract(observation, axis=0) ** 2).sum().idxmin()


@classmethod
def DefaultNamespace(cls):
    """The global default namespace (used on instance creation if not overridden)"""
    return cls.__NamespaceContext.defaultNamespace()


def wrap_iterator_inc_counter(iterator, counter, grpc_type,
    grpc_service_name, grpc_method_name):
    """Wraps an iterator and collect metrics."""
    for item in iterator:
        counter.labels(grpc_type=grpc_type, grpc_service=grpc_service_name,
            grpc_method=grpc_method_name).inc()
        yield item


def __call__(cls, *args, **kwargs):
    """Do not allow the class to be instantiated."""
    raise TypeError('Type {} cannot be instantiated.'.format(cls.__name__))


def parse_signed_request(signed_request_string):
    """
    Just here for your convenience, actual logic is in the
    FacebookAuthorization class
    """
    from open_facebook.api import FacebookAuthorization
    signed_request = FacebookAuthorization.parse_signed_data(
        signed_request_string)
    return signed_request


@staticmethod
def add_extra_info(info_dict, extra_info):
    """Set the keys from extra_info in info dict if they are missing"""
    for key, value in extra_info.items():
        info_dict.setdefault(key, value)


@staticmethod
def _gen_w1_weight(num_pos, num_neg):
    """
        Return w1 weight parameter based on pos and neg exemplars
        """
    return max(1.0, num_neg / float(num_pos))


def strip(value):
    """
    Strip all leading and trailing whitespaces.
    :param value: The value
    :type value: str
    :return: The value with all leading and trailing whitespaces removed
    :rtype: str
    """
    return value.strip()


def get_note_category(note):
    """get a note category"""
    if 'category' in note:
        category = note['category'] if note['category'] is not None else ''
    else:
        category = ''
    return category


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


@classmethod
def new_comm_kwargs(cls, *args, **kwargs):
    """Initialize communication with new queue."""
    kwargs.setdefault('address', 'file.txt')
    return args, kwargs


@classmethod
def create(cls, arg):
    """
        construct a subquery from arg
        """
    obj = cls()
    obj._connection = arg.connection
    obj._heading = arg.heading.make_subquery_heading()
    obj._arg = arg
    return obj


def bytes2str(bites: bytes, encoding: str='utf-8') ->str:
    """Convert bytes to a string

    :param bites: bytes
    :type bites: bytes
    :param encoding: encoding of the string (default is utf-8)
    :type encoding: str
    :return: converted bytes
    :rtype: str

    .. doctest:: python

        >>> a = b'abcdefg'
        >>> type(a)
        <class 'bytes'>
        >>> bytes2str(a)
        'abcdefg'
        >>> type(bytes2str(a))
        <class 'str'>

    """
    return bites.decode(encoding)


def get_git_description():
    """Open .git/description and determine if description exists."""
    try:
        with open('./.git/description', 'r') as git_desc:
            for line in git_desc:
                if line.startswith('Unnamed repository;'):
                    return 'YOUR PROJECT DESCRIPTION HERE'
                else:
                    return git_desc.read()
    except FileNotFoundError:
        return 'YOUR PROJECT DESCRIPTION HERE'


def is_adverb(pos_tag):
    """Return ``True`` if ``pos_tag`` is ``ADV``, False otherwise.

    :param pos_tag: Part of Speech tag
    :type pos_tag: string
    :return: True if POS is adverb
    :rtype: boolean
    """
    return pos_tag == 'ADV'


@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.dynamallow_validate(item), **kwargs)


def mass2_from_mtotal_eta(mtotal, eta):
    """Returns the secondary mass from the total mass and symmetric mass
    ratio.
    """
    return 0.5 * mtotal * (1.0 - (1.0 - 4.0 * eta) ** 0.5)


def get_preferred_sparse_format():
    """Get the preferred sparse matrix format supported by the backend.

    Different backends have their preferred backend. This info is useful when
    constructing a sparse matrix.
    """
    return 'coo'


def delete_db_security_group(DBSecurityGroupName=None):
    """
    Deletes a DB security group.
    See also: AWS API Documentation

    Examples
    The following example deletes a DB security group.
    Expected Output:

    :example: response = client.delete_db_security_group(
        DBSecurityGroupName='string'
    )

    :type DBSecurityGroupName: string
    :param DBSecurityGroupName: [REQUIRED]
            The name of the DB security group to delete.
            Note
            You cannot delete the default DB security group.
            Constraints:
            Must be 1 to 255 alphanumeric characters
            First character must be a letter
            Cannot end with a hyphen or contain two consecutive hyphens
            Must not be 'Default'

    :return: response = client.delete_db_security_group(
        DBSecurityGroupName='mysecgroup',
    )

    print(response)

    """
    pass


def get_encoding_from_witness(witness_type=None):
    """
    Derive address encoding (base58 or bech32) from transaction witness type

    :param witness_type: Witness type: legacy, p2sh-segwit or segwit
    :type witness_type: str

    :return str:
    """
    if witness_type == 'segwit':
        return 'bech32'
    elif witness_type in [None, 'legacy', 'p2sh-segwit']:
        return 'base58'
    else:
        raise ValueError('Unknown witness type %s' % witness_type)


def user_key(scancode):
    """Return a key symbol for a key not supported by pyglet.

    This can be used to map virtual keys or scancodes from unsupported
    keyboard layouts into a machine-specific symbol.  The symbol will
    be meaningless on any other machine, or under a different keyboard layout.

    Applications should use user-keys only when user explicitly binds them
    (for example, mapping keys to actions in a game options screen).
    """
    assert scancode > 0
    return scancode << 32


def __init__(s, name, type_list, field_list):
    """Entry point to initialize one type of AST node.

    `name` is the name of this constructor and should be capitalized.
    `type_list` is the list of node types of all parameters. `field_list` is
    the list of names of all parameters. If the constructor does not have any
    parameters, both lists will be None."""
    assert name[0].isupper()
    isNone = type_list is None and field_list is None
    isSameLen = not isNone and len(type_list) == len(field_list)
    assert isNone or isSameLen
    s.name = name
    s.type_list = type_list
    s.field_list = field_list


def _relative_degree(z, p):
    """
    Return relative degree of transfer function from zeros and poles
    """
    degree = len(p) - len(z)
    if degree < 0:
        raise ValueError(
            'Improper transfer function. Must have at least as many poles as zeros.'
            )
    else:
        return degree


def portletAvailable():
    """Is the portlet available in this context"""


def linalg_inverse(A=None, name=None, attr=None, out=None, **kwargs):
    """Compute the inverse of a matrix.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, *A* is a square matrix. We compute:

      *out* = *A*\\ :sup:`-1`

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

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

    Examples::

       Single matrix inverse
       A = [[1., 4.], [2., 3.]]
       inverse(A) = [[-0.6, 0.8], [0.4, -0.2]]

       Batch matrix inverse
       A = [[[1., 4.], [2., 3.]],
            [[1., 3.], [2., 4.]]]
       inverse(A) = [[[-0.6, 0.8], [0.4, -0.2]],
                     [[-2., 1.5], [1., -0.5]]]

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

    Parameters
    ----------
    A : Symbol
        Tensor of square matrix

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

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


def width(rect):
    """Returns the literal width of the rectangle.

    :rtype: float
    :return: The width of the rectangle. This can be a
        negative value.
    """
    return rect[1][0]


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 chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


def unescape(text):
    """
    Do reverse escaping.
    """
    text = text.replace('&', '&')
    text = text.replace('<', '<')
    text = text.replace('>', '>')
    text = text.replace('"', '"')
    text = text.replace(''', "'")
    return text


def iunique(iterable):
    """Return an iterable of unique items ordered by first occurrence"""
    seen = set()
    for item in iterable:
        if item not in seen:
            seen.add(item)
            yield item


@classmethod
def _create_from_stripe_object(cls, data, current_ids=None,
    pending_relations=None, save=True, stripe_account=None):
    """
        Set the stripe_account to the id of the Account instance being created.

        This ensures that the foreign-key relations that may exist in stripe are
        fetched using the appropriate connected account ID.
        """
    return super()._create_from_stripe_object(data=data, current_ids=
        current_ids, pending_relations=pending_relations, save=save,
        stripe_account=data['id'] if not stripe_account else stripe_account)


def compact_from_uint256(v):
    """Convert uint256 to compact encoding
    """
    nbytes = v.bit_length() + 7 >> 3
    compact = 0
    if nbytes <= 3:
        compact = (v & 16777215) << 8 * (3 - nbytes)
    else:
        compact = v >> 8 * (nbytes - 3)
        compact = compact & 16777215
    if compact & 8388608:
        compact >>= 8
        nbytes += 1
    return compact | nbytes << 24


def ensure_quotes(s: str) ->str:
    """Quote a string that isn't solely alphanumeric."""
    return '"{}"'.format(s) if not s.isalnum() else s


def has_connected_children(bone):
    """ Returns true/false whether a bone has connected children or not.
    """
    t = False
    for b in bone.children:
        t = t or b.use_connect
    return t


def subset_dot(subset, a, b, dtype=None, queue=None, slice=None):
    """
    .. versionadded:: 2011.1
    """
    from pyopencl.reduction import get_subset_dot_kernel
    krnl = get_subset_dot_kernel(a.context, dtype, subset.dtype, a.dtype, b
        .dtype)
    result, event1 = krnl(subset, a, b, queue=queue, slice=slice, wait_for=
        subset.events + a.events + b.events, return_event=True)
    result.add_event(event1)
    return result


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

    The ".dev0" means dirty.

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


def _has_page_changed(url, driver_url):
    """
    Has the page's URL changed? Exclude everything after a hash.
    """
    return url[0:url.find('#') if url.find('#') > 0 else len(url)].rstrip('/'
        ) != driver_url[0:driver_url.find('#') if driver_url.find('#') > 0 else
        len(driver_url)].rstrip('/')


def to_python_boolean(string):
    """Convert a string to boolean.
    """
    string = string.lower()
    if string in ('t', 'true', '1'):
        return True
    if string in ('f', 'false', '0'):
        return False
    raise ValueError("Invalid boolean value: '%s'" % string)


def flatten(fields):
    """
    Return a list which is a single level of flattening of the original list.
    """
    flat = []
    for field in fields:
        if isinstance(field, (list, tuple)):
            flat.extend(field)
        else:
            flat.append(field)
    return flat


@classmethod
def source(cls, guid):
    u"""
        Подключенный источник данных с указанным идентификатором

        :param guid: Идентификатор источника данных
        :type guid: str

        :return: Источник данных или None
        :rtype: creadoc.report.source.DataSource or None
        """
    return cls.__source_guids.get(guid)


def isfloat(tmp):
    """
    Check if a number is a float. Can take decimal point.

    Parameters
    ----------
    tmp : str
        Number in string form.

    Returns
    -------
    bool
        True if number is a float, False otherwise..

    """
    try:
        float(tmp)
        return True
    except ValueError:
        return False


@conf
def fc_flags(conf):
    """
	Defines common fortran configuration flags and file extensions
	"""
    v = conf.env
    v.FC_SRC_F = []
    v.FC_TGT_F = ['-c', '-o']
    v.FCINCPATH_ST = '-I%s'
    v.FCDEFINES_ST = '-D%s'
    if not v.LINK_FC:
        v.LINK_FC = v.FC
    v.FCLNK_SRC_F = []
    v.FCLNK_TGT_F = ['-o']
    v.FCFLAGS_fcshlib = ['-fpic']
    v.LINKFLAGS_fcshlib = ['-shared']
    v.fcshlib_PATTERN = 'lib%s.so'
    v.fcstlib_PATTERN = 'lib%s.a'
    v.FCLIB_ST = '-l%s'
    v.FCLIBPATH_ST = '-L%s'
    v.FCSTLIB_ST = '-l%s'
    v.FCSTLIBPATH_ST = '-L%s'
    v.FCSTLIB_MARKER = '-Wl,-Bstatic'
    v.FCSHLIB_MARKER = '-Wl,-Bdynamic'
    v.SONAME_ST = '-Wl,-h,%s'


def value():
    """return outgoing things and clear outgoing things"""


def unauthenticated(func):
    """Adds 'unauthenticated' attribute to decorated function.

    Usage:

    >>> @unauthenticated
    ... def mymethod(f):
    ...     pass
    """
    func.unauthenticated = True
    return func


def addgroup(deltas, linkmapper, transaction, addrevisioncb=None):
    """Process a series of deltas for storage.

        See the documentation in ``ifilemutation`` for more.
        """


@classmethod
def get_abjad_startup_string(class_):
    """
        Gets Abjad startup string.

        ..  container:: example

            >>> abjad_configuration = abjad.AbjadConfiguration()
            >>> abjad_configuration.get_abjad_startup_string()
            'Abjad 3.1 (development)'

        Returns string.
        """
    result = 'Abjad {} ({})'
    result = result.format(class_.get_abjad_version_string(), 'development')
    return result


def convert_unicode_string(unicode_string):
    """
    Convert a unicode string into str.

    :param unicode_string:
    :return: string.
    """
    if unicode_string is not None:
        return str(unicode_string)
    return None


def _is_hashable(x):
    """
    I implemented this because ``isinstance({}.__getitem__, collections.Hashable)``
    does not do what I want.
    """
    try:
        hash(x)
    except TypeError:
        return False
    else:
        return True


@classmethod
def from_json(cls, config_name: str, filename: str='config.json'):
    """
        Собрать экземпляр из JSON файла
        """
    path = cls.get_config_path(filename)
    data = cls.extract_json(config_name, path)
    return cls(created_from=path, **data)


@classmethod
def set_default(cls, currency_code: str):
    """Set currency as base currency with value of 1.

        :param currency_code: Code of base currency
        """
    currency = cls.query.filter_by(code=currency_code).first()
    if currency is None:
        raise ValueError(f'Currency not found: {currency_code}')
    value = currency.value
    for c in cls.query.all():
        c.value /= value


def group_sort():
    """Sort Bone Groups by their names in ascending order

    """
    pass


def calcInstrNoiseSq(photParams):
    """
    Combine all of the noise due to intrumentation into one value
    @param [in] photParams is an instantiation of the
    PhotometricParameters class that carries details about the
    photometric response of the telescope.
    @param [out] The noise due to all of these sources added in quadrature
    in ADU counts
    """
    instNoiseSq = (photParams.nexp * photParams.readnoise ** 2 + photParams
        .darkcurrent * photParams.exptime * photParams.nexp + photParams.
        nexp * photParams.othernoise ** 2)
    instNoiseSq = instNoiseSq / (photParams.gain * photParams.gain)
    return instNoiseSq


def reserve_name(name, reservation_scope):
    """
    Reserve a name in a reservation scope

    :param str name: The name to reserve
    :param reservation_scope:
    :type reservation_scope: Iterable[:class:`ast.AST`]

    """
    for namespace in reservation_scope:
        namespace.assigned_names.add(name)


@staticmethod
def __get_attr(what, type_attr, value_attr, **kwargs):
    """
        get the value of a parm
        :param what: string parm
        :param type_attr: type of parm
        :param value_attr:
        :param kwargs:
        :return: value of the parm
        """
    value = int(kwargs[what]) if type_attr == 'int' else kwargs[what]
    if what in kwargs and value in value_attr:
        return value


@classmethod
def change_default_dict_keys(cls, primary_name=None, secondary_name=None,
    score_name=None):
    """Change the dict key names - not advised. Params are any dict-key compatible type - cannot be None."""
    if primary_name is not None:
        cls._primary_default_name = primary_name
    if secondary_name is not None:
        cls._secondary_default_name = secondary_name
    if score_name is not None:
        cls._score_default_name = score_name


def create_generate(kind, project, resource, offset):
    """A factory for creating `Generate` objects

    `kind` can be 'variable', 'function', 'class', 'module' or
    'package'.

    """
    generate = eval('Generate' + kind.title())
    return generate(project, resource, offset)


def save_graph_to_svg(G, labels, filename, backward=False):
    """ Generate a figure of a networkx's graph object and save it. """
    import networkx as nx
    if backward:
        G = G.reverse()
    pydot_graph = nx.drawing.nx_pydot.to_pydot(G)
    pydot_graph.set_rankdir('LR')
    pydot_graph.set_nodesep(0.5)
    for n in pydot_graph.get_nodes():
        name = n.get_name()
        n.set_style('rounded')
        n.set_style('filled')
        n.set_shape('box')
        n.set_fillcolor('#E5E5E5')
        n.set_width(0)
        n.set_height(0)
        n.set_label(labels[name.strip('"')])
    pydot_graph.write_svg(filename)


def parse_capability_line(line):
    """
	Parses the provided firmware capability line.

	Lines are expected to be of the format

	    Cap:<capability name in caps>:<0 or 1>

	e.g.

	    Cap:AUTOREPORT_TEMP:1
	    Cap:TOGGLE_LIGHTS:0

	Args:
		line (str): the line to parse

	Returns:
		tuple: a 2-tuple of the parsed capability name and whether it's on (true) or off (false), or None if the line
		    could not be parsed
	"""
    line = line.lower()
    if line.startswith('cap:'):
        line = line[len('cap:'):]
    parts = line.split(':')
    if len(parts) != 2:
        return None
    capability, flag = parts
    if not flag in ('0', '1'):
        return None
    return capability.upper(), flag == '1'


def getDescription():
    """Return a description.
        """


@staticmethod
def p_phone_no(p):
    """phone_no : PHONE_NO STRING"""
    p[0] = p[2]


def base_initializer(shape, dtype, ctx, id_range):
    """The function signature for feature initializer.

    Any customized feature initializer should follow this signature (see
    example below).

    Parameters
    ----------
    shape : tuple of int
        The shape of the result features. The first dimension
        is the batch dimension.
    dtype : data type object
        The data type of the returned features.
    ctx : context object
        The device context of the returned features.
    id_range : slice
        The start id and the end id of the features to be initialized.
        The id could be node or edge id depending on the scenario.
        Note that the step is always None.

    Examples
    --------
    If PyTorch is used as backend, the following code defines an feature
    initializer that initializes tensor value to 1

    >>> import torch
    >>> import dgl
    >>> def initializer(shape, dtype, ctx, id_range):
    >>>     return torch.ones(shape, dtype=dtype, device=ctx)
    >>> g = dgl.DGLGraph()
    >>> g.set_n_initializer(initializer)

    See Also
    --------
    dgl.DGLGraph.set_n_initializer
    dgl.DGLGraph.set_e_initializer
    """
    raise NotImplementedError


def return_heatmap_data(df, method, drop_criteria):
    """Create and return a dictionary of specified correlations between df columns.

    This function is called from the return_heatmap method.
    Pairwise correlations between columns are calculated.

    Args:
    method: string. Method to be used for calculating correlation between df columns
            ('pearson', 'spearman' or 'kendall').
    drop_criteria: string or list of columns in df to be used for determining data to drop.
                  'any_rows': drops any rows in the data containing NaNs
                  'any_cols': drops any columns in the data containing NaNs
                  list: list of columns to be used for subset of drop_na function
                  None: no rows or columns with NaNs are dropped from the data

    Returns:
    heatmap_data: dictionary.  A dictionary of data required for heatmap figure created
    and returned by the return_heatmap method.
    """
    heatmap_data = {}
    if drop_criteria == 'any_rows':
        corr_data = df.dropna(axis=0, how='any')
        heatmap_data['drop_count'] = df.shape[0] - corr_data.shape[0]
        heatmap_data['title_text'] = 'rows'
    elif drop_criteria == 'any_cols':
        corr_data = df.dropna(axis=1, how='any')
        heatmap_data['drop_count'] = df.shape[1] - corr_data.shape[1]
        heatmap_data['title_text'] = 'columns'
    elif type(drop_criteria) == list:
        try:
            corr_data = df.dropna(axis=0, subset=drop_criteria)
            heatmap_data['drop_count'] = df.shape[0] - corr_data.shape[0]
            heatmap_data['title_text'
                ] = f"rows (subsetted on {', '.join(drop_criteria)}) Null values"
        except KeyError:
            print(
                'Specified column does not exist in data.  No Null values were dropped.'
                )
            corr_data = df.copy()
            heatmap_data['drop_count'] = 0
            heatmap_data['title_text'] = 'rows or columns'
    else:
        if drop_criteria != None:
            print(
                'Incorrect drop criteria specified.  No Null values were dropped.'
                )
        corr_data = df.copy()
        heatmap_data['drop_count'] = 0
        heatmap_data['title_text'] = 'rows or columns'
    heatmap_data['corrs'] = corr_data.corr(method)
    return heatmap_data


def _improve_answer_span(doc_tokens, input_start, input_end, tokenizer,
    orig_answer_text):
    """Returns tokenized answer spans that better match the annotated answer."""
    tok_answer_text = ' '.join(tokenizer.tokenize(orig_answer_text))
    for new_start in range(input_start, input_end + 1):
        for new_end in range(input_end, new_start - 1, -1):
            text_span = ' '.join(doc_tokens[new_start:new_end + 1])
            if text_span == tok_answer_text:
                return new_start, new_end
    return input_start, input_end


def _getVarLengths(data):
    """
    get the length of all the variables

    Parameters
    ----------
    data : SpaceData
        SpaceData object to return the length of the variables

    Returns
    -------
    data : dict
        dict of the names and lengths of a SpaceData
    """
    ans = {}
    for k, v in data.items():
        ans[k] = len(v)
    return ans


def set_pen_attr(element, attributes):
    """
    Set pen attributes.
    :param element:
    :param attributes:
    :return:
    """
    pen_attr = element.get('attr')
    if pen_attr is None:
        return {}
    else:
        return {'lineStyle': pen_attr.get('lineStyle'), 'lineWidth': float(
            pen_attr.get('lineWidth', '0')), 'lineColor': pen_attr.get(
            'lineColor')}


def getStationCoords(pbo_info, station_list):
    """
    Get the station coordinates for a list of stations

    @param pbo_info: PBO Metadata
    @param station_list: List of stations

    @return list of tuples containing lat, lon coordinates of stations
    """
    coord_list = []
    for station in station_list:
        lat = pbo_info[station]['refNEU'][0]
        lon = pbo_info[station]['refNEU'][1] - 360
        coord_list.append((lat, lon))
    return coord_list


@classmethod
def _get_BZ_integration_grid(cls, calc, **kwargs):
    """Return an array with Brillouin zone point counts along each vector of reciprocal lattice."""
    try:
        array, _ = calc.inputs.kpoints.get_kpoints_mesh()
        return array
    except AttributeError:
        return None
    except KeyError:
        return None


def _move_active_host_to_head(hosts, active_host):
    """
    to improve efficiency move active host to head
    """
    hosts.remove(active_host)
    hosts.insert(0, active_host)


@staticmethod
def create_reply(message, ephemeral=False) ->dict:
    """
        Create a reply suitable to send directly back to the invoking HTTP request

        Args:
          message: Text to send
          ephemeral: Whether the response should be limited to a single user, or to
                broadcast the reply (_and_ the user's original invocation) to the
                channel publicly
        """
    if ephemeral:
        return {'text': message, 'response_type': 'ephemeral'}
    else:
        return {'text': message, 'response_type': 'in_channel'}


@classmethod
def find_or_create(cls, _commit=True, **kwargs):
    """
        Find an object or, if it does not exist, create it.

        :param kwargs: the values of the object to find or create
        :type kwargs: dict
        :returns: the object that was created
        """
    obj = cls.find(**kwargs)
    if not obj:
        obj = cls.create(_commit=_commit, **kwargs)
    return obj


def register_handler(handler):
    """
    Install application-specific WMF image handler.

    :param handler: Handler object.
    """
    global _handler
    _handler = handler


def _handle_granularity_error(level):
    """
    Raises ValueError with detailed error message if one of the two situations is true:
      1. calculated granularity is less than minute (sec or ms)
      2. resampling is not enabled for situations where calculated granularity < min

      level : String
        the granularity that is below the min threshold
    """
    e_message = (
        '%s granularity is not supported. Ensure granularity => minute or enable resampling'
         % level)
    raise ValueError(e_message)


def timestamp_to_float(time):
    """Convert a pandas timestamp to a floating point date.

    >>> import datetime
    >>> time = datetime.date(2010, 10, 1)
    >>> timestamp_to_float(time)
    2010.75
    >>> time = datetime.date(2011, 4, 1)
    >>> timestamp_to_float(time)
    2011.25
    >>> timestamp_to_float(datetime.date(2011, 1, 1))
    2011.0
    >>> timestamp_to_float(datetime.date(2011, 12, 1)) == (2011.0 + 11.0 / 12)
    True
    """
    return time.year + (time.month - 1) / 12.0


def ReserveRate():
    """Valuation Reserve Rate per Sum Assured"""
    return None


def Edit_String_SimulData(data):
    """
    return string object made of lines which contains laue spots properties

    Called to be Edited in LaueToolsframe.control

    params:

    data tuple of spots properties
    data =(list_twicetheta, list_chi, list_energy, list_Miller, list_posX, list_posY,
           ListName, nb of(parent) grains,
            calibration parameters list, total nb of grains)
    """
    nb_total_grains = data[9]
    lines = 'Simulation Data from LAUE Pattern Program v1.0 2009 \n'
    lines += 'Total number of grains : %s\n' % int(nb_total_grains)
    lines += 'spot# h k l E 2theta chi X Y\n'
    nb = data[7]
    if isinstance(nb, int):
        nb_grains = data[7]
        TWT, CHI, ENE, MIL, XX, YY = data[:6]
        NAME = data[6]
        calib = data[8]
        for index_grain in range(nb_grains):
            nb_of_simulspots = len(TWT[index_grain])
            startgrain = '#G %d\t%s\t%d\n' % (index_grain, NAME[index_grain
                ], nb_of_simulspots)
            lines += startgrain
            for data_index in range(nb_of_simulspots):
                linedata = '%d\t%d\t%d\t%d\t%.5f\t%.4f\t%.4f\t%.4f\t%.4f\n' % (
                    data_index, MIL[index_grain][data_index][0], MIL[
                    index_grain][data_index][1], MIL[index_grain][
                    data_index][2], ENE[index_grain][data_index], TWT[
                    index_grain][data_index], CHI[index_grain][data_index],
                    XX[index_grain][data_index], YY[index_grain][data_index])
                lines += linedata
        lines += '#calibration parameters\n'
        for param in calib:
            lines += '# %s\n' % param
        return lines
    if isinstance(nb, list):
        print('nb in Edit_String_SimulData', nb)
        gen_i = 0
        TWT, CHI, ENE, MIL, XX, YY = data[:6]
        NAME = data[6]
        calib = data[8]
        for grain_ind in range(len(nb)):
            for tt in range(nb[grain_ind][1]):
                nb_of_simulspots = len(TWT[gen_i])
                startgrain = '#G %d\t%s\t%d\t%d\n' % (grain_ind, NAME[
                    grain_ind], tt, nb_of_simulspots)
                lines += startgrain
                for data_index in range(nb_of_simulspots):
                    linedata = (
                        '%d\t%d\t%d\t%d\t%.5f\t%.4f\t%.4f\t%.4f\t%.4f\n' %
                        (data_index, MIL[gen_i][data_index][0], MIL[gen_i][
                        data_index][1], MIL[gen_i][data_index][2], ENE[
                        gen_i][data_index], TWT[gen_i][data_index], CHI[
                        gen_i][data_index], XX[gen_i][data_index], YY[gen_i
                        ][data_index]))
                    lines += linedata
                gen_i += 1
        lines += '#calibration parameters\n'
        for param in calib:
            lines += '# %s\n' % param
        return lines


def transition_system(bdd):
    """Return the transition relation of a graph."""
    dvars = ['x0', "x0'", 'x1', "x1'"]
    for var in dvars:
        bdd.add_var(var)
    s = (
        "((!x0 & !x1) -> ( (!x0' & !x1') | (x0' & !x1') )) & ((x0 & !x1) -> ! (x0' & x1')) & ((!x0 & x1) -> ( (!x0' & !x1') | (x0' & x1') )) & ! (x0 & x1)"
        )
    transitions = bdd.add_expr(s)
    return transitions


def edowham(alpha_p, e_eff):
    """

    Calculate the elasticity parameter of the contact problem according to
    Dowson-Hamrock.

    Parameters
    ----------
    alpha_p: ndarray, scalar
        The pressure-viscosity coefficient of the lubricant.
    e_eff: ndarray, scalar
        The effective modulus of the contact problem.

    Returns
    -------
    param_elasticity: ndarray, scalar
        The elasticity parameter of the contact problem.

    """
    param_elasticity = alpha_p * e_eff
    return param_elasticity


@staticmethod
def add_callback(callback, control_instance):
    """ Method to add a callback to the control instance when the controller
        trait is modified

        Parameters
        ----------
        callback: @function (mandatory)
            the function that will be called when a 'textChanged' signal is
            emited.
        control_instance: QFrame (mandatory)
            the control widget we want to validate
        """
    pass


def negative(message, err='Please enter a negative number.', zero=True):
    """Command line input and error checking for negative numbers.

    Args:
        message (str): The input message displayed in the command line.
        err (str, optional): The message displayed for an erroneous input.
            Defaults to "Please enter a negative number.".
        zero (bool, optional): Zero status. True includes zero, False excludes
            zero. Defaults to True.

    Returns:
        float: The first sucessfully input negative number.
    """
    while True:
        data = input(message)
        data = data.strip()
        if data == '':
            print('Please provide an input.')
            continue
        try:
            data = float(data)
        except ValueError:
            print(err)
            continue
        if zero:
            if data > 0:
                print(err)
                continue
        elif data >= 0:
            print(err)
            continue
        return data


@staticmethod
def sanitize(value):
    """
        Measurements, tag keys, tag values, and field keys are always strings.
        For tag keys, tag values, and field keys always use a backslash character `\\` to escape:
        commas `,`, equal signas `=`, spaces.
        """
    return value.replace(',', '\\,').replace(' ', '\\ ').replace('=', '\\='
        ).lower()


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


@classmethod
def query_active_stop_ids(cls, session, limit=None, active_filter=True):
    """
        return an array of stop_id / agencies pairs
        {stop_id:'2112', agencies:['C-TRAN', 'TRIMET']}
        """
    ret_val = []
    stops = cls.query_active_stops(session, limit, active_filter)
    for s in stops:
        ret_val.append({'stop_id': s.stop_id, 'agencies': s.agencies})
    return ret_val


def triangleArea(a, b, c):
    """Calculates the area of a triangle spanned by three points.
    Note that the area will be negative if the points are not given in counter-clockwise order.

    Keyword arguments:
    a -- First point
    b -- Second point
    c -- Third point

    Returns:
    Area of triangle
    """
    return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1])


def writeFile(out_path, contents):
    """Write contents to file at given path"""
    with open(out_path, 'w') as out_file:
        out_file.write(contents)


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 write_curveball_csv(df, filename):
    """Reads growth measurements from a Curveball csv (comma separated values) file.

    Parameters
    ----------
    df : pandas.DataFrame, optional
        data frame to write
    filename : str
        path to the output file
    """
    df.to_csv(filename, index=False, encoding='utf8')


@staticmethod
def p_expression_number(p):
    """expression : CONST10
                      | CONST16"""
    p[0] = p[1]


def arg_to_dict(arg):
    """Convert an argument that can be None, list/tuple or dict to dict

    Example::

        >>> arg_to_dict(None)
        []
        >>> arg_to_dict(['a', 'b'])
        {'a':{},'b':{}}
        >>> arg_to_dict({'a':{'only': 'id'}, 'b':{'only': 'id'}})
        {'a':{'only':'id'},'b':{'only':'id'}}

    :return: dict with keys and dict arguments as value
    """
    if arg is None:
        arg = []
    try:
        arg = dict(arg)
    except ValueError:
        arg = dict.fromkeys(list(arg), {})
    return arg


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def diff_ignore(*args, **kwargs):
    """Always returns an empty diff"""
    return []


def itervalues():
    """iterate over values"""


def count(text, keyword):
    """
    获取keyword在text中的个数
    :param text: 文章
    :param keyword: 字符串
    :return: 个数
    """
    return text.count(keyword)


def uniform_disk(a):
    """Return the standard uncertainty for a uniform disk

    :arg float a: the radius

    Convert the radius of a uniform disk distribution ``a``
    to a standard uncertainty.

    See reference: B D Hall, *Metrologia* **48** (2011) 324-332

    **Example**::

        >>> z = ucomplex( 0, type_b.uniform_disk(1) )
        >>> z
        ucomplex((0+0j), u=[0.5,0.5], r=0.0, df=inf)

    """
    return a / 2.0