def bone_layers(layers: bool=(False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False)):
    """Change the layers that the selected bones belong to

    :param layers: Layer, Armature layers that bone belongs to
    :type layers: bool
    """
    pass


def assert_awaited(_mock_self):
    """
        Assert that the mock was awaited at least once.
        """
    self = _mock_self
    if self.await_count == 0:
        msg = f"Expected {self._mock_name or 'mock'} to have been awaited."
        raise AssertionError(msg)


def p_flag_multi_line(p):
    """flag : K_MULTI K_LINE
    """
    p[0] = [('multi_line', ())]


def print_stats(combinations, entropy):
    """Convenience wrapper to format basic password stats

    Return formatted combination and entropy of password

    Args:
        combinations (int): number of combinations of password

        entropy (float): entropy of password

    Returns:
        tuple: two strings holding formatted output ready for printing

    Example:
        >>> a, b = print_stats(10000, 97.235)
        >>> print(a)
        Passwords Combinations: 1.00e+4
        >>> print(b)
        Password Entropy: 97.24
    """
    comb = 'Password Combinations: {0:.2e}'.format(combinations)
    ent = 'Password Entropy: {0:.2f}'.format(entropy)
    return comb, ent


def get_zip_file(url, filepath):
    """Gets zip file from url.

    Args:
        url: A string, the url of zip file.
        filepath: A string, the file path inside the zip file.

    Returns:
        A String, the content of wanted file.
    """
    from io import BytesIO
    from io import StringIO
    from zipfile import ZipFile
    import requests
    zipfile = ZipFile(BytesIO(requests.get(url).content))
    file = zipfile.open(filepath).read().decode('utf8')
    return StringIO(file)


@classmethod
def make_disabled_fields(cls, obj, ar):
    """
        Return a set of disabled fields for the specified object and
        request.

        See :doc:`/dev/disabled_fields`.
        """
    s = set()
    state = cls.get_row_state(obj)
    if state is not None:
        s |= cls._state_to_disabled_actions.get(state.name, set())
    return s


def prompt(name, default=None):
    """
    Grab user input from command line.

    :param name: prompt text
    :param default: default value if no input provided.
    """
    prompt = name + (default and ' [%s]' % default or '')
    prompt += name.endswith('?') and ' ' or ': '
    while True:
        rv = input(prompt)
        if rv:
            return rv
        if default is not None:
            return default


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


def _parse_command_rbioc(command, param_set):
    """
    Parse command in Rbioc.

    Find a r-bioc command and replace the inputs and
    outputs with appropriate galaxy template.
    """
    cmd = command.split(' ')
    count = 0
    for i in range(len(cmd)):
        if '--' in cmd[i]:
            cmd[i + 1] = '$' + param_set[count].split('.')[0]
            count = count + 1
    return ' '.join(cmd)


def distance_from_dist_mod(mu):
    """
    d = 10**(1 + mu / 5)
    """
    d = 10 ** (1 + mu / 5)
    return d


@classmethod
def channels_axis(cls, data_format='channels_last'):
    """ Return the channels axis for the tensor

        Parameters
        ----------
        data_format : str {'channels_last', 'channels_first', 'N***'} or None

        Returns
        -------
        int
        """
    return 1 if data_format == 'channels_first' or data_format.startswith('NC'
        ) else -1


@classmethod
def newCalibrationParameters(cls):
    """ Create a new instance of CalibrationParameters with all parameters
            set to None -- i.e. work around Python's fake OOP implementation's
            inability to have more than one constructor

            @return New instance of CalibrationParameters
        """
    obj = cls(None, None, None, None, None, None, None, None, None, None,
        None, None, None)
    return obj


@classmethod
def extended(cls, atom1, atom2, atom3, atom4, atom5, atom6, atom7, atom8,
    type=None):
    """
        Alternative constructor for correction maps defined with 8 atoms (each
        torsion being separately specified). Correction maps are, to the best of
        my knowledge, used to parametrized "consecutive" torsions (i.e., atoms
        2, 3, and 4 are common to both torsions). However, the CHARMM definition
        specifies the torsions separately.

        If the torsions are _not_ consecutive (i.e., if atoms 2, 3, and 4 are
        not the same as atoms 5, 6, and 7), NotImplementedError is raised.

        Parameters
        ----------
        atom1 : :class:`Atom`
            The first atom of the first torsion
        atom2 : :class:`Atom`
            The second atom of the first torsion
        atom3 : :class:`Atom`
            The third atom of the first torsion
        atom4 : :class:`Atom`
            The fourth atom of the first torsion
        atom5 : :class:`Atom`
            The first atom of the second torsion
        atom6 : :class:`Atom`
            The second atom of the second torsion
        atom7 : :class:`Atom`
            The third atom of the second torsion
        atom8 : :class:`Atom`
            The fourth atom of the second torsion
        type : :class:`CmapType`
            The CmapType object containing the parameter map for this term
        """
    if atom2 is not atom5 or atom3 is not atom6 or atom7 is not atom4:
        raise NotImplementedError(
            'Only consecutive coupled-torsions are supported by CMAPs currently'
            )
    return cls(atom1, atom2, atom3, atom4, atom8, type=type)


@staticmethod
def compress(tensor):
    """Compresses a tensor and returns it with the context needed to decompress it."""
    pass


@classmethod
def export_journal(cls, journal):
    """Returns a string representation of an entire journal."""
    vars = {'journal': journal, 'entries': journal.entries, 'tags': journal
        .tags}
    return cls.template.render_block('journal', **vars)


def _rescale_layout(pos, scale=1):
    """
    Normalize the given coordinate list to the range [0, `scale`].

    Parameters
    ----------
    pos : array
        Coordinate list
    scale : number
        The upperbound value for the coordinates range

    Returns
    -------
    pos : array
        The rescaled (normalized) coordinates in the range [0, `scale`].

    Notes
    -----
    Changes `pos` in place.
    """
    pos -= pos.min(axis=0)
    pos *= scale / pos.max()
    return pos


def update_none(arg, update_by):
    """Update arguments with some default value
    Args:
        arg: variable object
        update_by: variable object
    """
    if arg is None:
        return update_by
    else:
        return arg


def valid_trait(trait, allow_forbidden):
    """Return True if the provided trait is the expected form.

    When allow_forbidden is True, then a leading '!' is acceptable.
    """
    if trait.startswith('!') and not allow_forbidden:
        return False
    return True


