def KK_RC79_fit(params, w, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    Rs = params['Rs']
    R1 = params['R1']
    R2 = params['R2']
    R3 = params['R3']
    R4 = params['R4']
    R5 = params['R5']
    R6 = params['R6']
    R7 = params['R7']
    R8 = params['R8']
    R9 = params['R9']
    R10 = params['R10']
    R11 = params['R11']
    R12 = params['R12']
    R13 = params['R13']
    R14 = params['R14']
    R15 = params['R15']
    R16 = params['R16']
    R17 = params['R17']
    R18 = params['R18']
    R19 = params['R19']
    R20 = params['R20']
    R21 = params['R21']
    R22 = params['R22']
    R23 = params['R23']
    R24 = params['R24']
    R25 = params['R25']
    R26 = params['R26']
    R27 = params['R27']
    R28 = params['R28']
    R29 = params['R29']
    R30 = params['R30']
    R31 = params['R31']
    R32 = params['R32']
    R33 = params['R33']
    R34 = params['R34']
    R35 = params['R35']
    R36 = params['R36']
    R37 = params['R37']
    R38 = params['R38']
    R39 = params['R39']
    R40 = params['R40']
    R41 = params['R41']
    R42 = params['R42']
    R43 = params['R43']
    R44 = params['R44']
    R45 = params['R45']
    R46 = params['R46']
    R47 = params['R47']
    R48 = params['R48']
    R49 = params['R49']
    R50 = params['R50']
    R51 = params['R51']
    R52 = params['R52']
    R53 = params['R53']
    R54 = params['R54']
    R55 = params['R55']
    R56 = params['R56']
    R57 = params['R57']
    R58 = params['R58']
    R59 = params['R59']
    R60 = params['R60']
    R61 = params['R61']
    R62 = params['R62']
    R63 = params['R63']
    R64 = params['R64']
    R65 = params['R65']
    R66 = params['R66']
    R67 = params['R67']
    R68 = params['R68']
    R69 = params['R69']
    R70 = params['R70']
    R71 = params['R71']
    R72 = params['R72']
    R73 = params['R73']
    R74 = params['R74']
    R75 = params['R75']
    R76 = params['R76']
    R77 = params['R77']
    R78 = params['R78']
    R79 = params['R79']
    return Rs + R1 / (1 + w * 1.0j * t_values[0]) + R2 / (1 + w * 1.0j *
        t_values[1]) + R3 / (1 + w * 1.0j * t_values[2]) + R4 / (1 + w *
        1.0j * t_values[3]) + R5 / (1 + w * 1.0j * t_values[4]) + R6 / (1 +
        w * 1.0j * t_values[5]) + R7 / (1 + w * 1.0j * t_values[6]) + R8 / (
        1 + w * 1.0j * t_values[7]) + R9 / (1 + w * 1.0j * t_values[8]
        ) + R10 / (1 + w * 1.0j * t_values[9]) + R11 / (1 + w * 1.0j *
        t_values[10]) + R12 / (1 + w * 1.0j * t_values[11]) + R13 / (1 + w *
        1.0j * t_values[12]) + R14 / (1 + w * 1.0j * t_values[13]) + R15 / (
        1 + w * 1.0j * t_values[14]) + R16 / (1 + w * 1.0j * t_values[15]
        ) + R17 / (1 + w * 1.0j * t_values[16]) + R18 / (1 + w * 1.0j *
        t_values[17]) + R19 / (1 + w * 1.0j * t_values[18]) + R20 / (1 + w *
        1.0j * t_values[19]) + R21 / (1 + w * 1.0j * t_values[20]) + R22 / (
        1 + w * 1.0j * t_values[21]) + R23 / (1 + w * 1.0j * t_values[22]
        ) + R24 / (1 + w * 1.0j * t_values[23]) + R25 / (1 + w * 1.0j *
        t_values[24]) + R26 / (1 + w * 1.0j * t_values[25]) + R27 / (1 + w *
        1.0j * t_values[26]) + R28 / (1 + w * 1.0j * t_values[27]) + R29 / (
        1 + w * 1.0j * t_values[28]) + R30 / (1 + w * 1.0j * t_values[29]
        ) + R31 / (1 + w * 1.0j * t_values[30]) + R32 / (1 + w * 1.0j *
        t_values[31]) + R33 / (1 + w * 1.0j * t_values[32]) + R34 / (1 + w *
        1.0j * t_values[33]) + R35 / (1 + w * 1.0j * t_values[34]) + R36 / (
        1 + w * 1.0j * t_values[35]) + R37 / (1 + w * 1.0j * t_values[36]
        ) + R38 / (1 + w * 1.0j * t_values[37]) + R39 / (1 + w * 1.0j *
        t_values[38]) + R40 / (1 + w * 1.0j * t_values[39]) + R41 / (1 + w *
        1.0j * t_values[40]) + R42 / (1 + w * 1.0j * t_values[41]) + R43 / (
        1 + w * 1.0j * t_values[42]) + R44 / (1 + w * 1.0j * t_values[43]
        ) + R45 / (1 + w * 1.0j * t_values[44]) + R46 / (1 + w * 1.0j *
        t_values[45]) + R47 / (1 + w * 1.0j * t_values[46]) + R48 / (1 + w *
        1.0j * t_values[47]) + R49 / (1 + w * 1.0j * t_values[48]) + R50 / (
        1 + w * 1.0j * t_values[49]) + R51 / (1 + w * 1.0j * t_values[50]
        ) + R52 / (1 + w * 1.0j * t_values[51]) + R53 / (1 + w * 1.0j *
        t_values[52]) + R54 / (1 + w * 1.0j * t_values[53]) + R55 / (1 + w *
        1.0j * t_values[54]) + R56 / (1 + w * 1.0j * t_values[55]) + R57 / (
        1 + w * 1.0j * t_values[56]) + R58 / (1 + w * 1.0j * t_values[57]
        ) + R59 / (1 + w * 1.0j * t_values[58]) + R60 / (1 + w * 1.0j *
        t_values[59]) + R61 / (1 + w * 1.0j * t_values[60]) + R62 / (1 + w *
        1.0j * t_values[61]) + R63 / (1 + w * 1.0j * t_values[62]) + R64 / (
        1 + w * 1.0j * t_values[63]) + R65 / (1 + w * 1.0j * t_values[64]
        ) + R66 / (1 + w * 1.0j * t_values[65]) + R67 / (1 + w * 1.0j *
        t_values[66]) + R68 / (1 + w * 1.0j * t_values[67]) + R69 / (1 + w *
        1.0j * t_values[68]) + R70 / (1 + w * 1.0j * t_values[69]) + R71 / (
        1 + w * 1.0j * t_values[70]) + R72 / (1 + w * 1.0j * t_values[71]
        ) + R73 / (1 + w * 1.0j * t_values[72]) + R74 / (1 + w * 1.0j *
        t_values[73]) + R75 / (1 + w * 1.0j * t_values[74]) + R76 / (1 + w *
        1.0j * t_values[75]) + R77 / (1 + w * 1.0j * t_values[76]) + R78 / (
        1 + w * 1.0j * t_values[77]) + R79 / (1 + w * 1.0j * t_values[78])


def contiguous_subsequences(sequence):
    """
    Extract a list of the contiguous subsequences in ``sequence``.

    Parameters
    ----------
    sequence : list of int
        A list of montotonically increasing integers

    Returns
    -------
    list of list of int
        A list of lists of contiguous subsequences in ``sequence``

    Examples
    --------
    >>> contiguous_subsequences([])
    []

    >>> contiguous_subsequences([1])
    [[1]]

    >>> contiguous_subsequences([1,2,3])
    [[1, 2, 3]]

    >>> contiguous_subsequences([-4,2,3,4,5,10,11,12,13,14])
    [[-4], [2, 3, 4, 5], [10, 11, 12, 13, 14]]
    """
    subsequences = []
    if len(sequence) == 0:
        return []
    current_subsequence = [sequence[0]]
    for i in range(1, len(sequence)):
        if sequence[i] == current_subsequence[-1] + 1:
            current_subsequence.append(sequence[i])
        else:
            subsequences.append(current_subsequence)
            current_subsequence = [sequence[i]]
    subsequences.append(current_subsequence)
    return subsequences


@classmethod
def get_config_opts(cls):
    """Defines the configuration options to be associated to this loadable

        :return: A list of configuration options relative to this Loadable
        :rtype: list of :class:`oslo_config.cfg.Opt` instances
        """
    return []


def catch_status_code_error(func):
    """
    Non-200 response will been regarded as fetch failed and will not pass to callback.
    Use this decorator to override this feature.
    """
    func._catch_status_code_error = True
    return func


@staticmethod
def one():
    """
        Return @c 1, the neutral element of integer multiplication.
        """
    return 1


def openDetached():
    """Return file data disconnected from database connection.

        Read access only.
        """


def thermal_sensation(ta, ws, rh, sr, tground):
    """Calculate Thermal Sensation (TS) from air temperature, wind speed,
    relative humidity, solar radiation and groud temperature.

    Thermal Sensation is an index which predicts sensation of
    satisfaction/dissatisfaction under the prevailing outdoor climatic
    conditions.
    Thermal Sensation is derived from original work carried out by Givoni and
    Noguchi [1].

    Note:
        [1] Givoni, Baruch & Noguchi, Mikiko & Saaroni, Hadas & Potchter,
        Oded & Yaakov, Yaron & Feller, Noa & Becker, Stefan. (2003). Outdoor
        comfort research issues. Energy and Buildings. 35. 77-86.
        10.1016/S0378-7788(02)00082-8.

    Args:
        ta: Air temperature [C]
        ws: Wind speed [m/s]
        rh: Relative humidity [%]
        sr: Solar radiation [Wh/m2]
        tground: Ground temperature [C]

    Returns:
        ts -- Thermal sensation [unitless]
    """
    ts = (1.7 + 0.1118 * ta + 0.0019 * sr - 0.322 * ws - 0.0073 * rh +
        0.0054 * tground)
    return ts


def add_entity_info(data_api, struct_inflator):
    """Add the entity info to the structure.
    :param data_api the interface to the decoded data
    :param struct_inflator the interface to put the data into the client object
    """
    for entity in data_api.entity_list:
        struct_inflator.set_entity_info(entity['chainIndexList'], entity[
            'sequence'], entity['description'], entity['type'])


def chkstr(s, v):
    """
    Small routine for checking whether a string is empty
    even a string

    :param s: the string in question
    :param v: variable name
    """
    if type(s) != str:
        raise TypeError('{var} must be str'.format(var=v))
    if not s:
        raise ValueError('{var} cannot be empty'.format(var=v))


@classmethod
def _validate_relationship_config(cls):
    """
        Validate ``cls.CONF_RELATIONSHIP``

        This method should be only called from ``Entity.validate_relationship_config()``,
        SHOULD NOT called from the subclass of :class:`Entity`.
        """
    subclasses = cls.get_all_subclass()
    for subclass in subclasses:
        if len(subclass.CONF_RELATIONSHIP.mapping) == 0:
            continue
        for klass, relationship in subclass.CONF_RELATIONSHIP.mapping.items():
            if klass not in subclasses:
                msg = '`{}` is not subclass of `crawlib2.Entity`'.format(klass
                    .full_classname())
                raise NotImplementedError(msg)
            if relationship.relationship not in ['one', 'many']:
                msg = "`relationship` has to be one of 'one' or 'many'!"
                raise NotImplementedError(msg)
            if relationship.relationship == 'many':
                if not hasattr(subclass, relationship.n_child_key):
                    msg = "`{}` doesn't define `{}` attribute!".format(subclass
                        .full_classname(), relationship.n_child_key)
                    raise NotImplementedError(msg)


@staticmethod
def __find_column(token):
    """Return the column of ``token``."""
    last_cr = token.lexer.lexdata.rfind('\n', 0, token.lexpos)
    if last_cr < 0:
        last_cr = 0
    column = token.lexpos - last_cr + 1
    return column


def youtube_time_format(seconds):
    """Takes time in seconds, returns YouTube format time code."""
    hours = int(seconds / 3600)
    seconds = seconds - hours * 3600
    minutes = int(seconds / 60)
    rest = seconds - minutes * 60
    final_str = ''
    if hours:
        final_str += str(hours) + 'h'
    if minutes:
        final_str += str(minutes) + 'm'
    if seconds:
        final_str += str(rest) + 's'
    return final_str


@staticmethod
def list_to_array(value):
    """
        Converts value into array object with empty array as default.
        Strings with comma-delimited values are split into array of strings.

        :param value: the list to convert.

        :return: array object or empty array when value is None
        """
    if value == None:
        return []
    elif type(value) in [list, tuple, set]:
        return list(value)
    elif type(value) in [str]:
        return value.split(',')
    else:
        return [value]


def hw_from_req(req):
    """ Utility function to get the hardware resource from requests """
    return req.app['com.opentrons.hardware']


def getWorkflowHistory():
    """Get the current workflow state.

        Returns a string with the current workflow state.
        """


def make_arrow(pad):
    """generate the leading arrow in front of traceback or debugger"""
    if pad >= 2:
        return '-' * (pad - 2) + '> '
    elif pad == 1:
        return '>'
    return ''


def bake():
    """Bake selected F-Curves to a set of sampled points defining a similar curve

    """
    pass


@staticmethod
def _add_string_param_by_name(req_dict, param_name, param_value, delimiter=''):
    """
        Adds the specified parameter to the dictionary as a string. If the
        param_value is a list, tuple, or set, the elements from the param_value
        are flattened into a string, with each element delimited by the value
        in the delimiter parameter.

        :param req_dict: The dictionary
        :param param_name: The name of the parameter
        :param param_value: The value for the parameter
        :param delimiter: The string to delimit flattened elements with
        """
    if param_value is not None:
        req_dict[param_name] = delimiter.join(param_value) if isinstance(
            param_value, (list, tuple, set)) else str(param_value)


def simplified_kpca(kpca, source_data):
    """
    Performs kernel PCA on the provided dataset and returns the familiar
    eigenvector, eigenvalue, and scree matrices.

    Note that the positions in the eigenvalues may need to be transposed

    Parameters
    ----------
    kpca : KernelPCA object
        configured Kernel PCA object ready to perform analysis
    source_data : 2D numpy array
        Data arranged as [iteration, features] example - [position, time]

    Returns
    -------
    eigenvalues : 2D numpy array
        Eigenvalues in the original space arranged as [component,iteration]
    scree : 1D numpy array
        S component
    eigenvector : 2D numpy array
        Eigenvectors in the original space arranged as [component,features]

    """
    X_kpca = kpca.fit(source_data.T)
    eigenvectors = X_kpca.alphas_.T
    eigenvalues = X_kpca.fit_transform(source_data)
    scree = kpca.lambdas_
    return eigenvalues, scree, eigenvectors


def add_step(s, step):
    """Adds a Step to the graph as a node.

    The name of the new Step cannot conflict with any steps that already
    exist in the graph. This method fails an assertion if given a
    duplicate step name.

    Args:
      step: A Step object
    """
    key = step.get_name()
    assert key not in s._steps.keys(
        ), 'add_step -- Duplicate step "{}", if this is intentional, first change the step name'.format(
        key)
    s._steps[key] = step


def __compare_sort_handler__(compare):
    """
    Handle sorting of scores.

    :param compare: Compare
    :type compare : pycm.Compare object
    :return: (max_overall_name,max_class_name) as tuple
    """
    sorted_by_class = sorted(compare.scores, key=lambda x: (compare.scores[
        x]['class'], compare.scores[x]['overall']))
    sorted_by_overall = sorted(compare.scores, key=lambda x: (compare.
        scores[x]['overall'], compare.scores[x]['class']))
    sorted_by_class.reverse()
    sorted_by_overall.reverse()
    compare.sorted = sorted_by_class
    max_overall_name = sorted_by_overall[0]
    max_class_name = sorted_by_class[0]
    return max_overall_name, max_class_name


def get_cv_indices(folds, cv_params, input_data, target_data):
    """Produce iterables of cross validation indices in the shape of (n_repeats, n_folds)

    Parameters
    ----------
    folds: Instance of `cv_type`
        Cross validation folds object, whose :meth:`split` receives `input_data` and `target_data`
    cv_params: Dict
        Parameters given to instantiate `folds`. Must contain `n_splits`. May contain `n_repeats`
    input_data: pandas.DataFrame
        Input data to be split by `folds`, to which yielded indices will correspond
    target_data: pandas.DataFrame
        Target data to be split by `folds`, to which yielded indices will correspond

    Yields
    ------
    Generator
        Cross validation indices in shape of (<n_repeats or 1>, <n_splits>)"""
    indices = folds.split(input_data, target_data)
    for rep in range(cv_params.get('n_repeats', 1)):
        yield (next(indices) for _ in range(cv_params['n_splits']))


@classmethod
def isword(cls, nextchar):
    """ Whether or not the next character is part of a word """
    return nextchar.isalpha()


def invert(series):
    """
    Swap index with values of series.

    Parameters
    ----------
    series : ~pandas.Series
        Series to swap on, must have a name.

    Returns
    -------
    ~pandas.Series
        Series after swap.

    See also
    --------
    pandas.Series.map
        Joins series ``a -> b`` and ``b -> c`` into ``a -> c``.
    """
    df = series.reset_index()
    df.set_index(series.name, inplace=True)
    return df[df.columns[0]]


def affiche_solution(sol):
    """
    Retourne une chaîne de caractères qui représente la solution.
    """
    a = ['poison', 'vin', 'reculer', 'avancer']
    res = ''
    for s in sol:
        res += '{0}, '.format(a[s])
    return res


@staticmethod
def sanitize_nan(lcs):
    """
        .. note:: These methods are meant to be applied to photometric tables
        as well
        """
    lcs = lcs.copy()
    avg_error = lcs.fluxerr.mean(skipna=True)
    lcs.fillna(dict(flux=0.0, fluxerr=avg_error), inplace=True)
    return lcs


def _reset_indices():
    """Reset all index counters."""
    global _current_secondary_index
    global _current_internal_index
    global _current_external_index
    _current_secondary_index = 0
    _current_internal_index = 0
    _current_external_index = 0


def compare_every_exon(user_exons: list, db_exons: list) ->bool:
    """compare_every_exon
    If exons match in position and count, return True, otherwise return False

    :param user_exons:
    :type user_exons: list
    :param db_exons:
    :type db_exons: list
    :rtype: bool
    """
    if len(user_exons) != len(db_exons):
        return False
    for i in range(len(user_exons)):
        starts_match = user_exons[i]['real_start'] == db_exons[i]['real_start']
        ends_match = user_exons[i]['real_end'] == db_exons[i]['real_end']
        if not (starts_match and ends_match):
            return False
    return True


def generic_find_uq_constraint_name(table, columns, insp):
    """Utility to find a unique constraint name in alembic migrations"""
    for uq in insp.get_unique_constraints(table):
        if columns == set(uq['column_names']):
            return uq['name']


def no_log_warn(logical_line):
    """Disallow 'LOG.warn('

    O339
    """
    if logical_line.startswith('LOG.warn('):
        yield 0, 'O339:Use LOG.warning() rather than LOG.warn()'


def grace(data, xlab='', ylab='', title=''):
    """
	Input data is of the form, [ [x1,y1], [x2,y2],....] where x and y are vectors
	"""
    try:
        import pygrace
        pg = pygrace.grace()
        for xy in data:
            pg.plot(xy[0], xy[1])
            pg.hold(1)
        pg.xlabel(xlab)
        pg.ylabel(ylab)
        pg.title(title)
        return True
    except:
        return False


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


@staticmethod
def _create_vertex(lpg_vertex_class, params):
    """ Creates a Live Packet Gather Vertex

        :param lpg_vertex_class: the type to create for the vertex
        :param params: the parameters of the vertex
        :return: the vertex built
        """
    return lpg_vertex_class(hostname=params.hostname, port=params.port, tag
        =params.tag, strip_sdp=params.strip_sdp, use_prefix=params.
        use_prefix, key_prefix=params.key_prefix, prefix_type=params.
        prefix_type, message_type=params.message_type, right_shift=params.
        right_shift, payload_as_time_stamps=params.payload_as_time_stamps,
        use_payload_prefix=params.use_payload_prefix, payload_prefix=params
        .payload_prefix, payload_right_shift=params.payload_right_shift,
        number_of_packets_sent_per_time_step=params.
        number_of_packets_sent_per_time_step, label=params.label)


def getCSSClass(element, cssClass=None):
    """Return the css class if any or an empty string."""


@classmethod
def get_decoder(cls, encoding):
    """Return a decoder for the given `encoding`.

        The decoder gets a `bytes` object as argument and returns another
        decoded `bytes` object.  If the `encoding` is not registered, a
        `KeyError` is raised.

        >>> decode = CodecReg.get_decoder('hex')
        >>> decode(b'464f4f00')
        b'FOO\\x00'
        """
    return cls._codecs[encoding].decode


@staticmethod
def is_datastore_mount_usable(mount_info):
    """Check if a datastore is usable as per the given mount info.

        The datastore is considered to be usable for a host only if it is
        writable, mounted and accessible.

        :param mount_info: HostMountInfo data object
        :return: True if datastore is usable
        """
    writable = mount_info.accessMode == 'readWrite'
    mounted = getattr(mount_info, 'mounted', True)
    accessible = getattr(mount_info, 'accessible', False)
    return writable and mounted and accessible


def checkBindings(current, expected):
    """
    This method checks that you give the appropriate forced bindings
    to the sepa instance. In an ysap, the required bindings are the
    ones that do not have a default value. Which means the ones that
    have their value == "".
    """
    set_current = set(current.keys())
    set_expected = set(expected.keys())
    set_difference = set_expected - set_current
    if len(set_difference) != 0:
        for key in set_difference:
            if expected[key]['value'] == '':
                raise KeyError(key + ' is a required forcedbinding')
    return True


def get_alphabetic_ratio(string):
    """
	gives the ratio of alphabetic characters to the rest
	:type string: str
	:rtype: float or NoneType
	"""
    length = len(string)
    if length == 0:
        return None
    else:
        return sum([(1) for character in string if character.isalpha()]
            ) / length


def overlap_dist(a, b, d):
    """
    calculates the hamming (overlap) distance between observations for data
    containing only nominal / categorical features, returns float value
    """
    dist = [None] * d
    for i in range(d):
        if a.iloc[i] == b.iloc[i]:
            dist[i] = 0
        else:
            dist[i] = 1
    dist = sum(dist)
    return dist


def bake():
    """Bake dynamic paint image sequence surface

    """
    pass


def register_extension_class(ext, base, *args, **kwargs):
    """Instantiate the given extension class and register as a public attribute of the given base.

    README: The expected protocol here is to instantiate the given extension and pass the base
    object as the first positional argument, then unpack args and kwargs as additional arguments to
    the extension's constructor.
    """
    ext_instance = ext.plugin(base, *args, **kwargs)
    setattr(base, ext.name.lstrip('_'), ext_instance)


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

        :param SharedFolderMountType val:
        :rtype: EventType
        """
    return cls('shared_folder_mount', val)


def disable():
    """Disables custom exception handling"""
    global ENABLED
    ENABLED = False


def strip_dir_path(source, dirname):
    """Keep the folder structure after the path folder by
    a) appending a '/' at the end of directory names
    b) removing the first character from a directory name if it is a '/'
    The result should look like this:
    file1.txt
    folder1/
    folder1/folder2/
    folder1/folder2/file2.txt
    """
    prefix = ''
    prefix = dirname.replace(source, '')
    if prefix != '':
        prefix += '/'
        if prefix.startswith('/'):
            prefix = prefix[1:]
    return prefix


def snap_cursor_to_center():
    """Snap cursor to the Center

    """
    pass


def find_dependencies(name, images):
    """
    Finds the dependencies of name in the
    images dictionary and returns an array
    of all keys in images that should be built

    :param name: The name of the image to build
    :type name: string

    :param images: The dictionary of images
    :type images: dict(string: image_definition)
    """
    names = []
    curname = name
    while 'from' in images[curname]:
        names.append(curname)
        curname = images[curname]['from']
    names.append(curname)
    return names


def psi_K_Cl_NO3_PK74(T, P):
    """c-a-a': potassium chloride nitrate [PK74]."""
    psi = -0.006
    valid = T == 298.15
    return psi, valid


