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

    The ".dev0" means dirty.

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


def crf_preprocess_candidates(candidates):
    """Receive annotated candidates and return features and labels list"""
    features = []
    labels = []
    for candidate in candidates:
        candidate_features = []
        candidate_labels = []
        for token_features, label in candidate:
            candidate_features.append(token_features)
            candidate_labels.append(label)
        features.append(candidate_features)
        labels.append(candidate_labels)
    return features, labels


def p_testlist_comp_2(p):
    """testlist_comp : test"""
    p[0] = p[1]


def from_iterable(iterables):
    """
    Backport of itertools.chain.from_iterable
    """
    for it in iterables:
        for element in it:
            yield element


def parse_rrset_record_values(e_resource_records):
    """
    Used to parse the various Values from the ResourceRecords tags on
    most rrset types.

    :param lxml.etree._Element e_resource_records: A ResourceRecords tag
        beneath a ResourceRecordSet.
    :rtype: list
    :returns: A list of resource record strings.
    """
    records = []
    for e_record in e_resource_records:
        for e_value in e_record:
            records.append(e_value.text)
    return records


@classmethod
def print_dict(cls, dict_IN, sort_by_key_IN=True, prefix_IN='----> ',
    separator_IN=' : ', line_separator_IN='\n', suffix_IN=None):
    """
        Accepts dictionary, optional "sort by key" flag.  Retrieves name/key
            list.  If sorted, sorts name/key list.  Then, loops over the
            name/key list, for each name retrieving associated value and
            printing the two.
        """
    cls.render_dict_string(dict_IN=dict_IN, sort_by_key_IN=sort_by_key_IN,
        prefix_IN=prefix_IN, separator_IN=separator_IN, suffix_IN=suffix_IN,
        line_separator_IN=line_separator_IN, print_items_IN=True)


def has_decorator(text, pre_decor='"', post_decor='"'):
    """
    Determine if a string is delimited by some characters (decorators).

    Args:
        text (str): The text input string.
        pre_decor (str): initial string decorator.
        post_decor (str): final string decorator.

    Returns:
        has_decorator (bool): True if text is delimited by the specified chars.

    Examples:
        >>> has_decorator('"test"')
        True
        >>> has_decorator('"test')
        False
        >>> has_decorator('<test>', '<', '>')
        True
    """
    return text.startswith(pre_decor) and text.endswith(post_decor)


def in_zip_file_path(fileinfo, filename):
    """makes a path to be used use inside of zip
        """


def _check_valid(key, val, valid):
    """Helper to check valid options"""
    if val not in valid:
        raise ValueError('%s must be one of %s, not "%s"' % (key, valid, val))


def remove_invalid_char(text):
    """去除字符串中的无效字符，一般用于保存文件时保证文件名的有效性.

    :param str text: 待处理的字符串
    :return: 处理后的字符串
    :rtype: str
    """
    invalid_char_list = ['/', '\\', ':', '*', '?', '"', '<', '>', '|', '\n']
    res = ''
    for char in text:
        if char not in invalid_char_list:
            res += char
    return res


def add_sizers(cls):
    """To be implemented in derived class."""


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

        :param FileRequestsEmailsRestrictedToTeamOnlyType val:
        :rtype: EventType
        """
    return cls('file_requests_emails_restricted_to_team_only', val)


@staticmethod
def computeMass(object):
    """
        Calculates the 'mass' of an object. in FreeCAD < 15, all objects had a mass.
        in FreeCAD >=15, faces no longer have mass, but instead have area.
        """
    if object.wrapped.ShapeType == 'Face':
        return object.wrapped.Area
    else:
        return object.wrapped.Mass


def get_genus_label(entry):
    """Get the genus name of an assembly summary entry."""
    return entry['organism_name'].split(' ')[0]


def psi_Ca_H_OH_HMW84(T, P):
    """c-c'-a: calcium hydrogen hydroxide [HMW84]."""
    psi = 0
    valid = T == 298.15
    return psi, valid


def variance_explained_score(clu, X):
    """Calculate the degree of variance explained by the latent
    clustering, i.e. Calinski-Harabasz score.

    Parameters
    ----------
    clu : list of frozensets
        Resource groups in an organizational model.
    X : DataFrame
        The corresponding resource feature table used for deriving the
        resource groups.

    Returns
    -------
    float
        The result score representing the degree of variance explained.

    Notes
    -----
    This is merely a wrap-up of function
    `sklearn.metrics.calinski_harabasz_score
    <https://scikit-learn.org/stable/modules/generated/sklearn.metrics.calinski_harabasz_score.html>`_.
    """
    from sklearn.metrics import calinski_harabasz_score
    resources = list(X.index)
    labels = [-1] * len(resources)
    for ig, g in enumerate(clu):
        for r in g:
            labels[resources.index(r)] = ig
    return calinski_harabasz_score(X.values, labels)


def replace(image, to_replace, to_add):
    """ Replace one band of the image with a provided band

    :param to_replace: name of the band to replace. If the image hasn't got
        that band, it will be added to the image.
    :type to_replace: str
    :param to_add: Image (one band) containing the band to add. If an Image
        with more than one band is provided, it uses the first band.
    :type to_add: ee.Image
    :return: Same Image provided with the band replaced
    :rtype: ee.Image
    """
    band = to_add.select([0])
    bands = image.bandNames()
    resto = bands.remove(to_replace)
    img_resto = image.select(resto)
    img_final = img_resto.addBands(band)
    return img_final


def getAvailableTLDs():
    """Return a sequence of country code top level domains.
        """


def check_elf(_filename, signature):
    """ Check for an ELF signature."""
    return signature == b'\x7fELF'


def to_curie(uri, namespaces, seperator=':', explicit=False):
    """Converts a URI to a CURIE using the prefixes defined in namespaces. If
    there is no matching prefix, return the URI unchanged.

    namespaces - a dictionary of prefix -> namespace mappings.

    separator - the character to use as the separator between the prefix and
                the local name.

    explicit - if True and the URI can be abbreviated, wrap the abbreviated
               form in []s to indicate that it is definitely a CURIE."""
    matches = []
    for prefix, namespace in namespaces.items():
        if uri.startswith(namespace):
            matches.append((prefix, namespace))
    if len(matches) > 0:
        prefix, namespace = sorted(matches, key=lambda pair: -len(pair[1]))[0]
        if explicit:
            return '[' + uri.replace(namespace, prefix + seperator) + ']'
        else:
            return uri.replace(namespace, prefix + seperator)
    return uri


@staticmethod
def distance(stop):
    """Key to sort a list of stops by their Distance
        """
    return stop.distance


def cindex(prediction, survtime, survevent):
    """Function to compute the concordance index for a risk prediction,
    i.e., the probability that, for a pair of randomly chosen
    comparable samples, the sample with the higher risk prediction
    will experience an event before the other sample or belongs to a
    higher binary class.

    :param prediction: a vector of risk predictions.
    :param survtime: a vector of event times.
    :param survevent: a vector of event occurence indicators (True and False).

    ::

        >>> from dreamtools.core.cindex import cindex
        >>> print(cindex([0, 1, 3,4], [0, 4, 3, 1], [True]*4))
        0.5
        >>> print(cindex([0, 1, 3,4], [0, 1, 3, 4], [True]*4))
        0.0

    """
    count = 0
    score = 0
    N = len(survtime)
    for i in range(0, N - 1):
        for j in range(i + 1, N):
            if survevent[i] == True and survevent[j] == True or survevent[i
                ] == True and survtime[j] >= survtime[i] or survevent[j
                ] == True and survtime[i] >= survtime[j]:
                count = count + 2
                if survtime[i] < survtime[j]:
                    if prediction[i] > prediction[j]:
                        score = score + 2
                    if prediction[i] == prediction[j]:
                        score = score + 1
                if survtime[i] == survtime[j]:
                    if prediction[i] == prediction[j]:
                        score = score + 2
                if survtime[i] > survtime[j]:
                    if prediction[i] < prediction[j]:
                        score = score + 2
                    if prediction[i] == prediction[j]:
                        score = score + 1
    return score / float(count)


def fields(initial=None, editable=None, display=None):
    """ Iterator over the fields of the available properties
        """


def _validate_output_feature_name_from_train_stats(output_feature_name,
    train_stats_per_model):
    """Validate prediction output_feature_name from model train stats and return it as list.

    :param output_feature_name: output_feature_name containing ground truth
    :param train_stats_per_model: list of per model train stats
    :return output_feature_names: list of output_feature_name(s) containing ground truth
    """
    output_feature_names_set = set()
    for ls in train_stats_per_model:
        for _, values in ls.items():
            for key in values:
                output_feature_names_set.add(key)
    try:
        if output_feature_name in output_feature_names_set:
            return [output_feature_name]
        else:
            return output_feature_names_set
    except TypeError:
        return output_feature_names_set


@classmethod
def getNextPlayer(cls, player=None):
    """
		Return the player who will play after the given player. If player is
		None, first player is returned.

		:param player:  Original player (Player)
		:return:  Next player (Player)

		"""
    if len(cls._player_list) < cls.min_num_of_players:
        raise RuntimeError('Minimum number of player is not reached')
    if player is None:
        return cls._player_list[0]
    next_player_index = (cls._player_list.index(player) + 1) % len(cls.
        _player_list)
    return cls._player_list[next_player_index]


def weights_by_size(left_node, right_node):
    """Calculate the relative size of two nodes

    Parameters
    ----------
    left_node : :class:`~idpflex.cnextend.ClusterNodeX`
        One of the two sibling nodes
    right_node : :class:`~idpflex.cnextend.ClusterNodeX`
        One of the two sibling nodes

    Returns
    -------
    tuple
        Weights representing the relative populations of two nodes

    """
    w = float(left_node.count) / (left_node.count + right_node.count)
    return w, 1 - w


@classmethod
def fromkeys(cls, seq, value=None):
    """Create a new :class:`AttributeConfiguration` with keys in ``seq`` and
        values in ``value``.

        :param seq: Iterable of keys
        :type seq: iterable

        :param value: Iterable of values
        :type value: iterable

        :rtype: :class:`AttributeConfiguration`

        """
    return cls(zip(seq, value))


def unpad(string):
    """Un-pads a string previously padded with the `pad` function."""
    return string[:-ord(string[len(string) - 1:])]


def readable_size(n):
    """Return a readable size string."""
    sizes = ['K', 'M', 'G']
    fmt = ''
    size = n
    for i, s in enumerate(sizes):
        nn = n / 1000 ** (i + 1)
        if nn >= 1:
            size = nn
            fmt = sizes[i]
        else:
            break
    return '%.2f%s' % (size, fmt)


def comparable(a, b):
    """
    Tests if two sets of comparable.

    Parameters
    ----------
    a : set
        One set.
    b : set
        The other set.

    Returns
    -------
    comp : bool
        True if `a` is a subset of `b` or vice versa.
    """
    return a < b or b < a


def convert_typestring_to_api_native(typestring):
    """
        This function converts the typestring representation of an api type to
        the appropriate graphql object.
    """
    import graphene
    return getattr(graphene, typestring)


def on_connect_failed():
    """ Called when the client connect failed"""
    print('connect failed...')