def psi_Na_HSO4_OH_HMW84(T, P):
    """c-a-a': sodium bisulfate hydroxide [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@staticmethod
def p_xcp_on_can_optional_list(p):
    """xcp_on_can_optional_list : xcp_on_can_optional
                                    | xcp_on_can_optional xcp_on_can_optional_list"""
    try:
        p[0] = [p[1]] + p[2]
    except IndexError:
        p[0] = [p[1]]


def dd():
    """Return day as a 2 digit string"""


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 booleans(request):
    """
    Allow to use booleans in templates.

    See: http://stackoverflow.com/questions/4557114/django-custom-template-tag-which-accepts-a-boolean-parameter
    """
    return {'True': True, 'true': True, 'False': False, 'false': False}


def dummy_sgs(dummies, sym, n):
    """
    Return the strong generators for dummy indices

    Parameters
    ==========

    dummies : list of dummy indices
        `dummies[2k], dummies[2k+1]` are paired indices
    sym : symmetry under interchange of contracted dummies::
        * None  no symmetry
        * 0     commuting
        * 1     anticommuting

    n : number of indices

    in base form the dummy indices are always in consecutive positions

    Examples
    ========

    >>> from sympy.combinatorics.tensor_can import dummy_sgs
    >>> dummy_sgs(list(range(2, 8)), 0, 8)
    [[0, 1, 3, 2, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 5, 4, 6, 7, 8, 9],
     [0, 1, 2, 3, 4, 5, 7, 6, 8, 9], [0, 1, 4, 5, 2, 3, 6, 7, 8, 9],
     [0, 1, 2, 3, 6, 7, 4, 5, 8, 9]]
    """
    if len(dummies) > n:
        raise ValueError('List too large')
    res = []
    if sym is not None:
        for j in dummies[::2]:
            a = list(range(n + 2))
            if sym == 1:
                a[n] = n + 1
                a[n + 1] = n
            a[j], a[j + 1] = a[j + 1], a[j]
            res.append(a)
    for j in dummies[:-3:2]:
        a = list(range(n + 2))
        a[j:j + 4] = a[j + 2], a[j + 3], a[j], a[j + 1]
        res.append(a)
    return res


def crop_matrix(data, start_col, stop_col):
    """
    Crop matrix (remove columns). The resulting matrix will be [start_col, stop_col]

    :param data: the data to sort.
    :type data: a 2D :class:`pandas.DataFrame` object.
    :param start_col: The name of the first column to keep.
    :type start_col: string.
    :param stop_col: The name of the last column to keep.
    :type stop_col: string.
    :return: sorted data.
    :rtype: a 2D :class:`pandas.DataFrame` object or None if data is None.
    """
    if data is None or data.empty:
        return data
    return data.loc[:, start_col:stop_col]


def asbool(value, true=(b'true', 'true'), false=(b'false', 'false')):
    """Return string as bool if possible, else raise TypeError.

    >>> asbool(b' False ')
    False

    """
    value = value.strip().lower()
    if value in true:
        return True
    if value in false:
        return False
    raise TypeError()


@staticmethod
def _find_the_caller(i=0):
    """Finds the caller of logging method

        :param i: number of upper elements relatively to the place of calling
            `_find_the_caller` method
        :return: a tuple where the first element is a filename, the second is
            a line number and the third is a line of code
        """
    import inspect
    i = i + 2
    caller = inspect.stack()[i]
    return caller[1], caller[2], caller[4][0].rstrip('\n').strip()


@classmethod
def from_page(cls, pageobj):
    """Return the ValidationEvent object for a given ValidationPage
        object.
        """
    return cls(pageobj.site, pageobj.release, pageobj.milestone, pageobj.
        compose, modular=pageobj.modular)


@staticmethod
def __indent__(column, value, maxvalue=0):
    """ May be used for special indent for first column """
    return '{0:<14}'.format(value) if column == maxvalue else '{0:>11}'.format(
        value)


def project_opened(project):
    """This function is called after opening the project"""


@classmethod
def create_from_file(cls, filename):
    """Read initdata and spectral data from file, and use those to create a new SpectrumData object.

        Parameters
        ----------
        filename: str

        Returns
        -------
        SpectrumData
            new SpectrumData object, initialized with data read from file
        """
    import scqubits.io_utils.fileio as io
    return io.read(filename)


@classmethod
def FromPartition(cls, partition, **kwargs):
    """ Create a new partition from an existing partition.

    Parameters
    ----------
    partition
      The :class:`~VertexPartition.MutableVertexPartition` to replicate.

    **kwargs
      Any remaining keyword arguments will be passed on to the constructor of
      the new partition.

    Notes
    -----
    This may for example come in handy when determining the quality of a
    partition using a different method. Suppose that we already have a
    partition ``p`` and that we want to determine the Significance of that
    partition. We can then simply use

    >>> p = la.find_partition(ig.Graph.Famous('Zachary'),
    ...                       la.ModularityVertexPartition)
    >>> sig = la.SignificanceVertexPartition.FromPartition(p).quality()
    """
    new_partition = cls(partition.graph, partition.membership, **kwargs)
    return new_partition


@staticmethod
def _parse_dn(dn):
    """Parses the pod, node from a
           distinguished name of the node and fills in the slot to be '1'

           :param dn: dn of node

           :returns: pod, node, slot
        """
    name = dn.split('/')
    pod = str(name[1].split('-')[1])
    node = str(name[2].split('-')[1])
    slot = '1'
    return pod, node, slot


def _unsafe_split_mgm(filename):
    """
    Takes a properly formatted path starting with 'root:' and containing '/store'
    """
    if not filename.startswith('root://'):
        raise ValueError('Cannot split mgm; passed filename: {0}'.format(
            filename))
    elif not '/store' in filename:
        raise ValueError("No substring '/store' in filename {0}".format(
            filename))
    i = filename.index('/store')
    mgm = filename[:i]
    lfn = filename[i:]
    return mgm, lfn


def get_ending(fit_format: int) ->str:
    """Get the file extension for a given fit format.

    Args:
        fit_format (int): .csv (0) or .pkl (1).

    Raises:
        Exception: If an invalid fit format is provided.

    Returns:
        str: The extension for the provided fit format.
    """
    if fit_format in [0]:
        ending = '.csv'
    elif fit_format == 1:
        ending = '.pkl'
    else:
        raise Exception('No such fit format: %s' % fit_format)
    return ending


def work(every, **kwargs):
    """
    Make the job to work
    :param every:
    :return:
    """
    raise NotImplemented


@classmethod
def from_csv(cls, filepath):
    """
        read menyanthes hydromonitor csv export file

        parameters
        ----------
        filepath : str
                   path to hydromonitor csv export file

        returns
        -------
        HydroMonitor object

        """
    header, metadata, data = cls._readcsv(cls, filepath)
    return cls(header=header, metadata=metadata, data=data)


def replace_route_table_association(DryRun=None, AssociationId=None,
    RouteTableId=None):
    """
    Changes the route table associated with a given subnet in a VPC. After the operation completes, the subnet uses the routes in the new route table it's associated with. For more information about route tables, see Route Tables in the Amazon Virtual Private Cloud User Guide .
    You can also use ReplaceRouteTableAssociation to change which table is the main route table in the VPC. You just specify the main route table's association ID and the route table to be the new main route table.
    See also: AWS API Documentation

    Examples
    This example associates the specified route table with the subnet for the specified route table association.
    Expected Output:

    :example: response = client.replace_route_table_association(
        DryRun=True|False,
        AssociationId='string',
        RouteTableId='string'
    )

    :type DryRun: boolean
    :param DryRun: Checks whether you have the required permissions for the action, without actually making the request, and provides an error response. If you have the required permissions, the error response is DryRunOperation . Otherwise, it is UnauthorizedOperation .

    :type AssociationId: string
    :param AssociationId: [REQUIRED]
            The association ID.

    :type RouteTableId: string
    :param RouteTableId: [REQUIRED]
            The ID of the new route table to associate with the subnet.

    :rtype: dict
    :return: {
        'NewAssociationId': 'string'
    }

    """
    pass


def validate_args(args):
    """
    Performs validation of common arguments provided to hooks.
    Currently only checks if key and certificate are both provided if either are.

    Args:
        args: arguments parsed from argparser object
    """
    if (args.clientcert or args.clientkey) and not (args.clientcert and
        args.clientkey):
        print(
            "Either both '--clientcert' and '--clientkey' must be set or neither should be set."
            )
        exit(1)


def delete_left(node, indices):
    """Delete the left part of an HTML tree.
    """
    for idx in indices:
        del node.contents[:idx]
        node = node.contents[0]


def dayshift(dataset, days=1):
    """
    Adds one day's worth of seconds to the dataset's epoch timestamp (dataset['tstamp'])
    """
    dataset['tstamp'] += days * 24 * 60 * 60
    return dataset


def ensure_latex(string):
    """Inserts $'s at the beginning and end of the string, if necessary."""
    if string.strip()[0] != '$':
        string = '$' + string
    if string.strip()[-1] != '$':
        string = string + '$'
    return string


def C2F(C):
    """Convert Celsius to Fahrenheit"""
    return 1.8 * C + 32


def unordered_domain_values(var, assignment, csp):
    """The default value order."""
    return csp.choices(var)


def has_key(key):
    """Tell if a key exists in the mapping; equivalent to __contains__"""


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 _np_dot(a, b, out=None):
    """
    Dot product of two arrays. Specifically,

    - If both `a` and `b` are 1-D arrays, it is inner product of vectors

    - If both `a` and `b` are 2-D arrays, it is matrix multiplication,

    - If either `a` or `b` is 0-D (scalar), it is equivalent to :func:`multiply`
      and using ``np.multiply(a, b)`` or ``a * b`` is preferred.

    - If `a` is an N-D array and `b` is a 1-D array, it is a sum product over
      the last axis of `a` and `b`.

    - If `a` is an N-D array and `b` is a 2-D array, it is a
      sum product over the last axis of `a` and the second-to-last axis of `b`::

        dot(a, b)[i,j,k] = sum(a[i,j,:] * b[:,k])

    Parameters
    ----------
    a : ndarray
        First argument.
    b : ndarray
        Second argument.

    out : ndarray, optional
        Output argument. It must have the same shape and type as the expected output.

    Returns
    -------
    output : ndarray
        Returns the dot product of `a` and `b`.  If `a` and `b` are both
        scalars or both 1-D arrays then a scalar is returned; otherwise
        an array is returned.
        If `out` is given, then it is returned

    Examples
    --------
    >>> a = np.array(3)
    >>> b = np.array(4)
    >>> np.dot(a, b)
    array(12.)

    For 2-D arrays it is the matrix product:

    >>> a = np.array([[1, 0], [0, 1]])
    >>> b = np.array([[4, 1], [2, 2]])
    >>> np.dot(a, b)
    array([[4., 1.],
           [2., 2.]])

    >>> a = np.arange(3*4*5*6).reshape((3,4,5,6))
    >>> b = np.arange(5*6)[::-1].reshape((6,5))
    >>> np.dot(a, b)[2,3,2,2]
    array(29884.)
    >>> np.sum(a[2,3,2,:] * b[:,2])
    array(29884.)
    """
    pass


def euclidean_distance(histo1, histo2):
    """
    Euclidean distance between two histograms

    :param histo1:
    :param histo2:
    :return:
    """
    val = 0
    lnot = []
    for w in histo1:
        if w in histo2:
            val += (histo1[w] - histo2[w]) ** 2
            lnot.append(w)
        else:
            val += histo1[w] * histo1[w]
    for w in histo2:
        if w not in lnot:
            val += histo2[w] * histo2[w]
    return val


def _extract_action_num_and_node_id(m):
    """Helper method: Extract *action_num* and *node_id* from the given regex
    match. Convert *action_num* to a 0-indexed integer."""
    return dict(action_num=int(m.group('action_num')) - 1, node_id=m.group(
        'node_id'))


@classmethod
def process_param(cls, param):
    """Process an @param decorator into a ParameterInfo."""
    return None


@classmethod
def disconnect(cls, entry):
    """Disconnect the social account for the given user"""
    raise NotImplementedError('Implement in subclass')


def save_graphlet_document(gexf_fh, gidx, num_graphlets, samplesize,
    cooccurence_corpus):
    """Saves the induced graphlet patterns into dataset folder, it is only used in conjunction
    with graphlet_corpus()

    Parameters
    ----------
    gexf_fh : str
        path to gexf file of graph
    gidx : int
        integer id of the graph, typically matches number in
        gexf_fh, if using TU Dortmund benchmark datasets
    num_graphlets : int
        size of graphlet patterns induced
    samplesize : int
        number of graphlet patterns sampled from graph
    cooccurrence_corpus : list
        list of graphlet patterns induced under cooccurrence
        rules, in this case all graphlets immediately adjacent
        to an induced graphlet pattern.

    Returns
    -------
    None : None
        The decomposition algorithm will induce graphlet patterns for graphs
        recording the dataset/"global" vocabulary of patterns within a dictionary.
        The graph and its associated patterns (by IDs given through our hash function)
        are saved into a  <graphid>.wldr<depth> file which contains a line delimited
        list of all the substructure pattern ids.

    """
    open_fname = gexf_fh + '.graphlet' + '_ng_' + str(num_graphlets
        ) + '_ss_' + str(samplesize)
    with open(open_fname, 'w') as fh:
        for graphlet_neighbourhood in cooccurence_corpus:
            sentence = str.join(' ', map(str, graphlet_neighbourhood))
            print(sentence, file=fh)


def datetime2dic(datetimeobj, dic):
    """
    Add datetime object to dictionary
    """
    dic['date'] = datetimeobj.ctime()
    return dic


def version_lower_than(gaphor_version, version):
    """
    Only major and minor versions are checked.

    >>> version_lower_than('0.3.0', (0, 15, 0))
    True

    """
    parts = gaphor_version.split('.')
    return tuple(map(int, parts[:2])) < version[:2]


def _compute_inside_group(df):
    """
    Compute inside Group
    Args:
        df(dataframe):

    Returns: Dataframe

    """
    inside_group = df.copy()
    inside_group['type'] = 'child'
    inside_group['variation'] = inside_group['value'] / inside_group[
        'value_start']
    inside_group.drop(['upperGroup_label', 'insideGroup', 'value_start'],
        axis=1, inplace=True)
    inside_group.rename(columns={'insideGroup_label': 'label'}, inplace=True)
    return inside_group


def save_text_to_file(content: str, path: str):
    """ Saves text to file """
    with open(path, mode='w') as text_file:
        text_file.write(content)