def get_genome_dir(infra_id, genver=None, annver=None, key=None):
    """Return the genome directory name from infra_id and optional arguments."""
    dirname = f'{infra_id}'
    if genver is not None:
        dirname += f'.gnm{genver}'
    if annver is not None:
        dirname += f'.ann{annver}'
    if key is not None:
        dirname += f'.{key}'
    return dirname


def _get_values_diff(test_type, series, index, ind):
    """
    Gets the difference between two values given a test type.
    :param test_type: one_sided or two_sided
    :param series: Series of values
    :param index: primary index
    :param ind: secondary index
    :return: Difference between 2 values
    """
    if test_type == 'one_sided':
        values_diff = series.loc[index] - series.loc[ind]
    elif test_type == 'two_sided':
        values_diff = abs(series.loc[index] - series.loc[ind])
    else:
        raise ValueError(
            'Test type is unknown: can be either one_sided or two_sided')
    return values_diff


def _present_config_results(config_records, resource_ids):
    """
    If resource_id is in config_results add to dictionary and return dictionary

    :param config_records: config compliance records
    :param resource_ids: list of resource ids
    :returns: dictionary of resource_id: compliance_type
    """
    found_ids = {}
    for config_records in config_records:
        config_record_id = config_records['EvaluationResultIdentifier'][
            'EvaluationResultQualifier']['ResourceId']
        if config_record_id in resource_ids:
            found_ids[config_record_id] = config_records['ComplianceType']
    return found_ids


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

        :param SingleUserLock val:
        :rtype: FileLockContent
        """
    return cls('single_user', val)


@classmethod
def build_batch(cls, size, **kwargs):
    """Build a batch of instances of the given class, with overriden attrs.

        Args:
            size (int): the number of instances to build

        Returns:
            object list: the built instances
        """
    return [cls.build(**kwargs) for _ in range(size)]


def get_endpoint_dist(ep_0, ep_1):
    """
    Calculate a list of site distances between two endpoints, assuming periodic
    boundary conditions.
    Args:
        ep_0 (Structure): the first endpoint structure.
        ep_1 (Structure): the second endpoint structure.
    Returns:
        dist (list): a list of distances between two structures.
    """
    ep_0.remove_oxidation_states()
    ep_1.remove_oxidation_states()
    assert ep_0.species == ep_1.species, 'Formula mismatch!'
    assert ep_0.lattice.abc == ep_0.lattice.abc, 'Lattice mismatch!'
    distances = []
    for site0, site1 in zip(ep_0, ep_1):
        fc = site0.frac_coords, site1.frac_coords
        d = ep_0.lattice.get_distance_and_image(fc[0], fc[1])[0]
        distances.append(d)
    return distances


def str_bool(b):
    """Convert boolean to string, in the way expected by the API."""
    return 'true' if b else 'false'


def _create_json(name, description, locked, type, jndiId, connection,
    connectionManager):
    """
    Create a JSON to be used for the REST API call
    """
    json = {'connection': connection, 'type': type, 'jndiId': jndiId,
        'name': name, 'description': description, 'locked': locked}
    if connectionManager is not None:
        json['connectionManager'] = connectionManager
    return json


@staticmethod
def incr_ip(ip_addr, offset=1):
    """Helper function to increase IP address
        """
    lst_ip = ip_addr.split('.')
    b_1 = format(int(lst_ip[0]), '08b')
    b_2 = format(int(lst_ip[1]), '08b')
    b_3 = format(int(lst_ip[2]), '08b')
    b_4 = format(int(lst_ip[3]), '08b')
    b_ip = b_1 + b_2 + b_3 + b_4
    b_newip = format(int(b_ip, 2) + offset, '032b')
    newd1 = int(b_newip[0:8], 2)
    newd2 = int(b_newip[8:16], 2)
    newd3 = int(b_newip[16:24], 2)
    newd4 = int(b_newip[24:32], 2)
    return '%s.%s.%s.%s' % (newd1, newd2, newd3, newd4)


@classmethod
def get_dialect_cls(cls, url):
    """Given a URL, return the :class:`.Dialect` that will be used.

        This is a hook that allows an external plugin to provide functionality
        around an existing dialect, by allowing the plugin to be loaded
        from the url based on an entrypoint, and then the plugin returns
        the actual dialect to be used.

        By default this just returns the cls.

        .. versionadded:: 1.0.3

        """
    return cls


@classmethod
def get_content_model_name(cls):
    """
        Return the name of the OneToOneField django automatically creates for
        child classes in multi-table inheritance.
        """
    return cls._meta.object_name.lower()


def flatten_arguments(arg_dict):
    """Flattens a dict of arguments into a list for subprocess."""
    args = []
    for arg_name, arg_value in sorted(arg_dict.items()):
        if isinstance(arg_value, bool):
            args += [arg_name]
        elif hasattr(arg_value, '__iter__') and not isinstance(arg_value, str):
            args += [arg_name] + list(arg_value)
        else:
            args += [arg_name, str(arg_value)]
    return args


def start_find():
    """Start searching text

    """
    pass


def uvs_rotate(use_ccw: bool=False):
    """Rotate UV coordinates inside faces

    :param use_ccw: Counter Clockwise
    :type use_ccw: bool
    """
    pass


def delete_security_configuration(Name=None):
    """
    Deletes a security configuration.
    See also: AWS API Documentation

    :example: response = client.delete_security_configuration(
        Name='string'
    )

    :type Name: string
    :param Name: [REQUIRED]
            The name of the security configuration.

    :rtype: dict
    :return: {}

    """
    pass


def product(iterable):
    """Return product of sequence of numbers.

    Equivalent of functools.reduce(operator.mul, iterable, 1).
    Multiplying numpy integers might overflow.

    >>> product([2**8, 2**30])
    274877906944
    >>> product([])
    1

    """
    prod = 1
    for i in iterable:
        prod *= i
    return prod


def window_fullscreen_toggle():
    """Toggle the current window fullscreen

    """
    pass


def safe_repr(obj):
    """
    Return a string describing Python object `obj`.

    Avoids calling any Python magic methods, so should be safe to use
    as a 'last resort' in implementation of `__str__` and `__repr__`.
    """
    return '%s@%x' % (obj.__class__.__name__, id(obj))


def get_var(name, context, default=None):
    """ Get a variable from a dict context

    Parameters
    ----------
    name : str or list(str)
        variable name
    context : dict
        variable dict
    default:
        default value or function which creates the default
        value if failed to find var in context
    """
    if not isinstance(name, (list, tuple)):
        name = name,
    current_context = context
    for current_name in name:
        if current_name in current_context:
            current_context = current_context[current_name]
        elif callable(default):
            return default()
        else:
            return default
    return current_context


def duplicate_move_keep_inputs(NODE_OT_duplicate=None,
    NODE_OT_translate_attach=None):
    """Duplicate selected nodes keeping input links and move them

    :param NODE_OT_duplicate: Duplicate Nodes, Duplicate selected nodes
    :param NODE_OT_translate_attach: Move and Attach, Move nodes and attach to frame
    """
    pass


def hide_tracks(unselected: bool=False):
    """Hide selected tracks

    :param unselected: Unselected, Hide unselected tracks
    :type unselected: bool
    """
    pass


def binary_reduce(reducer, binary_op, graph, lhs, rhs, lhs_data, rhs_data,
    out_size, lhs_map, rhs_map, out_map):
    """Perform binary operation between given data and reduce based on graph
    structure.

    Parameters
    ----------
    reducer : str
        Type of reduction: 'sum', 'max', 'min', 'mean', 'prod', 'none' (no
        reduction)
    binary_op : str
        Binary operation to perform, can be 'add', 'mul', 'sub', 'div'
    graph : GraphIndex
        The graph
    lhs : int
        The lhs target (src, dst, edge)
    rhs : int
        The rhs target (src, dst, edge)
    lhs_data : Tensor
        The lhs data
    rhs_data : Tensor
        The rhs data
    out_size : int
        Size of first dimension of output data
    lhs_map : tuple
        Two lhs id mapping arrays, one for forward pass, the other for backward
    rhs_map : tuple
        Two rhs id mapping arrays, one for forward pass, the other for backward
    out_map : tuple
        Two out id mapping arrays, one for forward pass, the other for backward

    Returns
    -------
    Tensor
        The result.
    """
    pass


def calculateconfigdiff(first, second, onlyfirst=True):
    """Calculate differences in configuration between 2 configurations.

       onlyfirst -- only check configuration entries that occur in the first config"""
    add = []
    diff1 = []
    diff2 = []
    remove = []
    for section, item, value in first.walkconfig():
        if not second.hasconfig(section, item):
            add.append((section, item, value))
        elif second.config(section, item) != value:
            diff1.append((section, item, value))
    if not onlyfirst:
        for section, item, value in second.walkconfig():
            if not first.hasconfig(section, item):
                remove.append((section, item, value))
            elif first.config(section, item) != value:
                diff2.append((section, item, value))
    return add, diff1, diff2, remove


def timer(start, end):
    """ Give duration time between 2 times in hh:mm:ss.

    Parameters
    ----------
    start: float
        the starting time.
    end: float
        the ending time.
    """
    hours, rem = divmod(end - start, 3600)
    minutes, seconds = divmod(rem, 60)
    return '{:0>2}:{:0>2}:{:05.2f}'.format(int(hours), int(minutes), seconds)


@staticmethod
def _assert_format_exists(file_format, methods):
    """Checks whether the given file format exists in 'methods'.
        """
    try:
        return methods[file_format]
    except KeyError:
        formats = ', '.join(sorted(methods.keys()))
        raise ValueError('Unsupported format: %r, try one of %s' % (
            file_format, formats))


def lambd_NH3_OH_CB89(T, P):
    """n-a: ammonia hydroxide [CB89]."""
    lambd = 0.103
    valid = T == 298.15
    return lambd, valid


def rhypo_to_rrup(rhypo, mag):
    """
    Converts hypocentral distance to an equivalent rupture distance
    dependent on the magnitude
    """
    rrup = rhypo - (0.7108 + 2.496e-06 * mag ** 7.982)
    rrup[rrup < 3.0] = 3.0
    return rrup


@staticmethod
def _get_checksum(data):
    """
        Calculates the modulo 256 checksum of a string of characters.
        This checksum, expressed in hexadecimal, is used in every
        communication of this instrument, as a sanity check.

        Returns a string corresponding to the hexademical value
        of the checksum, without the `0x` prefix.

        :param data: Byte string to be checksummed
        :type: `str`

        :rtype: `str`
        """
    chrs = list(data)
    total = 0
    for c in chrs:
        total += ord(c)
    return format(total % 256, '02X')


def globpath(filepath: str) ->str:
    """convert a filepath to a glob path, ['/'|''] to '.'

    filepath {str} -- filepath to glob

    return {str} -- new globpath
    """
    glob = filepath.replace('/', '.').replace('\\', '.')
    while glob[0] == '.':
        glob = glob[1:]
    return glob


def skin_root_mark():
    """Mark selected vertices as roots

    """
    pass


def add(language, identifier, path):
    """Add or update entry.

        For example: `self.add('en', 'identifier', 'What a lovely day!')`
        """


def list_objects(Bucket=None, Delimiter=None, EncodingType=None, Marker=
    None, MaxKeys=None, Prefix=None, RequestPayer=None):
    """
    Returns some or all (up to 1000) of the objects in a bucket. You can use the request parameters as selection criteria to return a subset of the objects in a bucket.
    See also: AWS API Documentation

    :example: response = client.list_objects(
        Bucket='string',
        Delimiter='string',
        EncodingType='url',
        Marker='string',
        MaxKeys=123,
        Prefix='string',
        RequestPayer='requester'
    )

    :type Bucket: string
    :param Bucket: [REQUIRED]

    :type Delimiter: string
    :param Delimiter: A delimiter is a character you use to group keys.

    :type EncodingType: string
    :param EncodingType: Requests Amazon S3 to encode the object keys in the response and specifies the encoding method to use. An object key may contain any Unicode character; however, XML 1.0 parser cannot parse some characters, such as characters with an ASCII value from 0 to 10. For characters that are not supported in XML 1.0, you can add this parameter to request that Amazon S3 encode the keys in the response.

    :type Marker: string
    :param Marker: Specifies the key to start with when listing objects in a bucket.

    :type MaxKeys: integer
    :param MaxKeys: Sets the maximum number of keys returned in the response. The response might contain fewer keys but will never contain more.

    :type Prefix: string
    :param Prefix: Limits the response to keys that begin with the specified prefix.

    :type RequestPayer: string
    :param RequestPayer: Confirms that the requester knows that she or he will be charged for the list objects request. Bucket owners need not specify this parameter in their requests.

    :rtype: dict
    :return: {
        'IsTruncated': True|False,
        'Marker': 'string',
        'NextMarker': 'string',
        'Contents': [
            {
                'Key': 'string',
                'LastModified': datetime(2015, 1, 1),
                'ETag': 'string',
                'Size': 123,
                'StorageClass': 'STANDARD'|'REDUCED_REDUNDANCY'|'GLACIER',
                'Owner': {
                    'DisplayName': 'string',
                    'ID': 'string'
                }
            },
        ],
        'Name': 'string',
        'Prefix': 'string',
        'Delimiter': 'string',
        'MaxKeys': 123,
        'CommonPrefixes': [
            {
                'Prefix': 'string'
            },
        ],
        'EncodingType': 'url'
    }

    :returns:
    (dict) --
    IsTruncated (boolean) -- A flag that indicates whether or not Amazon S3 returned all of the results that satisfied the search criteria.
    Marker (string) --
    NextMarker (string) -- When response is truncated (the IsTruncated element value in the response is true), you can use the key name in this field as marker in the subsequent request to get next set of objects. Amazon S3 lists objects in alphabetical order Note: This element is returned only if you have delimiter request parameter specified. If response does not include the NextMaker and it is truncated, you can use the value of the last Key in the response as the marker in the subsequent request to get the next set of object keys.
    Contents (list) --
    (dict) --
    Key (string) --
    LastModified (datetime) --
    ETag (string) --
    Size (integer) --
    StorageClass (string) -- The class of storage used to store the object.
    Owner (dict) --
    DisplayName (string) --
    ID (string) --

    Name (string) --
    Prefix (string) --
    Delimiter (string) --
    MaxKeys (integer) --
    CommonPrefixes (list) --
    (dict) --
    Prefix (string) --

    EncodingType (string) -- Encoding type used by Amazon S3 to encode object keys in the response.

    """
    pass


def _parse_conll_identifier(value: str, line: int, field: str, *, non_zero=
    False) ->int:
    """Parse a CoNLL token identifier, raise the appropriate exception if it is invalid.
       Just propagate the exception if `value` does not parse to an integer.

       If `non_zero` is truthy, raise an exception if `value` is zero.
       `field` and `line` are only used for the error message."""
    res = int(value)
    if res < 0:
        raise ValueError(
            'At line {line}, the `{field}` field must be a non-negative integer, got {value!r}'
            .format(line=line, field=field, value=value))
    elif non_zero and res == 0:
        raise ValueError(
            'At line {line}, the `{field}` field must be a positive integer, got {value!r}'
            .format(line=line, field=field, value=value))
    return res


def _jupyter_bundlerextension_paths():
    """Metadata for notebook bundlerextension"""
    return [{'name': 'notebook_zip_download', 'label':
        'IPython Notebook bundle (.zip)', 'module_name':
        'notebook.bundler.zip_bundler', 'group': 'download'}]


@classmethod
def get_example(cls) ->int:
    """Returns an example value for the Integer type."""
    if cls.example is not None:
        return cls.example
    return 1


def set_level(request, level):
    """
    Sets the minimum level of messages to be recorded, returning ``True`` if
    the level was recorded successfully.

    If set to ``None``, the default level will be used (see the ``get_level``
    method).
    """
    if not hasattr(request, '_messages'):
        return False
    request._messages.level = level
    return True


def PyWorkbookUser(DataHandlerUser):
    """overrides  _getsetfunc_ with something that uses DataHandlerUser
   instead of DataHanlder for setting items (needed to undo), plus inherits
   all the other functionality of DataHandlerUser (undo and redo)"""
    pass


@staticmethod
def _parseAccidental(accidental):
    """
        Given an accidental, calculate its shift amount.

        :param accidental: str. An accidental string.
        :return:
        """
    if accidental == "'":
        return -1
    if accidental.endswith("'"):
        mul = -1
        accidental = accidental[:-1]
    else:
        mul = 1
    try:
        return int(accidental) * mul
    except Exception as e:
        raise ValueError('Cannot convert accidental to integer: %s' %
            accidental)


@classmethod
def fromkeys(cls, iterable, *args):
    """Create a ChainMap with a single dict created from the iterable."""
    return cls(dict.fromkeys(iterable, *args))


def _normalize_percent_rgb(value):
    """
    Internal normalization function for clipping percent values into
    the permitted range (0%-100%, inclusive).

    """
    percent = value.split(u'%')[0]
    percent = float(percent) if u'.' in percent else int(percent)
    return (u'0%' if percent < 0 else u'100%' if percent > 100 else u'{}%'.
        format(percent))


def raise_error(msg, line, i, start_line):
    """ raise error when reading line

    Parameters
    ----------
    msg: str
    line: str
    i: int
    start_line: int

    Returns
    -------

    """
    raise IOError('{0}, for line #{1}: {2}'.format(msg, i + 1 + start_line,
        line.strip()))


def kaiser_beta(a):
    """Compute the Kaiser parameter `beta`, given the attenuation `a`.

    Parameters
    ----------
    a : float
        The desired attenuation in the stopband and maximum ripple in
        the passband, in dB.  This should be a *positive* number.

    Returns
    -------
    beta : float
        The `beta` parameter to be used in the formula for a Kaiser window.

    References
    ----------
    Oppenheim, Schafer, "Discrete-Time Signal Processing", p.475-476.
    """
    if a > 50:
        beta = 0.1102 * (a - 8.7)
    elif a > 21:
        beta = 0.5842 * (a - 21) ** 0.4 + 0.07886 * (a - 21)
    else:
        beta = 0.0
    return beta


def attribute(rl, attribute, type, threshold):
    """ Returns all repeats in ``rl`` with a attribute below (above) a certain
        threshold.

    Returns all repeats in ``rl`` with a attribute below (above) a certain
    threshold.

    Args:
        rl (RepeatList): An instance of the RepeatList class.
        attribute (str): The attribute of the Repeat instance
        type (str): Either "min" or "max"
        threshold (float): All repeats with an attribute value below (above)
                          this threshold are filtered out.
    """
    threshold = float(threshold)
    res = []
    for i_repeat in rl.repeats:
        value = getattr(i_repeat, attribute)
        if type == 'min':
            if value >= threshold:
                res.append(i_repeat)
        elif type == 'max':
            if value <= threshold:
                res.append(i_repeat)
        else:
            raise Exception(
                "type must either be 'min' or 'max'. Instead, it is {}.".
                format(type))
    return res


def non_hydrogen_count(mol):
    """Non-hydrogen atom count """
    return sum(1 for _, a in mol.atoms_iter() if a.symbol != 'H')


def absolute_vertical_stability(F_z, W_sub, gamma_SC) ->'abs_vert_stab_uty':
    """Absolute vertical stability unity check.
    Reference:
    DNVGL-RP-F109 (2017-05)
        sec:3.6.1, eq:3.39, page:31
    """
    abs_vert_stab_uty = gamma_SC * F_z / W_sub
    return abs_vert_stab_uty


def color_text(s):
    """
    Returns a colorized version of the given text based on a simple hash algorithm.
    """
    if not s:
        return s
    colors = ('03', '04', '05', '06', '07', '08', '09', '10', '11', '12',
        '13', '15')
    hash_output = hash(s.encode())
    num = hash_output % len(colors)
    return '\x03%s%s\x03' % (colors[num], s)


def _check_limits(fmin, fmid, fmax, extra='f'):
    """Check for monotonicity."""
    if fmin >= fmid:
        raise ValueError('%smin must be < %smid, got %0.4g >= %0.4g' % (
            extra, extra, fmin, fmid))
    if fmid >= fmax:
        raise ValueError('%smid must be < %smax, got %0.4g >= %0.4g' % (
            extra, extra, fmid, fmax))


def get_corners(fileName):
    """Gets the corners of a map (coordinates file) for plotting purposes.

    Parameters
    ----------
    fileName : fileName
        List of coordinates to get the boundaries from (lat, lon) rows.

    Returns
    -------
    list
        List of minMaxLongs & minMaxLats.

    """
    lats = []
    longs = []
    clusterData = open(fileName, 'r')
    next(clusterData)
    for line in clusterData:
        tokens = line.split(',')
        lat, long = float(tokens[1]), float(tokens[2])
        lats.append(lat)
        longs.append(long)
    minLat = min(lats)
    minLong = min(longs)
    maxLat = max(lats)
    maxLong = max(longs)
    return [[minLong, maxLong], [minLat, maxLat]]


def x11colors():
    """
    Get the x11 colors

    Returns
    -------
        The x11 colors
    """
    return {'aliceblue': 'F0F8FF', 'antiquewhite': 'FAEBD7', 'aqua':
        '00FFFF', 'aquamarine': '7FFFD4', 'azure': 'F0FFFF', 'beige':
        'F5F5DC', 'bisque': 'FFE4C4', 'black': '000000', 'blanchedalmond':
        'FFEBCD', 'blue': '0000FF', 'blueviolet': '8A2BE2', 'brown':
        'A52A2A', 'burlywood': 'DEB887', 'cadetblue': '5F9EA0',
        'chartreuse': '7FFF00', 'chocolate': 'D2691E', 'coral': 'FF7F50',
        'cornflowerblue': '6495ED', 'cornsilk': 'FFF8DC', 'crimson':
        'DC143C', 'cyan': '00FFFF', 'darkblue': '00008B', 'darkcyan':
        '008B8B', 'darkgoldenrod': 'B8860B', 'darkgray': 'A9A9A9',
        'darkgreen': '006400', 'darkgrey': 'A9A9A9', 'darkkhaki': 'BDB76B',
        'darkmagenta': '8B008B', 'darkolivegreen': '556B2F', 'darkorange':
        'FF8C00', 'darkorchid': '9932CC', 'darkred': '8B0000', 'darksalmon':
        'E9967A', 'darkseagreen': '8FBC8F', 'darkslateblue': '483D8B',
        'darkslategray': '2F4F4F', 'darkslategrey': '2F4F4F',
        'darkturquoise': '00CED1', 'darkviolet': '9400D3', 'deeppink':
        'FF1493', 'deepskyblue': '00BFFF', 'dimgray': '696969', 'dimgrey':
        '696969', 'dodgerblue': '1E90FF', 'firebrick': 'B22222',
        'floralwhite': 'FFFAF0', 'forestgreen': '228B22', 'fuchsia':
        'FF00FF', 'gainsboro': 'DCDCDC', 'ghostwhite': 'F8F8FF', 'gold':
        'FFD700', 'goldenrod': 'DAA520', 'gray': '808080', 'green':
        '008000', 'greenyellow': 'ADFF2F', 'grey': '808080', 'honeydew':
        'F0FFF0', 'hotpink': 'FF69B4', 'indianred': 'CD5C5C', 'indigo':
        '4B0082', 'ivory': 'FFFFF0', 'khaki': 'F0E68C', 'lavender':
        'E6E6FA', 'lavenderblush': 'FFF0F5', 'lawngreen': '7CFC00',
        'lemonchiffon': 'FFFACD', 'lightblue': 'ADD8E6', 'lightcoral':
        'F08080', 'lightcyan': 'E0FFFF', 'lightgoldenrodyellow': 'FAFAD2',
        'lightgray': 'D3D3D3', 'lightgreen': '90EE90', 'lightgrey':
        'D3D3D3', 'lightpink': 'FFB6C1', 'lightsalmon': 'FFA07A',
        'lightseagreen': '20B2AA', 'lightskyblue': '87CEFA',
        'lightslategray': '778899', 'lightslategrey': '778899',
        'lightsteelblue': 'B0C4DE', 'lightyellow': 'FFFFE0', 'lime':
        '00FF00', 'limegreen': '32CD32', 'linen': 'FAF0E6', 'magenta':
        'FF00FF', 'maroon': '800000', 'mediumaquamarine': '66CDAA',
        'mediumblue': '0000CD', 'mediumorchid': 'BA55D3', 'mediumpurple':
        '9370DB', 'mediumseagreen': '3CB371', 'mediumslateblue': '7B68EE',
        'mediumspringgreen': '00FA9A', 'mediumturquoise': '48D1CC',
        'mediumvioletred': 'C71585', 'midnightblue': '191970', 'mintcream':
        'F5FFFA', 'mistyrose': 'FFE4E1', 'moccasin': 'FFE4B5',
        'navajowhite': 'FFDEAD', 'navy': '000080', 'oldlace': 'FDF5E6',
        'olive': '808000', 'olivedrab': '6B8E23', 'orange': 'FFA500',
        'orangered': 'FF4500', 'orchid': 'DA70D6', 'palegoldenrod':
        'EEE8AA', 'palegreen': '98FB98', 'paleturquoise': 'AFEEEE',
        'palevioletred': 'DB7093', 'papayawhip': 'FFEFD5', 'peachpuff':
        'FFDAB9', 'peru': 'CD853F', 'pink': 'FFC0CB', 'plum': 'DDA0DD',
        'powderblue': 'B0E0E6', 'purple': '800080', 'red': 'FF0000',
        'rosybrown': 'BC8F8F', 'royalblue': '4169E1', 'saddlebrown':
        '8B4513', 'salmon': 'FA8072', 'sandybrown': 'F4A460', 'seagreen':
        '2E8B57', 'seashell': 'FFF5EE', 'sienna': 'A0522D', 'silver':
        'C0C0C0', 'skyblue': '87CEEB', 'slateblue': '6A5ACD', 'slategray':
        '708090', 'slategrey': '708090', 'snow': 'FFFAFA', 'springgreen':
        '00FF7F', 'steelblue': '4682B4', 'tan': 'D2B48C', 'teal': '008080',
        'thistle': 'D8BFD8', 'tomato': 'FF6347', 'turquoise': '40E0D0',
        'violet': 'EE82EE', 'wheat': 'F5DEB3', 'white': 'FFFFFF',
        'whitesmoke': 'F5F5F5', 'yellow': 'FFFF00', 'yellowgreen': '9ACD32'}


def identity(value):
    """ 直接返回值, 常用于函数式编程中. identity, used in functional programming mostly. """
    return value


def model_to_dict(obj, context):
    """
    Convert django model instance to dict
    """
    data = {}
    for field in obj._meta.fields:
        field_name = field.column if field.rel else field.name
        data[field.column] = getattr(obj, field_name)
    return data


def check_fastlitup(inp):
    """ quick check for iterables tuple, list """
    if inp.__class__ is list or inp.__class__ is tuple:
        return True
    else:
        return False


def windchill_temp(ta, ws):
    """Calculate the Wind Chill Temperature (WCT) from air temperature and wind
    speed.

    It is the perceived decrease in air temperature felt by the body on
    exposed skin due to the flow of air. It's used by both National
    Weather Service (NSW) in US and Canadian Meteorologist service.
    The formula is derived from Envirnoment Canada [1].

    Note:
        [1]  "Environment Canada - Weather and Meteorology - Canada's Wind
        Chill Index". Ec.gc.ca. Retrieved 2013-08-09.

    Args:
        ta: Air temperature [C]
        ws: Wind speed [m/s]

    Returns:
        twc -- Wind Chill Temperature [C]
    """
    ws_km_h = ws * 3.6
    twc = (13.12 + 0.6215 * ta - 11.37 * ws_km_h ** 0.16 + 0.3965 * ta *
        ws_km_h ** 0.16)
    return twc


def is_tuple(obj):
    """
    Checks if a given sequence is a tuple.

    Parameters
    ----------
    obj : object
        The input array.

    Returns
    -------
    test result : bool
        The test result of whether seq is a tuple or not.

    >>> is_tuple(('a', 'b'))
    True

    >>> is_tuple(['a', 'b'])
    False

    >>> is_tuple(4)
    False
    """
    return True if isinstance(obj, tuple) else False


def Singer_orographic_rainfall(z_closest_node_to_center):
    """Return a set of curve weights for a provided z, assuming an orographic
    rule following that presented in Singer & Michaelides 2017 & Singer et al.
    2018 and applicable specifically to Walnut Gulch. i.e., there are three
    orographic divisions, divided at 1350 m and 1500 m.

    Parameters
    ----------
    z_closest_node_to_center : float
        The elevation of the node closest to the storm center.

    Returns
    -------
    wgts : length 11 list
        The weighting parameters to use in selecting a storm distribution
        curve.
    """
    if z_closest_node_to_center <= 1350:
        wgts = [0.0318, 0.0759, 0.0851, 0.0941, 0.0941, 0.0941, 0.0941,
            0.0941, 0.1033, 0.1121, 0.1213]
    elif 1350 < z_closest_node_to_center <= 1500:
        wgts = [0.0478, 0.0778, 0.0869, 0.0959, 0.0959, 0.0959, 0.0959,
            0.0959, 0.1051, 0.1141, 0.0888]
    elif z_closest_node_to_center > 1500:
        wgts = [0.0696, 0.0786, 0.0878, 0.0968, 0.0968, 0.0968, 0.0968,
            0.0968, 0.106, 0.1149, 0.0591]
    return wgts


@classmethod
def is_datasource_for(cls, data, header, **kwargs):
    """Determines if header corresponds to an EUVI image"""
    return header.get('detector') == 'EUVI'


def example_node(G, n=1):
    """
    ### Prints out an example node ###
     REQUIRED:  G - a graph object
                n - number of nodes to print
    #--------------------------------------------------------------------------#
    """
    i = list(G.nodes(data=True))[:n]
    for j in i:
        print(j)


def copy_keywords(srchdr, dsthdr, keys):
    """Copy a list of FITS keywords from one header to another.

    Parameters
    ----------
    srchdr : `astropy.io.fits.Header`
        Source header
    dsthdr : `astropy.io.fits.Header`
        Destination header
    keys : list
        List of keys

    """
    for key in keys:
        if key in srchdr:
            dsthdr[key] = srchdr[key], srchdr.comments[key]


@classmethod
def _get_apic_classes(cls):
    """
        Get the APIC classes used by this acitoolkit class.

        :returns: list of strings containing APIC class names
        """
    resp = ['eqptLC']
    return resp


def duration_str(s):
    """
    s: number of seconds
    Return a human-readable string.
    Example: 100 => "1m40s", 10000 => "2h46m"
    """
    if s is None:
        return None
    m = int(s // 60)
    if m == 0:
        return '%.1fs' % s
    s -= m * 60
    h = int(m // 60)
    if h == 0:
        return '%dm%ds' % (m, s)
    m -= h * 60
    d = int(h // 24)
    if d == 0:
        return '%dh%dm' % (h, m)
    h -= d * 24
    y = int(d // 365)
    if y == 0:
        return '%dd%dh' % (d, h)
    d -= y * 365
    return '%dy%dd' % (y, d)


@staticmethod
def default_is_cart():
    """Dont make this as a default as this would cause orders being placed
        from backend to be placed under default.
        """
    return False


@staticmethod
def query_plugin(pa, webapp, interface, name, *args, **kwargs):
    """Same as queryPlugins, but returns a single plugin instance as
        opposed an entire list. `name` will be used to identify that plugin.
        Positional and keyword arguments will be used to instantiate the plugin
        object.

        ``pa``,
            Platform object, whose base class is :class:`Pluggdapps`.

        ``webapp``,
            Web application object, plugin implementing
            :class:`pluggdapps.interfaces.IWebApp` interface. It is an
            optional argument, which must be passed ``None`` otherwise.

        ``interface``,
            :class:`pluggdapps.plugin.Interface` class or canonical form of
            interface-name.

        ``name``,
            plugin name in canonical format. For example, canonical name for
            plugin class `ConfigSqlite3DB` defined under `pluggdapps` package
            will be, `pluggdapps.ConfigSqlite3DB`.

        ``args`` and ``kwargs``,
            Positional and key-word arguments used to instantiate the plugin.

        If ``settings`` key-word argument is present, it will be used to
        override default plugin settings. Return a single Plugin instance.
        """
    from pluggdapps.plugin import PluginMeta
    if isinstance(interface, str):
        intrf = interface.lower()
        interface = PluginMeta._interfmap.get(intrf, {}).get('cls', None)
    cls = PluginMeta._implementers.get(interface, {}).get(name.lower(), None)
    return cls(pa, webapp, *args, **kwargs) if cls else None


def is_local_variable(variable_name):
    """
    Is a variable name a local or fully qualified?

    >>> is_local_variable('FOO')
    True
    >>> is_local_variable('HH__FOO')
    False

    :param variable_name: str
    :return: bool
    """
    return '__' not in variable_name


def discount_rewards(rewards, gamma=0.99):
    """Discounts an array of rewarwds, generally used after
    an episode ends and before training.

    Args:
        rewards (:obj:`list` of float): The rewards to be discounted.
        gamma (float, optional): Gamma in the reward discount function.
            Higher gamma = higher importance on later rewards.

    Returns:
        (:obj:`list` of float): List of the disounted rewards.

    Examples:
        >>> print([round(x) for x in discount_rewards([1, 2, 3], gamma=0.99)])
            [5.92, 4.97, 3.0]
    """
    new_rewards = [float(rewards[-1])]
    for i in reversed(range(len(rewards) - 1)):
        new_rewards.append(float(rewards[i]) + gamma * new_rewards[-1])
    return new_rewards[::-1]


@staticmethod
def process_line(line):
    """
        Moves numbers inside a vector whether this vector represents
        a row or a column.

        .. runpython::
            :showcode:

            from ensae_teaching_cs.td_1a.cp2048 import Game2048
            print(Game2048.process_line([0, 2, 2, 4]))
        """
    res = []
    for n in line:
        if n == 0:
            continue
        if len(res) == 0:
            res.append(n)
        else:
            prev = res[-1]
            if prev == n:
                res[-1] = 2 * n
            else:
                res.append(n)
    while len(res) < len(line):
        res.append(0)
    return res


def kSi_NBS_SMB64(TempK, Sal):
    """Silicate dissociation constant following SMB64."""
    return 4e-10


@staticmethod
def removeChildren(namespace, prefixes, extendedModule, referedModule):
    """
        This static method is used to remove children from the extended module.

        Parameters
        ----------
        namespace: string
            namespace of the referedModule.
        prefixes: list
            list of prefixes of objects to remove.
        extendedModule: ExtendedModule
            :class:`ExtendedModule` object to remove objects from.
        referedModule: module
            refered module object.
        """
    locals = extendedModule.locals
    to_remove = []
    for key in locals.keys():
        if not key.startswith('__'):
            for prefix in prefixes:
                if key.startswith(prefix):
                    to_remove.append(key)
    for key in to_remove:
        del locals[key]


def clean_completion_name(name: str, char: str) ->str:
    """Clean the completion name, stripping bad surroundings

    1. Remove all surrounding " and '. For
    """
    if char == "'":
        return name.lstrip("'")
    if char == '"':
        return name.lstrip('"')
    return name


def indent(string, prefix='    '):
    """Replicate python3's textwrap.indent for python2.

    Parameters
    ----------
    string : str
        Any string.
    prefix : str
        What to indent with.

    Returns
    -------
    str
        Indented string
    """
    out = ''
    for i in string.split('\n'):
        out += '{}{}\n'.format(prefix, i)
    return out


def pad_line(line):
    """Helper function to pad line to 80 characters in case it is shorter"""
    size_of_line = len(line)
    if size_of_line < 80:
        padding = 80 - size_of_line + 1
        line = line.strip('\n') + ' ' * padding + '\n'
    return line[:81]


def getLanguagesForTLD(tld):
    """Return the relevant languages for a top level domain.
        """


@staticmethod
def _regr_test_lookup():
    """
    NOTE: this test will hit the github web site unauthenticated. There are
          pretty tight rate limits for that so if you are re-running this
          test repeatedly, it will fail. To manually verify you can set
          user and token and re-run.

