def describe_cluster_snapshots(ClusterIdentifier=None, SnapshotIdentifier=
    None, SnapshotType=None, StartTime=None, EndTime=None, MaxRecords=None,
    Marker=None, OwnerAccount=None, TagKeys=None, TagValues=None):
    """
    Returns one or more snapshot objects, which contain metadata about your cluster snapshots. By default, this operation returns information about all snapshots of all clusters that are owned by you AWS customer account. No information is returned for snapshots owned by inactive AWS customer accounts.
    If you specify both tag keys and tag values in the same request, Amazon Redshift returns all snapshots that match any combination of the specified keys and values. For example, if you have owner and environment for tag keys, and admin and test for tag values, all snapshots that have any combination of those values are returned. Only snapshots that you own are returned in the response; shared snapshots are not returned with the tag key and tag value request parameters.
    If both tag keys and values are omitted from the request, snapshots are returned regardless of whether they have tag keys or values associated with them.
    See also: AWS API Documentation

    :example: response = client.describe_cluster_snapshots(
        ClusterIdentifier='string',
        SnapshotIdentifier='string',
        SnapshotType='string',
        StartTime=datetime(2015, 1, 1),
        EndTime=datetime(2015, 1, 1),
        MaxRecords=123,
        Marker='string',
        OwnerAccount='string',
        TagKeys=[
            'string',
        ],
        TagValues=[
            'string',
        ]
    )

    :type ClusterIdentifier: string
    :param ClusterIdentifier: The identifier of the cluster for which information about snapshots is requested.

    :type SnapshotIdentifier: string
    :param SnapshotIdentifier: The snapshot identifier of the snapshot about which to return information.

    :type SnapshotType: string
    :param SnapshotType: The type of snapshots for which you are requesting information. By default, snapshots of all types are returned.
            Valid Values: automated | manual

    :type StartTime: datetime
    :param StartTime: A value that requests only snapshots created at or after the specified time. The time value is specified in ISO 8601 format. For more information about ISO 8601, go to the ISO8601 Wikipedia page.
            Example: 2012-07-16T18:00:00Z

    :type EndTime: datetime
    :param EndTime: A time value that requests only snapshots created at or before the specified time. The time value is specified in ISO 8601 format. For more information about ISO 8601, go to the ISO8601 Wikipedia page.
            Example: 2012-07-16T18:00:00Z

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of response records to return in each call. If the number of remaining response records exceeds the specified MaxRecords value, a value is returned in a marker field of the response. You can retrieve the next set of records by retrying the command with the returned marker value.
            Default: 100
            Constraints: minimum 20, maximum 100.

    :type Marker: string
    :param Marker: An optional parameter that specifies the starting point to return a set of response records. When the results of a DescribeClusterSnapshots request exceed the value specified in MaxRecords , AWS returns a value in the Marker field of the response. You can retrieve the next set of response records by providing the returned marker value in the Marker parameter and retrying the request.

    :type OwnerAccount: string
    :param OwnerAccount: The AWS customer account used to create or copy the snapshot. Use this field to filter the results to snapshots owned by a particular account. To describe snapshots you own, either specify your AWS customer account, or do not specify the parameter.

    :type TagKeys: list
    :param TagKeys: A tag key or keys for which you want to return all matching cluster snapshots that are associated with the specified key or keys. For example, suppose that you have snapshots that are tagged with keys called owner and environment . If you specify both of these tag keys in the request, Amazon Redshift returns a response with the snapshots that have either or both of these tag keys associated with them.
            (string) --

    :type TagValues: list
    :param TagValues: A tag value or values for which you want to return all matching cluster snapshots that are associated with the specified tag value or values. For example, suppose that you have snapshots that are tagged with values called admin and test . If you specify both of these tag values in the request, Amazon Redshift returns a response with the snapshots that have either or both of these tag values associated with them.
            (string) --

    :rtype: dict
    :return: {
        'Marker': 'string',
        'Snapshots': [
            {
                'SnapshotIdentifier': 'string',
                'ClusterIdentifier': 'string',
                'SnapshotCreateTime': datetime(2015, 1, 1),
                'Status': 'string',
                'Port': 123,
                'AvailabilityZone': 'string',
                'ClusterCreateTime': datetime(2015, 1, 1),
                'MasterUsername': 'string',
                'ClusterVersion': 'string',
                'SnapshotType': 'string',
                'NodeType': 'string',
                'NumberOfNodes': 123,
                'DBName': 'string',
                'VpcId': 'string',
                'Encrypted': True|False,
                'KmsKeyId': 'string',
                'EncryptedWithHSM': True|False,
                'AccountsWithRestoreAccess': [
                    {
                        'AccountId': 'string',
                        'AccountAlias': 'string'
                    },
                ],
                'OwnerAccount': 'string',
                'TotalBackupSizeInMegaBytes': 123.0,
                'ActualIncrementalBackupSizeInMegaBytes': 123.0,
                'BackupProgressInMegaBytes': 123.0,
                'CurrentBackupRateInMegaBytesPerSecond': 123.0,
                'EstimatedSecondsToCompletion': 123,
                'ElapsedTimeInSeconds': 123,
                'SourceRegion': 'string',
                'Tags': [
                    {
                        'Key': 'string',
                        'Value': 'string'
                    },
                ],
                'RestorableNodeTypes': [
                    'string',
                ],
                'EnhancedVpcRouting': True|False
            },
        ]
    }

    :returns:
    CreateClusterSnapshot and  CopyClusterSnapshot returns status as "creating".
    DescribeClusterSnapshots returns status as "creating", "available", "final snapshot", or "failed".
    DeleteClusterSnapshot returns status as "deleted".

    """
    pass


def add_size(kwargs, size=(800, 600)):
    """Add size to kwargs if not present."""
    if 'size' not in kwargs:
        kwargs['size'] = size
    return kwargs


def unordered_list(l):
    """given a list, returns another list with unique and alphabetically sorted elements.
    use for HTML attributes that have no semantics to their order e.g. class, rel.
    """
    return sorted(set(l))


def zoom_camera_1_to_1():
    """Match the camera to 1:1 to the render output

    """
    pass


def lateral_shift(transform, shift):
    """Makes a lateral shift of the forward vector of a transform"""
    transform.rotation.yaw += 90
    return transform.location + shift * transform.get_forward_vector()