def uch_psri(x, dp, d_pipe, gs, rhog, rhos, ut):
    """
    Choking velocity from PSRI 2016 notebook. Uses MKS units for input
    parameters but returns Uch in ft/s. Function requires SciPy fsolve to solve
    for Uch.

    Parameters
    ----------
    x : float
        Solve for Uch with SciPy fsolve
    dp : float
        Particle size [m]
    d_pipe : float
        Pipe diameter [m]
    gs : float
        Solids mass flux [kg/(s m^2)]
    rhog : float
        Density of gas [kg/m^3]
    rhos : float
        Density of particle [kg/m^3]
    ut : float
        Terminal velocity [m/s]

    Returns
    -------
    uch : float
        Choking velocity [ft/s]

    References
    ----------
    Notebook from PSRI 2016 workshop, pages J-20 and J-72.
    """
    uch = x
    g = 32.2
    dp = dp * 3.28084
    d_pipe = d_pipe * 3.28084
    gs = gs * 0.204817303
    rhog = rhog * 0.062428
    rhos = rhos * 0.062428
    ut = ut * 3.28084
    f1 = (uch - ut) / (g * dp) ** 0.5 - (gs / (uch * rhog)) ** 0.35 * (d_pipe /
        dp) ** 0.35 * (rhos / rhog) ** 0.1
    return f1


def upsert(dyn_query):
    """ Save or Update DynQuery.

    Args:
        dyn_query:

    Returns:

    """
    return dyn_query.save()


def datetime(value, format_str='%Y/%m/%d %H:%M'):
    """
    Convert a datetime to a different format.

    The default format looks like --> 2016/11/25 12:34

    Args:
        value (datetime.datetime): input date and time
        format_str (str): The datetime format string to apply to value

    Returns:
        str: value, after the format_str has been applied
    """
    return value.strftime(format_str)


def named_value(dictionary):
    """
    Gets the name and value of a dict with a single key (for example SenzaInfo
    parameters or Senza Components)
    """
    return next(iter(dictionary.items()))


@classmethod
def _validate_message(cls, message):
    """Validate other parts of the message other than those
        done in _message_id."""


@staticmethod
def supportsWorkAddition():
    """Indicates if a given policy supports addition of new work"""
    return False


@classmethod
def unixes(cls):
    """ Get a generator over the UNIX-based System values """
    for system in cls.all():
        if system.is_unix_based:
            yield system


def _list_to_str(ticker_list):
    """parses/joins ticker list

    Args:
        ticker_list (:obj:`list` or str): ticker(s) to parse

    Returns:
        (str): list of tickers

    """
    if isinstance(ticker_list, str):
        return ticker_list.upper()
    elif isinstance(ticker_list, list):
        return ','.join(ticker_list).upper()
    else:
        raise TypeError


def k2c(t):
    """ kelvin to degree celsius """
    return float(t) - 273.15


def check_annulus(args):
    """
    Checks and formats the annulus values.

    :param args: The command-line arguments.

    :type args: argparse.ArgumentParser Namespace

    :returns: argparse.ArgumentParser Namespace -- The updated command-line
        arguments.
    """
    if not (args.annulus1 and args.annulus2) and not args.annulus:
        args.annulus = None
    elif args.annulus1 and args.annulus2:
        args.annulus = [args.annulus1, args.annulus2]
    else:
        args.annulus = list(args.annulus)
        if not (args.annulus1 and args.annulus2):
            args.annulus1 = args.annulus[0]
            args.annulus2 = args.annulus[1]
    return args


def timezone_choice(tzname, country=None):
    """
    Given a timezone string, convert it to a two-tuple suitable
    for a choice in a FormField.

    >>> timezone_choice('UTC')
    ('UTC', 'UTC')
    >>> timezone_choice('Australia/Sydney')
    ('Australia/Sydney', 'Sydney')
    >>> timezone_choice('America/Indiana/Indianapolis')
    ('America/Indiana/Indianapolis', 'Indianapolis (Indiana)')
    """
    try:
        base, rest = tzname.split('/', 1)
    except ValueError:
        base, rest = None, tzname
    rest = rest.replace('_', ' ')
    try:
        mid, rest = rest.split('/')
        if mid != base and mid != country:
            rest = '{0} ({1})'.format(rest, mid)
    except ValueError:
        pass
    return tzname, rest


def pop_post(user_email, postid):
    """
        removes the post with post index 'postid'
        from the list of posts from 'user_email'
        """