>>> user, token = None, None
>>> import tempfile, shlex, os, zipfile
>>> from eyap.core import github_comments
>>> t = github_comments.GitHubCommentThread(
...     'emin63', 'eyap', user, token, thread_id='1')
>>> i, c = t.lookup_comment_list()
>>> t.url_extras = '?per_page=1'
>>> more_i, more_c = t.lookup_comment_list()
>>> i == more_i and c == more_c
True
>>> t.url_extras = ''
        """


def dice_outcome_extractor(run):
    """Return the atmospheric temperature of the final state."""
    return run.states[-1].TATM


def _spin():
    """
    Spin in an infinite loop.

    :return: None
    """
    while True:
        pass


def generate_extension(extension):
    """ Generate a regex pattern to check lower and upper case extensions

    Thanks to https://stackoverflow.com/a/10148272

    Parameters
    ----------
    extension : str
        Extension to parse without the first dot

    Returns
    -------
    str
        Regex pattern

    Examples
    --------
    >>> generate_extensions("nes")
    '[nN][eE][sS]'
    """
    pattern = str()
    for character in extension:
        if not character == '.':
            pattern += f'[{character.lower()}{character.upper()}]'
        else:
            pattern += '.'
    return pattern


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

        :param FileTransfersPolicyChangedType val:
        :rtype: EventType
        """
    return cls('file_transfers_policy_changed', val)


