def make_timestamp_period(**kwargs):
    """
    convert time to timestamp
    :param kwargs: support minutes, seconds
    :return: timestamp
    """
    minutes = kwargs.get('minutes', 0)
    seconds = kwargs.get('seconds', 0)
    return minutes * 60 + seconds


def task__squashfs_backup():
    """
    Backup files from image/squashfs

    Backup files to be restored after updating image/squashfs

    :actions:
      - ``sudo cp image/preseed/ubuntu.seed build/backup/ubuntu.seed``
      - ``sudo cp squashfs-root/etc/apt/sources.list build/backup/sources.list``
      - ``sudo mv squashfs-root/etc/resolv.conf squashfs-root/etc/resolv.conf.orig``
    :targets:
      - build/backup/ubuntu.seed
      - build/backup/sources.list
      - squashfs-root/etc/resolv.conf.orig
    :task_dep:
      - :func:`task__mount_dev`
    :uptodate:
      - True
    """
    return {'actions': [
        'sudo cp image/preseed/ubuntu.seed build/backup/ubuntu.seed || true',
        'sudo cp squashfs-root/etc/apt/sources.list build/backup/sources.list',
        'sudo mv squashfs-root/etc/resolv.conf squashfs-root/etc/resolv.conf.orig'
        ], 'targets': ['build/backup/sources.list',
        'squashfs-root/etc/resolv.conf.orig'], 'task_dep': ['_mount_dev'],
        'uptodate': [True]}


def dstfetch(yrstart, mostart, yrstop, mostop):
    """
    A function to fetch Kyoto Dst directly from the Kyoto WDC website.
    Returns raw ascii lines.
    """
    try:
        import urllib.parse, urllib.request
    except ImportError:
        import urllib
        urllib.parse = urllib
        urllib.request = urllib
    forminfo = {}
    forminfo2 = {}
    if yrstart - 2000 >= 0:
        forminfo['SCent'] = 20
    else:
        forminfo['SCent'] = 19
    forminfo['STens'] = int(('%d' % yrstart)[2])
    forminfo['SYear'] = int(('%d' % yrstart)[3])
    forminfo['SMonth'] = '%02i' % mostart
    if yrstop - 2000 >= 0:
        forminfo['ECent'] = 20
    else:
        forminfo['ECent'] = 19
    forminfo['ETens'] = int(('%d' % yrstop)[2])
    forminfo['EYear'] = int(('%d' % yrstop)[3])
    forminfo['EMonth'] = '%02i' % mostop
    email = urllib.parse.quote('spacepy@lanl.gov')
    target = ('http://wdc.kugi.kyoto-u.ac.jp/cgi-bin/dstae-cgi?' +
        '%s=%2i&%s=%i&%s=%i&%s=%s&%s=%2i&%s=%i&%s=%i&%s=%s&' % ('SCent',
        forminfo['SCent'], 'STens', forminfo['STens'], 'SYear', forminfo[
        'SYear'], 'SMonth', forminfo['SMonth'], 'ECent', forminfo['ECent'],
        'ETens', forminfo['ETens'], 'EYear', forminfo['EYear'], 'EMonth',
        forminfo['EMonth']))
    target = (target + 'Image+Type=GIF&COLOR=COLOR&AE+Sensitivity=0' +
        '&Dst+Sensitivity=0&Output=DST&Out+format=WDC&Email=' + email)
    f = urllib.request.urlopen(target)
    lines = f.readlines()
    return lines


def pistonpowerfactor(density_kgpm3):
    """Gagg-Ferrar model. Multiply by this to get power at given density."""
    sigma = density_kgpm3 / 1.225
    return 1.132 * sigma - 0.132


def parse_bed_to_loci(target):
    """Read BED file and create chr:pos for each targetbase. Return list."""
    loci = list()
    with open(target) as f:
        for line in f:
            chromosome, start, end, *_ = line.split()
            start = int(start)
            end = int(end)
            while start <= end:
                locus = '{}:{}'.format(chromosome, start)
                loci.append(locus)
                start += 1
    return loci


def maybe_cast_list(value, types):
    """
    Try to coerce list values into more specific list subclasses in types.
    """
    if not isinstance(value, list):
        return value
    if type(types) not in (list, tuple):
        types = types,
    for list_type in types:
        if issubclass(list_type, list):
            try:
                return list_type(value)
            except (TypeError, ValueError):
                pass
    return value


def quaternions_flip():
    """Flip quaternion values to achieve desired rotations, while maintaining the same orientations

    """
    pass


def open_for_store(**open_args):
    """
        Open and initialize a connection for storing objects.

        This connection is read/write, and its view of the database
        needs to be consistent for each statement, but should read a
        fresh snapshot on each statement for purposes of conflict
        resolution and cooperation with other store connections. It
        should be opened in ``READ COMMITTED`` isolation level,
        without autocommit. (Opening in ``REPEATABLE READ`` or higher,
        with a single snapshot, could reduce the use of locks, but
        increases the risk of serialization errors and having
        transactions rollback; we could handle that by raising
        ``ConflictError`` and letting the application retry, but only
        if we did that before ``tpc_finish``, and not all test cases
        can handle that either.)

        This connection will take locks on rows in the state tables,
        and hold them during the commit process.

        A connection opened by this method is the only type of
        connection that can hold the commit lock.

        :return: ``(conn, cursor)``
        """


def unindex_doc(docid):
    """Remove an object with id 'docid' from the index."""


def humanize_size(size):
    """Create a nice human readable representation of the given number
    (understood as bytes) using the "KiB" and "MiB" suffixes to indicate
    kibibytes and mebibytes. A kibibyte is defined as 1024 bytes (as opposed to
    a kilobyte which is 1000 bytes) and a mibibyte is 1024**2 bytes (as opposed
    to a megabyte which is 1000**2 bytes).

    :param size: the number to convert
    :type size: int
    :returns: the human readable representation of size
    :rtype: str
    """
    for factor, format_string in ((1, '%i'), (1024, '%iKiB'), (1024 * 1024,
        '%.1fMiB')):
        if size / factor < 1024:
            return format_string % (size / factor)
    return format_string % (size / factor)


def p_step_expr(p):
    """ step : STEP expr
    """
    p[0] = p[2]


def _import_from_dict(conf_dict):
    """ Import settings from a dictionary
    Args:
        conf_dict (dict): settings to be imported
    """
    globals().update(conf_dict)


def append_code(original, codefile):
    """Append the contents of one file to another.

    :param original: name of file that will be appended to
    :type original: str
    :param codefile: name of file that will be appende
    :type codefile: str

    This function is particularly useful when one wants to replace a function
    in student code with their own implementation of one. If two functions are
    defined with the same name in Python, the latter definition is taken so overwriting
    a function is as simple as writing it to a file and then appending it to the
    student's code.

    Example usage::

        # Include a file containing our own implementation of a lookup function.
        check50.include("lookup.py")

        # Overwrite the lookup function in helpers.py with our own implementation.
        check50.py.append_code("helpers.py", "lookup.py")
    """
    with open(codefile) as code, open(original, 'a') as o:
        o.write('\n')
        o.writelines(code)


@classmethod
def get_artifacts(cls, artifacts_to_prefetch):
    """
        Return a list of (sha, obj_blob) for all the object_path(s) specified in
        `artifacts_to_prefetch`.
        """
    raise NotImplementedError()


def _tex_comment(comment):
    """Prepends each line in string with the LaTeX comment key, '%'.
    """
    return '% ' + str.replace(comment, '\n', '\n% ') + '\n'


def raise_error_unsupported_categorical_option(option_name, option_value,
    layer_type, layer_name):
    """
    Raise an error if an option is not supported.
    """
    raise RuntimeError('Unsupported option %s=%s in layer %s(%s)' % (
        option_name, option_value, layer_type, layer_name))


@staticmethod
def is_false(value):
    """checks to see if a string is False"""
    if not value:
        return False
    value = str(value)
    return value.lower() in ['false', '0', 'f', 'n', 'no']