def add_str(cls):
    """Decorator to implement the correct str() function."""
    try:
        cls.__str__ = cls.__bytes__
    except AttributeError:
        pass
    return cls


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

        :param TeamMergeFromType val:
        :rtype: EventType
        """
    return cls('team_merge_from', val)


@staticmethod
def plot_line(x0, y0, x1, y1):
    """Zingl-Bresenham line draw algorithm"""
    x0 = int(x0)
    y0 = int(y0)
    x1 = int(x1)
    y1 = int(y1)
    dx = abs(x1 - x0)
    dy = -abs(y1 - y0)
    if x0 < x1:
        sx = 1
    else:
        sx = -1
    if y0 < y1:
        sy = 1
    else:
        sy = -1
    err = dx + dy
    while True:
        yield x0, y0
        if x0 == x1 and y0 == y1:
            break
        e2 = 2 * err
        if e2 >= dy:
            err += dy
            x0 += sx
        if e2 <= dx:
            err += dx
            y0 += sy


def move_limits_to_user(apps, schema_editor):
    """Move limits from Pool to User."""
    LimitsPool = apps.get_model('limits', 'LimitsPool')
    UserObjectLimit = apps.get_model('limits', 'UserObjectLimit')
    ContentType = apps.get_model('contenttypes', 'ContentType')
    if not ContentType.objects.exists():
        return
    name_to_content_type = {'domains_limit': ContentType.objects.get(
        app_label='admin', model='domain'), 'domain_aliases_limit':
        ContentType.objects.get(app_label='admin', model='domainalias'),
        'mailboxes_limit': ContentType.objects.get(app_label='admin', model
        ='mailbox'), 'mailbox_aliases_limit': ContentType.objects.get(
        app_label='admin', model='alias'), 'domain_admins_limit':
        ContentType.objects.get(app_label='core', model='user')}
    to_create = []
    qset = LimitsPool.objects.select_related('user').prefetch_related(
        'limit_set')
    for pool in qset:
        for limit in pool.limit_set.all():
            objlimit = UserObjectLimit(user=pool.user, max_value=limit.
                maxvalue, name=limit.name.replace('_limit', ''),
                content_type=name_to_content_type[limit.name])
            to_create.append(objlimit)
    UserObjectLimit.objects.bulk_create(to_create)


def get_boolean(message, default=True):
    """ Get a yes/no input from the user, prompting them with a message.

    Returns:
        input (boolean): True or False depending on the user's input
    """
    if not isinstance(default, bool):
        raise TypeError('Default must be a boolean')
    result = input('{} ({}): '.format(message, 'no' if not default else 'yes'))
    if not result:
        return default
    result = result.strip().lower()
    return result in ('yes', 'y')


def set_code(code):
    """
        Tell the wormhole to use a specific code, either copied from a
        wormhole that used ``allocate_code``, or created out-of-band by
        humans (and given to ``set_code`` on both wormholes).

        Any Deferreds returned by ``get_code()`` will be fired as soon as
        this is called.  Only one of generate_code/set_code/input_code may be
        used.

        :return: None
        """


def t2x(tree):
    """
    | convert docutils.nodes.document_tree  to xml

    :param docutils.nodes.document.
        doc-tree-root-node

    :return: string.
        xml_str
    """
    xdom = tree.asdom()
    xml_str = xdom.toprettyxml()
    xml_str = xml_str.replace('\t', ' ' * 4)
    return xml_str


def per_capita(value, population, per=10000, fail_silently=True):
    """
    Accepts two numbers, a value and population total, and returns
    the per capita rate.

    By default, the result is returned as a per 10,000 person figure.

    If you divide into zero -- an illegal operation -- a null value
    is returned by default. If you prefer for an error to be raised,
    set the kwarg 'fail_silently' to False.

    h3. Example usage

        >> import calculate
        >> calculate.per_capita(12, 100000)
        1.2

    h3. Documentation

        * "per capita":http://en.wikipedia.org/wiki/Per_capita
    """
    try:
        return float(value) / population * per
    except ZeroDivisionError:
        if fail_silently:
            return None
        else:
            raise ZeroDivisionError("Sorry. You can't divide into zero.")


def get_client_ip(request):
    """
    Returns client ip from request.
    Source: http://stackoverflow.com/a/4581997/821594
    """
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


@staticmethod
def get_f1(curr_result):
    """
        Simple getter for F1 statistics (N_F1, J_F1 and distance).
        :param curr_result: a result storer
        :type curr_result: ResultStorer

        :return: (J_F1, N_F1, distance)
        :rtype (float, float, int)
        """
    return curr_result.j_f1[0], curr_result.n_f1[0], -curr_result.distance[0
        ], curr_result.ccode[0] not in ('x', 'X')


def get_total_notices(layer):
    """Find the total number of notices in a layer"""
    count = 0
    for origin in layer.origins.origins:
        count += len(origin.notices)
    return count


def gaussian_resolution(res, zwl, mwl):
    """
    Get parameters for ndimage.gaussian_filter
    See http://stackoverflow.com/questions/14531072/how-to-count-bugs-in-an-image
    Input: res : grid resolution in degrees
           zwl : zonal distance in degrees
           mwl : meridional distance in degrees
    """
    zres = zwl.copy()
    mres = mwl.copy()
    zres *= 0.125
    mres *= 0.125
    zres /= res
    mres /= res
    return zres, mres


def get_haplotype_score(var):
    """
    Returns consistency of the site with two segregating haplotypes,
    or None if it isn't present in the VCF.
    """
    return var.INFO.get('HaplotypeScore')


@classmethod
def get_category_members_titles(cls, name, skip_index=True):
    """
        Generator that obtains a list of article titles in a category.

        Parameters
        ----------
        name: :class:`str`
            The category's name. ``Category:`` prefix is not necessary.
        skip_index: :class:`bool`
            Whether to skip index articles or not.

        Yields
        -------
        :class:`str`
            Titles of articles in this category.
        """
    for member in cls.get_category_members(name, skip_index):
        yield member.title


def _is_fk_msg(dialect, msg, key_cname, ref_cname):
    """
        easier unit testing this way
    """
    if dialect == 'sqlite':
        if ('violates foreign key constraint' in msg and '__%s__fk' %
            key_cname in msg):
            return True
    elif dialect == 'postgresql':
        msg = msg.replace('(psycopg2.IntegrityError) ', '', 1)
        if 'violates foreign key constraint' in msg:
            if msg.startswith('insert or update'
                ) and 'Key (%s)=' % key_cname in msg:
                return True
            if msg.startswith('update or delete'
                ) and 'Key (%s)=' % ref_cname in msg:
                return True
    elif dialect == 'mssql':
        is_fk_message = 'conflicted with the FOREIGN KEY constraint' in msg
        is_ref_message = 'conflicted with the REFERENCE constraint' in msg
        if is_fk_message and "column \\'%s\\'" % ref_cname in msg:
            return True
        if is_ref_message and "column \\'%s\\'" % key_cname in msg:
            return True
    else:
        raise ValueError('is_fk_exc() does not yet support dialect: %s' %
            dialect)
    return False


def migrate_repository_filter(repo_filter, src_repository, dst_repository):
    """Update a single repository filter in-place for the destination.

    If the filter checks that the repository is src_repository, it is
    updated to check that the repository is dst_repository.  If it does
    anything else, this function raises ValueError.
    """
    if src_repository is None:
        raise ValueError('component does not specify a source repository')
    elif dst_repository is None:
        raise ValueError(
            'no destination repository specified to update repository filter')
    elif repo_filter[1:] == ['=', src_repository]:
        repo_filter[2] = dst_repository
    elif repo_filter[1:] == ['in', [src_repository]]:
        repo_filter[2] = [dst_repository]
    else:
        raise ValueError('repository filter is not a simple source match')


@classmethod
def create(cls, serial, issuer, not_after, subject, subject_key, sign_key,
    extensions=None, not_before=None, issuer_unique=None, subject_unique=
    None, version=None):
    """Creates a certificate from certificate data.

        :param serial:         certificate serial number
        :type  serial:         int
        :param issuer:         certificate issuer
        :type  issuer:         :class:`VX509Name`
        :param not_after:      latest valid time
        :type  not_after:      :class:`datetime.datetime` or
                               :class:`datetime.timedelta`
        :param subject:        certificate subject
        :type  subject:        :class:`VX509Name`
        :param sign_key:       issuer's keypair
        :type  sign_key:       :class:`versile.crypto.VAsymmetricKey`
        :param extensions:     certificate extensions
        :type  extensions:     :class:`VX509CertificateExtension`\\ ,
        :param not_before:     earliest valid time
        :type  not_before:     :class:`datetime.datetime` or
                               :class:`datetime.timedelta`
        :param issuer_unique:  issuer unique ID
        :type  issuer_unique:  bytes
        :param subject_unique: subject unique ID
        :type  subject_unique: bytes
        :param version:        certificate version
        :type  version:        int
        :returns:              generated certificate
        :returns:              :class:`VX509Certificate`

        Certificate is only valid for timestamps between *not_before*
        and *not_after*. If a timedelta is provided for *not_after* or
        *not_before* then the timedelta is taken from the current
        system UTC time. If *not_before* is None then the current time
        mins 5 minutes is used.

        *sign_key* will be used to sign the certificate.

        If *version* is None then the certificate version is
        automatically set based on certificate parameters.

        """
    _create = cls.create_tbs
    tbs = _create(serial=serial, issuer=issuer, not_before=not_before,
        not_after=not_after, subject=subject, subject_key=subject_key,
        issuer_unique=issuer_unique, subject_unique=subject_unique,
        extensions=extensions, version=version)
    return cls.create_from_tbs(tbs_cert=tbs, sign_key=sign_key)


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 is_str(s):
    """return True or False if input is a string or not.
        python3 compatible.
    """
    return isinstance(s, str)


def within_time_range(d1, d2, maxdiff_seconds):
    """Return true if two datetime.datetime object differs less than the given seconds"""
    delta = d2 - d1 if d2 > d1 else d1 - d2
    diff = (delta.microseconds + (delta.seconds + delta.days * 24 * 3600) *
        1000000.0) / 1000000.0
    return diff < maxdiff_seconds


def _gridnd(val_f, c, *args):
    """
    Helper function used to implement the ``<type>grid<n>d`` functions.

    Parameters
    ----------
    val_f : function(array_like, array_like, tensor: bool) -> array_like
        The ``<type>val`` function, such as ``polyval``
    c, args :
        See the ``<type>grid<n>d`` functions for more detail
    """
    for xi in args:
        c = val_f(xi, c)
    return c


def add_app(parser):
    """Add an `app` flag to the _parser_."""
    parser.add_argument('-a', '--app', help='Spinnaker Application name',
        required=True)


def example_filter_yaroslavl_region(item):
    """
    Всегда разрешает импорт записи
    :param item:
    :return item or None:
    """
    if item.regioncode == '76':
        return item


@classmethod
def triclinic(cls, a, b, c, alpha, beta, gamma):
    """
        Initializes a Box in standard triclinic setting using only triclinic lattice
        parameters.

        a != b != c, alpha != beta != gamma

        Parameters
        ----------
        - a : float
            The a lattice constant
        - b : float
            The b lattice constant
        - c : float
            The c lattice constant
        - alpha : float
            The alpha lattice angle in degrees
        - beta : float
            The beta lattice angle in degrees
        - gamma : float
            The gamma lattice angle in degrees

        Returns
        -------
        atomman.Box
        """
    if a == b or a == c:
        raise ValueError('monoclinic lattice constants must be different')
    if alpha == beta or alpha == gamma:
        raise ValueError('monoclinic lattice angles must be different')
    return cls(a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma)


def isBool(x):
    """ Returns True, if x is a boolean.
    >>> isBool(True)
    True
    >>> isBool(False)
    True
    >>> isBool(1)
    True
    >>> isBool(0)
    True
    >>> isBool(2)
    False
    >>> isBool('true')
    False
    """
    if isinstance(x, int) and x in [0, 1]:
        return True
    return isinstance(x, bool)


def _trailing(template, *targets):
    """Substring of *template* following all *targets*.

    **Example**::

        template = "this is a test of the bunnies."
        _trailing(template, "is", "est", "the") == " bunnies"

    Each target is matched successively in the string, and the string
    remaining after the last target is returned. If one of the targets
    fails to match, a ValueError is raised.

    :param template: Template to extract a trailing string from.
    :type template: ``string``
    :param targets: Strings to successively match in *template*.
    :type targets: list of ``string``s
    :return: Trailing string after all targets are matched.
    :rtype: ``string``
    :raises ValueError: Raised when one of the targets does not match.
    """
    s = template
    for t in targets:
        n = s.find(t)
        if n == -1:
            raise ValueError('Target ' + t + ' not found in template.')
        s = s[n + len(t):]
    return s


@staticmethod
def get_cpu_count(connection):
    """return the number of processors on the server"""
    return int(connection.run('grep processor /proc/cpuinfo | wc -l'), warn
        =True)


def divide_nums(*args):
    """
    definition: func(arg1, arg2, ...) {...}
    objective : you can give as many args as you want and the func divides
                the nums from left to right
    """
    first_arg = args[0]
    for i in range(1, len(args), 1):
        first_arg /= args[i]
    return first_arg


def get_or(item, keys, default=''):
    """
    Fetch a property from a json object. Keys is a list of keys and indices to use to
    fetch the property. Returns the passed default string if the path through the json
    does not exist.
    :param item: The json to parse properties from
    :type item: json object
    :param keys: The list of keys and indices for the property
    :type keys: A list of string or int
    :param default: The default string to use if a property could not be found
    :type default: String
    :return: The requested property or the default value if missing
    :rtype: String
    """
    try:
        for key in keys:
            item = item[key]
        return item
    except (KeyError, IndexError):
        return default


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

    .. note::
       - For input ``n.5`` ``rint`` returns ``n`` while ``round`` returns ``n+1``.
       - For input ``-n.5`` both ``rint`` and ``round`` returns ``-n-1``.

    Example::

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

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

       - rint(default) = default
       - rint(row_sparse) = row_sparse
       - rint(csr) = csr

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

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

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

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


def lbetacf(a, b, x):
    """
This function evaluates the continued fraction form of the incomplete
Beta function, betai.  (Adapted from: Numerical Recipies in C.)

Usage:   lbetacf(a,b,x)
"""
    ITMAX = 200
    EPS = 3e-07
    bm = az = am = 1.0
    qab = a + b
    qap = a + 1.0
    qam = a - 1.0
    bz = 1.0 - qab * x / qap
    for i in range(ITMAX + 1):
        em = float(i + 1)
        tem = em + em
        d = em * (b - em) * x / ((qam + tem) * (a + tem))
        ap = az + d * am
        bp = bz + d * bm
        d = -(a + em) * (qab + em) * x / ((qap + tem) * (a + tem))
        app = ap + d * az
        bpp = bp + d * bz
        aold = az
        am = ap / bpp
        bm = bp / bpp
        az = app / bpp
        bz = 1.0
        if abs(az - aold) < EPS * abs(az):
            return az
    print('a or b too big, or ITMAX too small in Betacf.')


def openfile(fname):
    """
    Opens the file handle of file `fname`.

    """
    if hasattr(fname, 'readline'):
        return fname
    try:
        f = open(fname)
    except IOError:
        raise IOError("No such file: '%s'" % fname)
    if f.readline()[:2] != '\\x':
        f.seek(0, 0)
        return f
    f.close()
    raise NotImplementedError('Wow, binary file')


def assign(dst, src):
    """Assign all attributes from 'src' object to 'dst' object."""
    for a, v in list(src.__dict__.items()):
        setattr(dst, a, v)


def pk_name(table_name):
    """Returns the name that will be used in the database for a primary key, given:

       :arg table_name: The name of the table to which the primary key belongs.
    """
    return 'pk_%s' % table_name


def execute(some_callable):
    """Really simple functio that calls its argument."""
    some_callable()


def _is_dynamodb_critical_exception(err):
    """Return true for botocore exceptions due to exceeded througput."""
    error_code = getattr(err, 'response', {}).get('Error', {}).get('Code')
    return error_code in {'ProvisionedThroughputExceededException',
        'UnrecognizedClientException'}


@staticmethod
def p_sync_edge(p):
    """sync_edge : SYNC_EDGE SINGLE
                     | SYNC_EDGE DUAL"""
    p[0] = p[2]


def get_bit_size(x):
    """Return size of long in bits."""
    return len(bin(x)) - 2


def process(proc_data):
    """
    Final processing to conform to the schema.

    Parameters:

        proc_data:   (dictionary) raw structured data to process

    Returns:

        List of dictionaries. Structured data with the following schema:

        [
          {
            "unit_file":   string,
            "state":       string
          }
        ]
    """
    return proc_data


def main():
    """Run when called as a module."""
    raise RuntimeError('This module is not meant to be run by itself.')


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


@classmethod
def from_points(cls, points, boundary=None, holes=None):
    """Construct a mesh from a delaunay triangulation of a set of points.

        Parameters
        ----------
        points : list
            XYZ coordinates of the points.
            Z coordinates should be zero.

        Returns
        -------
        Mesh
            A mesh object.

        Examples
        --------
        >>>
        """
    from compas.geometry import delaunay_from_points
    faces = delaunay_from_points(points, boundary=boundary, holes=holes)
    return cls.from_vertices_and_faces(points, faces)


def showAddressMapping():
    """Display a mapping of email addresses -> mailing list paths"""


def report_copy():
    """Copy selected reports to Clipboard

    """
    pass


@classmethod
def from_vtk_cell(cls, vtk_cell, points, data=None):
    """Generate a hexahedron from VTK cells."""
    kwargs = {}
    if data is not None:
        kwargs['data'] = data
    vertices = []
    point_ids = vtk_cell.GetPointIds()
    for i_point in range(vtk_cell.GetNumberOfPoints()):
        vertices.append(points[point_ids.GetId(i_point)])
    return cls(vertices=vertices, **kwargs)


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

        :param PaperDocChangeMemberRoleType val:
        :rtype: EventType
        """
    return cls('paper_doc_change_member_role', val)