@staticmethod
def new_field(field_name: str, ordering: int, **kwargs):
    """
        Fields have no unique ID.
        :param field_name:
        :param ordering:
        :param kwargs:
        :return:
        """
    field = dict([('name', field_name), ('rtl', False), ('sticky', False),
        ('media', []), ('ord', ordering), ('font', 'Arial'), ('size', 12)])
    for k, v in field.items():
        if k in kwargs.keys():
            field[k] = kwargs[k]
    return field


@classmethod
def from_tagger(cls, data):
    """Construct an instance a from CkipTagger format."""
    return cls(map(cls.item_class.from_tagger, data))


def stack_window(new_win, parent_win):
    """Elevate the new window to the topmost level of the stack of windows.

    :param new_win: the new window to be stacked on top.
    :type new_win: `tkinter.Toplevel`
    :param parent_win: the parent window of new_win.
    :type parent_win: `tkinter.Toplevel`
    """
    new_win.lift(parent_win)
    parent_win.attributes('-topmost', False)
    new_win.attributes('-topmost', True)
    new_win.attributes('-topmost', False)


def list_public_keys(StartTime=None, EndTime=None, NextToken=None):
    """
    Returns all public keys whose private keys were used to sign the digest files within the specified time range. The public key is needed to validate digest files that were signed with its corresponding private key.
    See also: AWS API Documentation

    :example: response = client.list_public_keys(
        StartTime=datetime(2015, 1, 1),
        EndTime=datetime(2015, 1, 1),
        NextToken='string'
    )

    :type StartTime: datetime
    :param StartTime: Optionally specifies, in UTC, the start of the time range to look up public keys for CloudTrail digest files. If not specified, the current time is used, and the current public key is returned.

    :type EndTime: datetime
    :param EndTime: Optionally specifies, in UTC, the end of the time range to look up public keys for CloudTrail digest files. If not specified, the current time is used.

    :type NextToken: string
    :param NextToken: Reserved for future use.

    :rtype: dict
    :return: {
        'PublicKeyList': [
            {
                'Value': b'bytes',
                'ValidityStartTime': datetime(2015, 1, 1),
                'ValidityEndTime': datetime(2015, 1, 1),
                'Fingerprint': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


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

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

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


def flatten(text):
    """
    Flatten the text:
    * make sure each record is on one line.
    * remove parenthesis
    """
    lines = text.split('\n')
    tokens = []
    for l in lines:
        if len(l) == 0:
            continue
        l = l.replace('\t', ' ')
        tokens += filter(lambda x: len(x) > 0, l.split(' ')) + ['']
    capturing = False
    captured = []
    flattened = []
    while len(tokens) > 0:
        tok = tokens.pop(0)
        if not capturing and len(tok) == 0:
            if len(captured) > 0:
                flattened.append(' '.join(captured))
                captured = []
            continue
        if tok.startswith('('):
            tok = tok.lstrip('(')
            capturing = True
        if capturing and tok.endswith(')'):
            tok = tok.rstrip(')')
            capturing = False
        captured.append(tok)
    return '\n'.join(flattened)


def active():
    """
        @return: True if this call is still active, False if it has been
                 called or cancelled.
        """


def _percent_to_integer(percent):
    """
    Internal helper for converting a percentage value to an integer
    between 0 and 255 inclusive.

    """
    return int(round(float(percent.split(u'%')[0]) / 100 * 255))


def str_to_unicode(x, encoding='utf-8'):
    """ Do it First after Loading some text """
    if isinstance(x, str):
        if not isinstance(x, str):
            return str(x, encoding)
    else:
        return x


def queryInteraction():
    """
        Return the current interaction.

        Return None if there is no interaction.
        """


def _next_token(iterable, comments):
    """
	Yields only non-whitespace, non-comment lines.
	"""
    for line in iterable:
        parts = iter(line.strip().split(None, 1))
        key = next(parts, None)
        if not key:
            continue
        elif key == b'COMMENT':
            comments.append(next(parts, b''))
        else:
            yield key, next(parts, None)


@staticmethod
def rc(host, port, db=0, blocking=False, **kwargs):
    """Return a *new* instance of Redis client.

        For a full list of kwargs see https://redis-py.readthedocs.io/en/latest/#redis.Connection.

        Args:
            host (str, optional): The REDIS host. Defaults to localhost.
            port (int, optional): The REDIS port. Defaults to 6379.
            db (int, optional): The REDIS db. Defaults to 0.
            blocking_pool (bool): Use BlockingConnectionPool instead of ConnectionPool.
            errors (str, kwargs): The REDIS errors policy (e.g. strict).
            max_connections (int, kwargs): The maximum number of connections to REDIS.
            password (str, kwargs): The REDIS password.
            socket_timeout (int, kwargs): The REDIS socket timeout.
            timeout (int, kwargs): The REDIS Blocking Connection Pool timeout value.

        Returns:
            Redis.client: An instance of redis client.
        """
    from .key_value_store import RedisClient
    return RedisClient(host=host, port=port, db=db, blocking=blocking, **kwargs
        ).client


@classmethod
def get_records_properties(cls, *args):
    """すべてのエッジレコードで、キーで選んだプロパティを辞書配列で返す

        Args:
            *args: 取り出したいキーの文字列配列

        Returns:
            dict: 辞書配列
        """
    query = f'MATCH (n:Node) , (n)-[r:Link]->() return r;'
    results = []
    with cls.DRIVER.session() as session:
        for record in session.run(query):
            props = {}
            for key in args:
                props[key] = record[0][key]
            results.append(props)
    return results


def stringint(k, n):
    """ returns string of integer k with n zeros padding
    (by placing zeros before to have n characters)

    :param k: integer to convert
    :param n: nb of digits for zero padding

    :return: string of length n containing integer k

    Example: 1 -> '0001'

    15 -> '0015'
    """
    encodingdigits = '{' + ':0{}'.format(int(n)) + '}'
    res = encodingdigits % k
    return res


def check_inequality(setup_version, pipfile_op, pipfile_version):
    """
    Checks for version compatibility when at least one specifies
    an explicitly disallowed version

    Args:
        setup_version (packaging.version.Version):
            The version specified in setup.py
        pipfile_op (str):
            The comparison operation specified in the Pipfile
        pipfile_version (packaging.version.Version):
            The version specified in the Pipfile
    Returns:
        bool: Whether or not the check passed
    """
    inclusive_ops = ['==', '>=', '=>', '<=']
    return not (pipfile_op in inclusive_ops and setup_version ==
        pipfile_version)


def possible(s):
    """Make possibility array."""
    from kaidoku.misc import box
    p = [[]] * 81
    b = box()
    for i in range(81):
        if s[i] == 0:
            p[i] = [1] * 9
            for i2 in b[i]:
                if s[i2] > 0:
                    p[i][s[i2] - 1] = 0
        else:
            p[i] = [0] * 9
            p[i][s[i] - 1] = 1
    return p


def pixels_to_EMU(value):
    """1 pixel = 9525 EMUs"""
    return int(value * 9525)


def mule_get_msg(signals=None, farms=None, buffer_size=65536, timeout=-1):
    """Block until a mule message is received and return it.

    This can be called from multiple threads in the same programmed mule.

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

    :param bool signals: Whether to manage signals.

    :param bool farms: Whether to manage farms.

    :param int buffer_size:

    :param int timeout: Seconds.

    :rtype: bytes|str

    :raises ValueError: If not in a mule.
    """


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


@classmethod
def fromfile(cls, fh, ntrack, decade=None, ref_time=None, verify=True):
    """Read a frame from a filehandle.

        Parameters
        ----------
        fh : filehandle
            To read header from.
        ntrack : int
            Number of Mark 4 bitstreams.
        decade : int or None
            Decade in which the observations were taken.  Can instead pass an
            approximate ``ref_time``.
        ref_time : `~astropy.time.Time` or None
            Reference time within 4 years of the observation time.  Used only
            if ``decade`` is not given.
        verify : bool, optional
            Whether to do basic verification of integrity.  Default: `True`.
        """
    header = cls._header_class.fromfile(fh, ntrack, decade=decade, ref_time
        =ref_time, verify=verify)
    payload = cls._payload_class.fromfile(fh, header=header)
    return cls(header, payload, verify=verify)


def getconfigstr(configitems, ui=None):
    """Given a set of configuration entries of the form (section, item, value),
       a string in the hgrc format is generated.
       Giving the 'ui' argument makes sure values are taken from that argument,
       ignoring the 'value' entries in configitems."""
    data = []
    configitems.sort()
    previoussection = None
    for section, item, value in configitems:
        if ui and not ui.hasconfig(section, item):
            continue
        if not previoussection or section != previoussection:
            data.append(b'[%s]' % section)
        previoussection = section
        if ui:
            value = ui.config(section, item)
        if value is None:
            value = ''
        data.append(b'%s=%s' % (item, value))
    if not data:
        return ''
    data.append(b'')
    return b'\n'.join(data)


def frac_to_b(num=0.0, width=8, endian='big'):
    """
    Convert a positive float which is less than 1.0 to a binary string.
    The returned value is 0xFF*num represented as a binary string
      when the width is 8 (default).
    This is useful for simulating fixed point arithmetic.

    The endianess is little by default but can be set to big to return a
      bit reversal.

    The returned string is can be converted to an int in Python by setting
      the base to 2 e.g.:'int( frac_to_b(...) , 2 )'.

    E.g. frac_to_b() returns 00000000
         frac_to_b(0.3, 5) returns 01010
         frac_to_b(0.5, width=10, endian='little') returns 0000000001
    """
    assert type(num
        ) is float, 'Invalid type : num : Expected %(expect)s : %(actual)s' % {
        'expect': str(type(float())), 'actual': str(type(num))}
    assert num < 1.0, 'Invalid value : num : Expected %(expect)s : %(actual)s' % {
        'expect': 'num < 1.0', 'actual': str(num)}
    assert type(width
        ) is int, 'Invalid type : width : Expected %(expect)s : %(actual)s' % {
        'expect': str(type(int())), 'actual': str(type(width))}
    assert width >= 0, 'Invalid value : width : Expected %(expect)s : %(actual)s' % {
        'expect': 'width >= 0', 'actual': str(width)}
    assert type(endian
        ) is str, 'Invalid type : endian : Expected %(expect)s : %(actual)s' % {
        'expect': str(type(str())), 'actual': str(type(endian))}
    assert endian == 'little' or endian == 'big', 'Invalid value: endian : Expected %(expect)s : %(actual)s' % {
        'expect': '"little" OR "big"', 'actual': str(endian)}
    a = int(round(num * 2 ** width))
    b = ''
    while a:
        b += str(a % 2)
        a = int(a / 2)
    t = b[::-1]
    del a, b
    if len(t) > width:
        t = t[:width]
    else:
        t = '0' * (width - len(t)) + t
    if endian == 'little':
        t = t[::-1]
    return t


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

        :param BinderRemoveSectionDetails val:
        :rtype: EventDetails
        """
    return cls('binder_remove_section_details', val)


