def append_to_path(uri, path):
    """
    This is a helper function for appending a path to a URI (i.e, just the path portion
    of a full URL).  The main purpose is to make sure one and only one slash ends up between them.

    :param uri: the URI to append the path to.
    :param path: the path to append.
    :return: the result of the append.
    """
    if uri.endswith('/') and path.startswith('/'):
        uri += path[1:]
    elif not (uri.endswith('/') or path.startswith('/')):
        uri = uri + '/' + path
    else:
        uri += path
    return uri


def chars_to_ranges(s):
    """
    Return a list of character codes consisting of pairs
    [code1a, code1b, code2a, code2b,...] which cover all
    the characters in |s|.
    """
    char_list = list(s)
    char_list.sort()
    i = 0
    n = len(char_list)
    result = []
    while i < n:
        code1 = ord(char_list[i])
        code2 = code1 + 1
        i = i + 1
        while i < n and code2 >= ord(char_list[i]):
            code2 = code2 + 1
            i = i + 1
        result.append(code1)
        result.append(code2)
    return result


@classmethod
def create_write(cls, value):
    """ Create a new write capacity from a response """
    return cls(0, value['CapacityUnits'])


def _most_constraining(constraining, target_aspect):
    """Find most constraining dimension to scale."""
    if constraining[0] / float(constraining[1]) >= target_aspect[0] / float(
        target_aspect[1]):
        return 1
    else:
        return 0


@classmethod
def get_real_child_model(cls, data):
    """Returns the real base class specified by the discriminator"""
    discriminator_value = data[cls.json_discriminator_key]
    return cls.discriminator_value_class_map.get(discriminator_value)


def assert_inequivalent(o1, o2):
    """Asserts that o1 and o2 are distinct and inequivalent objects
    """
    if not (isinstance(o1, type) and isinstance(o2, type)):
        assert o1 is not o2
    assert not o1 == o2 and o1 != o2
    assert not o2 == o1 and o2 != o1


def fitsdate(date):
    """
-----------------------------------------------------------------------
Purpose:   Given a string from a FITS file, try to parse it and
           convert the string into three parts: an integer year, an
           integer month and a fractional day.
Input:     A string, representing a date in FITS format
Returns:   Integer year, integer month, fractional day.
Reference: -
Notes:     Process the FITS dates as part of the 'epochs' function.
           It processes the following formats:
           DD/MM/YY or DD/MM/19YY
           YYYY-MM-DD
           YYYY-MM-DDTHH:MM:SS
-----------------------------------------------------------------------
   """
    parts = date.split('/')
    if len(parts) == 3:
        return int(parts[2]) % 1900 + 1900, int(parts[1]), float(parts[0])
    parts = date.split('T')
    if len(parts) == 2:
        date = parts[0]
        parts = parts[1].split(':')
        facts = 3600.0, 60.0, 1.0
        time = 0.0
        for i in range(len(parts)):
            time += float(parts[i]) * facts[i]
    else:
        time = 0.0
    parts = date.split('-')
    return int(parts[0]), int(parts[1]), float(parts[2]) + time / 86400.0


def generate_role_with_colon_format(content, defined_role, generated_role):
    """Generate role data with input as Compute:ComputeA

    In Compute:ComputeA, the defined role 'Compute' can be added to
    roles_data.yaml by changing the name to 'ComputeA'. This allows duplicating
    the defined roles so that hardware specific nodes can be targeted with
    specific roles.

    :param content defined role file's content
    :param defined_role defined role's name
    :param generated_role role's name to generate from defined role
    :exception ValueError if generated role name is of invalid format
    """
    if generated_role == defined_role:
        msg = (
            'Generated role name cannot be same as existing role name (%s) with colon format'
            .format(defined_role))
        raise ValueError(msg)
    if not generated_role.startswith(defined_role):
        msg = (
            'Generated role name (%s) name should start with existing role name (%s)'
            .format(generated_role, defined_role))
        raise ValueError(msg)
    name_line = 'name:%s' % defined_role
    name_line_match = False
    processed = []
    for line in content.split('\n'):
        stripped_line = line.replace(' ', '')
        if name_line in stripped_line:
            line = line.replace(defined_role, generated_role)
            name_line_match = True
        processed.append(line)
    if not name_line_match:
        raise ValueError(' error')
    return '\n'.join(processed)


def getMid(elem):
    """Get mid xyz coordinates given a pyNastran Element
    """
    return elem.get_node_positions().mean(axis=0)


def escape_float(value):
    """
    Python's float are usually double:
    https://docs.python.org/3.6/library/stdtypes.html#numeric-types-int-float-complex
    """
    return '"%s"^^xsd:double' % value


def camel_case_to_lower_case_underscore(string):
    """
    Split string by upper case letters.
    F.e. useful to convert camel case strings to underscore separated ones.
    @return words (list)
    """
    words = []
    from_char_position = 0
    for current_char_position, char in enumerate(string):
        if char.isupper() and from_char_position < current_char_position:
            words.append(string[from_char_position:current_char_position].
                lower())
            from_char_position = current_char_position
    words.append(string[from_char_position:].lower())
    return '_'.join(words)


def negate(grads):
    """Negates the gradients.

    Args:
        grads: A numpy array of grads to use.

    Returns:
        The negated gradients.
    """
    return -grads


def generate_script(group, entry_point, header, template):
    """Generate the script based on the template.

    :param str group:
        The entry-point group name, e.g., "console_scripts".
    :param str header:
        The first line of the script, e.g., "!#/usr/bin/env python".
    :param str template:
        The script template.
    :returns:
        The templated script content
    :rtype:
        str
    """
    if not entry_point.attrs or len(entry_point.attrs) > 2:
        raise ValueError(
            "Script targets must be of the form 'func' or 'Class.class_method'."
            )
    script_text = template % dict(group=group, module_name=entry_point.
        module_name, import_target=entry_point.attrs[0], invoke_target='.'.
        join(entry_point.attrs))
    return header + script_text


def SizeBenefitSickHosp(t):
    """Sickness hospitalization benefit per policy"""
    return 0


def __delitem__(name, obj):
    """Add the named subclass to the mapping of subclasses"""


@classmethod
def from_stream(cls, stream, marker_code, offset):
    """
        Return an |_SofMarker| instance for the SOFn marker at *offset* in
        stream.
        """
    segment_length = stream.read_short(offset)
    px_height = stream.read_short(offset, 3)
    px_width = stream.read_short(offset, 5)
    return cls(marker_code, offset, segment_length, px_width, px_height)


@classmethod
def rgb(cls, r, g, b, a=255):
    """Convert rgba to KML hex value.

        Args:
          * r: int between 0 - 255 representing red
          * g: int between 0 - 255 representing green
          * b: int between 0 - 255 representing blue
          * a: int between 0 - 255 representing alpha (default 255)
        """
    return '%0.2x%0.2x%0.2x%0.2x' % (a, b, g, r)


def get_f0_length(f0):
    """Get non Python list F0's length

    Args:
        f0 (POINTER(c_double)): F0

    Returns:
        int: F0 length
    """
    return len(list(f0))


def driver_button_remove(all: bool=True):
    """Remove the driver(s) for the property(s) connected represented by the highlighted button

    :param all: All, Delete drivers for all elements of the array
    :type all: bool
    """
    pass


def filter_blank_dfs(dfs):
    """Filters a list of dataframes to remove those without data"""
    is_blank = lambda df: df is not None and len(df.dropna())
    return filter(is_blank, dfs)


def AdvectionRK4_3D(particle, fieldset, time):
    """Advection of particles using fourth-order Runge-Kutta integration including vertical velocity.

    Function needs to be converted to Kernel object before execution"""
    u1, v1, w1 = fieldset.UVW[time, particle.depth, particle.lat, particle.lon]
    lon1 = particle.lon + u1 * 0.5 * particle.dt
    lat1 = particle.lat + v1 * 0.5 * particle.dt
    dep1 = particle.depth + w1 * 0.5 * particle.dt
    u2, v2, w2 = fieldset.UVW[time + 0.5 * particle.dt, dep1, lat1, lon1]
    lon2 = particle.lon + u2 * 0.5 * particle.dt
    lat2 = particle.lat + v2 * 0.5 * particle.dt
    dep2 = particle.depth + w2 * 0.5 * particle.dt
    u3, v3, w3 = fieldset.UVW[time + 0.5 * particle.dt, dep2, lat2, lon2]
    lon3 = particle.lon + u3 * particle.dt
    lat3 = particle.lat + v3 * particle.dt
    dep3 = particle.depth + w3 * particle.dt
    u4, v4, w4 = fieldset.UVW[time + particle.dt, dep3, lat3, lon3]
    particle.lon += (u1 + 2 * u2 + 2 * u3 + u4) / 6.0 * particle.dt
    particle.lat += (v1 + 2 * v2 + 2 * v3 + v4) / 6.0 * particle.dt
    particle.depth += (w1 + 2 * w2 + 2 * w3 + w4) / 6.0 * particle.dt


@staticmethod
def generate_command(dag_id, task_id, execution_date, mark_success=False,
    ignore_all_deps=False, ignore_depends_on_past=False, ignore_task_deps=
    False, ignore_ti_state=False, local=False, pickle_id=None, file_path=
    None, raw=False, job_id=None, pool=None, cfg_path=None):
    """
        Generates the shell command required to execute this task instance.

        :param dag_id: DAG ID
        :type dag_id: unicode
        :param task_id: Task ID
        :type task_id: unicode
        :param execution_date: Execution date for the task
        :type execution_date: datetime
        :param mark_success: Whether to mark the task as successful
        :type mark_success: bool
        :param ignore_all_deps: Ignore all ignorable dependencies.
            Overrides the other ignore_* parameters.
        :type ignore_all_deps: boolean
        :param ignore_depends_on_past: Ignore depends_on_past parameter of DAGs
            (e.g. for Backfills)
        :type ignore_depends_on_past: boolean
        :param ignore_task_deps: Ignore task-specific dependencies such as depends_on_past
            and trigger rule
        :type ignore_task_deps: boolean
        :param ignore_ti_state: Ignore the task instance's previous failure/success
        :type ignore_ti_state: boolean
        :param local: Whether to run the task locally
        :type local: bool
        :param pickle_id: If the DAG was serialized to the DB, the ID
            associated with the pickled DAG
        :type pickle_id: unicode
        :param file_path: path to the file containing the DAG definition
        :param raw: raw mode (needs more details)
        :param job_id: job ID (needs more details)
        :param pool: the Airflow pool that the task should run in
        :type pool: unicode
        :return: shell command that can be used to run the task instance
        """
    iso = execution_date.isoformat()
    cmd = ['airflow', 'run', str(dag_id), str(task_id), str(iso)]
    cmd.extend(['--mark_success']) if mark_success else None
    cmd.extend(['--pickle', str(pickle_id)]) if pickle_id else None
    cmd.extend(['--job_id', str(job_id)]) if job_id else None
    cmd.extend(['-A']) if ignore_all_deps else None
    cmd.extend(['-i']) if ignore_task_deps else None
    cmd.extend(['-I']) if ignore_depends_on_past else None
    cmd.extend(['--force']) if ignore_ti_state else None
    cmd.extend(['--local']) if local else None
    cmd.extend(['--pool', pool]) if pool else None
    cmd.extend(['--raw']) if raw else None
    cmd.extend(['-sd', file_path]) if file_path else None
    cmd.extend(['--cfg_path', cfg_path]) if cfg_path else None
    return cmd