def create_task(conn, task):
    """
    Create a new task
    :param conn:
    :param task:
    :return:
    """
    sql = """ INSERT INTO vencodes(name,priority,status_id,project_id,begin_date,end_date)
              VALUES(?,?,?,?,?,?) """
    cur = conn.cursor()
    cur.execute(sql, task)
    return cur.lastrowid


def can_paginate(operation_name=None):
    """
    Check if an operation can be paginated.

    :type operation_name: string
    :param operation_name: The operation name. This is the same name
            as the method name on the client. For example, if the
            method name is create_foo, and you'd normally invoke the
            operation as client.create_foo(**kwargs), if the
            create_foo operation can be paginated, you can use the
            call client.get_paginator('create_foo').

    """
    pass


def read(pipe, funcs):
    """Reads and pushes piped output to a shared queue and appropriate lists."""
    for line in iter(pipe.readline, b''):
        for func in funcs:
            func(line.decode('utf-8'))
    pipe.close()


def p_inc_filename(p):
    """ inc_filename : STRING_ENCLOSED_DOUBLE_QUOTE """
    p[0] = p[1]


def get_foreign_keys(conn):
    """Return foreign_keys value."""
    cur = conn.cursor()
    cur.execute('PRAGMA foreign_keys')
    return cur.fetchone()[0]


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 get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def download_issuetypes(jira_connection, project_ids):
    """
    For Jira next-gen projects, issue types can be scoped to projects.
    For issue types that are scoped to projects, only extract the ones
    in the extracted projects.
    """
    print('downloading jira issue types... ', end='', flush=True)
    result = []
    for it in jira_connection.issue_types():
        if 'scope' in it.raw and it.raw['scope']['type'] == 'PROJECT':
            if it.raw['scope']['project']['id'] in project_ids:
                result.append(it.raw)
        else:
            result.append(it.raw)
    print('✓')
    return result


@classmethod
def get_url(cls):
    """Returns the information URL (homepage) for the plugin.

        Subclassses should set the class attribute URL, which is returned
        by the default implementation.
        """
    if not cls.URL:
        raise NotImplementedError
    return cls.URL


def div_ceil(n, d):
    """returns the ceiling of n divided by d as an int"""
    return n // d + (1 if n % d != 0 else 0)


def find_serial_port(name):
    """Utility function to scan available serial ports by name. The returned object is intended to be passed to the
    :meth:`~pyrealtime.serial_layer.SerialWriteLayer.from_port` constructor of
    :class:`~pyrealtime.serial_layer.SerialReadLayer` or :class:`~pyrealtime.serial_layer.SerialWriteLayer`.

    :param name: The name of the serial port to scan for. It will return the first available port containing name.
    :return: A closed serial port object
    """
    try:
        import serial
        import serial.tools.list_ports
    except ImportError:
        raise ModuleNotFoundError('PySerial not found')
    ports = list(serial.tools.list_ports.comports())
    port = None
    for p in ports:
        if name in p.description:
            port = p.device
    if port is None:
        for p in ports:
            if name in p.device:
                port = p.device
    if port is None:
        print('Error: could not find port: %s.' % name)
        print('Available ports:')
        for p in ports:
            print('%s: %s' % (p, p.description))
    return port


def trans_data(data):
    """
    transposed  data

    :param data: list
    :return: list
    """
    assert isinstance(data, list)
    return list(map(list, zip(*data)))


@classmethod
def plot_options(cls, obj, percent_size):
    """
        Given an object and a percentage size (as supplied by the
        %output magic) return all the appropriate plot options that
        would be used to instantiate a plot class for that element.

        Default plot sizes at the plotting class level should be taken
        into account.
        """
    raise NotImplementedError


def __instancecheck__(cls, obj):
    """
        Allows datatype to be used in isinstance() function.
        """
    if cls.pyex is not None:
        return isinstance(obj, cls.py) and not isinstance(obj, cls.pyex)
    else:
        return isinstance(obj, cls.py)


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


def has_lookahead(parser):
    """ Return True if the parser has the ability to perform lookahead. """
    return hasattr(parser, 'lookahead')


def community_count(clustering):
    """
    Counts the number of community in a fairer way than simply using
    len(clustering). Indeed, the former method counts single nodes as a
    community while this is not considered desirable. Hence, this method
    counts the number of communities having 2+ nodes.
    """
    nb_communities = 0
    for cluster in clustering:
        if len(cluster) >= 2:
            nb_communities += 1
    return nb_communities


@classmethod
def fixed_length(cls, l, allow_empty=False):
    """Create a sedes for binary data with exactly `l` bytes."""
    return cls(l, l, allow_empty=allow_empty)


def iter_hist_buckets(hist):
    """Return buckets for a histogram as a generator
    """
    for full_name, labels, value in hist.collect()[0].samples:
        if full_name.endswith('_bucket'):
            yield full_name, labels, value


@staticmethod
def readLenFromSocket(socket, length):
    """Read length bytes from socket."""
    s = b''
    while len(s) < length:
        s += socket.recv(length - len(s))
    return s


def get_single_key_value_pair(d):
    """
    Get the key and value of a length one dictionary.

    Parameters
    ----------
    d : dict
        Single element dictionary to split into key and value.

    Returns
    -------
    tuple
        of length 2, containing the key and value

    Examples
    --------

    >>> d = dict(key='value')
    >>> get_single_key_value_pair(d)
    ('key', 'value')

    """
    assert isinstance(d, dict), f'{d}'
    assert len(d) == 1, f'{d}'
    return list(d.items())[0]


def queen_constraint(A, a, B, b):
    """Constraint is satisfied (true) if A, B are really the same variable,
    or if they are not in the same row, down diagonal, or up diagonal."""
    return A == B or a != b and A + a != B + b and A - a != B - b


def process_cart3d(cart3d_filename, fmt2, fname2, log, data, quiet=False):
    """
    Converts Cart3d to STL/Nastran/Tecplot/Cart3d
    """
    assert fmt2 in ['stl', 'nastran', 'tecplot', 'cart3d'], 'format2=%s' % fmt2
    from pyNastran.converters.cart3d.cart3d import read_cart3d
    model = read_cart3d(cart3d_filename, log=log)
    if data['--scale'] != 1.0:
        model.points *= data['--scale']
        data['--scale'] = 1.0
    if fmt2 == 'stl':
        from pyNastran.converters.cart3d.cart3d_to_stl import cart3d_to_stl_filename
        cart3d_to_stl_filename(model, fname2, log=log, is_binary=data[
            '--binary'])
    elif fmt2 == 'nastran':
        from pyNastran.converters.cart3d.cart3d_to_nastran import cart3d_to_nastran_filename
        cart3d_to_nastran_filename(model, fname2, log=log)
    elif fmt2 == 'tecplot':
        from pyNastran.converters.cart3d.cart3d_to_tecplot import cart3d_to_tecplot
        cart3d_to_tecplot(model, fname2, log=log)
    elif fmt2 == 'cart3d':
        model.write_cart3d(fname2, is_binary=data['--binary'])
    else:
        raise NotImplementedError(
            'fmt2=%s is not supported by process_cart3d' % fmt2)


def callback_text(params, errors, best_params, best_error, index):
    """Default callback print-out for Fitters"""
    print('Round {}: fit {} with error: {}'.format(index, best_params,
        best_error))


def mask_dict_password(dictionary, secret='***'):
    """Replace passwords with a secret in a dictionary."""
    d = dictionary.copy()
    for k in d:
        if 'password' in k:
            d[k] = secret
    return d


def p_Arguments(p):
    """Arguments : "," Argument Arguments"""
    p[0] = [p[2]] + p[3]


def _inverse_convert_code(code):
    """
    将 xalpha 形式的代码转化为聚宽形式

    :param code:
    :return:
    """
    if code.startswith('SH'):
        return code[2:] + '.XSHG'
    elif code.startswith('SZ'):
        return code[2:] + '.XSHE'


@staticmethod
def have_resolved_history(hist):
    """
        This function tries to resolve a history. It returns True iff it
        succeeds.

        A history of a variable is a list of all the values it will assume
        all the times it is used in the circuit (each repetition in a loop
        or nested loops is counted as a different use.) For a hash
        placeholder, a history is a list of floats or None's. For a
        functional placeholder, a history is a list of functions or None's.

        Resolving a history successfully means replacing all None's by a
        value that is not a None. This is accomplished by moving in order of
        ascending index on the list and replacing each None by its
        predecessor. The very first use cannot be a None.

        Parameters
        ----------
        hist : list[float | function | None]

        Returns
        -------
        bool

        """
    for time, event in enumerate(hist):
        if event is None:
            if time == 0:
                return False
            else:
                hist[time] = hist[time - 1]
    return True


def colourBarMinorAxisSize(fontSize):
    """Calculates a good size for the minor axis of a colour bar.

    The minor axis is the axis perpendicular to the colour bar axis.

    :arg fontSize: Font size of colour bar labels, in points.
    """
    fontSize = fontSize
    fontSize = 6 + 96 * fontSize / 72.0
    return round(2 * fontSize + 40)


def modulo(y):
    """modulo(y)(x) = x % y

    Be careful with this because the % operator is not commutative.

    You may be interested in func.flip(modulo) to reverse the arguments.

    >>> modulo(2)(4)
    0
    >>> modulo(2)(5)
    1
    >>> from .func import flip
    >>> flip(modulo)(5)(2)
    1
    """
    return lambda x: x % y


def possible_timesigs(tempo):
    """
    Return possible timesignatures for a given tempo

    Time signatures are given in fractions where 2.5 means 5/8, 3.5 means 7/8
    it is assumed that tempo refers to a quarter note
    """
    fractional_timesigs = [1.5, 2.5, 3.5, 4.5]
    int_timesigs = [2, 3, 4, 5, 6, 7, 8, 9]
    if tempo > 80:
        return int_timesigs
    return sorted(int_timesigs + fractional_timesigs)


@staticmethod
def _read_file_block(file_handle, block_size=8192):
    """yield chunk_size blocks of file

        :param file_handle: handle to file
        :param chunk_size: block size of file to be read
        :return: block of file
        """
    while True:
        data = file_handle.read(block_size)
        if not data:
            break
        else:
            yield data