@staticmethod
def _get_index_keys(formatted_columns):
    """Get columns that are index key"""
    index_keys = list()
    for column in formatted_columns:
        column_name = column[0]
        column_is_primary_key = column[3]
        if not column_is_primary_key and column_name.lower().find('id', 0, 2
            ) != -1:
            index_keys.append(column_name)
    return index_keys


def arch_mapper(arch, package):
    """
    Update package download_url using FreeBSD arch information and return package.
    """
    package.download_url = ('https://pkg.freebsd.org/{}/latest/All/{}-{}.txz'
        .format(arch, package.name, package.version))
    return package


def summarize_ancestral_prob_df(df):
    """Combines multiple entries that have identical ancestral species MRCA
    and population MRCA states into one using pandas groupby.

    Parameters
    ----------
    df : pandas.DataFrame

    Returns
    -------
    pandas.DataFrame

    """
    df = df.groupby(['pattern', 'allele_count_a', 'allele_count_b',
        'anc_species_state', 'anc_pop_state', 'anc_species_pop']).apply(lambda
        x: x['joint_prob'].sum()).reset_index().set_index(['pattern',
        'allele_count_a', 'allele_count_b'])
    df.columns = ['anc_species_state', 'anc_pop_state', 'anc_species_pop',
        'prob']
    return df


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

        :param WebSessionLogInfo val:
        :rtype: AccessMethodLogInfo
        """
    return cls('enterprise_console', val)


@staticmethod
def configuration():
    """Return the configuration object.

        Applicable to the ThermostatController, SecurityControlPanel, ModeController, RangeController,
        and EventDetectionSensor.
        """
    return []


def tr_tet_tr_oct_cubo_coord_test(x, y, z):
    """Test for coordinate in truncated tetrahedron/truncated octahedron/
    cuboctahedron grid"""
    x = abs(x) % 6
    y = abs(y) % 6
    z = abs(z) % 6
    if x > 3:
        x = 6 - x
    if y > 3:
        y = 6 - y
    if z > 3:
        z = 6 - z
    dist2 = x ** 2 + y ** 2
    return z % 6 == 0 and (dist2 == 2 or dist2 == 8) or z % 6 == 1 and (
        dist2 == 1 or dist2 == 13) or z % 6 == 2 and (dist2 == 4 or dist2 == 10
        ) or z % 6 == 3 and dist2 == 5


@classmethod
def resume_all_sound(cls):
    """For all live sprites, resume any sound that was paused"""
    for sprite in (cls.live_sprites + cls._dying_loudly):
        sprite.resume_sound()


def txins(txs):
    """set of inputs spent by transactions"""
    result = set()
    for tx in txs:
        result |= tx.inputs
    return result


@classmethod
def from_activity(cls, activity, commit=None):
    """Create an instance from the activity."""
    from .agents import SoftwareAgent
    agent = SoftwareAgent.from_commit(activity.commit)
    return cls(plan=activity.__association_cls__(commit=commit or activity.
        commit, client=activity.client, path=activity.path, activity=
        activity), agent=agent, id=activity._id + '/association')


def create_input(data):
    """
    Take sentence data and return an input for
    the training or the evaluation function.
    """
    inputs = list()
    inputs.append(data['chars'])
    inputs.append(data['segs'])
    inputs.append(data['tags'])
    return inputs


def featurelist2map(lst):
    """
    create a dictionary for a list of features
    for each name one name one entry is created in the map containing
    1. pos : the position of the features with the name
    2. sgn : a sorted list of signs of the features with the name
    3. cnt : the number of features with the name
    3. scr : the sum of the scores of features with the name

    @param[in] lst a list of features
    """
    mp = {}
    for f in lst:
        if not f.name in mp:
            mp[f.name] = {}
            mp[f.name]['pos'] = set()
            mp[f.name]['sgn'] = None
            mp[f.name]['cnt'] = 0
            mp[f.name]['scr'] = 0
            mp[f.name]['start'] = 100000000
            mp[f.name]['stop'] = -1
            mp[f.name]['type'] = ''
        if f.strand > 0:
            mp[f.name]['start'] = min(f.start, mp[f.name]['start'])
            mp[f.name]['stop'] = max(f.stop, mp[f.name]['stop'])
        else:
            mp[f.name]['start'] = min(f.start, mp[f.name]['stop'])
            mp[f.name]['stop'] = max(f.stop, mp[f.name]['start'])
        mp[f.name]['pos'] = mp[f.name]['pos'].union(set(range(f.start, f.
            stop + 1)))
        if mp[f.name]['sgn'] == None or mp[f.name]['sgn'] == f.strand:
            mp[f.name]['sgn'] = f.strand
        else:
            f.strand = 0
        mp[f.name]['cnt'] += 1
        if f.score == None:
            mp[f.name]['scr'] += 0
        else:
            mp[f.name]['scr'] += f.score * (f.stop - f.start + 1)
        mp[f.name]['type'] = f.type
    return mp


def decode_response(enc_response, task):
    """ Decodes an encoded syllogistic response by transforming it to the
    corresponding tuple representation and inserting the appropriate terms.

    Parameters
    ----------
    enc_response : str
        Encoded syllogistic response (e.g., 'Aac').

    task : list(str)
        Syllogistic task in the tuple list representation (e.g.,
        [['Some', 'models', 'managers'], ['All', 'models', 'clerks']]).

    Returns
    -------
    list
        List representation of the response to decode.

    """
    if enc_response == 'NVC':
        return [['NVC']]
    if enc_response == ['NVC']:
        return [enc_response]
    if enc_response == [['NVC']]:
        return enc_response
    obj_a = set(task[0][1:]) - set(task[1][1:])
    obj_c = set(task[1][1:]) - set(task[0][1:])
    quant = enc_response[0].replace('A', 'All').replace('I', 'Some').replace(
        'O', 'Some not').replace('E', 'No')
    if enc_response[1:] == 'ac':
        return [[quant, list(obj_a)[0], list(obj_c)[0]]]
    return [[quant, list(obj_c)[0], list(obj_a)[0]]]


@staticmethod
def filenames_diff_cmd(r):
    """Get the names of the py files in diff."""
    return ['hg', 'diff', '--stat', '-r', r.rev]


def empty_adapter(_stream, matcher):
    """
    There is a fundamental mismatch between regular expressions and the
    recursive descent parser on how empty matchers are handled.  The main
    parser uses empty lists; regexp uses an empty string.  This is a hack
    that converts from one to the other.  I do not see a better solution.
    """
    results, stream_out = matcher()
    if results == ['']:
        results = []
    return results, stream_out


def interaction_preset_add(name: str='', remove_active: bool=False):
    """Add or remove an Application Interaction Preset

    :param name: Name, Name of the preset, used to make the path name
    :type name: str
    :param remove_active: remove_active
    :type remove_active: bool
    """
    pass


def parsing_set_all_offsset(response, tips=False):
    """
    功能：解析设置所有舵偏移值的回应信息
    输入：
    response：机器人返回的设置所有舵机偏移值的回应信息
    返回：
    success:判定是否设置成功。数据格式bool
    """
    if response == b'':
        print('回应内容为空，请重新获取回应！')
        return
    success = True
    cmd_len = response[2]
    cmd_type = response[3]
    if cmd_type != 39:
        print('解析类型错误，请检查回应内容，当前命令类型为%d' % cmd_type)
        return 0
    feedback = response[4:cmd_len - 1]
    for i in range(len(feedback)):
        if feedback[i] != 0:
            success = False
            if feedback[i] == 1:
                print('错误：%d号舵机的id值错误！' % (i + 1))
            elif feedback[i] == 2:
                print('错误：%d号舵机没有应答！' % (i + 1))
    if tips:
        ss = '成功' if success else '失败'
        print('设置所有舵机偏移值命令执行%s！' % ss)
    return success


def drawWire(canvas, points):
    """
    Draw the edges between the provided points.
    No labels.
    An edge is implied between consecutive vertices.
    No fill.
    """
    size = len(points)
    print(size)
    print
    for i in range(size):
        print(i, (i + 1) % size)
        p0 = points[i]
        p1 = points[(i + 1) % size]
        x0 = p0[0]
        y0 = p0[1]
        x1 = p1[0]
        y1 = p1[1]
        canvas.line([(x0, y0), (x1, y1)])


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


@classmethod
def create_module(cls, spec):
    """
        Module creator. Returning None causes Python to use the default module creator.
        """
    return None


@classmethod
def active(cls):
    """Return the current resident application object."""
    return cls._GLOBAL


def print_json_errors(res):
    """
    from a dimcli.Dataset object, print out an errors summary
    """
    if 'errors' in res.json.keys():
        if 'query' in res.json['errors']:
            print(res.json['errors']['query']['header'].strip('\n'))
            for key in res.json['errors']['query']['details']:
                print(key)
        else:
            print(res.json['errors'])


def shallow_flatten_uniq(list_of_lists):
    """Helper function returns a 1D list of unique items in a 2D list"""
    new_list = []
    for list_ in list_of_lists:
        for item in list_:
            if item not in new_list:
                new_list.append(item)
    return new_list


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

        :param NoteSharedDetails val:
        :rtype: EventDetails
        """
    return cls('note_shared_details', val)