def update_toc(toc, channel, name='GW'):
    """Add a channel to the page table of contents

    Parameters
    ----------
    toc : `dict`
        dictionary used as table of contents for a bootstrap page

    channel : `OmegaChannel`
        channel to be added to `toc`

    name : `str`, optional
        name of a channel's block, default: `'GW'`

    Returns
    -------
    out : `dict`
        the updated dictionary
    """
    out = toc
    try:
        out[channel.section]['channels'].append(channel)
    except KeyError:
        out[channel.section] = {'name': name, 'channels': [channel]}
    return out


def cmp(node, fulltext):
    """Compare fulltext to another revision.

        Returns True if the fulltext is different from what is stored.
        """


def get_config_for(args, component, prefix=''):
    """ Returns a dictionary of option value for a given component

    See :func:`arguments_from_optionable` documentation
    """
    config = {}
    vargs = vars(args)
    for option in component.options:
        if component.options[option].hidden:
            continue
        config[option] = vargs['%s%s' % (prefix, option)]
    return config


def anti_strand(strand):
    """
    Return the opposite strand
    Arguments:
    - `strand`: + or -
    """
    if strand == '+':
        return '-'
    else:
        return '+'


@staticmethod
def explain(formula):
    """
        разбить на части
        """
    level = 0
    formula1, formula2 = '', ''
    sub_formules = 1
    for alfa in formula:
        if alfa == '[':
            level += 1
        if alfa == ']':
            level -= 1
        if alfa == '~' and not level:
            sub_formules += 1
        elif sub_formules == 1:
            formula1 += alfa
        elif sub_formules == 2:
            formula2 += alfa
    return [formula1, formula2]


def drivers_delete_selected():
    """Delete drivers assigned to selected items

    """
    pass


@classmethod
def to(cls, method, path, view, endpoint=None, **kwargs):
    """Route a method+path to a view function.
        """
    return cls([method], path, view, endpoint_=endpoint, kwargs=kwargs)


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

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


@staticmethod
def k_safety(n):
    """
        Vertica defines k-safety values of 0, 1 or 2:
        https://my.vertica.com/docs/7.1.x/HTML/Content/Authoring/Glossary/
        K-Safety.htm
        """
    if n < 3:
        return 0
    elif n < 5:
        return 1
    else:
        return 2


def inside_box_boundaries(x, lb, ub):
    """Check if lb <= x <= ub."""
    return (lb <= x).all() and (x <= ub).all()


def control_value(f):
    """ Return the value of a control field (arg1). """
    return f[3][1]


def set_bit(index: int, value: int=0) ->int:
    """
    Set the bit on index to one.

    Parameters
    ----------
    index : int
        The index of the bit to set to one
    value : int
        The initial byte (as int) in which to set the index bit to one (default=0x00)

    Returns
    -------
    int
        The changed value (with the set bit)
    """
    return value | 1 << index


def encode_reference_new(val):
    """Encode python's Reference() class to erlang term REFERENCE_EXT."""
    return val.encode()


def get_default_params(dim: int) ->dict:
    """
        Returns the default parameters of the Multi-population ensemble DE (MPEDE)
        :param dim: Size of the problem (or individual).
        :type dim: int
        :return: Dict with the default parameters of the MPEDE Differential
        Evolution Algorithm.
        :rtype dict
        """
    pop_size = 250
    return {'max_evals': 10000 * dim, 'individual_size': dim, 'callback':
        None, 'population_size': pop_size, 'seed': None, 'lambdas': [0.2,
        0.2, 0.2, 0.4], 'ng': 20, 'c': 0.1, 'p': 0.04, 'opts': None}


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

        :param PasswordResetType val:
        :rtype: EventType
        """
    return cls('password_reset', val)


def formatError(error):
    """
    Format an error as a string. Write the error type as prefix.
    Eg. "[ValueError] invalid value".
    """
    return '[%s] %s' % (error.__class__.__name__, error)


def merge_dicts(dict1, dict2):
    """
    Merge 2 dictionaries.
    """
    merged = dict1.copy()
    merged.update(dict2)
    return merged


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

        :param str val:
        :rtype: LaunchResultBase
        """
    return cls('async_job_id', val)


def format_cvrect(cvrect):
    """Cvrect to tuple.

    tuple: left, top, width, height
    """
    return '%d,%d,%d,%d' % (cvrect.left, cvrect.top, cvrect.width, cvrect.
        height)


def read(path):
    """Read a text file.

    Args:
        path (str): Full path to file

    Returns:
        str: File text
    """
    with open(path, 'r') as handle:
        return handle.read()


def drange(start, stop, step=1):
    """
    Creates lists containing arithmetic progressions of any number type (int,
    float, ...)
    """
    r = start
    while r < stop:
        yield r
        r += step


@staticmethod
def lazy_and(first_should_trigger, second_should_trigger, dt):
    """
        Lazily ands the two rules. This will NOT call the should_trigger of the
        second rule if the first one returns False.
        """
    return first_should_trigger(dt) and second_should_trigger(dt)


@classmethod
def delete(cls, options=None):
    """Deletes existing record."""
    cls.command_sub = 'delete'
    return cls.execute(cls._construct_command(options), ignore_stderr=True)


@classmethod
def aggregate(cls, columns, kdims, function, **kwargs):
    """
        Aggregation currently not implemented.
        """
    raise NotImplementedError


@staticmethod
def make(id, client, cls, parent_id=None, json=None):
    """
        Makes an api object based on an id and class.

        :param id: The id of the object to create
        :param client: The LinodeClient to give the new object
        :param cls: The class type to instantiate
        :param parent_id: The parent id for derived classes
        :param json: The JSON to use to populate the new class

        :returns: An instance of cls with the given id
        """
    from .dbase import DerivedBase
    if issubclass(cls, DerivedBase):
        return cls(client, id, parent_id, json)
    else:
        return cls(client, id, json)


@classmethod
def match_header(cls, header):
    """
        This is an abstract HDU type for HDUs that contain table-like data.
        This is even more abstract than _TableBaseHDU which is specifically for
        the standard ASCII and Binary Table types.
        """
    raise NotImplementedError


def migrate(engine):
    """Return the number of rows migrated."""
    return 0


def selective_find(str, char, index, pos):
    """Return a pair (index, pos), indicating the next occurrence of
    char in str. index is the position of the character considering
    only ordinals up to and including char, and pos is the position in
    the full string. index/pos is the starting position in the full
    string."""
    l = len(str)
    while 1:
        pos += 1
        if pos == l:
            return -1, -1
        c = str[pos]
        if c == char:
            return index + 1, pos
        elif c < char:
            index += 1


@staticmethod
def remainder_by_divisor(expected, divisor):
    """Shortcut to get the remainder from the expected length.

        Since several input formats are chunked in even, multi-bit
        blocks, sometimes ending bits need to be sliced off in order to
        reproduce the original token.

        The resulting remainder is that number of bits.

        Args:
            expected (int): Length of expected public token.
            divisor (int): Multible by which the input data format is
                chunked by.

        Returns:
            int: from 0 to divisor - 1.

        """
    mod = expected % divisor
    if mod:
        return divisor - mod
    return 0


def match_edge(u_var, v_var, u_id, v_id, edge_var, u_label, v_label,
    edge_label='edge'):
    """Query for matching an edge.

    Parameters
    ----------
    u_var
        Name of the variable corresponding to the source of
        the edge
    v_var
        Name of the variable corresponding to the target of
        the edge
    u_id
        Id of the source node
    v_id
        Id of the target node
    edge_var
        Name of the variable to use for the matched edge
    label
        Label of the edge to match, default is 'edge'
    """
    query = ("MATCH ({}:{} {{id: '{}'}})-[{}:{}]->({}:{} {{id: '{}'}})\n".
        format(u_var, u_label, u_id, edge_var, edge_label, v_var, v_label,
        v_id))
    return query


def state_class_str(state):
    """Return a string describing an instance's class via its
    InstanceState.
    """
    if state is None:
        return 'None'
    else:
        return '<%s>' % (state.class_.__name__,)


@classmethod
def get_pseudopotential_atom_type(cls, calc, **kwargs):
    """Return a list of atom types.

        Each atom type MUST occur only once in this list. List MUST be sorted.
        """
    raw_types = cls._get_raw_pseudopotential_type(calc, **kwargs)
    return sorted(raw_types)


def article_date(value):
    """
    Convert a date to the format we want it displayed on the article template.

    Format looks like --> Friday, November 4, 2016

    Args:
        value (datetime.datetime): input date

    Returns:
        str: value, formatted nicely for displaying the date.
    """
    return value.strftime('%A, %B %-d, %Y')


def pull_unmapped_entrez_records(entrez_records: list):
    """
    Prepares a list of accession identifiers for EntrezRecord instances where the bitflag is not equal to 7,
     inferring lineage information was not properly entered.
    :param entrez_records: A list of EntrezRecord instances
    :return: List of EntrezRecords with bitflag != 7
    """
    unmapped_queries = list()
    x = 0
    while x < len(entrez_records):
        e_record = entrez_records[x]
        e_record.tracking_stamp()
        if e_record.bitflag < 6:
            unmapped_queries.append(e_record)
            entrez_records.pop(x)
        else:
            x += 1
    return unmapped_queries


def genebody_coverage(samfile, chrom, positions, bg_level=0):
    """
	calculate coverage for each nucleotide in *positions*. some times len(cvg) < len(positions)
	because positions where there is no mapped reads were ignored.
	"""
    cvg = []
    start = positions[0] - 1
    end = positions[-1]
    try:
        for pileupcolumn in samfile.pileup(chrom, start, end, truncate=True):
            ref_pos = pileupcolumn.pos + 1
            if ref_pos not in positions:
                continue
            if pileupcolumn.n == 0:
                cvg.append(0.0)
                continue
            cover_read = 0.0
            for pileupread in pileupcolumn.pileups:
                if pileupread.is_del:
                    continue
                if pileupread.alignment.is_qcfail:
                    continue
                if pileupread.alignment.is_secondary:
                    continue
                if pileupread.alignment.is_unmapped:
                    continue
                cover_read += 1.0
            cvg.append(cover_read)
    except:
        cvg = []
    if bg_level <= 0:
        return cvg
    else:
        tmp = []
        for i in cvg:
            subtracted_sig = int(i - bg_level)
            if subtracted_sig > 0:
                tmp.append(subtracted_sig)
            else:
                tmp.append(0)
        return tmp


