def convert_args_to_str(args, max_len=None):
    """ Convert args to a string, allowing for some arguments to raise
    exceptions during conversion and ignoring them.
    """
    length = 0
    strs = ['' for i in range(len(args))]
    for i, arg in enumerate(args):
        try:
            sarg = repr(arg)
        except Exception:
            sarg = '< could not convert arg to str >'
        strs[i] = sarg
        length += len(sarg) + 2
        if max_len is not None and length > max_len:
            return '({}'.format(', '.join(strs[:i + 1]))[:max_len]
    else:
        return '({})'.format(', '.join(strs))


def _get_usage(ctx):
    """Alternative, non-prefixed version of 'get_usage'."""
    formatter = ctx.make_formatter()
    pieces = ctx.command.collect_usage_pieces(ctx)
    formatter.write_usage(ctx.command_path, ' '.join(pieces), prefix='')
    return formatter.getvalue().rstrip('\n')


def extract_hydrogens_from_instructions(instruction):
    """
    If the core or the fragment atom contains a "-" means that the user is selecting an specific H to be bonded with
    the heavy atom. For this reason, this detects if this option has been selected by the user and extract the PDB-atom-name
    of each element.
    :param instruction: list that follow this structure: [fragment_pdb_file, pdb_atom_name_of_the_core
    (and H if required), pdb_atom_name_of_the_fragment (and H if required)]
    :return: if the "-" is found in the pdb_atom_name_of_the_core or pdb_atom_name_of_the_fragment it returns a list with
    PDB-atom-names split following this order: heavy_atom_core, hydrogen_core, heavy_atom_fragment, hydrogen_fragment.
    Otherwise it returns False.
    """
    if '-' in instruction[1] or '-' in instruction[2]:
        try:
            heavy_core = instruction[1].split('-')[0]
            hydrogen_core = instruction[1].split('-')[1]
            heavy_fragment = instruction[2].split('-')[0]
            hydrogen_fragment = instruction[2].split('-')[1]
            return heavy_core, hydrogen_core, heavy_fragment, hydrogen_fragment
        except IndexError:
            raise IndexError(
                'To use steriochemistry the hydrogen from the core AND fragmet must be specified via controlfile'
                )
    else:
        return False


@classmethod
def global_javac_classpath(cls, products):
    """Returns a classpath entry for the java compiler library, useable as a tool.

        If no javac library is specified, will return an empty list.  The caller must handle this
        case by defaulting to the JDK's tools.jar.  We can't provide that jar here because we'd have
        to know about a Distribution.
        """
    return cls.global_instance().javac_classpath(products)


def l1_torus_dissimilarity(a, b):
    """See `paper by Ebisu et al. <https://www.semanticscholar.org/paper/TorusE%3A-Knowledge-Graph-Embedding-on-a-Lie-Group-Ebisu-Ichise/990334cf76845e2da64d3baa10b0a671e433d4b6>`_
    for details about the definition of this dissimilarity function.

    """
    assert len(a.shape) == len(b.shape)
    return 2 * min(abs(a - b), 1 - abs(a - b)).sum(dim=-1)


def to_latin_1(value):
    """ Return the input string encoded in latin1 with replace mode for errors
    """
    return value.encode('latin-1', 'replace')


def get_indices_from_sequence(seq, as_dict={}):
    """function which tries to find a pattern provided as dict of the form {643:'Q', 671:'L', 742:'Y', 744:'S', 795:'L'}
	in a sequence, the pattern does not have to start with zero !"""
    if as_dict == {}:
        print('as_idx must be supplied !!')
        exit()
    min_idx = min(as_dict.keys())
    zero_idx2as_dict = {}
    for index, AS in list(as_dict.items()):
        zero_idx2as_dict[index - min_idx] = AS
    index = 0
    for item in seq:
        if item == zero_idx2as_dict[0]:
            temp_dict = {}
            comp_dict = {}
            for key in zero_idx2as_dict:
                if index + key <= len(seq):
                    temp_dict[index + key] = seq[index + key]
                    comp_dict[key] = seq[index + key]
            if comp_dict == zero_idx2as_dict:
                print('Matching sequence pattern found:')
                print(temp_dict)
                return temp_dict
        index += 1
    print('Matching sequence pattern could not be found')


def early_stop(val_acc_history, tasks, early_stop_step_single,
    early_stop_step_multi, required_progress):
    """
  Stop the training if there is no non-trivial progress in k steps
  @param val_acc_history: a list contains all the historical validation acc
  @param required_progress: the next acc should be higher than the previous by
      at least required_progress amount to be non-trivial
  @param t: number of training steps
  @return: a boolean indicates if the model should early stop
  """
    if len(tasks) == 1:
        t = early_stop_step_single
    else:
        t = early_stop_step_multi
    if len(val_acc_history) > t:
        if val_acc_history[-1] - val_acc_history[-1 - t] < required_progress:
            return True
    return False


def mark_as_read(now=None):
    """
        Mark the message as read.
        if ``now`` is provided, it is assumed as an utc timestamp
        and stored
        """


def camel_case_from_underscores(string):
    """generate a CamelCase string from an underscore_string."""
    components = string.split('_')
    string = ''
    for component in components:
        string += component[0].upper() + component[1:]
    return string


def get_pred_and_suc(value, times):
    """
    Return the predecessor and the successor of the value as well as the predecessor of the predecessor of the value
    in the array times.
    :param value: float
    :param times: SortedSet
    :return:
    """
    if len(times) == 2:
        return times[0], times[0], times[1]
    id_before = times.bisect_left(value)
    if value == times[id_before]:
        pred = value
        suc = times[id_before + 1]
        if id_before - 1 < 0:
            pred_pred = times[0]
        else:
            pred_pred = times[id_before - 1]
    else:
        pred = times[id_before - 1]
        suc = times[id_before]
        if id_before - 2 < 0:
            pred_pred = times[0]
        else:
            pred_pred = times[id_before - 2]
    return pred_pred, pred, suc


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

        :param str val:
        :rtype: DeleteSecondaryEmailResult
        """
    return cls('success', val)


def shutting_down(globals=globals):
    """
    Whether the interpreter is currently shutting down.
    For use in finalizers, __del__ methods, and similar; it is advised
    to early bind this function rather than look it up when calling it,
    since at shutdown module globals may be cleared.
    """
    v = globals().get('_shutting_down')
    return v is True or v is None


def extend_trafo_power(extendable_trafos, trafo_params):
    """
    Extend power of first trafo in list of extendable trafos

    Parameters
    ----------
    extendable_trafos : :obj:`list`
        Trafos with rated power below maximum size available trafo
    trafo_params : :pandas:`pandas.DataFrame<dataframe>`
        Transformer parameters
    """
    trafo = extendable_trafos[0]
    trafo_s_max_a_before = trafo.s_max_a
    trafo_nearest_larger = trafo_params.loc[(trafo_params.loc[trafo_params[
        'S_nom'] > trafo_s_max_a_before].loc[:, ('S_nom')].idxmin()), :]
    trafo.s_max_a = trafo_nearest_larger['S_nom']
    trafo.r_pu = trafo_nearest_larger['r_pu']
    trafo.x_pu = trafo_nearest_larger['x_pu']


@staticmethod
def extension(file_path):
    """Get the extension of a file"""
    ext = file_path.split('.')[-1]
    return ext


def _tzoffset2rfc822zone(seconds):
    """Takes an offset, such as from _tzoffset(), and returns an rfc822
       compliant zone specification. Please note that the result of
       _tzoffset() is the negative of what time.localzone and time.altzone is.
    """
    return '%+03d%02d' % divmod(seconds // 60, 60)


def list_tuple_2elem(var, var_name):
    """
    Check if parameter *var* is a list/tuple with 2 elements.

    :raises TypeError: Parameter *var* must be a list/tuple.
    :raises ValueError: Parameter *var* must contain 2 elements.
    """
    if var is None:
        return
    if not isinstance(var, (list, tuple)):
        raise TypeError('\n\nParameter {} must be a list/tuple\n'.format(
            var_name))
    if len(var) != 2:
        raise ValueError(
            '\n\nParameter {} must be a list/tuple of length two.\n'.format
            (var_name))


def atom_mass(atom, coef=0.01):
    """Get the mass of an atom and scale it.

    Parameters
    ----------
    atom : rdkit.Chem.rdchem.Atom
        RDKit atom instance.
    coef : float
        The mass will be multiplied by ``coef``.

    Returns
    -------
    list
        List containing one float only.
    """
    return [atom.GetMass() * coef]


def changeVolume(raw, scale):
    """
    Change the volume

    Parameters
    ----------
    raw: np.array
        The raw sound data
    scale: num
        The change scale

    Returns
    -------
    value: np.array
        The changed sound data
    """
    return raw * scale


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 dividez(a, b):
    """Divide one array-like object by another with items that are zero divisors set to zero"""
    d = a / b
    d[b == 0] = 0
    return d


def distance_calc(s1, s2):
    """
    Calculate Levenshtein distance between two words.

    :param s1: first word
    :type s1 : str
    :param s2: second word
    :type s2 : str
    :return: distance between two word

    References :
    1- https://stackoverflow.com/questions/2460177/edit-distance-in-python
    2- https://en.wikipedia.org/wiki/Levenshtein_distance
    """
    if len(s1) > len(s2):
        s1, s2 = s2, s1
    distances = range(len(s1) + 1)
    for i2, c2 in enumerate(s2):
        distances_ = [i2 + 1]
        for i1, c1 in enumerate(s1):
            if c1 == c2:
                distances_.append(distances[i1])
            else:
                distances_.append(1 + min((distances[i1], distances[i1 + 1],
                    distances_[-1])))
        distances = distances_
    return distances[-1]


def is_ipv4(address):
    """It checks if address is valid IP v4

    """
    import socket
    try:
        socket.inet_aton(address)
        return True
    except socket.error:
        return False


def __iter__():
    """Iter on the results.
        """


def get_plural_string(word: str, amount: int) ->str:
    """Returns singular or plural of the word depending on the amount.
	Example:
		word = 'piece', amount = 0 -> '0 pieces'
		word = 'piece', amount = 1 -> '1 piece'
		word = 'piece', amount = 5 -> '5 pieces'"""
    if amount == 1:
        return f'1 {word}'
    else:
        return f'{amount} {word}s'


def RGBColor(*args, **metadata):
    """ Returns a trait whose value must be a GUI toolkit-specific RGB-based
        color.

    Description
    -----------
    For wxPython, the returned trait accepts any of the following values:

    * A tuple of the form (*r*, *g*, *b*), in which *r*, *g*, and *b* represent
      red, green, and blue values, respectively, and are floats in the range
      from 0.0 to 1.0
    * An integer whose hexadecimal form is 0x*RRGGBB*, where *RR* is the red
      value, *GG* is the green value, and *BB* is the blue value

    Default Value
    -------------
    For wxPython, (1.0, 1.0, 1.0) (that is, white)
    """
    from traitsui.toolkit_traits import RGBColorTrait
    return RGBColorTrait(*args, **metadata)


def formatArgValues(args, varargs, varkw, localsDict, formatarg=str,
    formatvarargs=lambda name: '*' + name, formatvarkw=lambda name: '**' +
    name, formatvalue=lambda value: '=' + repr(value)):
    """Formats an argument spec from the 4 values returned by getArgValues"""
    specs = []
    for i in range(len(args)):
        name = args[i]
        specs.append(formatarg(name) + formatvalue(localsDict[name]))
    if varargs:
        specs.append(formatvarargs(varargs) + formatvalue(localsDict[varargs]))
    if varkw:
        specs.append(formatvarkw(varkw) + formatvalue(localsDict[varkw]))
    argvalues = '(' + ', '.join(specs) + ')'
    if '__return__' in localsDict:
        argvalues += ' -> ' + formatvalue(localsDict['__return__'])
    return argvalues


@classmethod
def from_binary_descriptor(cls, data):
    """
        Attempts to create a USBDescriptor subclass from the given raw
        descriptor data.
        """
    for subclass in cls.__subclasses__():
        if subclass.handles_binary_descriptor(data):
            return subclass.from_binary_descriptor(data)
    return None


def singlecolormap(color, func=None, n=64):
    """
    Creates a linear colormap where `color` is the top, and func(color) is the
    bottom.

    `func` should take an RGB tuple as its only input.  If `func` is None, then
    use a light gray as the min.

    `n` is the number of levels.
    """
    if func is None:

        def func(x):
            return '0.9'
    import numpy as np
    import matplotlib
    rgb = np.array(matplotlib.colors.colorConverter.to_rgb(color))
    return matplotlib.colors.LinearSegmentedColormap.from_list(name=
        'colormap', colors=[func(rgb), rgb], N=n)


@classmethod
def fromDict(cls, _dict):
    """ Builds instance from dictionary of properties. """
    obj = cls()
    obj.__dict__.update(_dict)
    return obj


def _can_crop_simply(center, output_image_shape, processed_frame):
    """
    We can make a simple crop if the output_image_shape with its center position set, fits in the processed_frame
    """
    return (center - output_image_shape // 2 >= 0).all() and (center +
        output_image_shape // 2 < processed_frame.shape).all()


def entries_to_lines(entries):
    """Turn a list of entries into a flat iterable of lines."""
    for entry in entries:
        for line in entry:
            yield line


def datetime_to_string(datetime):
    """
    Serializes a datetime to a string.
    :param datetime: datetime value
    :return: string. containing iso8601 format date string
    """
    return datetime.isoformat().replace('+00:00', 'Z')


def sensible_heat_flux_bare(rn_bare, fraction_h_bare=0.65):
    """
    Computes the bare soil sensible heat flux

    .. math ::

        H_{bare} = H_{f, bare}Q^*_{bare}

    Parameters
    ----------
    rn_bare : float
        net radiation bare soil
        :math:`Q^*_{bare}`
        [Wm-2]
    fraction_h_bare : float
        fraction of H of net radiation bare soil
        :math:`H_{f, bare}`
        [-]

    Returns
    -------
    h_bare : float
        sensible heat flux bare soil
        :math:`H_{bare}`
        [Wm-2]
     """
    return rn_bare * fraction_h_bare


def with_iter(context_manager):
    """Wrap an iterable in a ``with`` statement, so it closes once exhausted.

    For example, this will close the file when the iterator is exhausted::

        upper_lines = (line.upper() for line in with_iter(open('foo')))

    Any context manager which returns an iterable is a candidate for
    ``with_iter``.

    """
    with context_manager as iterable:
        yield from iterable


def recvall(sock, size):
    """
    Receive data of given size from a socket connection
    """
    data = b''
    while len(data) < size:
        s = sock.recv(size - len(data))
        data += s
        if not s:
            raise RuntimeError(
                'did not receive data from socket (size {}, got only {!r})'
                .format(size, data))
    return data


def subscribe(dest, ack='auto'):
    """STOMP subscribe command.

    dest:
        This is the channel we wish to subscribe to

    ack: 'auto' | 'client'
        If the ack is set to client, then messages received will
        have to have an acknowledge as a reply. Otherwise the server
        will assume delivery failure.

    """
    return 'SUBSCRIBE\ndestination: %s\nack: %s\n\n\x00\n' % (dest, ack)


@classmethod
def universal(cls):
    """Create a RegexSet object matching any string."""
    return cls('(.|\n)*')


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

        :param DeviceSessionArg val:
        :rtype: RevokeDeviceSessionArg
        """
    return cls('web_session', val)