def version_query_url(host, ifo, name):
    """Returns the URL to use in querying for flag versions

    Parameters
    ----------
    host : `str`
        the URL of the target DQSEGDB2 host

    ifo : `str`
        the interferometer prefix

    name : `str`
        the name of the flag

    Returns
    -------
    url : `str`
        the full REST URL to query for information

    Examples
    --------
    >>> from dqsegdb2.api import version_query_url
    >>> print(version_query_url('https://segments.ligo.org', 'G1',
    ...                         'GEO-SCIENCE'))
    'https://segments.ligo.org/dq/G1/GEO-SCIENCE'
    """
    return '{host}/dq/{ifo}/{name}'.format(host=host, ifo=ifo, name=name)


def is_public_ip(ip: str):
    """
    Returns whether it is a public IP address

    :param str ip: String
    :return: bool
    """
    try:
        import IPy
        if 'PUBLIC' == IPy.IP(ip).iptype():
            return True
        return False
    except:
        return False


def get_attrname(name):
    """Return the mangled name of the attribute's underlying storage."""
    return '_obj_' + name


def check_if_empty_list(response) ->bool:
    """This method is used to check if the result in a dict is an empty list

    :param response: Response get from the centreon server
    :type response: dict

    :return: Returns True, if response["result"] is an empty list
    :rtype: bool
    """
    if response:
        if 'result' in response:
            if isinstance(response['result'], list):
                if len(response['result']) == 0:
                    return True
    return False