def get_activation_link(request, user_id: int, code: str) ->str:
    """Return the link for the user to click on an email message.

    ``route_url()`` uses the protocol and domain detected from the
    current request.  Unfortunately in production, that's usually
    https for the load balancer, but http for a backend Pyramid server.
    So we take advantage of a ``scheme_domain_port`` configuration
    setting if provided.
    """
    scheme_domain_port: str = request.registry.settings.get(
        'scheme_domain_port', '')
    return scheme_domain_port + request.route_path('activate', user_id=
        user_id, code=code) if scheme_domain_port else request.route_url(
        'activate', user_id=user_id, code=code)


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

        :param PaperDocEditDetails val:
        :rtype: EventDetails
        """
    return cls('paper_doc_edit_details', val)


def _improve_answer_span(doc_tokens, input_start, input_end, tokenizer,
    orig_answer_text):
    """Returns tokenized answer spans that better match the annotated answer."""
    tok_answer_text = ' '.join(tokenizer.tokenize(orig_answer_text))
    for new_start in range(input_start, input_end + 1):
        for new_end in range(input_end, new_start - 1, -1):
            text_span = ' '.join(doc_tokens[new_start:new_end + 1])
            if text_span == tok_answer_text:
                return new_start, new_end
    return input_start, input_end


def forward(apps, schema_editor):
    """
    Creates a Device record for each existing Config
    TODO: delete this migration in future releases
    """
    if not schema_editor.connection.alias == 'default':
        return
    Device = apps.get_model('config', 'Device')
    Config = apps.get_model('config', 'Config')
    for config in Config.objects.all():
        device = Device(id=config.id, organization=config.organization,
            name=config.name, mac_address=config.mac_address, key=config.
            key, created=config.created, modified=config.modified)
        device.full_clean()
        device.save()
        config.device = device
        config.save()


@staticmethod
def _sink_snowflake():
    """Method to add Snowflake as sink"""
    pass


def available():
    """ Whether this step is available
        """


def main():
    """
    This is an example how to upload files and annotations to Dataloop platform.
    Image folder contains the images to upload.
    Annotations folder contains json file of the annotations. Same name as the image.
    We read the images one by one and create the Dataloop annotations using the annotation builder.
    Finally, we upload both the image and the matching annotations

    :return:
    """
    import json
    import os
    import dtlpy as dl
    project = dl.projects.get(project_name='Yachts')
    dataset = project.datasets.get(dataset_name='Open Seas')
    images_folder = '/home/local/images'
    annotations_folder = '/home/local/annotations'
    for img_filename in os.listdir(images_folder):
        _, ext = os.path.splitext(img_filename)
        ann_filename = os.path.join(annotations_folder, img_filename.
            replace(ext, '.json'))
        img_filename = os.path.join(images_folder, img_filename)
        item = dataset.items.upload(local_path=img_filename, remote_path=
            '/in_storm', overwrite=False)
        assert isinstance(item, dl.Item)
        with open(ann_filename, 'r') as f:
            annotations = json.load(f)
        builder = item.annotations.builder()
        for annotation in annotations:
            label_id = annotation['label']
            left = annotation['left']
            top = annotation['top']
            right = annotation['right']
            bottom = annotation['bottom']
            builder.add(annotation_definition=dl.Box(top=top, left=left,
                bottom=bottom, right=right, label=str(label_id)))
        item.annotations.upload(builder)


def extract_number(text):
    """Extract digit character from text.
    """
    result = list()
    chunk = list()
    valid_char = set('.1234567890')
    for char in text:
        if char in valid_char:
            chunk.append(char)
        else:
            result.append(''.join(chunk))
            chunk = list()
    result.append(''.join(chunk))
    result_new = list()
    for number in result:
        if '.' in number:
            try:
                result_new.append(float(number))
            except:
                pass
        else:
            try:
                result_new.append(int(number))
            except:
                pass
    return result_new


def sorted_counts(counts):
    """Use this to calibrate the removal of junk."""
    remove_ones = filter(lambda pair: pair[1] > 1, counts.items())
    return sorted(remove_ones, key=lambda pair: pair[1])


@classmethod
def process(cls, *, context=None, parameter=None):
    """ Evaluate the INPUT[INT] command. """
    address = context.stack.pop()
    value = context.input('IIN')
    context.heap[address] = value


@classmethod
def get_all_values(cls, section):
    """
        Returns all values from a section of the configuration file.
        """
    cls.__ensure_config()
    if cls.__config.has_section(section):
        return map(lambda k: cls.__config.get(section, k), cls.__config.
            options(section))
    else:
        return []


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


def merge_rows(archive, document, version, writer, partial=False,
    unchanged_cells=None, origin=None):
    """Merge rows in the given archive and database snapshot. Outputs the
    merged rows in the resulting archive to the given archive writer.

    Parameters
    ----------
    archive: histore.archive.base.Archive
        Archive containing previous snapshots of the dataset.
    document: histore.document.base.Document
        Dataset snapshot that is being merged into the archive.
    version: int
        Identifier of the new archive version.
    writer: histore.archive.writer.ArchiveWriter
        Consumer for rows in the new archive version.
    partial: bool, default=False
        Flag indicating whether the given document is a partial document. For
        partial documents missing rows in the archive are considered unchanged
        with respect to the given origin.
    unchanged_cells: set, default=None
        Set of identifier for columns whose cell values are not included in
        the values dictionary for document rows but that remain unchanged with
        respect to the specified source version (origin).
    origin: int, default=None
        Version that the row values originate from. Rows that remain unchanged
        have the timestamp extended for the version of origin.
    """
    arch_reader = archive.reader()
    doc_reader = document.reader()
    arch_row = arch_reader.next()
    doc_row = doc_reader.next()
    while arch_row is not None and doc_row is not None:
        comp = arch_row.comp(doc_row.key)
        if comp < 0:
            if partial:
                arch_row = arch_row.extend(version=version, origin=origin)
            writer.write_archive_row(arch_row)
            arch_row = arch_reader.next()
        elif comp > 0:
            writer.write_document_row(row=doc_row, version=version)
            doc_row = doc_reader.next()
        else:
            arch_row = arch_row.merge(values=doc_row.values, pos=doc_row.
                pos, version=version, unchanged_cells=unchanged_cells,
                origin=origin)
            writer.write_archive_row(arch_row)
            arch_row = arch_reader.next()
            doc_row = doc_reader.next()
    while arch_row is not None:
        if partial:
            arch_row = arch_row.extend(version=version, origin=origin)
        writer.write_archive_row(arch_row)
        arch_row = arch_reader.next()
    while doc_row is not None:
        writer.write_document_row(row=doc_row, version=version)
        doc_row = doc_reader.next()


def _timezone(utcoffset):
    """
    Return a string representing the timezone offset.

    >>> _timezone(0)
    '+00:00'
    >>> _timezone(3600)
    '+01:00'
    >>> _timezone(-28800)
    '-08:00'
    >>> _timezone(-1800)
    '-00:30'
    """
    hours = abs(utcoffset) // 3600
    minutes = abs(utcoffset) % 3600 // 60
    if utcoffset < 0:
        plusminus = '-'
    else:
        plusminus = '+'
    return '%c%02d:%02d' % (plusminus, hours, minutes)


def reject_certificate_transfer(certificateId=None, rejectReason=None):
    """
    Rejects a pending certificate transfer. After AWS IoT rejects a certificate transfer, the certificate status changes from PENDING_TRANSFER to INACTIVE .
    To check for pending certificate transfers, call  ListCertificates to enumerate your certificates.
    This operation can only be called by the transfer destination. After it is called, the certificate will be returned to the source's account in the INACTIVE state.
    See also: AWS API Documentation

    :example: response = client.reject_certificate_transfer(
        certificateId='string',
        rejectReason='string'
    )

    :type certificateId: string
    :param certificateId: [REQUIRED]
            The ID of the certificate.

    :type rejectReason: string
    :param rejectReason: The reason the certificate transfer was rejected.

    """
    pass


def _check_pages_api_limit(max_pages):
    """
    Internal function for checking number of pages requested to comply with api quota.

    Parameters
    ----------
    max_pages: int
        max number of pages that returned from the Petfinder API.

    Returns
    -------
    integer
        either the original max_pages if the user got an advanced quota or 10,000 which is the current normal quota for api requests

    """
    if max_pages > 10000:
        ans = input(
            """Total pages requested is {} which exceeds the daily API requests quota by PetFinder,
                        do you want to limit the pages to 10,000 only? y|n """
            .format(max_pages))
        if ans.lower() in ['y', 'yes']:
            max_pages = 10000
        elif ans.lower() not in ['n', 'no']:
            raise ValueError('Only y|n accepted as answers')
    return max_pages


def product(l, s=1):
    """product(iterable[, int]) -> value

    Return production of numbers, eager eval (no short circit when face 0).
    This function may have initial value as second argument."""
    for n in l:
        s *= n
    return s


def list_merge(boards_dict):
    """
    Merge dict of boards into list
    :param boards_dict: dict of boards
    :return: list of boards
    """
    return sum(boards_dict.values(), [])


def namespace_path_join(base, name):
    """Extend the current namespace path with an additional name

    Take a namespace path (i.e., package.module.class) and extends it
    with an additional name (i.e., package.module.class.subclass).
    This is similar to how os.path.join works.

    :param base: (String) The base namespace path.
    :param name: (String) The new name to append to the base path.
    :returns: (String) A new namespace path resulting from combination of
              base and name.
    """
    return '%s.%s' % (base, name)


def turn_all_axes_off(pylab):
    """ Turns everything off. (TODO) """
    axes = pylab.gca()
    axes.set_frame_on(False)
    pylab.setp(axes.get_xticklabels(), visible=False)
    pylab.setp(axes.get_yticklabels(), visible=False)
    axes.xaxis.offsetText.set_visible(False)
    axes.yaxis.offsetText.set_visible(False)
    axes.xaxis.set_ticks_position('none')
    axes.yaxis.set_ticks_position('none')
    for _, spine in axes.spines.items():
        spine.set_color('none')


def check_error(http):
    """
    Checks for http errors (400 series) and returns True if an error exists.

    Parameters
    ----------
    http : addinfourl whose fp is a socket._fileobject

    Returns
    -------
    has_error : bool
    """
    err = http.code
    if 400 <= err < 500:
        print('HTTP error {}. Make sure your PV exists.'.format(err))
        return True
    return False


def ndarray_empty(var, var_name):
    """
    Check if parameter *var* is not an empty numpy array.

    :raises ValueError: Parameter *var* must not be an emptynumpy ndarray.
    """
    if var.size == 0:
        raise ValueError(
            '\n\nParameter {} must not be an emptynumpy ndarray.\n'.format(
            var_name))


def action(discriminator, callable, args=(), kw={}, order=0, includepath=
    None, info=None):
    """Record a configuration action

        The job of most directives is to compute actions for later
        processing. The action method is used to record those actions.

        :param callable: The object to call to implement the action.
        :param tuple args: Arguments to pass to *callable*
        :param dict kw: Keyword arguments to pass to *callable*

        :param object discriminator: Used to to find actions that conflict.
            Actions conflict if they have equal discriminators. The
            exception to this is the special case of the discriminator
            with the value `None`. An action with a discriminator of `None`
            never conflicts with other actions.

        :keyword int order: This is possible to add an order argument to crudely control
            the order of execution.

        :keyword str info: Optional source line information

        :keyword includepath: is None (the default) or a tuple of
            include paths for this action.
        """


def bool_formatter(handler, item, value):
    """Boolean formatter."""
    glyph = 'ok' if value else 'minus'
    return '' % glyph


def plot_lc_phasezoom(ax, phi, flux, phase, phaseflux, phaseflux_err,
    phase_grid, model_phaseflux_grid, zoomfactor):
    """
    zoomfactor : period * 24 * 60
    """
    ax.plot(phi * zoomfactor, flux, 'k.', color='lightgrey', rasterized=
        True, zorder=10)
    ax.errorbar(phase * zoomfactor, phaseflux, yerr=phaseflux_err, fmt='b.',
        zorder=11)
    ax.plot(phase_grid * zoomfactor, model_phaseflux_grid, 'r-', lw=2,
        zorder=12)
    ax.set(xlim=[-240, 240])
    ax.set(xlabel='Time (min.)', ylabel='Flux')
    return ax


def p_pool_allow_deny_decls(p):
    """ pool_allow_deny_decls : pool_allow_deny_decl
                              | pool_allow_deny_decl pool_allow_deny_decls
    """
    p[0] = {'allow': [], 'deny': []}
    if 'allow' in p[1]:
        p[0]['allow'].append(p[1]['allow'])
    if 'deny' in p[1]:
        p[0]['deny'].append(p[1]['deny'])
    if len(p) > 2:
        p[0]['allow'] = p[0]['allow'] + p[2]['allow']
        p[0]['deny'] = p[0]['deny'] + p[2]['deny']


def dw_WriteBoundData(fname, areas):
    """
    writes B5\\_bounddata.inc
    """
    areas = sorted(areas, reverse=True)
    exfile = open(fname, 'w')
    print(';Written by dw_WriteBoundData', file=exfile)
    for i in areas:
        print("ITEM 'Area_%s'" % i, file=exfile)
        print("CONCENTRATION  'Area_%s' 'Check' 'Initial'" % i, file=exfile)
        print('DATA', file=exfile)
        print('1.0  1.0  0.0', file=exfile)
        print('', file=exfile)
    exfile.close()


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


@staticmethod
def setup_subparser(parser, cmd=None):
    """
        Set up a subparser for 'lint'
        """
    parser.add_argument('target', type=str, default=None, nargs='?', help=
        'Recipe file or prefix')


def __iter__():
    """An iterator over all the banned email addresses.

        :return: iterator over `IBan`"""


@classmethod
def batch_bytes(cls, parts):
    """Return the bytes of a JSON batch from its parts."""
    if parts:
        return b'[' + b', '.join(parts) + b']'
    return b''


@staticmethod
def filter_to_samp_observed(df, samp):
    """
        Filter to observed values in specific sample.

        :param df: DataFrame with all intensities and annotations. Missing values should be 0.
        :param samp: The specific sample of interest
        :return: DataFrame that only has rows whether the quantified value for the sample of interest is
        nonzero.
        """
    filt = df.loc[df[samp] != 0]
    return filt


def subset_sites(ts, position):
    """
    Return a copy of the specified tree sequence with sites reduced to those
    with positions in the specified list.
    """
    tables = ts.dump_tables()
    lookup = frozenset(position)
    tables.sites.clear()
    tables.mutations.clear()
    for site in ts.sites():
        if site.position in lookup:
            site_id = tables.sites.add_row(site.position, ancestral_state=
                site.ancestral_state, metadata=site.metadata)
            for mutation in site.mutations:
                tables.mutations.add_row(site_id, node=mutation.node,
                    parent=mutation.parent, derived_state=mutation.
                    derived_state, metadata=mutation.metadata)
    return tables.tree_sequence()


def mode_assignment(arg):
    """
    Translates arg to enforce proper assignment
    """
    arg = arg.upper()
    stream_args = 'STREAM', 'CONSOLE', 'STDOUT'
    try:
        if arg in stream_args:
            return 'STREAM'
        else:
            return arg
    except Exception:
        return None


def is_included_in(i1, i2):
    """ Is the interval included in i1?
        """
    return i2.inf <= i1.inf and i1.sup <= i2.sup


def with_ribs_fv(data3dr, voxelsize_mm, seeds=None, unique_cls=None):
    """
    Feature vector use intensity and body_navigation module with ribs.
    Implemented by M Bulka

    :param data3dr:
    :param voxelsize_mm:
    :param seeds:
    :param unique_cls:
    :return:
    """
    pass


def vector_from_points(a, b):
    """Construct a vector from two points.

    Parameters
    ----------
    a : sequence of float
        XYZ coordinates of first point.
    b : sequence of float
        XYZ coordinates of second point.

    Returns
    -------
    ab : sequence of float
        The vector from ``a`` to ``b``.

    Examples
    --------
    >>>

    """
    return b[0] - a[0], b[1] - a[1], b[2] - a[2]


def max(a, b):
    """
    Função max(1,3)=3
    :param a: Primeira parcela
    :param b: Segunda parcela
    :return: Retorna parcela maior
    """
    return a if a > b else b


def _mature(subseq, absolute, c, size=33, total=5000):
    """Create mature sequences around start/end"""
    reads = dict()
    probs = [0.1, 0.2, 0.4, 0.2, 0.1]
    end = 5 + size
    error = [-2, -1, 0, 1, 2]
    for error5 in error:
        for error3 in error:
            s = 5 - error5
            e = end - error3
            seen = subseq[s:e]
            counts = int(probs[error5 + 2] * probs[error3 + 2] * total) + 1
            name = 'seq_%s_%s_%s_x%s' % (c, s + absolute, e + absolute, counts)
            reads[name] = seen, counts
    return reads


def start_data_collection_by_agent_ids(agentIds=None):
    """
    Instructs the specified agents or connectors to start collecting data.
    See also: AWS API Documentation

    :example: response = client.start_data_collection_by_agent_ids(
        agentIds=[
            'string',
        ]
    )

    :type agentIds: list
    :param agentIds: [REQUIRED]
            The IDs of the agents or connectors from which to start collecting data. If you send a request to an agent/connector ID that you do not have permission to contact, according to your AWS account, the service does not throw an exception. Instead, it returns the error in the Description field. If you send a request to multiple agents/connectors and you do not have permission to contact some of those agents/connectors, the system does not throw an exception. Instead, the system shows Failed in the Description field.
            (string) --

    :rtype: dict
    :return: {
        'agentsConfigurationStatus': [
            {
                'agentId': 'string',
                'operationSucceeded': True|False,
                'description': 'string'
            },
        ]
    }

    """
    pass


@classmethod
def get_yom_kippur(cls, year):
    """
        Return the gregorian date of Yom Kippur.
        """
    return cls.search_hebrew_calendar(year, 7, 10)


def _parse_query_string(query):
    """Used for replacing cgi.parse_qsl.
    The cgi version returns the same pair for query 'key'
    and query 'key=', so reconstruction
    maps to the same string. But some sites does not handle both versions
    in the same way.
    This version returns (key, None) in the first case, and (key, '') in the
    second one, so correct reconstruction can be performed."""
    params = query.split('&')
    keyvals = []
    for param in params:
        kv = param.split('=') + [None]
        keyvals.append((kv[0], kv[1]))
    return keyvals


def parentrevs(rev):
    """Like parents() but operates on revision numbers."""


def collect_powers(s, v):
    """
        Collect repeated multiplications of string v in s and replace them by exponentiation.

        **Examples**::

            >>> collect_powers('c*c','c')
            'c**2'
            >>> collect_powers('c*c*c*c*c*c*c*c*c*c','c')
            'c**10'
            >>> collect_powers('d*c*c','c')
            'd*c**2'
    """
    import re
    m = s.count(v)
    for i in range(m, 0, -1):
        pattern = re.compile(v + '(\\*' + v + '){' + str(i) + '}')
        s = pattern.sub(v + '**' + str(i + 1), s)
    return s


def callbackShortHelp(option, opt, value, parser):
    """output short help (only command line options)."""
    parser.set_description(None)
    parser.set_usage(None)
    parser.print_help()
    parser.exit()


def get_link_text(link):
    """
    Return text of <a> element: either its string contents or the 'alt'
    of <img> tags inside.
    """
    txt = ' '.join(link.xpath('string()').extract())
    if not txt:
        txt = ' '.join(link.xpath('.//img/@alt').extract())
    return txt


def zpad(x, l):
    " Left zero pad value `x` at least to length `l`.\n\n    >>> zpad('', 1)\n    '\x00'\n    >>> zpad('Êþ', 4)\n    '\x00\x00Êþ'\n    >>> zpad('ÿ', 1)\n    'ÿ'\n    >>> zpad('Êþ', 2)\n    'Êþ'\n    "
    return b'\x00' * max(0, l - len(x)) + x


@staticmethod
def _set_gene(gene):
    """Private function for setting the gene identifier value in the class.

        Parameters
        ----------
        gene : str
            A gene identifier, either V or J, specifying the alignment's origin gene.

        Returns
        -------
        str
            The input gene character value after passing the validation test.

        Raises
        ------
        ValueError
            When the given gene character does not equal 'V' or 'J'.

        """
    gene = gene.upper()
    if gene not in ['V', 'J']:
        raise ValueError("Gene identifier should be either 'V' or 'J'", gene)
    return gene


def get_table_name(engine, obj):
    """return the table name for an object as seen by a given engine"""
    return engine._compute_table_name(obj.__class__)


def visual_transform_apply():
    """Apply the object’s visual transformation to its data

    """
    pass


@classmethod
def to_seconds(cls, timing, unit, model):
    """converts the schedule values to seconds, depending on to the
        schedule_model the value will differ. So if the schedule_model is
        'effort' or 'length' then the schedule_time and schedule_unit values
        are interpreted as work time, if the schedule_model is 'duration' then
        the schedule_time and schedule_unit values are considered as calendar
        time.
        """
    if not unit:
        return None
    lut = {'min': 60, 'h': 3600, 'd': 86400, 'w': 604800, 'm': 2419200, 'y':
        31536000}
    if model in ['effort', 'length']:
        from stalker import defaults
        day_wt = defaults.daily_working_hours * 3600
        week_wt = defaults.weekly_working_days * day_wt
        month_wt = 4 * week_wt
        year_wt = int(defaults.yearly_working_days) * day_wt
        lut = {'min': 60, 'h': 3600, 'd': day_wt, 'w': week_wt, 'm':
            month_wt, 'y': year_wt}
    return timing * lut[unit]


def _meta_to_inputdict(metaDict):
    """
    Converts a dictionary as returned by the isbnlib.meta() function to
    a valid inputdict for an entry object.

    :param metaDict: meta data
    :type metaDict: dict
    :return: inputdict
    :rtype: dict
    """
    inputDict = {}
    for key, vakue in metaDict.items():
        new_key = key.lower()
        if new_key == 'authors':
            new_key = 'author'
        if new_key == 'isbn-13':
            new_key = 'isbn'
        inputDict[new_key] = metaDict[key]
    inputDict['ID'] = str(inputDict.get('isbn', 'unknown'))
    inputDict['ENTRYTYPE'] = 'book'
    inputDict['author'] = ' and '.join(inputDict['author'])
    return inputDict


@staticmethod
def clear_profiling_cookies(request, response):
    """Expire any cookie that initiated profiling request."""
    if 'profile_page' in request.COOKIES:
        path = request.path
        response.set_cookie('profile_page', max_age=0, path=path)


@classmethod
def generate_single_float_sql_gt(cls, column_name, filter_value):
    """Return tuple with sql and replacement.

        This function builds the sql partial and replacement dict for
        a greater-than match for a single float against a single
        column in the database.

        Args:
            column_name (str): Name of column in DB.
            filter_value (str or float): This is what we look for in the column.
                Coerced to float.

        Returns:
            tuple: Item 0 contains the SQL partial string. Item 1 contains
                the replacement dictionary.

        """
    column_name_corrected = column_name.replace('_gt', '')
    sql = '{} > :{}'.format(column_name_corrected, column_name_corrected)
    replacement = {column_name_corrected: float(filter_value)}
    return sql, replacement


def iterative_fdk_cone_beam_reconstruction_filter(*args, **kwargs):
    """Procedural interface for IterativeFDKConeBeamReconstructionFilter"""
    import itk
    instance = itk.IterativeFDKConeBeamReconstructionFilter.New(*args, **kwargs
        )
    return instance.__internal_call__()


def httpdate(date_obj):
    """
    Formats a datetime object for use in HTTP headers.

        >>> import datetime
        >>> httpdate(datetime.datetime(1970, 1, 1, 1, 1, 1))
        'Thu, 01 Jan 1970 01:01:01'
    """
    return date_obj.strftime('%a, %d %b %Y %H:%M:%S')


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

        :param SsoChangeLoginUrlType val:
        :rtype: EventType
        """
    return cls('sso_change_login_url', val)