def _load_from_file(module_path):
    """
    Load a python module from its absolute filesystem path
    """
    from imp import load_module, PY_SOURCE
    imported = None
    if module_path:
        with open(module_path, 'r') as openfile:
            imported = load_module('mod', openfile, module_path, (
                'imported', 'r', PY_SOURCE))
    return imported


def thumbnail(filename, thname, size, fformat):
    """Create a thumbnail image and save it.
    """
    from PIL import Image
    img = Image.open(filename)
    img.thumbnail(size, Image.ANTIALIAS)
    img.save(thname, fformat)


def app_url():
    """The absolute URL of the app, based on `self.app`.
        """


def binipdisplay(s):
    """convert a binary array of ip adresses to a python list"""
    if len(s) % 4 != 0:
        raise EnvironmentError
    ol = []
    s = '.'
    for i in range(int(len(s) / 4)):
        s1 = s[:4]
        s = s[4:]
        ip = []
        for j in s1:
            ip.append(str(ord(j)))
        ol.append(s.join(ip))
    return ol


def rpc_command(method):
    """Decorator to declare an RPC command."""
    method.is_rpc_command = True
    return method


def unquote(s: str) ->str:
    """ Remove starting and ending quotes, only if quoted on both sides

    :param s: String to strip leading/trailing quotes from
    """
    if len(s) < 2:
        return s
    start_char, end_char = s[0], s[-1]
    if start_char == end_char and start_char in {'"', "'"}:
        return s.strip(start_char)
    else:
        return s


def key_exists(bucket, key):
    """Given a bucket and a key name, return True if the key exists."""
    return bucket.get_key(key) is not None


def __hash__():
    """
        Weak references should be suitable for hashing.
        If possible, they should hash the same as the underlying object.
        """


def getNibbles(byte):
    """
    Returns hi and lo bits in a byte as a tuple

    .. doctest::

        >>> getNibbles(142)
        (8, 14)

        Asserts byte value in byte range
        >>> getNibbles(256)
        Traceback (most recent call last):
        ...
        ValueError: Byte value out of range 0-255: 256
    """
    if not 0 <= byte <= 255:
        raise ValueError('Byte value out of range 0-255: %s' % byte)
    return byte >> 4 & 15, byte & 15


def read_cstr(file):
    """read zero terminated c string from file"""
    output = ''
    while True:
        char = file.read(1)
        if len(char) == 0:
            raise RuntimeError('EOF while reading cstr')
        char = chr(bytes(char)[0])
        if char == '\x00':
            break
        output += char
    return output


def p_statement_empty(p):
    """statement : SEMI"""
    pass


def delete_api_key(apiKey=None):
    """
    Deletes the  ApiKey resource.
    See also: AWS API Documentation

    :example: response = client.delete_api_key(
        apiKey='string'
    )

    :type apiKey: string
    :param apiKey: [REQUIRED]
            The identifier of the ApiKey resource to be deleted.

    """
    pass


def read_key(pysam_alignment_record):
    """
    Given a `pysam.AlignedSegment` instance, return the attributes identifying
    the *read* it comes from (not the alignment). There may be more than one
    alignment for a read, e.g. chimeric and secondary alignments.
    """
    return (pysam_alignment_record.query_name, pysam_alignment_record.
        is_duplicate, pysam_alignment_record.is_read1,
        pysam_alignment_record.is_read2)


@staticmethod
def parse(payload, candidate_classes):
    """ Parse a json response into an intent.

        :param payload: a JSON object representing an intent.
        :param candidate_classes: a list of classes representing various
                                  intents, each having their own `parse`
                                  method to attempt parsing the JSON object
                                  into the given intent class.
        :return: An object version of the intent if one of the candidate
                 classes managed to parse it, or None.
        """
    for cls in candidate_classes:
        intent = cls.parse(payload)
        if intent:
            return intent
    return None


@staticmethod
def setValue(value: int):
    """ Replacement for real progress bar: print """
    print('{}%..'.format(value), end='')


def load_scipy(finder, module):
    """the scipy module loads items within itself in a way that causes
       problems without the entire package and a number of other subpackages
       being present."""
    finder.IncludePackage('scipy._lib')
    finder.IncludePackage('scipy.misc')


def initialize_stats_dict(individual):
    """
    Initializes the stats dict for individual
    The statistics initialized are:
        'generation': generation in which the individual was evaluated. Initialized as: 0
        'mutation_count': number of mutation operations applied to the individual and its predecessor cumulatively. Initialized as: 0
        'crossover_count': number of crossover operations applied to the individual and its predecessor cumulatively. Initialized as: 0
        'predecessor': string representation of the individual. Initialized as: ('ROOT',)

    Parameters
    ----------
    individual: deap individual

    Returns
    -------
    object
    """
    individual.statistics['generation'] = 0
    individual.statistics['mutation_count'] = 0
    individual.statistics['crossover_count'] = 0
    individual.statistics['predecessor'] = 'ROOT',


def Reset():
    """Reset global state.  Used by unit tests that end up using
    SConsign multiple times to get a clean slate for each test."""
    global sig_files, DB_sync_list
    sig_files = []
    DB_sync_list = []


def mod_relpath(target_modpath: str, base_modpath: str) ->str:
    """ get relative path to `target_modpath` from `base_modpath`

    i.g.
        Args:
            `target_modpath`: nayvy.importing.import_statement
            `base_modpath`: nayvy.projects.path
        Returns:
            ..importing.import_statement
    """
    if target_modpath == base_modpath:
        return '.'
    target_path_elms = target_modpath.split('.')
    base_path_elms = base_modpath.split('.')
    if target_path_elms[0] != base_path_elms[0]:
        return target_modpath
    common_elm_num = 0
    for target_elm, base_elm in zip(target_path_elms, base_path_elms):
        if target_elm != base_elm:
            break
        common_elm_num += 1
    return '.' * (len(base_path_elms) - common_elm_num) + '.'.join(
        target_path_elms[common_elm_num:])


def set_col_bnds(me, xid, bt, lo, hi):
    """set_col_bnds with transparent index mapping."""
    xid = me._colmap.map(xid) if xid else xid
    if xid > 0:
        return me._set_col_bnds(xid, bt, lo, hi)


def _must_key_val_matches(must_key_vals, test_tags, include_empty_key):
    """
    Checks if the required key:vals are fulfilled by the test_tags

    :rtype: bool
    """
    key_val_test_tags = {}
    for k, v in test_tags.items():
        if v is None:
            continue
        key_val_test_tags[k] = v
    for k, v in must_key_vals.items():
        if k not in test_tags:
            if include_empty_key:
                continue
            else:
                return False
        if v not in key_val_test_tags.get(k, set()):
            return False
    return True


def getVarTotalKeeton(varZ, varZFinal, EofZ, EofZFinal, EofZZFinal):
    """
	Get total variance from NS loop and final contributions.
	For recursive method, since E[ZLive] = E[ZTot] etc.,
	and assuming that the recurrence relations account for the covariance between
	Z and ZFinal, this is just varZFinal.
	For Keeton's method, have to explicitly account for correlation as expectations for Z and ZLive are essentially calculated independently
	TODO: check if recurrence relations of Z and ZFinal properly account for correlation between two  ANSWER: they do not
	"""
    return varZ + varZFinal + 2.0 * (EofZZFinal - EofZ * EofZFinal)


@classmethod
def from_description(cls, description, default_key_length=None):
    """Load key info from key info description.

        :param str description: Key info description
        :param int default_key_length: Key length to use if not found in description
        """
    description_parts = description.split('/', 1)
    algorithm = description_parts[0]
    try:
        key_length = int(description_parts[1])
    except IndexError:
        if default_key_length is None:
            raise ValueError(
                'Description "{}" does not contain key length and no default key length is provided'
                .format(description))
        key_length = default_key_length
    return cls(description, algorithm, key_length)


def cmp(a, b):
    """
    Compare two objects.

    Returns 1 if a > b, returns -1 if b > a, returns 0 if they're equal.
    """
    return (a > b) - (a < b)


def check_bar_match(old_bar, new_bar):
    """Check if two bars belong in the same collection (bar chart).

    Positional arguments:
    old_bar -- a previously sorted bar dictionary.
    new_bar -- a new bar dictionary that needs to be sorted.

    """
    tests = []
    tests += new_bar['orientation'] == old_bar['orientation'],
    tests += new_bar['facecolor'] == old_bar['facecolor'],
    if new_bar['orientation'] == 'v':
        new_width = new_bar['x1'] - new_bar['x0']
        old_width = old_bar['x1'] - old_bar['x0']
        tests += new_width - old_width < 1e-06,
        tests += new_bar['y0'] == old_bar['y0'],
    elif new_bar['orientation'] == 'h':
        new_height = new_bar['y1'] - new_bar['y0']
        old_height = old_bar['y1'] - old_bar['y0']
        tests += new_height - old_height < 1e-06,
        tests += new_bar['x0'] == old_bar['x0'],
    if all(tests):
        return True
    else:
        return False


def frame_jump(end: bool=False):
    """Jump to first/last frame in frame range

    :param end: Last Frame, Jump to the last frame of the frame range
    :type end: bool
    """
    pass


@classmethod
def init(cls, *args, **kwargs):
    """Fabric to build fields."""
    return cls(*args, **kwargs).get_field()


def BJD2BKJD(bjd):
    """convert BJD to BKJD"""
    return bjd - 2454833.0


def is_proxy(obj):
    """ Return True if `obj` is an array proxy
    """
    try:
        return obj.is_proxy
    except AttributeError:
        return False


def store_multiple(option, opt, value, parser, *args, **kwargs):
    """
    Store multiple values in `parser.values`.  (Option callback.)

    Store `None` for each attribute named in `args`, and store the value for
    each key (attribute name) in `kwargs`.
    """
    for attribute in args:
        setattr(parser.values, attribute, None)
    for key, value in list(kwargs.items()):
        setattr(parser.values, key, value)


def parse_geometry(geometry):
    """
     GeoJSON order is [longitude, latitude, elevation].

    :param geometry: Is a list of coordinates in latLng order
    :type geometry: list

    :return: returns a list of coordinates in lngLat order for geojson
    :type: list
    """
    geom = []
    for coords in geometry:
        geom.append((float(coords[0]), float(coords[1])))
    return geom