def getChemblLigandByDrugName(drugname, returnSmile=False):
    """
        Returns a SmallMol object of a ligand by its drug name. This molecule is retrieve from Chembl. It is possible to
        return also the smile of the ligand.

        Parameters
        ----------
        drugname: str
            The drug name
        returnSmile: bool
            If True, the smile is returned

        Returns
        -------
        sm: moleculekit.smallmol.smallmol.SmallMol
            The SmallMol object

        smile: str
            The smile

        Example
        -------
        >>> sm = getChemblLigandByDrugName('paracetamol')  # doctest: +SKIP
        >>> sm.numAtoms  # doctest: +SKIP
        20
        >>> sm, smile = getChemblLigandByDrugName('paracetamol', returnSmile=True)  # doctest: +SKIP
        >>> smile  # doctest: +SKIP
        'CC(=O)Nc1ccc(O)cc1'
        """
    from moleculekit.smallmol.smallmol import SmallMol
    try:
        from chembl_webresource_client.new_client import new_client
    except ImportError as e:
        raise ImportError(
            'You need to install the chembl_webresource package to use this function. Try using `conda install -c chembl chembl_webresource_client`.'
            )
    drug = new_client.drug
    results = drug.filter(synonyms__icontains=drugname)
    chembl_id = None
    if len(results) == 0:
        return None
    found = False
    for drug_chembl in results:
        for name in drug_chembl['synonyms']:
            matched = [(True) for na in name.split() if na.lower() ==
                drugname.lower()]
            if sum(matched) != 0:
                found = True
                chembl_id = drug_chembl['molecule_chembl_id']
                break
            if found:
                break
    molecule = new_client.molecule
    molecule_chembl = molecule.get(chembl_id)
    smi = molecule_chembl['molecule_structures']['canonical_smiles']
    sm = SmallMol(smi)
    if returnSmile:
        return sm, smi
    return sm


def sanitize_df(df, d_round=2, **options):
    """All dataframe cleaning and standardizing logic goes here."""
    for c in df.columns[df.dtypes == float]:
        df[c] = df[c].round(d_round)
    return df


def fix_team_tricode(tricode):
    """
    Some of the tricodes are different than how I want them

    :param tricode: 3 letter team name - ex: NYR

    :return: fixed tricode
    """
    fixed_tricodes = {'TBL': 'T.B', 'LAK': 'L.A', 'NJD': 'N.J', 'SJS': 'S.J'}
    if tricode.upper() in list(fixed_tricodes.keys()):
        return fixed_tricodes[tricode.upper()]
    else:
        return tricode


def lookup_cmd(ops, cmd_id):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/lib/genl/mngt.c#L33

    Positional arguments:
    ops -- genl_ops class instance.
    cmd_id -- integer.

    Returns:
    genl_cmd class instance or None.
    """
    for i in range(ops.o_ncmds):
        cmd = ops.o_cmds[i]
        if cmd.c_id == cmd_id:
            return cmd
    return None


def _append_extended_basins(basin_list):
    """Replace extended basins with components, e.g. atlExt with atl, mexico ...
    Note: atlExt etc are removed from the list for error checking later on.

    Parameters
    ----------
    basin_list : list of strings
        list of basin names potentially including 'atlExt', 'pacExt', 'indExt'

    Returns
    -------
    basin_list : list of strings
        list of basin names with "Ext" version replaced with "sub"basins
    """
    for name in basin_list:
        if name == 'atlExt':
            basin_list.remove('atlExt')
            basin_list.append('atl')
            basin_list.append('mexico')
            basin_list.append('hudson')
            basin_list.append('med')
            basin_list.append('north')
            basin_list.append('baffin')
            basin_list.append('gin')
        elif name == 'pacExt':
            basin_list.remove('pacExt')
            basin_list.append('pac')
            basin_list.append('bering')
            basin_list.append('okhotsk')
            basin_list.append('japan')
            basin_list.append('eastChina')
        elif name == 'indExt':
            basin_list.remove('indExt')
            basin_list.append('ind')
            basin_list.append('southChina')
            basin_list.append('java')
            basin_list.append('timor')
            basin_list.append('red')
            basin_list.append('gulf')
    return basin_list


@classmethod
def check_applicability(cls):
    """ Check for Command's applicability. """
    _ = getattr(cls, 'applies_to', [])
    return len(_) == 0 or not hasattr(cls, 'console'
        ) or cls.console.module.fullpath in _


def _get_docstring_default_value(var_doc):
    """
    Get the description of argument's default value from docstring.

    Parameters
    ----------
    var_doc : str
        Docstring's part of argument.

    Returns
    -------
    default_val : str
        Description of the defautl value.
    """
    default_val = var_doc.split('\n')[0]
    is_in = ', default ' in default_val or '(default ' in default_val
    if not is_in:
        return ''
    default_val = default_val.split('default')[1]
    default_val = default_val.split(',')[0]
    default_val = default_val.replace(')', '')
    default_val = default_val.strip()
    return default_val


def crossing_counter(path, interface):
    """Count the crossing to an interfaces.

    Method to count the crosses of a path over an interface.

    Parameters
    -----------
    path : object like :py:class:`.PathBase`
        This is the input path which will be trimmed.
    interface : float
        This is the position of the interface.

    Returns
    -------
    cnt : integer
        Number of crossing of the given interface.

    """
    cnt = 0
    for i in range(len(path.phasepoints[:-1])):
        op1 = path.phasepoints[i].order[0]
        op2 = path.phasepoints[i + 1].order[0]
        if op2 >= interface > op1 or op1 >= interface > op2:
            cnt += 1
    return cnt


def assert_no_overlapping_dates(old_data, to_add):
    """assert old_data and to_data have no overlapping dates"""
    unq_dates = lambda x: set(x.date if hasattr(x, 'date') else x.index)
    overlap = unq_dates(to_add).intersection(unq_dates(old_data))
    if overlap:
        raise ValueError(u'Data for dates {} has already been ingested'.
            format(overlap))


def analyse_RmpRiTau_trace(time, soma_voltage, stim_start, stim_end,
    current_amplitude):
    """Analyse the output of the RmpRiTau protocol"""
    import efel
    trace = {}
    trace['T'] = time
    trace['V'] = soma_voltage
    trace['stim_start'] = [stim_start]
    trace['stim_end'] = [stim_end]
    efel_results = efel.getFeatureValues([trace], ['voltage_base',
        'steady_state_voltage_stimend', 'decay_time_constant_after_stim'])
    voltage_base = efel_results[0]['voltage_base'][0]
    ss_voltage = efel_results[0]['steady_state_voltage_stimend'][0]
    dct = efel_results[0]['decay_time_constant_after_stim'][0]
    input_resistance = float(ss_voltage - voltage_base) / current_amplitude
    rmpritau_dict = {}
    rmpritau_dict['Rmp'] = '%.6g' % voltage_base
    rmpritau_dict['Rmp_Units'] = 'mV'
    rmpritau_dict['Rin'] = '%.6g' % input_resistance
    rmpritau_dict['Rin_Units'] = 'MOhm'
    rmpritau_dict['Tau'] = '%.6g' % dct
    rmpritau_dict['Tau_Units'] = 'ms'
    print('Resting membrane potential is %s %s' % (rmpritau_dict['Rmp'],
        rmpritau_dict['Rmp_Units']))
    print('Input resistance is %s %s' % (rmpritau_dict['Rin'],
        rmpritau_dict['Rin_Units']))
    print('Time constant is %s %s' % (rmpritau_dict['Tau'], rmpritau_dict[
        'Tau_Units']))
    import json
    with open('rmp_ri_tau.json', 'w') as rmpritau_json_file:
        json.dump(rmpritau_dict, rmpritau_json_file, sort_keys=True, indent
            =4, separators=(',', ': '))


@classmethod
def _ap_find_package_name(cls):
    """
        Return the package name to search for modules.

        By default we look at the module name of the *cls* object
        given.

        Subclasses may override.
        """
    ext_module_name = cls.__module__
    package_name = ext_module_name.rsplit('.', 1)[0]
    return package_name


def clamp(x, lower, upper=None):
    """Clamps number within the inclusive lower and upper bounds.

    Args:
        x (number): Number to clamp.
        lower (number, optional): Lower bound.
        upper (number): Upper bound

    Returns:
        number

    Example:

        >>> clamp(-10, -5, 5)
        -5
        >>> clamp(10, -5, 5)
        5
        >>> clamp(10, 5)
        5
        >>> clamp(-10, 5)
        -10

    .. versionadded:: 4.0.0
    """
    if upper is None:
        upper = lower
        lower = x
    if x < lower:
        x = lower
    elif x > upper:
        x = upper
    return x


def normalize_preferences(choices):
    """Removes duplicates and drops falsy values from a single preference order."""
    new_choices = []
    for choice in choices:
        if choice and choice not in new_choices:
            new_choices.append(choice)
    return new_choices


@classmethod
def info(cls, name):
    """ Get information about a disk."""
    return cls._info(cls.usable_id(name))


def lorentzian(x, x0=0.0, gamma=1.0, amp=1.0, offset=0.0, gradient=0.0):
    """
    lorentzian function : (x, x0=0., gamma=1., amp=1., offset=0., gradient=0.)
    gamma = FWHM : Full Width at Half Maximum
    amp is the amplitude at the center
    This function is not normalized to 1
    Area under this Lorentzian is (A * Gamma * pi / 2) with offset and gradient = 0.
    """
    return amp * (gamma / 2) ** 2 / ((x - x0) ** 2 + (gamma / 2) ** 2
        ) + offset + gradient * x


def indent(lines, amount=2, char=' '):
    """Indent a string.

    Prepends whitespace to every line in the passed string. (Lines are
    separated by newline characters.)

    Args:
        lines (str): The string to indent.

    Keyword Args:
        amount (int): The number of columns to indent by.
        char (str): The character to to use as the indentation.

    Returns:
        str: The indented string.

    Example:
        >>> print(indent('line1\\nline2', char='*'))
        **line1
        **line2
    """
    lines = str(lines)
    padding = amount * char
    return padding + ('\n' + padding).join(lines.split('\n'))


def anovadict(res):
    """update regression results dictionary with ANOVA specific statistics

    not checked for completeness
    """
    ad = {}
    ad.update(res.__dict__)
    anova_attr = ['df_model', 'df_resid', 'ess', 'ssr', 'uncentered_tss',
        'mse_model', 'mse_resid', 'mse_total', 'fvalue', 'f_pvalue', 'rsquared'
        ]
    for key in anova_attr:
        ad[key] = getattr(res, key)
    ad['nobs'] = res.model.nobs
    ad['ssmwithmean'] = res.uncentered_tss - res.ssr
    return ad


def parallel_gpu_jobs(allow_growth=True, fraction=0.5):
    """Sets the max used memory as a fraction for tensorflow
    backend

    allow_growth :: True of False

    fraction :: a float value (e.g. 0.5 means 4gb out of 8gb)

    """
    import keras.backend as K
    import tensorflow as tf
    gpu_options = tf.GPUOptions(allow_growth=allow_growth,
        per_process_gpu_memory_fraction=fraction)
    config = tf.ConfigProto(gpu_options=gpu_options)
    session = tf.Session(config=config)
    K.set_session(session)


@classmethod
def postcommit_hook(cls, method, *args, **kwargs):
    """ Same in the registry a hook to call just after the commit

        you can choice if the hook is called in function of ``call_only_if``:

        * ``commited``: Call if the commit is done without exception
        * ``raised``: Call if one exception was raised
        * ``always``: Always call

        .. warning::

            Only one instance with same paramters of the hook is called
            after the commit

        :param method: the method to call on this model
        :param put_at_the_end_if_exist: If ``True`` the hook is move at the end
        :param call_only_if: ['commited' (default), 'raised', 'always']
        """
    cls.registry.postcommit_hook(cls.__registry_name__, method, *args, **kwargs
        )


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