def defaults(opts, *defaults):
    """defaults({'a': 'a'}, {'a': 'b', 'b': 'b'}) -> {'a': 'a', 'b': 'b'}

    Set defaults in a dictionary.
    """
    for default in defaults:
        for key, value in default.iteritems():
            if key not in opts:
                opts[key] = value
    return opts


def is_float(value):
    """Checks if `value` is a float.

    Args:
        value (mixed): Value to check.

    Returns:
        bool: Whether `value` is a float.

    Example:

        >>> is_float(1.0)
        True
        >>> is_float(1)
        False

    .. versionadded:: 2.0.0
    """
    return isinstance(value, float)


def atoi(text):
    """Convert string to integer"""
    return int(text) if text.isdigit() else text


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 add_mesh(cube, url):
    """
    Adds the unstructured mesh info the to cube.  Soon in an iris near you!

    """
    from pyugrid import UGrid
    ug = UGrid.from_ncfile(url)
    cube.mesh = ug
    cube.mesh_dimension = 1
    return cube


def instance_build(cls, *args, **kwargs):
    """Builds an instance belonging to one of related types."""
    raise NotImplementedError


def to_binary(value, encoding='utf-8'):
    """Convert value to binary string, default encoding is utf-8

    :param value: Value to be converted
    :param encoding: Desired encoding
    """
    if not value:
        return b''
    if isinstance(value, bytes):
        return value
    if isinstance(value, str):
        return value.encode(encoding)
    return bytes(value)


@classmethod
def restart(cls, resources, background=False):
    """Restart a PaaS instance."""
    if not isinstance(resources, (list, tuple)):
        resources = [resources]
    opers = []
    for item in resources:
        oper = cls.call('paas.restart', cls.usable_id(item))
        if isinstance(oper, list):
            opers.extend(oper)
        else:
            opers.append(oper)
    if background:
        return opers
    cls.echo('Restarting your PaaS instance.')
    cls.display_progress(opers)


def __wrap_string_vales(_where_value):
    """This function wraps values going in the WHERE clause in single-quotes if they are not integers.

    :param _where_value: The value to be evaluated and potentially wrapped in single-quotes
    :returns: The value in int or string format
    """
    try:
        _where_value = int(_where_value)
    except (TypeError, ValueError):
        _where_value = f"'{_where_value}'"
    return _where_value


def __call__(context, request, args):
    """See IQueryDefaults.__call__"""


def zerocopy_from_dgl_ndarray(input):
    """Zerocopy a dgl.ndarray.NDArray to framework-specific Tensor

    Parameters
    ----------
    input : dgl.ndarray.NDArray

    Returns
    -------
    Tensor
    """
    pass


def to_python_arg(java_arg):
    """Convert a Thrift JavaObjectArg into a basic Python data type"""
    arg = None
    for val in java_arg.__dict__.values():
        if val is not None:
            arg = val
            break
    return arg


def link():
    """Get the url of this reference.
        """


def hsts_header(domain):
    """
    Domain's HSTS header is its canonical endpoint's header.
    """
    canonical, https, httpswww = (domain.canonical, domain.https, domain.
        httpswww)
    if canonical.host == 'www':
        canonical_https = httpswww
    else:
        canonical_https = https
    return canonical_https.hsts_header


def hug(*xs):
    """Return a tuple of all the arguments."""
    return xs


@staticmethod
def _find_cpu(clc, module):
    """
        Find or validate the CPU value by calling the CLC API
        :param clc: clc-sdk instance to use
        :param module: module to validate
        :return: Int value for CPU
        """
    cpu = module.params.get('cpu')
    group_id = module.params.get('group_id')
    alias = module.params.get('alias')
    state = module.params.get('state')
    if not cpu and state == 'present':
        group = clc.v2.Group(id=group_id, alias=alias)
        if group.Defaults('cpu'):
            cpu = group.Defaults('cpu')
        else:
            module.fail_json(msg=str(
                "Can't determine a default cpu value. Please provide a value for cpu."
                ))
    return cpu


@staticmethod
def is_command_file(filename):
    """Determines based on file name if command file."""
    if filename.endswith('.py') and filename.startswith('command_'):
        return True
    return False


def new_app_text(db):
    """
    Returns /docProps/app.xml text

    :param pylightxl.Database db: database contains sheetnames, and their data
    :return str: /docProps/app.xml text
    """
    xml_base = (
        '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<Properties xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">\r\n<Application>Microsoft Excel</Application>\r\n<DocSecurity>0</DocSecurity>\r\n<ScaleCrop>false</ScaleCrop>\r\n<HeadingPairs>\r\n<vt:vector baseType="variant" size="2">\r\n<vt:variant>\r\n<vt:lpstr>Worksheets</vt:lpstr>\r\n</vt:variant>\r\n<vt:variant>\r\n<vt:i4>{num_sheets}</vt:i4>\r\n</vt:variant>\r\n</vt:vector>\r\n</HeadingPairs>\r\n<TitlesOfParts>\r\n<vt:vector baseType="lpstr" size="{num_sheets}">\r\n{many_tag_vt}\r\n</vt:vector>\r\n</TitlesOfParts>\r\n<Company></Company>\r\n<LinksUpToDate>false</LinksUpToDate>\r\n<SharedDoc>false</SharedDoc>\r\n<HyperlinksChanged>false</HyperlinksChanged>\r\n<AppVersion>16.0300</AppVersion>\r\n</Properties>'
        )
    tag_vt = '<vt:lpstr>{sheet_name}</vt:lpstr>\r\n'
    num_sheets = len(db.ws_names)
    many_tag_vt = ''
    for sheet_name in db.ws_names:
        many_tag_vt += tag_vt.format(sheet_name=sheet_name)
    rv = xml_base.format(num_sheets=num_sheets, many_tag_vt=many_tag_vt)
    return rv