def import_class(klass):
    """Import the named class and return that class"""
    mod = __import__(klass.rpartition('.')[0])
    for segment in klass.split('.')[1:-1]:
        mod = getattr(mod, segment)
    return getattr(mod, klass.rpartition('.')[2])


def getPermissionsForRole(role_id):
    """Get the premissions granted to a role.

        Return a sequence of (permission id, setting) tuples for the given
        role.

        If no permissions have been granted to this
        role, then the empty list is returned.
        """


def index(lista, co):
    """.index with on absolute values"""
    for i in range(len(lista)):
        if abs(lista[i]) == co:
            return i
    else:
        raise IndexError


def addcapabilities(repo, caps):
    """Adds advertised capabilities specific to this protocol.

        Receives the list of capabilities collected so far.

        Returns a list of capabilities. The passed in argument can be returned.
        """


@staticmethod
def _list_element_starts_with(items, needle):
    """True of any of the list elements starts with needle"""
    for item in items:
        if item.startswith(needle):
            return True
    return False


def update_max_extent(maximum_extent, extent):
    """Update the *maximum_extent* to cover also *extent*"""
    if maximum_extent is None:
        maximum_extent = extent
    else:
        if maximum_extent[0] > extent[0]:
            maximum_extent[0] = extent[0]
        if maximum_extent[1] > extent[1]:
            maximum_extent[1] = extent[1]
        if maximum_extent[2] < extent[2]:
            maximum_extent[2] = extent[2]
        if maximum_extent[3] < extent[3]:
            maximum_extent[3] = extent[3]
    return maximum_extent


def nt_escape(node_string):
    """Properly escape strings for n-triples and n-quads serialization."""
    output_string = ''
    for char in node_string:
        if char == u'\t':
            output_string += '\\t'
        elif char == u'\n':
            output_string += '\\n'
        elif char == u'\r':
            output_string += '\\r'
        elif char == u'"':
            output_string += '\\"'
        elif char == u'\\':
            output_string += '\\\\'
        elif char >= u' ' and char <= u'!' or char >= u'#' and char <= u'[' or char >= u']' and char <= u'~':
            output_string += char
        elif char >= u'\x7f' and char <= u'\uffff':
            output_string += '\\u%04X' % ord(char)
        elif char >= u'𐀀' and char <= u'\U0010ffff':
            output_string += '\\U%08X' % ord(char)
    return output_string


def prod(x, y, log, alog, gf):
    """ Product x times y """
    if not x or not y:
        return 0
    return alog[(log[x] + log[y]) % (gf - 1)]


def egcd(b, n):
    """
    Given two integers (b, n), returns (gcd(b, n), a, m) such that
    a*b + n*m = gcd(b, n).

    Adapted from several sources:
      https://brilliant.org/wiki/extended-euclidean-algorithm/
      https://rosettacode.org/wiki/Modular_inverse
      https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm
      https://en.wikipedia.org/wiki/Euclidean_algorithm

    >>> egcd(1, 1)
    (1, 0, 1)
    >>> egcd(12, 8)
    (4, 1, -1)
    >>> egcd(23894798501898, 23948178468116)
    (2, 2437250447493, -2431817869532)
    >>> egcd(pow(2, 50), pow(3, 50))
    (1, -260414429242905345185687, 408415383037561)

    """
    x0, x1, y0, y1 = 1, 0, 0, 1
    while n != 0:
        q, b, n = b // n, n, b % n
        x0, x1 = x1, x0 - q * x1
        y0, y1 = y1, y0 - q * y1
    return b, x0, y0


def get_system_info():
    """Yield a sequence of `(name, version)` tuples describing the
        name and version information of external packages used by a
        component.
        """