def get_bd(r, a):
    """Converts turnover and relative extinction to birth and death rates."""
    return -r / (a - 1), -a * r / (a - 1)


def parse_params(params: dict, parse_functions: (dict, None)=None) ->dict:
    """
    参数后处理，根据parse_functions中定义的转换函数，对params中的变量值进行转换。
    例如，可用于将无法直接dump的变量转换成可以dump的变量。

    Examples
    --------
    >>> params = {"a": 1}
    >>> parse_functions = {"a": lambda x: x + x}
    >>> parse_params(params, parse_functions)
    {'a': 2}
    >>> params = {"a": 1}
    >>> parse_params(params)
    {'a': 1}

    """
    if parse_functions is not None:
        for name, func in parse_functions.items():
            if name in params:
                params[name] = func(params[name])
    return params


@staticmethod
def checkConfig(config):
    """Just check the given config, do not apply it. Report result to glin core."""
    return True


def norm_l1(u):
    """
    L1 norm for vector u.
    """
    return abs(u).sum()


def destroy():
    """
        Destroys the result view
        """


def motifs_from_proto(motifs, is_one_dimensional=False):
    """
    Utility function to transform motif locations back to single dimension
    or multi-dimension location.

    Parameter
    ---------
    motifs : array_like
        The protobuf formatted array.
    is_one_dimensional : boolean
        A flag to indicate if the original locations should be 1D.

    Returns
    -------
    list :
        The transformed motif locations.
    """
    out = []
    for motif in motifs:
        tmp = {'motifs': [], 'neighbors': []}
        for location in motif.motifs:
            if is_one_dimensional:
                tmp['motifs'].append(location.row)
            else:
                tmp['motifs'].append((location.row, location.col))
        for neighbor in motif.neighbors:
            if is_one_dimensional:
                tmp['neighbors'].append(neighbor.row)
            else:
                tmp['neighbors'].append((neighbor.row, neighbor.col))
        out.append(tmp)
    return out