def square(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise squared value of the input.

    .. math::
       square(x) = x^2

    Example::

       square([2, 3, 4]) = [4, 9, 16]

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

       - square(default) = default
       - square(row_sparse) = row_sparse
       - square(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_pow.cc:L118

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

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

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


def _rectangle_small_p(a, b, eps):
    """Return ``True`` if the given rectangle is small enough."""
    (u, v), (s, t) = a, b
    if eps is not None:
        return s - u < eps and t - v < eps
    else:
        return True


def get_suitable_int_type(upper: int, lower: int=0) ->str:
    """Returns the suitable integer type with the least bits.

  Returns the integer type that can hold all values between max_val and min_val
  (inclusive) and has the least bits.

  Args:
    max_val: Maximum value that needs to be valid.
    min_val: Minimum value that needs to be valid.

  Returns:
    The suitable type.
  """
    assert upper >= lower
    upper = max(upper, 0)
    lower = min(lower, 0)
    if lower == 0:
        return 'uint%d' % upper.bit_length()
    return 'int%d' % (max(upper.bit_length(), (lower + 1).bit_length()) + 1)


def _h13_s(s):
    """Define the boundary between Region 1 and 3, h=f(s)

    Parameters
    ----------
    s : float
        Specific entropy, [kJ/kgK]

    Returns
    -------
    h : float
        Specific enthalpy, [kJ/kg]

    Notes
    ------
    Raise :class:`NotImplementedError` if input isn't in limit:

        * s(100MPa,623.15K) ≤ s ≤ s'(623.15K)

    References
    ----------
    IAPWS, Revised Supplementary Release on Backward Equations p(h,s) for
    Region 3, Equations as a Function of h and s for the Region Boundaries, and
    an Equation Tsat(h,s) for Region 4 of the IAPWS Industrial Formulation 1997
    for the Thermodynamic Properties of Water and Steam,
    http://www.iapws.org/relguide/Supp-phs3-2014.pdf. Eq 7

    Examples
    --------
    >>> _h13_s(3.7)
    1632.525047
    >>> _h13_s(3.5)
    1566.104611
    """
    if s < 3.397782955 or s > 3.77828134:
        raise NotImplementedError('Incoming out of bound')
    sigma = s / 3.8
    I = [0, 1, 1, 3, 5, 6]
    J = [0, -2, 2, -12, -4, -3]
    n = [0.913965547600543, -4.30944856041991e-05, 60.3235694765419,
        1.17518273082168e-18, 0.220000904781292, -69.0815545851641]
    suma = 0
    for i, j, ni in zip(I, J, n):
        suma += ni * (sigma - 0.884) ** i * (sigma - 0.864) ** j
    return 1700 * suma


def _byte_to_int(data: bytes) ->int:
    """
    Returns integer value of big endian byte data
    :param data:
    :return: Integer value
    :rtype: int
    """
    return ord(data[0:1]) + ord(data[1:2]) * 256 + ord(data[2:3]
        ) * 65536 + ord(data[3:4]) * 16777216


@classmethod
def add_hook(cls, hook_type, hook_func):
    """Add a new hook of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param hook_func: hook function
        """
    if hook_type not in cls._hooks_map:
        cls._hooks_map[hook_type] = []
    cls._hooks_map[hook_type].append(hook_func)


def findEvenSplit(line):
    """
    Given a string, splits it into two evenly spaced lines
    """
    word_list = line.split(' ')
    differences = []
    for i in range(len(word_list)):
        group1 = ' '.join(word_list[0:i + 1])
        group2 = ' '.join(word_list[i + 1:])
        differences.append(abs(len(group1) - len(group2)))
    index = differences.index(min(differences))
    for i in range(len(word_list)):
        if i == index:
            group1 = ' '.join(word_list[0:i + 1])
            group2 = ' '.join(word_list[i + 1:])
    return ''.join([group1, '\n', group2]).rstrip()


def add_host_config_params_dns(docker_host, host_config_params=None):
    """Add dns input params

    This is not a generic implementation. This method will setup dns with the
    expectation that a local consul agent is running on the docker host and will
    service the dns requests.

    Args:
    -----
    docker_host (string): Docker host ip address which will be used as the dns server
    host_config_params (dict): Target dict to accumulate host config inputs

    Returns:
    --------
    Updated host_config_params
    """
    if host_config_params == None:
        host_config_params = {}
    host_config_params['dns'] = [docker_host]
    host_config_params['dns_search'] = ['service.consul']
    host_config_params['extra_hosts'] = {'consul': docker_host}
    return host_config_params


def set_instances_default(cls, attr, value):
    """Set DEFAULT attribute for instances of classes created
        by this metaclass

        Arguments:
        attr -- attribute name
        value -- new attribute value
        """
    for instance in cls.get_instances():
        instance.set_instance_attr(attr, value)


@staticmethod
def _dict_to_tuples(dictionary: dict) ->tuple:
    """Since dictionaries are not hashable, this is a helper function
        converting a dictionary into a sorted tuple."""
    return tuple(sorted(dictionary.items()))


def is_server_error(code: int) ->bool:
    """Return true if the code is a server error HTTP response code.

    Args:
        code (int): The HTTP response code.

    Returns:
        bool: True if the code was a server error else false.
    """
    return code >= 500 and code < 600


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

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


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

        :param list of [str] val:
        :rtype: GroupMembersAddError
        """
    return cls('members_not_in_team', val)


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

    The ".dev0" means dirty.

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


def __object_has_attr(instance, attribute_name):
    """
    Checks if an attribute with the given name
    exists in the given instance.
    This method provides an additional layer of abstraction
    that allows it to be used in objects or in maps.

    :type instance: Object
    :param instance: The instance to be checked
    for attribute.
    :type attribute_name: String
    :param attribute_name: The name of the attribute
    to be checked in the instance.
    :rtype: bool
    :return: The result of the has attribute testing
    in the instance.
    """
    instance_type = type(instance)
    if instance_type == dict:
        return attribute_name in instance
    else:
        return hasattr(instance, attribute_name)


@classmethod
def leaf_list(cls, name, parent=None, interleave=None):
    """Create _list_ node for a leaf-list."""
    node = cls('_list_', parent, interleave=interleave)
    node.attr['name'] = name
    node.keys = None
    node.minEl = '0'
    node.maxEl = None
    node.occur = 3
    return node


def set_record_topology(record, topology, pass_if_already_set=False):
    """Set record.annotations['topology'] (if not already set?)"""
    record_topology = record.annotations.get('topology', None)
    do_nothing = pass_if_already_set and record_topology is not None
    if not do_nothing:
        record.annotations['topology'] = topology


def _suffix_rules(token, **kwargs):
    """ Default morphological tagging rules for English, based on word suffixes.
    """
    word, pos = token
    if word.endswith('ing'):
        pos = 'VBG'
    if word.endswith('ly'):
        pos = 'RB'
    if word.endswith('s') and not word.endswith(('is', 'ous', 'ss')):
        pos = 'NNS'
    if word.endswith(('able', 'al', 'ful', 'ible', 'ient', 'ish', 'ive',
        'less', 'tic', 'ous')) or '-' in word:
        pos = 'JJ'
    if word.endswith('ed'):
        pos = 'VBN'
    if word.endswith(('ate', 'ify', 'ise', 'ize')):
        pos = 'VBP'
    return [word, pos]


def register_class(cls_name, cls, is_unique=False):
    """
    This function registers given class into tpRigToolkit module
    :param cls_name: str, name of the class we want to register
    :param cls: class, class we want to register
    :param is_unique: bool, Whether if the class should be updated if new class is registered with the same name
    """
    import tpDcc
    if is_unique:
        if cls_name in tpDcc.__dict__:
            setattr(tpDcc.__dict__, cls_name, getattr(tpDcc.__dict__, cls_name)
                )
    else:
        tpDcc.__dict__[cls_name] = cls


def find_closest(pos, L):
    """
    (int, list) -> tuple

    :param pos: Position of interest along chromosome 0-based
    :param L: List of (positions, counts)

    Returns a tuple (i, k) corresponding to the closest position i from pos
    and the highest count k if multiple counts exist for the smallest distance
    between pos and i
    """
    D = {}
    for i in L:
        dist = abs(pos - i[0])
        if dist in D:
            D[dist].append((i[1], i[0]))
        else:
            D[dist] = [(i[1], i[0])]
    for i in D:
        D[i].sort(key=lambda x: x[0])
    distances = sorted(D.keys())
    smallest_dist = distances[0]
    return smallest_dist, D[smallest_dist][-1][0], D[smallest_dist][-1][1]


def publish_display_data(data, metadata=None, source=None, *, transient=
    None, **kwargs):
    """Publish data and metadata to all frontends.

    See the ``display_data`` message in the messaging documentation for
    more details about this message type.

    Keys of data and metadata can be any mime-type.

    Parameters
    ----------
    data : dict
        A dictionary having keys that are valid MIME types (like
        'text/plain' or 'image/svg+xml') and values that are the data for
        that MIME type. The data itself must be a JSON'able data
        structure. Minimally all data should have the 'text/plain' data,
        which can be displayed by all frontends. If more than the plain
        text is given, it is up to the frontend to decide which
        representation to use.
    metadata : dict
        A dictionary for metadata related to the data. This can contain
        arbitrary key, value pairs that frontends can use to interpret
        the data. mime-type keys matching those in data can be used
        to specify metadata about particular representations.
    source : str, deprecated
        Unused.
    transient : dict, keyword-only
        A dictionary of transient data, such as display_id.
        """
    from IPython.core.interactiveshell import InteractiveShell
    display_pub = InteractiveShell.instance().display_pub
    if transient:
        kwargs['transient'] = transient
    display_pub.publish(data=data, metadata=metadata, **kwargs)


def count_open_workflow_executions(domain=None, startTimeFilter=None,
    typeFilter=None, tagFilter=None, executionFilter=None):
    """
    Returns the number of open workflow executions within the given domain that meet the specified filtering criteria.
    Access Control
    You can use IAM policies to control this action's access to Amazon SWF resources as follows:
    If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified constraints, the action fails. The associated event attribute's cause parameter will be set to OPERATION_NOT_PERMITTED. For details and example IAM policies, see Using IAM to Manage Access to Amazon SWF Workflows .
    See also: AWS API Documentation

    :example: response = client.count_open_workflow_executions(
        domain='string',
        startTimeFilter={
            'oldestDate': datetime(2015, 1, 1),
            'latestDate': datetime(2015, 1, 1)
        },
        typeFilter={
            'name': 'string',
            'version': 'string'
        },
        tagFilter={
            'tag': 'string'
        },
        executionFilter={
            'workflowId': 'string'
        }
    )

    :type domain: string
    :param domain: [REQUIRED]
            The name of the domain containing the workflow executions to count.

    :type startTimeFilter: dict
    :param startTimeFilter: [REQUIRED]
            Specifies the start time criteria that workflow executions must meet in order to be counted.
            oldestDate (datetime) -- [REQUIRED]Specifies the oldest start or close date and time to return.
            latestDate (datetime) --Specifies the latest start or close date and time to return.

    :type typeFilter: dict
    :param typeFilter: Specifies the type of the workflow executions to be counted.
            Note
            executionFilter , typeFilter and tagFilter are mutually exclusive. You can specify at most one of these in a request.
            name (string) -- [REQUIRED]Required. Name of the workflow type.
            version (string) --Version of the workflow type.

    :type tagFilter: dict
    :param tagFilter: If specified, only executions that have a tag that matches the filter are counted.
            Note
            executionFilter , typeFilter and tagFilter are mutually exclusive. You can specify at most one of these in a request.
            tag (string) -- [REQUIRED]Required. Specifies the tag that must be associated with the execution for it to meet the filter criteria.

    :type executionFilter: dict
    :param executionFilter: If specified, only workflow executions matching the WorkflowId in the filter are counted.
            Note
            executionFilter , typeFilter and tagFilter are mutually exclusive. You can specify at most one of these in a request.
            workflowId (string) -- [REQUIRED]The workflowId to pass of match the criteria of this filter.

    :rtype: dict
    :return: {
        'count': 123,
        'truncated': True|False
    }

    :returns:
    domain (string) -- [REQUIRED]
    The name of the domain containing the workflow executions to count.

    startTimeFilter (dict) -- [REQUIRED]
    Specifies the start time criteria that workflow executions must meet in order to be counted.

    oldestDate (datetime) -- [REQUIRED]Specifies the oldest start or close date and time to return.

    latestDate (datetime) --Specifies the latest start or close date and time to return.

    typeFilter (dict) -- Specifies the type of the workflow executions to be counted.

    Note
    executionFilter , typeFilter and tagFilter are mutually exclusive. You can specify at most one of these in a request.

    name (string) -- [REQUIRED]Required. Name of the workflow type.

    version (string) --Version of the workflow type.

    tagFilter (dict) -- If specified, only executions that have a tag that matches the filter are counted.

    Note
    executionFilter , typeFilter and tagFilter are mutually exclusive. You can specify at most one of these in a request.

    tag (string) -- [REQUIRED]Required. Specifies the tag that must be associated with the execution for it to meet the filter criteria.

    executionFilter (dict) -- If specified, only workflow executions matching the WorkflowId in the filter are counted.

    Note
    executionFilter , typeFilter and tagFilter are mutually exclusive. You can specify at most one of these in a request.

    workflowId (string) -- [REQUIRED]The workflowId to pass of match the criteria of this filter.

    """
    pass


def get_gene_ids(model):
    """
    This function returns a list of IDs of all genes in the model.

    Parameters
    ----------
    model : cobra.core.Model.Model
        A cobra model.

    Returns
    -------
    genes : list
        A list containing all IDs of genes in the model.
    """
    genes = []
    for gene in model.genes:
        genes.append(gene.id)
    genes = list(set(genes))
    return genes


def coerce_single_line_str(value):
    """
    Multiline strings have two options:

        1. Preserve new lines with the back slash:

            value = ""\"A new value                 and something else                 to boot.
            ""\"

            A new value
            and something else
            to boot.

        2. Preserve left spacing with the pipe:

            value = ""\"A new value                 |   it's true.""\"

           A new value
              it's true.

    """


def mode(list_):
    """ Return the mode of a list. """
    return max(set(list_), key=list(list_).count)


def to_3_list(item):
    """
    Converts item into a 3 item list
    :param item: var
    :return: list<var, var, var>
    """
    if not isinstance(item, list):
        item = [item] * 3
    return item


@classmethod
def scratch_pad(cls):
    """ A class method to use the Components intent methods as a scratch pad"""
    return cls.from_env(task_name='scratch_pad', default_save=False,
        default_save_intent=False, reset_templates=False, align_connectors=
        False).intent_model


def set_common_cutoff(common_def):
    """
    Sets the number of incoming connections at which we deem a function 'common'
    Default is 10 (which is used if this method is never called).
    :param common_def: number of incoming connections
    """
    global COMMON_CUTOFF
    COMMON_CUTOFF = common_def


def delete():
    """Delete selected strips

    """
    pass


def remove_extension(filename):
    """Remove the extension from a filename string"""
    return filename[:filename.index('.')]


def p_opt_column_def_options_list(p):
    """opt_column_def_options_list : opt_column_def_options opt_column_def_options_list"""
    if p[2] is None:
        p[0] = p[1]
    else:
        p[2].update(p[1])
        p[0] = p[2]


def websocket_handshake(security_key=None, origin=None, proto=None):
    """Waits for websocket handshake.

    :param str|unicode security_key: Websocket security key to use.

    :param str|unicode origin: Override ``Sec-WebSocket-Origin``.

    :param str|unicode proto: Override ``Sec-WebSocket-Protocol``.

    :rtype: None

    :raises IOError: If unable to complete handshake.
    """


@classmethod
def get_counterparty_by_edrpou(cls, city_ref, code):
    """
        Method for fetching info about counterparty by `EDRPOU` - National State Registry
        of Ukrainian Enterprises and Organizations (8-digit code).

        :example:
            ``Counterparty.get_counterparty_by_edrpou(city_ref='0006560c-4079-11de-b509-001d92f78698', code='12345678')``
        :param city_ref:
            ID of the city of counterparty
        :type city_ref:
            str or unicode
        :param code:
            EDRPOU code of the counterparty
        :type code:
            str or unicode
        :return:
            dictionary with info about counterparty
        :rtype:
            dict
        """
    return cls.send(method='getCounterpartyByEDRPOU', method_props={
        'CityRef': city_ref, 'EDRPOU': code})


def _reg2float(reg):
    """Converts 32-bit register value to floats in Python.

    Parameters
    ----------
    reg: int
        A 32-bit register value read from the mailbox.

    Returns
    -------
    float
        A float number translated from the register value.

    """
    if reg == 0:
        return 0.0
    sign = (reg & 2147483648) >> 31 & 1
    exp = ((reg & 2139095040) >> 23) - 127
    if exp == 0:
        man = (reg & 8388607) / pow(2, 23)
    else:
        man = 1 + (reg & 8388607) / pow(2, 23)
    result = pow(2, exp) * man * (sign * -2 + 1)
    return float('{0:.2f}'.format(result))


def readBytes(fs, n):
    """Reads exactly n bytes and returns them."""
    r = fs.read(n)
    if len(r) != n:
        raise Exception('Can not read {} bytes only {} left'.format(n, len(r)))
    return r


def _assert_type(data, key, tpe, default=None):
    """Extract and verify if a key in a dictionary has a given type."""
    value = data.get(key, default)
    if not isinstance(value, tpe):
        raise ValueError(
            f'Config error: {key}: expected {tpe}, found {type(value)}')
    return value


def is_list(l):
    """
    Returns whether the object is a list.
    :param l: the object
    :return: whether is a list
    """
    return isinstance(l, list)


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.cognitive.GenerateThumbnails'


def keymap_restore(all: bool=False):
    """Restore key map(s)

    :param all: All Keymaps, Restore all keymaps to default
    :type all: bool
    """
    pass


@classmethod
def __declare_first__(cls):
    """declarative hook called within the 'before_configure' mapper event."""
    for lcl, rmt in cls._to_ref:
        cls._decl_class_registry[lcl]._reference_table(cls.
            _decl_class_registry[rmt].__table__)
    cls._to_ref.clear()


def lru_append(kc, lru, kckey, maxsize):
    """Delete old data from ``kc``, then add the new ``kckey``.

    :param kc: a three-layer keycache
    :param lru: an :class:`OrderedDict` with a key for each triple that should fill out ``kc``'s three layers
    :param kckey: a triple that indexes into ``kc``, which will be added to ``lru`` if needed
    :param maxsize: maximum number of entries in ``lru`` and, therefore, ``kc``

    """
    if kckey in lru:
        return
    while len(lru) >= maxsize:
        (peb, turn, tick), _ = lru.popitem(False)
        if peb not in kc:
            continue
        kcpeb = kc[peb]
        if turn not in kcpeb:
            continue
        kcpebturn = kcpeb[turn]
        if tick not in kcpebturn:
            continue
        del kcpebturn[tick]
        if not kcpebturn:
            del kcpeb[turn]
        if not kcpeb:
            del kc[peb]
    lru[kckey] = True


def makename(package, module):
    """Join package and module with a dot."""
    if package:
        name = package
        if module:
            name += '.' + module
    else:
        name = module
    return name


def asbool(obj):
    """
    Interprets an object as a boolean value.

    :rtype: bool

    """
    if isinstance(obj, str):
        obj = obj.strip().lower()
        if obj in ('true', 'yes', 'on', 'y', 't', '1'):
            return True
        if obj in ('false', 'no', 'off', 'n', 'f', '0'):
            return False
        raise ValueError('Unable to interpret value "%s" as boolean' % obj)
    return bool(obj)


def stacked_bar(tag, title, datalist):
    """

    data list should be a list of dictionary formatted as follows

    {"name": "A"
     "data": {
        "R1_mapped": 50,
        "R2_mapped": 50,
        "R1_unmapped": 50,
        "R2_unmapped": 50,
        }
    }
    """
    dataitems = ''
    for item in datalist:
        datatext = []
        for k, v in item['data'].items():
            datatext.append('{y:%s,label:"%s"}' % (v, k))
        datatext = ',\n        '.join(datatext)
        params = {'name': item['name'], 'datatext': datatext}
        dataitems += (
            """
      {
        type: "stackedBar100",
        showInLegend: true,
        name: "%(name)s",
        dataPoints: [
        %(datatext)s
        ]
        },
    """
             % params)
    metadata = {'tag': tag, 'title': title, 'dataitems': dataitems}
    script = """
<script type="text/javascript">
  window.onload = function () {
    var chart = new CanvasJS.Chart("chartContainer%(tag)s",
    {
      theme: "theme2",
      title:{
        text: "%(title)s"
      },
      animationEnabled: true,
      axisY:{
        title: "percent"
      },
      legend :{
        horizontalAlign: 'center',
        verticalAlign: 'bottom'
      },
      toolTip: {
        shared: true
      },
      data:[
        %(dataitems)s
      ]

    });

chart.render();
}
</script>
"""
    return script % metadata


def mangle(classname, attrname):
    """mangles name according to python name-mangling
       conventions for private variables"""
    return '_%s__%s' % (classname, attrname)


@staticmethod
def _init_daughter(cell):
    """Add a new daughter of the cell in an appropriate site."""
    daughter = cell.new_daughter()
    site = cell.site
    daughter.add_to(site.random_neighbor())
    return daughter


def instance(cls):
    """Create a new instance of a class.
    Parameters
    ----------
    cls : type
        The class to create an instance of.
    Returns
    -------
    instance : cls
        A new instance of ``cls``.
    """
    return cls()


def add(object):
    """Add an object to the context.  Returns the added object.
        """


def multires_higher_levels_delete(modifier: str=''):
    """Deletes the higher resolution mesh, potential loss of detail

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


def book_value_per_share(book_value, total_shares):
    """Computes book value per share.

    @params
    -------
    book_value: book value (equity) of an enterprice
    total_shares: total number of shares

    returns
    -------
    Book value per share, int or float

    explanation
    -----------
    Book value per share is often used as a valuation measure for companies. If it is less than the
    market price of a stock, the stock is considered as overvalued and if more than market price, stock is
    considered as undervalued.
    """
    return book_value / total_shares


def _setup_mappers(tables, mappers):
    """Given a dict of tables, keyed by table name as in self.tables,
        set up all SQLAlchemy mappers for the database and save them to the
        dict 'mappers', keyed by table name..
        """


def get_attribute(obj, attr_name):
    """
    Retrieve the attribute of a specific object
    :param obj: object from which get the value
    :param attr_name: name of the attribute
    :return: value of the attribute
    """
    return getattr(obj, attr_name)


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


def readfitfile_comments(fitfilepath):
    """read comments and return corresponding strings
    #CCDLabel
    #pixelsize
    #Frame dimensions
    #DetectorParameters
    """
    dictcomments = {}
    ccdlabelflag = False
    pixelsizeflag = False
    framedimflag = False
    detectorflag = False
    f = open(fitfilepath, 'r')
    nblines = 0
    for line in f.readlines():
        nblines += 1
    f.seek(0)
    lineindex = 0
    while lineindex < nblines:
        line = f.readline()
        if ccdlabelflag:
            dictcomments['CCDLabel'] = line.split('#')[1].strip()
            ccdlabelflag = False
        if pixelsizeflag:
            dictcomments['pixelsize'] = line.split('#')[1].strip()
            pixelsizeflag = False
        if framedimflag:
            dictcomments['framedim'] = line.split('#')[1].strip()
            framedimflag = False
        if detectorflag:
            dictcomments['detectorparameters'] = line.split('#')[1].strip()
            detectorflag = False
        if line.startswith(('#CCDLabel', '# CCDLabel')):
            ccdlabelflag = True
        if line.startswith(('#pixelsize', '# pixelsize')):
            pixelsizeflag = True
        if line.startswith(('#Frame dimensions', '# Frame dimensions')):
            framedimflag = True
        if line.startswith(('#DetectorParameters', '# DetectorParameters')):
            detectorflag = True
        lineindex += 1
    f.close()
    return dictcomments


def select_plot_data_single(values_list, plot_information, number_of_flights):
    """
    List of data to plot returns values_list which has structure:
    [[[axis, [data_source, column], [axis, [data_source, column]],
     [[axis, [data_source, column], [axis, [data_source, column]]]"""
    plot_data = []
    for data_set in range(number_of_flights):
        plot_data_temp = []
        for data in plot_information:
            values_list_index = 0
            for values_list_data in values_list[data_set]:
                if data[2].lower() == values_list_data[0].lower():
                    data.append(values_list_index)
                    for column in values_list[data_set][values_list_index][1:]:
                        if column[0].lower() == data[1].lower():
                            plot_data_temp.append([data[0], column, data[2]])
                            break
                values_list_index += 1
        plot_data.append(plot_data_temp)
    return plot_data


def iter_fields(node):
    """
    Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
    that is present on *node*.
    """
    for field in node._fields:
        try:
            yield field, getattr(node, field)
        except AttributeError:
            pass


def try_parse(value, parser, default=None):
    """Try to parse value using parser, returning default if the parse fails"""
    try:
        return parser(value)
    except (TypeError, ValueError):
        return default


@classmethod
def has_card_provider(cls, store):
    """Find out if there is a card provider
        :param store: a database store
        :returns: if there is a card provider
        """
    return bool(store.find(cls).count())


@classmethod
def list_versions(cls, options=None):
    """Build foreman-maintain upgrade list-versions"""
    cls.command_sub = 'list-versions'
    if options is None:
        options = {}
    result = cls._construct_command(options)
    return result


@classmethod
def get_software_package_compilation_timestamp(cls, calc, **kwargs):
    """
        Returns the timestamp of package/program compilation in ISO 8601
        format.
        """
    from dateutil.parser import parse
    try:
        date = calc.out.job_info.get_dict()['compiled']
        return parse(date.replace('_', ' ')).isoformat()
    except Exception:
        return None


def human_readable_time(time):
    """
    HUMAN_READABLE_TIME convert a time ns, us, ms depending on its value

    Paramaters
    ----------
    time (float) :
        time value

    Returns
    -------
    time (float):
        time value converted
    units (str):
        unit of measurement

    AUTHOR: Luca Giaccone (luca.giaccone@polito.it)
    DATE: 11.08.2018
    HISTORY:
    """
    if time < 1e-09:
        time = time * 1000000.0
        unit = 'ns'
    elif time < 1e-06:
        time = time * 1000000.0
        unit = 'us'
    elif time < 0.001:
        time = time * 1000.0
        unit = 'ms'
    else:
        unit = 's'
    return time, unit


def pytest_bug_item_mark(item, config):
    """
    Called after set mark
    :param item: pytest item
    :param config: Base pytest config
    """


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

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

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


def fsplit(pred, objs):
    """Split a list into two classes according to the predicate."""
    t = []
    f = []
    for obj in objs:
        if pred(obj):
            t.append(obj)
        else:
            f.append(obj)
    return t, f


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

    The ".dev0" means dirty.

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


def _border_type(i, values):
    """
    Returns border type:

    :param i: index of potential border
    :param values: insulation index values
    :return: if border: 1 or -1, else 0. 1 if derivative at border is >0, -1 otherwise
    """
    if i == 0:
        return 1
    if i == len(values) - 1:
        return -1
    if values[i - 1] <= 0 <= values[i + 1]:
        return 1
    if values[i + 1] <= 0 <= values[i - 1]:
        return -1
    return 0


def next_p2(n):
    """Returns the smallest integer, greater than n
    (n positive and >= 1) which can be obtained as power of 2.
    """
    if n < 1:
        raise ValueError('n must be >= 1')
    v = 2
    while v <= n:
        v = v * 2
    return v


def circuit_new(circuit):
    """A new circuit has been created.  You'll always get one of
        these for every Circuit even if it doesn't go through the "launched"
        state."""


def set_default(item, default, use_default):
    """if an item provided is None and boolean use_default is set to True,
       return the default. Otherwise, return the item.
    """
    if item is None and use_default:
        return default
    return item


def Hx2Rh(Hx):
    """needs doc string"""
    Rh = [0, 0, 0]
    itk = -Hx[0] + Hx[1] + Hx[2]
    if itk % 3 != 0:
        return 0
    else:
        Rh[1] = itk // 3
        Rh[0] = Rh[1] + Hx[0]
        Rh[2] = Rh[1] - Hx[1]
        if Rh[0] < 0:
            for i in range(3):
                Rh[i] = -Rh[i]
        return Rh


def limovieParser(line, frame, time, value, ref1, ref2, ref3, extra):
    """
    Limovie sample line ---
        3.5,21381195,21381200,22,27,43.0000,,,,,2737.8,3897.32 ...
    """
    part = line.split(',')
    frame.append(part[0])
    time.append('[' + part[3] + ':' + part[4] + ':' + part[5] + ']')
    value.append(part[10])
    if part[11]:
        ref1.append(part[11])
    if part[12]:
        ref2.append(part[12])


def parse_like_term(term):
    """
        Parse search term into (operation, term) tuple. Recognizes operators
        in the beginning of the search term. Case insensitive is the default.

        * = case sensitive (can precede other operators)
        ^ = starts with
        = = exact

        :param term:
            Search term
    """
    case_sensitive = term.startswith('*')
    if case_sensitive:
        term = term[1:]
    if term.startswith('^'):
        oper = 'startswith'
        term = term[1:]
    elif term.startswith('='):
        oper = 'exact'
        term = term[1:]
    else:
        oper = 'contains'
    if not case_sensitive:
        oper = 'i' + oper
    return oper, term


def base_dict_to_string(base_dict):
    """
    Converts a dictionary to a string. {'C': 12, 'A':4} gets converted to C:12;A:4
    :param base_dict: Dictionary of bases and counts created by find_if_multibase
    :return: String representing that dictionary.
    """
    outstr = ''
    base_list = sorted(base_dict.items(), key=lambda kv: kv[1], reverse=True)
    for base in base_list:
        outstr += '{}:{};'.format(base[0], base[1])
    return outstr[:-1]


@classmethod
def add_arguments(cls):
    """
        Sub-Command Document Write At Here.
        """
    pass


def snapshot_cache(check_exists):
    """Returns location of snapshot file"""
    from os import path, makedirs
    cache_directory = path.expanduser('~/.cache/nixml/')
    cache_file = cache_directory + 'snapshots.tsv'
    if check_exists and not path.exists(cache_file):
        return None
    makedirs(cache_directory, exist_ok=True)
    return cache_file


@classmethod
def get_model_class(cls, error=True):
    """
        Returns the data model class for which the master view exists.
        """
    if not hasattr(cls, 'model_class') and error:
        raise NotImplementedError('You must define the `model_class` for: {}'
            .format(cls))
    return getattr(cls, 'model_class', None)


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


@classmethod
def run(cls):
    """Entry point for running job from the command-line.

        This is also the entry point when a mapper or reducer is run
        by Hadoop Streaming.

        Does one of:

        * Run a mapper (:option:`--mapper`). See :py:meth:`run_mapper`
        * Run a combiner (:option:`--combiner`). See :py:meth:`run_combiner`
        * Run a reducer (:option:`--reducer`). See :py:meth:`run_reducer`
        * Run the entire job. See :py:meth:`run_job`
        """
    cls().execute()


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def show_config(config):
    """Show the current configuration."""
    print('\nCurrent Configuration:\n')
    for k, v in sorted(config.config.items()):
        print('{0:15}: {1}'.format(k, v))


def map_db_collection_with_class(db, db_classes):
    """
    maps database-collection with classes
    """
    for db_class in db_classes:
        name = db_class._collection
        if name:
            setattr(db, name, db_class(getattr(db, name)))


def dw_WriteNrSegments(fname, nr):
    """
    Writes the number of segments to B3 file

    B3\\_nrofseg.inc
    """
    exfile = open(fname, 'w')
    print(';Written by dw_WriteNrSegments', file=exfile)
    print(str(nr) + ' ; nr of segments', file=exfile)
    exfile.close()


@classmethod
def puppet_module_remove(cls, options):
    """Remove a puppet module from the content view"""
    cls.command_sub = 'puppet-module remove'
    return cls.execute(cls._construct_command(options), output_format='csv')


def _generateSpecial_VolumeOpts_overrideDataRange(overlayList, displayCtx,
    source, longArg):
    """Generates the :attr:`.VolumeOpts.overrideDataRange` option.

    If the :attr:`.VolumeOpts.enableOverrideDataRange` property is ``False``,
    no arguments are generated.
    """
    if not source.enableOverrideDataRange:
        return []
    else:
        return False


@staticmethod
def handle_continue_exception(node, exception, message):
    """Handle exception raised in `_continue` call.

        If the process state of the node has not yet been put to excepted, the exception was raised before the process
        instance could be reconstructed, for example when the process class could not be loaded, thereby circumventing
        the exception handling of the state machine. Raising this exception will then acknowledge the process task with
        RabbitMQ leaving an uncleaned node in the `CREATED` state for ever. Therefore we have to perform the node
        cleaning manually.

        :param exception: the exception object
        :param message: string message to use for the log message
        """
    from aiida.engine import ProcessState
    if not node.is_excepted:
        node.logger.exception(message)
        node.set_exception(str(exception))
        node.set_process_state(ProcessState.EXCEPTED)
        node.seal()


def modify_replication_group(ReplicationGroupId=None,
    ReplicationGroupDescription=None, PrimaryClusterId=None,
    SnapshottingClusterId=None, AutomaticFailoverEnabled=None,
    CacheSecurityGroupNames=None, SecurityGroupIds=None,
    PreferredMaintenanceWindow=None, NotificationTopicArn=None,
    CacheParameterGroupName=None, NotificationTopicStatus=None,
    ApplyImmediately=None, EngineVersion=None, AutoMinorVersionUpgrade=None,
    SnapshotRetentionLimit=None, SnapshotWindow=None, CacheNodeType=None,
    NodeGroupId=None):
    """
    Modifies the settings for a replication group.
    See also: AWS API Documentation

    :example: response = client.modify_replication_group(
        ReplicationGroupId='string',
        ReplicationGroupDescription='string',
        PrimaryClusterId='string',
        SnapshottingClusterId='string',
        AutomaticFailoverEnabled=True|False,
        CacheSecurityGroupNames=[
            'string',
        ],
        SecurityGroupIds=[
            'string',
        ],
        PreferredMaintenanceWindow='string',
        NotificationTopicArn='string',
        CacheParameterGroupName='string',
        NotificationTopicStatus='string',
        ApplyImmediately=True|False,
        EngineVersion='string',
        AutoMinorVersionUpgrade=True|False,
        SnapshotRetentionLimit=123,
        SnapshotWindow='string',
        CacheNodeType='string',
        NodeGroupId='string'
    )

    :type ReplicationGroupId: string
    :param ReplicationGroupId: [REQUIRED]
            The identifier of the replication group to modify.

    :type ReplicationGroupDescription: string
    :param ReplicationGroupDescription: A description for the replication group. Maximum length is 255 characters.

    :type PrimaryClusterId: string
    :param PrimaryClusterId: For replication groups with a single primary, if this parameter is specified, ElastiCache promotes the specified cluster in the specified replication group to the primary role. The nodes of all other clusters in the replication group are read replicas.

    :type SnapshottingClusterId: string
    :param SnapshottingClusterId: The cache cluster ID that is used as the daily snapshot source for the replication group. This parameter cannot be set for Redis (cluster mode enabled) replication groups.

    :type AutomaticFailoverEnabled: boolean
    :param AutomaticFailoverEnabled: Determines whether a read replica is automatically promoted to read/write primary if the existing primary encounters a failure.
            Valid values: true | false
            Note
            ElastiCache Multi-AZ replication groups are not supported on:
            Redis versions earlier than 2.8.6.
            Redis (cluster mode disabled):T1 and T2 cache node types. Redis (cluster mode enabled): T1 node types.

    :type CacheSecurityGroupNames: list
    :param CacheSecurityGroupNames: A list of cache security group names to authorize for the clusters in this replication group. This change is asynchronously applied as soon as possible.
            This parameter can be used only with replication group containing cache clusters running outside of an Amazon Virtual Private Cloud (Amazon VPC).
            Constraints: Must contain no more than 255 alphanumeric characters. Must not be Default .
            (string) --

    :type SecurityGroupIds: list
    :param SecurityGroupIds: Specifies the VPC Security Groups associated with the cache clusters in the replication group.
            This parameter can be used only with replication group containing cache clusters running in an Amazon Virtual Private Cloud (Amazon VPC).
            (string) --

    :type PreferredMaintenanceWindow: string
    :param PreferredMaintenanceWindow: Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period.
            Valid values for ddd are:
            sun
            mon
            tue
            wed
            thu
            fri
            sat
            Example: sun:23:00-mon:01:30

    :type NotificationTopicArn: string
    :param NotificationTopicArn: The Amazon Resource Name (ARN) of the Amazon SNS topic to which notifications are sent.
            Note
            The Amazon SNS topic owner must be same as the replication group owner.

    :type CacheParameterGroupName: string
    :param CacheParameterGroupName: The name of the cache parameter group to apply to all of the clusters in this replication group. This change is asynchronously applied as soon as possible for parameters when the ApplyImmediately parameter is specified as true for this request.

    :type NotificationTopicStatus: string
    :param NotificationTopicStatus: The status of the Amazon SNS notification topic for the replication group. Notifications are sent only if the status is active .
            Valid values: active | inactive

    :type ApplyImmediately: boolean
    :param ApplyImmediately: If true , this parameter causes the modifications in this request and any pending modifications to be applied, asynchronously and as soon as possible, regardless of the PreferredMaintenanceWindow setting for the replication group.
            If false , changes to the nodes in the replication group are applied on the next maintenance reboot, or the next failure reboot, whichever occurs first.
            Valid values: true | false
            Default: false

    :type EngineVersion: string
    :param EngineVersion: The upgraded version of the cache engine to be run on the cache clusters in the replication group.
            Important: You can upgrade to a newer engine version (see Selecting a Cache Engine and Version ), but you cannot downgrade to an earlier engine version. If you want to use an earlier engine version, you must delete the existing replication group and create it anew with the earlier engine version.

    :type AutoMinorVersionUpgrade: boolean
    :param AutoMinorVersionUpgrade: This parameter is currently disabled.

    :type SnapshotRetentionLimit: integer
    :param SnapshotRetentionLimit: The number of days for which ElastiCache retains automatic node group (shard) snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
            Important If the value of SnapshotRetentionLimit is set to zero (0), backups are turned off.

    :type SnapshotWindow: string
    :param SnapshotWindow: The daily time range (in UTC) during which ElastiCache begins taking a daily snapshot of the node group (shard) specified by SnapshottingClusterId .
            Example: 05:00-09:00
            If you do not specify this parameter, ElastiCache automatically chooses an appropriate time range.

    :type CacheNodeType: string
    :param CacheNodeType: A valid cache node type that you want to scale this replication group to.

    :type NodeGroupId: string
    :param NodeGroupId: The name of the Node Group (called shard in the console).

    :rtype: dict
    :return: {
        'ReplicationGroup': {
            'ReplicationGroupId': 'string',
            'Description': 'string',
            'Status': 'string',
            'PendingModifiedValues': {
                'PrimaryClusterId': 'string',
                'AutomaticFailoverStatus': 'enabled'|'disabled'
            },
            'MemberClusters': [
                'string',
            ],
            'NodeGroups': [
                {
                    'NodeGroupId': 'string',
                    'Status': 'string',
                    'PrimaryEndpoint': {
                        'Address': 'string',
                        'Port': 123
                    },
                    'Slots': 'string',
                    'NodeGroupMembers': [
                        {
                            'CacheClusterId': 'string',
                            'CacheNodeId': 'string',
                            'ReadEndpoint': {
                                'Address': 'string',
                                'Port': 123
                            },
                            'PreferredAvailabilityZone': 'string',
                            'CurrentRole': 'string'
                        },
                    ]
                },
            ],
            'SnapshottingClusterId': 'string',
            'AutomaticFailover': 'enabled'|'disabled'|'enabling'|'disabling',
            'ConfigurationEndpoint': {
                'Address': 'string',
                'Port': 123
            },
            'SnapshotRetentionLimit': 123,
            'SnapshotWindow': 'string',
            'ClusterEnabled': True|False,
            'CacheNodeType': 'string'
        }
    }

    :returns:
    Redis versions earlier than 2.8.6.
    Redis (cluster mode disabled):T1 and T2 cache node types. Redis (cluster mode enabled): T1 node types.

    """
    pass


def list_topics(NextToken=None):
    """
    Returns a list of the requester's topics. Each call returns a limited list of topics, up to 100. If there are more topics, a NextToken is also returned. Use the NextToken parameter in a new ListTopics call to get further results.
    See also: AWS API Documentation

    :example: response = client.list_topics(
        NextToken='string'
    )

    :type NextToken: string
    :param NextToken: Token returned by the previous ListTopics request.

    :rtype: dict
    :return: {
        'Topics': [
            {
                'TopicArn': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


@staticmethod
def _count_lane_invasion(weak_self, event):
    """
        Callback to update lane invasion count
        """
    self = weak_self()
    if not self:
        return
    self.actual_value += 1


def manual_time_offset(values_list, time_x_offset, number_of_flights):
    """Applies a manually defined time offset to the "Time" to all time columns in the values_list"""
    if not time_x_offset:
        return values_list
    elif len(time_x_offset) != number_of_flights:
        print(
            'time_x_offset is not the same length as the number of flights. It has not been applied.'
            )
        return values_list
    else:
        pass
    for flight in range(number_of_flights):
        for sensor_index in range(len(values_list[flight])):
            for data_set_index in range(len(values_list[flight][sensor_index])
                ):
                new_time_data = []
                if values_list[flight][sensor_index][data_set_index][0
                    ] == 'Time':
                    for data_point in values_list[flight][sensor_index][
                        data_set_index][2]:
                        new_time_data.append(float(data_point) + float(
                            time_x_offset[flight]))
                    values_list[flight][sensor_index][data_set_index][2
                        ] = new_time_data
    return values_list


def register_data_language(parse_func, extension):
    """Register a data language for template input.

        parse_func - a function that takes a text and parses it into
                     a data structure.
        extension - the extension to register the data language under.
                     (example: .json).
        """


@classmethod
def _increment_flaky_attribute(cls, test_item, flaky_attribute):
    """
        Increments the value of an attribute on a flaky test.

        :param test_item:
            The test callable on which to set the attribute
        :type test_item:
            `callable` or :class:`nose.case.Test` or :class:`Function`
        :param flaky_attribute:
            The name of the attribute to set
        :type flaky_attribute:
            `unicode`
        """
    cls._set_flaky_attribute(test_item, flaky_attribute, cls.
        _get_flaky_attribute(test_item, flaky_attribute) + 1)


@staticmethod
def get_namespace():
    """
        Retrieves the name space of this command handler
        """
    return 'report'


def _get_ngrams(n, text):
    """Calcualtes n-grams.

    Args:
      n: which n-grams to calculate
      text: An array of tokens

    Returns:
      A set of n-grams
    """
    ngram_set = set()
    text_length = len(text)
    max_index_ngram_start = text_length - n
    for i in range(max_index_ngram_start + 1):
        ngram_set.add(tuple(text[i:i + n]))
    return ngram_set


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

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


def getURLContext():
    """Returns the context the base url."""


def _calc_detlam(xx, yy, zz, yx, zx, zy):
    """
    Calculate determinant of symmetric 3x3 matrix

    [[xx,yx,xz],
     [yx,yy,zy],
     [zx,zy,zz]]
     """
    return zz * (yy * xx - yx ** 2) - zy * (zy * xx - zx * yx) + zx * (zy *
        yx - zx * yy)


@classmethod
def print_exception_warning(cls, tool: str) ->None:
    """
        Print warning about exception not being applied for an issue.

        Warning will only be printed once per tool.
        """
    print(
        '[WARNING] File exceptions not available for {} tool plugin due to lack of absolute paths for issues.'
        .format(tool))


def _format_warnings(message, category, filename, lineno, file=None, line=None
    ):
    """ Warning formatter

    Args:
        message: warning message
        category (str): level of warning
        filename (str): path for warning output
        lineno (int): Where the warning originates

    Returns:
        Formatted warning for logging purposes

    """
    return ' {}:{}:{}: {}\n'.format(category.__name__, filename, lineno,
        message)


def getCommands(args):
    """Split (if needed) and obtain the list of commands that were sent into Skelebot"""
    commands = []
    command = []
    for arg in args:
        if arg == '+':
            commands.append(command)
            command = []
        else:
            command.append(arg)
    commands.append(command)
    return commands


def get_source(fullname):
    """ Return the source code for the module identified by 'fullname'.

        Return a string, using newline characters for line endings, or None
        if the source is not available.

        Raise ImportError if the module can't be found by the importer at all.
        """


def clean_parenthesized_string(string):
    """Produce a clipped substring of `string` comprising all characters from the beginning of
    `string` through the closing paren that matches the first opening paren in `string`

    Parameters
    ----------
    string: String
        A string that contains a parenthesized statement in its entirety, along with extra content
        to be removed. The target parenthesized statement may contain additional parentheses

    Returns
    -------
    clean_string: String
        A substring of `string`, extending from the beginning of `string`, through the closing paren
        that matches the first opening paren found, producing a valid parenthesized statement"""
    close_paren = 0
    for i in range(len(string)):
        if string[i] == '(':
            close_paren += 1
        elif string[i] == ')':
            if close_paren > 1:
                close_paren -= 1
            else:
                return string[:i + 1]
    raise ValueError(
        f'Need closing paren:"""\n{string}\n"""\nRemaining close_paren: {close_paren}'
        )


def disable_honeyagent():
    """
        disable_honeyagent

        Disable HoneyAgent Java sandbox analysis

        @return: None
        """


@classmethod
def name(cls):
    """Return the name of the build system, eg 'make'."""
    raise NotImplementedError


def process_add_on(add_on):
    """
    simple function to ensure that a query add on string starts with "?"
    """
    if add_on.startswith('&'):
        add_on = '?' + add_on[1:]
    if add_on and not add_on.startswith('?'):
        add_on = '?' + add_on
    return add_on


def p_stringliteral(p):
    """stringliteral : STRPREFIX SHORTSTRING
                     | STRPREFIX LONGSTRING
                     | SHORTSTRING
                     | LONGSTRING"""
    if len(p) == 3:
        p[0] = p[1] + p[2]
    else:
        p[0] = p[1]


@classmethod
def can_install(cls, component, user):
    """Check whether addon is compatible with given component."""
    for key, values in cls.compat.items():
        if getattr(component, key) not in values:
            return False
    return True


def revert_mainfile(use_scripts: bool=True):
    """Reload the saved file

    :param use_scripts: Trusted Source, Allow .blend file to execute scripts automatically, default available from system preferences
    :type use_scripts: bool
    """
    pass


@classmethod
def join_name(cls, source, direction):
    """
        Joins a shift *source* and a shift *direction* to return a shift name. If either *source* or
        *direction* is *None*, *None* is returned. If *source* is *NOMINAL*, *direction* must be
        *NOMINAL* as well. Otherwise, *direction* must be either *UP* or *DOWN*. Example:

        .. code-block:: python

            join_name("nominal", "nominal")  # -> "nominal"
            join_name("nominal", "up")       # -> ValueError: pointless nominal shift direction
            join_name("pdf", "up")           # -> "pdf_up"
            join_name("pdf", "high")         # -> ValueError: invalid shift direction
        """
    if source == cls.NOMINAL:
        if direction != cls.NOMINAL:
            raise ValueError('pointless nominal shift direction: {}'.format
                (direction))
        else:
            return cls.NOMINAL
    elif direction in (cls.UP, cls.DOWN):
        return '{}_{}'.format(source, direction)
    else:
        raise ValueError('unknown shift direction: {}'.format(direction))


def is_upsidedown_wrong(name):
    """Tell if the string would get a different meaning if written upside down"""
    chars = set(name)
    mistakable = set('69NZMWpbqd')
    rotatable = set('80oOxXIl').union(mistakable)
    return chars.issubset(rotatable) and not chars.isdisjoint(mistakable)


def native_string(string):
    """
    Make C{string} be the type of C{str}, decoding with ASCII if required.
    """
    if isinstance(string, bytes):
        return string.decode('ascii')
    else:
        raise ValueError('This is already a native string.')


def psf_with_odd_dimensions_from_psf(psf):
    """
    If the PSF kernel has one or two even-sized dimensions, return a PSF object where the kernel has odd-sized
    dimensions (odd-sized dimensions are required by a *Convolver*).

    Kernels are rescaled using the scikit-image routine rescale, which performs rescaling via an interpolation
    routine. This may lead to loss of accuracy in the PSF kernel and it is advised that users, where possible,
    create their PSF on an odd-sized array using their data reduction pipelines that remove this approximation.

    Parameters
    ----------
    rescale_factor : float
        The factor by which the kernel is rescaled. If this has a value of 1.0, the kernel is rescaled to the
        closest odd-sized dimensions (e.g. 20 -> 19). Higher / lower values scale to higher / lower dimensions.
    renormalize : bool
        Whether the PSF should be renormalized after being rescaled.
    """
    return psf.rescaled_with_odd_dimensions_from_rescale_factor(rescale_factor
        =1.0)


def name(path):
    """Extracts file name without extension"""
    return path[:path.rfind('.', 0)]


def process_origin(data, template):
    """
    Replace {$origin} in template with a serialized $ORIGIN record
    """
    record = ''
    if data is not None:
        record += '$ORIGIN %s' % data
    return template.replace('{$origin}', record)


def _find_left_index(gridpoints, s):
    """Find the least lowest entry that is larger or equal.

    Parameters
    ----------
    gridpoints:
        Array of path positions.
    s:
        A path position.

    Returns
    -------
    out:
        The desired index.

    """
    for i in range(1, len(gridpoints)):
        if gridpoints[i - 1] <= s < gridpoints[i]:
            return i - 1
    return len(gridpoints) - 2


def carb_effect_curve(t, absorption_time):
    """Returns the fraction of total carbohydrate effect with a given absorption time on blood
    glucose at the specified number of minutes after eating.

    This is the integral of Carbs on Board (COB), defined by a Scheiner GI curve from Think Link a
    Pancreas, fig 7-8. This is based on an algorithm that first appeared in GlucoDyn

    See: https://github.com/kenstack/GlucoDyn

    :param t: The time in minutes since the carbs were eaten
    :type t: float
    :param absorption_time: The total absorption time of the carbohydrates in minutes
    :type absorption_time: int
    :return: A percentage of the initial carb intake, from 0 to 1
    :rtype: float
    """
    if t <= 0:
        return 0.0
    elif t <= absorption_time / 2.0:
        return 2.0 / absorption_time ** 2 * t ** 2
    elif t < absorption_time:
        return -1.0 + 4.0 / absorption_time * (t - t ** 2 / (2.0 *
            absorption_time))
    else:
        return 1.0


def get_current_k8s_namespace():
    """Get the current namespace of kubernetes."""
    with open('/var/run/secrets/kubernetes.io/serviceaccount/namespace', 'r'
        ) as f:
        return f.readline()


def close(z):
    """
    Close *z* if possible.
    """
    if hasattr(z, 'close'):
        z.close()


@staticmethod
def _validate_init_data(**kwargs):
    """ Validate data for the constructor of a new object """
    raise NotImplementedError('Not implemented in base (BaseTensorTD) class')


@staticmethod
def get_output_of_stage():
    """Result of processing input with current control params."""
    raise NotImplementedError


@staticmethod
def strip_ws_name(range_str):
    """Splits out the worksheet reference, if any, from a range reference."""
    if '!' in range_str:
        sheet, range_str = range_str.rsplit('!', 1)
        return sheet + '!', range_str
    return '', range_str


def merge_metadata(cls):
    """
    Merge all the __metadata__ dicts in a class's hierarchy

    keys that do not begin with '_' will be inherited.

    keys that begin with '_' will only apply to the object that defines them.

    """
    cls_meta = cls.__dict__.get('__metadata__', {})
    meta = {}
    for base in cls.__bases__:
        meta.update(getattr(base, '__metadata__', {}))
    for key in list(meta.keys()):
        if key.startswith('_'):
            del meta[key]
    meta.update(cls_meta)
    return meta


def percentage(value, total_sum):
    """calculate a percentage"""
    if total_sum == 0:
        return 0
    else:
        return round(100 * float(value) / float(total_sum))


def set_config_fields(app):
    """  Add custom who can read/right fields in the schema so we can know the documents rights

        :param app the eve application
    """
    account_definition = {'type': 'list', 'default': [], 'schema': {'type':
        'objectid', 'data_relation': {'resource': app.config[
        'ACCOUNT_RESOURCE'], 'field': '_id'}}}
    domain = app.config['DOMAIN']
    for resource in domain:
        if resource != app.config['ACCOUNT_RESOURCE'
            ] and resource not in app.config['RESOURCE_BLACKLIST']:
            domain[resource]['schema'][app.config['ACL_FIELDS_READ']
                ] = account_definition
            domain[resource]['schema'][app.config['ACL_FIELDS_WRITE']
                ] = account_definition


def _already_there_msg(folder):
    """Print a message indicating that dataset is already in place."""
    msg = 'Dataset is already in place. If you want to fetch it again '
    msg += 'please first remove the folder %s ' % folder
    print(msg)


@staticmethod
def has(obj, key):
    """
		Returns `True` if the `key` is a key or a defined attribute in `obj`. Otherwise, returns `False`.

		Parameters
		----------
		obj : dict or object
			The target to check existence of a key-value pair or an attribute.
		key : str
			A `dict` key or an attribute name.

		Returns
		-------
		bool
			Existence of a key-value pair or an attribute.
		"""
    if isinstance(obj, dict):
        return key in obj
    else:
        return hasattr(obj, key)


def create_blank_udic(ndim):
    """
    Create a blank universal dictionary for a spectrum of dimension ndim.
    """
    udic = dict()
    udic['ndim'] = ndim
    for i in range(ndim):
        d = dict()
        d['sw'] = 999.99
        d['complex'] = True
        d['obs'] = 999.99
        d['car'] = 999.99
        d['size'] = 1
        d['label'] = ['X', 'Y', 'Z', 'A'][i]
        if i == ndim - 1:
            d['encoding'] = 'direct'
        else:
            d['encoding'] = 'states'
        d['time'] = True
        d['freq'] = False
        udic[i] = d
    return udic


def delete_rest_api(restApiId=None):
    """
    Deletes the specified API.
    See also: AWS API Documentation

    :example: response = client.delete_rest_api(
        restApiId='string'
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            The ID of the RestApi you want to delete.

    """
    pass


def formatPath(path):
    """
return a string representation of the path with:
    - doubling of escape characters \\\\;
    - strip of the side ' characters.
    """
    return repr(path).strip("'")


def isDiscussionAllowedFor(content):
    """ Return True discussion is allowed for 'content', else False.

        o Result may be looked up from an object-specific value, or by place,
          or from a site-wide policy.

        o Permission:  Public
        """


def compile_menu(name):
    """Compiles the menu from application specifications.

    Args:
        name (str): name of the menu to compile.
    """
    return {}


def id_equals(id1, id2):
    """Return True if the two IDs are considered equal."""
    return id1.lower() == id2.lower()


@staticmethod
def _readMeta(fd):
    """Read meta array from the top of a file. Read lines until a blank line is reached.
        This function should ideally work for ALL versions of MetaArray.
        """
    meta = u''
    while True:
        line = fd.readline().strip()
        if line == '':
            break
        meta += line
    ret = eval(meta)
    return ret


@classmethod
def default(cls):
    """Return the singleton instance. Create if necessary."""
    if cls._DEFAULT is None:
        cls._DEFAULT = cls()
    return cls._DEFAULT


def compress_array(array, new_size):
    """Compress array by averaging over fusionned cells"""
    l = len(array)
    k = l / new_size
    new_array = list()
    for i in range(0, l, k):
        val = sum(array[i:i + k]) / k
        new_array.append(val)
    return new_array


def p_const_map(p):
    """const_map : '{' const_map_seq '}' """
    p[0] = dict(p[2])


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


def __extract_license(dist):
    """Extracts license information from PKG-INFO metadata. Returns "UNKNOWN" if no license can be found.

    :param dist: the distribution
    :type dist: pkg_resources.Distribution
    :return: license (str) or None
    """
    if not dist.has_metadata('PKG-INFO'):
        return 'UNKNOWN'
    for line in dist.get_metadata_lines('PKG-INFO'):
        try:
            meta_key, meta_value = line.split(': ', 1)
        except ValueError:
            continue
        if meta_key == 'License':
            return meta_value


def _subject_from_forward(forward):
    """Get subject id from inverse operator."""
    return forward['src']._subject


def tensor(data, dtype=None):
    """Create a tensor given the data and data type.

    Parameters
    ----------
    data : input data
        The interface should at least support list and numpy array.
        The data is copied to a newly-allocated tensor.
    dtype : data type, optional
        It should be one of the values in the data type dict.
        If is none, the type should be inferred from data.

    Returns
    -------
    Tensor
        A framework-specific tensor.
    """
    pass


def hex_to_dec(x):
    """
    Convert hex to decimal
    """
    return int(x, 16)


def sRGB2RGB(img):
    """ this function converts a sRGB img to  linear RGB values.

        It loops through each pixel, and apply a conversion to pass from sRGB to linear RGB value.

        :param img: image to analyze, in sRGB
        :type img: numpy.ndarray
        :return: image to analyze, in RGB
        :rtyipe: numpy.ndarray
    """
    newimg = []
    for row in img:
        thisrow = []
        for pixel in row:
            thispixel = []
            for value in pixel:
                if value / 255 <= 0.04045:
                    thispixel.append(value / (255 * 12.92))
                else:
                    thispixel.append(((value / 255 + 0.055) / 1.055) ** 2.4)
            thisrow.append(thispixel)
        newimg.append(thisrow)
    return newimg


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


def clipMinMax(size, minSize, maxSize):
    """
    Clip the size so it is bigger then minSize but smaller than maxSize.
    """
    return size.expandedTo(minSize).boundedTo(maxSize)


def tune_axes(axes):
    """
    BlueSky plan to tune a list of axes in sequence

    EXAMPLE

    Sequentially, tune a list of preconfigured axes::

        RE(tune_axes([mr, m2r, ar, a2r])
    """
    for axis in axes:
        yield from axis.tune()


@classmethod
def factory(cls, global_config, **local_config):
    """Return an instance of the WSGI Router class."""
    return cls()


@classmethod
def _from_base_layout(cls, layout, added_sig=[1, -1], **kw
    ) ->'ConformalLayout':
    """ helper to implement :func:`clifford.conformalize` """
    sig_c = list(layout.sig) + added_sig
    return cls._from_sig(sig=sig_c, firstIdx=layout.firstIdx, layout=layout,
        **kw)


@staticmethod
def setter(*args, **kwargs):
    """A stub. If it isn't overwritten, the property is read-only."""
    raise TypeError(
        "Cannot modify property.  It doesn't have a setter function.")


@classmethod
def prepare_highlight_fields(cls, view):
    """Prepare faceted search fields.

        Prepares the following structure:

            >>> {
            >>>     'author.name': {
            >>>         'enabled': False,
            >>>         'options': {
            >>>             'fragment_size': 150,
            >>>             'number_of_fragments': 3
            >>>         }
            >>>     }
            >>>     'title': {
            >>>         'options': {
            >>>             'pre_tags' : ["<em>"],
            >>>             'post_tags' : ["</em>"]
            >>>         },
            >>>         'enabled': True,
            >>>     },
            >>> }

        :param view:
        :type view: rest_framework.viewsets.ReadOnlyModelViewSet
        :return: Highlight fields options.
        :rtype: dict
        """
    highlight_fields = view.highlight_fields
    for field, options in highlight_fields.items():
        if 'enabled' not in highlight_fields[field]:
            highlight_fields[field]['enabled'] = False
        if 'options' not in highlight_fields[field]:
            highlight_fields[field]['options'] = {}
    return highlight_fields


def _split_geo_name(v):
    """split name of form first,middle,last into dict"""
    return dict(zip('first middle last'.split(), v.split(',')))


def hosts_convert(entry):
    """
    convert an LDAP entry dict to a hosts map tuple
    """
    hostnames = entry['aeFqdn']
    return hostnames[0], hostnames[1:], entry['ipHostNumber']


def iterator(d):
    """
    Helper to get and a proper dict iterator with Py2k and Py3k
    """
    try:
        return d.iteritems()
    except AttributeError:
        return d.items()


def get_sent_dict(sent_filepath):
    """Return a {text:sent_num} dictionary.

    Given an absolute path to a .sentences file
    """
    sent_dict = {}
    sent_iter = 0
    with open(sent_filepath, 'r', encoding='utf-8') as sent_stream:
        for line in sent_stream:
            line = line.rstrip()
            sent_dict[sent_iter] = line
            sent_iter += 1
    return sent_dict


def merge_bed(discordants_pd):
    """Function that takes as input a bed file and returns a pandas dataframe indicating if files should be merged. This
    function will merge everything that is overlapping by at least 1bp"""
    overlap = (discordants_pd.start - discordants_pd.shift().end - 1).lt(0)
    chr_overlap = discordants_pd.chrom == discordants_pd.shift().chrom
    return (overlap * 1 + chr_overlap * 1).lt(2).cumsum()


def color_text(textin, color):
    """
    Adds Latex color to a string.
    """
    if '#' in color:
        textin = '{\\color[HTML]{%s} %s }' % (color.replace('#', '').upper(
            ), textin)
    else:
        textin = '{\\color{%s} %s }' % (color, textin)
    return textin


@classmethod
def get_hartree_energy(cls, calc, **kwargs):
    """Return Hartree energy in eV."""
    return cls._get_pw_energy_value(calc, 'energy_hartree')


def color_list():
    """ List with colors
    """
    color_list = ['darkturquoise', 'orange', 'firebrick', 'darkviolet',
        'khaki', 'olive', 'darkseagreen', 'darkcyan', 'indianred',
        'darkblue', 'orchid', 'gainsboro', 'mediumseagreen', 'lightgray',
        'mediumturquoise', 'lemonchiffon', 'cadetblue', 'lightyellow',
        'lavenderblush', 'coral', 'purple', 'aqua', 'mediumslateblue',
        'darkorange', 'mediumaquamarine', 'darksalmon', 'beige']
    return color_list


def validate(db='', returnDict=False, err=False, deep=True):
    """
    Vaidates the database whether the database is properly operable or not.
    """
    pass


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

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

    .. sourcecode:: Python

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

    The function makes sure that the returned value never overshoots:

    .. sourcecode:: Python

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

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


def HelperMethod1(arg1, arg2, banana):
    """
    Helper meethod for doing something cool. Exactly what it will do, we don't
    know that just yet.

    Inputs: arg1
            arg2
            banana #Because who doesn't like bananas?!?

    Outputs: A silly print statement
    """
    print('Method was called, did you call it? o_O')
    arguments = [arg1, arg2, banana]
    import random
    print(
        'One day a {}, came into the office and was wearing a {} as a hat, thinking it was a {}'
        .format(random.choice(arguments), random.choice(arguments), random.
        choice(arguments)))


def seconds_to_text(secs):
    """ Converts seconds to a string of hours:minutes:seconds """
    hours = secs // 3600
    minutes = (secs - hours * 3600) // 60
    seconds = secs - hours * 3600 - minutes * 60
    return '%02d:%02d:%02d' % (hours, minutes, seconds)


@classmethod
def check_form_match(cls, tensor1=None, tensor2=None, qhape1=None, shape1=
    None, dirs1=None, qhape2=None, shape2=None, dirs2=None, qodulus=None):
    """Check that the given two tensors have the same form in the sense
        that, i.e. that their indices have the same dimensions. Instead of
        giving two tensors, two shapes can also be given.
        """
    if tensor1 is not None:
        shape1 = tensor1.shape
    if tensor2 is not None:
        shape2 = tensor2.shape
    return shape1 == shape2


def get_length_w(fig_width, region_start, region_end, fontsize):
    """
    to improve the visualization of the labels
    it is good to have an estimation of their length
    in base pairs. In the following code I try to get the
    length of a 'W' in base pairs.
    """
    inches_per_pt = 1.0 / 72.27
    font_in_inches = fontsize * inches_per_pt
    region_len = region_end - region_start
    bp_per_inch = region_len / fig_width
    font_in_bp = font_in_inches * bp_per_inch
    return font_in_bp


def lemmatiser(list_of_words, tag, translated_option, lem_instance=False,
    preserve_case=False):
    """
    Take a list of unicode words and a tag and return a lemmatised list
    """
    from corpkit.dictionaries.word_transforms import wordlist, taglemma
    if not lem_instance:
        from nltk.stem.wordnet import WordNetLemmatizer
        lem_instance = WordNetLemmatizer()
    output = []
    for word in list_of_words:
        if 'u' in translated_option:
            word = taglemma.get(word.lower(), 'Other')
        else:
            word = wordlist.get(word, lem_instance.lemmatize(word, tag))
        output.append(word)
    return output


def uncommon():
    """least common incoming thing"""


def adapt_shape_array(X, shape_must_be):
    """
    This function takes care of the unspecified dimensions in the required shapes of data structures.
    The None elements in the shape tuple will be replaced with actual shape of the input array.

    Parameters
    ----------
    X: ndarray
        The input numpy array.

    shape_must_be: tuple
        The required shape of the input array, might contains None elements.

    Returns
    -------
    tuple
        The actual shape with no None elements.

    """
    if None in shape_must_be:
        copy_shape_must_be = list(shape_must_be)
        while None in copy_shape_must_be:
            ind = copy_shape_must_be.index(None)
            copy_shape_must_be[ind] = X.shape[ind]
        return tuple(copy_shape_must_be)
    else:
        return shape_must_be


@staticmethod
def process_response(response, request=None):
    """Do whatever you'd like to the response."""
    return response


def CheckLineIntersection(x1, y1, x2, y2, x3, y3, x4, y4):
    """
    Check for line intersection

    :param `x1`: x1 position
    :param `y1`: y1 position
    :param `x2`: x2 position
    :param `y2`: y2 position
    :param `x3`: x3 position
    :param `y3`: y3 position
    :param `x4`: x4 position
    :param `y4`: y4 position

    :returns: a lenght ratio and a k line???

    """
    denominator_term = (y4 - y3) * (x2 - x1) - (y2 - y1) * (x4 - x3)
    numerator_term = (x3 - x1) * (y4 - y3) + (x4 - x3) * (y1 - y3)
    length_ratio = 1.0
    k_line = 1.0
    if denominator_term < 0.005 and denominator_term > -0.005:
        line_constant = -1.0
    else:
        line_constant = float(numerator_term) / denominator_term
    if line_constant < 1.0 and line_constant > 0.0:
        if y4 - y3 < 0.005 and y4 - y3 > -0.005:
            k_line = (x1 - x3 + line_constant * (x2 - x1)) / (x4 - x3)
        else:
            k_line = (y1 - y3 + line_constant * (y2 - y1)) / (y4 - y3)
        if k_line >= 0 and k_line < 1:
            length_ratio = line_constant
        else:
            k_line = 1
    return length_ratio, k_line


@classmethod
def program_name(cls):
    """Return the name of the program that this main window represents"""
    return 'MCR-ALS'


def dispatch_hook(key, hooks, hook_data, **kwargs):
    """Dispatches a hook dictionary on a given piece of data."""
    hooks = hooks or dict()
    if key in hooks:
        hooks = hooks.get(key)
        if hasattr(hooks, '__call__'):
            hooks = [hooks]
        for hook in hooks:
            _hook_data = hook(hook_data, **kwargs)
            if _hook_data is not None:
                hook_data = _hook_data
    return hook_data


def psi_Na_Sr_Cl_MWRB78(T, P):
    """c-c'-a: sodium strontium chloride [MWRB78]."""
    psi = -0.0052
    valid = T == 298.15
    return psi, valid


def get_group_gn(dim, dim_per_gp, num_groups):
    """get number of groups used by GroupNorm, based on number of channels."""
    assert dim_per_gp == -1 or num_groups == -1, 'GroupNorm: can only specify G or C/G.'
    if dim_per_gp > 0:
        assert dim % dim_per_gp == 0, 'dim: {}, dim_per_gp: {}'.format(dim,
            dim_per_gp)
        group_gn = dim // dim_per_gp
    else:
        assert dim % num_groups == 0, 'dim: {}, num_groups: {}'.format(dim,
            num_groups)
        group_gn = num_groups
    return group_gn


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


def latex_table(result, *, decimal_places=3, label=None):
    """
    Creates a latex table from the results dataframe of the statistical analysis.

    # Parameters

    result (RankResult):
        Should be the return value the autorank function.

    decimal_places (int, default=3):
        Number of decimal places that are used for the report.

    label (str, default=None):
        Label of the table. Defaults to 'tbl:stat_results' if None.
    """
    if label is None:
        label = 'tbl:stat_results'
    table_df = result.rankdf
    columns = table_df.columns.to_list()
    if result.pvalue >= result.alpha:
        columns.remove('effect_size')
        columns.remove('magnitude')
    if result.posthoc == 'tukeyhsd':
        columns.remove('meanrank')
    columns.insert(columns.index('ci_lower'), 'CI')
    columns.remove('ci_lower')
    columns.remove('ci_upper')
    rename_map = {}
    if result.all_normal:
        rename_map['effect_size'] = '$d$'
    else:
        rename_map['effect_size'] = 'D-E-L-T-A'
    rename_map['magnitude'] = 'Magnitude'
    rename_map['mad'] = 'MAD'
    rename_map['median'] = 'MED'
    rename_map['meanrank'] = 'MR'
    rename_map['mean'] = 'M'
    rename_map['std'] = 'SD'
    format_string = '[{0[ci_lower]:.' + str(decimal_places
        ) + 'f}, {0[ci_upper]:.' + str(decimal_places) + 'f}]'
    table_df['CI'] = table_df.agg(format_string.format, axis=1)
    table_df = table_df[columns]
    table_df = table_df.rename(rename_map, axis='columns')
    float_format = '{:0.' + str(decimal_places) + 'f}'
    table_string = table_df.to_latex(float_format=float_format.format).strip()
    table_string = table_string.replace('D-E-L-T-A', '$\\delta$')
    print('\\begin{table}[h]')
    print('\\centering')
    print(table_string)
    print('\\caption{Summary of populations}')
    print('\\label{%s}' % label)
    print('\\end{table}')


def textile(text, **kwargs):
    """
    Applies Textile conversion to a string, and returns the HTML.

    This is simply a pass-through to the ``textile`` template filter
    included in ``django.contrib.markup``, which works around issues
    PyTextile has with Unicode strings. If you're not using Django but
    want to use Textile with ``MarkupFormatter``, you'll need to
    supply your own Textile filter.

    """
    from django.contrib.markup.templatetags.markup import textile
    return textile(text)


def properties():
    """Toggle the properties region visibility

    """
    pass


def setLogFormat(f_format):
    """Set the log format. (Has to be set before logToSomething is called)."""
    global FANCYLOG_LOGGING_FORMAT
    FANCYLOG_LOGGING_FORMAT = f_format


def getId():
    """
        Return the object's id in the tree.
        """


@staticmethod
def activity_2_freq(trace):
    """For a given trace, return a mapping from activity to frequency in trace.

        Parameters
        ----------
        trace: `tuple` of `str`
            a trace as a tuple of activities

        Returns
        -------
        `dict`
            mapping from activity to frequency in trace
        """
    d = {}
    for a in trace:
        if a not in d:
            d[a] = 0
        d[a] += 1
    return d


def table_to_str(tab):
    """
    Produce a formatted string for a translation table.

    Given a table stored as a dictionary, sort the contents and return the
    table as text in the translation table format for storage.

    """
    table_str = ''
    items = list(tab.items())
    items.sort(key=lambda x: (-len(x[0]), x[0]))
    for i in items:
        table_str += i[0] + '|' + '|'.join(i[1]) + '\n'
    return table_str


def all_keys():
    """
        Return an iterable over all keys in the collection. May return a
        deferred instead of the iterable.
        """


@classmethod
def isMine(cls, *args, **kwds):
    """
        True if this file or object can be identified
        for use by this class. Useful to override for
        classes that can be initialized from disk.
        """
    return False


def decode_signed_value(name, value):
    """Reverse of `create_signed_value`. Returns orignal value string."""


def do_insertions(insertions, tokens):
    """
    Helper for lexers which must combine the results of several
    sublexers.

    ``insertions`` is a list of ``(index, itokens)`` pairs.
    Each ``itokens`` iterable should be inserted at position
    ``index`` into the token stream given by the ``tokens``
    argument.

    The result is a combined token stream.

    TODO: clean up the code here.
    """
    insertions = iter(insertions)
    try:
        index, itokens = next(insertions)
    except StopIteration:
        for item in tokens:
            yield item
        return
    realpos = None
    insleft = True
    for i, t, v in tokens:
        if realpos is None:
            realpos = i
        oldi = 0
        while insleft and i + len(v) >= index:
            tmpval = v[oldi:index - i]
            yield realpos, t, tmpval
            realpos += len(tmpval)
            for it_index, it_token, it_value in itokens:
                yield realpos, it_token, it_value
                realpos += len(it_value)
            oldi = index - i
            try:
                index, itokens = next(insertions)
            except StopIteration:
                insleft = False
                break
        yield realpos, t, v[oldi:]
        realpos += len(v) - oldi
    while insleft:
        realpos = realpos or 0
        for p, t, v in itokens:
            yield realpos, t, v
            realpos += len(v)
        try:
            index, itokens = next(insertions)
        except StopIteration:
            insleft = False
            break


def help(key):
    """Return the help text specific to a certain key
        """
    help_dict = {}
    return_text = help_dict.get(key, 'no help available')
    return return_text


def create_empty_copy(G, with_data=True):
    """Return a copy of the graph G with all of the edges removed.
        Parameters
        ----------

        G : graph
           A DyNetx graph

        with_data :  bool (default=True)
           Include data.

        Notes
        -----
        Graph and edge data is not propagated to the new graph.
        """
    H = G.__class__()
    H.add_nodes_from(G.nodes(data=with_data))
    if with_data:
        H.graph.update(G.graph)
    return H


def parse_seqid_file(seqfile):
    """
    Read in a file of SEQ IDs, and return the list of IDs
    :param seqfile: Files containing a column of SEQ IDs
    :return: list of SEQ IDs to process
    """
    seqids = list()
    with open(seqfile) as f:
        for line in f:
            line = line.rstrip()
            if line:
                seqids.append(line)
    return seqids


@classmethod
def get_desc(cls, setid):
    """Retrieves character set information as string using an ID

        Retrieves character set and collation information based on the
        given MySQL ID.

        Returns a tuple.
        """
    try:
        return '%s/%s' % cls.get_info(setid)
    except:
        raise