def theta_HCO3_HSO4_HMW84(T, P):
    """a-a': bicarbonate bisulfate [HMW84]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def iget(d, key):
    """
    A function for getting value while ignoring case sensitive of the key.
    """
    _ = lambda s: s.strip().lower()
    ret = ''
    for k, v in d.items():
        if _(k) == _(key):
            ret = v
    return ret


def on_goal(goal: str, meta, *, raw: str):
    """Callback; set this attribute in the parent class."""
    raise NotImplementedError


def read_quast_file(file):
    """
    Extracts misassembly regions from QUAST file, usually located in /QUAST_output/contig_reports/all_alignments_$$.tsv
    :param file:
    :return:
    """
    total_count = 0
    relocation_count = 0
    translocation_count = 0
    inversion_count = 0
    misassemblies = []
    with open(file) as f:
        prev_line = ''
        for line in f:
            line = line.rstrip().replace(',', '')
            splits = line.split('\t')
            if splits[0].split(' ')[0] == 'relocation':
                s_ref, e_ref, s_con, e_con, ref, con, idn, ambi, bg = (
                    prev_line.split('\t'))
                misassemblies.append([ref, s_ref, e_ref, splits[0].split(
                    ' ')[0]])
                relocation_count += 1
                total_count += 1
            elif splits[0] == 'translocation':
                s_ref, e_ref, s_con, e_con, ref, con, idn, ambi, bg = (
                    prev_line.split('\t'))
                misassemblies.append([ref, s_ref, e_ref, splits[0]])
                translocation_count += 1
                total_count += 1
            elif splits[0] == 'inversion':
                s_ref, e_ref, s_con, e_con, ref, con, idn, ambi, bg = (
                    prev_line.split('\t'))
                misassemblies.append([ref, s_ref, e_ref, splits[0]])
                inversion_count += 1
                total_count += 1
            prev_line = line
    print('#####--TOTAL MISSASSEMBLIES: REPORTED BY QUAST--#####')
    print('Total Misassemblies:\t', total_count)
    print('Total relocations:\t', relocation_count)
    print('Total translocations:\t', translocation_count)
    print('Total inversions:\t', inversion_count)
    print('#####################################################\n')
    return misassemblies


@staticmethod
def _get_router_ids_from_removed_devices_info(removed_devices_info):
    """Extract router_ids from the removed devices info dict.

        :param removed_devices_info: Dict of removed devices and their
               associated resources.
        Format:
                {
                  'hosting_data': {'hd_id1': {'routers': [id1, id2, ...]},
                                   'hd_id2': {'routers': [id3, id4, ...]},
                                   ...
                                  },
                  'deconfigure': True/False
                }
        :return removed_router_ids: List of removed router ids
        """
    removed_router_ids = []
    for hd_id, resources in removed_devices_info['hosting_data'].items():
        removed_router_ids += resources.get('routers', [])
    return removed_router_ids


def environment_filename(plan_name):
    """Generates the filename of a deployment plan's environment file
    when it is written out as a file for Heat.

    :type plan_name: str
    :rtype: str
    """
    return '%s-%s' % (plan_name, 'environment.yaml')


def unrelate(category_name, discriminator):
    """ Indicate an intent to break the relationship between this
        IIntrospectable with another IIntrospectable (the one associated with
        the ``category_name`` and ``discriminator``) during action execution.
        """


def primitive_nurbs_curve_add(radius: float=1.0, view_align: bool=False,
    enter_editmode: bool=False, location: float=(0.0, 0.0, 0.0), rotation:
    float=(0.0, 0.0, 0.0), layers: bool=(False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False)):
    """Construct a Nurbs Curve

    :param radius: Radius
    :type radius: float
    :param view_align: Align to View, Align the new object to the view
    :type view_align: bool
    :param enter_editmode: Enter Editmode, Enter editmode when adding this object
    :type enter_editmode: bool
    :param location: Location, Location for the newly added object
    :type location: float
    :param rotation: Rotation, Rotation for the newly added object
    :type rotation: float
    :param layers: Layer
    :type layers: bool
    """
    pass


def get_rpath_psp(kind, exchange, atomicnumber=None):
    """
    Get the ftp path to get the PSP

    :param kind: (str) Source of Pseudopotentials
    :param exchange: (str) 'LDA' or 'GGA'
    :param atomicnumber: (int) Atomic Number
    :return:
    """
    rpath = None
    if kind == 'FHI' and exchange == 'LDA':
        rpath = '/pub/abinitio/Psps/LDA_FHI/'
    elif kind == 'FHI' and exchange == 'GGA':
        rpath = '/pub/abinitio/Psps/GGA_FHI/'
    elif kind == 'GTH' and exchange == 'LDA':
        rpath = '/pub/abinitio/Psps/LDA_GTH/'
    elif kind == 'CORE' and exchange == 'LDA':
        rpath = '/pub/abinitio/Psps/LDA_Core/'
    elif kind == 'HGH' and exchange == 'LDA':
        rpath = '/pub/abinitio/Psps/LDA_HGH/'
    elif kind == 'HGH' and exchange == 'GGA':
        rpath = '/pub/abinitio/Psps/GGA_HGH/'
    elif kind == 'TM' and exchange == 'LDA':
        if atomicnumber is None:
            raise ValueError('Atomic number required')
        rpath = '/pub/abinitio/Psps/LDA_TM.psps/' + str(atomicnumber).zfill(2
            ) + '/'
    elif kind == 'AE' and exchange == 'DEN':
        rpath = '/pub/abinitio/Psps/AE_DEN/'
    elif kind == 'FC' and exchange == 'DEN':
        rpath = '/pub/abinitio/Psps/FC_DEN/'
    elif kind == 'PAW' and exchange == 'LDA':
        rpath = ' https://www.abinit.org/ATOMICDATA/JTH-LDA-atomicdata.tar.gz'
    elif kind == 'PAW' and exchange == 'PBE':
        rpath = ' https://www.abinit.org/ATOMICDATA/JTH-PBE-atomicdata.tar.gz'
    elif kind == 'ONC' and exchange == 'PBE':
        rpath = (
            ' http://www.pseudo-dojo.org/pseudos/nc-sr_pbe_standard_psp8.tgz')
    else:
        print('Not know kind of PSP')
    return rpath


def setext_heading(text, level):
    """Return an setext heading.

    `text` is the text to include in the heading. Leading and trailing
    whitespace is trimmed from `text`. If `level` is the number `1`, a first
    level (h1) heading is returned. If `level` is the number `2` (or anything
    else), a second level (h2) heading is returned.

    See https://github.github.com/gfm/#setext-heading for more information.
    """
    if level == 1:
        hchar = '='
    else:
        hchar = '-'
    return '{}\n{}'.format(text.strip(), hchar * len(text.strip()))


def orderedSet(iterable):
    """ Remove all duplicates from the input iterable """
    res = []
    for el in iterable:
        if el not in res:
            res.append(el)
    return res


def str_adjustment(file: str, group_files: str, cdo, options, verbose, **kwargs
    ):
    """
    Add attributes to sustr and svstr
    :param preprocessor: PreProcessor object, contains a lot of necessary adjustments
    :param file: file which contains all necessary parameters to calculate dQdSST
    :param group_files: list of all files which contain necessary parameters to calculate dQdSST
    :param flags: any extra info necessary
    :return:
    """
    if verbose:
        print('Adjusting for surface stress')
    temp = cdo.setattribute(
        "sustr@long_name='surface u-momentum stress',svstr@long_name='surface v-momentum stress',sustr@unit='Newton meter-2',svstr@unit='Newton meter-2',sustr@files='"
         + group_files + "',svstr@files='" + group_files + "'", input=file,
        options=options)
    cdo.copy(input=temp, output=file, options=options)
    if verbose:
        print('surface stress has been added')


def activities(archived=False):
    """Return a list of activity definitions.
        """


def get_setup(job=None):
    """
    Return the resource specific setup.

    :param job: optional job object.
    :return: setup commands (list).
    """
    return []


def _orbits_transversals_from_bsgs(base, strong_gens_distr,
    transversals_only=False, slp=False):
    """
    Compute basic orbits and transversals from a base and strong generating set.

    The generators are provided as distributed across the basic stabilizers.
    If the optional argument ``transversals_only`` is set to True, only the
    transversals are returned.

    Parameters
    ==========

    ``base`` - the base
    ``strong_gens_distr`` - strong generators distributed by membership in basic
    stabilizers
    ``transversals_only`` - a flag switching between returning only the
    transversals/ both orbits and transversals
    ``slp`` - if ``True``, return a list of dictionaries containing the
              generator presentations of the elements of the transversals,
              i.e. the list of indices of generators from `strong_gens_distr[i]`
              such that their product is the relevant transversal element

    Examples
    ========

    >>> from sympy.combinatorics import Permutation
    >>> Permutation.print_cyclic = True
    >>> from sympy.combinatorics.named_groups import SymmetricGroup
    >>> from sympy.combinatorics.util import _orbits_transversals_from_bsgs
    >>> from sympy.combinatorics.util import (_orbits_transversals_from_bsgs,
    ... _distribute_gens_by_base)
    >>> S = SymmetricGroup(3)
    >>> S.schreier_sims()
    >>> strong_gens_distr = _distribute_gens_by_base(S.base, S.strong_gens)
    >>> _orbits_transversals_from_bsgs(S.base, strong_gens_distr)
    ([[0, 1, 2], [1, 2]], [{0: (2), 1: (0 1 2), 2: (0 2 1)}, {1: (2), 2: (1 2)}])

    See Also
    ========

    _distribute_gens_by_base, _handle_precomputed_bsgs

    """
    from sympy.combinatorics.perm_groups import _orbit_transversal
    base_len = len(base)
    degree = strong_gens_distr[0][0].size
    transversals = [None] * base_len
    slps = [None] * base_len
    if transversals_only is False:
        basic_orbits = [None] * base_len
    for i in range(base_len):
        transversals[i], slps[i] = _orbit_transversal(degree,
            strong_gens_distr[i], base[i], pairs=True, slp=True)
        transversals[i] = dict(transversals[i])
        if transversals_only is False:
            basic_orbits[i] = list(transversals[i].keys())
    if transversals_only:
        return transversals
    else:
        if not slp:
            return basic_orbits, transversals
        return basic_orbits, transversals, slps


def _reverse_and_conj(x):
    """
    Reverse array `x` in all dimensions and perform the complex conjugate
    """
    reverse = (slice(None, None, -1),) * x.ndim
    return x[reverse].conj()


def _element_matches(element_to_remove: str, element_to_check: str) ->bool:
    """Checks if an element meets the criteria to be removed from list.

    Some attribute elements (eg. macros) can be defined with a number value
    eg. MACRO_SOMETHING=5. If we are then instructed to remove
    MACRO_SOMETHING then this element needs to be recognised and removed
    in addition to exact matches.

    Args:
        element_to_remove: the element as taken from list to be removed from an attribute
        element_to_check: an element that currently makes up part of an attribute definition

    Returns:
        A boolean reflecting whether the element is a match and should be removed
    """
    return (element_to_check == element_to_remove or element_to_check.
        startswith(f'{element_to_remove}='))


def getFlags(in_args):
    """
    in_args: sys.argv;
    return set.
    """
    _res = filter(lambda arg: arg if arg[0] == '-' else '', in_args)
    return set(''.join(map(lambda arg: arg[1:], _res)))


def unmean(cur_mean, cur_N, value_to_remove):
    """
    Removes the influence of <value_to_remove> from a mean value that currently is calculated
    from <cur_N> samples.

    That is, if <value_to_remove> is the <cur_N>th sample, return what the mean of the 1-(<cur_N>-1)th samples
    must be.
    """
    return cur_mean * (float(cur_N) / float(cur_N - 1)
        ) - value_to_remove / float(cur_N - 1)


@classmethod
def fromkeys(cls, iterable, value=None):
    """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
        and values equal to v (which defaults to None).

        """
    d = cls()
    for key in iterable:
        d[key] = value
    return d


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 get_user_attributes(obj, exclude_methods=True):
    """Returns a list of non-system attributes for an object.

    :param obj: object or class to inspect
    :param exclude_methods: [optional] do not include callable methods in the
        returned list, defaults to True

    :returns: list of non-system attributes of an object or class
    """
    base_attributes = dir(type('dummy', (object,), {}))
    attributes = dir(obj)
    results = []
    for attribute in attributes:
        try:
            if attribute in base_attributes or exclude_methods and callable(
                getattr(obj, attribute)):
                continue
            results.append(attribute)
        except AttributeError:
            pass
    return results


def get_binder_regex(pdb_name, receptor):
    """
    Get binder regex for provided filename.

    e.g. bound 11as_r_u_cleaned.pdb1 would give 11as_r_._cleaned.pdb1.
    """
    new_pdb_name = list(pdb_name)
    new_pdb_name[7] = '.'
    new_pdb_name[5] = 'r' if receptor else 'l'
    new_pdb_name = ['^'] + new_pdb_name + ['$']
    return ''.join(new_pdb_name)


def unindex_doc(docid):
    """Remove a document from the index.

        docid: int, identifying the document

        return: None

        This call is a no-op if the docid isn't in the index, however,
        after this call, the index should have no references to the docid.
        """


def set_validation_data(nn, task, reader):
    """Sets the neural network validation data."""
    if task == 'pos' or task == 'srl_predicates':
        nn.set_validation_data(reader.sentences, reader.tags)
    elif task.startswith('srl') and task != 'srl_predicates':
        arg_limits = None if task != 'srl_classify' else reader.arg_limits
        nn.set_validation_data(reader.sentences, reader.predicates, reader.
            tags, arg_limits)
    elif task.endswith('dependency'):
        if task.startswith('unlabeled'):
            nn.set_validation_data(reader.sentences, reader.heads)
        else:
            nn.set_validation_data(reader.sentences, reader.heads, reader.
                labels)
    else:
        raise ValueError('Unknown task: %s' % task)


@staticmethod
def _check_key_valid(key):
    """_check_key_valid.

        Internal method to check if an input key to the dictionary is valid.
        Checks to see if ``key`` is a tuple.

        Parameters
        ----------
        key : anything, but must be a tuple to be valid.

        Returns
        -------
        None.

        Raises
        ------
        KeyError if the key is invalid.

        """
    if not isinstance(key, tuple):
        raise KeyError('Key formatted incorrectly, must be tuple')


def split_lstring(buf):
    """split a list of length-prefixed strings into python not-length-prefixed bytes"""
    result = []
    mv = memoryview(buf)
    while mv:
        length = mv[0]
        result.append(bytes(mv[1:1 + length]))
        mv = mv[1 + length:]
    return result


def to_flamegraph(stacks, counts):
    """ Convert the stack dumps and sample counts into the flamegraph format.

    Return a list of lines.
    """
    lines = []
    for id in counts:
        stack = ';'.join(reversed(stacks[id]))
        count = counts[id]
        lines.append('{0} {1}'.format(stack, count))
    return lines


def MergeStandardOptions(options, params):
    """
    Take an options object generated by the command line and merge
    the values into the IISParameters object.
    """
    pass


def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]


@classmethod
def _attributes(cls, attr_name):
    """
        Returns a tuple containing just the valyue of the given attr_name of all
        the elements.

        :return: tuple of different types
        """
    return tuple(map(lambda x: getattr(x, attr_name), list(cls)))


@classmethod
def from_jsondict(cls, jsondict):
    """ initialize a DimArray from a json-compatible dictionary
        """
    jsondict = jsondict.copy()
    dima = cls(jsondict.pop('values', None), axes=jsondict.pop('labels',
        None), dims=jsondict.pop('dims', None))
    if 'meta' in jsondict:
        dima._metadata(jsondict['meta'])
    return dima


@classmethod
def from_str(cls, text):
    """ Convert a text representation of a qualified object name into an ObjectName instance

        For example, 'foo.bar', '"foo".bar', '"foo"."bar"', etc. will be converted an object with
        schema 'foo' and object name 'bar'. Double quotes around the schema or object name are
        stripped, but note that we don't do anything with impossible input like 'foo."bar".baz'
        (which is impossible because the object name would include double quotes in it). Instead,
        we let processing proceed and the issue bubble up downstream.
        """
    if '.' not in text:
        return cls(schema=text)
    schema, unqualified_name = text.split('.', 1)
    return cls(schema=schema, unqualified_name=unqualified_name)


def preprocess_arguments(argsets, converters):
    """convert and collect arguments in order of priority

    Parameters
    ----------
    argsets : [{argname: argval}]
        a list of argument sets, each with lower levels of priority
    converters : {argname: function}
        conversion functions for each argument

    Returns
    -------
    result : {argname: argval}
        processed arguments
    """
    result = {}
    for argset in argsets:
        for argname, argval in argset.items():
            if not argname in converters:
                raise ValueError('Unrecognized argument: {0}'.format(argname))
            if argname not in result and argval is not None:
                argval = converters[argname](argval)
                result[argname] = argval
    if not len(converters.keys()) == len(result.keys()):
        missing = set(converters.keys()) - set(result.keys())
        s = 'The following arguments are missing: {0}'.format(list(missing))
        raise ValueError(s)
    return result


def read_dict_text(fn):
    """
    Read a dictionary with several sections from plain text format. Section is denoted by first character being '#'.
    Returns dictionary of lists
    :param fn: filename
    :return: Dictionary with a list of lines for each section
    """
    dict = {}
    lines = []
    prevsec = ''
    with open(fn) as f:
        for x in f.readlines():
            x = x.strip()
            if x[0] == '#':
                if len(lines) > 0 and prevsec != '':
                    dict[prevsec] = lines
                    lines = []
                    prevsec = x[1:]
            else:
                lines.append(x)
    if len(lines) > 0 and prevsec != '':
        dict[prevsec] = lines
    return dict


def _minimasearch_parallel_init(c_neighbour_list, terminating, PROCNAME):
    """Allow easy data sharing between processes without pickling.

    Args:
        c_neighbour_list: (internal data structure of libFireDeamon) a data
            structure describing which point on a grid is whose neighbour
        terminating: (return value of multiprocessing.Event()) specifies
            whether or not a parallel computation has been terminated
            prematurely or not
        PROCNAME: (string) name of the process
    """
    global data_ms
    data_ms = c_neighbour_list, terminating, PROCNAME


def shape_contains(shape, pos):
    """
    Check if a tensor of the given shape contains the
    position.
    """
    assert len(shape) == len(pos)
    for val, max_val in zip(pos, shape):
        if val < 0 or val >= max_val:
            return False
    return True


def payment_delete(payment):
    """This is called just before a payment is deleted

        :param payment: the payment which is going to be deleted
        """


def set_progress(how):
    """ Enables or disables the progress bars for the loading, writing and downloading
    of datasets

    :param how: True if you want the progress bar, False otherwise
    :return: None

    Example::

        import gmql as gl

        gl.set_progress(True)   # abilitates progress bars
        # ....do something...
        gl.set_progress(False)  # removes progress bars
        # ....do something...
    """
    global __progress_bar
    if isinstance(how, bool):
        __progress_bar = how
    else:
        raise ValueError('how must be a boolean. {} was found'.format(type(
            how)))


@staticmethod
def in_quad(progress):
    """.. image:: images/anim_in_quad.png
        """
    return progress * progress


def water(target, temperature='pore.temperature', salinity='pore.salinity'):
    """
    Calculates density of pure water or seawater at atmospheric pressure
    using Eq. (8) given by Sharqawy et. al [1]. Values at temperature higher
    than the normal boiling temperature are calculated at the saturation
    pressure.

    Parameters
    ----------
    target : OpenPNM Object
        The object for which these values are being calculated.  This
        controls the length of the calculated array, and also provides
        access to other necessary thermofluid properties.

    temperature : string
        The dictionary key containing the temperature values.  Temperature must
        be in Kelvin for this emperical equation to work

    salinity : string
        The dictionary key containing the salinity values.  Salinity must be
        expressed in g of salt per kg of solution (ppt).

    Returns
    -------
    value : NumPy ndarray
        The density of water/seawater in [kg/m3]

    Notes
    -----
     T must be in K, and S in g of salt per kg of phase, or ppt (parts per
        thousand)
    VALIDITY: 273 < T < 453 K; 0 < S < 160 g/kg;
    ACCURACY: 0.1 %

    References
    ----------
    [1] Sharqawy M. H., Lienhard J. H., and Zubair, S. M., Desalination and
    Water Treatment, 2010.

    """
    T = target[temperature]
    if salinity in target.keys():
        S = target[salinity]
    else:
        S = 0
    a1 = 999.92293295
    a2 = 0.020341179217
    a3 = -0.0061624591598
    a4 = 2.2614664708e-05
    a5 = -4.6570659168e-08
    b1 = 0.80200240891
    b2 = -0.0020005183488
    b3 = 1.6771024982e-05
    b4 = -3.0600536746e-08
    b5 = -1.6132224742e-11
    TC = T - 273.15
    rho_w = a1 + a2 * TC + a3 * TC ** 2 + a4 * TC ** 3 + a5 * TC ** 4
    d_rho = (b1 * S + b2 * S * TC + b3 * S * TC ** 2 + b4 * S * TC ** 3 +
        b5 * S ** 2 * TC ** 2)
    rho_sw = rho_w + d_rho
    value = rho_sw
    return value


@classmethod
def from_point(cls, point):
    """
        Create and return a new Point instance from another Point instance.

        """
    return cls(point.latitude, point.longitude, point.altitude)


def delete_port_group(session, portgroup_moref):
    """Delete a specific port group

    :param session: vCenter soap session
    :param portgroup_moref: managed portgroup object reference
    """
    task = session.invoke_api(session.vim, 'Destroy_Task', portgroup_moref)
    session.wait_for_task(task)


def hr_size(num, suffix='B') ->str:
    """
    Human-readable data size
    From https://stackoverflow.com/a/1094933
    :param num: number of bytes
    :param suffix: Optional size specifier
    :return: Formatted string
    """
    for unit in ' KMGTPEZ':
        if abs(num) < 1024.0:
            return '%3.1f%s%s' % (num, unit if unit != ' ' else '', suffix)
        num /= 1024.0
    return '%.1f%s%s' % (num, 'Y', suffix)


def getSchema():
    """Return a single schema representing fields from all member schemata
        """


def get_domain_server_version(domain):
    """
    Get the Server version based on the Server header for the web server.
    """
    if domain.canonical.server_version is not None:
        return domain.canonical.server_version
    if domain.https.server_version is not None:
        return domain.https.server_version
    if domain.httpswww.server_version is not None:
        return domain.httpswww.server_version
    if domain.httpwww.server_version is not None:
        return domain.httpwww.server_version
    if domain.http.server_version is not None:
        return domain.http.server_version
    return None


def within_set(df, items=None):
    """
    Assert that df is a subset of items

    Parameters
    ==========
    df : DataFrame
    items : dict
      mapping of columns (k) to array-like of values (v) that
      ``df[k]`` is expected to be a subset of

    Returns
    =======
    df : DataFrame
    """
    for k, v in items.items():
        if not df[k].isin(v).all():
            bad = df.loc[~df[k].isin(v), k]
            raise AssertionError('Not in set', bad)
    return df


@staticmethod
def G_factor(HV, HH):
    """
        Compute G-factor to correct for differences in transmittion effiency of the horizontal and vertical polarized light

        Parameters
        ----------
        HV : ndarray
             horizontal excitation - vertical emission
        HH : ndarray
             horizontal excitation - horizontal emission
        Returns
        -------
        G : float
            G-factor

        Notes
        -----
        The G-factor is defined as follows:

        .. math::
            G = \\frac{\\int HV}{\\int HH}
        """
    G = sum(HV) / sum(HH)
    return G


@classmethod
def load_tree(cls, path, config, nav_path='', parent=None):
    """
        Load chapters tree.
        """
    raise Exception(NotImplemented)


def copy():
    """Copy selected text to clipboard

    """
    pass


def is_int(s):
    """Returns true if s represents an integer"""
    try:
        int(s)
        return True
    except ValueError:
        return False


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 dict_maker(directory_list):
    """
    uses the list of file directories constructed by pathlist_make(),
    In the case of the obs and model results, merely returns a dict of file name and path for later use.

    :return:
    """
    location_dict = {}
    if 'rzsm_u_' in directory_list[0]:
        for item in directory_list:
            item_list = item.split('.')
            sel = item_list[0]
            label = sel[-20:]
            location_dict[label] = item
        return location_dict
    elif 'rzsm_' in directory_list[0]:
        for item in directory_list:
            item_list = item.split('.')
            sel = item_list[0]
            label = sel[-19:]
            location_dict[label] = item
        return location_dict


def getArguments(parser):
    """Provides additional validation of the arguments collected by argparse."""
    return parser.parse_args()


def __len__():
    """ Return the length of the result set"""


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


def data_unlink():
    """Unlink active Grease Pencil datablock

    """
    pass


@classmethod
def get_api_root(cls):
    """
        Obtain an object representing the management API root for this user.

        The API root contains entry points for managing

        Returns:
            dict
            Example:
                {<hashid>: {
                    'name': 'ktuin.com',
                    'items': {'product': <product crud entry point>},
                    'tasks': {
                        'process': <process task entry point>,
                        'crawl': <crawl task entry point>
                    }
                ....}
        """
    return cls.management_api_call()['response']


def PolsSurg(t):
    """Number of policies: Surgery"""
    return 0


def Option(instrument, maturity_date, strike):
    """Create Option object for option information specified
	"""
    return {**{'MatDt': str(maturity_date) + 'T00:00:00.000-05:00',
        'StrkPx': str(int(strike)), 'SecTyp': 'OPT', '__maturity': str(
        maturity_date), '__strike': str(int(strike))}, **instrument}


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


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


@classmethod
def can_download(cls, url):
    """
        Determine if this class can download the given ``url``.
        """
    if url is None:
        return False
    return u'youtube.com' in url or u'youtu.be' in url or len(url) == 11


@classmethod
def from_data(cls, data):
    """Construct a point from a data dict.

        Parameters
        ----------
        data : dict
            The data dictionary.

        Returns
        -------
        :class:`compas.geometry.Point`
            The constructed point.

        Examples
        --------
        >>> point = Point.from_data([0.0, 0.0, 0.0])
        >>> point
        Point(0.000, 0.000, 0.000)
        """
    return cls(*data)


def noop(*args, **kw) ->None:
    """No operation. Returns nothing"""
    pass


def zero_values_indices(diffs):
    """generate increasing index pairs ``(i, j)`` with ``all(diffs[i:j] == 0)``

    and ``diffs[j] != 0 or j == len(diffs)``, thereby identifying "flat
    spots/areas" in `diffs`.

    Returns the respective generator type.

    Not anymore used to smoothen ECDFs.

    Example:

    >>> from cma.utilities.utils import zero_values_indices
    >>> for i, j in zero_values_indices([0, 0.1, 0, 0, 3.2, 0, 2.1]):
    ...     print((i, j))
    (0, 1)
    (2, 4)
    (5, 6)

    """
    i = 0
    while i < len(diffs):
        if diffs[i] == 0:
            j = i
            while j < len(diffs) and diffs[j] == 0:
                j += 1
            yield i, j
            i = j + 1
        else:
            i += 1


def MIDPOINT(df, n, price='Close'):
    """
    MidPoint over period
    Returns: list of floats = jhta.MIDPOINT(df, n, price='Close')
    Source: http://www.tadoc.org/indicator/MIDPOINT.htm
    """
    midpoint_list = []
    for i in range(len(df[price])):
        if i + 1 < n:
            midpoint = float('NaN')
        else:
            start = i + 1 - n
            end = i + 1
            midpoint = (max(df[price][start:end]) + min(df[price][start:end])
                ) / 2
        midpoint_list.append(midpoint)
    return midpoint_list


def _list(element):
    """Regular expression for a gambit list"""
    return '{(\\s+' + element + ')+\\s+}'


def suggestDType(x):
    """Return a suitable dtype for x"""
    if isinstance(x, list) or isinstance(x, tuple):
        if len(x) == 0:
            raise Exception('can not determine dtype for empty list')
        x = x[0]
    if hasattr(x, 'dtype'):
        return x.dtype
    elif isinstance(x, float):
        return float
    elif isinstance(x, int):
        return int
    else:
        return object


def disable_warnings():
    """Temporary fix to disable requests' InsecureRequestWarning"""
    import urllib3
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def update_patch_baseline(BaselineId=None, Name=None, GlobalFilters=None,
    ApprovalRules=None, ApprovedPatches=None, RejectedPatches=None,
    Description=None):
    """
    Modifies an existing patch baseline. Fields not specified in the request are left unchanged.
    See also: AWS API Documentation

    :example: response = client.update_patch_baseline(
        BaselineId='string',
        Name='string',
        GlobalFilters={
            'PatchFilters': [
                {
                    'Key': 'PRODUCT'|'CLASSIFICATION'|'MSRC_SEVERITY'|'PATCH_ID',
                    'Values': [
                        'string',
                    ]
                },
            ]
        },
        ApprovalRules={
            'PatchRules': [
                {
                    'PatchFilterGroup': {
                        'PatchFilters': [
                            {
                                'Key': 'PRODUCT'|'CLASSIFICATION'|'MSRC_SEVERITY'|'PATCH_ID',
                                'Values': [
                                    'string',
                                ]
                            },
                        ]
                    },
                    'ApproveAfterDays': 123
                },
            ]
        },
        ApprovedPatches=[
            'string',
        ],
        RejectedPatches=[
            'string',
        ],
        Description='string'
    )

    :type BaselineId: string
    :param BaselineId: [REQUIRED]
            The ID of the patch baseline to update.

    :type Name: string
    :param Name: The name of the patch baseline.

    :type GlobalFilters: dict
    :param GlobalFilters: A set of global filters used to exclude patches from the baseline.
            PatchFilters (list) -- [REQUIRED]The set of patch filters that make up the group.
            (dict) --Defines a patch filter.
            Key (string) -- [REQUIRED]The key for the filter (PRODUCT, CLASSIFICATION, MSRC_SEVERITY, PATCH_ID)
            Values (list) -- [REQUIRED]The value for the filter key.
            (string) --

    :type ApprovalRules: dict
    :param ApprovalRules: A set of rules used to include patches in the baseline.
            PatchRules (list) -- [REQUIRED]The rules that make up the rule group.
            (dict) --Defines an approval rule for a patch baseline.
            PatchFilterGroup (dict) -- [REQUIRED]The patch filter group that defines the criteria for the rule.
            PatchFilters (list) -- [REQUIRED]The set of patch filters that make up the group.
            (dict) --Defines a patch filter.
            Key (string) -- [REQUIRED]The key for the filter (PRODUCT, CLASSIFICATION, MSRC_SEVERITY, PATCH_ID)
            Values (list) -- [REQUIRED]The value for the filter key.
            (string) --

            ApproveAfterDays (integer) -- [REQUIRED]The number of days after the release date of each patch matched by the rule the patch is marked as approved in the patch baseline.

    :type ApprovedPatches: list
    :param ApprovedPatches: A list of explicitly approved patches for the baseline.
            (string) --

    :type RejectedPatches: list
    :param RejectedPatches: A list of explicitly rejected patches for the baseline.
            (string) --

    :type Description: string
    :param Description: A description of the patch baseline.

    :rtype: dict
    :return: {
        'BaselineId': 'string',
        'Name': 'string',
        'GlobalFilters': {
            'PatchFilters': [
                {
                    'Key': 'PRODUCT'|'CLASSIFICATION'|'MSRC_SEVERITY'|'PATCH_ID',
                    'Values': [
                        'string',
                    ]
                },
            ]
        },
        'ApprovalRules': {
            'PatchRules': [
                {
                    'PatchFilterGroup': {
                        'PatchFilters': [
                            {
                                'Key': 'PRODUCT'|'CLASSIFICATION'|'MSRC_SEVERITY'|'PATCH_ID',
                                'Values': [
                                    'string',
                                ]
                            },
                        ]
                    },
                    'ApproveAfterDays': 123
                },
            ]
        },
        'ApprovedPatches': [
            'string',
        ],
        'RejectedPatches': [
            'string',
        ],
        'CreatedDate': datetime(2015, 1, 1),
        'ModifiedDate': datetime(2015, 1, 1),
        'Description': 'string'
    }

    :returns:
    (string) --

    """
    pass


def relativeScope(fromScope, destScope):
    """relativeScope(fromScope, destScope) -> list

Given two globally-scoped names, return a minimal scoped name list
which identifies the destination scope, without clashing with another
identifier. For example, given IDL:

  module M {
    typedef short A;
    typedef long  B;

    module N {
      typedef string B;
      interface I {
        void op(in ::M::A x, in ::M::B y);
      };
    };
  };

relativeScope(["M", "N", "I"], ["M", "A"]) -> ["A"]
relativeScope(["M", "N", "I"], ["M", "B"]) -> ["M", "B"]

If the only valid result is a globally-scoped name, the result list is
prefixed with None:

  module O {
    typedef short C;
  };
  module P {
    module O {
      interface J {
        void op(in ::O::C z);
      };
    };
  };

relativeScope(["P", "O", "J"], ["O", "C"]) -> [None, "O", "C"]
"""
    if not fromScope:
        return destScope
    import _omniidl
    rs = _omniidl.relativeScopedName(fromScope, destScope)
    if rs is None:
        return [None] + destScope
    else:
        return rs


def boundary(costheta, a=1, epsilon=0.1, nu=0):
    """Projected boundary of a prolate spheroid

    Compute the boundary according to equation (4) in
    :cite:`Boyde2009` with the addition of the
    Poisson's ratio of the object.

    .. math::

       B(\\theta) = a (1+\\epsilon)
       \\left[ (1+\\epsilon)^2 - \\epsilon (1+\\nu)
       (2+\\epsilon (1-\\nu)) \\cos^2 \\theta \\right]^{-1/2}

    This boundary function was derived for a prolate spheroid under
    the assumption that the semi-major axis :math:`a` and the
    semi-minor axes :math:`b=c` are defined as

    .. math::

       a = b \\cdot \\frac{1+ \\epsilon}{1- \\nu \\epsilon}

    The boundary function :math:`B(\\theta)` can be derived with
    the above relation using the equation for a prolate spheroid.

    Parameters
    ----------
    costheta: float or np.ndarray
        Cosine of polar coordinates :math:`\\theta`
        at which to compute the boundary.
    a: float
        Equatorial radii of prolate spheroid (semi-minor axis).
    epsilon: float
        Stretch ratio; defines size of semi-major axis:
        :math:`a = (1+\\epsilon) b`. Note that this is not
        the eccentricity of the prolate spheroid.
    nu: float
        Poisson's ratio :math:`\\nu` of the material.

    Returns
    -------
    B: 1d ndarray
        Radial object boundary in dependence of theta
        :math:`B(\\theta)`.

    Notes
    -----
    For :math:`\\nu=0`, the above equation becomes
    equation (4) in :cite:`Boyde2009`.
    """
    x = costheta
    B = a * (1 + epsilon) / ((1 + epsilon) ** 2 - epsilon * (1 + nu) * (2 +
        epsilon * (1 - nu)) * x ** 2) ** 0.5
    return B


def get_schema():
    """Schema structure of this resource

    :return: schema dictionary
    :rtype: dict
    """
    return {'schema': {'schema_version': {'type': 'integer', 'default': 1},
        'user': {'schema_version': 1, 'title': 'Concerned user', 'type':
        'objectid', 'data_relation': {'resource': 'user', 'embeddable':
        True}, 'required': True}, 'realm': {'schema_version': 1, 'title':
        'Concerned realm', 'type': 'objectid', 'data_relation': {'resource':
        'realm', 'embeddable': True}, 'required': True}, 'sub_realm': {
        'schema_version': 1, 'title': 'Sub-realms', 'comment':
        'Is this right applicable to the sub-realms of the realm?', 'type':
        'boolean', 'default': False}, 'resource': {'schema_version': 1,
        'title': 'Concerned resource', 'comment':
        'Resource concerned with the right', 'type': 'string', 'default':
        '*', 'allowed': ['*', 'actionacknowledge', 'actiondowntime',
        'actionforcecheck', 'alignak', 'alignakdaemon', 'realm', 'command',
        'timeperiod', 'user', 'usergroup', 'userrestrictrole', 'host',
        'hostgroup', 'hostdependency', 'hostescalation', 'service',
        'servicegroup', 'servicedependency', 'serviceescalation', 'grafana',
        'graphite', 'influxdb', 'statsd', 'timeseriesretention',
        'aligank_notifications', 'livesynthesis', 'livesynthesisretention',
        'logcheckresult', 'history']}, 'crud': {'schema_version': 1,
        'title': 'Right', 'comment':
        "User's right for the concerned resource in the concerned realm. Use ``*`` if all resources are concerned."
        , 'type': 'list', 'default': ['read'], 'allowed': ['create', 'read',
        'update', 'delete', 'custom']}}, 'schema_deleted': {}}


def basic_meas_photometry(rerun, band):
    """
    Return a dict of column names for basic independent photometric measurements.
    """
    if 'pdr2' in rerun or 's18a' in rerun:
        meas_dict = {'object_id': 'meas.object_id', 'ra': 'meas.{}_ra'.
            format(band), 'dec': 'meas.{}_dec'.format(band), 'cmodel_mag':
            'meas.{}_cmodel_mag'.format(band), 'cmodel_mag_err':
            'meas.{}_cmodel_magsigma'.format(band), 'cmodel_ellipse_11':
            'meas.{}_cmodel_ellipse_11'.format(band), 'cmodel_ellipse_22':
            'meas.{}_cmodel_ellipse_22'.format(band), 'cmodel_ellipse_12':
            'meas.{}_cmodel_ellipse_12'.format(band), 'cmodel_exp_mag':
            'meas.{}_cmodel_exp_mag'.format(band), 'cmodel_exp_mag_err':
            'meas.{}_cmodel_exp_magsigma'.format(band),
            'cmodel_exp_ellipse_11': 'meas.{}_cmodel_exp_ellipse_11'.format
            (band), 'cmodel_exp_ellipse_22':
            'meas.{}_cmodel_exp_ellipse_22'.format(band),
            'cmodel_exp_ellipse_12': 'meas.{}_cmodel_exp_ellipse_12'.format
            (band), 'cmodel_dev_mag': 'meas.{}_cmodel_dev_mag'.format(band),
            'cmodel_dev_mag_err': 'meas.{}_cmodel_dev_magsigma'.format(band
            ), 'cmodel_dev_ellipse_11': 'meas.{}_cmodel_dev_ellipse_11'.
            format(band), 'cmodel_dev_ellipse_22':
            'meas.{}_cmodel_dev_ellipse_22'.format(band),
            'cmodel_dev_ellipse_12': 'meas.{}_cmodel_dev_ellipse_12'.format
            (band), 'cmodel_fracdev': 'meas.{}_cmodel_fracdev'.format(band),
            'psf_mag': 'meas2.{}_psfflux_mag'.format(band), 'psf_mag_err':
            'meas2.{}_psfflux_magsigma'.format(band)}
    elif 's17a' in rerun:
        meas_dict = {'object_id': 'meas.object_id', 'ra': 'meas.{}_ra'.
            format(band), 'dec': 'meas.{}_dec'.format(band), 'cmodel_mag':
            'meas.{}_cmodel_mag'.format(band), 'cmodel_mag_err':
            'meas.{}_cmodel_magsigma'.format(band), 'cmodel_ellipse_11':
            'meas.{}_cmodel_ellipse_11'.format(band), 'cmodel_ellipse_22':
            'meas.{}_cmodel_ellipse_22'.format(band), 'cmodel_ellipse_12':
            'meas.{}_cmodel_ellipse_12'.format(band), 'cmodel_exp_mag':
            'meas.{}_cmodel_exp_mag'.format(band), 'cmodel_exp_mag_err':
            'meas.{}_cmodel_exp_magsigma'.format(band),
            'cmodel_exp_ellipse_11': 'meas.{}_cmodel_exp_ellipse_11'.format
            (band), 'cmodel_exp_ellipse_22':
            'meas.{}_cmodel_exp_ellipse_22'.format(band),
            'cmodel_exp_ellipse_12': 'meas.{}_cmodel_exp_ellipse_12'.format
            (band), 'cmodel_dev_mag': 'meas.{}_cmodel_dev_mag'.format(band),
            'cmodel_dev_mag_err': 'meas.{}_cmodel_dev_magsigma'.format(band
            ), 'cmodel_dev_ellipse_11': 'meas.{}_cmodel_dev_ellipse_11'.
            format(band), 'cmodel_dev_ellipse_22':
            'meas.{}_cmodel_dev_ellipse_22'.format(band),
            'cmodel_dev_ellipse_12': 'meas.{}_cmodel_dev_ellipse_12'.format
            (band), 'cmodel_fracdev': 'meas.{}_cmodel_fracdev'.format(band),
            'psf_mag': 'meas.{}_psfflux_mag'.format(band), 'psf_mag_err':
            'meas.{}_psfflux_magsigma'.format(band)}
    elif 'pdr1' in rerun or 's16a' in rerun:
        meas_dict = {'object_id': 'meas.object_id', 'ra': 'meas.{}ra'.
            format(band), 'dec': 'meas.{}dec'.format(band), 'cmodel_mag':
            'meas.{}cmodel_mag'.format(band), 'cmodel_mag_err':
            'meas.{}cmodel_mag_err'.format(band), 'cmodel_ellipse_11':
            'meas.{}cmodel_ellipse_11'.format(band), 'cmodel_ellipse_22':
            'meas.{}cmodel_ellipse_22'.format(band), 'cmodel_ellipse_12':
            'meas.{}cmodel_ellipse_12'.format(band), 'cmodel_exp_mag':
            'meas.{}cmodel_exp_mag'.format(band), 'cmodel_exp_mag_err':
            'meas.{}cmodel_exp_mag_err'.format(band),
            'cmodel_exp_ellipse_11': 'meas.{}cmodel_exp_ellipse_11'.format(
            band), 'cmodel_exp_ellipse_22': 'meas.{}cmodel_exp_ellipse_22'.
            format(band), 'cmodel_exp_ellipse_12':
            'meas.{}cmodel_exp_ellipse_12'.format(band), 'cmodel_dev_mag':
            'meas.{}cmodel_dev_mag'.format(band), 'cmodel_dev_mag_err':
            'meas.{}cmodel_dev_mag_err'.format(band),
            'cmodel_dev_ellipse_11': 'meas.{}cmodel_dev_ellipse_11'.format(
            band), 'cmodel_dev_ellipse_22': 'meas.{}cmodel_dev_ellipse_22'.
            format(band), 'cmodel_dev_ellipse_12':
            'meas.{}cmodel_dev_ellipse_12'.format(band), 'cmodel_fracdev':
            'meas.{}cmodel_fracdev'.format(band), 'psf_mag':
            'meas.{}mag_psf'.format(band), 'psf_mag_err':
            'meas.{}mag_psf_err'.format(band)}
    else:
        raise NameError('Wrong rerun name')
    return meas_dict


def pmp_raw(v, *args):
    """
    Return the tuple [v-%v,v+%v]

    If called as pmp_raw(value, +pp, -pm) or pmp_raw(value, -pm, +pp),
    return (v-pm%v, v+pp%v).
    """
    if len(args) == 1:
        percent = args[0]
        b1, b2 = v * (1 - 0.01 * percent), v * (1 + 0.01 * percent)
    elif len(args) == 2:
        plus, minus = args
        if plus < minus:
            plus, minus = minus, plus
        b1, b2 = v * (1 + 0.01 * minus), v * (1 + 0.01 * plus)
    else:
        raise TypeError('pmp(value, delta) or pmp(value, -p1, +p2)')
    return (b1, b2) if v > 0 else (b2, b1)


@classmethod
def from_two_hertz(cls, apitch, bpitch):
    """Creates a JustInterval from two Hertz values.

        :param apitch: A value in Hertz
        :type apitch: int
        :param bpitch: A value in Hertz
        :type bpitch: int

        :rtype: JustInterval

        **Examples**

        >>> JustInterval.from_two_hertz(220, 440)
        JustInterval(2, 1)
        """
    if isinstance(apitch, int) and isinstance(bpitch, int):
        pass
    else:
        try:
            apitch = apitch.frequency
            bpitch = bpitch.frequency
        except AttributeError:
            msg = 'Arguments must either be integers or '
            msg += 'have a hertz attribute. '
            msg += 'Got: {} and {}'.format(type(apitch), type(bpitch))
            raise ValueError(msg)
    smaller = apitch if apitch <= bpitch else bpitch
    greater = apitch if apitch > bpitch else bpitch
    return cls(greater, smaller)


@classmethod
def download_smart_data(cls, request, ppm_id, provider):
    """
        Downloads the SMART dataset for the passed user
        :param request: The original Django request object
        :param ppm_id: The PPM ID of the requesting user
        :param provider: The SMART provider
        :return: The requested entire dataset
        """
    response = cls.get(request,
        f'/sources/api/smart/{provider}/{ppm_id}/download', raw=True)
    if response:
        return response.content
    return None


def get():
    """the cached value or VALUE_NOT_CACHED
        """


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


@staticmethod
def p_mod_common_optional_parameter_list_optional(p):
    """mod_common_optional_list_optional : empty
                                             | mod_common_optional_list"""
    p[0] = tuple() if p[1] is None else p[1]


def _collapse0(a):
    """Collapse all dimensions of `a` except the first.
    """
    return a.reshape(a.shape[0], -1)


def split_email(email):
    """Splits email in username and domain part."""
    username, domain = email.split('@')
    return username, domain


def interaction_model_generator(model_config):
    """ uses the system configuration to compute the interaction_matrix """
    interaction_index = model_config.fetch_index_of_interaction()
    alpha = model_config.create_empty_interaction_matrix()
    for kk, (ii, jj) in enumerate(interaction_index):
        interaction = list(model_config.interactions)[kk]
        for item in model_config.interactions[interaction]:
            parameters = item['parameters'].copy()
            for nn, entry in enumerate(parameters):
                if (type(entry) == str) & (entry in list(model_config.
                    compartment)):
                    parameters[nn] = model_config.compartment[entry]['value']
            alpha[ii, jj] += int(item['sign']) * globals()[item['fkt']](*
                parameters)
            alpha[jj, jj] -= int(item['sign']) * globals()[item['fkt']](*
                parameters)
    return alpha


def module_name_split(name):
    """
    Split the module name into package name and module name.
    """
    if '.' in name:
        package_name, module = name.rsplit('.', 1)
    else:
        package_name, module = '', name
    return package_name, module


@classmethod
def topic(cls, **kwargs) ->str:
    """Get MQTT topic for this message type."""
    return 'hermes/dialogueManager/endSession'


def sequence_minus(seq1, seq2):
    """Calculate difference of two sequences.

    Result contains the elements from first sequence that are not
    present in second sequence, in original order. Works even
    if sequence elements are not hashable.
    """
    result = list(seq1)
    for item in seq2:
        try:
            result.remove(item)
        except ValueError:
            pass
    return result


@staticmethod
def _assert(condition=False, exception=Exception, message=None):
    """
        Checks condition and raises exception if it is wrong.

        :param bool condition: condition to check;
        :param BaseException exception: raised exception;
        :param str message: message for `exception(message)`;
        :raises exception: if `condition` is wrong.
        """
    if message is None:
        exc = exception
    else:
        exc = exception(message)
    if not condition:
        raise exc


def is_dict_element_present(dict, key):
    """
    This function checks whether the key is present in dict.
    :param dict:
    :param key:
    :return:
    """
    for item in dict:
        if item == key:
            return True
    return False


def smooth():
    """Flatten angles of selected points

    """
    pass


def _strong_gens_from_distr(strong_gens_distr):
    """
    Retrieve strong generating set from generators of basic stabilizers.

    This is just the union of the generators of the first and second basic
    stabilizers.

    Parameters
    ==========

    ``strong_gens_distr`` - strong generators distributed by membership in basic
    stabilizers

    Examples
    ========

    >>> from sympy.combinatorics import Permutation
    >>> Permutation.print_cyclic = True
    >>> from sympy.combinatorics.named_groups import SymmetricGroup
    >>> from sympy.combinatorics.util import (_strong_gens_from_distr,
    ... _distribute_gens_by_base)
    >>> S = SymmetricGroup(3)
    >>> S.schreier_sims()
    >>> S.strong_gens
    [(0 1 2), (2)(0 1), (1 2)]
    >>> strong_gens_distr = _distribute_gens_by_base(S.base, S.strong_gens)
    >>> _strong_gens_from_distr(strong_gens_distr)
    [(0 1 2), (2)(0 1), (1 2)]

    See Also
    ========

    _distribute_gens_by_base

    """
    if len(strong_gens_distr) == 1:
        return strong_gens_distr[0][:]
    else:
        result = strong_gens_distr[0]
        for gen in strong_gens_distr[1]:
            if gen not in result:
                result.append(gen)
        return result


def yield_keyvals(block):
    """Return indexes, keys and expected values for matching recursive keys

    Given a list or dict, return a 3-tuple of the 'split' key (key split on
    dots), the original key, and the expected value. If the input is a list, it
    is enumerated so the 'keys' are just [0, 1, 2, ...]

    Example:

        Matching a dictionary with a couple of keys:

        >>> gen = yield_keyvals({"a": {"b": "c"}})
        >>> next(gen)
        (['a'], 'a', {'b': 'c'})

        Matching nested key access:

        >>> gen = yield_keyvals({"a.b.c": "d"})
        >>> next(gen)
        (['a', 'b', 'c'], 'a.b.c', 'd')

        Matching a list of items:

        >>> gen = yield_keyvals(["a", "b", "c"])
        >>> next(gen)
        (['0'], '0', 'a')
        >>> next(gen)
        (['1'], '1', 'b')
        >>> next(gen)
        (['2'], '2', 'c')

    Args:
        block (dict, list): input matches

    Yields:
        (list, str, str): key split on dots, key, expected value
    """
    if isinstance(block, dict):
        for joined_key, expected_val in block.items():
            split_key = joined_key.split('.')
            yield split_key, joined_key, expected_val
    else:
        for idx, val in enumerate(block):
            sidx = str(idx)
            yield [sidx], sidx, val


def get_ttrajs(sctrajs, tica):
    """
    Reduce the dimensionality of a dictionary of scaled or featurized trajectories
    :param traj_dict: The dictionary of featurized/scaled trajectories, represented as np.arrays of shape (n_frames, n_features)
    :param tica: A tICA object which must have been fit first
    :return ttrajs: A dict of tica-transformed trajectories, represented as np.arrays of shape (n_frames, n_components)
    """
    ttrajs = {}
    for k, v in sctrajs.items():
        ttrajs[k] = tica.partial_transform(v)
    return ttrajs


@classmethod
def _discover_params(cls):
    """
        Returns a dict where filter keyword is key, and class is value.
        To handle param alias (maxRecords or max_records), both versions are
        added.
        """
    try:
        return cls.filters
    except AttributeError:
        filters = {}
        for param_class_name in dir(cls):
            param_class = getattr(cls, param_class_name)
            if hasattr(param_class, 'kwarg'):
                filters[param_class.kwarg] = param_class
                filters[param_class.param_name] = param_class
        cls.filters = filters
    return cls.filters


def get_preferred_sparse_format():
    """Get the preferred sparse matrix format supported by the backend.

    Different backends have their preferred backend. This info is useful when
    constructing a sparse matrix.
    """
    return 'coo'


def _convert_xray_trace_id(xray_trace_id):
    """
    Convert X-Ray trace id (hex)'s last 63 bits to a Datadog trace id (int).
    """
    return str(9223372036854775807 & int(xray_trace_id[-16:], 16))


def opt_arg(spec, property, default_value=None):
    """Get an optional property, possibly with a default value.
    @param spec: the JSON-like filter spec (a dict)(
    @param property: the property name to retrieve
    @param default_value: the default value to return if not found
    @returns: the value if found, otherwise default_value/None
    """
    value = spec.get(property)
    if value is None:
        return default_value
    else:
        return value


def trailingslashit(string=''):
    """
    Removes trailing forward slashes and backslashes if they exist.
    """
    return '{}/'.format(string.strip('/\\'))


def arccosh(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns the element-wise inverse hyperbolic cosine of the input array, \\
    computed element-wise.

    The storage type of ``arccosh`` output is always dense

    Defined in src/operator/tensor/elemwise_unary_op_trig.cc:L474

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

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

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


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


def parity(num: int) ->int:
    """Return the parity of a non-negative integer.

    For example, here are the parities of the first ten integers:

    >>> [parity(n) for n in range(10)]
    [0, 1, 1, 0, 1, 0, 0, 1, 1, 0]

    This function is undefined for negative integers:

    >>> parity(-1)
    Traceback (most recent call last):
        ...
    ValueError: expected num >= 0
    """
    if num < 0:
        raise ValueError('expected num >= 0')
    par = 0
    while num:
        par ^= num & 1
        num >>= 1
    return par


@staticmethod
def _format_process_obj(obj_list, formatted_obj):
    """
        Function for formatting process object from API result
        :param obj_list: list, object attribute value list
        :param formatted_obj: dict
        :return: dict
        """
    attr_with_na_value_index_dict = {'sha256hash': (4, ('n/a',)),
        'sha1hash': (6, ('n/a',)), 'md5hash': (8, ('n/a',)), 'file_path': (
        9, ('n/a',)), 'process_ppid': (10, ('n/a',)), 'process_user': (11,
        ('n/a',)), 'timestamp': (13, ('0',)), 'process_name': (1, ('n/a',)),
        'process_id': (2, ('n/a', '0')), 'file_size': (12, ('0',))}
    for key, value in attr_with_na_value_index_dict.items():
        if obj_list[value[0]].strip() not in value[1]:
            formatted_obj[key] = obj_list[value[0]].strip()
    formatted_obj['type'] = obj_list[0].strip()
    formatted_obj['event_count'] = '1'
    return formatted_obj


def add_greeting(nc, line):
    """Add one-liner script or several lines (newline separated)"""
    assert type(nc) == dict
    nc['greeting'] = nc.get('greeting') or ''
    if not nc['greeting'].endswith('\n'):
        nc['greeting'] += '\n'
    nc['greeting'] += line + '\n'


@staticmethod
def checkBoundaries(points):
    """
        checkBoundaries removes point 0,0 and 0, 360 if present.

        :param points:
        :return: points
        """
    if points[0] == (0, 0):
        del points[0]
    if points[len(points) - 1] == (0, 360):
        del points[-1]
    return points


def parse_host_port(address, default_port=None):
    """Interpret a string as a host:port pair.

    An IPv6 address MUST be escaped if accompanied by a port,
    because otherwise ambiguity ensues: 2001:db8:85a3::8a2e:370:7334
    means both [2001:db8:85a3::8a2e:370:7334] and
    [2001:db8:85a3::8a2e:370]:7334.

    >>> parse_host_port('server01:80')
    ('server01', 80)
    >>> parse_host_port('server01')
    ('server01', None)
    >>> parse_host_port('server01', default_port=1234)
    ('server01', 1234)
    >>> parse_host_port('[::1]:80')
    ('::1', 80)
    >>> parse_host_port('[::1]')
    ('::1', None)
    >>> parse_host_port('[::1]', default_port=1234)
    ('::1', 1234)
    >>> parse_host_port('2001:db8:85a3::8a2e:370:7334', default_port=1234)
    ('2001:db8:85a3::8a2e:370:7334', 1234)
    >>> parse_host_port(None)
    (None, None)
    """
    if not address:
        return None, None
    if address[0] == '[':
        _host, _port = address[1:].split(']')
        host = _host
        if ':' in _port:
            port = _port.split(':')[1]
        else:
            port = default_port
    elif address.count(':') == 1:
        host, port = address.split(':')
    else:
        host = address
        port = default_port
    return host, None if port is None else int(port)


@classmethod
def deserialize(cls, dict_model):
    """Returns an unsaved class object based on the valid properties passed in."""
    kwargs = {}
    for f in cls._meta.concrete_fields:
        if f.attname in dict_model:
            kwargs[f.attname] = dict_model[f.attname]
    return cls(**kwargs)


def yield_three(iterable):
    """
    From some iterable, return three items, bundling all extras into last one.
    """
    return iterable[0], iterable[1], iterable[2:]


def symlink_if_necessary(path, destination):
    """forcefully create a symlink with a given value, but only if it doesn't already exist"""
    from py._error import error as pylib_error
    try:
        supervise_link = destination.readlink()
    except (pylib_error.ENOENT, pylib_error.EINVAL):
        supervise_link = None
    if supervise_link != path.strpath:
        from .subprocess import check_call
        check_call(('ln', '-sfn', '--', path.strpath, destination.strpath))


def generate_ssh_key_parser(subparsers, name, default_key_size=2048,
    default_key_type='rsa'):
    """
    Create an argparse sub-command with `name` attached to `subparsers`.
    """
    generate_ssh_key = subparsers.add_parser(name, help=
        'Create a SSH public and private key pair.')
    generate_ssh_key.add_argument('--key-file', metavar='FILE', help=
        'Store the keys pair in FILE and FILE.pub. Default id_TYPE.')
    generate_ssh_key.add_argument('--key-size', type=int, metavar='SIZE',
        default=default_key_size, help=
        'Generate a RSA or DSA key of size SIZE. Default %(default)s')
    generate_ssh_key.add_argument('--key-type', metavar='[rsa|dsa]',
        default=default_key_type, help=
        'Generate a DSA or RSA key. Default %(default)s.')
    generate_ssh_key.add_argument('--key-comment', metavar='COMMENT_TEXT',
        help='Generate the public key using this comment. Default no comment.')
    generate_ssh_key.add_argument('--key-skip', action='store_true',
        default=False, help=
        'Do not create a new key if a key file already exists.')
    return generate_ssh_key


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 var_no_scaling(model, *args, **kwargs):
    """Dummy function to bypass scaling.

    Parameters
    ----------
    model : :any:`CovModel`
        Covariance Model used for the field.

    Returns
    -------
    var : :class:`float`
        The model variance.
    """
    return model.sill


@classmethod
def add_options(cls, options):
    """Add options to the OptionsManager."""
    cls.option_manager = options
    options.add_option('--outputdir', help=
        'Directory to save the HTML output.', parse_from_config=True,
        default='./flake8_dashboard')
    options.add_option('--debug', help=
        'Write additional debugging information as csv format.',
        parse_from_config=True, default=False, action='store_true')
    options.add_option('--title', help=
        "Set the dashboard's title. No title by default.",
        parse_from_config=True, default=None)


def delete_uncompleted_calculations(db, user):
    """
    Delete the uncompleted calculations of the given user.

    :param db: a :class:`openquake.server.dbapi.Db` instance
    :param user: user name
    """
    db("UPDATE job SET status = 'deleted' WHERE user_name=?x AND status != 'complete'"
        , user)


def _head_timedelta(current, next_, after):
    """Return rows of ``next_`` whose index is before the last
    observation in ``current`` + ``after``.

    Parameters
    ----------
    current : DataFrame
    next_ : DataFrame
    after : timedelta

    Returns
    -------
    overlapped : DataFrame
    """
    return next_[next_.index < current.index.max() + after]


def _is_method(function, args):
    """
    Return ``True`` if `function` to be decorated is a method.

    Decorator is required to have set an `original` attribute on the wrapped
    method pointing to the original unwrapped function.
    """
    try:
        method = getattr(args[0], function.__name__)
        return method.original is function
    except (IndexError, AttributeError):
        return False


@classmethod
def from_list(cls, constructor_list):
    """
        Construct an envelope from a list that can take a number of formats
        :param constructor_list: either a flat list that just contains levels, or a list of lists either of the form
         [levels_list, total_duration], [levels_list, durations_list] or [levels_list, durations_list, curve_shape_list]
         for example:
         - an input of [1, 0.5, 0.3] is interpreted as evenly spaced levels with a total duration of 1
         - an input of [[1, 0.5, 0.3], 3.0] is interpreted as levels and durations with a total duration of e.g. 3.0
         - an input of [[1, 0.5, 0.3], [0.2, 0.8]] is interpreted as levels and durations
         - an input of [[1, 0.5, 0.3], [0.2, 0.8], [2, 0.5]] is interpreted as levels, durations, and curvatures
        :return: an Envelope constructed accordingly
        """
    assert hasattr(constructor_list, '__len__')
    if hasattr(constructor_list[0], '__len__'):
        if len(constructor_list) == 2:
            if hasattr(constructor_list[1], '__len__'):
                return cls.from_levels_and_durations(constructor_list[0],
                    constructor_list[1])
            else:
                return cls.from_levels(constructor_list[0], length=
                    constructor_list[1])
        elif len(constructor_list) >= 3:
            return cls.from_levels_and_durations(constructor_list[0],
                constructor_list[1], constructor_list[2])
    else:
        return cls.from_levels(constructor_list)


def _ipVersionToLen(version):
    """Return number of bits in address for a certain IP version.

    >>> _ipVersionToLen(4)
    32
    >>> _ipVersionToLen(6)
    128
    >>> _ipVersionToLen(5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "IPy.py", line 1076, in _ipVersionToLen
        raise ValueError("only IPv4 and IPv6 supported")
    ValueError: only IPv4 and IPv6 supported
    """
    if version == 4:
        return 32
    elif version == 6:
        return 128
    else:
        raise ValueError('only IPv4 and IPv6 supported')


def show_results(results, n=10, print_results=True):
    """Show the top-n results of a classification."""
    s = ''
    if len(results) == 0:
        s += '-- No results --'
    else:
        s += '{0:18s} {1:7s}\n'.format('Class', 'Prob')
        s += '#' * 50 + '\n'
        for entry in results:
            if n == 0:
                break
            else:
                n -= 1
            s += '{0:18s} {1:>7.4f}%\n'.format(entry['semantics'], entry[
                'probability'] * 100)
        s += '#' * 50
    if print_results:
        print(s)
    return s


def is_weekday(date):
    """Checks if the date provided as an arguement is a weekday or not"""
    return True if date.weekday() in range(0, 5) else False


@staticmethod
def model_path_validation(val):
    """
    Custom validation method for the 'model' key

    :return: If the 'model' key is valid
    :rtype: bool
    """
    return bool(val) and not val.startswith('/')


def make_editions_dict(editions):
    """Take a reporter editions dict and flatten it, returning a dict for
    use in the DictWriter.
    """
    d = {}
    nums = ['1', '2', '3', '4', '5', '6']
    num_counter = 0
    for k, date_dict in editions.items():
        d['edition%s' % nums[num_counter]] = k
        if date_dict['start'] is not None:
            d['start_e%s' % nums[num_counter]] = date_dict['start'].isoformat()
        if date_dict['end'] is not None:
            d['end_e%s' % nums[num_counter]] = date_dict['end'].isoformat()
        num_counter += 1
    return d


def __cve_details(data, db):
    """
    Get a CVE details.
    """
    _cve = data.parameter
    _query = 'SELECT cve_description FROM CVE WHERE cve LIKE ?;'
    res = []
    res_append = res.append
    res_append("[*] Detail for CVE '%s':" % _cve)
    r = db.raw(query=_query, parameters=(_cve,)).fetchone()
    if r is not None:
        res_append('\n    %s' % r[0])
    res_append('\n')
    return '\n'.join(res)


def psi_Na_Cl_HPO4_HFM89(T, P):
    """c-a-a': sodium chloride hydrogen-phosphate [HFM89]."""
    psi = -0.003
    valid = T == 298.15
    return psi, valid


def clear_graph(node_label=None):
    """Generate query for removing everything from the graph.

    Parameters
    ----------
    label
        Label of the graph to remove. If None, all the database is cleared
    """
    if node_label is None:
        query = 'MATCH (n)\n'
    else:
        query = 'MATCH (n:{})\n'.format(node_label)
    query += 'OPTIONAL MATCH (n)-[r]-()\n' + 'DELETE n, r\n'
    return query


def parsing_rb_single(response, tips=False):
    """
    功能：解析回读单个舵机角度命令执行后机器人的回应信息。
    输入：空
    返回：
    angle：回读单个舵机角度的命令。
    """
    if response == b'':
        print('回应内容为空，请重新获取回应！')
        return
    cmd_len = response[2]
    cmd_type = response[3]
    if cmd_type != 36:
        print('解析类型错误，请检查回应内容，当前命令类型为%d' % cmd_type)
        return 0
    joint_id = response[4]
    angle = response[5]
    if tips:
        print('回读到%d号舵机的角度值为：%d' % (joint_id, angle))
    return angle


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

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


def calc_list_average(l):
    """
    Calculates the average value of a list of numbers
    Returns a float
    """
    total = 0.0
    for value in l:
        total += value
    return total / len(l)


def assert_awaited(_mock_self):
    """
        Assert that the mock was awaited at least once.

        .. versionadded:: 0.12
        """
    self = _mock_self
    if self.await_count == 0:
        msg = "Expected '%s' to have been awaited." % self._mock_name or 'mock'
        raise AssertionError(msg)


@classmethod
def is_intersecting(cls, first, second):
    """
        :param first: first exon to check
        :type first: tuple([int, int])

        :param second: second exon to check
        :type second: tuple([int, int])

        :rtype bool

        Implementation of the is_intersecting method.
        It checks overlaps between exons.
        """
    if first == second or cls.overlap(first, second) < 0:
        return False
    return True


@classmethod
def wipe_cache(p_class):
    """ Wipes the cache """
    p_class.cache = {}


def reverse_bits(i, n):
    """Reverse the bits of the ``n``-bit decimal number ``i``.

    Examples:
        >>> reverse_bits(12, 7)
        24
        >>> reverse_bits(0, 1)
        0
        >>> reverse_bits(1, 2)
        2
    """
    return int(bin(i)[2:].zfill(n)[::-1], 2)


def _ansi_color(command):
    """
    Return the ansi sequence for the provided color
    """
    return '\x1b[%sm' % command


@staticmethod
def _VisualizationDriver_write_data(cubefile, grid, molecule, flag, index, spin
    ):
    """
    Writes cubic grid data to cube file.

    :param cubefile:
        Name of the cube file.
    :param grid:
        The cubic grid.
    :param molecule:
        The molecule.
    :param flag:
        The flag for molecular orbitals ('mo') or density ('density').
    :param index:
        Index (0-based) of the molecular orbital or density matrix.
    :param spin:
        Spin of the molecular orbital or density.
    """
    f_cube = open(cubefile, 'w')
    x = molecule.x_to_numpy()
    y = molecule.y_to_numpy()
    z = molecule.z_to_numpy()
    natoms = molecule.number_of_atoms()
    elem_ids = molecule.elem_ids_to_numpy()
    x0, y0, z0 = grid.x_origin(), grid.y_origin(), grid.z_origin()
    dx, dy, dz = grid.x_step_size(), grid.y_step_size(), grid.z_step_size()
    nx, ny, nz = grid.x_num_points(), grid.y_num_points(), grid.z_num_points()
    print('VeloxChem Cube File', file=f_cube)
    if flag == 'mo':
        print('MO {:d} ({:s})'.format(index + 1, spin), file=f_cube)
        print('{:5d}{:12.6f}{:12.6f}{:12.6f}{:5d}'.format(-natoms, x0, y0,
            z0, 1), file=f_cube)
    elif flag == 'density':
        print('Electron density ({:s})'.format(spin), file=f_cube)
        print('{:5d}{:12.6f}{:12.6f}{:12.6f}{:5d}'.format(natoms, x0, y0,
            z0, 1), file=f_cube)
    print('{:5d}{:12.6f}{:12.6f}{:12.6f}'.format(nx, dx, 0, 0), file=f_cube)
    print('{:5d}{:12.6f}{:12.6f}{:12.6f}'.format(ny, 0, dy, 0), file=f_cube)
    print('{:5d}{:12.6f}{:12.6f}{:12.6f}'.format(nz, 0, 0, dz), file=f_cube)
    for a in range(natoms):
        print('{:5d}{:12.6f}{:12.6f}{:12.6f}{:12.6f}'.format(elem_ids[a],
            float(elem_ids[a]), x[a], y[a], z[a]), file=f_cube)
    if flag == 'mo':
        print('{:5d}{:5d}'.format(1, index + 1), file=f_cube)
    data = grid.values_to_numpy()
    for ix in range(nx):
        for iy in range(ny):
            for iz in range(nz):
                print(' {:12.5E}'.format(data[ix, iy, iz]), end='', file=f_cube
                    )
                if iz % 6 == 5:
                    print('', file=f_cube)
            print('', file=f_cube)
    f_cube.close()


def dbh_directory(path, contenttype, extension, roottag, nsurl):
    """ Generic Directory Handler - Returns directory_generic for all inode/directory """
    if contenttype.startswith('inode/directory') or contenttype.startswith(
        'application/x-directory') or contenttype.startswith('directory'):
        return 'db_directory'
    else:
        return False


def create_color_name(c):
    """
    Checks if the color name is a proper color name. If not it will convert the name to a proper style.
    :param c: The input color name
    :type c: str
    :return: The input color name in a proper style
    :rtype: str
    """
    if 'mag' not in c:
        c = c.split('-')
        c = '{}mag - {}mag'.format(c[0].replace(' ', ''), c[1].replace(' ', '')
            )
    return c


def _get_win_folder_from_registry(csidl_name):
    """This is a fallback technique at best. I'm not sure if using the
    registry for this guarantees us the correct answer for all CSIDL_*
    names.
    """
    import winreg
    shell_folder_name = {'CSIDL_APPDATA': 'AppData', 'CSIDL_COMMON_APPDATA':
        'Common AppData', 'CSIDL_LOCAL_APPDATA': 'Local AppData'}[csidl_name]
    key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
        'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'
        )
    dir, type = winreg.QueryValueEx(key, shell_folder_name)
    return dir


def failed_dispatch(loader, queue, error):
    """
    Do not cache individual loads if the entire batch dispatch fails,
    but still reject each request so they do not hang.
    """
    for l in queue:
        loader.clear(l.key)
        l.future.set_exception(error)


def split(alist, split):
    """ split a list into 'split' items """
    newlist = []
    accum = []
    for i, element in enumerate(alist):
        accum.append(element)
        if len(accum) == split or i == len(alist) - 1:
            newlist.append(accum)
            accum = []
    return newlist


@classmethod
def find_one(cls, *args, **kwargs):
    """Same as ``collection.find_one``, return model object instead of simple dict."""
    d = cls.collection.find_one(*args, **kwargs)
    if d:
        return cls(**d)


def get_a_cluster(base, cluster_id, expected_status=None, wait_timeout=None):
    """Utility function that gets a Senlin cluster."""
    if expected_status is None:
        res = base.client.get_obj('clusters', cluster_id)
    else:
        base.client.wait_for_status('clusters', cluster_id, expected_status,
            wait_timeout)
        res = base.client.get_obj('clusters', cluster_id)
    return res['body']


def _int_or_none(string: str) ->(int or None):
    """Returns None iff coordinate is special "~"
    character or else the respective integer value.
    """
    if string == '~':
        return None
    return int(string)


def reduce_max(input):
    """Returns the max of all elements in the input tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.

    Returns
    -------
    Tensor
        A framework-specific tensor with shape (1,)
    """
    pass


def _tester(func, *args):
    """
    Tests function ``func`` on arguments and returns first positive.

    >>> _tester(lambda x: x%3 == 0, 1, 2, 3, 4, 5, 6)
    3
    >>> _tester(lambda x: x%3 == 0, 1, 2)
    None

    :param func: function(arg)->boolean
    :param args: other arguments
    :return: something or none
    """
    for arg in args:
        if arg is not None and func(arg):
            return arg
    return None


def get_paginator(operation_name=None):
    """
    Create a paginator for an operation.

    :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').

    :rtype: L{botocore.paginate.Paginator}
    """
    pass


@staticmethod
def unassign_student(student):
    """Unassigns a student to a school."""
    student.assigned = False
    student.assigned_school = None


def savedictionariestoConfigurationIniFile(simulationParamsDict,
    sceneParamsDict, timeControlParamsDict=None, moduleParamsDict=None,
    trackingParamsDict=None, torquetubeParamsDict=None, analysisParamsDict=
    None, cellLevelModuleParamsDict=None, inifilename=None):
    """
    Saves dictionaries from working memory into a Configuration File
    with extension format .ini.

    Parameters
    ----------
    simulationParamsDict
    sceneParamsDict
    timeControlParamsDict
        Default None
    moduleParamsDict
        Default None
    trackingParamsDict
        Default None
    torquetubeParamsDict
        Default None
    analysisParamsDict
        Default None,
    cellLevelModuleParamsDict
        Default None

    Returns
    -------
    Writes output into inifilename passed (default if inifilename=None is
    'example.ini')
    """
    import configparser
    config = configparser.ConfigParser(allow_no_value=True)
    config.optionxform = str
    config['simulationParamsDict'] = simulationParamsDict
    config['sceneParamsDict'] = sceneParamsDict
    try:
        config['timeControlParamsDict'] = timeControlParamsDict
    except:
        pass
    try:
        config['timeControlParamsDict'] = timeControlParamsDict
    except:
        pass
    try:
        config['timeControlParamsDict'] = timeControlParamsDict
    except:
        pass
    try:
        config['moduleParamsDict'] = moduleParamsDict
    except:
        pass
    try:
        config['trackingParamsDict'] = trackingParamsDict
    except:
        pass
    try:
        config['torquetubeParamsDict'] = torquetubeParamsDict
    except:
        pass
    try:
        config['analysisParamsDict'] = analysisParamsDict
    except:
        pass
    try:
        config['cellLevelModuleParamsDict'] = cellLevelModuleParamsDict
    except:
        pass
    if inifilename is None:
        inifilename = 'example.ini'
    with open(inifilename, 'w') as configfile:
        config.write(configfile)


def turned_off_response(message):
    """Return a device turned off response."""
    return {'requestId': message.get('requestId'), 'payload': {'errorCode':
        'deviceTurnedOff'}}


def subjects():
    """Get the subjects.
        """


def dbh_checklist_1_chx(path, contenttype, extension, roottag, nsurl):
    """ Generic Checklist Handler - Returns checlist for Checklist Files """
    if (extension.lower() == 'chx' or extension.lower() == 'chf' or
        extension.lower() == 'plx' or extension.lower() == 'plf'
        ) and nsurl.startswith('http://thermal.cnde.iastate.edu'):
        return 'db_checklist_editor'
    else:
        return False


def new_workbookrels_text(db):
    """
    Returns /xl/_rels/workbook.xml.rels text

    :param pylightxl.Database db: database contains sheetnames, and their data
    :return str: /xl/_rels/workbook.xml.rels text
    """
    xml_base = (
        '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\r\n{many_tag_sheets}\r\n{tag_sharedStrings}\r\n</Relationships>'
        )
    xml_tag_sheet = (
        '<Relationship Target="worksheets/sheet{sheet_num}.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Id="rId{sheet_num}"/>\r\n'
        )
    xml_tag_sharedStrings = (
        '<Relationship Target="sharedStrings.xml" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Id="rId{ID}"/>\r\n'
        )
    many_tag_sheets = ''
    for wsID, _ in enumerate(db.ws_names, 1):
        many_tag_sheets += xml_tag_sheet.format(sheet_num=wsID)
    if db._sharedStrings:
        tag_sharedStrings = xml_tag_sharedStrings.format(ID=len(db.ws_names
            ) + 1)
    else:
        tag_sharedStrings = ''
    rv = xml_base.format(many_tag_sheets=many_tag_sheets, tag_sharedStrings
        =tag_sharedStrings)
    return rv


def method_signature(method_name):
    """
        method_signature returns a description of the argument format for
        the given method_name.
        """


def sign(x):
    """Sign indication of a number"""
    return 1 if x > 0 else -1 if x < 0 else 0


def _mp_map_wrapper(args):
    """Map wrapper function for :mod:`multiprocessing`.

    Args:
        args (Tuple[Callable, Iterable[Any], Mapping[str, Any]]): the function to execute,
            the positional arguments and the keyword arguments packed into a tuple

    Returns:
        Any: the function execution result

    """
    func, posargs, kwargs = args
    return func(*posargs, **kwargs)


def draw_root_frets(draw, instrument, text_top_area, text_bottom_area,
    image_height, palette):
    """Add the frets to the root finder image"""
    for fret_num in list(range(1, instrument.number_of_frets)):
        fret_pos_x = fret_num * (instrument.fret_spacing / 4) + (instrument
            .top_gap / 2 + instrument.nut_width / 2)
        draw.line((fret_pos_x, text_top_area, fret_pos_x, image_height -
            text_bottom_area), palette.fret_colour, width=1)
    return draw


def pushingmarkerfor(obsstore, ispushed, node):
    """true if some markers are to be pushed for node

    We cannot just look in to the pushed obsmarkers from the pushop because
    discovery might have filtered relevant markers. In addition listing all
    markers relevant to all changesets in the pushed set would be too expensive
    (O(len(repo)))

    (note: There are cache opportunity in this function. but it would requires
    a two dimensional stack.)
    """
    successorsmarkers = obsstore.successors
    stack = [node]
    seen = set(stack)
    while stack:
        current = stack.pop()
        if ispushed(current):
            return True
        markers = successorsmarkers.get(current, ())
        for m in markers:
            nexts = m[1]
            if not nexts:
                nexts = m[5] or ()
            for n in nexts:
                if n not in seen:
                    seen.add(n)
                    stack.append(n)
    return False


def healthcheck():
    """
    Request handler for performing an application-level health check. This is
    not part of the published API, it is intended for use by OpenShift or other
    monitoring tools.

    Returns a 200 response if the application is alive and able to serve requests.
    """
    return 'Health check OK', 200, [('Content-Type', 'text/plain')]


@staticmethod
def core_packages():
    """
        Return a list of 'core packages'

        These packages constitute required the application framework. They
        cannot be removes via the 'Add-on/plugins' manager. They however can
        be updated. The package that defines the application's `main()` entry
        point must always be in this list.
        """
    return ['arithmos-widget-base']


def L1_norm(seq):
    """calculates the L1 norm of a sequence or vector

	:param seq: the sequence or vector
	:returns: the L1 norm"""
    norm = 0
    for i in range(len(seq)):
        norm += abs(seq[i])
    return norm


def KK_RC18(w, Rs, R_values, t_values):
    """
    Kramers-Kronig Function: -RC-

    Kristian B. Knudsen (kknu@berkeley.edu / kristianbknudsen@gmail.com)
    """
    return Rs + R_values[0] / (1 + w * 1.0j * t_values[0]) + R_values[1] / (
        1 + w * 1.0j * t_values[1]) + R_values[2] / (1 + w * 1.0j * t_values[2]
        ) + R_values[3] / (1 + w * 1.0j * t_values[3]) + R_values[4] / (1 +
        w * 1.0j * t_values[4]) + R_values[5] / (1 + w * 1.0j * t_values[5]
        ) + R_values[6] / (1 + w * 1.0j * t_values[6]) + R_values[7] / (1 +
        w * 1.0j * t_values[7]) + R_values[8] / (1 + w * 1.0j * t_values[8]
        ) + R_values[9] / (1 + w * 1.0j * t_values[9]) + R_values[10] / (1 +
        w * 1.0j * t_values[10]) + R_values[11] / (1 + w * 1.0j * t_values[11]
        ) + R_values[12] / (1 + w * 1.0j * t_values[12]) + R_values[13] / (
        1 + w * 1.0j * t_values[13]) + R_values[14] / (1 + w * 1.0j *
        t_values[14]) + R_values[15] / (1 + w * 1.0j * t_values[15]
        ) + R_values[16] / (1 + w * 1.0j * t_values[16]) + R_values[17] / (
        1 + w * 1.0j * t_values[17])


def fit_cca(data_0, data_1, n_cca_dims=10):
    """
    Initialize and fit CCA sklearn object

    :param data_0: shape (n_samples, n_features_0)
    :type data_0: array-like
    :param data_1: shape (n_samples, n_features_1)
    :type data_1: array-like
    :param n_cca_dims: number of CCA dimensions to fit
    :type n_cca_dims: int
    :return: sklearn cca object
    """
    from sklearn.cross_decomposition import CCA
    cca = CCA(n_components=n_cca_dims, max_iter=1000)
    cca.fit(data_0, data_1)
    return cca


def plugins():
    """Return enabled plugins."""


def column_rename(universe_dict):
    """Appends the name of the instrument to the columns.
    To help keep track of the instruments in the full dataset.

    :param universe_dict:               The dictionary of time series
    :type  universe_dict:               dict

    :return:                            The dictionary of time series
    :rtype:                             dict
    """
    for df_name in universe_dict:
        for col in universe_dict[df_name].columns:
            universe_dict[df_name].rename(columns={col: col + '_' + df_name
                }, inplace=True)
    return universe_dict


def parse_options(parser, args):
    """
    Parse command line options and print usage message if no arguments were
    provided for the command.
    """
    options, args = parser.parse_args(args)
    if not args:
        parser.print_usage()
        raise SystemExit(1)
    if args[0] not in ('start', 'stop', 'status'):
        parser.print_usage()
        raise SystemExit(1)
    return options, args


def prepare_response(response, spec, default_response_content_type):
    """Rework response according to OAS version"""
    if spec.openapi_version.major < 3:
        if 'example' in response:
            response['examples'] = {default_response_content_type: response
                .pop('example')}
    else:
        for field in ('schema', 'example', 'examples'):
            if field in response:
                response.setdefault('content', {}).setdefault(
                    default_response_content_type, {})[field] = response.pop(
                    field)