def resource_accepts_ranges(resource):
    """Check whether a resource can serve ranged bodies
    """
    return hasattr(resource, 'get_typed_body_range')


def _torf(args):
    """Return True if all args are True, False if they
    are all False, else None.

    >>> from sympy.core.logic import _torf
    >>> _torf((True, True))
    True
    >>> _torf((False, False))
    False
    >>> _torf((True, False))
    """
    sawT = sawF = False
    for a in args:
        if a is True:
            if sawF:
                return
            sawT = True
        elif a is False:
            if sawT:
                return
            sawF = True
        else:
            return
    return sawT


def _remove_attributes(attrs, remove_list):
    """
    Removes attributes in the remove list from the input attribute dict
    :param attrs : Dict of operator attributes
    :param remove_list : list of attributes to be removed

    :return new_attr : Dict of operator attributes without the listed attributes.
    """
    new_attrs = {}
    for attr in attrs.keys():
        if attr not in remove_list:
            new_attrs[attr] = attrs[attr]
    return new_attrs


def chunk_interslices(nchunks):
    """Make staggered chunks

    Similar to chunk_slices, but pick every nth element instead of
    getting a contiguous patch for each chunk

    Parameters:
        nchunks: how many chunks to make

    Returns:
        a list of (start, stop, step) tuples with length nchunks

    Example:
        >>> chunk_slices(2) == [(0, None, 2), (1, None, 2)]
        True
    """
    ret = [None] * nchunks
    for i in range(nchunks):
        ret[i] = i, None, nchunks
    return ret


def proc_runtime_config_setter(this, value):
    """Try to override the proc property values
    if possible from runtime config"""
    if not value:
        return
    for key, val in value.items():
        if key == 'envs':
            this.envs.update(val)
        elif key == 'config':
            this.config.update(val)
        elif this._setcounter.get(key) or key == 'runner':
            continue
        else:
            setattr(this, key, val)


def impact_to_coverage(impact, impact_col_name='Impact'):
    """
    Convert an impact DataFrame to a coverage DataFrame

    The returned coverage DataFrame can be used for input to a
    :py:class:`CoverageFormulation<chama.optimization.CoverageFormulation>`.

    Parameters
    ----------
    impact : pandas DataFrame
        DataFrame containing three columns. 'Scenario' is the name of the
        scenarios, 'Sensor' is the name of the sensors, and a third column
        (called impact_col_name) contains an impact value.
    impact_col_name : str
        The name of the column containing the impact data (default = 'Impact')

    Returns
    -------
    coverage : pandas DataFrame
        DataFrame with columns 'Sensor' and 'Coverage' to be used as input
        to a coverage-based sensor placement solver.

    """
    coverage = impact.copy()
    coverage.drop(impact_col_name, axis=1, inplace=True)
    coverage = coverage.groupby('Sensor')['Scenario'].unique()
    coverage = coverage.reset_index()
    coverage.rename(columns={'Scenario': 'Coverage'}, inplace=True)
    return coverage


@classmethod
def sanitize(cls, url):
    """Clean and validate urls that should be verified as broken links."""
    if not url:
        return ''
    if url.startswith('#'):
        return ''
    if url.startswith('mailto:'):
        return ''
    if url.endswith('#respond'):
        return ''
    if cls.must_ignore(url):
        return ''
    if url.startswith('//'):
        url = cls.base_url_protocol + ':' + url
    elif url.startswith('/'):
        url = cls.base_url_protocol + '://' + cls.base_url_domain + url
    url = url.strip()
    return url


@staticmethod
def _run_on_subset(func, df_subset):
    """Applies a function to a dataframe subset."""
    return df_subset.apply(func, axis=1)


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

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

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


def get_required_values(generator, field):
    """
    Gets required values for a generator from the field.
    If required value is a function, calls it with field as argument.
    If required value is a string, simply fetch the value from the field
    and return.
    """
    rt = {}
    if hasattr(generator, 'required'):
        for item in generator.required:
            if callable(item):
                key, value = item(field)
                rt[key] = value
            elif isinstance(item, str):
                rt[item] = getattr(field, item)
            else:
                raise ValueError(
                    "Required value '%s' is of wrong type.                                   Don't make mommy sad."
                     % str(item))
    return rt


def unsubscribe_from_dataset(IdentityPoolId=None, IdentityId=None,
    DatasetName=None, DeviceId=None):
    """
    Unsubscribes from receiving notifications when a dataset is modified by another device.
    This API can only be called with temporary credentials provided by Cognito Identity. You cannot call this API with developer credentials.
    See also: AWS API Documentation

    :example: response = client.unsubscribe_from_dataset(
        IdentityPoolId='string',
        IdentityId='string',
        DatasetName='string',
        DeviceId='string'
    )

    :type IdentityPoolId: string
    :param IdentityPoolId: [REQUIRED]
            A name-spaced GUID (for example, us-east-1:23EC4050-6AEA-7089-A2DD-08002EXAMPLE) created by Amazon Cognito. The ID of the pool to which this identity belongs.

    :type IdentityId: string
    :param IdentityId: [REQUIRED]
            Unique ID for this identity.

    :type DatasetName: string
    :param DatasetName: [REQUIRED]
            The name of the dataset from which to unsubcribe.

    :type DeviceId: string
    :param DeviceId: [REQUIRED]
            The unique ID generated for this device by Cognito.

    :rtype: dict
    :return: {}

    """
    pass


def placate_pyflakes(*args):
    """A do-nothing method that suppresses pyflakes warnings."""


@staticmethod
def refresh(critic, tables, cached_objects):
    """Refresh objects after transaction commit

           The |tables| parameter is a set of database tables that were modified
           in the transaction. The |cached_objects| parameter is a dictionary
           mapping object ids to cached objects (wrappers) of this type."""
    pass


def get_sector_count(count):
    """! @brief Return string for sector count with correct plurality."""
    if count == 1:
        return '1 sector'
    else:
        return '{} sectors'.format(count)


def getAllLanguages():
    """Find all the languages that are available"""


def _parse_content_type_header(header):
    """Returns content type and parameters from given header

    :param header: string
    :return: tuple containing content type and dictionary of
         parameters
    """
    tokens = header.split(';')
    content_type, params = tokens[0].strip(), tokens[1:]
    params_dict = {}
    items_to_strip = '"\' '
    for param in params:
        param = param.strip()
        if param:
            key, value = param, True
            index_of_equals = param.find('=')
            if index_of_equals != -1:
                key = param[:index_of_equals].strip(items_to_strip)
                value = param[index_of_equals + 1:].strip(items_to_strip)
            params_dict[key.lower()] = value
    return content_type, params_dict


def parse(css):
    """Parse a CSS style into a dict."""
    result = {}
    for declaration in css.split(';'):
        if declaration:
            key, value = declaration.split(':')
            result[key] = value.strip()
    return result


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


def sex2dec(hour, minute, second, microsecond=0.0):
    """ Convert a sexagesimal time to decimal hours.

    Parameters
    ----------
    hour, min, sec : int, float

    Returns
    -------
        Time in decimal hours

    """
    return float(hour) + minute / 60.0 + (second + microsecond / 1000000.0
        ) / 3600.0


def is_dict_type(value):
    """Treat any dict, MergeDict, MultiDict instance as dict type"""
    return isinstance(value, dict) or value.__class__.__name__ in ('MergeDict',
        'MultiDict')


def _convert_squeeze(builder, node, graph, err):
    """
    convert to CoreML Squeeze Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L4903
    """
    axes = node.attrs.get('axes', None)
    builder.add_squeeze(name=node.name, input_name=node.inputs[0],
        output_name=node.outputs[0], axes=axes)


@classmethod
def status(cls, name, value):
    """
        starts a timer with the given name.

        :param name: the name of the timer
        :type name: string
        :param status: the name of a status
        :type status: bool

        """
    if cls.debug:
        print('Timer', name, 'status', value)
    cls.timer_status[name] = value


def selectability_toggle():
    """Toggle the selectability

    """
    pass


def next_key(basekey, keys):
    """Returns the next unused key for basekey in the supplied array.

    The first try is `basekey`, followed by `basekey-2`, `basekey-3`, etc
    until a free one is found.
    """
    if basekey not in keys:
        return basekey
    i = 2
    while '{}-{}'.format(basekey, i) in keys:
        i = i + 1
    return '{}-{}'.format(basekey, i)


def parse_atfile_cat(input):
    """
    Return the list of catalog filenames specified as part of the input @-file

    """
    with open(input[1:]) as f:
        catlist = []
        catdict = {}
        for line in f.readlines():
            if line[0] == '#' or not line.strip():
                continue
            lspl = line.split()
            if len(lspl) > 1:
                catdict[lspl[0]] = lspl[1:]
                catlist.append(lspl[1:])
            else:
                catdict[lspl[0]] = None
                catlist.append(None)
    return catlist, catdict


@classmethod
def find(cls, db, token):
    """Find a token object by value.

        Returns None if not found.

        `kind='user'` only returns API tokens for users
        `kind='service'` only returns API tokens for services
        """
    prefix_match = cls.find_prefix(db, token)
    for orm_token in prefix_match:
        if orm_token.match(token):
            return orm_token


def on_close(ws):
    """
    Cleanup before closing connection.

    :param ws: WebSocketApp
    """
    print('Connection closed')


def humanize(us) ->str:
    """Turn microseconds into human readable

    Parameters
    ----------
    us : int
        Microseconds

    Returns
    -------
    string
        us as milliseconds, seconds, minutes or hours
    """
    ms = 1000
    sec = 1000 * ms
    min = 60 * sec
    hour = 60 * min
    if us >= hour:
        return '%sh' % round(us / hour, 1)
    if us >= min:
        return '%sm' % round(us / min, 1)
    if us >= sec:
        return '%ss' % round(us / sec, 1)
    if us >= ms:
        return '%sms' % round(us / ms, 1)
    return '%sus' % us