def schema_defines_object(schema):
    """
    If properties are defined for a schema, it will translate to an instance of
    `Object`.
    """
    return schema.properties and schema.type_ in ('object', None
        ) and not schema.additional_properties


def is_indel(reference_bases, alternate_bases):
    """ Return whether or not the variant is an INDEL """
    if len(reference_bases) > 1:
        return True
    for alt in alternate_bases:
        if alt is None:
            return True
        elif len(alt) != len(reference_bases):
            return True
    return False


@classmethod
def print_convergence(cls, progress, true):
    """Print the progress of a model over each iteration.

        -- {progress} should be a list of {scipy.stats.norm} distributions,
           such as the one returned by {predict_from_trace}.
        -- {true} should be the true, final converged value, which is used
           in the output for illustrating the convergence progress.
        """
    print(' %2s %6s  %6s  %7s  %9s  %6s' % ('It', 'PDF', 'CDF', 'Error',
        'PostMean', 'Stdev'))
    for i, d in enumerate(progress):
        print('%2d: %6.4f  %6.4f  %7.4f  %9.4f  %6.4f' % (i, d.pdf(true), d
            .cdf(true), (d.mean() - true) / true, d.mean(), d.std()))


def boolean_flag(name, configurable, set_help='', unset_help=''):
    """Helper for building basic --trait, --no-trait flags.

    Parameters
    ----------

    name : str
        The name of the flag.
    configurable : str
        The 'Class.trait' string of the trait to be set/unset with the flag
    set_help : unicode
        help string for --name flag
    unset_help : unicode
        help string for --no-name flag

    Returns
    -------

    cfg : dict
        A dict with two keys: 'name', and 'no-name', for setting and unsetting
        the trait, respectively.
    """
    set_help = set_help or 'set %s=True' % configurable
    unset_help = unset_help or 'set %s=False' % configurable
    cls, trait = configurable.split('.')
    setter = {cls: {trait: True}}
    unsetter = {cls: {trait: False}}
    return {name: (setter, set_help), ('no-' + name): (unsetter, unset_help)}