def configureSet(request):
    """
        Called when a node configuration change request has been received.

        @param request: The publish-subscribe request.
        @type request: L{wokkel.pubsub.PubSubRequest}
        @return: A deferred that fires with C{None} when the node's
                 configuration has been changed.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def unique(seq, idfun=None):
    """Get list unique values, preserving order"""
    if idfun is None:

        def idfun(x):
            return x
    seen = {}
    result = []
    for item in seq:
        marker = idfun(item)
        if marker in seen:
            continue
        seen[marker] = 1
        result.append(item)
    return result


def add_subtools(o):
    """Add subtools to the given parser."""
    o = o.add_argument_group('subtools')
    o.add_argument('--generate-builtins', action='store', dest=
        'generate_builtins', default=None, help=
        'Precompile builtins pyi and write to the given file.')
    o.add_argument('--parse-pyi', action='store_true', dest='parse_pyi',
        default=False, help='Try parsing a PYI file. For testing of typeshed.')


def Fit(fn):
    """ Fit with a wrapper """

    def wrapper(self):
        self.paramFROMinput()
        if 'track_header' in self.parameters:
            self.header = self.parameters.pop('track_header')
        else:
            self.header = True
        if 'func_method' in self.parameters:
            self.method = self.parameters.pop('func_method')
        else:
            self.method = None
        available_methods = self.metadata.WParameters.func_method.options
        if self.method not in available_methods:
            msg = (
                "@Task #%i(%s): The method '%s' is not available for the function '%s'."
                 % (self.iblock, self.Task, self.method, self.Function))
            raise NameError(msg)
        elif self.method is None:
            api = self.import_sklearn()
            self.set_value('api', api)
            fn(self)
        elif self.method is 'fit_transform':
            api = self.import_sklearn()
            self.required('df', req=True)
            df = self.inputs['df'].value
            df = api.fit_transform(df)
            self.set_value('api', api)
            self.set_value('df', df)
            fn(self)
        elif self.method is 'transform':
            self.required('df', req=True)
            self.required('api', req=True)
            df = self.inputs['df'].value
            api = self.inputs['api'].value
            df = api.transform(df)
            self.set_value('api', api)
            self.set_value('df', df)
            fn(self)
        elif self.method is 'inverse_transform':
            self.required('df', req=True)
            self.required('api', req=True)
            df = self.inputs['df'].value
            api = self.inputs['api'].value
            df = api.inverse_transform(df)
            self.set_value('api', api)
            self.set_value('df', df)
        elif self.method is 'fit':
            api = self.import_sklearn()
            self.required('dfx', req=True)
            self.required('dfy', req=True)
            dfx = self.inputs['dfx'].value
            dfy = self.inputs['dfy'].value
            api.fit(dfx, dfy)
            dfy_predict = api.predict(dfx)
            self.set_value('api', api)
            self.set_value('dfy_predict', dfy_predict)
            fn(self)
        elif self.method is 'predict':
            self.required('dfx', req=True)
            self.required('api', req=True)
            dfx = self.inputs['dfx'].value
            api = self.inputs['api'].value
            dfy_predict = api.predict(dfx)
            self.set_value('api', api)
            self.set_value('dfy_predict', dfy_predict)
            fn(self)
        self.Send()
        del self.inputs


def transform(obj):
    """
    Transforms an object to its NEURON representation, if the __neuron__ magic
    method is present.
  """
    if hasattr(obj, '__neuron__'):
        return obj.__neuron__()
    return obj


def package_listing(c):
    """
    Return a nicely parsed package-group listing
    """
    result = {}
    for group, object in c._groups.iteritems():
        mandatory = object.mandatory_packages.keys()
        default = object.default_packages.keys()
        optional = object.optional_packages.keys()
        result[group] = [mandatory, default, optional]
    return result


def compute_scale_coef(ai_extremum, ai_canvas_size):
    """ compute the four scale coefficient to apply to the outlines to make it fit into a canvas
  """
    min_x, min_y, max_x, max_y = ai_extremum
    canvas_width, canvas_height, margin_x, margin_y = ai_canvas_size
    r_scale_coef = 1, 0, 1, 0
    if max_x - min_x > 0 and max_y - min_y > 0:
        lx = (canvas_width - 2 * margin_x) / float(max_x - min_x)
        ly = (canvas_height - 2 * margin_y) / float(max_y - min_y)
        lxy = min(lx, ly)
        lx = 1 * lxy
        ly = -1 * lxy
        kx = (canvas_width - (max_x - min_x) * lx) / 2 - min_x * lx
        ky = (canvas_height - (max_y - min_y) * abs(ly)) / 2 - max_y * ly
        r_scale_coef = lx, kx, ly, ky
    return r_scale_coef


def make_logger_prefix(tag: str):
    """creates a function to add logger prefix, which returns tag when used empty"""
    return lambda text='': '{}{}'.format(tag, ': ' + text if text else '')


@staticmethod
def ensure_proper_language_model(nlp):
    """Checks if the spacy language model is properly loaded.

        Raises an exception if the model is invalid."""
    if nlp is None:
        raise Exception(
            "Failed to load spacy language model. Loading the model returned 'None'."
            )
    if nlp.path is None:
        raise Exception(
            "Failed to load spacy language model for lang '{}'. Make sure you have downloaded the correct model (https://spacy.io/docs/usage/)."
            .format(nlp.lang))


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


def pic_flag(compiler=None):
    """
    returns PIC (position independent code) flags, such as -fPIC
    """
    if not compiler or compiler == 'Visual Studio':
        return ''
    return '-fPIC'


def get_headers(oauth_token: str) ->dict:
    """Common headers for all requests"""
    return {'Authorization': f'OAuth {oauth_token}'}


def get_empty_cell(ctype='markdown'):
    """Empty cell of type `ctype`."""
    return {'cell_type': ctype, 'metadata': {}, 'source': []}


def rotation_clear(clear_delta: bool=False):
    """Clear the object’s rotation

    :param clear_delta: Clear Delta, Clear delta rotation in addition to clearing the normal rotation transform
    :type clear_delta: bool
    """
    pass


def lnprob_fun(pars, x, y, sigy):
    """
    The model is a straight line.
    This function returns the natural logarithm of

        P(model | data) ~ P(data | model) P(model)

    In this case we assume:

        1) P(model) = cost (i.e. uninformative prior)
        2) P(data | model) = likelihood for Gaussian errors

    This implies:

        P(model | data) ~ -0.5*chi^2

    """
    ymod = pars[0] + pars[1] * x
    resid = (y - ymod) / sigy
    chi2 = resid @ resid
    return -0.5 * chi2


def add_keys(apps, schema_editor):
    """
    We can't import the Post model directly as it may be a newer
    version than this migration expects. We use the historical version.
    """
    Setting = apps.get_model('settings', 'Setting')
    key = ''
    try:
        key = 'INVITATION_FORMAT_STRING'
        Setting.objects.get(key=key)
    except Exception:
        Setting.objects.create(title=' کد دعوت', key=key, value=
            'شما می توانید با کد {{}} به برنامه بپیوندید.', value_type='s',
            is_show=False, is_variable_in_home=True)


@staticmethod
def _extract_attribute(resource, attribute):
    """Retrieve the desired attribute from the resource

        :param resource: The resource object to extract the attribute from.
        :param attribute: The name of the attribute to subtract as string.
        :return: The extracted attribute or None
        """
    try:
        return getattr(resource, attribute)
    except AttributeError:
        raise


def __check_positive(items, zero):
    """Checks a list of strings whether items are valid positive numbers.

    Args:
        items (list of [str,]): The list of items to test.
        zero (bool): Zero status. True includes zero, False excludes zero.

    Returns:
        list of [float,]: The list of items converted to positive numbers.
            Returns None if any one test fails.
    """
    for i, item in enumerate(items):
        try:
            items[i] = float(item)
        except ValueError:
            print('Failed on item: "{}"'.format(item))
            return None
        if zero:
            if items[i] < 0:
                print('Failed on item: "{}"'.format(item))
                return None
        elif items[i] <= 0:
            print('Failed on item: "{}"'.format(item))
            return None
    return items


def clamp(n, lo, hi):
    """clamp n to a value between lo and hi inclusive."""
    return max(min(hi, n), lo)


def s_hfmc(hfmc_array):
    """
    观测发生率，观测的正样本占总样本的比例
    :param hfmc_array:包含命中空报和漏报的多维数组，其中最后一维长度为4，分别记录了（命中数，空报数，漏报数，正确否定数）
    :return:0-1的实数，观测的正样本占总样本的比例
    """
    hit = hfmc_array[..., 0]
    fal = hfmc_array[..., 1]
    mis = hfmc_array[..., 2]
    cn = hfmc_array[..., 3]
    s0 = (hit + mis) / (hit + mis + fal + cn)
    return s0


@staticmethod
def summary(attachment, flat=False):
    """Non detailed view of an attachment."""
    result = {'id': attachment.id, 'status': attachment.attach_status,
        'instance': attachment.instance_uuid, 'volume_id': attachment.volume_id
        }
    if flat:
        return result
    return {'attachment': result}


def slip(offset: int=0):
    """Trim the contents of the active strip

    :param offset: Offset, Offset to the data of the strip
    :type offset: int
    """
    pass


def default_cxx_release_flags():
    """Default C++ flags for debug=False. Note: FFC always overrides these."""
    safe_fastmath_parts = ('-fno-math-errno', '-fno-trapping-math',
        '-ffinite-math-only')
    return ('-O3',) + safe_fastmath_parts


def arg_n(f):
    """
    Returns the number of arguments allowed for the given function `f`
    @sig arg_n :: (* -> a) -> int
    """
    return f.__code__.co_argcount


def args(*args, **kw):
    """arguments for current callable"""


def ray_cast(origin, direction, distance):
    """Cast a ray onto the mesh.

		Parameters:
		co (Vector) – Start location of the ray in object space.
		direction (Vector) – Direction of the ray in object space.
		distance (float) – Maximum distance threshold.

		Returns: Returns a tuple (Vector location, Vector normal, int index, float distance), Values will all be None if no hit is found.

		Return type: tuple"""
    from . import Vector
    return Vector, Vector, 1, 1.0


def _single_element(node, name):
    """If node contains one or more children with nodename "name", return the
    first one. If not, return None"""
    elems = node.getElementsByTagName(name)
    if elems:
        return elems[0]
    else:
        return None


def linear(current, target, rate, dt):
    """
    This function returns the new value after moving towards
    target at the given speed constantly for the time dt.

    If for example the current position is 10 and the target is -20,
    the returned value will be less than 10 if rate and dt are greater
    than 0:

    .. sourcecode:: Python

        new_pos = linear(10, -20, 10, 0.1)  # new_pos = 9

    The function makes sure that the returned value never overshoots:

    .. sourcecode:: Python

        new_pos = linear(10, -20, 10, 100)  # new_pos = -20

    :param current: The current value of the variable to be changed.
    :param target: The target value to approach.
    :param rate: The rate at which the parameter should move towards target.
    :param dt: The time for which to calculate the change.
    :return: The new variable value.
    """
    sign = (target > current) - (target < current)
    if not sign:
        return current
    new_value = current + sign * rate * dt
    if sign * new_value > sign * target:
        return target
    return new_value


def _expand_ranges(ranges_text, delimiter=',', indicator='-'):
    """ Expands a range text to a list of integers.

    For example:

    .. code-block:: python

        range_text = '1,2-4,7'
        print(_expand_ranges(range_text)) # [1, 2, 3, 4, 7]

    :param str ranges_text: The text of ranges to expand
    :returns: A list of integers
    :rtype: list[int]
    """
    results = set()
    for group in filter(None, ranges_text.split(delimiter)):
        group = group.strip()
        if indicator not in group:
            if not group.isdigit():
                raise ValueError(
                    "group '{group}' could not be interpreted as a valid digit"
                    .format(**locals()))
            results.add(int(group))
        else:
            start, finish = list(filter(None, group.split(indicator)))
            if not start.isdigit() or not finish.isdigit():
                raise ValueError(
                    "group '{group}' could not be interpreted as a valid range"
                    .format(**locals()))
            for entry in range(int(start), int(finish) + 1, 1):
                results.add(entry)
    return sorted(list(results))


@classmethod
def save(cls):
    """do app status save"""
    pass


def no_op(*args):
    """No-op function for callbacks.
    """
    pass


def update_attributes(obj, **kwargs):
    """Update object with provided properties."""
    for k, v in kwargs.items():
        k = k.split('.') if '.' in k else k.split('__')
        o = obj
        for name in k[:-1]:
            o = getattr(o, name)
        getattr(o, k[-1])
        setattr(o, k[-1], v)


def get_gcd(a, b):
    """Return greatest common divisor for a and b."""
    while a:
        a, b = b % a, a
    return b


def _layer_label(layer, show_layer_names):
    """Select the node label from the layer"""
    from keras.layers.wrappers import Wrapper
    layer_name = layer.name
    class_name = layer.__class__.__name__
    if isinstance(layer, Wrapper):
        layer_name = '{}({})'.format(layer_name, layer.layer.name)
        child_class_name = layer.layer.__class__.__name__
        class_name = '{}({})'.format(class_name, child_class_name)
    return '{}: {}'.format(layer_name, class_name
        ) if show_layer_names else class_name


def import_uri(obj):
    """
    >>> import_uri(import_uri)
    'aioworkers.utils.import_uri'
    >>> import_uri(Path)
    'pathlib.Path'
    >>> import_uri(Path.exists)
    'pathlib.Path.exists'
    """
    return '.'.join((obj.__module__, obj.__qualname__))


def catch_error(failure):
    """ used for errbacks
    """
    return failure.getErrorMessage()


def sort_bed_nicely(bed_file):
    """Sorts BED file but in sorted_nicely order"""
    import pybedtools
    import tempfile
    from ngs_toolkit.utils import sorted_nicely
    if isinstance(bed_file, str):
        sites = pybedtools.BedTool(bed_file)
    elif isinstance(bed_file, pybedtools.BedTool):
        pass
    chrom_names = tempfile.NamedTemporaryFile()
    with open(chrom_names.name, 'w') as handle:
        for chrom in sorted_nicely(sites.to_dataframe()['chrom'].unique()):
            handle.write(chrom + '\n')
    return sites.sort(g=chrom_names.name)


def convert_by_vocab(vocab, items):
    """Converts a sequence of [tokens|ids] using the vocab."""
    output = []
    for item in items:
        output.append(vocab[item])
    return output


def naive(x):
    """
    Compute the log base 2 of an unsigned 32-bit word

    Use the obvious way: O(N) operations
    Shift to the right `x` until `x` equals to zero.
    The log base 2 corresponds to the index of the most significant bit set.

    Parameters
    ----------
    x : int
        The unsigned 32-bit word to find the log base 2 of.

    References
    ----------
    .. [1] https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious

    Returns
    -------
    int
        The log base 2 of `x`
    """
    if x < 0:
        raise ValueError('x has to be positive')
    r = -1
    while x:
        r += 1
        x >>= 1
    return r


def get_image_spdxref(image_obj):
    """Given the image object, return an SPDX reference ID"""
    return 'SPDXRef-{}'.format(image_obj.get_human_readable_id())


def regular_inv(A, EPS_A=1e-07, EPS_residual=0.001):
    """Computes the inverse of a matrix. Attempts a regularization by adding an epsilon to the diagonal, if the matrix is ill-conditioned.

    Parameters
    ----------
    A : array-like, square
        input matrix
    EPS_A : double, optional, default=1e-7
        epsilon to be added to the diagonal of A, if necessary
    EPS_residual : double, optional, default=1e-3
        maximum residual in A*A^{-1} before attempting regularization

    Returns
    -------
    A^{-1} : array-like, square
        numerical inverse of A

    """
    import numpy as np
    import scipy.linalg as sla
    inv_A = sla.inv(A)
    residual = np.sum(np.fabs(inv_A.dot(A) - np.identity(A.shape[0])))
    if residual > EPS_residual:
        A = A + EPS_A * np.identity(A.shape[0])
        inv_A = sla.inv(A)
        residual = np.sum(np.fabs(inv_A.dot(A) - np.identity(A.shape[0])))
        if residual > 0.001:
            from pyselfi.utils import PrintValue
            PrintValue('condition number of A', np.linalg.cond(A))
            PrintValue('residuals in A*A^{-1}', residual)
            raise ValueError(
                'Matrix inversion is imprecise for A, even after regularization attempt.'
                )
        inv_A = inv_A - EPS_A * np.identity(A.shape[0])
    return inv_A


def print_subheading(title: str) ->None:
    """
    Print a non-breaking subheading in the form of "=> The given text".

    :param title: The text to print
    :return: None
    """
    print(f'\x1b[1;33m=>\x1b[0m {title}', end='', flush=True)


def _pre_mcs_init(cls):
    """
        Callback for BaseModelMetaclass subclasses to run code just before a
        concrete Model class gets registered with SQLAlchemy.

        This is intended to be used for advanced meta options implementations.
        """


def get_uri():
    """Return the (string) URI of the object that was checked."""


@classmethod
def list_all_scenario_types(scenario_cls):
    """Lists all the tests in all scenarios."""
    scenarios = scenario_cls.list_all_scenarios()
    scenario_dict = {}
    for scenario in scenarios:
        testype, test = scenario.split('.')
        if testype in scenario_dict:
            scenario_dict[testype].append(test)
        else:
            scenario_dict[testype] = []
            scenario_dict[testype].append(test)
    return scenario_dict


@staticmethod
def is_indicator():
    """ Determines if the object is a Indicator. """
    return False


def valueLineSplit(line):
    """
    Custom split function for splitting up the components of a value line.

    Could not use normal String.split(' ') due to spaces in some of the value
    name strings.
    """
    components = list()
    part = ''
    in_quotes = False
    for ch in line:
        if ch == ' ' and not in_quotes:
            components.append(part)
            part = ''
        elif ch == '"' and not in_quotes:
            in_quotes = True
        elif ch == '"' and in_quotes:
            in_quotes = False
        else:
            part += ch
    return components


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

        :param SharingChangeLinkPolicyDetails val:
        :rtype: EventDetails
        """
    return cls('sharing_change_link_policy_details', val)