def unpack(params):
    """Flatten tuple dict key/value pairs
    e.g.
    assert (
        expand_paired_params([
            ('latent_dim', 2),
            (('a', 'b'), (1, 2)),
            ('lets_overfit', True)
        ])
        == {'latent_dim': 1, 'a': 1, 'b': 2, 'lets_overfit': True},)
    """
    params = params.items() if isinstance(params, dict) else params
    for n, v in params:
        if isinstance(n, tuple):
            for ni, vi in zip(n, v):
                yield ni, vi
        else:
            yield n, v


def getRing(startAtom, atomSet, lookup, oatoms):
    """getRing(startAtom, atomSet, lookup, oatoms)->atoms, bonds
    starting at startAtom do a bfs traversal through the atoms
    in atomSet and return the smallest ring found

    returns (), () on failure
    note: atoms and bonds are not returned in traversal order"""
    path = {}
    bpaths = {}
    for atomID in atomSet.keys():
        path[atomID] = None
        bpaths[atomID] = []
    q = []
    handle = startAtom.handle
    for atom in oatoms[handle]:
        q.append((atom, handle))
        path[atom.handle] = {atom.handle: 1, handle: 1}
        bpaths[atom.handle] = [startAtom.findbond(atom)]
    qIndex = 0
    lenQ = len(q)
    while qIndex < lenQ:
        current, sourceHandle = q[qIndex]
        handle = current.handle
        qIndex += 1
        for next in oatoms[handle]:
            m = next.handle
            if m != sourceHandle:
                if not m in atomSet:
                    return (), ()
                if path.get(m, None):
                    intersections = 0
                    for atom in path[handle].keys():
                        if atom in path[m]:
                            intersections = intersections + 1
                            sharedAtom = atom
                    if intersections == 1:
                        del path[handle][sharedAtom]
                        path[handle].update(path[m])
                        result = path[handle].keys()
                        bond = next.findbond(current)
                        bonds = bpaths[handle] + bpaths[m] + [bond]
                        return result, bonds
                else:
                    path[m] = path[handle].copy()
                    path[m][m] = 1
                    bond = next.findbond(current)
                    bpaths[m] = bpaths[handle] + [next.findbond(current)]
                    q.append((next, handle))
                    lenQ = lenQ + 1
    return (), ()


def _gdbPut(this, cmd, *args, **kwargs):
    """
        place a message on the to-be-processed queue
        """
    this.reqQ.put((cmd, args, kwargs))


def with_context(exc, context):
    """
    Attaches a ``context`` value to an Exception.

    Before:

    .. code-block:: python

        exc = Exception('Frog blast the vent core!')
        exc.context = { ... }
        raise exc

    After:

    .. code-block:: python

        raise with_context(
            exc=Exception('Frog blast the vent core!'),
            context={ ... },
        )
    """
    if not hasattr(exc, 'context'):
        exc.context = {}
    exc.context.update(context)
    return exc


@classmethod
def start_recording_skipped(cls):
    """
        Start collecting OptionErrors for all skipped options recorded
        with the record_skipped_option method
        """
    cls._errors_recorded = []


def _m_mangled_attr_name(name, cls_name):
    """Returns `name` as mangled by Python for occurences of `__%s` % name
       inside the definition of a class with name `cls_name`.

       >>> print (_m_mangled_attr_name ("foo", "Bar"))
       _Bar__foo
       >>> print (_m_mangled_attr_name ("foo", "_Bar"))
       _Bar__foo
       >>> print (_m_mangled_attr_name ("foo", "_Bar_"))
       _Bar___foo
    """
    if cls_name.startswith('_'):
        format = '%s__%s'
    else:
        format = '_%s__%s'
    return format % (cls_name, name)


def get_xsd_types(namespace_prefix=''):
    """Returns the list of all supported XSD types

    Args:
        namespace_prefix:

    Returns:

    """
    if namespace_prefix != '':
        namespace_prefix += ':'
    return ['{0}anyType'.format(namespace_prefix), '{0}string'.format(
        namespace_prefix), '{0}normalizedString'.format(namespace_prefix),
        '{0}token'.format(namespace_prefix), '{0}duration'.format(
        namespace_prefix), '{0}dateTime'.format(namespace_prefix),
        '{0}time'.format(namespace_prefix), '{0}date'.format(
        namespace_prefix), '{0}gYearMonth'.format(namespace_prefix),
        '{0}gYear'.format(namespace_prefix), '{0}gMonthDay'.format(
        namespace_prefix), '{0}gDay'.format(namespace_prefix), '{0}gMonth'.
        format(namespace_prefix), '{0}boolean'.format(namespace_prefix),
        '{0}base64Binary'.format(namespace_prefix), '{0}hexBinary'.format(
        namespace_prefix), '{0}float'.format(namespace_prefix), '{0}double'
        .format(namespace_prefix), '{0}anyURI'.format(namespace_prefix),
        '{0}QName'.format(namespace_prefix), '{0}decimal'.format(
        namespace_prefix), '{0}integer'.format(namespace_prefix),
        '{0}nonPositiveInteger'.format(namespace_prefix),
        '{0}negativeInteger'.format(namespace_prefix), '{0}long'.format(
        namespace_prefix), '{0}nonNegativeInteger'.format(namespace_prefix),
        '{0}unsignedLong'.format(namespace_prefix), '{0}positiveInteger'.
        format(namespace_prefix), '{0}unsignedInt'.format(namespace_prefix),
        '{0}unsignedShort'.format(namespace_prefix), '{0}unsignedByte'.
        format(namespace_prefix), '{0}long'.format(namespace_prefix),
        '{0}int'.format(namespace_prefix), '{0}short'.format(
        namespace_prefix), '{0}byte'.format(namespace_prefix)]


def xld_footer_matches():
    """Matches for the XLD footer block."""
    return {'good': ['No errors occurred', 'End of status report'],
        'badish': ['Some inconsistencies found']}


def single(args, kwds):
    """Return a true value only when a unique argument is given.

    When needed, the most suitable result will be wrapped using the
    `~xotl.tools.fp.option.Maybe`:class:.

    .. versionadded:: 1.8.0

    """
    from xotl.tools.fp.option import Just, Wrong, take
    if len(args) == 1 and not kwds:
        res = take(args[0])
        if not res:
            res = Just(res)
        res = Just(res)
    elif not args and len(kwds) == 1:
        res = kwds
    else:
        res = Wrong((args, kwds))
    return res


@classmethod
def _parse_trace_logging(cls, trace_def):
    """Parse tracing by Python's logging facilities.

        :param trace_def: definition of tracing as supplied in the YAML file
        """
    if trace_def is True:
        cls._trace_logging.append(trace_def)


def RK4Step(x0, dt, fv, direction=1.0):
    """
	This Function returns the step taken along the field provided by the
	function 'fv' using the Runge-Kutta 4th order method.

	Inputs:
		x0: initial location vector.
		dt: Step size.
		fv: Callable function which provides a field vector given a
			positional vector.
		direction: direction in which to trace, +1.0 will trace along
		the field direction, -1.0 will trace in the opposite direction.

	Returns:
		new positional vector of the same form as x0.

	"""
    v0 = direction * fv(x0)
    v1 = direction * fv(x0 + 0.5 * dt * v0[:, (0)])
    v2 = direction * fv(x0 + 0.5 * dt * v1[:, (0)])
    v3 = direction * fv(x0 + dt * v1[:, (0)])
    x1 = x0 + dt * (v0[:, (0)] + 2.0 * v1[:, (0)] + 2.0 * v2[:, (0)] + v3[:,
        (0)]) / 6.0
    return x1


def dump_stats(myStats):
    """
    Show stats when pings are done
    """
    print('\n----%s PYTHON PING Statistics----' % myStats.thisIP)
    if myStats.pktsSent > 0:
        myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd
            ) / myStats.pktsSent
    print(
        '%d packets transmitted, %d packets received, %0.1f%% packet loss' %
        (myStats.pktsSent, myStats.pktsRcvd, 100.0 * myStats.fracLoss))
    if myStats.pktsRcvd > 0:
        print('round-trip (ms)  min/avg/max = %d/%0.1f/%d' % (myStats.
            minTime, myStats.totTime / myStats.pktsRcvd, myStats.maxTime))
    print('')
    return


def mrbayes_model_output(Q, eq):
    """
    Output the MrBayes instruction to get user defined rates.

    WARNING: This output is not verified against MrBayes.
    """
    output_string = 'prset aarevmatpr = fixed('
    rate_list = []
    for row in range(1, 20):
        for col in range(0, row):
            r = Q[row, col] / eq[col]
            rate_list.append(f'{r:8.5}')
    output_string += ','.join(rate_list) + ')'
    return output_string


def friction_fnc(normal_force, friction_coefficient):
    """Usage: Find force of friction using normal force and friction coefficent"""
    return normal_force * friction_coefficient


@classmethod
def de_json(cls, json_type):
    """
        Возвращает инстанс этого класса из созданного json dict'а или строки
        Эта функция должна быть перезаписана для каждого субкласса

        Returns
        -------
        Инстанс этого класса из созданного json dict'а или строки
        """
    raise NotImplementedError


def bool_input(input_str: str) ->str:
    """
    Prints a message asking for a yes/no response, otherwise it will continue asking.

    :param input_str: Message to print.
    :return: User response.
    """
    input_str = input_str + ' [Y|n] '
    result = None
    while result is None:
        response = input(input_str)
        if response in ('', 'y', 'Y'):
            result = True
        elif response in ('n', 'N'):
            result = False
        else:
            print('Wrong option')
    return result


def not_0(upper, lower):
    """Fills both values to whichever is not equal to 0, or leaves in place."""
    if upper == 0:
        return lower, lower
    elif lower == 0:
        return upper, upper
    else:
        return upper, lower


def t_php_VARIABLE(t):
    """\\$[A-Za-z_][\\w_]*"""
    return t


def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox', '.env', 'env', 'venv',
        'node_modules', 'bower_components']
    prefs['save_objectdb'] = True
    prefs['compress_objectdb'] = False
    prefs['automatic_soa'] = True
    prefs['soa_followed_calls'] = 0
    prefs['perform_doa'] = True
    prefs['validate_objectdb'] = True
    prefs['max_history_items'] = 32
    prefs['save_history'] = True
    prefs['compress_history'] = False
    prefs['indent_size'] = 4
    prefs['extension_modules'] = []
    prefs['import_dynload_stdmods'] = True
    prefs['ignore_syntax_errors'] = False
    prefs['ignore_bad_imports'] = False
    prefs['prefer_module_from_imports'] = False
    prefs['split_imports'] = False
    prefs['pull_imports_to_top'] = True
    prefs['sort_imports_alphabetically'] = False
    prefs['type_hinting_factory'
        ] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'


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