def ensure_sequence_filter(data):
    """
    Ensure sequenced data.

    **sequence**

        ensure that parsed data is a sequence

    .. code-block:: yaml

        {% set my_string = "foo" %}
        {% set my_list = ["bar", ] %}
        {% set my_dict = {"baz": "qux"} %}

        {{ my_string|sequence|first }}
        {{ my_list|sequence|first }}
        {{ my_dict|sequence|first }}

    will be rendered as:

    .. code-block:: yaml

        foo
        bar
        baz
    """
    if not isinstance(data, (list, tuple, set, dict)):
        return [data]
    return data


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

        :param RewindPolicyChangedType val:
        :rtype: EventType
        """
    return cls('rewind_policy_changed', val)


def operations(specification):
    """
    Get all operations of the specification.

    :param specification: openapi_core Spec object.

    :return: Generator yielding openapi_core Operation objects.
    """
    for operations in specification.paths.values():
        for operation in operations.operations.values():
            yield operation


def SetDrawingDefaults(drawingData):
    """Add required items into data['drawing'] array if not present. This does not add
    all the items in SetupDrawingData, but it seems that this is not a problem. Perhaps the
    two routines could be combined?
    """
    defaultDrawing = {'viewPoint': [[0.5, 0.5, 0.5], []], 'showHydrogen':
        True, 'backColor': [0, 0, 0], 'depthFog': False, 'Zclip': 50.0,
        'cameraPos': 50.0, 'Zstep': 0.5, 'radiusFactor': 0.85,
        'contourLevel': 1.0, 'bondRadius': 0.1, 'ballScale': 0.33,
        'vdwScale': 0.67, 'ellipseProb': 50, 'sizeH': 0.5, 'unitCellBox':
        True, 'showABC': True, 'selectedAtoms': [], 'Atoms': [], 'oldxy': [
        ], 'magMult': 1.0, 'bondList': {}, 'viewDir': [1, 0, 0], 'Plane': [
        [0, 0, 1], False, False, 0.0, [255, 255, 0]]}
    for key in defaultDrawing:
        if key not in drawingData:
            drawingData[key] = defaultDrawing[key]


def serialise_real(f, context=None):
    """Serialise a Real value.

    f -- real number (int or float)

    If the absolute value is too small to conveniently express as a decimal,
    returns b"0" (this currently happens if abs(f) is less than 0.0001).

    """
    f = float(f)
    try:
        i = int(f)
    except OverflowError:
        raise ValueError
    if f == i:
        return str(i).encode('ascii')
    s = repr(f)
    if 'e-' in s:
        return b'0'
    return s.encode('ascii')


@classmethod
def read_chunk(cls, opc_sync: bool, context: str) ->'IoTransferEventArgs':
    """Creates new IoTransferEventArgs of read string

		:param opc_sync: defines if the command is OPC-synchronised
		:param context: SCPI query. It is truncated to maximum of 100 characters.
		:return: IoTransferEventArgs object of a read string operation."""
    return cls(True, opc_sync, None, context)


def mod(before, after):
    """Returns before mod after.

        .. code-block:: xml

            <i>before % after</i>
        """
    return before % after


def parse_strings(s):
    """Parse comma separated values. Return None if s is None."""
    return s.split(',') if s is not None else s


def validate_card(card_num):
    """
    Check if credit card is valid using the Luhn algorithm

    Input: Card number, integer or string
    Output: Valid?, boolean
    """
    double = 0
    total = 0
    digits = str(card_num)
    for i in range(len(digits) - 1, -1, -1):
        for c in str((double + 1) * int(digits[i])):
            total += int(c)
        double = (double + 1) % 2
    return total % 10 == 0


def _get_setfilesuffix_methodname(altsuffix_name):
    """
        Return the name of the method name to set suffix to `altsuffix_name`
        e.g. `logfile()` for setting to `log`.
        """
    return altsuffix_name + 'file'


def renderBatchLink(batch, cssClass=None):
    """Render batch links."""


def get_roles_info(parsed_args):
    """Get flavor name and scale for all deployment roles.

    :returns: dict role name -> (flavor name, scale)
    """
    return {'control': (parsed_args.control_flavor, parsed_args.
        control_scale), 'compute': (parsed_args.compute_flavor, parsed_args
        .compute_scale), 'ceph-storage': (parsed_args.ceph_storage_flavor,
        parsed_args.ceph_storage_scale), 'block-storage': (parsed_args.
        block_storage_flavor, parsed_args.block_storage_scale),
        'swift-storage': (parsed_args.swift_storage_flavor, parsed_args.
        swift_storage_scale)}


def flatten_fieldsets(fieldsets):
    """Returns a list of field names from an admin fieldsets structure."""
    field_names = []
    for name, opts in fieldsets:
        for field in opts['fields']:
            if isinstance(field, (list, tuple)):
                field_names.extend(field)
            else:
                field_names.append(field)
    return field_names


def fillna(df, fill_value=''):
    """
    Replace null values with `fill_value`.

    Also replaces in categorical columns.
    """
    for col in df.dtypes[df.dtypes == 'category'].index:
        if fill_value not in df[col].cat.categories:
            df[col].cat.add_categories([fill_value], inplace=True)
    return df.fillna(fill_value)


def pystr(v_str):
    """Convert string repr of Fortran string to Python string."""
    assert isinstance(v_str, str)
    if v_str[0] in ("'", '"') and v_str[0] == v_str[-1]:
        quote = v_str[0]
        out = v_str[1:-1]
    else:
        quote = None
        out = v_str
    if quote:
        out = out.replace(2 * quote, quote)
    return out


def input_text(content: str, toolkit=None):
    """
    输入文字（不支持中文）。中文输入可以利用ADBKeyBoard (https://github.com/senzhk/ADBKeyBoard)

    :param content: 期望的输入内容
    :param toolkit:
    :return:
    """
    toolkit.adb.run(['shell', 'input', 'text', content])


def loc(df, iindexer, cindexer=None):
    """
    .loc for known divisions
    """
    if cindexer is None:
        return df.loc[iindexer]
    else:
        return df.loc[iindexer, cindexer]


def write_membership_settings(outfile, config_params):
    """Writes the Membership section of the final.ini file"""
    outfile.write('\n[Membership]\n')
    outfile.write('probability_row_change = %f\n' % config_params[
        'memb.prob_row_change'])
    outfile.write('probability_column_change = %f\n' % config_params[
        'memb.prob_col_change'])
    outfile.write('max_changes_per_row = %d\n' % config_params[
        'memb.max_changes_per_row'])
    outfile.write('max_changes_per_column = %d\n' % config_params[
        'memb.max_changes_per_col'])
    outfile.write('min_cluster_rows_allowed = %d\n' % config_params[
        'memb.min_cluster_rows_allowed'])
    outfile.write('max_cluster_rows_allowed = %d\n' % config_params[
        'memb.max_cluster_rows_allowed'])
    outfile.write('clusters_per_row = %d\n' % config_params[
        'memb.clusters_per_row'])
    outfile.write('clusters_per_column = %d\n' % config_params[
        'memb.clusters_per_col'])


def lower(option, value):
    """
    Enforces lower case options and option values where appropriate
    """
    if type(option) is str:
        option = option.lower()
    if type(value) is str:
        value = value.lower()
    return option, value


@classmethod
def update_requirements(cls, srv=None, *options):
    """
        Update an image so that it includes depencies requireed by code.

        This function implements the last step to transform the generic environment indicated by
        the dockerimg or dockerfile into the correct environment for the source code.
        """
    if srv is None or srv == '-a':
        for k in list(cls._ocean.manifest.keys()):
            for s in cls._ocean.manifest[k]:
                cls.update_requirements(s, options)
        return
    return cls._ocean._do_build_built(srv, options)


@classmethod
def remove_label(cls, group):
    """ Remove an existing label

        The goal of this function is to remove an existing label of a specific
        group::

            @Configuration.add('create-db', label="Name of the group")
            def bar(parser, defaul):
                pass

            Configuration.remove_label('create-db')

        :param group: group is a set of parser option
        """
    if group in cls.labels:
        del cls.labels[group]


def _w_long(x):
    """Convert a 32-bit integer to little-endian."""
    return (int(x) & 4294967295).to_bytes(4, 'little')


def flight_log_multiaxis_graph_contents_replacer(contents):
    """Values list is from the function flight_data_and_axis."""
    comma = None
    lines = contents.split('\n')
    line_list = []
    for index in range(len(lines)):
        if '"MULTIAXIS_GRAPH\\n"' in lines[index]:
            line_list.append(index)
    graph_data = []
    for index in line_list:
        a = 0
        b = 1
        local_graph_data = [index]
        while a == 0:
            if lines[index + b] == '   ]':
                graph_data.append(local_graph_data)
                break
            if lines[index + b] != '    "\\n",':
                local_graph_data.append(index + b)
            b += 1
    graph_list = []
    graph_data_index = 0
    for data in graph_data:
        graph_list.append([[], []])
        axis = 0
        for index in data[1:]:
            ignore = False
            line = lines[index]
            line = line.replace('    "', '')
            line = line.replace('"', '')
            line = line.replace('\\n,', '')
            if line == 'LEFT_AXIS':
                axis = 0
                ignore = True
            if line == 'RIGHT_AXIS':
                axis = 1
                ignore = True
            line = line.lower()
            line = line.replace(' ', '\\", \\"')
            line = line.replace('_', ' ')
            if ignore is False:
                graph_list[graph_data_index][axis].append('[\\"' + line +
                    '\\"]')
        graph_data_index += 1
    notebook_lines = []
    for data in graph_list:
        line = ('  {\n   "cell_type": "code",\n' +
            """   "execution_count": null,
   "metadata": {},
""" +
            """   "outputs": [],
   "source": [
""" +
            '   "x_limits=[\\"x_min\\", \\"x_max\\"]\\n",\n' +
            """   "y_limits_left=[\\"y_min\\", \\"y_max\\"]\\n",
""" +
            '   "y_limits_right=[\\"y_min\\", \\"y_max\\"]\\n",\n' +
            '   "legend_location=1\\n",\n' + '   "multiaxis_graph_plotter([')
        for axis_left in data[0]:
            line += axis_left + ', '
        line = line[:-2]
        line += '], ['
        for axis_right in data[1]:
            line += axis_right + ', '
        line = line[:-2]
        line += '], values_list, x_limits, y_limits_left, y_limits_right,' + """ marker_list, legend_location)"
   ]
  }"""
        notebook_lines.append(line)
    index = 0
    for element in line_list:
        old_cell_text = ''
        for lines_before in reversed(lines[:element]):
            a = 0
            old_cell_text = lines_before + '\n' + old_cell_text
            if lines_before == '  {':
                a = 1
                for lines_after in lines[element:]:
                    if '  },' in lines_after:
                        old_cell_text = old_cell_text + '  },\n'
                        comma = True
                        break
                    elif '  }' in lines_after:
                        old_cell_text = old_cell_text + '  }\n'
                        comma = False
                        break
                    else:
                        old_cell_text = old_cell_text + lines_after + '\n'
            if a == 1:
                break
        if comma is True:
            end = ',\n'
        else:
            end = '\n'
        contents = contents.replace(old_cell_text, notebook_lines[index] + end)
        index += 1
    return contents


def convert_to_str(value):
    """convert True/False to yes/no and all values to strongs"""
    if isinstance(value, bool):
        if value:
            return 'yes'
        return 'no'
    return str(value)


@staticmethod
def get_referenced_beam_sequence_index(fx_grp_seq, beam_number):
    """
        Determine the index of the referenced beam sequence for a given beam_number. This properly connects BeamSequence
        beams and ReferencedBeamSequence beams.
        :param fx_grp_seq: Index of the fraction group (likely 0 unless TPS allows multiple prescriptions
        :param beam_number: The beam number of the beam of interest within BeamSequence
        :return: the ReferencedBeamSequence index that matches beam_number
        :rtype: int
        """
    for i, ref_beam_seq in enumerate(fx_grp_seq.ReferencedBeamSequence):
        if ref_beam_seq.ReferencedBeamNumber == beam_number:
            return i
    print(
        'ERROR: Failed to find a matching reference beam in ReferencedBeamSequence for beam number %s'
         % beam_number)


def set_default_attr(obj, name, value):
    """
    Set attribute to obj if attribute is not exists

    :param obj: object
    :param name: attribure name
    :param value: attribure value
    :return: if is attribute not exists
    """
    if not hasattr(obj, name):
        setattr(obj, name, value)
        return value
    return getattr(obj, name, value)


def Rayleigh(Pr, Gr):
    """Calculates Rayleigh number or `Ra` using Prandtl number `Pr` and
    Grashof number `Gr` for a fluid with the given
    properties, temperature difference, and characteristic length used
    to calculate `Gr` and `Pr`.

    .. math::
        Ra = PrGr

    Parameters
    ----------
    Pr : float
        Prandtl number []
    Gr : float
        Grashof number []

    Returns
    -------
    Ra : float
        Rayleigh number []

    Notes
    -----
    Used in free convection problems only.

    Examples
    --------
    >>> Rayleigh(1.2, 4.6E9)
    5520000000.0

    References
    ----------
    .. [1] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook,
       Eighth Edition. McGraw-Hill Professional, 2007.
    .. [2] Cengel, Yunus, and John Cimbala. Fluid Mechanics: Fundamentals and
       Applications. Boston: McGraw Hill Higher Education, 2006.
    """
    return Pr * Gr


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

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


def any(name, alternates):
    """Return a named group pattern matching list of alternates."""
    return '(?P<%s>' % name + '|'.join(alternates) + ')'


def print_project_info(stdscr, project):
    """
    Prints the project info.
    """
    stdscr.addstr(1, 1, project.name)
    for index, board in enumerate(project.boards):
        if index == project.active_board:
            stdscr.addstr(index + 3, 2, ''.join(['* ', str(project.boards[
                index])]))
        else:
            stdscr.addstr(index + 3, 2, ''.join(['  ', str(project.boards[
                index])]))


@staticmethod
def get_ending_latex():
    """
        Returns ending code of Latex document.

        Returns
        -------
        str
        """
    return '\\end{document}'


def print_progress_bar(iteration, total, prefix='', suffix='', decimals=1,
    length=100, fill='#'):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
    """
    percent = ('{0:.' + str(decimals) + 'f}').format(100 * (iteration /
        float(total)))
    filled_length = int(length * iteration // total)
    bar = fill * filled_length + '-' * (length - filled_length)
    print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end='\r')
    if iteration == total:
        print()


def getDisplayValue(displayValue):
    """Takes potentially multilined value and converts it to a single line"""
    lines = str(displayValue).splitlines()
    lineCount = len(lines)
    if lineCount > 1:
        nonEmptyIndex = None
        index = -1
        for line in lines:
            index += 1
            if len(line.strip()) > 0:
                nonEmptyIndex = index
                break
        if nonEmptyIndex is None:
            displayValue = ''
        else:
            if len(lines[nonEmptyIndex]) > 128:
                displayValue = lines[nonEmptyIndex][:128] + '<...>'
            else:
                displayValue = lines[nonEmptyIndex]
                if nonEmptyIndex < lineCount - 1:
                    displayValue += '<...>'
            if nonEmptyIndex > 0:
                displayValue = '<...>' + displayValue
    elif lineCount == 1:
        if len(lines[0]) > 128:
            displayValue = lines[0][:128] + '<...>'
        else:
            value = lines[0]
    return displayValue


def filter_false_positive(df, process_time):
    """
    method that takes in FireEye (FE) alerts and filters FE-tests and False Positives
    :param process_time:
    :param df:
    :return:
    """
    result = []
    track = []
    count = 0
    for o in df['alerts']:
        count += 1
        if 'closedState' in o:
            if o['closedState'] != 'False Positive':
                if 'distinguishers' in o:
                    try:
                        if 'virus' in o['distinguishers']:
                            if o['distinguishers']['virus'] != 'fetestevent':
                                result.append(o)
                            else:
                                track.append(o)
                        else:
                            result.append(o)
                    except TypeError:
                        result.append(o)
                else:
                    result.append(o)
            else:
                track.append(o)
        elif 'distinguishers' in o:
            try:
                if 'virus' in o['distinguishers']:
                    if o['distinguishers']['virus'] != 'fetestevent':
                        result.append(o)
                    else:
                        track.append(o)
                else:
                    result.append(o)
            except TypeError:
                result.append(o)
    trackfile = open('tracking_fetest_' + process_time + '.txt', 'w')
    numskip = 1
    for item in track:
        trackfile.write('\n\n**** {:d}: Display ID {} ****\n\n{}'.format(
            numskip, item['displayId'], item))
        numskip += 1
    return result


def getCloneCandidate(outputs):
    """
    :returns single connected & enabled display output which will be cloned
    """
    index = None
    for i, output in enumerate(outputs):
        if output and index is None:
            index = i
        if output['isPrimary']:
            return output
    if index is None:
        raise Exception('No connected display outputs detected.')
    return outputs[index]


def chi_list(chi_max, dchi=20, nsweeps=20):
    """Compute a 'ramping-up' chi_list.

    The resulting chi_list allows to increases `chi` by `dchi` every `nsweeps` sweeps up to a given
    maximal `chi_max`.

    Parameters
    ----------
    chi_max : int
        Final value for the bond dimension.
    dchi :int
        Step size how to increase chi
    nsweeps : int
        Step size for sweeps

    Returns
    -------
    chi_list : dict
        To be used as `chi_list` parameter for DMRG, see :func:`run`.
        Keys increase by `nsweeps`, values by `dchi`, until a maximum of `chi_max` is reached.
    """
    chi_max = int(chi_max)
    nsweeps = int(nsweeps)
    if chi_max < dchi:
        return {(0): chi_max}
    chi_list = {}
    for i in range(chi_max // dchi):
        chi = int(dchi * (i + 1))
        chi_list[nsweeps * i] = chi
    if chi < chi_max:
        chi_list[nsweeps * (i + 1)] = chi_max
    return chi_list


def GetNumDensity(ElList, Vol):
    """needs a doc string"""
    sumNoAtoms = 0.0
    for El in ElList:
        sumNoAtoms += ElList[El]['FormulaNo']
    return sumNoAtoms / Vol


@classmethod
def validscale(cls, v):
    """Check SCALEMIN<=SCALEMAX, and both in range for CDF datatype.

        Compares `SCALEMIN
        <https://spdf.gsfc.nasa.gov/istp_guide/vattributes.html#SCALEMIN>`_
        to ``SCALEMAX`` to make sure it isn't larger and both are
        within range of the variable CDF datatype.

        Parameters
        ----------
        v : :class:`~spacepy.pycdf.Var`
            Variable to check

        Returns
        -------
        list of str
            Description of each validation failure.

        """
    return cls._validhelper(v, False)


@classmethod
def activate(cls, flow_task, prev_activation, token):
    """Instantiate new task."""
    task = flow_task.flow_class.task_class(process=prev_activation.process,
        flow_task=flow_task, token=token)
    task.save()
    task.previous.add(prev_activation.task)
    activation = cls()
    activation.initialize(flow_task, task)
    return activation


def create_log_group(logGroupName=None, tags=None):
    """
    Creates a log group with the specified name.
    You can create up to 5000 log groups per account.
    You must use the following guidelines when naming a log group:
    See also: AWS API Documentation

    :example: response = client.create_log_group(
        logGroupName='string',
        tags={
            'string': 'string'
        }
    )

    :type logGroupName: string
    :param logGroupName: [REQUIRED]
            The name of the log group.

    :type tags: dict
    :param tags: The key-value pairs to use for the tags.
            (string) --
            (string) --

    :returns:
    logGroupName (string) -- [REQUIRED]
    The name of the log group.

    tags (dict) -- The key-value pairs to use for the tags.

    (string) --
    (string) --

    """
    pass


def _purge_cptrs():
    """purges all cptr information"""
    global _all_cptrs, _all_cindices, _c_ptr_vector, _last_c_ptr_length
    global _c_ptr_vector_storage, _c_ptr_vector_storage_nrn
    _all_cptrs = []
    _all_cindices = []
    _c_ptr_vector = None
    _c_ptr_vector_storage_nrn = None
    _c_ptr_vector_storage = None
    _last_c_ptr_length = None


def PreSetup(data):
    """Create part of an initial (empty) phase dictionary

    from GSASIIphsGUI.py, near end of UpdatePhaseData

    Author: Jackson O'Donnell (jacksonhodonnell .at. gmail.com)
    """
    if 'RBModels' not in data:
        data['RBModels'] = {}
    if 'MCSA' not in data:
        data['MCSA'] = {'Models': [{'Type': 'MD', 'Coef': [1.0, False, [0.8,
            1.2]], 'axis': [0, 0, 1]}], 'Results': [], 'AtInfo': {}}
    if 'dict' in str(type(data['MCSA']['Results'])):
        data['MCSA']['Results'] = []
    if 'Modulated' not in data['General']:
        data['General']['Modulated'] = False


def random_id():
    """
    Cast the UUID to a string
    """
    from uuid import uuid4
    return str(uuid4())


@classmethod
def covered(cls):
    """
        Represents a bit of code, usually a statement, that executed successfully but
        doesn't have an actual value.
        """
    return cls('', -2)


def pytest_xdist_rsyncstart(source, gateways):
    """ called before rsyncing a directory to remote gateways takes place. """


def chk_fraction_digits_arg(s):
    """Checks if the string `s` is a valid fraction-digits argument.

    Return True or False."""
    try:
        v = int(s)
        if v >= 1 and v <= 18:
            return True
        else:
            return False
    except ValueError:
        return False


def _serialize_reference(header, obj, indent=12):
    """Serialize REFERENCE.

    Parameters
    ----------
    obj : list
    """
    padding = '  '
    sort_order = {'REFERENCE': 0, 'AUTHORS': 1, 'TITLE': 2, 'JOURNAL': 3,
        'PUBMED': 4}
    for obj_i in obj:
        ref_i = []
        for h in sorted(obj_i, key=lambda k: sort_order.get(k, 100)):
            if h == header:
                s = '{h:<{indent}}{ref}'.format(h=h, indent=indent, ref=
                    obj_i[h])
            else:
                s = '{h:<{indent}}{value}'.format(h=padding + h, indent=
                    indent, value=obj_i[h])
            ref_i.append(s)
        yield '%s\n' % '\n'.join(ref_i)


def shade_flat():
    """Set shading to flat

    """
    pass


def get_pairs(word):
    """Return set of symbol pairs in a word.

    Word is represented as tuple of symbols (symbols being variable-length strings).
    """
    pairs = set()
    prev_char = word[0]
    for char in word[1:]:
        pairs.add((prev_char, char))
        prev_char = char
    return pairs


@staticmethod
def format_as_diff(lines):
    """Function to remove empty diff lines, convert to bash diff format
        Python uses +/-, so convert that to </>

        For example:
            < this is
            < expected
            ---
            > and this is actual
        """
    output = []
    left_toggle = True
    for line in lines:
        if line[0] == '+':
            if not left_toggle:
                output += ['\n']
            output += ['< ' + line[1:]]
            left_toggle = True
        elif line[0] == '-':
            if left_toggle:
                output += ['---']
            output += ['> ' + line[1:]]
            left_toggle = False
    return output


@classmethod
def flashCookieManager(cls):
    """
        Class method to get a reference to the flash cookies manager.

        @return reference to the flash cookies manager
        @rtype FlashCookieManager
        """
    if cls._flashCookieManager is None:
        from .FlashCookieManager.FlashCookieManager import FlashCookieManager
        cls._flashCookieManager = FlashCookieManager()
    return cls._flashCookieManager


def array_is_structured(array):
    """ Returns True if the array has a structured data type.
    """
    return bool(array.dtype.names)


def counter(start=1):
    """Simple counter generator, used to keep track of query args.

    :param start:  The number to start out the counter with.

    """
    while True:
        yield start
        start += 1


def _is_prioritized(label: str) ->bool:
    """
    Tells if label is prioritized or not.

    >>> _is_prioritized('feature')
    True

    >>> _is_prioritized('deadline:miss')
    False

    """
    return ':' not in label


def get_real_space_mask_from_fit(mask, fit):
    """Get the masks of the fit if the masks should be plotted on the fit.

    Parameters
    -----------
    fit : datas.fitting.fitting.AbstractLensHyperFit
        The fit to the datas, which includes a lisrt of every model image, residual_map, chi-squareds, etc.
    mask : bool
        If *True*, the masks is plotted on the fit's datas.
    """
    if mask:
        return fit.masked_dataset.mask
    else:
        return None


def get_transition(env):
    """
    Generate a transition from the environment.

    This basically does a single step on the environment
    and then closes it.

    Parameters
    ----------
    env : gym environment

        A gym environment.

    Returns
    -------
    s, a, r, s_next, a_next, done, info : tuple

        A single transition. Note that the order and the number of items
        returned is different from what ``env.reset()`` return.

    """
    try:
        s = env.reset()
        a = env.action_space.sample()
        a_next = env.action_space.sample()
        s_next, r, done, info = env.step(a)
        return s, a, r, s_next, a_next, done, info
    finally:
        env.close()


def __call__(field):
    """ return true if the field is to be considered as
            countable """


def incid_ref_press(p_d, gamma_inc) ->'p_inc':
    """Calculate DNVGL-ST-F101 «incidental reference pressure».

    :param p_d: $p_d$ design pressure
    :param gamma_inc: $\\gamma_{inc}$ incidental to design pressure ratio
    :returns: p_inc: $p_{inc}$ incidental reference pressure

    Reference:
    DNVGL-ST-F101 (2017-12)
        eq:4.3 sec:4.2.2.2 page:67 p_{inc}

    Example:
    >>> incid_ref_press(100e5, 1.1)
    11000000.0
    """
    return p_d * gamma_inc


def update_attrs(item, **kwargs):
    """Set a dictionary of attributes."""
    for attr, value in kwargs.items():
        if hasattr(item, attr):
            setattr(item, attr, value)


def viz_property(statement, properties):
    """Create properties for graphviz element"""
    if not properties:
        return statement + ';'
    return statement + '[{}];'.format(' '.join(properties))


def POW(number, exponent):
    """
    Raises a number to the specified exponent and returns the result.
    See https://docs.mongodb.com/manual/reference/operator/aggregation/pow/
    for more details
    :param number: The number or field that will be raised
    :param exponent: The number or field that will be the exponent
    :return: Aggregation operator
    """
    return {'$pow': [number, exponent]}


def get_line(picardfile, phrase):
    """Read file. Report line number that starts with phrase and the first
    blank line after that line. Return tuple of integers
    """
    with open(picardfile, 'r') as f:
        start = 1000
        end = 1000
        for i, line in enumerate(f):
            if line.startswith(phrase):
                start = i
            if line.startswith('\n'):
                end = i
            if start < end:
                return start, end


@classmethod
def delete_instance(cls, obj):
    """Actively remove the stored instance."""
    try:
        instance = cls._instances[obj]
    except (KeyError, AttributeError):
        pass
    else:
        instance.delete()


def join(chars=[]):
    """
    Join a list of characters into a string.
    """
    return ''.join(chars)


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 update_member(id, **data):
    """Update an existing member."""


def _write_error_to_file(err_msg, path_to_err):
    """ Helper script to write error message to file """
    with open(path_to_err, 'w') as f:
        f.write(err_msg)


def get(isdsAppliance, check_mode=False, force=False):
    """
    Get all snmp objects
    """
    return isdsAppliance.invoke_get('Get all alert objects', '/system_alerts')


def stroke_subdivide(number_cuts: int=1):
    """Subdivide between continuous selected points of the stroke adding a point half way between them

    :param number_cuts: Number of Cuts
    :type number_cuts: int
    """
    pass


def test_update(orig_dict, new_dict):
    """Modify test in place to update with new data."""
    for key, val in new_dict.items():
        if key == 'data':
            orig_dict[key] = val
        elif isinstance(val, dict):
            orig_dict[key].update(val)
        elif isinstance(val, list):
            orig_dict[key] = orig_dict.get(key, []) + val
        else:
            orig_dict[key] = val


def doBack(action):
    """Process something if back action get exceuted."""


def dot(v1, v2):
    """returns dot product between two vectors, non class member.

    Parameters
    ----------
    v1: Vector
        The first vector.
    v2: Vector
        The second vector.

    Returns
    -------
    float
        The dot product of the vectors.
    """
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z


def parse_generation(generation):
    """
    Parses a generation, returning both the name and the dynamic parameter
    the generation is based on.

    So parse_generation("nav:user_id") => ("nav", "user_id")
    and parse_generation("nav") => ("nav", None)
    """
    parts = generation.split(':')
    if len(parts) == 1:
        return parts[0], None
    else:
        return tuple(parts)


def getTypeInfo():
    """ Return the ITypeInformation object for this object.

        o A shortcut to 'getTypeInfo' of portal_types.

        o Permission:  Public
        """


def stabilize_2d_rotation_remove():
    """Remove selected track from rotation stabilization

    """
    pass


@staticmethod
def from_xml(xml_file):
    """
        Returns a tuple of (api_object, binding_object).
        Parameters:
        xml_file - either a filename or a stream object
        """
    from maec.utils.parser import EntityParser
    parser = EntityParser()
    maec_package = parser.parse_xml(xml_file)
    maec_package_obj = maec_package.to_obj()
    return maec_package, maec_package_obj


def ae_7(provider):
    """Send A-ASSOCIATE-AC PDU."""
    provider.dul_socket.send(provider.primitive.encode())
    return 'Sta6'


def get_table_code(sol, table_name, unused_options):
    """
    Gets the table code of a given parameter.  For example, the
    DISPLACMENT(PLOT,POST)=ALL makes an OUGV1 table and stores the
    displacement.  This has an OP2 table code of 1, unless you're running a
    modal solution, in which case it makes an OUGV1 table of eigenvectors
    and has a table code of 7.

    Parameters
    ----------
    options : list[int/float/str]
        the options for a parameter
    value : int/float/str
        the value of the parameter

    Returns
    -------
    table_code : int
       the OP2 table_code
    """
    if table_name in ['VECTOR', 'PRESSURE']:
        table_name = 'DISPLACEMENT'
    key = sol, table_name
    tables = {(101, 'ACCELERATION'): 11, (103, 'ACCELERATION'): 11, (106,
        'ACCELERATION'): 11, (107, 'ACCELERATION'): 11, (108,
        'ACCELERATION'): 11, (129, 'ACCELERATION'): 11, (145,
        'ACCELERATION'): 11, (146, 'ACCELERATION'): 11, (101,
        'DISPLACEMENT'): 1, (103, 'DISPLACEMENT'): 7, (105, 'DISPLACEMENT'):
        7, (106, 'DISPLACEMENT'): 1, (107, 'DISPLACEMENT'): 7, (108,
        'DISPLACEMENT'): 1, (109, 'DISPLACEMENT'): 1, (111, 'DISPLACEMENT'):
        7, (112, 'DISPLACEMENT'): 1, (129, 'DISPLACEMENT'): 7, (145,
        'DISPLACEMENT'): 1, (146, 'DISPLACEMENT'): 1, (101, 'ESE'): 18, (
        103, 'ESE'): 18, (105, 'ESE'): 18, (106, 'ESE'): 18, (107, 'ESE'):
        18, (108, 'ESE'): 18, (109, 'ESE'): 18, (110, 'ESE'): 18, (111,
        'ESE'): 18, (112, 'ESE'): 18, (145, 'ESE'): 18, (146, 'ESE'): 18, (
        101, 'FORCE'): 3, (103, 'FORCE'): 3, (105, 'FORCE'): 3, (106,
        'FORCE'): 3, (107, 'FORCE'): 4, (108, 'FORCE'): 3, (111, 'FORCE'):
        3, (112, 'FORCE'): 3, (129, 'FORCE'): 3, (145, 'FORCE'): 3, (146,
        'FORCE'): 3, (101, 'GPFORCE'): 19, (105, 'GPFORCE'): 19, (106,
        'GPFORCE'): 19, (107, 'GPFORCE'): 19, (108, 'GPFORCE'): 19, (111,
        'GPFORCE'): 19, (112, 'GPFORCE'): 19, (129, 'GPFORCE'): 19, (145,
        'GPFORCE'): 19, (146, 'GPFORCE'): 19, (101, 'GPSTRESS'): 20, (105,
        'GPSTRESS'): 20, (106, 'GPSTRESS'): 20, (107, 'GPSTRESS'): 20, (108,
        'GPSTRESS'): 20, (111, 'GPSTRESS'): 20, (112, 'GPSTRESS'): 20, (129,
        'GPSTRESS'): 20, (145, 'GPSTRESS'): 20, (146, 'GPSTRESS'): 20, (101,
        'GPSTRAIN'): 21, (105, 'GPSTRAIN'): 21, (106, 'GPSTRAIN'): 21, (107,
        'GPSTRAIN'): 21, (108, 'GPSTRAIN'): 21, (111, 'GPSTRAIN'): 21, (112,
        'GPSTRAIN'): 21, (129, 'GPSTRAIN'): 21, (145, 'GPSTRAIN'): 21, (146,
        'GPSTRAIN'): 21, (101, 'MPCFORCES'): 3, (103, 'MPCFORCES'): 3, (106,
        'MPCFORCES'): 3, (108, 'MPCFORCES'): 3, (112, 'MPCFORCES'): 3, (129,
        'MPCFORCES'): 3, (145, 'MPCFORCES'): 3, (146, 'MPCFORCES'): 3, (101,
        'OLOAD'): 2, (103, 'OLOAD'): 2, (105, 'OLOAD'): 2, (106, 'OLOAD'):
        2, (107, 'OLOAD'): 2, (108, 'OLOAD'): 2, (111, 'OLOAD'): 2, (112,
        'OLOAD'): 2, (129, 'OLOAD'): 2, (145, 'OLOAD'): 2, (146, 'OLOAD'):
        2, (101, 'SPCFORCES'): 3, (103, 'SPCFORCES'): 3, (105, 'SPCFORCES'):
        3, (106, 'SPCFORCES'): 3, (107, 'SPCFORCES'): 3, (108, 'SPCFORCES'):
        3, (110, 'SPCFORCES'): 3, (111, 'SPCFORCES'): 3, (112, 'SPCFORCES'):
        3, (129, 'SPCFORCES'): 3, (145, 'SPCFORCES'): 3, (146, 'SPCFORCES'):
        3, (101, 'STRAIN'): 5, (105, 'STRAIN'): 5, (106, 'STRAIN'): 5, (107,
        'STRAIN'): 5, (108, 'STRAIN'): 5, (110, 'STRAIN'): 5, (111,
        'STRAIN'): 5, (112, 'STRAIN'): 5, (129, 'STRAIN'): 5, (145,
        'STRAIN'): 5, (146, 'STRAIN'): 5, (101, 'STRESS'): 5, (103,
        'STRESS'): 5, (105, 'STRESS'): 5, (106, 'STRESS'): 5, (107,
        'STRESS'): 5, (108, 'STRESS'): 5, (111, 'STRESS'): 5, (112,
        'STRESS'): 5, (129, 'STRESS'): 5, (145, 'STRESS'): 5, (146,
        'STRESS'): 5, (145, 'SVECTOR'): 14, (101, 'FLUX'): 4, (103, 'FLUX'):
        4, (106, 'FLUX'): 4, (112, 'FLUX'): 4, (108, 'FLUX'): 4, (153,
        'FLUX'): 4, (159, 'FLUX'): 4, (101, 'THERMAL'): 3, (159, 'THERMAL'):
        3, (101, 'VELOCITY'): 10, (103, 'VELOCITY'): 10, (106, 'VELOCITY'):
        10, (107, 'VELOCITY'): 10, (108, 'VELOCITY'): 10, (111, 'VELOCITY'):
        10, (112, 'VELOCITY'): 10, (129, 'VELOCITY'): 10, (145, 'VELOCITY'):
        10, (146, 'VELOCITY'): 10, (101, 'VUGRID'): 10}
    if key not in tables:
        raise KeyError(key)
    table_code = tables[key]
    return table_code


def get_nova_client(session):
    """Return a nova client using *session*."""
    from novaclient import client
    return client.Client('2', session=session)


def add42(number: int) ->int:
    """
    Add 42 to number.

    >>> add42(100)
    142
    """
    return number + 42


def processFasta(fi, headless=False):
    """
    Provides a generator to the contents of a Fasta file.
    The function can handle single seq/multi seq, formatted/unformatted Fasta.

    Input: a file/stream handle
    Output: a generator object providing identifier and sequence information
    for each record in the Fastq file
    """
    seq, identifier = [], ''
    for line in fi:
        line = line.strip()
        if not line:
            continue
        if line.startswith('>'):
            if headless:
                line = line.lstrip('>')
            if seq:
                yield identifier, ''.join(seq)
                seq = []
            identifier = line
        else:
            seq.append(line)
    if seq:
        yield identifier, ''.join(seq)


def getAssignmentMappingUrl(manager):
    """Given a portlet manager, get the URL to its assignment mapping.
        """


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

        :param SsoChangeSamlIdentityModeType val:
        :rtype: EventType
        """
    return cls('sso_change_saml_identity_mode', val)


@classmethod
def get_exam_by_id(cls, exam_id):
    """
        Returns the Proctored Exam if found else returns None,
        Given exam_id (PK)
        """
    try:
        proctored_exam = cls.objects.get(id=exam_id)
    except cls.DoesNotExist:
        proctored_exam = None
    return proctored_exam


def _company_tax_rate(column):
    """ Uses income statement to get company tax rate """
    income_before_tax = column['Earnings before Tax']
    income_tax_expense = column['Income Tax Expense']
    return income_tax_expense / income_before_tax


def utf8_decoder(s):
    """ Decode the unicode as UTF-8 """
    if s is None:
        return None
    return s.decode('utf-8')


def is_json_value_header(shape):
    """Determines if the provided shape is the special header type jsonvalue.

    :type shape: botocore.shape
    :param shape: Shape to be inspected for the jsonvalue trait.

    :return: True if this type is a jsonvalue, False otherwise
    :rtype: Bool
    """
    return hasattr(shape, 'serialization') and shape.serialization.get(
        'jsonvalue', False) and shape.serialization.get('location'
        ) == 'header' and shape.type_name == 'string'


def strip_spaces_and_quotes(value):
    """Remove invalid whitespace and/or single pair of dquotes and return None
    for empty strings.

    Used to prepare cookie values, path, and domain attributes in a way which
    tolerates simple formatting mistakes and standards variations.
    """
    value = value.strip() if value else ''
    if value and len(value) > 1 and value[0] == value[-1] == '"':
        value = value[1:-1]
    if not value:
        value = ''
    return value


def maximum_element_size_for_length(length):
    """

	Returns the maximum element size representable in a given number of bytes.

	:arg length: the limit on the length of the encoded representation in bytes
	:type length: int
	:returns: the maximum element size representable
	:rtype: int

	"""
    return 2 ** (7 * length) - 2


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


def parse_repository_tag(repo_path):
    """Splits image identification into base image path, tag/digest
    and it's separator.

    Example:

    >>> parse_repository_tag('user/repo@sha256:digest')
    ('user/repo', 'sha256:digest', '@')
    >>> parse_repository_tag('user/repo:v1')
    ('user/repo', 'v1', ':')
    """
    tag_separator = ':'
    digest_separator = '@'
    if digest_separator in repo_path:
        repo, tag = repo_path.rsplit(digest_separator, 1)
        return repo, tag, digest_separator
    repo, tag = repo_path, ''
    if tag_separator in repo_path:
        repo, tag = repo_path.rsplit(tag_separator, 1)
        if '/' in tag:
            repo, tag = repo_path, ''
    return repo, tag, tag_separator


def p_ExtendedAttributes(p):
    """ExtendedAttributes : "," ExtendedAttribute ExtendedAttributes"""
    p[0] = [p[2]] + p[3]


def do_code_hilite(md, what='all'):
    """
    "inverse" mode for source code highlighting:
    the file contains mainly code and md is within docstrings
    what in  all, code, doc, mod
    """
    if what not in ('all', 'code', 'doc', 'mod'):
        what = 'all'
    code_mode, md_mode = 1, 2
    blocks, block, mode = [], [], code_mode
    blocks.append([mode, block])
    lines = ('\n' + md).splitlines()
    mdstart = '\x01'
    while lines:
        line = lines.pop(0)
        if mode == code_mode:
            if line.rstrip() in ('"""_', "'''_", '/*_'):
                mdstart = line.rstrip()[:-1]
                mode = md_mode
                block = []
                if mdstart == '/*':
                    mdstart = '*/'
                blocks.append([md_mode, block])
                continue
        elif line.rstrip() == mdstart:
            if what == 'doc':
                break
            mode = code_mode
            block = []
            blocks.append([code_mode, block])
            continue
        if mode == code_mode:
            if what in ('all', 'code'):
                block.append(line)
        elif what != 'code':
            block.append(line)
    out = []
    for mode, block in blocks:
        b = '\n'.join(block)
        if not b:
            continue
        if mode == code_mode:
            out.append('```\n%s\n```' % b)
        else:
            out.append('\n'.join(block))
    return '\n'.join(out)


def is_float(s):
    """Returns true if s represents a float"""
    try:
        float(s)
        return True
    except ValueError:
        return False


def redirect(url):
    """
	Just a script for redirect to an another page
	"""
    return "<script>window.location.href='" + url + "';</script>"


def statement_is_fundef(node):
    """Return true if a statement node is for a function or macro definition.
  """
    tokens = node.get_semantic_tokens()
    if not tokens:
        return False
    funname = tokens[0].spelling.lower()
    return funname in ('function', 'macro')


def guess_atom_charge(atomname):
    """Guess atom charge from the name.

    .. Warning:: Not implemented; simply returns 0.
    """
    return 0.0


def task(*args, **kwargs):
    """Decorator to create and bind tasks to the env."""


def acl_get(path, item, st, numeric_owner=False):
    """
    Saves ACL Entries

    If `numeric_owner` is True the user/group field is not preserved only uid/gid
    """


def CMISId():
    """Return content CMIS identifier.
        """


@classmethod
def get(cls, top, parent=None):
    """
        Gather all the Overlay information for a switch
        The overlay object does not have a corresponding object in the APIC
        so does not cause a direct read of the APIC itself.  The children,
        tunnels, of the ConcreteOverlay are what trigger the read of the APIC.

        :param parent:
        :param top: the topSystem level json object
        :returns: Single overlay object in a list
        """
    cls.check_parent(parent)
    ovly = cls()
    ovly._top = top
    if parent.vpc_info:
        if parent.vpc_info['oper_state'] == 'active':
            ovly.attr['vpc_tep_ip'] = str(parent.vpc_info['vtep_ip'].split(
                '/')[0])
    if parent:
        ovly.attr['dn'] = str(parent.dn + '/overlay')
        ovly._parent = parent
        ovly._parent.add_child(ovly)
        ovly.node = ovly._parent.node
        ovly.pod = ovly._parent.pod
    else:
        ovly.attr['dn'] = '/overlay'
    return [ovly]


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

    The ".dev0" means dirty.

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


def create_app(object_name='pygameweb.config.Config', engine=None,
    session_factory=None):
    """returns a flask app.

    http://flask.pocoo.org/docs/patterns/appfactories/

    :param object_name: the object to load the config from.
    :param engine: an sqlalchemy engine.
    :param session_factory: an sqlalchemy session_factory.
    """
    from flask import Flask
    from flask_bootstrap import Bootstrap
    from flask_mail import Mail
    from pygameweb import db
    app = Flask(__name__)
    app.config.from_object(object_name)
    Bootstrap(app)
    db.init(app, engine, session_factory)
    Mail(app)
    if app.config['DEBUG'] and not app.config['TESTING']:
        app.config['DEBUG_TB_PROFILER_ENABLED'] = True
        app.config['DEBUG_TB_TEMPLATE_EDITOR_ENABLED'] = True
        app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False
        from flask_debugtoolbar import DebugToolbarExtension
        try:
            DebugToolbarExtension(app, sqlalchemy_engine=app.engine)
        except TypeError:
            DebugToolbarExtension(app)
    from pygameweb.cache import cache, limiter
    cache.init_app(app)
    if not app.config['TESTING']:
        limiter.init_app(app)
    return app


def split_filename(filename):
    """
    Received a standard style rpm fullname and returns
    name, version, release, epoch, arch
    Example: foo-1.0-1.i386.rpm returns foo, 1.0, 1, i386
             1:bar-9-123a.ia64.rpm returns bar, 9, 123a, 1, ia64

    This function replaces rpmUtils.miscutils.splitFilename, see
    https://bugzilla.redhat.com/1452801
    """
    if filename.endswith('.rpm'):
        filename = filename.split('.rpm')[0]
    components = filename.split(':')
    if len(components) > 1:
        epoch = components[0]
    else:
        epoch = ''
    arch = filename.rsplit('.')[-1]
    remaining = filename.rsplit('.%s' % arch)[0]
    release = remaining.rsplit('-')[-1]
    version = remaining.rsplit('-')[-2]
    name = '-'.join(remaining.rsplit('-')[:-2])
    return name, version, release, epoch, arch


def gather_nd(data=None, indices=None, name=None, attr=None, out=None, **kwargs
    ):
    """Gather elements or slices from `data` and store to a tensor whose
    shape is defined by `indices`.

    Given `data` with shape `(X_0, X_1, ..., X_{N-1})` and indices with shape
    `(M, Y_0, ..., Y_{K-1})`, the output will have shape `(Y_0, ..., Y_{K-1}, X_M, ..., X_{N-1})`,
    where `M <= N`. If `M == N`, output shape will simply be `(Y_0, ..., Y_{K-1})`.

    The elements in output is defined as follows::

      output[y_0, ..., y_{K-1}, x_M, ..., x_{N-1}] = data[indices[0, y_0, ..., y_{K-1}],
                                                          ...,
                                                          indices[M-1, y_0, ..., y_{K-1}],
                                                          x_M, ..., x_{N-1}]

    Examples::

      data = [[0, 1], [2, 3]]
      indices = [[1, 1, 0], [0, 1, 0]]
      gather_nd(data, indices) = [2, 3, 0]

      data = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
      indices = [[0, 1], [1, 0]]
      gather_nd(data, indices) = [[3, 4], [5, 6]]

    Parameters
    ----------
    data : Symbol
        data
    indices : Symbol
        indices

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

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


def p_enclosure(p):
    """enclosure : parenth_form
                  | string_conversion
                  | list_display
                  | table_display """
    p[0] = p[1]


def _set_center(el, pos):
    """Set element <el>'s center using its storer_rect as reference."""
    center_x, center_y = pos
    x_shift = 0
    y_shift = 0
    if center_x is not None:
        x_shift = center_x - el.get_storer_rect().centerx
    if center_y is not None:
        y_shift = center_y - el.get_storer_rect().centery
    el.move((x_shift, y_shift))


def get_event_labels_counted(event_log, key):
    """
    Fetches the labels (and their frequency) present in a log, given a key to use within the events.

    Parameters
    ----------
    :param event_log: log to use
    :param key: to use for event identification, can for example  be "concept:name"

    Returns
    -------
    :return: a list of labels
    """
    labels = dict()
    for t in event_log:
        for e in t:
            if key in e:
                if e[key] not in labels:
                    labels[e[key]] = 0
                labels[e[key]] = labels[e[key]] + 1
    return labels


@staticmethod
def get_sizes(count, share, validation=False):
    """With `count` samples, returns how many should go to train and test

        """
    if count == 1:
        if validation:
            return 1, 0, 0
        else:
            return 1, 0
    if count == 2:
        if validation:
            return 1, 1, 0
        else:
            return 1, 1
    n_train = int(count * share)
    assert n_train < count
    if n_train == 0:
        n_train += 1
    if not validation:
        return n_train, count - n_train
    elif count - n_train == 1:
        n_train -= 1
        return n_train, 1, 1
    else:
        n_val = int(int(count - n_train) / 2)
        return n_train, n_val, count - n_train - n_val


def getConfiguration(roomJID):
    """
        Grab the configuration from the room.

        This sends an iq request to the room.

        @param roomJID: The bare JID of the room.
        @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}

        @return: A deferred that fires with the room's configuration form as
            a L{data_form.Form} or C{None} if there are no configuration
            options available.
        """


@classmethod
def setUpClass(cls):
    """
        This method will be called before any tests of this class will be executed. It creates and starts a mock
        server thread using the callback which will save all the request received by the mock into a list of this
        class

        CHANGELOG

        Added 10.06.2019

        :return:
        """
    cls.MOCK_SERVER = cls.MOCK_SERVER_CLASS(callback=cls.request_callback)
    cls.MOCK_SERVER.start()


@classmethod
def batch_requests(cls, *requests):
    """
        Given many requests, will create a batch request per https://developers.google.com/discovery/v1/batch

        Arguments:

            *requests (aiogoogle.models.Request): Request objects

        Returns:

            aiogoogle.models.Request:
        """
    raise NotImplementedError


@staticmethod
def supports_site(url):
    """
        As long as the url exists, this crawler will work!

        Determines if this crawler works on the given url.

        :param str url: The url to test
        :return bool: Determines wether this crawler work on the given url
        """
    return True


@classmethod
def gen_schemas(cls):
    """Return json schema representation of the artifact type."""
    schemas_prop = {}
    for field_name, field in cls.fields.items():
        schemas_prop[field_name] = cls._schema_field(field, field_name=
            field_name)
    schemas = {'properties': schemas_prop, 'name': cls.get_type_name(),
        'version': cls.VERSION, 'title': 'Artifact type %s of version %s' %
        (cls.get_type_name(), cls.VERSION), 'type': 'object',
        'display_name': cls.get_display_type_name(), 'required': ['name']}
    return schemas


def tofloat(a):
    """  parse string list/tuple to float list """
    b = []
    for i in a:
        b.append(float(i))
    return b


def sort_resource_nb(contact):
    """Sort by number of connected resources"""
    return -len(contact)


def find_user_phid(p, user):
    """
    Fetches a phid for a given user.
    """
    phabUser = p.user.find(aliases=[user])
    return phabUser[user]


def list_attached_indices(DirectoryArn=None, TargetReference=None,
    NextToken=None, MaxResults=None, ConsistencyLevel=None):
    """
    Lists indices attached to an object.
    See also: AWS API Documentation

    :example: response = client.list_attached_indices(
        DirectoryArn='string',
        TargetReference={
            'Selector': 'string'
        },
        NextToken='string',
        MaxResults=123,
        ConsistencyLevel='SERIALIZABLE'|'EVENTUAL'
    )

    :type DirectoryArn: string
    :param DirectoryArn: [REQUIRED]
            The ARN of the directory.

    :type TargetReference: dict
    :param TargetReference: [REQUIRED]
            A reference to the object to that has indices attached.
            Selector (string) --A path selector supports easy selection of an object by the parent/child links leading to it from the directory root. Use the link names from each parent/child link to construct the path. Path selectors start with a slash (/) and link names are separated by slashes. For more information about paths, see Accessing Objects . You can identify an object in one of the following ways:
            $ObjectIdentifier - An object identifier is an opaque string provided by Amazon Cloud Directory. When creating objects, the system will provide you with the identifier of the created object. An object s identifier is immutable and no two objects will ever share the same object identifier
            /some/path - Identifies the object based on path
            #SomeBatchReference - Identifies the object in a batch call

    :type NextToken: string
    :param NextToken: The pagination token.

    :type MaxResults: integer
    :param MaxResults: The maximum number of results to retrieve.

    :type ConsistencyLevel: string
    :param ConsistencyLevel: The consistency level to use for this operation.

    :rtype: dict
    :return: {
        'IndexAttachments': [
            {
                'IndexedAttributes': [
                    {
                        'Key': {
                            'SchemaArn': 'string',
                            'FacetName': 'string',
                            'Name': 'string'
                        },
                        'Value': {
                            'StringValue': 'string',
                            'BinaryValue': b'bytes',
                            'BooleanValue': True|False,
                            'NumberValue': 'string',
                            'DatetimeValue': datetime(2015, 1, 1)
                        }
                    },
                ],
                'ObjectIdentifier': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def _find_human_readable_labels(synsets, synset_to_human):
    """Build a list of human-readable labels.

  Args:
    synsets: list of strings; each string is a unique WordNet ID.
    synset_to_human: dict of synset to human labels, e.g.,
      'n02119022' --> 'red fox, Vulpes vulpes'

  Returns:
    List of human-readable strings corresponding to each synset.
  """
    humans = []
    for s in synsets:
        assert s in synset_to_human, 'Failed to find: %s' % s
        humans.append(synset_to_human[s])
    return humans


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

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

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


@classmethod
def version_delete(cls, options):
    """Removes content-view version."""
    cls.command_sub = 'version delete'
    return cls.execute(cls._construct_command(options), ignore_stderr=True)


def GetInstanceConsole(r, instance):
    """
    Request information for connecting to instance's console.

    @type instance: string
    @param instance: Instance name
    """
    return r.request('get', '/2/instances/%s/console' % instance)


def take_at_most(iterable, n):
    """
    Return a list of at most `n` elements of an iterable, or all the elements
    of the iterable if there are less than `n`
    """
    iterator = iter(iterable)
    result = []
    try:
        for _ in range(n):
            result.append(next(iterator))
    except StopIteration:
        pass
    return result


@classmethod
def from_ini(cls, content):
    """ Create an instance of ``INIParser`` from some ini content string.

        :param str content: The ini content to create an instance from
        :return: The new ``INIParser`` instance
        :rtype: INIParser
        """
    parser = cls()
    parser.read_string(content)
    return parser


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


@classmethod
def systemGrants(cls):
    """return dictionary of all system grants with their descriptions"""
    import pkgutil
    from importlib import import_module
    from .. import _grants
    result = {}
    for mdata in pkgutil.iter_modules(_grants.__path__):
        mod = import_module(_grants.__package__ + '.' + mdata[1])
        result.update(getattr(mod, 'grants'))
    return result


def deserialize_datetime(string):
    """
    Deserializes string to datetime.

    The string should be in iso8601 datetime format.

    :param string: str.
    :type string: str
    :return: datetime.
    :rtype: datetime
    """
    try:
        from dateutil.parser import parse
        return parse(string)
    except ImportError:
        return string


def make_cnx_string(location, database):
    """
    Make a connection string for sqlalchemy for either sql or sqlite.

    Args
    ------
    location : str
    database : str, either 'sql' or 'sqlite'

    Returns
    ------
    location : str, amended location string for sqlalchemy

    """
    if database not in ['sql', 'sqlite']:
        raise Exception('database must be "sql" or "sqlite"')
    if database == 'sqlite':
        if 'sqlite:///' not in location:
            location = 'sqlite:///' + location
    if database == 'sql':
        if 'mysql+mysqlconnector://' not in location:
            location = 'mysql+mysqlconnector://' + location
    return location


def inline(*args):
    """
    Dummy 'inline' Quant DSL decorator - we just want the name in the namespace.
    """
    import mock
    return mock.Mock


def statement(engine, query):
    """ Statement compiler for a given SQLAlchemy engine + query.

        Arguments:
            engine (sqlalchemy.engine.Engine):  SQLAlchemy connection engine
            query  (sqlalchemy.orm.Query):      SQLAlchemy query

        Returns:
            Compiled engine-specific statement. """
    stmt = query.statement.compile(engine)
    return stmt


def get_model_name(model):
    """
    Returns the name of the model
    """
    return model._meta.model_name


def _mark_choice_letters_used(count, context):
    """Marks the choice letters as used."""
    for i in range(count):
        context.mark_used(chr(ord('a') + i))


@staticmethod
def _get_power_from_obstruction_class(face, e01, e02, ptolemy_index):
    """
        This reimplements _get_power_from_obstruction_class
        from addl_code/ptolemy_equations.c

        Let face face of a tetrahedron be glued to some other face. This
        will identify two Ptolemy coordinates up to a sign and an N-th root
        of unity (for an PSL(N,C)-representation. I.e., we get an equation
        between Ptolemy coordinates of the form
        (+/-) u^p c_index_t = c_index'_t'
        where u is the N-th root of unity, c_index_t is the Ptolemy coordinate
        on the given face and c_index'_t' on the face that it glued to the
        given face.
        _compute_sign will give the sign (+/-) based on the index and the
        face gluing permutation.
        _get_power_from_obstruction_class will give p given the face, the
        Ptolemy index and the edge cocycle that assigns e01 to the edge 01
        and e02 to the edge e02 that is determined through the cohomology
        obstruction class by _get_obstruction_on_edges.
        """
    v1 = (face + 2) % 4
    v2 = (face + 3) % 4
    return ptolemy_index[v1] * e01 + ptolemy_index[v2] * e02


@staticmethod
def _is_indexable(data):
    """
        Check if the data object is indexable.

        Parameters:
            data: The data to be partitioned

        Returns:
            bool: True, if data is an indexable object. False, otherwise.
        """
    if hasattr(data, '__len__') and hasattr(data, '__getitem__'):
        return True
    else:
        return False


def __getitem__(key):
    """get state of zip job
        """


def print_scientific_double(value: float) ->str:
    """
    Prints a value in 16-character scientific double precision.

    Scientific Notation:                   5.0E+1
    Double Precision Scientific Notation:  5.0D+1
    """
    if value < 0:
        Format = '%16.9e'
    else:
        Format = '%16.10e'
    svalue = Format % value
    field = svalue.replace('e', 'D')
    if field == '-0.0000000000D+00':
        field = '0.0000000000D+00'
    return field


@classmethod
def get_name(cls):
    """ Returns the name of the optimizer.

			# Return value

			A lower-case string unique to this optimizer.
		"""
    return cls.__name__.lower()


def parse_cluster_pubsub_numpat(res, **options):
    """
    Result callback, handles different return types
    switchable by the `aggregate` flag.
    """
    aggregate = options.get('aggregate', True)
    if not aggregate:
        return res
    numpat = 0
    for node, node_numpat in res.items():
        numpat += node_numpat
    return numpat


def p_values_last(p):
    """values : named_signal_value"""
    p[0] = [p[1]]


def update_ipmi_properties(task):
    """Update ipmi properties to node driver_info

    :param task: a task from TaskManager.
    """
    node = task.node
    info = node.driver_info
    info['ipmi_address'] = info.get('ilo_address')
    info['ipmi_username'] = info.get('ilo_username')
    info['ipmi_password'] = info.get('ilo_password')
    if 'console_port' in info:
        info['ipmi_terminal_port'] = info['console_port']
    task.node.driver_info = info


@classmethod
def add_hostgroup(cls, options=None):
    """Associate a hostgroup"""
    cls.command_sub = 'add-hostgroup'
    return cls.execute(cls._construct_command(options))


@classmethod
def register(cls, resource_body_cls):
    """Register resource."""
    resource_type = resource_body_cls.resource_type
    assert resource_type not in cls._REGISTERED_TYPES
    cls._REGISTERED_TYPES[resource_type] = resource_body_cls
    return resource_body_cls


def ip2long(ip_addr):
    """Converts an IP address string to an integer."""
    from socket import inet_aton
    from struct import unpack
    ip_packed = inet_aton(ip_addr)
    ip = unpack('!L', ip_packed)[0]
    return ip


@classmethod
def from_transfer_format(cls, fmt, raw_bytes, resolution):
    """
        Given the raw bytes string received from the socket and the resolution of the image, this method will create
        a new PhantomImage object from that information using the format identified by the given string format token
        name "fmt"

        CHANGELOG

        Added 28.02.2019

        Changed 12.07.2019
        Added the 'P12L' format

        :param fmt:
        :param raw_bytes:
        :param resolution:
        :return:
        """
    _methods = {'P16': cls.from_p16, 'P16R': cls.from_p16, 'P8': cls.
        from_p8, 'P8R': cls.from_p8, 'P10': cls.from_p10, 'P12L': cls.
        from_p12l()}
    return _methods[fmt](raw_bytes, resolution)


def parse_public_key(user_pubkey):
    """ Return paramiko key class instance of a user's public key text. """
    import paramiko
    if len(user_pubkey.split()) == 3:
        key_msg, key_data, _ = user_pubkey.split()
    elif len(user_pubkey.split()) == 2:
        key_msg, key_data = user_pubkey.split()
    elif len(user_pubkey.split()) == 1:
        key_msg, key_data = 'ssh-rsa', user_pubkey
    else:
        raise ValueError('Malformed public key format: {0!r}'.format(
            user_pubkey))
    try:
        key_bytes = key_data.decode('ascii')
    except UnicodeDecodeError:
        raise ValueError('Malformed public key encoding: {0!r}'.format(
            key_data))
    decoded_keybytes = paramiko.py3compat.decodebytes(key_bytes)
    try:
        return {'ssh-rsa': paramiko.RSAKey, 'ssh-dss': paramiko.DSSKey,
            'ecdsa-sha2-nistp256': paramiko.ECDSAKey}.get(key_msg)(data=
            decoded_keybytes)
    except KeyError:
        raise ValueError('Malformed public key_msg: {0!r}'.format(key_msg))


def vertex_group_normalize():
    """Normalize weights of the active vertex group, so that the highest ones are now 1.0

    """
    pass


def flip(array, axis=1):
    """Defines the missing numpy.flip function."""
    indexer = [slice(None)] * array.ndim
    indexer[axis] = slice(None, None, -1)
    return array[tuple(indexer)]


def ssqrange(charge, sz, nsingle):
    """
    Make a list giving all possible :math:`S^{2}` values for given charge and :math:`S_{z}`.

    Parameters
    ----------
    charge : int
        Value of the charge.
    sz : int
        Value of sz.
    nsingle : int
        Number of single particle states.

    Returns
    -------
    list
        List of all possible :math:`S^{2}` values for given charge and :math:`S_{z}`.
    """
    szmax = min(charge, nsingle - charge)
    return list(range(abs(sz), szmax + 1, +2))


def get_region(chrom, start, end, region_trees):
    """Check if a position overlapps any regions

    Arguments:
       chrom (str): The chromosome
       start (int): The start position for the feature
       end (int): The stop position for the feature
       region_trees (dict): A dictionary with chromosomes as keys and interval trees as values

    Returns:
        regions (set): The regions that the variant ovelapps
    """
    regions = set()
    if chrom in region_trees:
        tree = region_trees[chrom]
        result = tree[start:end]
        for interval in result:
            regions.add(interval.data)
    return regions


def _validate_dependencies_met():
    """
    Verifies that PyOpenSSL's package-level dependencies have been met.
    Throws `ImportError` if they are not met.
    """
    from cryptography.x509.extensions import Extensions
    if getattr(Extensions, 'get_extension_for_class', None) is None:
        raise ImportError(
            "'cryptography' module missing required functionality.  Try upgrading to v1.3.4 or newer."
            )
    from OpenSSL.crypto import X509
    x509 = X509()
    if getattr(x509, '_x509', None) is None:
        raise ImportError(
            "'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer."
            )


@classmethod
def get_types_of_payers(cls):
    """
        Method for fetching info about types of payers.

        :example:
            ``Common.get_types_of_payers()``
        :return:
            dictionary with info about types of payers
        """
    return cls.send(method='getTypesOfPayers')


def cache_directives_in_headers(headers):
    """
    Checks if cache controls are set in response headers
    """
    cache_control = 'cache-control' in headers
    pragma = 'pragma' in headers and 'no-cache' in headers['pragma']
    expires = 'expires' in headers
    return expires or pragma or cache_control


def load_from_entry_points():
    """Loads extensions from "tatoo.extensions" entry points."""


@classmethod
def get_object(cls, identifiant, token=None):
    """Return an instance of a class based on its identifiant"""
    if identifiant in cls._LIST_OBJECTS:
        return cls._LIST_OBJECTS[identifiant]
    else:
        return cls(token, identifiant)


def flux_density_gruen(m):
    """
    Flux density as given by Gruen (1985). May eventually be moved to a util file.

    :param float m: mass in grams
    :return: Number of objects per metre squared per second
    """
    n = (2200.0 * m ** 0.306 + 15.0) ** -4.38 + 1.3e-09 * (m +
        100000000000.0 * m ** 2 + 1e+27 * m ** 4) ** -0.36 + 1.3e-16 * (m +
        1000000.0 * m ** 2) ** -0.85
    return n


def strip_and_pad(name):
    """Makes the list 3 digits long.

    If the _name_ list is passed in with more than three digits then
    only the first three digits are kept. If the _name_ list is shorter
    than three digits then the _name_ list is padded with '0' until it
    is three digits long.

    :param name: The name list
    :return: A list that is only 3 digits long.

    """
    if not name:
        return ['0', '0', '0']
    if len(name) > 3:
        name = name[:3]
    elif len(name) < 3:
        while len(name) < 3:
            name.append('0')
    return name


@classmethod
def available_serializers(cls):
    """Get the list of available serialization formats

        Returns
        -------
        :class:`list` of :class:`str`
        """
    return list(cls._serializers.keys())


def write_to_stream(stream, data):
    """
    Write data to the given stream, then close the stream.
    """
    stream.write(data)
    stream.close()


def init_fuel_tech_p_by(all_enduses_with_fuels, fueltypes_nr):
    """Helper function to define stocks for all enduse and fueltype

    Arguments
    ----------
    all_enduses_with_fuels : dict
        Provided fuels
    fueltypes_nr : int
        Nr of fueltypes

    Returns
    -------
    fuel_tech_p_by : dict

    """
    fuel_tech_p_by = {}
    fueltpe_dicts = dict.fromkeys(range(fueltypes_nr), {})
    for enduse in all_enduses_with_fuels:
        fuel_tech_p_by[enduse] = dict(fueltpe_dicts)
    return fuel_tech_p_by


def final_spin_of_merger_from_NR(*args, NRfit='average', return_fits_used=False
    ):
    """Return the final spin resulting from a BBH merger using NR fits

    Parameters
    ----------
    NRfit: str
        Name of the fit you wish to use. If you wish to use a precessing fit
        please use the syntax 'precessing_{}'.format(fit_name). If you wish
        to have an average NR fit, then pass 'average'
    return_fits_used: Bool, optional
        if True, return the fits that were used. Only used when NRfit='average'
    """
    from pesummary.gw.file import nrutils
    if NRfit.lower() == 'average':
        func = getattr(nrutils, 'bbh_final_spin_average_precessing')
    elif 'pan' in NRfit.lower():
        func = getattr(nrutils, 'bbh_final_spin_non_spinning_Panetal')
    elif 'precessing' in NRfit.lower():
        func = getattr(nrutils, 'bbh_final_spin_precessing_{}'.format(NRfit
            .split('precessing_')[1]))
    else:
        func = getattr(nrutils, 'bbh_final_spin_non_precessing_{}'.format(
            NRfit))
    if NRfit.lower() == 'average':
        return func(*args, return_fits_used=return_fits_used)
    return func(*args)


def rgb2hex(color):
    """Converts an RGB tupple or list to a hex string."""
    hex_clr = '#' + bytes(color).hex()
    return hex_clr


def PNT2Tidal_Pv10(XA):
    """ TaylorT2 0PN Quadrupolar Tidal Coefficient, v^10 Phasing Term.

   XA = mass fraction of object """
    return 72 - 66 * XA


def map_brand(output_db, scraper_id, scraper_company, scraper_brand):
    """Get the canonical company corresponding to the
    given brand in the scraper data."""
    select_sql = (
        'SELECT company, brand FROM scraper_brand_map WHERE scraper_id = ? AND scraper_company = ? AND scraper_brand = ?'
        )
    rows = list(output_db.execute(select_sql, [scraper_id, scraper_company,
        scraper_brand]))
    if rows:
        return tuple(rows[0])
    else:
        return None