def cal_log_gamma(log_alpha, log_beta, log_likelihood, log_state={}):
    """
    The function to calculate the log of the posterior probability of each state
    at each timestamp.
    Parameters
    ----------
    log_alpha : array-like of shape (t, k)
        log of forward variable alpha.
    log_alpha : array-like of shape (t, k)
        log of backward variable beta.
    log_likelihood : float
        log likelihood of the sequence
    log_state: dict(int -> array-like of shape (k, ))
        timestamp i is a key of log_state if we know the state of that timestamp.
        Mostly used in semi-supervised and supervised IOHMM.
        log_state[t][i] is 0 and log_state[t][~i] is -np.Infinity
        if we know the state is i at timestamp t.
    Returns
    -------
    log_gamma : array-like of shape (t, k)
        the log of the posterior probability of each state.
        log_gamma_{t, i} is the posterior log of the probability of
        being in state i at stimestamp t.
        see https://en.wikipedia.org/wiki/Forward-backward_algorithm for details.
    """
    log_gamma = log_alpha + log_beta - log_likelihood
    for i in log_state:
        log_gamma[(i), :] = log_state[i]
    return log_gamma


@staticmethod
def encode(code, seq_low, seq_high):
    """Method for encoding the system_code or unit_code from binary to a gateway-readable format"""
    encoded_msg = ''
    for bit in code:
        if bit == '0':
            encoded_msg += seq_high
        elif bit == '1':
            encoded_msg += seq_low
        else:
            raise ValueError('Invalid value in system_code or unit_code!')
    return encoded_msg


@staticmethod
def to_string(_, item):
    """Used by lxml's ETree to serialize values implicitly."""
    return item.value


def isEqual(lhs, rhs):
    """types should be a either a list, tuple, etc"""
    print(lhs)
    print(rhs)
    for x, y in zip(lhs, rhs):
        if x == y:
            continue
        else:
            return False
    return True


def copy_reference(resource, doc, env, *args, **kwargs):
    """A row-generating function that yields from a reference. This permits an upstream package to be
    copied and modified by this package, while being formally referenced as a dependency

    The function will generate rows from a reference that has the same name as the resource term
    """
    yield from doc.reference(resource.name)


def url_open(url: str=''):
    """Open a website in the web-browser

    :param url: URL, URL to open
    :type url: str
    """
    pass


def currency_data(xml):
    """Returns currency data from the xml file."""


def separate():
    """Separate selected points from connected unselected points into a new object

    """
    pass


def _login_referrer(request, params):
    """Extract a "came_from" parameter from the specified dictionary or
    just provide an URL to the home page.
    """
    return params.get('came_from', request.path)


def block_num_from_hash(block_hash: str) ->int:
    """
    return the first 4 bytes (8 hex digits) of the block ID (the block_num)
    Args:
        block_hash (str):

    Returns:
        int:
    """
    return int(str(block_hash)[:8], base=16)


def hitran_bands(df):
    """Print all bands in HITRAN transitions

    Parameters
    ----------
    df : pandas DataFrame
        HITRAN transitions returned by read_hitran_file
    """
    bands = df.global_upper_quanta.unique()
    for b in bands:
        nu = df[df.global_upper_quanta.str.contains(b) & df.
            global_lower_quanta.str.contains(b'GROUND')].nu.mean()
        print(b, nu)


def _transform_options(config, equivalents):
    """
    Get the equivalent name of the checked options
    """
    for option in config:
        if config[option] and option in equivalents:
            yield equivalents[option]


def genericChildren(path):
    """
    List the children of the given path.

    :return: an iterable of all currently-existing children of the path.
    :rtype: iterable
    """
    return map(path.child, path.listdir())


def set_close_exec(fd: int) ->None:
    """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor."""
    raise NotImplementedError()


@classmethod
def table_name_col(cls):
    """
        Return the name of the metadata column used to store the feature table
        name.
        """
    return 'table_name'


@staticmethod
def _gen_memd_wrappers_retarget(cls, factory):
    """Generates wrappers for all the memcached operations.
        :param factory: A function to be called to return the wrapped
            method. It will be called with two arguments; the first is
            the unbound method being wrapped, and the second is the name
            of such a method.

          The factory shall return a new unbound method

        :return: A dictionary of names mapping the API calls to the
            wrapped functions
        """
    d = {}
    for n in cls._MEMCACHED_OPERATIONS:
        for variant in (n, n + '_multi'):
            try:
                d[variant] = factory(getattr(cls, variant), variant)
            except AttributeError:
                if n in cls._MEMCACHED_NOMULTI:
                    continue
                raise
    return d


@staticmethod
def _get_domain_from_url(url):
    """
        Returns the domain name for a given URL.

        :args:
            url (str): the given URL

        :return:
            (str): the domain name
        """
    domain = url.split('/')[2].split('?')[0].strip()
    try:
        return domain.strip()
    except IndexError:
        pass


def data_type_dict():
    """Returns a dictionary from data type string to the data type.

    The dictionary should include at least:
    float16
    float32
    float64
    uint8
    int8
    int16
    int32
    int64

    This function will be called only *once* during the initialization fo the
    backend module. The returned dictionary will become the attributes of the
    backend module.

    Examples
    --------
    >>> import torch as th
    >>> def data_type_dict():
    >>>   return { 'float16' : th.float16, 'float32' : th.float32, ... }

    After the module is initialized.

    >>> import backend as F
    >>> F.float16  # this will point to torch.float16

    Returns
    -------
    dict of str to data type
        The data type dict.
    """
    pass


@staticmethod
def _normalize_inputs(framework, data, project) ->tuple:
    """
        Normalize constructor inputs

        A :class:`ProjectFramework` is constructed against a particular framework
        and data. For convenience, these can be specified by passing in a Project
        containing the framework and data. This function takes in all of the inputs
        provided to the constructor (whether making a blank instance or reading a
        spreadsheet) and returns the framework and data. The order of precedence is

        - If separate framework or data is provided, it will be used
        - Otherwise, they will be drawn from the project

        So for example, a project and data could be provided, in which case the framework
        would come from the project and the data would come from the explicit argument
        (even if the project also contained data).

        :param framework: Optionally a :class:`ProjectFramework` instance
        :param data: Optionally a :class:`ProjectData` instance
        :param project: Optionally a :class:`Project` instance
        :return: Tuple containing ``(framework,data)``

        """
    if (framework is None and project is None or data is None and project is
        None):
        errormsg = (
            'To read in a ProgramSet, please supply one of the following sets of inputs: (a) a Framework and a ProjectData, (b) a Project.'
            )
        raise Exception(errormsg)
    if framework is None:
        if project.framework is None:
            errormsg = (
                'A Framework was not provided, and the Project has not been initialized with a Framework'
                )
            raise Exception(errormsg)
        else:
            framework = project.framework
    if data is None:
        if project.data is None:
            errormsg = 'Project data has not been loaded yet'
            raise Exception(errormsg)
        else:
            data = project.data
    return framework, data


def enable_lazy():
    """Convenience function for configuring _() to use lazy gettext

    Call this at the start of execution to enable the gettextutils._
    function to use lazy gettext functionality. This is useful if
    your project is importing _ directly instead of using the
    gettextutils.install() way of importing the _ function.
    """
    global USE_LAZY
    USE_LAZY = True


@staticmethod
def set_collapsed(block, val):
    """
        Sets the fold trigger state (collapsed or expanded).

        :param block: The block to modify
        :param val: The new trigger state (True=collapsed, False=expanded)
        """
    if block is None:
        return
    state = block.userState()
    if state == -1:
        state = 0
    state &= 2013265919
    state |= int(val) << 27
    block.setUserState(state)


def lambd_CO2_K_HMW84(T, P):
    """n-c: carbon-dioxide potassium [HMW84]."""
    lambd = 0.051
    valid = T == 298.15
    return lambd, valid


@staticmethod
def create(class_name, from_event=None):
    """
        Creates a new event of the specified class, while preserving the values
        of the origin event (as much as possible).
        :param class_name: The name of the type of event to create
        :param from_event: The event from wich the common values will be copied
        """
    new_event = eval(class_name)()
    if from_event is not None:
        for key in new_event.__dict__.keys():
            if key in from_event.__dict__ and key != 'type':
                new_event.__dict__[key] = from_event.__dict__[key]
    return new_event


@staticmethod
def _bitdiff(this_bytes, other_bytes):
    """ Calculates the percent of different bits between two byte
        strings.
        """
    if len(this_bytes) == 0 or len(other_bytes) == 0:
        return None
    masks = [1, 2, 4, 8, 16, 32, 64, 128]
    diffbits = 0
    totalbits = 0
    for this_byte, other_byte in zip(this_bytes, other_bytes):
        for mask in masks:
            this_masked = mask & this_byte
            other_masked = mask & other_byte
            diffbits += this_masked != other_masked
            totalbits += 1
    doubdiff = diffbits / totalbits
    return int(doubdiff * 100)