def region_flip():
    """Toggle the region’s alignment (left/right or top/bottom)

    """
    pass


def _is_verbose(argv):
    """ Doing this the low level way in order to init log as early as possible """
    return '--verbose' in argv


def has_controller(thread):
    """Check if the current thread has a controller."""
    return hasattr(thread, 'thread_controller')


def Gst_est(Ht_est, Hs_est):
    """Basic Equation: Gst = (Ht-Hs)/Ht"""
    if Ht_est == 0.0:
        return 0.0
    else:
        Gst_est = (Ht_est - Hs_est) / Ht_est
        return Gst_est


def getBaseRequest(connectionParameters={}, userSettings={}):
    """
      translate the connection parameters, a flat dictionary, to the format used by
      requests (or other connector), also, translate names to ones used by the datasource.
    """
    if userSettings == {}:
        userSettings = dict(file_type='JSON')
        print(
            "result format was set to JSON since none could be found or was passed as a 'ResultFormat' in userSettings"
            )
    output = {'url': connectionParameters['url'], 'params': {'api_key':
        connectionParameters['key'], 'file_type': userSettings['ResultFormat']}
        }
    return output


def should_we_load(kls):
    """ should we load this class as a check? """
    if kls.__name__.endswith('AbstractCheck'):
        return False
    if not kls.__name__.endswith('Check'):
        return False
    mro = kls.__mro__
    for m in mro:
        if m.__name__ == 'AbstractCheck':
            return True
    return False


def code_to_md(source, metadata, language):
    """
    Represent a code cell with given source and metadata as a md cell
    :param source:
    :param metadata:
    :param language:
    :return:
    """
    options = []
    if language:
        options.append(language)
    if 'name' in metadata:
        options.append(metadata['name'])
    return ['```{}'.format(' '.join(options))] + source + ['```']


def phrase(term: str) ->str:
    """
    Format words to query results containing the desired phrase.

    :param term: A phrase that appears in that exact form. (e.q. phrase "Chicago Bulls" vs. words "Chicago" "Bulls")
    :return: String in the format google understands
    """
    return '"{}"'.format(term)


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

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

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


def __new__(mcs, name, bases, dct):
    """Override the new method"""
    return type.__new__(mcs, str(name), bases, dct)


def colgen(*lstcol, **kargs):
    """Returns a generator that mixes provided quantities forever
    trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default"""
    if len(lstcol) < 2:
        lstcol *= 2
    trans = kargs.get('trans', lambda x, y, z: (x, y, z))
    while True:
        for i in range(len(lstcol)):
            for j in range(len(lstcol)):
                for k in range(len(lstcol)):
                    if i != j or j != k or k != i:
                        yield trans(lstcol[(i + j) % len(lstcol)], lstcol[(
                            j + k) % len(lstcol)], lstcol[(k + i) % len(
                            lstcol)])


@classmethod
def list(cls):
    """Return the cache as a tuple (not a list)."""
    return tuple(cls.cache)


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

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


@staticmethod
def fill_vencode_list(promoter_list, vencode_list, combinations_number):
    """
        Given an incomplete list of x REs that make up a VEnCode, it fills the list up, up to y VEnCodes (
        y = RE combinations number), based on next sparse REs.
        :param promoter_list: list of promoters to add to VEnCodes
        :param vencode_list:
        :param combinations_number:
        :return: A list of y REs that comprise a VEnCode, where y = combinations number.
        """
    assert len(vencode_list
        ) <= combinations_number, 'vencode list len is bigger than wanted RE number'
    if len(vencode_list) == combinations_number:
        return vencode_list
    for prom in promoter_list:
        if prom in vencode_list:
            continue
        vencode_list.append(prom)
        if len(vencode_list) == combinations_number:
            break
    return vencode_list


@staticmethod
def _choose_indicator_color(color: str) ->int:
    """Return the selected color number by its given name.

        This is color which the indicators will be highlighted and the
        progress bar itself, from the list.

        Checking for a possible incorrect, passed parameter, passes in the
        _CheckParams() class.
        """
    return {'black': 0, 'red': 1, 'green': 2, 'yellow': 3, 'blue': 4,
        'magenta': 5, 'cyan': 6, 'gray': 7, 'white': 8}[color]


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 points_to_vec(pt1, pt2, flip=False):
    """
    Converts the coordinate of two points (pt1 > pt2) to a vector

    flip: bool, default = False
        If the coordinate system should be flipped such that higher y-coords
        are lower (e.g. needed when working with images in opencv).
    """
    vx = pt2[0] - pt1[0]
    vy = pt1[1] - pt2[1] if flip else pt2[1] - pt1[1]
    return vx, vy


def canddata_feature(canddata, feature):
    """ Calculate a feature (or candloc) from a canddata instance.
    feature must be name from st.features or 'candloc'.
    """
    if feature == 'candloc':
        return canddata.loc
    elif feature == 'snr1':
        return canddata.snr1
    elif feature == 'snrarms':
        return canddata.snrarms
    elif feature == 'snrk':
        return canddata.snrk
    elif feature == 'cluster':
        return canddata.cluster
    elif feature == 'clustersize':
        return canddata.clustersize
    elif feature == 'specstd':
        return canddata.specstd
    elif feature == 'specskew':
        return canddata.specskew
    elif feature == 'speckur':
        return canddata.speckur
    elif feature == 'immax1':
        return canddata.immax1
    elif feature == 'l1':
        return canddata.l1
    elif feature == 'm1':
        return canddata.m1
    elif feature == 'imskew':
        return canddata.imskew
    elif feature == 'imkur':
        return canddata.imkur
    elif feature == 'tskew':
        return canddata.tskew
    elif feature == 'tkur':
        return canddata.tkur
    else:
        raise NotImplementedError('Feature {0} calculation not implemented'
            .format(feature))


@classmethod
def get_name(cls):
    """Name of the representation or differential.

        In lower case, with any trailing 'representation' or 'differential'
        removed. (E.g., 'spherical' for
        `~astropy.coordinates.SphericalRepresentation` or
        `~astropy.coordinates.SphericalDifferential`.)
        """
    name = cls.__name__.lower()
    if name.endswith('representation'):
        name = name[:-14]
    elif name.endswith('differential'):
        name = name[:-12]
    return name


def normalize_scheme(scheme):
    """Normalize scheme part of the url.

    Params:
        scheme : string : url scheme, e.g., 'https'

    Returns:
        string : normalized scheme data.

    """
    return scheme.lower()