@classmethod
def maybe_readable_combine_ids(cls, ids):
    """Generates combined id for a set of ids, but if the set is a single id, just use that.

        :API: public
        """
    ids = list(ids)
    return ids[0] if len(ids) == 1 else cls.combine_ids(ids)


def rtuFrameSize(data, byte_count_pos):
    """ Calculates the size of the frame based on the byte count.

    :param data: The buffer containing the frame.
    :param byte_count_pos: The index of the byte count in the buffer.
    :returns: The size of the frame.

    The structure of frames with a byte count field is always the
    same:

    - first, there are some header fields
    - then the byte count field
    - then as many data bytes as indicated by the byte count,
    - finally the CRC (two bytes).

    To calculate the frame size, it is therefore sufficient to extract
    the contents of the byte count field, add the position of this
    field, and finally increment the sum by three (one byte for the
    byte count field, two for the CRC).
    """
    return data[byte_count_pos][0] + byte_count_pos + 3


def instantiate(repo, name=None, filename=None):
    """
    Instantiate the generator and filename specification
    """
    default_transformers = repo.options.get('transformer', {})
    transformers = {}
    if name is not None:
        if name in default_transformers:
            transformers = {name: default_transformers[name]}
        else:
            transformers = {name: {'files': []}}
    else:
        transformers = default_transformers
    input_matching_files = None
    if filename is not None:
        input_matching_files = repo.find_matching_files([filename])
    for t in transformers:
        for k in transformers[t]:
            if 'files' not in k:
                continue
            if k == 'files' and input_matching_files is not None:
                transformers[t][k] = input_matching_files
            elif transformers[t][k] is None or len(transformers[t][k]) == 0:
                transformers[t][k] = []
            else:
                matching_files = repo.find_matching_files(transformers[t][k])
                transformers[t][k] = matching_files
    return transformers


@classmethod
def parse_config(cls, peer_config):
    """
        Imports Peer from config.
        :param peer_config:
        :return:
        """
    instance = cls()
    instance._config['Peer'] = peer_config['Peer']
    for key, value in peer_config.items('Peer'):
        setattr(instance, key, value)
    return instance


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

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


@classmethod
def build(cls, **kwargs):
    """Build the dict, set the object attribut and return it."""
    ret = dict()
    attributs = cls._clean_attr()
    for one_attribut in attributs:
        if one_attribut in kwargs:
            value = kwargs[one_attribut]
        else:
            value = getattr(cls, one_attribut)
        ret.update({one_attribut: value})
    return ret


def cluster_of_word(vocab, clusters, word):
    """Dice a que cluster pertenece a la palabra word.
    """
    indice = vocab.index(word)
    return clusters[indice]


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

		Parameters:
			track (dict): A library track dict.

		Returns:
			dict: A mutation dict.
		"""
    return track


def object_data_add(context: 'bpy.types.Context', obdata: 'bpy.data',
    operator: 'bpy.types.Operator'=None, use_active_layer=True, name: str=None
    ) ->'bpy.types.ObjectBase':
    """Add an object using the view context and preference to to initialize the location, rotation and layer.

    :param context: The context to use.
    :type context: 'bpy.types.Context'
    :param obdata: the data used for the new object.
    :type obdata: 'bpy.data'
    :param operator: The operator, checked for location and rotation properties.
    :type operator: 'bpy.types.Operator'
    :param name: Optional name
    :type name: str
    :return:  the newly created object in the scene.
    """
    pass


def begin():
    """
        Start a new transaction.
        """


def A(n):
    """ A number consisting entirely of ones is called a repunit.
    We shall define R(k) to be a repunit of length k; for example,
    R(6) = 111111.

    Given that n is a positive integer and GCD(n, 10) = 1, it can be shown
    that there always exists a value, k, for which R(k) is divisible by n,
    and let A(n) be the least such value of k; for example, A(7) = 6 and
    A(41) = 5.

    The least value of n for which A(n) first exceeds ten is 17. """
    rep = 1
    k = 1
    while rep % n != 0:
        k += 1
        rep = (rep * 10 + 1) % n
    return k


def most_common(lst: list):
    """Used by consensus"""
    return max(set(lst), key=lst.count)


def unset_permission_for_principal(permission_id, principal_id):
    """Remove the permission (either denied or allowed) from the
        principal.
        """


def _computer_create_temp_file(transport, scheduler, authinfo):
    """
    Internal test to check if it is possible to create a temporary file
    and then delete it in the work directory

    :note: exceptions could be raised

    :param transport: an open transport
    :param scheduler: the corresponding scheduler class
    :param authinfo: the AuthInfo object (from which one can get computer and aiidauser)
    :return: tuple of boolean indicating success or failure and an optional string message
    """
    import tempfile
    import datetime
    import os
    file_content = "Test from 'verdi computer test' on {}".format(datetime.
        datetime.now().isoformat())
    workdir = authinfo.get_workdir().format(username=transport.whoami())
    try:
        transport.chdir(workdir)
    except IOError:
        transport.makedirs(workdir)
        transport.chdir(workdir)
    with tempfile.NamedTemporaryFile(mode='w+') as tempf:
        fname = os.path.split(tempf.name)[1]
        remote_file_path = os.path.join(workdir, fname)
        tempf.write(file_content)
        tempf.flush()
        transport.putfile(tempf.name, remote_file_path)
    if not transport.path_exists(remote_file_path):
        return False, 'failed to create the file `{}` on the remote'.format(
            remote_file_path)
    handle, destfile = tempfile.mkstemp()
    os.close(handle)
    try:
        transport.getfile(remote_file_path, destfile)
        with open(destfile, encoding='utf8') as dfile:
            read_string = dfile.read()
        if read_string != file_content:
            message = (
                'retrieved file content is different from what was expected')
            message += '\n  Expected: {}'.format(file_content)
            message += '\n  Retrieved: {}'.format(read_string)
            return False, message
    finally:
        os.remove(destfile)
    transport.remove(remote_file_path)
    return True, None


def is_equivalent(step1, step2):
    """Compare steps, ignoring their priority."""
    return step1.get('interface') == step2.get('interface') and step1.get(
        'step') == step2.get('step')


def noCheck(command, status, output, error):
    """ Do no check result"""
    return


def correct_pad(backend, inputs, kernel_size):
    """Returns a tuple for zero-padding for 2D convolution with downsampling.
    # Arguments
        input_size: An integer or tuple/list of 2 integers.
        kernel_size: An integer or tuple/list of 2 integers.
    # Returns
        A tuple.
    """
    img_dim = 2 if backend.image_data_format() == 'channels_first' else 1
    input_size = backend.int_shape(inputs)[img_dim:img_dim + 2]
    if isinstance(kernel_size, int):
        kernel_size = kernel_size, kernel_size
    if input_size[0] is None:
        adjust = 1, 1
    else:
        adjust = 1 - input_size[0] % 2, 1 - input_size[1] % 2
    correct = kernel_size[0] // 2, kernel_size[1] // 2
    return (correct[0] - adjust[0], correct[0]), (correct[1] - adjust[1],
        correct[1])


@classmethod
def from_vizier_table(cls, table_id, nside=256):
    """
        Creates a `~mocpy.moc.MOC` object from a VizieR table.

        **Info**: This method is already implemented in `astroquery.cds <https://astroquery.readthedocs.io/en/latest/cds/cds.html>`__. You can ask to get a `mocpy.moc.MOC` object
        from a vizier catalog ID.

        Parameters
        ----------
        table_id : str
            table index
        nside : int, optional
            256 by default

        Returns
        -------
        result : `~mocpy.moc.MOC`
            The resulting MOC.
        """
    nside_possible_values = 8, 16, 32, 64, 128, 256, 512
    if nside not in nside_possible_values:
        raise ValueError('Bad value for nside. Must be in {0}'.format(
            nside_possible_values))
    result = cls.from_ivorn('ivo://CDS/' + table_id, nside)
    return result


def OpenCableParametersForm(*args, **kwargs):
    """ Stub Anduin function."""
    print('OpenCableParametersForm', args, kwargs)


def clean_dict(mydict, keep_keys=None, rm_keys=None):
    """
    remove unwanted items in dicts
    """
    if keep_keys is not None:
        for k in list(mydict.keys()):
            if k not in keep_keys:
                del mydict[k]
    if rm_keys is not None:
        for k in list(mydict.keys()):
            if k in rm_keys:
                del mydict[k]