def _count_garbage_phrases(video_title, song_title):
    """Checks if there are any phrases in the title of the video that would
        indicate it doesn't have the audio we want
    :param string: a string, the youtube video title
    :param title: a string, the actual title of the song we're looking for
    :rtype: an integer, of the number of bad phrases in the song
    """
    garbage_phrases = (
        'cover  album  live  clean  rare version  full  full album  row  at  @  session  how to  npr music  reimagined  hr version'
        .split('  '))
    bad_phrases = 0
    for gphrase in garbage_phrases:
        if gphrase in song_title.lower():
            continue
        if gphrase in video_title.lower():
            bad_phrases += 1
    return bad_phrases


def enforce_at_most(version):
    """Assert that the current Python version is equal or lower than *version*."""
    assert version.at_most(), 'Requires at most Python ' + str(version)


def dialog_username_extractor(buttons):
    """ Extract username of a follow button from a dialog box """
    if not isinstance(buttons, list):
        buttons = [buttons]
    person_list = []
    for person in buttons:
        if person and hasattr(person, 'text') and person.text:
            try:
                person_list.append(person.find_element_by_xpath(
                    '../../../*').find_elements_by_tag_name('a')[1].text)
            except IndexError:
                pass
    return person_list


def logVFT(T, log_eta_inf, A, T0):
    """
    Computes the base-10 log of viscosity using the Vogel-Fulcher-Tammann eq.

    Parameters
    ----------
    T : float or array_like
        Temperature. Unit: Kelvin.

    log_eta_inf : float
        Base-10 logarithm of the asymptotic viscosity at the limit of infinite
        temperature.

    A : float
        Adjustable parameter inside the exponential. Unit: Kelvin.

    T0 : float
        Divergence temperature. Unit: Kelvin.

    Returns
    -------
    log10_viscosity : float or array_like
        Returns the base-10 logarithm of viscosity.

    References
    ----------
    [1] Vogel, H. (1921). Das Temperatureabhängigketsgesetz der Viskosität von
        Flüssigkeiten. Physikalische Zeitschrift 22, 645–646.

    [2] Fulcher, G.S. (1925). Analysis of recent measurements of the viscosity
        of glasses. Journal of the American Ceramic Society 8, 339–355.

    [3] Tammann, G., and Hesse, W. (1926). Die Abhängigkeit der Viscosität von
        der Temperatur bie unterkühlten Flüssigkeiten. Z. Anorg. Allg. Chem.
        156, 245–257.
    """
    log10_viscosity = log_eta_inf + A / (T - T0)
    return log10_viscosity


def log_target_types(all_logs=False, **kwargs):
    """
    Log targets for log tasks. A log target defines the log types
    that will be affected by the operation. For example, when creating
    a DeleteLogTask, you can specify which log types are deleted.

    :param bool for_alert_event_log: alert events traces (default: False)
    :param bool for_alert_log: alerts (default: False)
    :param bool for_fw_log: FW logs (default: False)
    :param bool for_ips_log: IPS logs (default: False)
    :param bool for_ips_recording: any IPS pcaps (default: False)
    :param bool for_l2fw_log: layer 2 FW logs (default: False)
    :param bool for_third_party_log: any 3rd party logs (default: False)
    :return: dict of log targets
    """
    log_types = {'for_alert_event_log': False, 'for_alert_log': False,
        'for_audit_log': False, 'for_fw_log': False, 'for_ips_log': False,
        'for_ips_recording_log': False, 'for_l2fw_log': False,
        'for_third_party_log': False}
    if all_logs:
        for key in log_types.keys():
            log_types[key] = True
    else:
        for key, value in kwargs.items():
            log_types[key] = value
    return log_types


def generate_canonical_request(method, parsed_url, headers, signed_headers,
    content_sha256):
    """
    Generate canonical request.

    :param method: HTTP method.
    :param parsed_url: Parsed url is input from :func:`urlsplit`
    :param headers: HTTP header dictionary.
    :param content_sha256: Content sha256 hexdigest string.
    """
    parsed_url_path = parsed_url.path.replace('%7E', '~')
    parsed_url_query = parsed_url.query.replace('%7E', '~')
    lines = [method, parsed_url_path, parsed_url_query]
    header_lines = []
    for header in signed_headers:
        value = headers[header.title()]
        value = str(value).strip()
        header_lines.append(header + ':' + value)
    lines = lines + header_lines
    lines.append('')
    lines.append(';'.join(signed_headers))
    lines.append(content_sha256)
    return '\n'.join(lines)


def p_phrase_or_term(p):
    """phrase_or_term : TERM
                      | PHRASE"""
    p[0] = p[1]


def str2bool(_str):
    """
    returns True/False value from given string, it tries to translate the
    string into boolean

    :param _str: string value to translate into boolean
    :rtype: boolean
    :returns: boolean from given string
    """
    if _str is None:
        return False
    if _str in (True, False):
        return _str
    _str = str(_str).strip().lower()
    return _str in ('t', 'true', 'y', 'yes', 'on', '1')


def get_application_names(topology, node):
    """Return a list of names of applications deployed on a node

    Parameters
    ----------
    topology : Topology
        The topology
    node : any hashable type
        The ID of the node

    Returns
    -------
    application_names : list
        A list of application names
    """
    return [] if 'application' not in topology.node[node] else list(topology
        .node[node]['application'].keys())


def _parse_section_heading(raw_section):
    """Parse the heading section.

    Parameters
    ----------
    raw_section : list of strings
        The text data for a given section which will be parsed.

    Returns
    -------
    setting : dict
        A dict with keys corresponding to the settings.

    """
    if not raw_section:
        return None
    return {'text': '\n'.join(raw_section)}


def prepare_table(table):
    """Make the table 'symmetric' where the lower left part of the matrix is
       the reverse probability
    """
    n = len(table)
    for i, row in enumerate(table):
        assert len(row) == n
        for j, el in enumerate(row):
            if i == j:
                table[i][i] = 0.0
            elif i > j:
                table[i][j] = 1 - table[j][i]
    return table