@classmethod
def _fmt_auto(cls, x, **kw):
    """auto formatting class-method."""
    f = cls._to_float(x)
    if abs(f) > 100000000.0:
        fn = cls._fmt_exp
    elif f != f:
        fn = cls._fmt_text
    elif f - round(f) == 0:
        fn = cls._fmt_int
    else:
        fn = cls._fmt_float
    return fn(x, **kw)


def _copy_channel(inst, ch_name, new_ch_name):
    """Add a copy of a channel specified by ch_name.

    Input data can be in the form of Raw, Epochs or Evoked.

    The instance object is modified inplace.

    Parameters
    ----------
    inst : instance of Raw | Epochs | Evoked
        Data containing the EEG channels
    ch_name : str
        Name of the channel to copy.
    new_ch_name : str
        Name given to the copy of the channel.

    Returns
    -------
    inst : instance of Raw | Epochs | Evoked
        The data with a copy of a given channel.
    """
    new_inst = inst.copy().pick_channels([ch_name])
    new_inst.rename_channels({ch_name: new_ch_name})
    inst.add_channels([new_inst], force_update_info=True)
    return inst


def getNodes(requestor, service, nodeIdentifier):
    """
        Get all nodes contained by this node.

        @param requestor: The entity the request originated from.
        @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param service: The publish-subscribe service entity.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: Identifier of the node to request the childs
            for.
        @type nodeIdentifier: C{unicode}
        @return: A deferred that fires with a list of child node identifiers.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def _check_string(s: str) ->bool:
    """Check if s is a string

    :param s: string to check
    :returns True if s is a string
    """
    return isinstance(s, str)


def _balance_partitions(x, N_partitions, N_elements):
    """Balances out the number of elements across the partitions"""
    n_per_part = N_elements / N_partitions / 2
    part = 0
    if x > N_elements / 2:
        x = N_elements - x
    part = x / n_per_part
    return part if part < N_partitions else part - 1


def load_state_dict(monitor, state):
    """
        pytorch-like API. Alias for __setstate__

        Args:
            state (Dict):
        """
    return monitor.__setstate__(state)


def getab(taub, taud):
    """calculates value of ab in equation (19)

    Equation (19) in ASHRAE Fundamentals 2009 pg 14.9

    Parameters
    ----------
    taub : float
        value of taub in equation (19)
    taud : float
        value of taud in equation (19)

    Returns
    -------
    float
        the value of ab

    """
    v1 = 1.219
    v2 = 0.043 * taub
    v3 = 0.151 * taud
    v4 = 0.204 * taub * taud
    return v1 - v2 - v3 - v4


def define_attrs(required, extra=[]):
    """Create __slots__ by adding extra attributes to required ones"""
    slots = tuple(required + extra)
    attributes = tuple(required)
    return slots, attributes


def contingency_table(dataframe, rownames, colnames, margins=True):
    """Contingency Table (also called Cross Tabulation)
       - Table in a matrix format that displays the (multivariate) frequency distribution of the variables
       - http://en.wikipedia.org/wiki/Contingency_table
       Args:
           rownames: the column name or list of columns names that make the keys of the rows
           colnames: the column name or list of columns names that make the keys of the columns
    """
    sub_set = [rownames, colnames]
    _sub_df = dataframe[sub_set]
    return _sub_df.pivot_table(index=rownames, columns=colnames, margins=
        margins, aggfunc=len, fill_value=0)


def _descend_namespace(caller_globals, name):
    """
    Given a globals dictionary, and a name of the form "a.b.c.d", recursively
    walk the globals expanding caller_globals['a']['b']['c']['d'] returning
    the result. Raises an exception (IndexError) on failure.
    """
    names = name.split('.')
    cur = caller_globals
    for i in names:
        if type(cur) is dict:
            cur = cur[i]
        else:
            cur = getattr(cur, i)
    return cur


@classmethod
def describe(cls):
    """
        Prints in the console a table showing the key, the label and the extra
        of all the definitions inside the class

        :return: None
        """
    key_list = list(map(str, cls.keys())) + ['Key']
    max_ = max(list(map(len, key_list)))
    if max_ < 2:
        max_ = 2
    row_format = '{:>' + str(max_) + '}' + ' | {:} | {:}'
    headers = ['Key', 'Label', 'Extra']
    print('Class: ', cls.__name__)
    header_line = row_format.format(*headers)
    print(header_line)
    print('-' * (len(header_line) - 1))
    for item in cls:
        print(row_format.format(str(item.key), item.label, item.extra))


@staticmethod
def get_extensions():
    """
        Returns supported extensions of the DCC
        :return: list(str)
        """
    return ['.ma', '.mb']


def irep(x, n, dim):
    """Replicate x n-times on a new dimension dim-th dimension"""
    x_shape = x.shape
    shp = x_shape[:dim] + (1,) + x_shape[dim:]
    return x.reshape(shp).repeat(n, axis=dim)


def download(sid):
    """
    neuropythy.hcp.download(sid) is equivalent to neuropythy.data['hcp'].download(sid).
    """
    import neuropythy as ny
    return ny.data['hcp'].download(sid)


@classmethod
def get_css_classes(cls, instance):
    """
        Returns a list of CSS classes to be added as class="..." to the current HTML tag.
        """
    if getattr(cls, 'default_css_class', None):
        css_classes = [cls.default_css_class]
    else:
        css_classes = []
    return css_classes


def add_int_enums_to_docstring(enum):
    """Decorator for IntEnum which re-writes the documentation string so that
    Sphinx enumerates all the enumeration values.

    This is a work-around for Sphinx autodoc's inability to properly document
    IntEnums.

    This decorator adds enumeration names and values to the 'Attributes'
    section of the docstring of the decorated IntEnum class.

    Example::

        >>> from enum import IntEnum
        >>> @add_int_enums_to_docstring
        ... class MyIntEnum(IntEnum):
        ...     '''An example IntEnum.'''
        ...     a = 0
        ...     b = 1
        >>> print(MyIntEnum.__doc__)
        An example IntEnum.
        <BLANKLINE>
        Attributes
        ----------
        a = 0
        b = 1
        <BLANKLINE>
    """
    if enum.__doc__ is None:
        enum.__doc__ = ''
    enum.__doc__ += '\n\nAttributes\n----------\n'
    for val in list(enum):
        enum.__doc__ += '{} = {}\n'.format(val.name, int(val))
    return enum


def double_linear_con(progress):
    """
    Returns a linear value (x2) with a flattened tail for the Scheduler

    :param progress: (float) Current progress status (in [0, 1])
    :return: (float) 1 - progress*2 if (1 - progress*2) >= 0.125 else 0.125
    """
    progress *= 2
    eps = 0.125
    if 1 - progress < eps:
        return eps
    return 1 - progress


@classmethod
def _get_default(cls, attribute):
    """Return the default value for `attribute`.

        If no default is specified in this style, get the default from the
        nearest superclass.
        If `attribute` is not supported, raise a :class:`KeyError`."""
    try:
        for klass in cls.__mro__:
            if attribute in klass._attributes:
                return klass._attributes[attribute].default_value
    except AttributeError:
        raise KeyError("No attribute '{}' in {}".format(attribute, cls))


def check_dht_value_type(value):
    """
    Checks to see if the type of the value is a valid type for
    placing in the dht.
    """
    typeset = [int, float, bool, str, bytes]
    return type(value) in typeset


def clothing(inp):
    """ A dummy function the just copy the input to the output.

    <unit>
        <output name="outp" type="Str" description="test" />
        <input name="inp" type="Str" description="test" />
    </unit>
    """
    outp = inp
    return outp


@staticmethod
def compute_block_metric(block):
    """Return comparable metric on block information."""
    instruction_ctr = 0
    for line in block:
        if line.instruction is None:
            continue
        instruction_ctr += 1
    return instruction_ctr


def tuplesort(seq):
    """
    Sort a list by a sequence.

    Parameters
    ----------
    seq : tuple
        Sequence to sort by
    """
    return sorted(range(len(seq)), key=seq.__getitem__)


@classmethod
def static_header_len(cls, height):
    """Given a header height return its length."""
    if height >= cls.ZEROCOIN_START_HEIGHT:
        return cls.ZEROCOIN_HEADER
    else:
        return cls.BASIC_HEADER_SIZE


def enable_lazy():
    """Convenience function for configuring _() to use lazy gettext

    Call this at the start of execution to enable the gettextutils._
    function to use lazy gettext functionality. This is useful if
    your project is importing _ directly instead of using the
    gettextutils.install() way of importing the _ function.
    """
    global USE_LAZY
    USE_LAZY = True


def cena_constant_tau(imt, mag, params):
    """
    Returns the inter-event tau for the constant tau case
    """
    if imt.name == 'PGV':
        return params['PGV']['tau']
    else:
        return params['SA']['tau']


def broadcast_logical_xor(lhs=None, rhs=None, name=None, attr=None, out=
    None, **kwargs):
    """Returns the result of element-wise **logical xor** with broadcasting.

    Example::

       x = [[ 1.,  1.,  0.],
            [ 1.,  1.,  0.]]

       y = [[ 1.],
            [ 0.]]

       broadcast_logical_xor(x, y) = [[ 0.,  0.,  1.],
                                      [ 1.,  1.,  0.]]

    Defined in src/operator/tensor/elemwise_binary_broadcast_op_logic.cc:L190

    Parameters
    ----------
    lhs : Symbol
        First input to the function
    rhs : Symbol
        Second input to the function

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

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