@staticmethod
def p_a2ml_taggedstruct_member_list_optional(p):
    """a2ml_taggedstruct_member_list_optional : empty
                                                  | a2ml_taggedstruct_member_list"""
    p[0] = p[1]


def to_bytes(s, encoding='utf-8'):
    """Ensure that s is converted to bytes from the encoding."""
    if hasattr(s, 'encode') and not isinstance(s, bytes):
        s = s.encode(encoding)
    return s


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


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 getAccelerator(count):
    """Provides an accelerator text for a menu item"""
    if count < 10:
        return '&' + str(count) + '.  '
    return '&' + chr(count - 10 + ord('a')) + '.  '


def exact_log2(num):
    """Find and return an integer i >= 0 such that num == 2**i.

    If no such integer exists, this function raises ValueError.
    """
    if not isinstance(num, int):
        raise TypeError('unsupported operand type: %r' % (type(num).__name__,))
    n = int(num)
    if n <= 0:
        raise ValueError('cannot compute logarithm of non-positive number')
    i = 0
    while n != 0:
        if n & 1 and n != 1:
            raise ValueError('No solution could be found')
        i += 1
        n >>= 1
    i -= 1
    assert num == 1 << i
    return i


def __hash_combine(h1, h2):
    """
    Combine two hash values to create a new hash value
    :param h1: int
    :param h2: int
    :return: int
    """
    h1 = h1 ^ h2 + 2654435769 + (h1 << 6) + (h2 >> 2)
    return h1


@classmethod
def declare_entry(cls, entry, pre_assemble_callback=None, assemble_callback
    =None, initialize_callback=None):
    """ Add new entry in the declared entries

        ::

            def assemble_callback(registry):
                ...

            def initialize_callback(registry):
                ...

            RegistryManager.declare_entry(
                'Entry name', assemble_callback=assemble_callback,
                initialize_callback=initialize_callback)

            @Declarations.register(Declarations.``Entry name``)
            class MyClass:
                ...

        .. warning::

            The entry must be declared in the application, not in the bloks
            The declaration must be done before the loading of the bloks

        :param entry: entry name
        :param assemble_callback: function callback to call to assemble
        :param initialize_callback: function callback to call to init after
            assembling
        """
    if entry not in cls.declared_entries:
        cls.declared_entries.append(entry)
        if pre_assemble_callback:
            cls.callback_pre_assemble_entries[entry] = pre_assemble_callback
        if assemble_callback:
            cls.callback_assemble_entries[entry] = assemble_callback
        if initialize_callback:
            cls.callback_initialize_entries[entry] = initialize_callback


def _mkx(i, steps, n):
    """
    Generate list according to pattern of g0 and b0.
    """
    x = []
    for step in steps:
        x.extend(list(range(i, step + n, n)))
        i = step + (n - 1)
    return x


def separate_namespace(qname):
    """Separates the namespace from the element"""
    import re
    try:
        namespace, element_name = re.search('^{(.+)}(.+)$', qname).groups()
    except:
        namespace = None
        element_name = qname
    return namespace, element_name


@classmethod
def requires_conversion(cls, fileset, file_format):
    """Checks whether the fileset matches the requested file format"""
    if file_format is None:
        return False
    try:
        filset_format = fileset.format
    except AttributeError:
        return False
    else:
        return file_format != filset_format


def dump_stats(myStats):
    """
    Show stats when pings are done
    """
    print('\n----%s PYTHON PING Statistics----' % myStats.thisIP)
    if myStats.pktsSent > 0:
        myStats.fracLoss = (myStats.pktsSent - myStats.pktsRcvd
            ) / myStats.pktsSent
    print(
        '%d packets transmitted, %d packets received, %0.1f%% packet loss' %
        (myStats.pktsSent, myStats.pktsRcvd, 100.0 * myStats.fracLoss))
    if myStats.pktsRcvd > 0:
        print('round-trip (ms)  min/avg/max = %d/%0.1f/%d' % (myStats.
            minTime, myStats.totTime / myStats.pktsRcvd, myStats.maxTime))
    print('')
    return


def isMegamanicEditable():
    """Exists and returns true if the object is MegamanicEditable"""


def swapaxes(input, axis1, axis2):
    """Interchange the two given axes of a tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    axis1, axis2 : int
        The two axes.

    Returns
    -------
    Tensor
        The transposed tensor.
    """
    pass


def column_exists(df, col):
    """Check the column name exists in the DataFrame.

    Args:
        df (:obj:`DataFrame`): Pandas DataFrame.
        col (str): Column name.

    Returns:
        bool: True if exists, False if not exists.

    """
    if col and col not in df.columns:
        print('The specify column `{0!s}` not found in the input file'.
            format(col))
        return False
    else:
        return True


@classmethod
def get_option_names(cls):
    """Get names of all options."""
    return list(map(lambda x: x.name, cls.get_options()))


def output_available(condition, comparison, value):
    """
    Check if output source is available
    Currently only handle simple SIG condition
    XHX, CLTV, CSV should be handled when present in the blockchain
    """
    if hasattr(condition.left, 'pubkey'):
        return comparison(condition.left.pubkey, value)
    else:
        return False


def update_kwargs(kwargs, **keyvalues):
    """Update dict with keys and values if keys do not already exist.

    >>> kwargs = {'one': 1, }
    >>> update_kwargs(kwargs, one=None, two=2)
    >>> kwargs == {'one': 1, 'two': 2}
    True

    """
    for key, value in keyvalues.items():
        if key not in kwargs:
            kwargs[key] = value


def _pass(value):
    """Just return the given value."""
    return value


def _cast_make_object(canidate_class, cpp_object, is_class):
    """Make an object for cast"""
    if is_class:
        return canidate_class
    elif hasattr(canidate_class, '_convert_cpp'):
        return canidate_class._convert_cpp(cpp_object)
    else:
        return canidate_class(cpp_object)


def count_stars(chars):
    """
    Count the number of trailing '#' (~== '#+$')

    >>> count_stars("http://example.org/p?q#fragment####")
    <<< 4
    """
    count = 0
    for c in chars[::-1]:
        if c != '#':
            break
        count += 1
    return count


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


def _iter_choices(choices):
    """
    Yields ``(value, label)`` tuples for the given `choices`.
    """
    for choice in choices:
        if not isinstance(choice, tuple):
            choice = choice, choice
        yield choice


def _fix_broken_dataset_file_project(client):
    """Ensure project is correctly set on ``DatasetFile``."""
    for dataset in client.datasets.values():
        for file_ in dataset.files:
            if not file_._project or 'NULL/NULL' in file_._project._id:
                file_._project = client.project
        dataset.to_yaml()


def saveImg(path, img):
    """Save image object to path"""
    print('Save to {}\n'.format(path))
    img.write(path)


def ax_append_title(ax, title, loc='center', fontsize=None):
    """Add title to previous ax.title. Return new title."""
    prev_title = ax.get_title(loc=loc)
    new_title = prev_title + title
    ax.set_title(new_title, loc=loc, fontsize=fontsize)
    return new_title


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 wnba_points_made(row):
    """
    function to calculate the points earned by a team with each shot made

    Inputs:
    row - row of pbp dataframe

    Outputs - value of shot made
    """
    if row['is_three'] == 1 and row['shot_made'] == 1:
        return 3
    elif row['is_three'] == 0 and row['shot_made'] == 1 and row['etype'] != 3:
        return 2
    elif row['etype'] == 3 and row['shot_made'] == 1:
        return 1
    else:
        return 0


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

    Usage:

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


def parse_photo_link(photo_url):
    """
    Extracts the base URL (URL without query parameters) and the photo name from a Onedrive photo URL
    :param photo_url: photo URL
    :return: base URL and photo name
    """
    base_url = photo_url.split('=')[0]
    name = base_url.split('/')[-1]
    return base_url, name


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 beginningPage(R):
    """As pages may not be given as numbers this is the most accurate this function can be"""
    p = R['PG']
    if p.startswith('suppl '):
        p = p[6:]
    return p.split(' ')[0].split('-')[0].replace(';', '')


def readline(file, skip_blank=False):
    """Read a line from provided file, skipping any blank or comment lines"""
    while True:
        line = file.readline()
        if not line:
            return None
        if line[0] != '#' and not (skip_blank and line.isspace()):
            return line


@classmethod
def _constructor(cls, mapping, configuration):
    """
        A standardized constructor used internally by Attr.

        mapping: A mapping of key-value pairs. It is HIGHLY recommended
            that you use this as the internal key-value pair mapping, as
            that will allow nested assignment (e.g., attr.foo.bar = baz)
        configuration: The return value of Attr._configuration
        """
    raise NotImplementedError('You need to implement this')


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


def is_url(string):
    """
    Checks if the given string starts with 'http(s)'.
    """
    try:
        return string.startswith('http://') or string.startswith('https://')
    except AttributeError:
        return False


@classmethod
def begin(cls):
    """
        Initialize a thread-local transaction. An exception is raised if
        there's already a pending transaction.
        """
    if cls.app.local.sqla_tx is not None:
        raise Exception('there is already an open transaction')
    cls.app.local.sqla_tx = cls.app.local.sqla_conn.begin()


def setNanny(*args):
    """Access and changes protected Nanny mode class data. The returned value representation is an integer ranging from 0 to 1. This approach is a secure method to access and change saved system Nanny mode values.

    Parameters
    ----------
    abort_state : int
        Values for abort state range from 0 for 'System Performance Nominal' to 1 for 'Abort'.
    value : int
        Set values from 0 for 'System Performance Nominal' to 1 for 'Abort'.

    Returns
    -------
    nanny : int
         0 = automated system monitoring mode disabled, 1 = automated system monitoring mode enabled.
    """
    args[0].nanny = args[1]
    return args[0]


def c_schar(i):
    """
    Convert arbitrary integer to c signed char type range as if casted in c.

    >>> c_schar(0x12345678)
    120
    >>> (c_schar(-128), c_schar(-129), c_schar(127), c_schar(128))
    (-128, 127, 127, -128)
    """
    return (i + 128) % 256 - 128