def request_spot_fleet(DryRun=None, SpotFleetRequestConfig=None):
    """
    Creates a Spot fleet request.
    You can submit a single request that includes multiple launch specifications that vary by instance type, AMI, Availability Zone, or subnet.
    By default, the Spot fleet requests Spot instances in the Spot pool where the price per unit is the lowest. Each launch specification can include its own instance weighting that reflects the value of the instance type to your application workload.
    Alternatively, you can specify that the Spot fleet distribute the target capacity across the Spot pools included in its launch specifications. By ensuring that the Spot instances in your Spot fleet are in different Spot pools, you can improve the availability of your fleet.
    For more information, see Spot Fleet Requests in the Amazon Elastic Compute Cloud User Guide .
    See also: AWS API Documentation

    Examples
    This example creates a Spot fleet request with two launch specifications that differ only by subnet. The Spot fleet launches the instances in the specified subnet with the lowest price. If the instances are launched in a default VPC, they receive a public IP address by default. If the instances are launched in a nondefault VPC, they do not receive a public IP address by default. Note that you can't specify different subnets from the same Availability Zone in a Spot fleet request.
    Expected Output:
    This example creates a Spot fleet request with two launch specifications that differ only by Availability Zone. The Spot fleet launches the instances in the specified Availability Zone with the lowest price. If your account supports EC2-VPC only, Amazon EC2 launches the Spot instances in the default subnet of the Availability Zone. If your account supports EC2-Classic, Amazon EC2 launches the instances in EC2-Classic in the Availability Zone.
    Expected Output:
    This example assigns public addresses to instances launched in a nondefault VPC. Note that when you specify a network interface, you must include the subnet ID and security group ID using the network interface.
    Expected Output:
    This example creates a Spot fleet request that launches 30 instances using the diversified allocation strategy. The launch specifications differ by instance type. The Spot fleet distributes the instances across the launch specifications such that there are 10 instances of each type.
    Expected Output:

    :example: response = client.request_spot_fleet(
        DryRun=True|False,
        SpotFleetRequestConfig={
            'ClientToken': 'string',
            'SpotPrice': 'string',
            'TargetCapacity': 123,
            'ValidFrom': datetime(2015, 1, 1),
            'ValidUntil': datetime(2015, 1, 1),
            'TerminateInstancesWithExpiration': True|False,
            'IamFleetRole': 'string',
            'LaunchSpecifications': [
                {
                    'ImageId': 'string',
                    'KeyName': 'string',
                    'SecurityGroups': [
                        {
                            'GroupName': 'string',
                            'GroupId': 'string'
                        },
                    ],
                    'UserData': 'string',
                    'AddressingType': 'string',
                    'InstanceType': 't1.micro'|'t2.nano'|'t2.micro'|'t2.small'|'t2.medium'|'t2.large'|'t2.xlarge'|'t2.2xlarge'|'m1.small'|'m1.medium'|'m1.large'|'m1.xlarge'|'m3.medium'|'m3.large'|'m3.xlarge'|'m3.2xlarge'|'m4.large'|'m4.xlarge'|'m4.2xlarge'|'m4.4xlarge'|'m4.10xlarge'|'m4.16xlarge'|'m2.xlarge'|'m2.2xlarge'|'m2.4xlarge'|'cr1.8xlarge'|'r3.large'|'r3.xlarge'|'r3.2xlarge'|'r3.4xlarge'|'r3.8xlarge'|'r4.large'|'r4.xlarge'|'r4.2xlarge'|'r4.4xlarge'|'r4.8xlarge'|'r4.16xlarge'|'x1.16xlarge'|'x1.32xlarge'|'i2.xlarge'|'i2.2xlarge'|'i2.4xlarge'|'i2.8xlarge'|'i3.large'|'i3.xlarge'|'i3.2xlarge'|'i3.4xlarge'|'i3.8xlarge'|'i3.16xlarge'|'hi1.4xlarge'|'hs1.8xlarge'|'c1.medium'|'c1.xlarge'|'c3.large'|'c3.xlarge'|'c3.2xlarge'|'c3.4xlarge'|'c3.8xlarge'|'c4.large'|'c4.xlarge'|'c4.2xlarge'|'c4.4xlarge'|'c4.8xlarge'|'cc1.4xlarge'|'cc2.8xlarge'|'g2.2xlarge'|'g2.8xlarge'|'cg1.4xlarge'|'p2.xlarge'|'p2.8xlarge'|'p2.16xlarge'|'d2.xlarge'|'d2.2xlarge'|'d2.4xlarge'|'d2.8xlarge'|'f1.2xlarge'|'f1.16xlarge',
                    'Placement': {
                        'AvailabilityZone': 'string',
                        'GroupName': 'string',
                        'Tenancy': 'default'|'dedicated'|'host'
                    },
                    'KernelId': 'string',
                    'RamdiskId': 'string',
                    'BlockDeviceMappings': [
                        {
                            'VirtualName': 'string',
                            'DeviceName': 'string',
                            'Ebs': {
                                'SnapshotId': 'string',
                                'VolumeSize': 123,
                                'DeleteOnTermination': True|False,
                                'VolumeType': 'standard'|'io1'|'gp2'|'sc1'|'st1',
                                'Iops': 123,
                                'Encrypted': True|False
                            },
                            'NoDevice': 'string'
                        },
                    ],
                    'Monitoring': {
                        'Enabled': True|False
                    },
                    'SubnetId': 'string',
                    'NetworkInterfaces': [
                        {
                            'NetworkInterfaceId': 'string',
                            'DeviceIndex': 123,
                            'SubnetId': 'string',
                            'Description': 'string',
                            'PrivateIpAddress': 'string',
                            'Groups': [
                                'string',
                            ],
                            'DeleteOnTermination': True|False,
                            'PrivateIpAddresses': [
                                {
                                    'PrivateIpAddress': 'string',
                                    'Primary': True|False
                                },
                            ],
                            'SecondaryPrivateIpAddressCount': 123,
                            'AssociatePublicIpAddress': True|False,
                            'Ipv6Addresses': [
                                {
                                    'Ipv6Address': 'string'
                                },
                            ],
                            'Ipv6AddressCount': 123
                        },
                    ],
                    'IamInstanceProfile': {
                        'Arn': 'string',
                        'Name': 'string'
                    },
                    'EbsOptimized': True|False,
                    'WeightedCapacity': 123.0,
                    'SpotPrice': 'string'
                },
            ],
            'ExcessCapacityTerminationPolicy': 'noTermination'|'default',
            'AllocationStrategy': 'lowestPrice'|'diversified',
            'FulfilledCapacity': 123.0,
            'Type': 'request'|'maintain',
            'ReplaceUnhealthyInstances': True|False
        }
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type SpotFleetRequestConfig: dict
    :param SpotFleetRequestConfig: [REQUIRED]
            The configuration for the Spot fleet request.
            ClientToken (string) --A unique, case-sensitive identifier you provide to ensure idempotency of your listings. This helps avoid duplicate listings. For more information, see Ensuring Idempotency .
            SpotPrice (string) -- [REQUIRED]The bid price per unit hour.
            TargetCapacity (integer) -- [REQUIRED]The number of units to request. You can choose to set the target capacity in terms of instances or a performance characteristic that is important to your application workload, such as vCPUs, memory, or I/O.
            ValidFrom (datetime) --The start date and time of the request, in UTC format (for example, YYYY -MM -DD T*HH* :MM :SS Z). The default is to start fulfilling the request immediately.
            ValidUntil (datetime) --The end date and time of the request, in UTC format (for example, YYYY -MM -DD T*HH* :MM :SS Z). At this point, no new Spot instance requests are placed or enabled to fulfill the request.
            TerminateInstancesWithExpiration (boolean) --Indicates whether running Spot instances should be terminated when the Spot fleet request expires.
            IamFleetRole (string) -- [REQUIRED]Grants the Spot fleet permission to terminate Spot instances on your behalf when you cancel its Spot fleet request using CancelSpotFleetRequests or when the Spot fleet request expires, if you set terminateInstancesWithExpiration .
            LaunchSpecifications (list) -- [REQUIRED]Information about the launch specifications for the Spot fleet request.
            (dict) --Describes the launch specification for one or more Spot instances.
            ImageId (string) --The ID of the AMI.
            KeyName (string) --The name of the key pair.
            SecurityGroups (list) --One or more security groups. When requesting instances in a VPC, you must specify the IDs of the security groups. When requesting instances in EC2-Classic, you can specify the names or the IDs of the security groups.
            (dict) --Describes a security group.
            GroupName (string) --The name of the security group.
            GroupId (string) --The ID of the security group.

            UserData (string) --The user data to make available to the instances. If you are using an AWS SDK or command line tool, Base64-encoding is performed for you, and you can load the text from a file. Otherwise, you must provide Base64-encoded text.
            AddressingType (string) --Deprecated.
            InstanceType (string) --The instance type. Note that T2 and HS1 instance types are not supported.
            Placement (dict) --The placement information.
            AvailabilityZone (string) --The Availability Zone.
            [Spot fleet only] To specify multiple Availability Zones, separate them using commas; for example, 'us-west-2a, us-west-2b'.
            GroupName (string) --The name of the placement group (for cluster instances).
            Tenancy (string) --The tenancy of the instance (if the instance is running in a VPC). An instance with a tenancy of dedicated runs on single-tenant hardware. The host tenancy is not supported for Spot instances.
            KernelId (string) --The ID of the kernel.
            RamdiskId (string) --The ID of the RAM disk.
            BlockDeviceMappings (list) --One or more block device mapping entries.
            (dict) --Describes a block device mapping.
            VirtualName (string) --The virtual device name (ephemeral N). Instance store volumes are numbered starting from 0. An instance type with 2 available instance store volumes can specify mappings for ephemeral0 and ephemeral1 .The number of available instance store volumes depends on the instance type. After you connect to the instance, you must mount the volume.
            Constraints: For M3 instances, you must specify instance store volumes in the block device mapping for the instance. When you launch an M3 instance, we ignore any instance store volumes specified in the block device mapping for the AMI.
            DeviceName (string) --The device name exposed to the instance (for example, /dev/sdh or xvdh ).
            Ebs (dict) --Parameters used to automatically set up EBS volumes when the instance is launched.
            SnapshotId (string) --The ID of the snapshot.
            VolumeSize (integer) --The size of the volume, in GiB.
            Constraints: 1-16384 for General Purpose SSD (gp2 ), 4-16384 for Provisioned IOPS SSD (io1 ), 500-16384 for Throughput Optimized HDD (st1 ), 500-16384 for Cold HDD (sc1 ), and 1-1024 for Magnetic (standard ) volumes. If you specify a snapshot, the volume size must be equal to or larger than the snapshot size.
            Default: If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size.
            DeleteOnTermination (boolean) --Indicates whether the EBS volume is deleted on instance termination.
            VolumeType (string) --The volume type: gp2 , io1 , st1 , sc1 , or standard .
            Default: standard
            Iops (integer) --The number of I/O operations per second (IOPS) that the volume supports. For io1 , this represents the number of IOPS that are provisioned for the volume. For gp2 , this represents the baseline performance of the volume and the rate at which the volume accumulates I/O credits for bursting. For more information about General Purpose SSD baseline performance, I/O credits, and bursting, see Amazon EBS Volume Types in the Amazon Elastic Compute Cloud User Guide .
            Constraint: Range is 100-20000 IOPS for io1 volumes and 100-10000 IOPS for gp2 volumes.
            Condition: This parameter is required for requests to create io1 volumes; it is not used in requests to create gp2 , st1 , sc1 , or standard volumes.
            Encrypted (boolean) --Indicates whether the EBS volume is encrypted. Encrypted Amazon EBS volumes may only be attached to instances that support Amazon EBS encryption.
            NoDevice (string) --Suppresses the specified device included in the block device mapping of the AMI.

            Monitoring (dict) --Enable or disable monitoring for the instances.
            Enabled (boolean) --Enables monitoring for the instance.
            Default: false
            SubnetId (string) --The ID of the subnet in which to launch the instances. To specify multiple subnets, separate them using commas; for example, 'subnet-a61dafcf, subnet-65ea5f08'.
            NetworkInterfaces (list) --One or more network interfaces. If you specify a network interface, you must specify subnet IDs and security group IDs using the network interface.
            (dict) --Describes a network interface.
            NetworkInterfaceId (string) --The ID of the network interface.
            DeviceIndex (integer) --The index of the device on the instance for the network interface attachment. If you are specifying a network interface in a RunInstances request, you must provide the device index.
            SubnetId (string) --The ID of the subnet associated with the network string. Applies only if creating a network interface when launching an instance.
            Description (string) --The description of the network interface. Applies only if creating a network interface when launching an instance.
            PrivateIpAddress (string) --The private IPv4 address of the network interface. Applies only if creating a network interface when launching an instance. You cannot specify this option if you're launching more than one instance in a RunInstances request.
            Groups (list) --The IDs of the security groups for the network interface. Applies only if creating a network interface when launching an instance.
            (string) --
            DeleteOnTermination (boolean) --If set to true , the interface is deleted when the instance is terminated. You can specify true only if creating a new network interface when launching an instance.
            PrivateIpAddresses (list) --One or more private IPv4 addresses to assign to the network interface. Only one private IPv4 address can be designated as primary. You cannot specify this option if you're launching more than one instance in a RunInstances request.
            (dict) --Describes a secondary private IPv4 address for a network interface.
            PrivateIpAddress (string) -- [REQUIRED]The private IPv4 addresses.
            Primary (boolean) --Indicates whether the private IPv4 address is the primary private IPv4 address. Only one IPv4 address can be designated as primary.

            SecondaryPrivateIpAddressCount (integer) --The number of secondary private IPv4 addresses. You can't specify this option and specify more than one private IP address using the private IP addresses option. You cannot specify this option if you're launching more than one instance in a RunInstances request.
            AssociatePublicIpAddress (boolean) --Indicates whether to assign a public IPv4 address to an instance you launch in a VPC. The public IP address can only be assigned to a network interface for eth0, and can only be assigned to a new network interface, not an existing one. You cannot specify more than one network interface in the request. If launching into a default subnet, the default value is true .
            Ipv6Addresses (list) --One or more IPv6 addresses to assign to the network interface. You cannot specify this option and the option to assign a number of IPv6 addresses in the same request. You cannot specify this option if you've specified a minimum number of instances to launch.
            (dict) --Describes an IPv6 address.
            Ipv6Address (string) --The IPv6 address.

            Ipv6AddressCount (integer) --A number of IPv6 addresses to assign to the network interface. Amazon EC2 chooses the IPv6 addresses from the range of the subnet. You cannot specify this option and the option to assign specific IPv6 addresses in the same request. You can specify this option if you've specified a minimum number of instances to launch.

            IamInstanceProfile (dict) --The IAM instance profile.
            Arn (string) --The Amazon Resource Name (ARN) of the instance profile.
            Name (string) --The name of the instance profile.
            EbsOptimized (boolean) --Indicates whether the instances are optimized for EBS I/O. This optimization provides dedicated throughput to Amazon EBS and an optimized configuration stack to provide optimal EBS I/O performance. This optimization isn't available with all instance types. Additional usage charges apply when using an EBS Optimized instance.
            Default: false
            WeightedCapacity (float) --The number of units provided by the specified instance type. These are the same units that you chose to set the target capacity in terms (instances or a performance characteristic such as vCPUs, memory, or I/O).
            If the target capacity divided by this value is not a whole number, we round the number of instances to the next whole number. If this value is not specified, the default is 1.
            SpotPrice (string) --The bid price per unit hour for the specified instance type. If this value is not specified, the default is the Spot bid price specified for the fleet. To determine the bid price per unit hour, divide the Spot bid price by the value of WeightedCapacity .

            ExcessCapacityTerminationPolicy (string) --Indicates whether running Spot instances should be terminated if the target capacity of the Spot fleet request is decreased below the current size of the Spot fleet.
            AllocationStrategy (string) --Indicates how to allocate the target capacity across the Spot pools specified by the Spot fleet request. The default is lowestPrice .
            FulfilledCapacity (float) --The number of units fulfilled by this request compared to the set target capacity.
            Type (string) --The type of request. Indicates whether the fleet will only request the target capacity or also attempt to maintain it. When you request a certain target capacity, the fleet will only place the required bids. It will not attempt to replenish Spot instances if capacity is diminished, nor will it submit bids in alternative Spot pools if capacity is not available. When you want to maintain a certain target capacity, fleet will place the required bids to meet this target capacity. It will also automatically replenish any interrupted instances. Default: maintain .
            ReplaceUnhealthyInstances (boolean) --Indicates whether Spot fleet should replace unhealthy instances.

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

    """
    pass