def show_taglist(obj):
    """Additional prompt to show unique tag list.

    Parameters
    ----------
    obj : BukuDb instance
        A valid instance of BukuDb class.
    """
    unique_tags, dic = obj.get_tag_all()
    if not unique_tags:
        count = 0
        print('0 tags')
    else:
        count = 1
        for tag in unique_tags:
            print('%6d. %s (%d)' % (count, tag, dic[tag]))
            count += 1
        print()


def _get_writable(stream_or_path, mode):
    """This method returns a tuple containing the stream and a flag to indicate
    if the stream should be automatically closed.

    The `stream_or_path` parameter is returned if it is an open writable stream.
    Otherwise, it treats the `stream_or_path` parameter as a file path and
    opens it with the given mode.

    It is used by the svg and png methods to interpret the file parameter.

    :type stream_or_path: str | io.BufferedIOBase
    :type mode: str | unicode
    :rtype: (io.BufferedIOBase, bool)
    """
    is_stream = hasattr(stream_or_path, 'write')
    if not is_stream:
        stream_or_path = open(stream_or_path, mode)
    return stream_or_path, not is_stream


def is_main_process():
    """ Check if this is the main control process and may handle one time tasks
    """
    try:
        from mpi4py import MPI
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()
        return rank == 0
    except (ImportError, ValueError, RuntimeError):
        return True


@staticmethod
def evaluation_at(sub_expr1, sub_expr2, val_dict):
    """
        Compute addition of sub_expr1 with sub_expr2 using inputs of variable
        values from val_dict.

        INPUTS
        =======
        sub_expr1: expression or constant
        sub_expr2: expression or constant
        val_dict: a dictionary containing variable name and values.

        RETURNS
        ========
        sub_expr1 + sub_expr2
        """
    return sub_expr1.evaluation_at(val_dict) + sub_expr2.evaluation_at(val_dict
        )


def oracle_add_escape(_value, _escape_character):
    """Add the oracle escape ke_delimiteryword if nessesary."""
    if _escape_character not in ('', None):
        return _value + " ESCAPE '" + _escape_character + "'"
    else:
        return _value


@staticmethod
def add(store_track):
    """Build a track add event.

		Parameters:
			store_track (dict): A store track dict.

		Returns:
			dict: A mutation dict.
		"""
    store_track['trackType'] = 8
    return {'create': store_track}


def python_3000_not_equal(logical_line):
    """New code should always use != instead of <>.

    The older syntax is removed in Python 3.

    Okay: if a != 'no':
    W603: if a <> 'no':
    """
    pos = logical_line.find('<>')
    if pos > -1:
        yield pos, "W603 '<>' is deprecated, use '!='"


def convert_coordinates(q, conversion, axisorder):
    """
    Convert a 3-tuple in data coordinates into to simplex data
    coordinates for plotting.

    Parameters
    ----------
    q: 3-tuple
       the point to be plotted in data coordinates

    conversion: dict
        keys = ['b','l','r']
        values = lambda function giving the conversion
    axisorder: String giving the order of the axes for the coordinate tuple
        e.g. 'blr' for bottom, left, right coordinates.

    Returns
    -------
    p: 3-tuple
       The point converted to simplex coordinates.
    """
    p = []
    for k in range(3):
        p.append(conversion[axisorder[k]](q[k]))
    return tuple(p)


def parse_fasta_entry(text, known_species=None):
    """Split an entry of "Acession genus species etc" into fields.

    Returns a two-tuple of taxid (always zero), genus-species.

    >>> parse_fasta_entry('HQ013219 Phytophthora arenaria')
    (0, 'Phytophthora arenaria')

    >>> parse_fasta_entry('P13660 Phytophthora aff infestans')
    (0, 'Phytophthora aff infestans')
    """
    acc, sp = text.split(None, 1)
    taxid = 0
    return taxid, sp


def getTimeout():
    """ returns an integer value of the timeout setting """


@classmethod
def get_oauthlib_core(cls):
    """
        Cache and return `OAuthlibCore` instance so it will be created only on first request
        """
    if not hasattr(cls, '_oauthlib_core'):
        server = cls.get_server()
        core_class = cls.get_oauthlib_backend_class()
        cls._oauthlib_core = core_class(server)
    return cls._oauthlib_core