def reverse_path(start, end, prev):
    """ Returns the path from start to end, given a previous table. """
    path = []
    while end != start:
        path.append(end)
        end = prev[end]
    path.append(start)
    path.reverse()
    return path


def get_ax_size_in_pixels(fig, ax):
    """ Get the size of axis frame in pixels """
    bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
    return bbox.width * fig.dpi - 7, bbox.height * fig.dpi - 7


def iter_latest_block(w3, to_block=None):
    """Returns a generator that dispenses the latest block, if
    any new blocks have been mined since last iteration.

    If there are no new blocks None is returned.

    If ``to_block`` is defined, ``StopIteration`` is raised
    after to_block is reached.

    >>> mined_blocks = dispense_mined_blocks(w3, 0, 10)
    >>> next(new_blocks)  # Latest block = 0
    0
    >>> next(new_blocks)  # No new blocks
    >>> next(new_blocks)  # Latest block = 1
    1
    >>> next(new_blocks)  # Latest block = 10
    10
    >>> next(new_blocks)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      StopIteration
    >>>
    """
    _last = None
    is_bounded_range = to_block is not None and to_block is not 'latest'
    while True:
        latest_block = w3.eth.blockNumber
        if is_bounded_range and latest_block > to_block:
            return
        if _last is not None and _last == latest_block:
            yield None
        else:
            yield latest_block
        _last = latest_block


def sbolRule10101(sbol_obj, arg):
    """An SBOL document MUST declare the use of the following XML namespace:
    http://sbols.org/v2#."""
    raise NotImplementedError('Not yet implemented')


def _flatten_results(result, default_value=None):
    """ Formats results to map to a single value or default value if empty. """
    for k in list(result):
        v = result[k]
        if len(v) > 1:
            raise ValueError(
                'Expected one result, but more returned for "{}": {}'.
                format(k, v))
        if len(v) == 1:
            result[k] = v[0]
        elif default_value is not None:
            result[k] = default_value
        else:
            del result[k]
    return result


def shim_vdrp_measurement(vdrp_measurement_doc):
    """Shim a measurement document from validate_drp to a measurement document
    expected by SQuaSH.
    """
    metric = vdrp_measurement_doc.pop('metric')
    value = vdrp_measurement_doc.pop('value')
    output_doc = {'metric': metric['name'], 'value': value, 'metadata':
        vdrp_measurement_doc}
    return output_doc


@classmethod
def create_from(cls, src, force_copy=False, **extra):
    """Create a LogicProgram of the current class from another LogicProgram.

        :param src: logic program to convert
        :type src: :class:`.LogicProgram`
        :param force_copy: default False, If true, always create a copy of the original logic         program.
        :type force_copy: bool
        :param extra: additional arguments passed to all constructors and action functions
        :returns: LogicProgram that is (externally) identical to given one
        :rtype: object of the class on which this method is invoked

        If the original LogicProgram already has the right class and force_copy is False, then         the original program is returned.
        """
    return cls.createFrom(src, force_copy=force_copy, **extra)


def create_bzip2(archive, compression, cmd, verbosity, interactive, filenames):
    """Create a BZIP2 archive."""
    cmdlist = [cmd, 'a']
    if not interactive:
        cmdlist.append('-y')
    cmdlist.extend(['-tbzip2', '-mx=9', '--', archive])
    cmdlist.extend(filenames)
    return cmdlist


def _get_raw_info(raw_fname):
    """Get info from raw."""
    from mne.io import read_raw_fif
    raw = read_raw_fif(raw_fname, preload=True)
    return raw.info


def refix(val, p_in='', p_out=''):
    """

    Convert between different SI unit prefixes. Available options are:

    :code:`'T'`   Terra

    :code:`'G'` Giga

    :code:`'M'` Mega

    :code:`'k'` Kilo

    :code:`'m'` Milli

    :code:`'mu'` Micro

    :code:`'n'` Nano

    :code:`'p'` Pico

    Parameters
    ----------
    val: scalar
        The value for which to convert the unit prefix.
    p_in: string, any of the above, optional
        The current prefix of :code:`val`. If :code:`p_in` is undefined,
        :code:`val` has no SI unit prefix.
    p_out: string, any of the above, optional
        The prefix of :code:`val_refix` after the conversion.  If :code:`p_in`
        is undefined, :code:`val_refix` has no SI unit prefix.

    Returns
    -------
    val_refix: scalar
        The value in units of prefix :code:`p_out`.

    """
    prefix = {'p': 10 ** -12, 'n': 10 ** -9, 'mu': 10 ** -6, 'm': 10 ** -3,
        '': 10 ** -0, 'k': 10 ** 3, 'M': 10 ** 6, 'G': 10 ** 9, 'T': 10 ** 12}
    val_refix = val * prefix[p_in] / prefix[p_out]
    return val_refix


def extractVersion(tag):
    """
    Extract the version number from as SVN tag.

    >>> extractVersion('GAUDI_v23r8')
    'v23r8'
    >>> extractVersion('LCGCMT_preview')
    'preview'
    >>> extractVersion('HEAD')
    'HEAD'
    """
    if '_' in tag:
        return tag.split('_', 1)[1]
    return tag


def parseTarget(target, forceSSH=False, useOption=False):
    """parseTarget(target[,forceSSH,useOption]) --> (login, host, path)
    if useOption, then login will prepend '-l' if login is included"""
    dpath = target.split(':')[-1]
    rhost = target.split(':')[0]
    if rhost == dpath:
        if forceSSH:
            return '', 'localhost', dpath
        return '', '', dpath
    dhost = rhost.split('@')[-1]
    duser = rhost.split('@')[0]
    if duser == dhost:
        return '', dhost, dpath
    if useOption:
        duser = '-l ' + duser
    return duser, dhost, dpath


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

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

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


def call_if_callable(v):
    """ Preprocess a value: return it ; but call it, if it's a lambda (for late binding) """
    return v() if callable(v) else v


def mix(color1, color2, pos=0.5):
    """
    Return the mix of two colors at a state of :pos:

    Retruns color1 * pos + color2 * (1 - pos)
    """
    opp_pos = 1 - pos
    red = color1[0] * pos + color2[0] * opp_pos
    green = color1[1] * pos + color2[1] * opp_pos
    blue = color1[2] * pos + color2[2] * opp_pos
    return int(red), int(green), int(blue)


def _enable_legacy_windows_support() ->None:
    """Initialize Windows legacy support."""
    from colorama import init
    init()


def pack(*args):
    """Pack arguments of different types into a list.

    The ``pack`` / ``unpack`` pair is used to ensure that even with mixed
    arguments internal the logic always sees a list of arrays.

    :returns:
        a tuple of ``keys, values``. The ``keys`` are an opaque hashable
        object that can be used to unpack the values. ``values`` will be
        a tuple of flattend arguments.
    """
    keys = []
    values = []
    for arg in args:
        if isinstance(arg, tuple):
            keys.append(len(arg))
            values.extend(arg)
        elif isinstance(arg, dict):
            k, v = zip(*arg.items())
            keys.append(tuple(k))
            values.extend(v)
        else:
            keys.append(None)
            values.append(arg)
    return tuple(keys), tuple(values)


def str2bool(v):
    """
    convert string to bool
    :param v:
    :return:
    """
    if isinstance(v, bool):
        return v
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    return True


def makeBytes(text):
    """ Make sure the argument is bytes, converting with UTF-8 encoding
    if it is a string. """
    if isinstance(text, bytes):
        return text
    elif isinstance(text, str):
        return text.encode('utf-8')
    else:
        raise ValueError('Expected str or bytes!')


def group_pairs(items):
    """Groups an even-sized list into contiguous pairs."""
    if len(items) % 2 != 0:
        raise ValueError(f'Expected even number of items, got {items!r}')
    return list(zip(items[::2], items[1::2]))


def set_shared_steemd_instance(steemd_instance):
    """ This method allows us to override default steem instance for all users of
    _shared_steemd_instance.
    """
    global _shared_steemd_instance
    _shared_steemd_instance = steemd_instance


def get_request_validator(restApiId=None, requestValidatorId=None):
    """
    Gets a  RequestValidator of a given  RestApi .
    See also: AWS API Documentation

    :example: response = client.get_request_validator(
        restApiId='string',
        requestValidatorId='string'
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            [Required] The identifier of the RestApi to which the specified RequestValidator belongs.

    :type requestValidatorId: string
    :param requestValidatorId: [REQUIRED]
            [Required] The identifier of the RequestValidator to be retrieved.

    :rtype: dict
    :return: {
        'id': 'string',
        'name': 'string',
        'validateRequestBody': True|False,
        'validateRequestParameters': True|False
    }

    """
    pass


def _resolve_name(name, package, level):
    """Return the absolute name of the module to be imported."""
    if not hasattr(package, 'rindex'):
        raise ValueError("'package' not set to a string")
    dot = len(package)
    for x in range(level, 1, -1):
        try:
            dot = package.rindex('.', 0, dot)
        except ValueError:
            raise ValueError(
                'attempted relative import beyond top-level package')
    return '%s.%s' % (package[:dot], name)


@classmethod
def reset(cls):
    """
        Reset the instance count.
        """
    cls._instance_count = 1


def remove_from_groupings(obj):
    """ Remove obj's grouping relevant information to its workspace.
        """


@classmethod
def add_params(cls, cmdline_parser):
    """ Shared params in all backends """
    parser = cmdline_parser
    parser.add_argument('-e', '--elastic_url', default=
        'http://127.0.0.1:9200', help=
        'Host with elastic search (default: http://127.0.0.1:9200)')
    parser.add_argument('--elastic_url-enrich', help=
        'Host with elastic search and enriched indexes')


def srfqe(qe, wavelength):
    """'Return the spectral response (A/W) given the quantum efficiency (0 yo 1 units) and wavelength (nm)"""
    spectral_response = qe * wavelength / 1239.8
    return spectral_response