def get_solver_info(net):
    """
    This function print the information related to the solver option
    :param net:
    """
    print('Here are the current solver options: ')
    print(net.solver_option)
    print('\nHere are definition of the current solver options: ')
    print(net.solver_info)


def myobj_noderiv(y, z, v, w):
    """Return objective without derivatives
    """
    return y ** 2 + z - v + w ** 2


def _margeff_cov_params_count(model, cov_margins, params, exog, count_ind,
    method, J):
    """
    Returns the Jacobian for discrete regressors for use in margeff_cov_params.

    For discrete regressors the marginal effect is

    \\Delta F = F(XB) | d += 1 - F(XB) | d -= 1

    The row of the Jacobian for this variable is given by

    (f(XB)*X | d += 1 - f(XB)*X | d -= 1) / 2

    where F is the default prediction for the model.
    """
    for i in count_ind:
        exog0 = exog.copy()
        exog0[:, (i)] -= 1
        dfdb0 = model._derivative_predict(params, exog0, method)
        exog0[:, (i)] += 2
        dfdb1 = model._derivative_predict(params, exog0, method)
        dfdb = dfdb1 - dfdb0
        if dfdb.ndim >= 2:
            dfdb = dfdb.mean(0) / 2
        if J > 1:
            K = dfdb.shape[1] / (J - 1)
            cov_margins[i::K, :] = dfdb
        else:
            cov_margins[(i), :len(dfdb)] = dfdb
    return cov_margins


@staticmethod
def ConvertToFixtureName(func_name):
    """
        Converts a function name to a fixture name:
            - lower-case
            - underscores separates words
            - ends with an underscore

        The fixture name is used as a parameter of a Command function.

        Ex.
            MyDb -> my_db_

        :param unicode func_name:
            The function name, using camel cases standard.

        :return unicode:
        """
    import re
    s1 = re.sub('(.)([A-Z][a-z]+)', '\\1_\\2', func_name)
    result = re.sub('([a-z0-9])([A-Z])', '\\1_\\2', s1).lower()
    if not result.endswith('_'):
        result += '_'
    return result


def _sequence_len(msa, description):
    """
    Takes an MSA and a description as an input and returns the sequence length
    of that description.
    """
    sequence = msa.get_sequence(description)
    if sequence:
        return len(sequence.ungapped())
    return 0


def getFirstLine(doc):
    """ Get the first non empty line from doc. """
    if doc:
        for lines in doc.split('\n'):
            l = lines.strip()
            if l:
                return l
    return ''


@staticmethod
def _update_last_batch(batch, *new_captions):
    """Given a batch of captions, sets their end time equal to the start
        time of the first caption in *new_captions

        The start time of the first caption in new_captions should never be 0.
        This means an invalid SCC file.

        :type batch: tuple[Caption]
        :type new_captions: tuple[Caption]
        """
    if not new_captions:
        return
    if not new_captions[0]:
        return
    if not new_captions[0].nodes:
        return
    new_caption = new_captions[0]
    if batch and batch[-1].end == 0:
        for caption in batch:
            caption.end = new_caption.start


@classmethod
def get_dperp_apar(cls, x, apar, r=1):
    """
        calculate inplane lattice parameter and the out of plane lattice plane
        spacing (of the atomic planes!) from composition and relaxation

        Parameters
        ----------
        x :     float
            chemical composition parameter
        apar :  float
            inplane lattice parameter of the material below the current layer
            (onto which the present layer is strained to). This value also
            served as a reference for the relaxation parameter.
        r :     float
            relaxation parameter. 1=relaxed, 0=pseudomorphic

        Returns
        -------
        dperp : float
            perpendicular d-spacing
        apar :  float
            inplane lattice parameter
        """
    abulk = cls.abulk(x)
    aparl = apar + (abulk - apar) * r
    dperp = abulk * (1 + cls.poisson_ratio(x) * (1 - aparl / abulk)) / 4.0
    return dperp, aparl


@classmethod
def concatenate(cls, objects, **kwargs):
    """Concatenate objects to get object that would be recieved if
        the concatenated serialization were deserialized.

        Args:
            objects (list): Objects to be concatenated.
            **kwargs: Additional keyword arguments are ignored.

        Returns:
            list: Set of objects that results from concatenating those provided.

        """
    total = dict()
    for x in objects:
        total.update(x)
    return [total]


@classmethod
def delete_all_scopes(cls):
    """ Removes all scopes. """
    for key in list(cls.collection_classes.keys()):
        if key is not None:
            del cls.collection_classes[key]


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 service_list(service=None, key_name=None, **kwargs):
    """General list function for Google APIs."""
    resp_list = []
    req = service.list(**kwargs)
    while req is not None:
        resp = req.execute()
        if key_name and key_name in resp:
            resp_list.extend(resp[key_name])
        else:
            resp_list.append(resp)
        if hasattr(service, 'list_next'):
            req = service.list_next(previous_request=req, previous_response
                =resp)
        else:
            req = None
    return resp_list


def output_F(results, contrast):
    """
    This convenience function outputs the results of an Fcontrast
    from a regression

    Parameters
    ----------
    results : object
        implementing Tcontrast method
    contrast : array
        contrast matrix

    Returns
    -------
    F : array
        array of F values
    """
    return results.Fcontrast(contrast).F


def grams2mu(grams):
    """Convert a force in grams (yes, I know...) into machine units."""
    return int(grams / 7.0 + 0.5)


def AUC_analysis(AUC):
    """
    Analysis AUC with interpretation table.

    :param AUC: area under the ROC curve
    :type AUC : float
    :return: interpretation result as str
    """
    try:
        if AUC == 'None':
            return 'None'
        if AUC < 0.6:
            return 'Poor'
        if AUC >= 0.6 and AUC < 0.7:
            return 'Fair'
        if AUC >= 0.7 and AUC < 0.8:
            return 'Good'
        if AUC >= 0.8 and AUC < 0.9:
            return 'Very Good'
        return 'Excellent'
    except Exception:
        return 'None'


@classmethod
def parse(class_, f):
    """Parse a transaction Tx from the file-like object f."""
    raise NotImplemented()


def download_file(service, fileid, filetypes, outp, test=False):
    """
    https://developers.google.com/drive/api/v3/ref-export-formats
    """
    from googleapiclient.http import MediaIoBaseDownload
    from os import makedirs
    from os.path import dirname
    import io
    for mimeType in filetypes:
        request = service.files().export_media(fileId=fileid, mimeType=mimeType
            )
        outp_ = (outp if '.' in outp else
            f"{outp}.{mimeType.split('/')[1].split('+')[0]}")
        makedirs(dirname(outp), exist_ok=True)
        fh = io.FileIO(file=outp_, mode='w')
        downloader = MediaIoBaseDownload(fh, request)
        done = False
        while done is False:
            status, done = downloader.next_chunk()
            if test:
                print(f'Downloading {outp_}: {int(status.progress() * 100)}')


def get_protocol(request):
    """Returns 'http' or 'https' for the request protocol"""
    if request.is_secure():
        return 'https'
    return 'http'


@staticmethod
def _register_zid():
    """
        This operates in the flask request context. We pass in the WSGI environ into the configured auth_checker and
        register the provided zID into the request-scoped globals.

        :return: None
        """
    from flask import g, request, current_app
    g.zid = current_app.config['AUTH_CHECKER'].check_auth(request.environ)


@staticmethod
def extension():
    """Return most common file extension for format."""
    return 'csv'


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


def p_and_expr_1(p):
    """and_expr : shift_expr"""
    p[0] = p[1]


def base_to_int(s, base, lenb):
    """
    >>> base26_to_int('be')
    30

    """
    num = 0
    for char in s:
        num = num * lenb + base.index(char)
    return num


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

        :param SharedContentChangeInviteeRoleType val:
        :rtype: EventType
        """
    return cls('shared_content_change_invitee_role', val)


def divide_coordinates(coordinates):
    """
    Divide coordinates into about 50 pieces for following use.
    :param coordinates: coordinates contains gps data.
    :return: divided coordinates
    """
    interval = len(coordinates) // 50 + 1
    divided_coordinates = []
    for i in range(0, len(coordinates), interval):
        divided_coordinates.append(coordinates[i:i + interval])
    return divided_coordinates


def verb(dirty):
    """
    Given a 'dirty' string (lowercased, with trailing whitespaces), strips
    it and returns it uppercased.
    """
    return dirty.strip().upper()