def fix(data=None, out=None, name=None, **kwargs):
    """Returns element-wise rounded value to the nearest \\
    integer towards zero of the input.

    Example::

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

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

       - fix(default) = default
       - fix(row_sparse) = row_sparse
       - fix(csr) = csr

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

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

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

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


def calculate_time_difference(startDate, endDate):
    """
    *Return the time difference between two dates as a string*

    **Key Arguments**

    - ``startDate`` -- the first date in YYYY-MM-DDTHH:MM:SS format
    - ``endDate`` -- the final date YYYY-MM-DDTHH:MM:SS format

    **Return**

    - ``relTime`` -- the difference between the two dates in Y,M,D,h,m,s (string)

    **Usage**

    ```python
    from fundamentals import times
    diff = times.calculate_time_difference(startDate="2015-10-13 10:02:12", endDate="2017-11-04 16:47:05")
    print diff

    # OUT: 2yrs 22dys 6h 44m 53s
    ```
    """
    from datetime import datetime
    from dateutil import relativedelta
    if 'T' not in startDate:
        startDate = startDate.strip().replace(' ', 'T')
    if 'T' not in endDate:
        endDate = endDate.strip().replace(' ', 'T')
    startDate = datetime.strptime(startDate, '%Y-%m-%dT%H:%M:%S')
    endDate = datetime.strptime(endDate, '%Y-%m-%dT%H:%M:%S')
    d = relativedelta.relativedelta(endDate, startDate)
    relTime = ''
    if d.years > 0:
        relTime += str(d.years) + 'yrs '
    if d.months > 0:
        relTime += str(d.months) + 'mths '
    if d.days > 0:
        relTime += str(d.days) + 'dys '
    if d.hours > 0:
        relTime += str(d.hours) + 'h '
    if d.minutes > 0:
        relTime += str(d.minutes) + 'm '
    if d.seconds > 0:
        relTime += str(d.seconds) + 's'
    if relTime == '':
        relTime = '0s'
    return relTime


def trackbar(theWhere, theX, theY, theWidth, theValue, theMin, theMax,
    theSegments=1, theLabelFormat='%.1Lf', theOptions=0, theDiscreteStep=1):
    """
	Display a trackbar for numeric values that the user can increase/decrease
	by clicking and/or dragging the marker right or left. This component can use
	different types of data as its value, so it is imperative provide the right
	label format, e.g. '%d' for ints, otherwise you might end up with weird errors.

	Example:

	```
	# using float
	trackbar(where, x, y, width, &floatValue, 0.0, 50.0)

	# using float
	trackbar(where, x, y, width, &floatValue, 0.0f, 50.0f)

	# using char
	trackbar(where, x, y, width, &charValue, (char)1, (char)10)
	```

	Parameters
	----------
	theWhere: np.ndarray
		image/frame where the component should be rendered.
	theX: int
		position X where the component should be placed.
	theY: int
		position Y where the component should be placed.
	theWidth: int
		width of the trackbar.
	theValue: [number]
		array or list of numbers whose first position, i.e. theValue[0], will be used to store the current value of the trackbar. It will be modified when the user interacts with the trackbar. Any numeric type can be used, e.g. int, float, long double, etc.
	theMin: number
		minimum value allowed for the trackbar.
	theMax: number
		maximum value allowed for the trackbar.
	theSegments: int
		number of segments the trackbar will have (default is 1). Segments can be seen as groups of numbers in the scale of the trackbar. For example, 1 segment means a single groups of values (no extra labels along the scale), 2 segments mean the trackbar values will be divided in two groups and a label will be placed at the middle of the scale.
	theLabelFormat: str
		formating string that will be used to render the labels. If you are using a trackbar with integers values, for instance, you can use `%d` to render labels.
	theOptions: uint
		options to customize the behavior/appearance of the trackbar, expressed as a bitset. Available options are defined as `cvui.TRACKBAR_` constants and they can be combined using the bitwise `|` operand. Available options are: `TRACKBAR_HIDE_SEGMENT_LABELS` (do not render segment labels, but do render min/max labels), `TRACKBAR_HIDE_STEP_SCALE` (do not render the small lines indicating values in the scale), `TRACKBAR_DISCRETE` (changes of the trackbar value are multiples of theDiscreteStep param), `TRACKBAR_HIDE_MIN_MAX_LABELS` (do not render min/max labels), `TRACKBAR_HIDE_VALUE_LABEL` (do not render the current value of the trackbar below the moving marker), `TRACKBAR_HIDE_LABELS` (do not render labels at all).
	theDiscreteStep: number
		amount that the trackbar marker will increase/decrease when the marker is dragged right/left (if option TRACKBAR_DISCRETE is ON)

	Returns
	----------
	`true` when the value of the trackbar changed.

	See Also
	----------
	counter()
	"""
    print('This is wrapper function to help code autocompletion.')


def select(choice_list):
    """ Ask the user to select an option
    choice_list: The list of options
    return the index of the choice
    """
    print('Please select an option :')
    for index, choice in choice_list.items():
        print('\t{}) {}'.format(index, choice))
    choice = int(input('-> '))
    while not choice in choice_list:
        print('Invalid value')
        choice = int(input('-> '))
    return choice


def common_elements(left, right) ->int:
    """ Returns the number of elements that are common between `left` and `right`"""
    common = set(left) & set(right)
    return len(common)


def vibe_check(feature_ranks, table_sdf, safe_range=[-9007199254740991,
    9007199254740991]):
    """Returns an error if the input data can't be safely used in Qurro as is.

       Our definition of "safe" here is that none of these DataFrames contain
       any numeric values that are outside the specified safe numeric range. By
       default, this range is [-(2**53 - 1), (2**53 - 1)].

       Primarily, this is useful for validating the BIOM table and feature
       rankings. I imagine the presence of things like numeric IDs in the
       metadata will make this hard to properly screen for without introducing
       a ton of false positives, which will annoy people; maybe we can make the
       simplifying assumption that if your data is in a categorical metadata
       column then you don't care about its numeric representation?

       Parameters
       ----------

       feature_ranks: pd.DataFrame
            A DataFrame defining feature rankings, where the index corresponds
            to feature IDs and the columns correspond to ranking names.
            Critically, every entry in this should be numeric.

       table_sdf: pd.DataFrame (or pd.SparseDataFrame)
            DataFrame representation of a feature table. Similarly to the
            feature rankings, every entry in this should be numeric.

       safe_range: collection with exactly two entries
            The first entry in the safe_range specifies the minimum value we
            allow, and the second entry specifies the maximum value we allow.
            Any numbers outside of this range are deemed to "fail the vibe
            check," in internet meme parlance circa autumn 2019.

       Returns
       -------

       None

       Raises
       ------

       ValueError: if safe_range does not contain exactly two entries, or
                   if the second entry in safe_range is less than or equal to
                   the first entry in safe_range

       OverflowError: if the feature rankings or BIOM table inputs contain any
                      numbers outside of the specified safe range
    """
    if len(safe_range) != 2:
        raise ValueError('safe_range must have a length of 2.')
    if safe_range[1] <= safe_range[0]:
        raise ValueError('safe_range[1] must be GREATER THAN safe_range[0].')
    upper_error = (
        'The input THING contains entries larger than the "safe" upper limit for numbers of {}. This means that the Qurro visualization interface is not usable, at least not currently. We suggest using Qurro\'s "Qarcoal" command to compute log-ratios outside of the Qurro visualization interface.'
        .format(safe_range[1]))
    lower_error = (
        'The input THING contains entries lower than the "safe" lower limit for numbers of {}. This means that the Qurro visualization interface is not usable, at least not currently. We suggest using Qurro\'s "Qarcoal" command to compute log-ratios outside of the Qurro visualization interface.'
        .format(safe_range[0]))
    for df, df_name in ((table_sdf, 'feature table'), (feature_ranks,
        'feature rankings data')):
        if (df > safe_range[1]).any().any():
            raise OverflowError(upper_error.replace('THING', df_name))
        if (df < safe_range[0]).any().any():
            raise OverflowError(lower_error.replace('THING', df_name))


@classmethod
def from_list(cls, l):
    """Generate an GeneSet object from a list of strings.

        Note: See also :meth:`to_list`.

        Parameters
        ----------
        l: list or tuple of str
            A list of strings representing gene set ID, name, genes,
            source, collection, and description. The genes must be
            comma-separated. See also :meth:`to_list`.

        Returns
        -------
        `genometools.basic.GeneSet`
            The gene set.
        """
    id_ = l[0]
    name = l[3]
    genes = l[4].split(',')
    src = l[1] or None
    coll = l[2] or None
    desc = l[5] or None
    return cls(id_, name, genes, src, coll, desc)


@classmethod
def from_nested_parenthesis(cls, nested_parenthesis):
    """
        Initiate recursively a tree with tuple (node, (left value, right value))

        :example:

        >>> nested_par = ("+", (1, 2))
        >>> t = Tree.from_nested_parenthesis(nested_par)
        >>> t.node
        '+'
        >>> t.left_value
        1
        >>> t.right_value
        2
        >>> nested_par = ("+", (
        ...    ("*", (3, 4)),
        ...    2))
        >>> t = Tree.from_nested_parenthesis(nested_par)
        >>> t.node
        '+'
        >>> type(t.left_value)
        <class 'mapytex.calculus.core.tree.Tree'>
        >>> t.right_value
        2

        """
    try:
        nested_len = len(nested_parenthesis)
        num_len = len(nested_parenthesis[1])
    except TypeError:
        raise ValueError('Nested parenthesis are not composed of lists')
    if nested_len != 2 and num_len != 2:
        raise ValueError("Nested parenthesis don't have right shape")
    node = nested_parenthesis[0]
    try:
        left_value = cls.from_nested_parenthesis(nested_parenthesis[1][0])
    except ValueError:
        left_value = nested_parenthesis[1][0]
    try:
        right_value = cls.from_nested_parenthesis(nested_parenthesis[1][1])
    except ValueError:
        right_value = nested_parenthesis[1][1]
    return cls(node, left_value, right_value)


def get_func_name(func):
    """Return a name which includes the module name and function name."""
    func_name = getattr(func, '__name__', func.__class__.__name__)
    module_name = func.__module__
    if module_name is not None:
        module_name = func.__module__
        return '{}.{}'.format(module_name, func_name)
    return func_name


def extract_barcode(record, embedded_barcode):
    """extracts barcodes from a fastq record according to an EmbeddedBarcode object.

    :param FastqRecord record: record to extract from
    :param EmbeddedBarcode embedded_barcode: defines the barcode start and end and the names of the quality
      and sequence tags
    :return tuple: (sequence tag name, tag content (nucleotides), tag type (Z))
    :return tuple: (quality tag name, tag content (qualities), tag type (Z))
    """
    seq = record.sequence[embedded_barcode.start:embedded_barcode.end]
    qual = record.quality[embedded_barcode.start:embedded_barcode.end]
    return (embedded_barcode.sequence_tag, seq, 'Z'), (embedded_barcode.
        quality_tag, qual, 'Z')


@classmethod
def export_to_hdf5(cls, h5_file, model, eids):
    """exports the elements in a vectorized way"""
    pids = []
    nodes = []
    for eid in eids:
        element = model.elements[eid]
        pids.append(element.pid)
        nodes.append(element.nodes)
    h5_file.create_dataset('eid', data=eids)
    h5_file.create_dataset('pid', data=pids)
    h5_file.create_dataset('nodes', data=nodes)


def GetExportPath(G2frame):
    """Determines the default location to use for writing files. Tries sequentially
    G2frame.LastExportDir and G2frame.LastGPXdir.

    :returns: a string containing the path to be used when writing files or '.'
      if none of the above are specified.
    """
    if G2frame.LastExportDir:
        return G2frame.LastExportDir
    elif G2frame.LastGPXdir:
        return G2frame.LastGPXdir
    else:
        return '.'


@staticmethod
def _set_widget_background_color(widget, color):
    """
        Changes the base color of a widget (background).
        :param widget: widget to modify
        :param color: the color to apply
        """
    pal = widget.palette()
    pal.setColor(pal.Base, color)
    widget.setPalette(pal)


def tuple_factory(colnames, rows):
    """
    Returns each row as a tuple

    Example::

        >>> from cassandra.query import tuple_factory
        >>> session = cluster.connect('mykeyspace')
        >>> session.row_factory = tuple_factory
        >>> rows = session.execute("SELECT name, age FROM users LIMIT 1")
        >>> print rows[0]
        ('Bob', 42)

    .. versionchanged:: 2.0.0
        moved from ``cassandra.decoder`` to ``cassandra.query``
    """
    return rows


@staticmethod
def calculate_text_coords(rectangle_coords):
    """Calculate Canvas text coordinates based on rectangle coords"""
    return int(rectangle_coords[0] + (rectangle_coords[2] -
        rectangle_coords[0]) / 2), int(rectangle_coords[1] + (
        rectangle_coords[3] - rectangle_coords[1]) / 2)


@staticmethod
def exclude_all(items):
    """
        Test if an array-like field doesn't include any of these items.

        Example::

            {"tag": ["a", "b", "c"]} doesn't include any of ["d", "e"]
        """
    return {'$nin': items}


def __call__(cls, value, names=None, module=None, type=None, start=1):
    """Either returns an existing member, or creates a new enum class.

        This method is used both when an enum class is given a value to match
        to an enumeration member (i.e. Color(3)) and for the functional API
        (i.e. Color = Enum('Color', names='red green blue')).

        When used for the functional API: `module`, if set, will be stored in
        the new class' __module__ attribute; `type`, if set, will be mixed in
        as the first base class.

        Note: if `module` is not set this routine will attempt to discover the
        calling module by walking the frame stack; if this is unsuccessful
        the resulting class will not be pickleable.

        """
    if names is None:
        return cls.__new__(cls, value)
    return cls._create_(value, names, module=module, type=type, start=start)


def get_step_f(step_f, lR2, lS2):
    """Update the stepsize of given the primal and dual errors.

    See Boyd (2011), section 3.4.1
    """
    mu, tau = 10, 2
    if lR2 > mu * lS2:
        return step_f * tau
    elif lS2 > mu * lR2:
        return step_f / tau
    return step_f


def _getDictWithKey(key, dict_list):
    """ Returns the first dictionary in dict_list which contains the given key"""
    for d in dict_list:
        if key in d:
            return d
    return None


def run_instances(DryRun=None, ImageId=None, MinCount=None, MaxCount=None,
    KeyName=None, SecurityGroups=None, SecurityGroupIds=None, UserData=None,
    InstanceType=None, Placement=None, KernelId=None, RamdiskId=None,
    BlockDeviceMappings=None, Monitoring=None, SubnetId=None,
    DisableApiTermination=None, InstanceInitiatedShutdownBehavior=None,
    PrivateIpAddress=None, Ipv6Addresses=None, Ipv6AddressCount=None,
    ClientToken=None, AdditionalInfo=None, NetworkInterfaces=None,
    IamInstanceProfile=None, EbsOptimized=None, TagSpecifications=None):
    """
    Launches the specified number of instances using an AMI for which you have permissions.
    You can specify a number of options, or leave the default options. The following rules apply:
    To ensure faster instance launches, break up large requests into smaller batches. For example, create 5 separate launch requests for 100 instances each instead of 1 launch request for 500 instances.
    An instance is ready for you to use when it's in the running state. You can check the state of your instance using  DescribeInstances . You can tag instances and EBS volumes during launch, after launch, or both. For more information, see  CreateTags and Tagging Your Amazon EC2 Resources .
    Linux instances have access to the public key of the key pair at boot. You can use this key to provide secure access to the instance. Amazon EC2 public images use this feature to provide secure access without passwords. For more information, see Key Pairs in the Amazon Elastic Compute Cloud User Guide .
    For troubleshooting, see What To Do If An Instance Immediately Terminates , and Troubleshooting Connecting to Your Instance in the Amazon Elastic Compute Cloud User Guide .
    See also: AWS API Documentation

    :example: response = client.run_instances(
        DryRun=True|False,
        ImageId='string',
        MinCount=123,
        MaxCount=123,
        KeyName='string',
        SecurityGroups=[
            'string',
        ],
        SecurityGroupIds=[
            'string',
        ],
        UserData='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',
            'HostId': 'string',
            'Affinity': 'string'
        },
        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',
        DisableApiTermination=True|False,
        InstanceInitiatedShutdownBehavior='stop'|'terminate',
        PrivateIpAddress='string',
        Ipv6Addresses=[
            {
                'Ipv6Address': 'string'
            },
        ],
        Ipv6AddressCount=123,
        ClientToken='string',
        AdditionalInfo='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,
        TagSpecifications=[
            {
                'ResourceType': 'customer-gateway'|'dhcp-options'|'image'|'instance'|'internet-gateway'|'network-acl'|'network-interface'|'reserved-instances'|'route-table'|'snapshot'|'spot-instances-request'|'subnet'|'security-group'|'volume'|'vpc'|'vpn-connection'|'vpn-gateway',
                'Tags': [
                    {
                        'Key': 'string',
                        'Value': 'string'
                    },
                ]
            },
        ]
    )

    :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 ImageId: string
    :param ImageId: [REQUIRED]
            The ID of the AMI, which you can get by calling DescribeImages .

    :type MinCount: integer
    :param MinCount: [REQUIRED]
            The minimum number of instances to launch. If you specify a minimum that is more instances than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches no instances.
            Constraints: Between 1 and the maximum number you're allowed for the specified instance type. For more information about the default limits, and how to request an increase, see How many instances can I run in Amazon EC2 in the Amazon EC2 General FAQ.

    :type MaxCount: integer
    :param MaxCount: [REQUIRED]
            The maximum number of instances to launch. If you specify more instances than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches the largest possible number of instances above MinCount .
            Constraints: Between 1 and the maximum number you're allowed for the specified instance type. For more information about the default limits, and how to request an increase, see How many instances can I run in Amazon EC2 in the Amazon EC2 FAQ.

    :type KeyName: string
    :param KeyName: The name of the key pair. You can create a key pair using CreateKeyPair or ImportKeyPair .
            Warning
            If you do not specify a key pair, you can't connect to the instance unless you choose an AMI that is configured to allow users another way to log in.

    :type SecurityGroups: list
    :param SecurityGroups: [EC2-Classic, default VPC] One or more security group names. For a nondefault VPC, you must use security group IDs instead.
            Default: Amazon EC2 uses the default security group.
            (string) --

    :type SecurityGroupIds: list
    :param SecurityGroupIds: One or more security group IDs. You can create a security group using CreateSecurityGroup .
            Default: Amazon EC2 uses the default security group.
            (string) --

    :type UserData: string
    :param UserData: The user data to make available to the instance. For more information, see Running Commands on Your Linux Instance at Launch (Linux) and Adding User Data (Windows). 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.
            This value will be base64 encoded automatically. Do not base64 encode this value prior to performing the operation.

    :type InstanceType: string
    :param InstanceType: The instance type. For more information, see Instance Types in the Amazon Elastic Compute Cloud User Guide .
            Default: m1.small

    :type Placement: dict
    :param Placement: The placement for the instance.
            AvailabilityZone (string) --The Availability Zone of the instance.
            GroupName (string) --The name of the placement group the instance is in (for cluster compute 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 the ImportInstance command.
            HostId (string) --The ID of the Dedicated Host on which the instance resides. This parameter is not supported for the ImportInstance command.
            Affinity (string) --The affinity setting for the instance on the Dedicated Host. This parameter is not supported for the ImportInstance command.

    :type KernelId: string
    :param KernelId: The ID of the kernel.
            Warning
            We recommend that you use PV-GRUB instead of kernels and RAM disks. For more information, see PV-GRUB in the Amazon Elastic Compute Cloud User Guide .

    :type RamdiskId: string
    :param RamdiskId: The ID of the RAM disk.
            Warning
            We recommend that you use PV-GRUB instead of kernels and RAM disks. For more information, see PV-GRUB in the Amazon Elastic Compute Cloud User Guide .

    :type BlockDeviceMappings: list
    :param BlockDeviceMappings: The block device mapping.
            Warning
            Supplying both a snapshot ID and an encryption value as arguments for block-device mapping results in an error. This is because only blank volumes can be encrypted on start, and these are not created from a snapshot. If a snapshot is the basis for the volume, it contains data by definition and its encryption status cannot be changed using this action.
            (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.

    :type Monitoring: dict
    :param Monitoring: The monitoring for the instance.
            Enabled (boolean) -- [REQUIRED]Indicates whether detailed monitoring is enabled. Otherwise, basic monitoring is enabled.

    :type SubnetId: string
    :param SubnetId: [EC2-VPC] The ID of the subnet to launch the instance into.

    :type DisableApiTermination: boolean
    :param DisableApiTermination: If you set this parameter to true , you can't terminate the instance using the Amazon EC2 console, CLI, or API; otherwise, you can. To change this attribute to false after launch, use ModifyInstanceAttribute . Alternatively, if you set InstanceInitiatedShutdownBehavior to terminate , you can terminate the instance by running the shutdown command from the instance.
            Default: false

    :type InstanceInitiatedShutdownBehavior: string
    :param InstanceInitiatedShutdownBehavior: Indicates whether an instance stops or terminates when you initiate shutdown from the instance (using the operating system command for system shutdown).
            Default: stop

    :type PrivateIpAddress: string
    :param PrivateIpAddress: [EC2-VPC] The primary IPv4 address. You must specify a value from the IPv4 address range of the subnet.
            Only one private IP address can be designated as primary. You can't specify this option if you've specified the option to designate a private IP address as the primary IP address in a network interface specification. You cannot specify this option if you're launching more than one instance in the request.

    :type Ipv6Addresses: list
    :param Ipv6Addresses: [EC2-VPC] Specify one or more IPv6 addresses from the range of the subnet to associate with the primary 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.

    :type Ipv6AddressCount: integer
    :param Ipv6AddressCount: [EC2-VPC] A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your 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.

    :type ClientToken: string
    :param ClientToken: Unique, case-sensitive identifier you provide to ensure the idempotency of the request. For more information, see Ensuring Idempotency .
            Constraints: Maximum 64 ASCII characters

    :type AdditionalInfo: string
    :param AdditionalInfo: Reserved.

    :type NetworkInterfaces: list
    :param NetworkInterfaces: One or more network interfaces.
            (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.

    :type IamInstanceProfile: dict
    :param IamInstanceProfile: The IAM instance profile.
            Arn (string) --The Amazon Resource Name (ARN) of the instance profile.
            Name (string) --The name of the instance profile.

    :type EbsOptimized: boolean
    :param EbsOptimized: Indicates whether the instance is 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

    :type TagSpecifications: list
    :param TagSpecifications: The tags to apply to the resources during launch. You can tag instances and volumes. The specified tags are applied to all instances or volumes that are created during launch.
            (dict) --The tags to apply to a resource when the resource is being created.
            ResourceType (string) --The type of resource to tag. Currently, the resource types that support tagging on creation are instance and volume .
            Tags (list) --The tags to apply to the resource.
            (dict) --Describes a tag.
            Key (string) --The key of the tag.
            Constraints: Tag keys are case-sensitive and accept a maximum of 127 Unicode characters. May not begin with aws:
            Value (string) --The value of the tag.
            Constraints: Tag values are case-sensitive and accept a maximum of 255 Unicode characters.

    :rtype: dict
    :return: {
        'ReservationId': 'string',
        'OwnerId': 'string',
        'RequesterId': 'string',
        'Groups': [
            {
                'GroupName': 'string',
                'GroupId': 'string'
            },
        ],
        'Instances': [
            {
                'InstanceId': 'string',
                'ImageId': 'string',
                'State': {
                    'Code': 123,
                    'Name': 'pending'|'running'|'shutting-down'|'terminated'|'stopping'|'stopped'
                },
                'PrivateDnsName': 'string',
                'PublicDnsName': 'string',
                'StateTransitionReason': 'string',
                'KeyName': 'string',
                'AmiLaunchIndex': 123,
                'ProductCodes': [
                    {
                        'ProductCodeId': 'string',
                        'ProductCodeType': 'devpay'|'marketplace'
                    },
                ],
                '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',
                'LaunchTime': datetime(2015, 1, 1),
                'Placement': {
                    'AvailabilityZone': 'string',
                    'GroupName': 'string',
                    'Tenancy': 'default'|'dedicated'|'host',
                    'HostId': 'string',
                    'Affinity': 'string'
                },
                'KernelId': 'string',
                'RamdiskId': 'string',
                'Platform': 'Windows',
                'Monitoring': {
                    'State': 'disabled'|'disabling'|'enabled'|'pending'
                },
                'SubnetId': 'string',
                'VpcId': 'string',
                'PrivateIpAddress': 'string',
                'PublicIpAddress': 'string',
                'StateReason': {
                    'Code': 'string',
                    'Message': 'string'
                },
                'Architecture': 'i386'|'x86_64',
                'RootDeviceType': 'ebs'|'instance-store',
                'RootDeviceName': 'string',
                'BlockDeviceMappings': [
                    {
                        'DeviceName': 'string',
                        'Ebs': {
                            'VolumeId': 'string',
                            'Status': 'attaching'|'attached'|'detaching'|'detached',
                            'AttachTime': datetime(2015, 1, 1),
                            'DeleteOnTermination': True|False
                        }
                    },
                ],
                'VirtualizationType': 'hvm'|'paravirtual',
                'InstanceLifecycle': 'spot'|'scheduled',
                'SpotInstanceRequestId': 'string',
                'ClientToken': 'string',
                'Tags': [
                    {
                        'Key': 'string',
                        'Value': 'string'
                    },
                ],
                'SecurityGroups': [
                    {
                        'GroupName': 'string',
                        'GroupId': 'string'
                    },
                ],
                'SourceDestCheck': True|False,
                'Hypervisor': 'ovm'|'xen',
                'NetworkInterfaces': [
                    {
                        'NetworkInterfaceId': 'string',
                        'SubnetId': 'string',
                        'VpcId': 'string',
                        'Description': 'string',
                        'OwnerId': 'string',
                        'Status': 'available'|'attaching'|'in-use'|'detaching',
                        'MacAddress': 'string',
                        'PrivateIpAddress': 'string',
                        'PrivateDnsName': 'string',
                        'SourceDestCheck': True|False,
                        'Groups': [
                            {
                                'GroupName': 'string',
                                'GroupId': 'string'
                            },
                        ],
                        'Attachment': {
                            'AttachmentId': 'string',
                            'DeviceIndex': 123,
                            'Status': 'attaching'|'attached'|'detaching'|'detached',
                            'AttachTime': datetime(2015, 1, 1),
                            'DeleteOnTermination': True|False
                        },
                        'Association': {
                            'PublicIp': 'string',
                            'PublicDnsName': 'string',
                            'IpOwnerId': 'string'
                        },
                        'PrivateIpAddresses': [
                            {
                                'PrivateIpAddress': 'string',
                                'PrivateDnsName': 'string',
                                'Primary': True|False,
                                'Association': {
                                    'PublicIp': 'string',
                                    'PublicDnsName': 'string',
                                    'IpOwnerId': 'string'
                                }
                            },
                        ],
                        'Ipv6Addresses': [
                            {
                                'Ipv6Address': 'string'
                            },
                        ]
                    },
                ],
                'IamInstanceProfile': {
                    'Arn': 'string',
                    'Id': 'string'
                },
                'EbsOptimized': True|False,
                'SriovNetSupport': 'string',
                'EnaSupport': True|False
            },
        ]
    }

    :returns:
    DryRun (boolean) -- 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 .
    ImageId (string) -- [REQUIRED]
    The ID of the AMI, which you can get by calling  DescribeImages .

    MinCount (integer) -- [REQUIRED]
    The minimum number of instances to launch. If you specify a minimum that is more instances than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches no instances.
    Constraints: Between 1 and the maximum number you're allowed for the specified instance type. For more information about the default limits, and how to request an increase, see How many instances can I run in Amazon EC2 in the Amazon EC2 General FAQ.

    MaxCount (integer) -- [REQUIRED]
    The maximum number of instances to launch. If you specify more instances than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches the largest possible number of instances above MinCount .
    Constraints: Between 1 and the maximum number you're allowed for the specified instance type. For more information about the default limits, and how to request an increase, see How many instances can I run in Amazon EC2 in the Amazon EC2 FAQ.

    KeyName (string) -- The name of the key pair. You can create a key pair using  CreateKeyPair or  ImportKeyPair .

    Warning
    If you do not specify a key pair, you can't connect to the instance unless you choose an AMI that is configured to allow users another way to log in.

    SecurityGroups (list) -- [EC2-Classic, default VPC] One or more security group names. For a nondefault VPC, you must use security group IDs instead.
    Default: Amazon EC2 uses the default security group.

    (string) --

    SecurityGroupIds (list) -- One or more security group IDs. You can create a security group using  CreateSecurityGroup .
    Default: Amazon EC2 uses the default security group.

    (string) --

    UserData (string) -- The user data to make available to the instance. For more information, see Running Commands on Your Linux Instance at Launch (Linux) and Adding User Data (Windows). 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.

    This value will be base64 encoded automatically. Do not base64 encode this value prior to performing the operation.

    InstanceType (string) -- The instance type. For more information, see Instance Types in the Amazon Elastic Compute Cloud User Guide .
    Default: m1.small

    Placement (dict) -- The placement for the instance.

    AvailabilityZone (string) --The Availability Zone of the instance.

    GroupName (string) --The name of the placement group the instance is in (for cluster compute 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 the  ImportInstance command.

    HostId (string) --The ID of the Dedicated Host on which the instance resides. This parameter is not supported for the  ImportInstance command.

    Affinity (string) --The affinity setting for the instance on the Dedicated Host. This parameter is not supported for the  ImportInstance command.

    KernelId (string) -- The ID of the kernel.

    Warning
    We recommend that you use PV-GRUB instead of kernels and RAM disks. For more information, see PV-GRUB in the Amazon Elastic Compute Cloud User Guide .

    RamdiskId (string) -- The ID of the RAM disk.

    Warning
    We recommend that you use PV-GRUB instead of kernels and RAM disks. For more information, see PV-GRUB in the Amazon Elastic Compute Cloud User Guide .

    BlockDeviceMappings (list) -- The block device mapping.

    Warning
    Supplying both a snapshot ID and an encryption value as arguments for block-device mapping results in an error. This is because only blank volumes can be encrypted on start, and these are not created from a snapshot. If a snapshot is the basis for the volume, it contains data by definition and its encryption status cannot be changed using this action.

    (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) -- The monitoring for the instance.

    Enabled (boolean) -- [REQUIRED]Indicates whether detailed monitoring is enabled. Otherwise, basic monitoring is enabled.

    SubnetId (string) -- [EC2-VPC] The ID of the subnet to launch the instance into.
    DisableApiTermination (boolean) -- If you set this parameter to true , you can't terminate the instance using the Amazon EC2 console, CLI, or API; otherwise, you can. To change this attribute to false after launch, use  ModifyInstanceAttribute . Alternatively, if you set InstanceInitiatedShutdownBehavior to terminate , you can terminate the instance by running the shutdown command from the instance.
    Default: false

    InstanceInitiatedShutdownBehavior (string) -- Indicates whether an instance stops or terminates when you initiate shutdown from the instance (using the operating system command for system shutdown).
    Default: stop

    PrivateIpAddress (string) -- [EC2-VPC] The primary IPv4 address. You must specify a value from the IPv4 address range of the subnet.
    Only one private IP address can be designated as primary. You can't specify this option if you've specified the option to designate a private IP address as the primary IP address in a network interface specification. You cannot specify this option if you're launching more than one instance in the request.

    Ipv6Addresses (list) -- [EC2-VPC] Specify one or more IPv6 addresses from the range of the subnet to associate with the primary 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) -- [EC2-VPC] A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your 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.
    ClientToken (string) -- Unique, case-sensitive identifier you provide to ensure the idempotency of the request. For more information, see Ensuring Idempotency .
    Constraints: Maximum 64 ASCII characters

    AdditionalInfo (string) -- Reserved.
    NetworkInterfaces (list) -- One or more network interfaces.

    (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 instance is 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

    TagSpecifications (list) -- The tags to apply to the resources during launch. You can tag instances and volumes. The specified tags are applied to all instances or volumes that are created during launch.

    (dict) --The tags to apply to a resource when the resource is being created.

    ResourceType (string) --The type of resource to tag. Currently, the resource types that support tagging on creation are instance and volume .

    Tags (list) --The tags to apply to the resource.

    (dict) --Describes a tag.

    Key (string) --The key of the tag.
    Constraints: Tag keys are case-sensitive and accept a maximum of 127 Unicode characters. May not begin with aws:

    Value (string) --The value of the tag.
    Constraints: Tag values are case-sensitive and accept a maximum of 255 Unicode characters.

    """
    pass


def differ_paths(old, new):
    """ Compare old and new paths """
    if old and old.endswith(('\\', '/')):
        old = old[:-1]
        old = old.replace('\\', '/')
    if new and new.endswith(('\\', '/')):
        new = new[:-1]
        new = new.replace('\\', '/')
    return new != old


def delete_slide(presentation, index):
    """Delete a slide from Presentation."""
    rid = presentation.slides._sldIdLst[index].rId
    presentation.part.drop_rel(rid)
    del presentation.slides._sldIdLst[index]


@classmethod
def rev_parse(cls, git, revision):
    """Parse revision string."""
    start, is_range, stop = revision.partition('..')
    if not is_range:
        start, stop = None, start
    elif not stop:
        stop = 'HEAD'
    return cls(start=git.rev_parse(start) if start else None, stop=git.
        rev_parse(stop))


def is_logout_request(assertion):
    u"""
    Проверка того, что это запрос (утверждение) на выход из системы

    :param assertion: Утверждение (Assertion, xml)
    :type assertion: etree.ElementTree
    :return: True, если запрос на выход
    :rtype: bool
    """
    logout_resp = assertion.xpath('//saml2p:LogoutRequest', namespaces={
        'saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol'})
    return len(logout_resp) > 0


def revision2doc(revision, page):
    """
    Implements RevisionDocument v0.0.2
    """
    redirect = None
    if page.redirect is not None:
        redirect = page.redirect.title
    page_doc = {'id': page.id, 'title': page.title, 'namespace': page.
        namespace, 'redirect_title': redirect, 'restrictions': page.
        restrictions}
    if revision.contributor is not None:
        contributor_doc = {'id': revision.contributor.id, 'user_text':
            revision.contributor.user_text}
    else:
        contributor_doc = None
    revision_doc = {'page': page_doc, 'id': revision.id, 'timestamp':
        revision.timestamp.long_format(), 'contributor': contributor_doc,
        'minor': revision.minor, 'comment': str(revision.comment) if
        revision.comment is not None else None, 'text': str(revision.text) if
        revision.text is not None else None, 'bytes': revision.bytes,
        'sha1': revision.sha1, 'parent_id': revision.parent_id, 'model':
        revision.model, 'format': revision.format}
    return revision_doc


def inc():
    """Increase the indentation"""
    global __count
    __count += 1


def fix_requirements(require_file):
    """
    Check the selected requirements file. If it contains
    a `pkg-resources==0.0.0` entry, then comment this line
    to prevent pip from crashing.
    """
    with open(require_file, 'r+') as f:
        content = f.read()
        if '#pkg-resources==0.0.0' in content:
            pass
        elif 'pkg-resources==0.0.0' in content:
            content = content.replace('pkg-resources==0.0.0',
                '#pkg-resources==0.0.0')
            f.seek(0)
            f.write(content)


def update(*args, **kwds):
    """od.update(E, **F) -> None.  Update od from dict/iterable E and F.

        If E is a dict instance, does:           for k in E: od[k] = E[k]
        If E has a .keys() method, does:         for k in E.keys(): od[k] = E[k]
        Or if E is an iterable of items, does:   for k, v in E: od[k] = v
        In either case, this is followed by:     for k, v in F.items(): od[k] = v

        """
    if len(args) > 2:
        raise TypeError(
            'update() takes at most 2 positional arguments (%d given)' % (
            len(args),))
    elif not args:
        raise TypeError('update() takes at least 1 argument (0 given)')
    self = args[0]
    other = ()
    if len(args) == 2:
        other = args[1]
    if isinstance(other, dict):
        for key in other:
            self[key] = other[key]
    elif hasattr(other, 'keys'):
        for key in other.keys():
            self[key] = other[key]
    else:
        for key, value in other:
            self[key] = value
    for key, value in kwds.items():
        self[key] = value


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

        :param files.SyncSettingsError val:
        :rtype: TeamFolderCreateError
        """
    return cls('sync_settings_error', val)


def __new__(cls, *args, **kwargs):
    """
        When a field is instantiated, we store the arguments that were used,
        so that we can present a helpful representation of the object.
        """
    instance = super().__new__(cls)
    instance._args = args
    instance._kwargs = kwargs
    return instance


def escape_filename(filename):
    """Surround filename in "" and escape " in the filename
    """
    filename = filename.replace('"', '\\"').replace('`', '\\`')
    filename = '"%s"' % filename
    return filename


def get_account_id_from_arn(trail_arn):
    """Gets the account ID portion of an ARN"""
    return trail_arn.split(':')[4]


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

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


def create_empty_context(version='2.5.6'):
    u"""
    Создание пустого контекста запроса, используемого для формирования
    СМЭВ-сообщения. В зависимости от версии, набор необходимых полей может
    меняться. По умолчанию формируется контекст для создания сообщения
    по версии 2.5.6 МР и проставляется флаг тестового взаимодействия.

    В случае запроса формирования контекста по неподдерживаемой нами
    версии МР - выбрасывается исключение.

    :param str version: Версия МР, для которой создается контекст.
    :return: Словарь контекста.
    :rtype: dict
    """
    blanks = {'2.5.6': {'Sender': {'Code': u'', 'Name': u''}, 'Originator':
        {'Code': u'', 'Name': u''}, 'Recipient': {'Code': u'', 'Name':
        u'Recipient'}, 'Service': {'Mnemonic': u'', 'Version': u''},
        'Status': 'REQUEST', 'TypeCode': 'GSRV', 'TestMsg': True}, '2.5.5':
        {'Sender': {'Code': u'', 'Name': u''}, 'Originator': {'Code': u'',
        'Name': u''}, 'Recipient': {'Code': u'', 'Name': u'Recipient'},
        'ServiceName': u'', 'Status': 'REQUEST', 'TypeCode': 'GSRV',
        'TestMsg': True}}
    assert version in blanks, 'Unknown SMEV version: %s' % version
    return blanks[version]


def is_authenticated(request):
    """
    Returns True if request.user authenticated else returns False
    """
    return request.user.is_authenticated


def sayhi():
    """ function to return the string 'my first package' """
    return (
        "This is Tarek Saliba's first package that anyone can install it! How cool!!!"
        )


@classmethod
def from_path(cls, path, encoding='utf-8', serializer='yaml', resolver=None,
    default=None):
    """
        Create config from a single file
        :type path: six.text_type|six.string_type
        :type encoding: six.string_types
        :type serializer: ISerializer|six.text_type|six.binary_type
        :type resolver: DSLResolver
        :type default: collections.Mapping
        :rtype: Config
        """
    return cls.from_files(files=[path], encoding=encoding, serializer=
        serializer, resolver=resolver, default=default)


def sculptmode_toggle():
    """Toggle sculpt mode in 3D view

    """
    pass


def concat_iter(*iters):
    """Concatenate iterators"""
    for iterator in iters:
        for value in iterator:
            yield value


def cross3(v1, v2):
    """
    Quick convenient function to compute cross product betwee two 3-element vectors
    cross3: 326 ns | np.cross: 35.8 us
    """
    a1, a2, a3 = v1
    b1, b2, b3 = v2
    return [a2 * b3 - a3 * b2, a3 * b1 - a1 * b3, a1 * b2 - a2 * b1]


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


def addAnswer(value, comments=''):
    """Add an answer and optional comments for a user.
        This method protects _addAnswer from anonymous users specifying a
        userid when they vote, and thus apparently voting as another user
        of their choice.
        """


def _write_qt_qmake_config(qt_qmake_config, pro):
    """ Write the qmake configuration values to a .pro file. """
    for name in ('QT', 'CONFIG', 'DEFINES', 'INCLUDEPATH', 'LIBS'):
        value = qt_qmake_config.get(name)
        if value:
            pro.write('    %s += %s\n' % (name, value))


def _string_rpc_registration_request(rpc):
    """Converts ServerOriginatedRPC or RPCSignature to a string."""
    if rpc is None:
        return None
    args = sorted(map(lambda x: x.name, rpc.arguments))
    return rpc.name + '(' + ','.join(args) + ')'


def numpy2oracle(dtype):
    """Takes a numpy dtype object and converts to an Oracle data type
    string.

    TODO: Vectorize?

    Parameters:
    ----------
    dtype: Numpy dtype object

    Returns:
    --------
    otype: Oracle data type string
    """
    kind = dtype.kind
    size = dtype.itemsize
    if kind == 'S':
        return 'VARCHAR2(%d)' % size
    elif kind == 'i' or kind == 'u':
        if size == 1:
            return 'NUMBER(3,0)'
        elif size == 2:
            return 'NUMBER(5,0)'
        elif size == 4:
            return 'NUMBER(10,0)'
        else:
            return 'NUMBER(20,0)'
    elif kind == 'f':
        if size == 4:
            return 'BINARY_FLOAT'
        elif size == 8:
            return 'BINARY_DOUBLE'
        else:
            msg = 'Unsupported float type: %s' % kind
            raise ValueError(msg)
    elif kind == 'M':
        return 'DATETIME'
    elif kind == 'O':
        return 'OBJECT'
    else:
        return ''


def get_rv_toolkits():
    """Returns a list of reference viewer supported toolkits."""
    return ['qt4', 'qt5', 'pyside', 'pyside2', 'gtk3', 'pg']


def handle_message(sender, message):
    """
    Handles message events from the AlarmDecoder.
    """
    print(sender, message.raw)


@staticmethod
def extensions():
    """Return accepted extensions for this loader"""
    return ('bmp', 'jpg', 'jpeg', 'jpe', 'lbm', 'pcx', 'png', 'pnm', 'tga',
        'tiff', 'webp', 'xcf', 'xpm', 'xv')


def write_app_urls(app_name):
    """Writes a basic urls.py for a django-app"""
    urls_imports = ['from django.conf.urls import url\n',
        'from . import views\n']
    app_name_line = "app_name= '%s'\n" % app_name
    url_pattern_lines = ['urlpatterns= [\n',
        "  url(r'^$',views.index,name='index'),\n", '  ]\n']
    out_file = open('urls.py', 'w')
    for line in urls_imports:
        out_file.write(line)
    out_file.write(app_name_line)
    for line in url_pattern_lines:
        out_file.write(line)
    out_file.close()


def check_host(host):
    """ Helper function to get the hostname in desired format """
    if not ('http' in host and '//' in host) and host[len(host) - 1] == '/':
        return ''.join(['http://', host[:len(host) - 1]])
    elif not ('http' in host and '//' in host):
        return ''.join(['http://', host])
    elif host[len(host) - 1] == '/':
        return host[:len(host) - 1]
    else:
        return host


def print2(parameter, string):
    """ Show the message on the console and also save in a list for future backup. """
    print(string)
    parameter.append(string)


def check_upload_method_permissions(user, translation, method: str):
    """Check whether user has permission to perform upload method."""
    if method == 'source':
        return (translation.is_source and not translation.filename and user
            .has_perm('upload.perform', translation))
    if method in ('translate', 'fuzzy'):
        return user.has_perm('unit.edit', translation)
    if method == 'suggest':
        return not translation.is_readonly and user.has_perm('suggestion.add',
            translation)
    if method == 'approve':
        return user.has_perm('unit.review', translation)
    if method == 'replace':
        return translation.filename and user.has_perm('component.edit',
            translation)
    raise ValueError(f'Invalid method: {method}')


def chunks(iterable, n):
    """Yield iterable split into chunks.

    If 'n' is an integer, yield the iterable as n-sized chunks.
    If 'n' is a list of integers, yield chunks of sizes: n[0],
    n[1], ..., len(iterable) - sum(n)

    >>> from invenio_sipstore.archivers.utils import chunks
    >>> list(chunks('abcdefg', 3))
    ['abc', 'def', 'g']
    >>> list(chunks('abcdefg', [1, ]))
    ['a', 'bcdefg']
    >>> list(chunks('abcdefg', [1, 2, 3]))
    ['a', 'bc', 'def', 'g']
    """
    if isinstance(n, int):
        for i in range(0, len(iterable), n):
            yield iterable[i:i + n]
    elif isinstance(n, list):
        acc = 0
        if sum(n) < len(iterable):
            n.append(len(iterable))
        for i in n:
            if acc < len(iterable):
                yield iterable[acc:acc + i]
                acc += i


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

        :param LegacyDeviceSessionLogInfo val:
        :rtype: LinkedDeviceLogInfo
        """
    return cls('legacy_device_session', val)


def get_machine_count(ip_config):
    """Get total machine count from ip_config file
    """
    with open(ip_config) as f:
        machine_count = len(f.readlines())
    return machine_count


def get_relative_path(root_path, path):
    """
    Return a path relativefrom the posix 'path' relative to a
    base path of `len_base_path` length where the base is a directory if
    `base_is_dir` True or a file otherwise.
    """
    return path[len(root_path):].lstrip('/')


def split_number_and_unit(s):
    """Parse a string that consists of a integer number and an optional unit.
    @param s a non-empty string that starts with an int and is followed by some letters
    @return a triple of the number (as int) and the unit
    """
    if not s:
        raise ValueError('empty value')
    s = s.strip()
    pos = len(s)
    while pos and not s[pos - 1].isdigit():
        pos -= 1
    number = int(s[:pos])
    unit = s[pos:].strip()
    return number, unit


def fnone(data=None):
    """Devuelve el valor sin filtrar.

    Funcion dummy, devuelve lo  que le entra.

    Parameters
    ----------
    data : any

    Returns
    -------
    any
        Lo mismo que la entrada

    """
    return data