def max_sequential_nt(mer1, mer2):
    """Returns the maximum number of nt that would bind between two kmers.

    :param kmer1: the first kmer
    :param kmer2: the second kmer (order unimportant)
    """
    binding = {'A': 'T', 'T': 'A', 'C': 'G', 'G': 'C', '_': False}
    if len(mer2) > len(mer1):
        mer1, mer2 = mer2, mer1
    mer1_len = len(mer1)
    mer2 = mer2[::-1]
    mer1 = mer1.ljust(mer1_len + len(mer2), '_')
    max_bind = 0
    for offset in range(mer1_len):
        consecutive = 0
        for x in range(len(mer2)):
            if binding[mer1[offset + x]] == mer2[x]:
                consecutive += 1
                if consecutive > max_bind:
                    max_bind = consecutive
            else:
                consecutive = 0
    return max_bind


@staticmethod
def split(txt, seps):
    """
        Splits a text in a meaningful list of words based on a list of word
        separators (define in pyqode.core.settings)

        :param txt: Text to split
        :param seps: List of words separators
        :return: A **set** of words found in the document (excluding
            punctuations, numbers, ...)
        """
    default_sep = seps[0]
    for sep in seps[1:]:
        if sep:
            txt = txt.replace(sep, default_sep)
    raw_words = txt.split(default_sep)
    words = set()
    for word in raw_words:
        if word.replace('_', '').isalpha():
            words.add(word)
    return sorted(words)


@classmethod
def from_json(cls, obj):
    """Construct a MarathonConstraint from a parsed response.

        :param dict attributes: object attributes from parsed response

        :rtype: :class:`MarathonConstraint`
        """
    if len(obj) == 2:
        field, operator = obj
        return cls(field, operator)
    if len(obj) > 2:
        field, operator, value = obj
        return cls(field, operator, value)


@classmethod
def changed(cls, entity, blob, old_value, new_value):
    """Perform any actions necessary after this attribute's value changes.

        This will be called by the blob after the value of this attribute
        has changed, override it to do any necessary post-setter actions.

        :param entity: The entity this attribute is on
        :param DataBlob blob: The blob that changed
        :param old_value: The previous value
        :param new_value: The new value
        :returns None:

        """


def row_to_index(row):
    """
    Returns the 0-based index of given row name.

    Parameters
    ----------
    row : int or unicode
        Row name.

    Returns
    -------
    int
        0-based row index.

    Examples
    --------
    >>> row_to_index('1')
    0
    """
    row = int(row)
    assert row > 0, 'Row must be greater than 0!'
    return row - 1


@staticmethod
def _get_custom_fields_details(fields):
    """Return a List of all Custom Incident Fields which are Dictionaries with
        the attributes: api_name, label, type, prefix, placeholder and tooltip"""
    return_list = []
    for field in fields:
        the_field = {}
        the_field['api_name'] = field.get('name')
        the_field['label'] = field.get('text')
        the_field['type'] = field.get('input_type')
        the_field['prefix'] = field.get('prefix')
        the_field['placeholder'] = field.get('placeholder') if field.get(
            'placeholder') else '-'
        the_field['tooltip'] = field.get('tooltip') if field.get('tooltip'
            ) else '-'
        return_list.append(the_field)
    return return_list


def filter(df, column_name, field_value):
    """Filter a data frame to only include matches with field value in column_name"""
    tmp_df = df[df[column_name].isnull() == False]
    return tmp_df[tmp_df[column_name] == field_value]


def escape_windows_cmd_string(s):
    """Returns a string that is usable by the Windows cmd.exe.
    The escaping is based on details here and emperical testing:
    http://www.robvanderwoude.com/escapechars.php
    """
    for c in '()%!^<>&|"':
        s = s.replace(c, '^' + c)
    s = s.replace('/?', '/.')
    return s


@classmethod
def from_frame(cls, frame):
    """Creates a ``Reflection`` that mirrors at the ``Frame``.

        Parameters
        ----------
        frame : :class:`Frame`

        """
    return cls(frame.point, frame.normal)


def pathlookup(obj_or_path_tuple, depth=None, include_origin=True):
    """ Returns an iterator of document ids within
        obj_or_path_tuple (a traversable object or a path tuple).  If depth
        is specified, returns only objects at that depth.  If
        ``include_origin`` is ``True``, returns the docid of the object
        passed as ``obj_or_path_tuple`` in the returned set, otherwise it
        omits it."""


def mps2kph(value):
    """float: velocity: metres per second to kilometers per hour."""
    return value * 3.6


@staticmethod
def p_opbject_type(p):
    """object_type : empty
                       | BU_
                       | BO_
                       | SG_
                       | EV_"""
    p[0] = p[1]


def clipping(fontid: int, xmin: float, ymin: float, xmax: float, ymax: float):
    """Set the clipping, enable/disable using CLIPPING.

    :param fontid: The id of the typeface as returned by blf.load(), for default font use 0.
    :type fontid: int
    :param xmin: Clip the drawing area by these bounds.
    :type xmin: float
    :param ymin: Clip the drawing area by these bounds.
    :type ymin: float
    :param xmax: Clip the drawing area by these bounds.
    :type xmax: float
    :param ymax: Clip the drawing area by these bounds.
    :type ymax: float
    """
    pass


def dump_fcidump(filename, data):
    """Write one- and two-electron integrals in the Molpro 2012 FCIDUMP format.

    Works only for restricted wavefunctions.

    Keep in mind that the FCIDUMP format changed in Molpro 2012, so files
    written with this function cannot be used with older versions of Molpro

    Parmeters
    ---------
    filename : str
        The filename of the FCIDUMP file. This is usually "FCIDUMP".

    data : IOData
        Must contain ``one_mo``, ``two_mo``. May contain ``core_energy``, ``nelec`` and
        ``ms``.
    """
    with open(filename, 'w') as f:
        one_mo = data.one_mo
        two_mo = data.two_mo
        nactive = one_mo.shape[0]
        core_energy = getattr(data, 'core_energy', 0.0)
        nelec = getattr(data, 'nelec', 0)
        ms2 = getattr(data, 'ms2', 0)
        print(' &FCI NORB=%i,NELEC=%i,MS2=%i,' % (nactive, nelec, ms2), file=f)
        print('  ORBSYM= ' + ','.join(str(1) for v in range(nactive)) + ',',
            file=f)
        print('  ISYM=1', file=f)
        print(' &END', file=f)
        for i in range(nactive):
            for j in range(i + 1):
                for k in range(nactive):
                    for l in range(k + 1):
                        if i * (i + 1) / 2 + j >= k * (k + 1) / 2 + l:
                            value = two_mo[i, k, j, l]
                            if value != 0.0:
                                print('%23.16e %4i %4i %4i %4i' % (value, i +
                                    1, j + 1, k + 1, l + 1), file=f)
        for i in range(nactive):
            for j in range(i + 1):
                value = one_mo[i, j]
                if value != 0.0:
                    print('%23.16e %4i %4i %4i %4i' % (value, i + 1, j + 1,
                        0, 0), file=f)
        if core_energy != 0.0:
            print('%23.16e %4i %4i %4i %4i' % (core_energy, 0, 0, 0, 0), file=f
                )


def choose_words(length):
    """Randomly select LENGTH words, join them with hyphens, return the
        result."""


def get_full_policy_path(arn):
    """
    Resource string will output strings like the following examples.

    Case 1:
      Input: arn:aws:iam::aws:policy/aws-service-role/AmazonGuardDutyServiceRolePolicy
    Output:
      aws-service-role/AmazonGuardDutyServiceRolePolicy
    Case 2:
      Input: arn:aws:iam::123456789012:role/ExampleRole
      Output: ExampleRole
    :param arn:
    :return:
    """
    split_arn = arn.split(':')
    resource_string = ':'.join(split_arn[5:])
    resource_string = resource_string.split('/')[1:]
    resource_string = '/'.join(resource_string)
    return resource_string


def safe_iterator(node, tag=None):
    """Return an iterator that is compatible with Python 2.6"""
    if node is None:
        return []
    if hasattr(node, 'iter'):
        return node.iter(tag)
    else:
        return node.getiterator(tag)


def keyconfig_activate(filepath: str=''):
    """Undocumented contribute <https://developer.blender.org/T51061>

    :param filepath: filepath
    :type filepath: str
    """
    pass


def index(obj, attributes=None):
    """ queue an index operation for the given object and attributes """


def dict_from_cookiejar(cj):
    """Returns a key/value dictionary from a CookieJar.

    :param cj: CookieJar object to extract cookies from.
    """
    cookie_dict = {}
    for cookie in cj:
        cookie_dict[cookie.name] = cookie.value
    return cookie_dict


def getLineProperties(propertynode):
    """Returns a dictionary with line properties based on the specified
    xmlstore.TypedStore node.

    Internal use only.
    """
    line = propertynode['Line']
    linestyle = line.getValue(usedefault=True)
    linewidth = line['Width'].getValue(usedefault=True)
    color = line['Color'].getValue(usedefault=True)
    result = {'linestyle': linestyle, 'linewidth': linewidth, 'color':
        color.getNormalized()}
    if propertynode['CanHaveMarker'].getValue(usedefault=True):
        marker = propertynode['Marker']
        markertype = marker.getValue(usedefault=True)
        markersize = marker['Size'].getValue(usedefault=True)
        markerfacecolor = marker['FaceColor'].getValue(usedefault=True)
        markeredgecolor = marker['EdgeColor'].getValue(usedefault=True)
        markeredgewidth = marker['EdgeWidth'].getValue(usedefault=True)
        result.update({'marker': markertype, 'markersize': markersize,
            'markerfacecolor': markerfacecolor.getNormalized(),
            'markeredgecolor': markeredgecolor.getNormalized(),
            'markeredgewidth': markeredgewidth})
    return result


def make_palette_chunks(palette):
    """
    Create the byte sequences for a ``PLTE`` and
    if necessary a ``tRNS`` chunk.
    Returned as a pair (*p*, *t*).
    *t* will be ``None`` if no ``tRNS`` chunk is necessary.
    """
    p = bytearray()
    t = bytearray()
    for x in palette:
        p.extend(x[0:3])
        if len(x) > 3:
            t.append(x[3])
    if t:
        return p, t
    return p, None


def _cb_dist(ctx, param, value):
    """
    Click callback to ensure `--distance` can be either a float or a field name.
    """
    try:
        return float(value)
    except ValueError:
        return value


def _quotify(mystr):
    """
    quotifies an html tag attribute value.
    Assumes then, that any ocurrence of ' or " in the
    string is escaped if original string was quoted
    with it.
    So this function does not altere the original string
    except for quotation at both ends, and is limited just
    to guess if string must be quoted with '"' or "'"
    """
    quote = '"'
    length = len(mystr)
    for i in range(length):
        if mystr[i] == '\\' and i + 1 < length and mystr[i + 1] == "'":
            quote = "'"
            break
        elif mystr[i] == '\\' and i + 1 < length and mystr[i + 1] == '"':
            quote = '"'
            break
        elif mystr[i] == "'":
            quote = '"'
            break
        elif mystr[i] == '"':
            quote = "'"
            break
    return quote + mystr + quote


def is_expired_cert(domain):
    """
    Returns if its canonical https endpoint has an expired cert
    """
    canonical, https, httpswww = (domain.canonical, domain.https, domain.
        httpswww)
    if canonical.host == 'www':
        canonical_https = httpswww
    else:
        canonical_https = https
    return canonical_https.https_expired_cert


def get_next_version():
    """Get the id of the next version. This is the approved version
        if available, or the unapproved version otherwise, or None if
        there is no next version at all.
        """


def format_list(record_list):
    """Format a list into a string to increase readability in CSV"""
    if not record_list:
        return None
    return ', '.join(record_list)


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

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

      *out* = *det(A)*

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

    .. note:: The operator supports float32 and float64 data types only.
    .. note:: There is no gradient backwarded when A is non-invertible (which is
              equivalent to det(A) = 0) because zero is rarely hit upon in float
              point computation and the Jacobi's formula on determinant gradient
              is not computationally efficient when A is non-invertible.

    Examples::

       Single matrix determinant
       A = [[1., 4.], [2., 3.]]
       det(A) = [-5.]

       Batch matrix determinant
       A = [[[1., 4.], [2., 3.]],
            [[2., 3.], [1., 4.]]]
       det(A) = [-5., 5.]

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

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

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

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


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


def findParam(event, groupName, paramName):
    """
    Finds a Param in a given VOEvent that has the specified groupName
    and paramName. If it is a bare param, the group name is the empty string.
    """
    w = event.get_What()
    if not w:
        print('No <What> section in the event!')
        return None
    if groupName == '':
        for p in event.get_What().get_Param():
            if p.get_name() == paramName:
                return p
    else:
        for g in event.get_What().get_Group():
            if g.get_name == groupName:
                for p in event.get_What().get_Param():
                    if p.get_name() == paramName:
                        return p
    print('Cannot find param named %s/%s' % (groupName, paramName))
    return None


def copy_image_info(reference, target):
    """
    Copy origin, direction, and spacing from one antsImage to another

    ANTsR function: `antsCopyImageInfo`

    Arguments
    ---------
    reference : ANTsImage
        Image to get values from.
    target  : ANTsImAGE
        Image to copy values to

    Returns
    -------
    ANTsImage
        Target image with reference header information
    """
    target.set_origin(reference.origin)
    target.set_direction(reference.direction)
    target.set_spacing(reference.spacing)
    return target


def apply_embedding(bpmn_graph, log=None, aggregated_statistics=None,
    parameters=None):
    """
    Embed decoration information inside the BPMN graph

    Parameters
    -----------
    bpmn_graph
        BPMN graph object
    log
        (Optional) log where the replay technique should be applied
    aggregated_statistics
        (Optional) element-wise statistics calculated on the Petri net
    parameters
        Possible parameters, of the algorithm

    Returns
    -----------
    bpmn_graph
        Annotated BPMN graph
    """
    del log
    del aggregated_statistics
    del parameters
    return bpmn_graph


def f_to_c(f):
    """Convert Fahrenheit to Celsius."""
    return (f - 32.0) / 1.8


def update_Fpsi(Fpsi, psi, f, dx, a, b):
    """
    Used to solve the one-dimensional electrostatic Poisson equation,

        psi'' = -f,

    under Dirichlet (fixed potential) boundary conditions:

        psi[0] = a
        psi[-1] = b

    Arguments
    ---------
    Fpsi : vector of length N
        Vector to update.
    psi : vector of length N
        last estimate of the electrostatic potential [V]
    f : vector of length N
        source term [V cm**-2]
    dx : scalar
        grid spacing [cm]
    a : float
        left Dirichlet boundary value [V]
    b : float
        right Dirichlet boundary value [V]
    """
    dx2 = dx * dx
    Fpsi[1:-1] = psi[:-2] - 2 * psi[1:-1] + psi[2:] + f[1:-1] * dx2
    Fpsi[0] = psi[0] - a
    Fpsi[-1] = psi[-1] - b


@classmethod
def unmarshal(cls, raw: bytes):
    """Returns a new DirectoryBlock object, unmarshalling given bytes according to:
        https://github.com/FactomProject/FactomDocs/blob/master/factomDataStructureDetails.md#directory-block

        Useful for working with a single dblock out of context, pulled directly from a factomd database for instance.

        DirectoryBlock created will not include contextual metadata, such as anchor information or the pointer to the
        next directory block.
        """
    block, data = cls.unmarshal_with_remainder(raw)
    assert len(data) == 0, 'Extra bytes remaining!'
    return block


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


@classmethod
def sync(cls, site, force_insert=False):
    """
        Create or synchronize Alias object from ``site``.

        If `force_insert`, forces creation of Alias object.
        """
    domain = site.domain
    if not domain:
        cls._sync_blank_domain(site)
        return
    if force_insert:
        alias = cls.objects.create(site=site, is_canonical=True, domain=domain)
    else:
        alias, created = cls.objects.get_or_create(site=site, is_canonical=
            True, defaults={'domain': domain})
        if not created and alias.domain != domain:
            alias.site = site
            alias.domain = domain
            alias.save()
    return alias


def komogorov(r, r0):
    """Calculate the phase structure function D_phi in the komogorov approximation

    Parameters
    ----------
    r : `numpy.ndarray`
        r, radial frequency parameter (object space)
    r0 : `float`
        Fried parameter

    Returns
    -------
    `numpy.ndarray`

    """
    return 6.88 * (r / r0) ** (5 / 3)


def _round_pow_2(value):
    """Round value to next power of 2 value - max 16"""
    if value > 8:
        return 16
    elif value > 4:
        return 8
    elif value > 2:
        return 4
    return value


def parse_STRING(data):
    """STRING: ([^\\\\n]*)\\\\n."""
    content, line = data
    i = 0
    while i < len(content) and content[i] != '\n':
        i += 1
    value = content[:i].strip()
    return [value, (content[i + 1:], line + 1)]


def list_exports(NextToken=None):
    """
    Lists all exported output values in the account and region in which you call this action. Use this action to see the exported output values that you can import into other stacks. To import values, use the ` Fn::ImportValue http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html`_ function.
    For more information, see AWS CloudFormation Export Stack Output Values .
    See also: AWS API Documentation

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

    :type NextToken: string
    :param NextToken: A string (provided by the ListExports response output) that identifies the next page of exported output values that you asked to retrieve.

    :rtype: dict
    :return: {
        'Exports': [
            {
                'ExportingStackId': 'string',
                'Name': 'string',
                'Value': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def commandexecutor():
    """A context manager that resolves to an ipeercommandexecutor.

        The object this resolves to can be used to issue command requests
        to the peer.

        Callers should call its ``callcommand`` method to issue command
        requests.

        A new executor should be obtained for each distinct set of commands
        (possibly just a single command) that the consumer wants to execute
        as part of a single operation or round trip. This is because some
        peers are half-duplex and/or don't support persistent connections.
        e.g. in the case of HTTP peers, commands sent to an executor represent
        a single HTTP request. While some peers may support multiple command
        sends over the wire per executor, consumers need to code to the least
        capable peer. So it should be assumed that command executors buffer
        called commands until they are told to send them and that each
        command executor could result in a new connection or wire-level request
        being issued.
        """


def is_valid_xvg(ext):
    """ Checks if file is XVG """
    formats = ['xvg']
    return ext in formats


def _read(prompt: str, typ=None):
    """Reads input and converts it to the respective type."""
    while True:
        raw = input(prompt)
        if typ is not None:
            try:
                return typ(raw)
            except (TypeError, ValueError):
                print(f'Invalid {typ}: {raw}.')
                continue
        return raw


@classmethod
def dbapi(cls):
    """ Hook to the dbapi2.0 implementation's module"""
    import teradatasql
    return teradatasql


def to_datetime(python_dt):
    """Converts python datetime to the salesforce format.

    Example: 2014-11-20T14:23:44.000+0000
    """
    return python_dt.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + '+0000'


def _isnamedtuple(obj):
    """Named tuples are identified via duck typing:
       <http://www.gossamer-threads.com/lists/python/dev/1142178>
    """
    return isinstance(obj, tuple) and hasattr(obj, '_fields')


@classmethod
def get_storage_name_for(cls, section_name):
    """Get storage name for a configuration section."""
    if not section_name or section_name == 'default':
        return 'default'
    return section_name


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


def currency_match(match):
    """Parses a number with a currency.

    Args:
        match (regex match): A match
    """
    if not match:
        return None
    try:
        value = int(match.group('euro')) * 100
        cent = match.group('cent')
        if cent is not None:
            if len(cent) == 1:
                value += int(cent) * 10
            elif len(cent) == 2:
                value += int(cent)
            else:
                assert False
        return value, match.group('currency')
    except ValueError as e:
        return None


def print_graph(graph):
    """Util for pretty graph printing."""
    graph.print_graph()


@classmethod
def make_config_for_update_event(cls, url, mac):
    """Create local push notification for update sensor data."""
    content = ('{"name":"{0}","id":{1},"temp":{2},' +
        '"cap":{3},"lux":{4},"mac":"' + mac + '"}')
    return cls.make_post_local('update', url, content)


def _unwrap(value):
    """Return floats untouched, but ask Series for their NumPy arrays."""
    return getattr(value, 'values', value)


def parse_weight_file(inputFile):
    """The RSCU file contains two columns: codon and weight"""
    weights = {}
    i = 0
    with open(inputFile, 'r') as f:
        for line in f:
            i += 1
            if line.strip() == '':
                continue
            if i == 1:
                continue
            codon = str(line.strip().split('\t')[0])
            weight = float(line.strip().split('\t')[1])
            weights[codon] = weight
    return weights


def lorentzian_function(a, x):
    """a[0]=amplitude,a[1]=center,a[2]=FWHM"""
    return a[0] * 1 / (1 + (x - a[1]) ** 2 / a[2] ** 2)


def descendant(*segments):
    """
        Traverse to a descendant of this path.
        """