def vote_display(vote, arg=None):
    """
    Given a string mapping values for up and down votes, returns one
    of the strings according to the given ``Vote``:

    =========  =====================  =============
    Vote type   Argument               Outputs
    =========  =====================  =============
    ``+1``     ``"Bodacious,Bogus"``  ``Bodacious``
    ``-1``     ``"Bodacious,Bogus"``  ``Bogus``
    =========  =====================  =============

    If no string mapping is given, "Up" and "Down" will be used.

    Example usage::

        {{ vote|vote_display:"Bodacious,Bogus" }}
    """
    if arg is None:
        arg = 'Up,Down'
    bits = arg.split(',')
    if len(bits) != 2:
        return vote.vote
    up, down = bits
    if vote.vote == 1:
        return up
    return down


def get_similarity(d, val1, val2, mismatch_penalty=1):
    """
    Get similarity for partial matching.
    """
    dis = d.get(tuple((val2, val1)), -mismatch_penalty)
    return dis


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

        :param SharedContentChangeInviteeRoleDetails val:
        :rtype: EventDetails
        """
    return cls('shared_content_change_invitee_role_details', val)


def is_conductance(target_cell):
    """
    Returns True if the target cell uses conductance-based synapses, False if
    it uses current-based synapses, and None if the synapse-basis cannot be
    determined.
    """
    if hasattr(target_cell, 'local') and target_cell.local and hasattr(
        target_cell, 'celltype'):
        is_conductance = target_cell.celltype.conductance_based
    else:
        is_conductance = None
    return is_conductance


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


@staticmethod
def _to_triplet(mat, ids=None):
    """Covert a 2d array into sparse triplet format.

        Parameters
        ----------
        mat: 2d array, required
            A Numpy 2d array of integers.
        ids: list, optional, default: None
            A list of ids (or labels) of the objects to be used in the output triplet matrix.

        Returns
        -------
        A set corresponding to the sparse triplet representation of mat.
        """
    tuples = set()
    n = mat.shape[0]
    k = mat.shape[1]
    if ids is None:
        ids = range(n)
    for n_ in range(n):
        for k_ in range(k):
            j = int(mat[n_, k_])
            tuples.add((ids[n_], ids[j], 1.0))
    return tuples


def resolve_name(name):
    """Resolve a name like ``module.object`` to an object and return it.

    Raise `ImportError` if the module or name is not found.
    """
    parts = name.split('.')
    cursor = len(parts) - 1
    module_name = parts[:cursor]
    attr_name = parts[-1]
    while cursor > 0:
        try:
            ret = __import__('.'.join(module_name), fromlist=[attr_name])
            break
        except ImportError:
            if cursor == 0:
                raise
            cursor -= 1
            module_name = parts[:cursor]
            attr_name = parts[cursor]
            ret = ''
    for part in parts[cursor:]:
        try:
            ret = getattr(ret, part)
        except AttributeError:
            raise ImportError(name)
    return ret


def handle_ctcpversion(irc, source, ctcp, data):
    """
    Handles CTCP version requests.
    """
    return irc.version()


def is_interrupted(th):
    """指定したスレッドでinterrupt が呼び出されたか診断する"""
    return True if hasattr(th, 'interrupted') and th.interrupted else False


@staticmethod
def _is_same_migration(migration1, migration2):
    """Check if two migrations match, migration attributes that do not have effect on migration are ignored."""
    if migration1.keys() != migration2.keys():
        return False
    for flow_name in migration1.keys():
        if migration1[flow_name]['tainting_nodes'] != migration2[flow_name][
            'tainting_nodes']:
            return False
        if set(migration1[flow_name]['tainted_edges'].keys()) != set(migration2
            [flow_name]['tainted_edges'].keys()):
            return False
        if migration1[flow_name]['translation'] != migration2[flow_name][
            'translation']:
            return False
    return True


@classmethod
def delete_exception_handler(cls, handler):
    """Removes a L{ExceptionHandler} from the HTTP client
        @warning: SHOULD ONLY BE CALLED FROM A PROVIDER THROUGH A TEST
                  FIXTURE
        """
    if handler in cls._exception_handlers:
        cls._exception_handlers.remove(handler)


@staticmethod
def _get_min_time(dt):
    """
        Makes clock to 00:00:00
        :param dt: datetime
        :return: datetime
        """
    return dt.replace(hour=0, minute=0, second=0)


def convertLUtoUN(s):
    """Capitalize a string."""
    r = ''
    i = 0
    while i < len(s):
        if i == 0:
            r += s[i].upper()
            i += 1
        elif s[i] == '_' and i < len(s) - 1:
            r += s[i + 1].upper()
            i += 2
        else:
            r += s[i]
            i += 1
    return r


def can_add_doc(docs, new_doc):
    """To avoid documents duplicate, look for all url doc.

	Parse self.infos of Crawler and return True if new_doc isn't in it.

	:param docs: the documents to check
	:type docs: list
	:param new_doc: the doc to add
	:type new_doc: dict
	:return: True if can add the doc

	"""
    for doc in docs:
        if doc['url'] == new_doc['url']:
            return False
    return True


def consumeBodyIter():
    """Returns the response body as an iterable.

        Note that this function can be only requested once, since it is
        constructed from the result.
        """


@classmethod
def AppName(cls):
    """Return our name to allow users to explicitly specify us."""
    return 'logistics_tracker'


def clean_mtproto_tag(config, group_index):
    """
    清理mtproto 协议减少时无用的tag
    """
    if 'tag' in config['inbounds'][group_index]:
        tag = config['inbounds'][group_index]['tag']
        rules = config['routing']['rules']
        for index, rule in enumerate(rules):
            if rule['outboundTag'] != 'tg-out':
                continue
            if len(rule['inboundTag']) == 1:
                del rules[index]
                for out_index, oubound_mtproto in enumerate(config['outbounds']
                    ):
                    if oubound_mtproto['protocol'] == 'mtproto':
                        del config['outbounds'][out_index]
                        break
            else:
                for tag_index, rule_tag in enumerate(rule['inboundTag']):
                    if rule_tag == tag:
                        del rule['inboundTag'][tag_index]
                        break
            break


def find_elements(full_list: list, list_with_values: list) ->list:
    """
    Find occurrences in a list and make a index related.

    TODO: Implement in declative style
    """
    intervals = []
    for x, val in enumerate(full_list):
        for y in list_with_values:
            if y == val:
                intervals.append((x, val))
    return intervals


def _check_user_entry(user):
    """Fixes wrong format of users."""
    if 'tenant_name' in user:
        keys = set(user.keys())
        if keys == {'username', 'password', 'tenant_name',
            'project_domain_name', 'user_domain_name'}:
            if user['user_domain_name'] == '' and user['project_domain_name'
                ] == '':
                del user['user_domain_name']
                del user['project_domain_name']
                return True
            else:
                user['project_name'] = user.pop('tenant_name')
                return True


def parent_directory(path):
    """
    Get parent directory. If root, return None
    "" => None
    "foo/" => "/"
    "foo/bar/" => "foo/"
    """
    if path == '':
        return None
    prefix = '/'.join(path.split('/')[:-2])
    if prefix != '':
        prefix += '/'
    return prefix


@classmethod
def jvmdoc(cls):
    """Subclasses should return their Jvmdoc configuration."""
    raise NotImplementedError()


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


@classmethod
def get_flags(cls):
    """
        Return the short and the long version of this option.

        The long flag (e.g. '--foo_bar'; used on the command-line like this:
        --foo_bar[=ARGS]) is derived from the class-name by stripping away any
        -Option suffix and converting the rest to snake_case.

        The short flag (e.g. '-f'; used on the command-line like this:
        -f [ARGS]) the short_flag class-member if that is set, or the first
        letter of the long flag otherwise.

        Returns
        -------
        (str, str)
            tuple of short-flag, and long-flag

        """
    return cls.get_short_flag(), cls.get_flag()


def _show_mpl_heatmap(exec_name, trajectory_list, **kwargs):
    """
    Produces a matplotlib plot of the trajectory
    """
    for traj in trajectory_list:
        traj.show_mpl_heatmap(**kwargs)


@staticmethod
def _where_builder(filters, case):
    """
        Build where part for query
        :param filters: dict filters for rows (where)
        :return: str update query and dict where data
        """
    query = ''
    where_data = {}
    for key in filters:
        if isinstance(filters[key], tuple):
            if len(filters[key]) == 3:
                if '=' in filters[key][2]:
                    query += (key + ' >= ' + '%(where_start_' + key +
                        ')s AND ' + key + ' <= ' + '%(where_end_' + key +
                        ')s ' + case + ' ')
                else:
                    query += (key + ' > ' + '%(where_start_' + key +
                        ')s AND ' + key + ' < ' + '%(where_end_' + key +
                        ')s ' + case + ' ')
                where_data['start_' + key] = filters[key][0]
                where_data['end_' + key] = filters[key][1]
            elif len(filters[key]) == 2:
                if not filters[key][0]:
                    query += key + ' ' + filters[key][1
                        ] + ' ' + 'NULL ' + case + ' '
                else:
                    query += key + ' ' + filters[key][1
                        ] + ' ' + '%(where_' + key + ')s ' + case + ' '
                    where_data[key] = filters[key][0]
            else:
                raise ValueError('Missing case param in filter: %s' %
                    filters[key][0])
        elif not filters[key] and not isinstance(filters[key], int):
            query += key + ' is NULL ' + case + ' '
        else:
            query += key + ' = ' + '%(where_' + key + ')s ' + case + ' '
            where_data[key] = filters[key]
    return query.rstrip(case + ' '), where_data


def read_credentials(cred_source, from_file=True):
    """ Fetch user credentials from text file.

    Converts string input in path to dictionary. Credentials must
    be stored as a dictionary to work properly.

    """
    if from_file:
        creds = {}
        with open(cred_source) as f:
            lines = f.readlines()
            for line in lines:
                line = line.split()
                creds[line[0]] = line[1]
    else:
        creds = cred_source
    return creds


def parse_source_file(source_file):
    """Parses a source file thing and returns the file name

    Example:

    >>> parse_file('hg:hg.mozilla.org/releases/mozilla-esr52:js/src/jit/MIR.h:755067c14b06')
    'js/src/jit/MIR.h'

    :arg str source_file: the source file ("file") from a stack frame

    :returns: the filename or ``None`` if it couldn't determine one

    """
    if not source_file:
        return None
    vcsinfo = source_file.split(':')
    if len(vcsinfo) == 4:
        vcstype, root, vcs_source_file, revision = vcsinfo
        return vcs_source_file
    if len(vcsinfo) == 2:
        vcstype, vcs_source_file = vcsinfo
        return vcs_source_file
    if source_file.startswith('/'):
        return source_file
    return None


def sample():
    """Use mouse to sample color in current frame

    """
    pass


def post_install(context):
    """Post install script"""
    if context.readDataFile('medialogcaptchawidget_default.txt') is None:
        return


def str_loads(data, content_type='application/json', encoding='utf-8'):
    """Returns the string instead of trying to convert it.
    """
    return data


def passthrough(oObj):
    """Passthrough adapter for calling Ixxx() on an object of type xxx"""
    return oObj


def _equal_phases(downloaded_phase, calculated_phase):
    """
    Compare calculated and downloaded phases.

    If the downloaded_phase is -1, this function returns True, otherwise,
    the phases are compared and True is returned if they are equal.

    >>> _equal_phases(0, 0)
    True
    >>> _equal_phases(-1, 1)
    True
    >>> _equal_phases(2, 1)
    False
    """
    if downloaded_phase != -1:
        if downloaded_phase != calculated_phase:
            return False
    return True


@classmethod
def array_equal(cls, mx, other_mx):
    """Return True if mx and other_mx are equal (including nan's, unlike
        numpy's array_equal
        """
    raise NotImplementedError


def angleBrackets(s):
    """Returns < < s > >"""
    lt = '<<'
    rt = '>>'
    return lt + s + rt


@classmethod
def adapt_emulated_to_native(cls, impl, **kw):
    """Produce a PostgreSQL native :class:`_postgresql.ENUM` from plain
        :class:`.Enum`.

        """
    kw.setdefault('validate_strings', impl.validate_strings)
    kw.setdefault('name', impl.name)
    kw.setdefault('schema', impl.schema)
    kw.setdefault('inherit_schema', impl.inherit_schema)
    kw.setdefault('metadata', impl.metadata)
    kw.setdefault('_create_events', False)
    kw.setdefault('values_callable', impl.values_callable)
    return cls(**kw)


def keepAlphanum(s):
    """Returns string p_s whose non-alphanum chars have been removed"""
    if s is None:
        return s
    res = ''
    for c in s:
        if c.isalnum():
            res += c
    return res


@staticmethod
def get_report_data_file_id():
    """
        Get the report.data id of the extractor
        :return: the report.data id
        """
    return 'fast5.extractor'


def getHostByName(name, timeout=(1, 3, 11, 45)):
    """
        Resolve the domain name C{name} into an IP address.

        @type name: C{str}
        @param name: DNS name to resolve.

        @type timeout: Sequence of C{int}
        @param timeout: Number of seconds after which to reissue the query.
            When the last timeout expires, the query is considered failed.

        @rtype: L{twisted.internet.defer.Deferred}
        @return: The callback of the Deferred that is returned will be
            passed a string that represents the IP address of the
            specified name, or the errback will be called if the
            lookup times out.  If multiple types of address records
            are associated with the name, A6 records will be returned
            in preference to AAAA records, which will be returned in
            preference to A records.  If there are multiple records of
            the type to be returned, one will be selected at random.

        @raise twisted.internet.defer.TimeoutError: Raised
            (asynchronously) if the name cannot be resolved within the
            specified timeout period.
        """


def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy."""
    z = x.copy()
    z.update(y)
    return z


def getId():
    """Get workflow version id for this object.

        This is used to mark all versions of an object with the same id.
        """


def margin_width(box, width, left=True, right=True):
    """Add box paddings, borders and margins to ``width``."""
    percentages = 0
    for value in ((['margin_left', 'padding_left'] if left else []) + ([
        'margin_right', 'padding_right'] if right else [])):
        style_value = box.style[value]
        if style_value != 'auto':
            if style_value.unit == 'px':
                width += style_value.value
            else:
                assert style_value.unit == '%'
                percentages += style_value.value
    if left:
        width += box.style['border_left_width']
    if right:
        width += box.style['border_right_width']
    if percentages < 100:
        return width / (1 - percentages / 100.0)
    else:
        return 0


def name():
    """Return the name of the object.

        :return: name

        """

    def fget(self):
        return self._name

    def fset(self, value):
        self._name = value
    return locals()


@classmethod
def quotes_by_instrument_urls(cls, client, urls):
    """
        fetch and return results
        """
    instruments = ','.join(urls)
    params = {'instruments': instruments}
    url = 'https://api.robinhood.com/marketdata/quotes/'
    data = client.get(url, params=params)
    results = data['results']
    while 'next' in data and data['next']:
        data = client.get(data['next'])
        results.extend(data['results'])
    return results


def create_geometry_string(geometry):
    """This function converts MolecularData geometry to psi4 geometry.

    Args:
        geometry: A list of tuples giving the coordinates of each atom.
            example is [('H', (0, 0, 0)), ('H', (0, 0, 0.7414))]. Distances in
            angstrom. Use atomic symbols to specify atoms.

    Returns:
        geo_string: A string giving the geometry for each atom on a line, e.g.:
            H 0. 0. 0.
            H 0. 0. 0.7414
    """
    geo_string = ''
    for item in geometry:
        atom = item[0]
        coordinates = item[1]
        line = '{} {} {} {}'.format(atom, coordinates[0], coordinates[1],
            coordinates[2])
        if len(geo_string) > 0:
            geo_string += '\n'
        geo_string += line
    return geo_string


@classmethod
def modify_url_for_impersonation(cls, url, impersonate_user, username):
    """
        Modify the SQL Alchemy URL object with the user to impersonate if applicable.
        :param url: SQLAlchemy URL object
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        """
    if impersonate_user is not None and username is not None:
        url.username = username


def phi2lon(phi, unit='deg'):
    """spherical phi -> longitude transform; currently a no-op"""
    return phi


@classmethod
def collapse(cls, holomap, ranges=None, mode='data'):
    """
        Given a map of Overlays, apply all applicable compositors.
        """
    if cls.definitions == []:
        return holomap
    clone = holomap.clone(shared_data=False)
    data = zip(ranges[1], holomap.data.values()
        ) if ranges else holomap.data.items()
    for key, overlay in data:
        clone[key] = cls.collapse_element(overlay, ranges, mode)
    return clone


@classmethod
def run_hooks(cls, hook_type, *args, **kwargs):
    """Run all hooks of specified type.

        :param cls: class that registers hooks
        :param hook_type: hook type, e.g., '__pre_parse_args__'
        :param args: args to be passed to every hook function
        :param kwargs: kwargs to be passed to every hook function
        """
    hook_funcs = cls._hooks_map.get(hook_type) or []
    for hook_func in hook_funcs:
        hook_func(*args, **kwargs)


@staticmethod
def consumer_init(cfg):
    """
        function for consumer initialization.

        Args:
            cfg (easycore.common.config.CfgNode): config of this process, you can use it to transfer data
                to `consumer_work` and `consumer_end` function.
        """
    pass


def format_xml(element):
    """
    Format an XML element, e.g. Beaker job description, for printing.

    :param element: XML element to format.
    """
    prettyfied = element.prettify()
    return prettyfied


def get_my_ip():
    """Try to obtain our external ip (from the Pyro4 nameserver's point of view)

    Returns
    -------
    str
        IP address.

    Warnings
    --------
    This tries to sidestep the issue of bogus `/etc/hosts` entries and other local misconfiguration,
    which often mess up hostname resolution.
    If all else fails, fall back to simple `socket.gethostbyname()` lookup.

    """
    import socket
    try:
        from Pyro4.naming import locateNS
        ns = locateNS()
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect((ns._pyroUri.host, ns._pyroUri.port))
        result, port = s.getsockname()
    except Exception:
        try:
            import commands
            result = commands.getoutput('ifconfig').split('\n')[1].split()[1][
                5:]
            if len(result.split('.')) != 4:
                raise Exception()
        except Exception:
            result = socket.gethostbyname(socket.gethostname())
    return result


def update_rep(rep: str) ->str:
    """ If rep is None, return rep as mat, which refers to the whole expression matrix
    """
    return rep if rep is not None else 'mat'


@staticmethod
def parse(files):
    """ Parse a set of files

        :param files: List of file's paths that needs to be parsed
        :type files: str

        :yields: Sentence thar were parsed
        :ytype: Sentence
        """
    raise NotImplementedError()


def filter_range(IStart, IEnd, IStep):
    """
    Filter current range.

    :param IStart: current start point
    :type IStart: float
    :param IEnd: current end point
    :type IEnd: float
    :param IStep: current step
    :type IStep: float
    :return: filtered range as list
    """
    temp = None
    IStartO = IStart
    IEndO = IEnd
    IStepO = abs(IStep)
    if IStartO > IEndO:
        temp = IStartO
        IStartO = IEndO
        IEndO = temp
    return [IStartO, IEndO, IStepO]


def socket_set_hwm(socket, hwm=-1):
    """libzmq 2/3/4 compatible sethwm"""
    try:
        socket.sndhwm = socket.rcvhwm = hwm
    except AttributeError:
        socket.hwm = hwm


@staticmethod
def _get_letstr(letterstr):
    """Get letterstr for printing."""
    return letterstr


def start_samp_proxy():
    """Starts (registers) and returns a SAMP proxy"""
    import os
    import xmlrpclib
    lockfile = os.path.expanduser('~/.samp')
    if not os.path.exists(lockfile):
        raise RuntimeError('A running SAMP hub was not found.')
    else:
        HUB_PARAMS = {}
        for line in open(lockfile):
            if not line.startswith('#'):
                key, value = line.split('=', 1)
                HUB_PARAMS[key] = value.strip()
    s = xmlrpclib.ServerProxy(HUB_PARAMS['samp.hub.xmlrpc.url'])
    metadata = {'samp.name': 'PyBDSM', 'samp.description.text':
        'PyBDSM: the Python Blob Detection and Source Measurement software'}
    result = s.samp.hub.register(HUB_PARAMS['samp.secret'])
    private_key = result['samp.private-key']
    s.samp.hub.declareMetadata(private_key, metadata)
    return s, private_key


def send(dest, msg, transactionid=None):
    """STOMP send command.

    dest:
        This is the channel we wish to subscribe to

    msg:
        This is the message body to be sent.

    transactionid:
        This is an optional field and is not needed
        by default.

    """
    transheader = ''
    if transactionid:
        transheader = 'transaction: %s\n' % transactionid
    return 'SEND\ndestination: %s\n%s\n%s\x00\n' % (dest, transheader, msg)


@staticmethod
def get_addresses_model():
    """
        This is needed so the BaseState can validate the
        provided addresses and throw an error if any are missing.
        As well as automatically generate documentation.
        NOTE: types must always be "str"
        return = {
            'required_addresses': {
                'req_address_name_1': str,
                'req_address_name_2': str,
            },
            'optional_addresses': {
                'opt_address_name_1': str,
                'opt_address_name_2': str,
            },
        }
        """
    return {'required_addresses': {'publisher': str, 'replyer': str},
        'optional_addresses': {}}


def deep_get(dikt, path):
    """Get a value or values located in `path` from a nested dictionary.
    Use a string separated by periods as the path to access
    values in a nested dictionary:
    deep_get(data, "data.files.0") == data["data"]["files"][0]
    deep_get(data, "data.files") == data["data"]["files"][]
    """
    value = dikt
    for component in path.split('.'):
        if component.isdigit():
            value = value[int(component)]
        elif type(value) == list:
            new = []
            for v in value:
                if component in v:
                    new.append(v[component])
            value = new
        elif component in value:
            value = value[component]
    return value


def getErrorResponse(e):
    """ generated source for method getErrorResponse """
    response = {'status': e.getStatus(), 'error_msg': e.message}
    return response


def cutoff(s, length=120):
    """Cuts a given string if it is longer than a given length."""
    if length < 5:
        raise ValueError('length must be >= 5')
    if len(s) <= length:
        return s
    else:
        i = (length - 2) / 2
        j = (length - 3) / 2
        return s[:i] + '...' + s[-j:]


def list_qualification_requests(QualificationTypeId=None, NextToken=None,
    MaxResults=None):
    """
    The ListQualificationRequests operation retrieves requests for Qualifications of a particular Qualification type. The owner of the Qualification type calls this operation to poll for pending requests, and accepts them using the AcceptQualification operation.
    See also: AWS API Documentation

    :example: response = client.list_qualification_requests(
        QualificationTypeId='string',
        NextToken='string',
        MaxResults=123
    )

    :type QualificationTypeId: string
    :param QualificationTypeId: The ID of the QualificationType.

    :type NextToken: string
    :param NextToken: If the previous response was incomplete (because there is more data to retrieve), Amazon Mechanical Turk returns a pagination token in the response. You can use this pagination token to retrieve the next set of results.

    :type MaxResults: integer
    :param MaxResults: The maximum number of results to return in a single call.

    :rtype: dict
    :return: {
        'NumResults': 123,
        'NextToken': 'string',
        'QualificationRequests': [
            {
                'QualificationRequestId': 'string',
                'QualificationTypeId': 'string',
                'WorkerId': 'string',
                'Test': 'string',
                'Answer': 'string',
                'SubmitTime': datetime(2015, 1, 1)
            },
        ]
    }

    """
    pass


def p_relation(parser):
    """
    relation : RELATION_ID TAB TYPE SPACE argument COLON id SPACE argument COLON id
    """
    parser[0] = '%s\t%s %s:%s %s:%s' % (parser[1], parser[3], parser[5],
        parser[7], parser[9], parser[11])
    return parser


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 truncate_int32(value):
    """
    Truncate the given value so it can be stored in exactly 4 bytes. The sign
    will be kept. Too high or too low values will be cut off, not clamped to
    the valid range.

    @param value: The value to truncate.
    @type value: C{int}

    @return: The truncated value.
    @rtype: C{int}.
    """
    return int(value & 2147483647 | -(value & 2147483648))


@staticmethod
def percentage_with_time_remaining(current, total, time_remaining):
    """Returns the progress percentage and time remaining."""
    return '{}% (~{} remaining)'.format(int(current / total * 100),
        time_remaining)


def __string_to_int(data):
    """Convert string of bytes Python integer, MSB"""
    val = 0
    if type(data) == str:
        data = bytearray(data)
    for i, c in enumerate(data[::-1]):
        val += 256 ** i * c
    return val


def no_prefix(name):
    """does the given constant have a ZMQ_ prefix?"""
    return name.startswith('E') and not name.startswith('EVENT')


def ensure_model_obj_has_mapping_constructor(model_obj):
    """
    Ensure that `model_obj` has a 'get_mappings_for_fit' method. Raises a
    helpful ValueError if otherwise.
    """
    if not hasattr(model_obj, 'get_mappings_for_fit'):
        msg = "model_obj MUST have a 'get_mappings_for_fit' method."
        raise ValueError(msg)
    return None


def is_frame(pos):
    """Return ``True`` if `pos` is of type frame."""
    return isinstance(pos, int)


def new():
    """Add a new screen

    """
    pass


def cleanup_test_name(name, strip_tags=True, strip_scenarios=False):
    """Clean up the test name for display.

    By default we strip out the tags in the test because they don't help us
    in identifying the test that is run to it's result.

    Make it possible to strip out the testscenarios information (not to
    be confused with tempest scenarios) however that's often needed to
    indentify generated negative tests.
    """
    if strip_tags:
        tags_start = name.find('[')
        tags_end = name.find(']')
        if tags_start > 0 and tags_end > tags_start:
            newname = name[:tags_start]
            newname += name[tags_end + 1:]
            name = newname
    if strip_scenarios:
        tags_start = name.find('(')
        tags_end = name.find(')')
        if tags_start > 0 and tags_end > tags_start:
            newname = name[:tags_start]
            newname += name[tags_end + 1:]
            name = newname
    return name


def check(check_ctxt, msgs, key, msgsrc, settings):
    """
    Performs a set of checks over the given key (context, message)...
    """
    if check_ctxt is None:
        return
    multi_rnatip = check_ctxt.get('multi_rnatip')
    multi_lines = check_ctxt.get('multi_lines')
    py_in_rna = check_ctxt.get('py_in_rna')
    not_capitalized = check_ctxt.get('not_capitalized')
    end_point = check_ctxt.get('end_point')
    undoc_ops = check_ctxt.get('undoc_ops')
    spell_checker = check_ctxt.get('spell_checker')
    spell_errors = check_ctxt.get('spell_errors')
    if multi_rnatip is not None:
        if key in msgs and key not in multi_rnatip:
            multi_rnatip.add(key)
    if multi_lines is not None:
        if '\n' in key[1]:
            multi_lines.add(key)
    if py_in_rna is not None:
        if key in py_in_rna[1]:
            py_in_rna[0].add(key)
    if not_capitalized is not None:
        if key[1] not in settings.WARN_MSGID_NOT_CAPITALIZED_ALLOWED and key[1
            ][0].isalpha() and not key[1][0].isupper():
            not_capitalized.add(key)
    if end_point is not None:
        if key[1].strip().endswith('.') and not key[1].strip().endswith('...'
            ) and key[1] not in settings.WARN_MSGID_END_POINT_ALLOWED:
            end_point.add(key)
    if undoc_ops is not None:
        if key[1] == settings.UNDOC_OPS_STR:
            undoc_ops.add(key)
    if spell_checker is not None and spell_errors is not None:
        err = spell_checker.check(key[1])
        if err:
            spell_errors[key] = err


@classmethod
def block_header(cls, block, height):
    """Return the block header bytes"""
    deserializer = cls.DESERIALIZER(block)
    return deserializer.read_header(height, cls.HEADER_SIZE_NO_SOLUTION)


def get_python_metadata(path):
    """ Returns the first Docstring from python file, only .py extensions"""
    file_extension = path.split('.')[-1].lower()
    if not file_extension == 'py':
        return
    else:
        f = open(path, 'r')
        quote_number = 0
        string = ''
        for line in f.readlines():
            if '#' in line:
                pass
            elif '"""' in line:
                if quote_number < 2:
                    quote_number = line.count('"""') + quote_number
                    string = string + line
                elif quote_number == 2:
                    return {'Python_Docstring': string}


@staticmethod
def get_vms(node):
    """
        Get a list of VMs that are connected to VPP interfaces

        :param node: VPP node.
        :type node: dict
        :returns: Dictionary containing a list of VMs and the interfaces
                  that are connected to VPP
        :rtype: dictionary
        """
    vmdict = {}
    print('Need to implement get vms')
    return vmdict


@classmethod
def parse(cls, name, data_size, reader, parsers):
    """given a 4 byte name, data_size int, BitstreamReader
        and dict of {"atom":handler} sub-parsers,
        returns an atom of this class"""
    assert name == b'free'
    reader.skip_bytes(data_size)
    return cls(data_size)


def play_rendered_anim():
    """Play back rendered frames/movies using an external player

    """
    pass


def remove_initial_data(apps, schema_editor):
    """This function does nothing. The below code is commented out together
    with an explanation of why we don't need to bother reversing any of the
    initial data"""
    pass


@classmethod
def _object_getbuffer_hook(cls, ll_module):
    """
        Return a cached object code for `ll_module`.
        """
    try:
        self = ll_module.__library
    except AttributeError:
        return
    if self._object_caching_enabled and self._compiled_object:
        buf = self._compiled_object
        self._compiled_object = None
        return buf


def set_aes_src(lucid, srcval):
    """Call lucid8824.set_aes_src"""
    lucid.set_aes_src(srcval)


@classmethod
def stream_deserialize(cls, f, **kwargs):
    """Deserialize from a stream"""
    raise NotImplementedError


def brush_colors_flip():
    """Toggle foreground and background brush colors

    """
    pass


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

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

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


def cumsum(iterable):
    """ Returns an iterator over the cumulative sum of values in the given list.
    """
    n = 0
    for x in iterable:
        n += x
        yield n


@classmethod
def showPortLabels(cls, state):
    """
        Shows or hides port labels.

        :param state: boolean
        """
    cls._draw_port_labels = state


def set_union(sets):
    """Non variadic version of set.union.
    """
    return set.union(*sets)


def check_disk(num1, num2):
    """Check detach disk result via simple disk number
       comparison
    """
    if num2 < num1:
        return 0
    elif num2 == num1:
        return 1
    else:
        return 2


def mirror_ho_m(height_image, magnification):
    """Usage: Find height of object using magnification"""
    return height_image / magnification


def allow_run_from_web_ui() ->bool:
    """When false, then it is not possible to run an ETL from the web UI"""
    return True


def _TriDict(tris):
    """tris is a list of triangles (a,b,c), CCW-oriented indices.
    Return dict mapping all edges in the triangles to the containing
    triangle list."""
    ans = dict()
    for i in range(0, len(tris)):
        a, b, c = t = tris[i]
        ans[a, b] = t
        ans[b, c] = t
        ans[c, a] = t
    return ans


def stitch_kepler_lcdict(lcdict):
    """This stitches Kepler light curves together across quarters.

    FIXME: implement this.

    Parameters
    ----------

    lcdict : lcdict
        An `lcdict` produced by `consolidate_kepler_fitslc`. The flux
        measurements between quarters will be stitched together.

    Returns
    -------

    lcdict
        Returns an `lcdict` (this is useable by most astrobase functions for LC
        processing). The flux measurements will have been shifted to form a
        seamless light curve across quarters suitable for long-term variability
        investigation.

    """


def ungroupslice(groups, gslice):
    """this is a helper for contigsub."""
    """coordinate transform: takes a match from seqingroups() and transforms to ungrouped coordinates"""
    eltsbefore = 0
    for i in range(gslice[0]):
        eltsbefore += len(groups[i]) - 1
    x = eltsbefore + gslice[1]
    return [x - 1, x + gslice[2] - 1]


def utc(dateString):
    """ ISO 8601の、UTCを示す末尾の 'Z' を、'+0000' に置き換える
    """
    if dateString.endswith('Z'):
        dateString = dateString.replace('Z', '+0000')
    return dateString


@classmethod
def _get_backend_type(cls, value):
    """
        helper to resolve backend constant from type
        """
    try:
        return cls._backend_type_map[value]
    except KeyError:
        pass
    msg = 'unsupported argon2 hash (type %r not supported by %s backend)' % (
        value, cls.get_backend())
    raise ValueError(msg)


def _compare_set(new_set, old_set, change_list, root):
    """
        a method for list changes made to a set

    :param new_set: set with new values
    :param old_set: set with old values
    :param change_list: list of differences between old and new
    :patam root: string with record of path to the root of the main object
    :return: list of differences between old and new
    """
    from copy import deepcopy
    path = deepcopy(root)
    missing_items = old_set - new_set
    extra_items = new_set - old_set
    for item in missing_items:
        change_list.append({'action': 'REMOVE', 'key': None, 'value': item,
            'path': path})
    for item in extra_items:
        change_list.append({'action': 'ADD', 'key': None, 'value': item,
            'path': path})
    return change_list


@staticmethod
def key(key):
    """
        Override if the key must be modified to access the store
        :param key: key into the store
        :return: modifier key
        """
    return key


def convert_db_row_to_dict(row, mapped_fields):
    """
    Convert row of database to dictionary.

    :param row: row of database.
    :param mapped_fields: list of tuple, which means field names.
    """
    data = {}
    for field, value in zip(mapped_fields, row):
        data[field] = value
    return data


def setdefaults(dct, defaults):
    """Given a target dct and a dict of {key:default value} pairs,
    calls setdefault for all of those pairs."""
    for key in defaults:
        dct.setdefault(key, defaults[key])
    return dct


def getDescription():
    """Return the description of this builder (a string)."""


@classmethod
def force_type(cls, response, environ=None):
    """
        enforce that the wsgi response is a response object of the current type.

        :param object response: response object.

        :param environ: a wsgi environment object.

        :rtype: CoreResponse
        """
    response = cls.response_converter(response)
    return super().force_type(response, environ)


def convert_units(P, In='cm', Out='m'):
    """
    Quickly convert distance units between meters, centimeters and millimeters
    """
    c = {'m': {'mm': 1000.0, 'cm': 100.0, 'm': 1.0}, 'cm': {'mm': 10.0,
        'cm': 1.0, 'm': 0.01}, 'mm': {'mm': 1.0, 'cm': 0.1, 'm': 0.001}}
    return c[In][Out] * P


def convert_basin_stack_to_value_dict(basin_stack_list):
    """
    This takes the basin stack list and then gives each basin in a stack layer a constant value. Used for plotting. So if there are several basin stacks each one gets a different value.

    Args:
        basin_stack_list (list of int lists): The basins that will be stacked. Each item in the list is a collection of basins that will be used in each indivdual stack plot. So, for example, if this is [ [1,2,3],[4,5]] then there will be two stacked plot, the first with basins 1,2,3 and the second with basins 4 and 5.

    Returns:
        this_value_dict (dict): A dictionary assigning a single value to each basin. Basins in the same stack will have the same value.

    Author: SMM

    Date: 11/01/2017

    """
    N_stacks = len(basin_stack_list)
    print('The number of stacks are: ' + str(N_stacks))
    if len(basin_stack_list) == 0:
        this_value_dict = {}
    else:
        this_value_dict = {}
        for idx, stack in enumerate(basin_stack_list):
            value = float(idx) / float(N_stacks)
            for item in stack:
                this_value_dict[item] = value
    return this_value_dict


def psi_Ca_MgOH_CO3_HMW84(T, P):
    """c-c'-a: calcium magnesium-hydroxide carbonate [HMW84]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


def ReserveUernPremEnd(t):
    """Unearned Premium: End of period"""
    return 0


def __getitem__(cls, name: str) ->str:
    """
        Get the value of an enum member.

        Args:
            name (:obj:`str`): The name of the item.

        Returns:
            :obj:`str`: The value of the instance.

        Examples:
            >>> ColorChoice['GREEN']
            '#0F0'
        """
    return super().__getitem__(name).value


def loseConnection():
    """
        Close the connection sending a close frame first.
        """


def get_quotechars(data, quote_chars=None):
    """Get potential quote characters

    Quote characters are those that occur in the ``quote_chars`` set and are
    found at least once in the file.

    Parameters
    ----------

    data: str
        The data of the file as a string

    quote_chars: iterable
        Characters that should be considered quote characters. If it is None,
        the following default set is used::

        ["'", '"', "~", "`"]

    Returns
    -------
    quotes: set
        Set of potential quote characters. The empty string is added by
        default.

    """
    if quote_chars is None:
        quote_chars = ["'", '"', '~', '`']
    Q = set(quote_chars) & set(data)
    Q.add('')
    return Q


def viewer_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin: int=
    0, ymax: int=0, extend: bool=True):
    """Set the boundaries for viewer operations

    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    """
    pass


def set_form_partial_validation(form, minimum_required):
    """
    Get a form ready for partial validation.
    For all fields not in `minimum_required`, set
    `Field.required` to False.

    :param minimum_required: list of minimum required fields
    :return: None
    """
    for field_name, field in getattr(form, 'all_fields', form.fields).items():
        if field_name not in minimum_required:
            field.required = False


@staticmethod
def _get_flaky_attribute(test_item, flaky_attribute):
    """
        Gets an attribute describing the flaky test.

        :param test_item:
            The test method from which to get the attribute
        :type test_item:
            `callable` or :class:`nose.case.Test` or :class:`Function`
        :param flaky_attribute:
            The name of the attribute to get
        :type flaky_attribute:
            `unicode`
        :return:
            The test callable's attribute, or None if the test
            callable doesn't have that attribute.
        :rtype:
            varies
        """
    return getattr(test_item, flaky_attribute, None)


def config_bool(value):
    """Represent a boolean in a way compatible with configparser."""
    return 'true' if value else 'false'


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 render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

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

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


def set_status_and_headers_in_response(response, status, headers):
    """Set status and headers in flask Reponse object"""
    if headers:
        response.headers.extend(headers)
    if status is not None:
        if isinstance(status, int):
            response.status_code = status
        else:
            response.status = status


def _mem_unitconv(mem, units='MB'):
    """Convert memory from bytes to the specified unit.

    Parameters
    ----------
    mem : int
        The amount of memory in bytes.
    units : {'B', 'KB', 'MB', 'GB'}
        Specificy the units of the output ('B'=bytes, 'KB'=kilobytes,
        'MB=megabytes, 'GB'=gigabytes).

    Returns
    -------
    mem : float
        The amount of memory in the specified units.
    """
    if units.lower() == 'b':
        return mem
    elif units.lower() == 'kb':
        denom = 1024.0
    elif units.lower() == 'mb':
        denom = 1024 * 1024.0
    elif units.lower() == 'gb':
        denom = 1024 * 1024 * 1024.0
    else:
        raise ValueError(
            'units must be B, KB, MB or GB. (corresponding to bytes, kilobytes, megabytes, gigabytes)'
            )
    return mem / denom


def stream_raw_sse(mkrequest, *pargs, _last_event_id=None, headers=None, **
    kwargs):
    """
    Streams Server-Sent Events, each event produced as a sequence of
    (field, value) pairs.

    Does not handle reconnection, etc.
    """
    if headers is None:
        headers = {}
    headers['Accept'] = 'text/event-stream'
    headers['Cache-Control'] = 'no-cache'
    if _last_event_id is not None:
        headers['Last-Event-ID'] = _last_event_id
    with mkrequest(*pargs, headers=headers, stream=True, **kwargs) as resp:
        fields = []
        for line in resp.iter_lines(decode_unicode=True):
            if not line:
                yield fields
                fields = []
            elif line.startswith(':'):
                pass
            elif ':' in line:
                field, value = line.split(':', 1)
                if value.startswith(' '):
                    value = value[1:]
                fields += [(field, value)]
            else:
                fields += [(line, '')]


def models_from_ids(sas, cls, ids):
    """Generator that, given a sequence of IDs, yields model instances.

    Performance is poor. TODO SOMEONE IMPROVE THIS PLEASE
    """
    for id in ids:
        yield sas.query(cls).get(id)


@classmethod
def _extract_data(cls):
    """ Raw data parsing/extraction. """
    raise NotImplementedError


def mergeConfig(propertySources):
    """将property_sources的各项配置整合到一个字典里"""
    config = dict()
    for property in propertySources:
        source = property.get('source', {})
        for key, value in source.items():
            config[key] = value
    return config


def replace_sublist(li, target, replacement):
    """
  Replace a sublist with another sublist.
  Not very effcient.
  If 'eq' is given, this will be used to compare items.
  """
    result = []
    i = 0
    while i < len(li):
        if li[i:i + len(target)] == target:
            i += len(target)
            result.extend(replacement)
        else:
            result.append(li[i])
            i += 1
    return result


def join():
    """Attach selected nodes to a new common frame

    """
    pass


def average_color(colors):
    """
    Returns average for the list, or None of the list is empty. Each element is
    an inner list of 4 numbers.
    """
    count = len(colors)
    if count == 0:
        return None
    totals = [0, 0, 0, 0]
    for color in colors:
        for i in range(0, 4):
            totals[i] += color[i]
    avg = []
    for i in range(0, 4):
        avg.append(round(totals[i] / count))
    return avg


@staticmethod
def parse_bar(input_entry):
    """
        This function extracts the bargraph line.
        each row is spanned:
        Name, time, keys, values

        :param input_entry: line to parse
        :return:
        parsed_entry
        """
    keys_list = []
    value_list = []
    for key in sorted(input_entry.keys()):
        resp_in = input_entry[key]
        for elements in resp_in:
            for key_in in sorted(elements.keys()):
                keys_list.append(key_in)
                value_list.append(elements[key_in])
    keys = keys_list
    values = value_list
    return keys, values


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

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


def getEnv(env_variable, default, description=None):
    """return environment variable of env_variable if possible, otherwise
    return default"""
    from os import environ
    try:
        variable = environ[env_variable]
    except KeyError:
        if not default:
            raise RuntimeError(
                'Environment variable %r is not set. The variable should be %r.'
                 % (env_variable, description))
        print(
            '** warning: environment variable %s, which is the %s, is not found. It is set to default value %s'
             % (env_variable, description, default))
        variable = default
    return variable


def ensure_maxlength_100_chars_and_tags_key_val_not_none(instance,
    attribute, value):
    """
    A helper function to ensure that the values for
    the reserved kays are less than a hundred character limit
    and that the tags do not have any none keys or vals
    """
    if isinstance(value, str):
        if len(value) > 100:
            raise ValueError('Values must not exceed length of 100 chars')
    elif isinstance(value, dict):
        for key in value:
            if key is None or key == 'None':
                raise ValueError("Tags keys can't be None")
            if value.get(key) is None:
                raise ValueError("Tags values can't be None")
            for elem in value[key]:
                if elem is None:
                    raise ValueError("Tags values can't be None")
                if len(elem) > 100:
                    raise ValueError(
                        'Values must not exceed length of 100 chars')
    return value


def plural(n: int, thing: str) ->str:
    """Add "s" to string if needed.

    >>> plural(0, 'hat'), plural(1, 'hat'), plural(2, 'hat')
    ('0 hats', '1 hat', '2 hats')
    """
    if n == 1:
        return '1 ' + thing
    return f'{n} {thing}s'


def get_column_name(df, column, total_columns=None):
    """
    gets the name of a column from either an integer or a passed name.
    Allows the total columns to be overwritten for cases where additional columns
    are added to the dataframe.
    """
    if total_columns is None:
        total_columns = df.shape[1]
    if column in df.columns:
        return column
    try:
        column_index = int(column)
        if column_index < 0:
            column_index = column_index + total_columns
        return df.columns.values.tolist()[column_index]
    except (ValueError, TypeError):
        try:
            from dativa.file_processing import FpInvalidSourceFieldError
            raise FpInvalidSourceFieldError(column)
        except ImportError:
            raise KeyError('Invalid column name: {}'.format(column))


def name_mapper(name=None):
    """
    General Purpose name remapping function
    If not fed a name, it returns the mapping dictionary
    If fed a name, it returns either the mapped name or the name (if no mapping is defined)
    Parameters
    ----------
    name: string
        The name of a JWST object
    Returns
    -------
    dictionary or string
        Either the remapped string (where necessary) or the complete mapping dictionary.
    """
    short_str_mappings = {'nircam ssgrism': 'nircam lw_tsgrism',
        'nirspec msa': 'nirspec mos', 'ssgrism': 'lw_tsgrism', 'msa': 'mos'}
    if name is None:
        return short_str_mappings
    elif name in short_str_mappings:
        return short_str_mappings[name]
    else:
        return name


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

        :param WebSessionsChangeFixedLengthPolicyType val:
        :rtype: EventType
        """
    return cls('web_sessions_change_fixed_length_policy', val)


@classmethod
def disable(cls):
    """Disables tracking security state changes.
        """
    return cls.build_send_payload('disable', {}), None


def draw_digraph(graph: iter, layout: dict=None):
    """Print given iterable of 2-uplet understood as edges"""
    import networkx as nx
    import matplotlib
    matplotlib.use('TkAgg')
    import matplotlib.pyplot as plt
    from matplotlib.lines import Line2D
    G = nx.DiGraph()
    G.add_edges_from(graph)
    graph_pos = layout or nx.shell_layout(G)
    nx.draw_networkx_nodes(G, graph_pos, node_size=1000, node_color='blue',
        alpha=0.3)
    nx.draw_networkx_edges(G, graph_pos, width=2, alpha=0.3, edge_color='green'
        )
    nx.draw_networkx_labels(G, graph_pos, font_size=12, font_family=
        'sans-serif')
    plt.show()


def addon_remove(module: str=''):
    """Delete the add-on from the file system

    :param module: Module, Module name of the add-on to remove
    :type module: str
    """
    pass


def get_date(date):
    """Return date. Needed for testing."""
    return date


def _volume(shape):
    """Return the volume of a shape."""
    prod = 1
    for start, stop in shape:
        prod *= stop - start
    return prod


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

        :param DomainVerificationAddDomainSuccessDetails val:
        :rtype: EventDetails
        """
    return cls('domain_verification_add_domain_success_details', val)


def normalize(a, axis=None):
    """Normalizes the input array so that it sums to 1.

    :param a: non-normalized input array
    :param axis: dimension along which normalization is to be performed
    """
    a_sum = a.sum(axis)
    if axis and a.ndim > 1:
        a_sum[a_sum == 0] = 1
        shape = list(a.shape)
        shape[axis] = 1
        a_sum.shape = shape
    a /= a_sum


def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy.
    http://stackoverflow.com/questions/38987/how-can-i-merge-two-python-dictionaries-in-a-single-expression
    """
    z = x.copy()
    z.update(y)
    return z


def apply_vector_left(a, B):
    """ multiply 2D matrix with 2D vector, vectorized """
    a1, a2 = a
    (b11, b12), (b21, b22) = B
    return a1 * b11 + a2 * b21, a1 * b12 + a2 * b22


@classmethod
def create(cls, request_handler, name, apptable_name, columns, is_multirow=
    False):
    """Create a datatable and return a DataTable object

        :param request_handler:
        :param name:
        :param apptable_name:
        :param columns:
        :param is_multirow:
        :rtype: :class:`fineract.objects.datatable.DataTable`
        """
    params = {'datatableName': name, 'apptableName': apptable_name,
        'multiRow': is_multirow, 'columns': columns}
    data = request_handler.make_request('POST', '/datatables', json=params)
    return cls(request_handler, request_handler.make_request('GET',
        '/datatables/{}'.format(data['resourceIdentifier'])), False)


@classmethod
def saving(cls, callback):
    """
        Register a saving model event with the dispatcher.

        :type callback: callable
        """
    cls._register_model_event('saving', callback)


def get_list_string(var_name, list_obj, ncols=5):
    """ Function to get string format of a list object.

    :param var_name: name of variable
    :type var_name: str

    :param list_obj: object of squence variable
    :type list_obj: list

    :param ncols: number of columns, default is 5
    :type ncols: int

    Example::
        >>> a = [(1,2,3), (2,3,4)]
        >>> get_list_string('a', a)
        >>> 'a = [\\n    (1, 2, 3),\\n    (2, 3, 4),\\n]\\n\\n'
    """
    begin = var_name + ' = ['
    indent = ' ' * 4
    data = ''
    for idx, elem in enumerate(list_obj):
        if hasattr(elem, '__iter__'):
            data += '\n' + indent + str(elem) + ','
            continue
        if idx % ncols == 0:
            data += '\n' + indent
        if isinstance(elem, str):
            data += "'" + elem + "', "
        else:
            data += str(elem) + ', '
    end = '\n]\n\n'
    content = begin + data + end
    return content


def polynomial_reduce_mod(poly, polymod, p):
    """Reduce poly by polymod, integer arithmetic modulo p.

  Polynomials are represented as lists of coefficients
  of increasing powers of x."""
    assert polymod[-1] == 1
    assert len(polymod) > 1
    while len(poly) >= len(polymod):
        if poly[-1] != 0:
            for i in range(2, len(polymod) + 1):
                poly[-i] = (poly[-i] - poly[-1] * polymod[-i]) % p
        poly = poly[0:-1]
    return poly


def predicate_split(func, stream, key=None):
    """
    Given a stream and a function, split the stream into two sequences based on
    the results of the func for that item

    :param func: function to invoke with the item; function must return True or False
    :param stream: iterable to split into two sequences
    :param key: if set, a function to use to pull the attribute to inspect.  Basically
        the same sort of trick as the key paramater for :py:func:`sorted`
    :return: two lists, the first a list of everything that was False, the second a
        list of everything that was True

    Example usage:

    >>> from snakeoil.sequences import predicate_split
    >>> odd, even = predicate_split(lambda x:x % 2 == 0, range(10))
    >>> assert odd == [1, 3, 5, 7, 9]
    >>> assert even == [0, 2, 4, 6, 8]
    """
    true_l, false_l = [], []
    tappend, fappend = true_l.append, false_l.append
    if key is not None:
        for item in stream:
            if func(key(item)):
                tappend(item)
            else:
                fappend(item)
    else:
        for item in stream:
            if func(item):
                tappend(item)
            else:
                fappend(item)
    return false_l, true_l


@classmethod
def with_json_and_owner(cls, jsonobj, owner):
    """ Instantiates by forwarding to `with_json()`, then remembers the
        "owner" of the instantiated elements. The "owner" is the resource
        containing the receiver and is used to resolve contained resources.

        :raises: TypeError on anything but dict or list of dicts
        :raises: FHIRValidationError if instantiation fails
        :param dict jsonobj: Decoded JSON dictionary (or list thereof)
        :param FHIRElement owner: The owning parent
        :returns: An instance or a list of instances created from JSON data
        """
    instance = cls.with_json(jsonobj)
    if isinstance(instance, list):
        for inst in instance:
            inst._owner = owner
    else:
        instance._owner = owner
    return instance


def add_key_value_pair(key, value, header, body):
    """
    Given a key and a value, add them to the header and the body of the
    new CSV object
    """
    header += str(key) + ','
    body += str(value) + ','
    return header, body


@classmethod
def join_segments(cls, segments, absolute=True):
    """Create a :class:`URLPath` from an iterable of segments."""
    if absolute:
        path = cls('/')
    else:
        path = cls('')
    for segment in segments:
        path = path.add_segment(segment)
    return path


def create_realtime_endpoint(MLModelId=None):
    """
    Creates a real-time endpoint for the MLModel . The endpoint contains the URI of the MLModel ; that is, the location to send real-time prediction requests for the specified MLModel .
    See also: AWS API Documentation

    :example: response = client.create_realtime_endpoint(
        MLModelId='string'
    )

    :type MLModelId: string
    :param MLModelId: [REQUIRED]
            The ID assigned to the MLModel during creation.

    :rtype: dict
    :return: {
        'MLModelId': 'string',
        'RealtimeEndpointInfo': {
            'PeakRequestsPerSecond': 123,
            'CreatedAt': datetime(2015, 1, 1),
            'EndpointUrl': 'string',
            'EndpointStatus': 'NONE'|'READY'|'UPDATING'|'FAILED'
        }
    }

    """
    pass


@classmethod
def from_pb(cls, obj):
    """
        Unpack a Protobuf object.

        :param obj: the Protobuf object to parse.
        :return: an instance of the class that implements the interface.
        """


def scale(me, flags=None):
    """scale or unscale (without arguments) the problem.
flags: options can be combined
with the bitwise OR operator and may be the following:
GLP_SF_GM | perform geometric mean scaling;
GLP_SF_EQ | perform equilibration scaling;
GLP_SF_2N | round scale factors to nearest power of two;
GLP_SF_SKIP | skip scaling, if the problem is well scaled.
GLP_SF_AUTO | chooses the scaling options automatically.
     """
    if type(flags) is int:
        me.scale_prob(flags)
    else:
        me.unscale_prob()


def add_suffix(in_files, suffix):
    """
    Wrap nipype's fname_presuffix to conveniently just add a prefix

    >>> add_suffix([
    ...     '/path/to/sub-045_ses-test_T1w.nii.gz',
    ...     '/path/to/sub-045_ses-retest_T1w.nii.gz'], '_test')
    'sub-045_ses-test_T1w_test.nii.gz'

    """
    import os.path as op
    from nipype.utils.filemanip import fname_presuffix, filename_to_list
    return op.basename(fname_presuffix(filename_to_list(in_files)[0],
        suffix=suffix))


def parseEnsemblLabels(intree):
    """
    Function to convert a Dendropy tree obtained from Ensembl (in NHX) format.
    Returns a new tree (leaves the input tree unchanged)

    :param intree: a tree as Dendropy object
    """
    t = intree.clone(depth=1)
    for n in t.internal_nodes():
        if n.annotations['D'].value == 'Y' or n.annotations['DD'].value == 'Y':
            n.label = 'duplication'
        else:
            n.label = 'speciation'
    t.seed_node.label = None
    cn = t.seed_node.child_nodes()
    if not t.is_rooted and len(cn) == 2:
        i = 1 if cn[0].is_leaf() else 0
        tmp = cn[i].label
        cn[i].edge.collapse()
        t.seed_node.label = tmp
    return t


def to_bytes(value):
    """ str to bytes (py3k) """
    vtype = type(value)
    if vtype == bytes or vtype == type(None):
        return value
    try:
        return vtype.encode(value)
    except UnicodeEncodeError:
        pass
    return value


def remove_src(text):
    """
    Remove the news source from the text, only context returned.
    """
    text = str(text).strip()
    keywords = ['讯：', '讯:', '讯 ', '讯，', '消息 ', '消息:', '消息：', '报道：', '报道:',
        '报道 ', '消息，', '日电 ', '据人民网报道，']
    for word in keywords:
        if text.find(word) != -1:
            index = text.index(word)
            text = text[index + len(word):]
            break
    idx = -1
    if text.startswith('('):
        idx = text.index(')')
    elif text.startswith('（'):
        idx = text.index('）')
    text = text[idx + 1:]
    idx = -1
    if '讯(' in text:
        idx = text.index(')')
    elif '讯（' in text:
        idx = text.index('）')
    text = text[idx + 1:]
    return text.strip()


@classmethod
def fromRaw(cls, skype=None, raw={}):
    """
        Create a new instance based on the raw properties of an API response.

        This can be overridden to automatically create subclass instances based on the raw content.

        Args:
            skype (Skype): parent Skype instance
            raw (dict): raw object, as provided by the API

        Returns:
            SkypeObj: the new class instance
        """
    return cls(skype, raw, **cls.rawToFields(raw))


def psi_H_K_Cl_PK74(T, P):
    """c-c'-a: hydrogen potassium chloride [PK74]."""
    psi = -0.007
    valid = T == 298.15
    return psi, valid


@classmethod
def all(cls, collection, skip=None, limit=None):
    """
            Returns all documents of the collection

            :param collection Collection instance
            :param skip  The number of documents to skip in the query
            :param limit The maximal amount of documents to return. The skip is applied before the limit restriction.

            :returns Document list
        """
    kwargs = {'skip': skip, 'limit': limit}
    return cls._construct_query(name='all', collection=collection, multiple
        =True, **kwargs)


def __new__(mcs, name, bases, class_body, **kwargs):
    """
        Override of `__new__` to ensure the __init__ signature is compatible.
        """
    return super().__new__(mcs, name, bases, class_body)


def _filter_resources(prefix, resources):
    """
    Returns a list of resources, which starts with given prefix
    """
    return list(filter(lambda r: r.startswith(prefix), resources))


def get_classes(class_name):
    """get_classes(class_name) -> class_object_list : cast new type class only"""
    cls_list = []
    import gc
    import inspect
    for obj in gc.get_objects():
        try:
            if getattr(obj, '__class__', None):
                if inspect.isclass(obj) and obj.__name__ == class_name:
                    cls_list.append(obj)
        except ReferenceError:
            continue
    return cls_list


@staticmethod
def log_message(movetype: int, name: str, result: bool) ->str:
    """
        Function to dynamically create log of Markov step @[mstep]

        Parameters
    	----------
            movetype : :obj:`int`
                Markov step[i] for i in [0, 6], inclusive. There
                are 7 Markov steps that determine the braid-to-braidrep
                modification.

            name : :obj:`str`
                The name of the Markov step.

            result : :obj:`bool`
                Boolean representing whether the move was successfully
                executed or not.

        Returns
		-------
            String of log for BraidWord.word at Markov step [i] for
            i in [0, 6], inclusive.

        """
    beg = f'MoveType: {str(movetype)}, '
    tmp = f'Attempted {name}: '
    if result == True:
        tmp += name + ' Succeeded.'
    else:
        tmp += name + ' Failed.'
    return beg + tmp


@classmethod
def load(cls, graph, element):
    """
        Instantiates the node in the graph if it's not already stored in the graph

        :param graph: The dependency graph this node is a member of
        :type graph: corenlp_xml.dependencies.DependencyGraph
        :param element: The lxml element wrapping the node
        :type element: lxml.ElementBase

        """
    node = graph.get_node_by_idx(id(element.get('idx')))
    if node is None:
        node = cls(graph, element)
        graph.register_node(node)
    return node


def time_to_vega(time):
    """
    Convert an `~astropy.time.Time` object into a string compatible with Vega.
    """
    year, month, day, hour, minute, second = time.datetime.timetuple()[:6]
    month -= 1
    return f'datetime({year}, {month}, {day}, {hour}, {minute}, {second})'


def _find_direct_matches(list_for_matching, list_to_be_matched_to):
    """
    Find all 100% matches between the values of the two iterables

    Parameters
    ----------
    list_for_matching : list, set
        iterable containing the keys
    list_to_be_matched_to : list, set
        iterable containing the values to match to the keys

    Returns
    -------

    matched : dict
        all 100% matches

    """
    matches = dict()
    for entry_a in list_for_matching.copy():
        if entry_a in list_to_be_matched_to:
            matches[entry_a] = entry_a
            list_for_matching.remove(entry_a)
            list_to_be_matched_to.remove(entry_a)
    return matches


def p_typetypedecl(p):
    """typetypedecl : TYPE CONID EQUAL type"""
    p[0] = [p[1], [p[2], p[4]]]


def copy_location(new_node, old_node):
    """
    Copy source location (`lineno` and `col_offset` attributes) from
    *old_node* to *new_node* if possible, and return *new_node*.
    """
    for attr in ('lineno', 'col_offset'):
        if (attr in old_node._attributes and attr in new_node._attributes and
            hasattr(old_node, attr)):
            setattr(new_node, attr, getattr(old_node, attr))
    return new_node


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

        :param FileTransfersTransferSendDetails val:
        :rtype: EventDetails
        """
    return cls('file_transfers_transfer_send_details', val)


def fits_ccddata_writer(ccd_data, filename, hdu_mask='MASK',
    hdu_uncertainty='UNCERT', hdu_flags=None, key_uncertainty_type='UTYPE',
    **kwd):
    """
    Write CCDData object to FITS file.

    Parameters
    ----------
    filename : str
        Name of file.

    hdu_mask, hdu_uncertainty, hdu_flags : str or None, optional
        If it is a string append this attribute to the HDUList as
        `~astropy.io.fits.ImageHDU` with the string as extension name.
        Flags are not supported at this time. If ``None`` this attribute
        is not appended.
        Default is ``'MASK'`` for mask, ``'UNCERT'`` for uncertainty and
        ``None`` for flags.

    key_uncertainty_type : str, optional
        The header key name for the class name of the uncertainty (if any)
        that is used to store the uncertainty type in the uncertainty hdu.
        Default is ``UTYPE``.

        .. versionadded:: 3.1

    kwd :
        All additional keywords are passed to :py:mod:`astropy.io.fits`

    Raises
    -------
    ValueError
        - If ``self.mask`` is set but not a `numpy.ndarray`.
        - If ``self.uncertainty`` is set but not a
          `~astropy.nddata.StdDevUncertainty`.
        - If ``self.uncertainty`` is set but has another unit then
          ``self.data``.

    NotImplementedError
        Saving flags is not supported.
    """
    hdu = ccd_data.to_hdu(hdu_mask=hdu_mask, hdu_uncertainty=
        hdu_uncertainty, key_uncertainty_type=key_uncertainty_type,
        hdu_flags=hdu_flags)
    hdu.writeto(filename, **kwd)


def create(requestor, service, nodeIdentifier):
    """
        Called when a node creation request has been received.

        @param requestor: The entity the request originated from.
        @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param service: The entity the request was addressed to.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: The suggestion for the identifier of the node
            to be created. If the request did not include a suggestion for the
            node identifier, the value is C{None}.
        @type nodeIdentifier: C{unicode} or C{NoneType}
        @return: A deferred that fires with a C{unicode} that represents
                 the identifier of the new node.
        @rtype: L{Deferred<twisted.internet.defer.Deferred>}
        """


def deleteLink(nodeA, nodeB):
    """Delete a link between two node objects.

    This function can be empty. Used for optional complex database quieries.

    Parameters:
        nodeA (MgvNode): source node.
        nodeB (MgvNode): destination node.
    """
    return


def lambd_tris_K_GT17simopt(T, P):
    """n-c: tris potassium [GT17simopt]."""
    lambd = 0.02895
    valid = T == 298.15
    return lambd, valid


def write_to_csv(csv_file, dir, name, id):
    """
    Writes a row to the CSV file.

    :param csv_file: the file handle to write to.
    :type csv_file: file
    :param dir: the directory to write out
    :type dir: str`
    :param name: the file name (without path or extension)
    :type name: str
    :param id: the ID to write out
    :type id: str
    """
    csv_file.write('"')
    csv_file.write(dir)
    csv_file.write('"')
    csv_file.write(',')
    csv_file.write('"')
    csv_file.write(name.replace('"', ''))
    csv_file.write('"')
    csv_file.write(',')
    csv_file.write(id)
    csv_file.write('\n')


@classmethod
def reserve(cls, context, tag, node_id):
    """Get and reserve a node.

        To prevent other ManagerServices from manipulating the given
        Node while a Task is performed, mark it reserved by this host.

        :param cls: the :class:`Node`
        :param context: Security context.
        :param tag: A string uniquely identifying the reservation holder.
        :param node_id: A node ID or UUID.
        :raises: NodeNotFound if the node is not found.
        :returns: a :class:`Node` object.

        """
    db_node = cls.dbapi.reserve_node(tag, node_id)
    node = cls._from_db_object(context, cls(), db_node)
    return node


def table(listOfDicts):
    """Loop through a list of dicts and return a markdown table as a multi-line string.

        listOfDicts -- A list of dictionaries, each dict is a row
        """
    markdowntable = ''
    markdownheader = '| ' + ' | '.join(map(str, listOfDicts[0].keys())) + ' |'
    markdownheaderseparator = '|-----' * len(listOfDicts[0].keys()) + '|'
    markdowntable += markdownheader + '\n'
    markdowntable += markdownheaderseparator + '\n'
    for row in listOfDicts:
        markdownrow = ''
        for key, col in row.items():
            markdownrow += '| ' + str(col) + ' '
        markdowntable += markdownrow + '|' + '\n'
    return markdowntable


def toRPM(rawVelocity):
    """速度情報の単位を[1/100 * rpm]から[rpm]に変換する
    """
    return rawVelocity / float(100)


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


def operator_cheat_sheet():
    """List all the Operators in a text-block, useful for scripting

    """
    pass


def ndof_orbit():
    """Orbit the view using the 3D mouse

    """
    pass


@classmethod
def is_attempt_filename(cls, fname):
    """
        Returns if the filename is an attempt filename (ends in .attempt.json).
        """
    return fname.endswith('attempt.json')


def func_eq(parser, x, y):
    """Returns true, if ``x`` equals ``y``."""
    if x == y:
        return '1'
    else:
        return ''


def __get_shift__(match):
    """
    Parses the shift part of a filename e.g. +128, -110
    """
    shift = 0
    keys = match.groupdict().keys()
    if 'operator' in keys and 'shift_si' in keys:
        operator = match.group('operator')
        shift_str = match.group('shift')
        if operator != '' and shift_str:
            shift = int(shift_str)
            if operator == '-':
                shift = -shift
    return shift


@staticmethod
def to_nullable_map(value):
    """
        Converts value into map object or returns null when conversion is not possible.

        :param value: the value to convert.

        :return: map object or null when conversion is not supported.
        """
    if isinstance(value, dict):
        return value
    elif hasattr(value, '_ast'):
        return value._ast()
    elif hasattr(value, '__iter__'):
        data = {}
        index = 0
        for v in value:
            data[str(index)] = v
            index += 1
        return data
    elif hasattr(value, '__dict__'):
        data = {}
        for k in dir(value):
            v = getattr(value, k)
            if not callable(v) and not k.startswith('_'):
                data[k] = v
        return data
    else:
        return None


def has(property):
    """
        Есть ли у домена указанное свойство?

        @param property: имя свойства
        @type property: C{str}
        @rtype: C{bool}
        """


def colorize(text, color, bold=False):
    """
    https://github.com/kennethreitz/crayons
    Included colors are red, green, yellow, blue, black,
    magenta, cyan, white, and normal
    """
    return eval('str(crayons.{}(text, bold=bold))'.format(color))


@classmethod
def batch_size(cls, tensor):
    """ Return batch size (the length of the first dimension) of the input tensor

        Parameters
        ----------
        tensor : tf.Tensor

        Returns
        -------
        batch size : int or None
        """
    return tensor.get_shape().as_list()[0]


def path2fname(path):
    """
    extracts file name from path
  """
    return path.split('/')[-1]


def score_formula(f1, f2):
    """
    Binary strict version
    """
    score = -1000
    if len(f1) != len(f2) or not f1 or not f2:
        return -1000
    for piece1 in f1:
        if piece1 not in f2:
            break
        elif f1[piece1] != f2[piece1]:
            break
    else:
        score = 1000
    return score


def save_cookiestxt(fp, cookies):
    """Write 'cookies' in Netscape cookies.txt format to 'fp'"""
    fp.write('# Netscape HTTP Cookie File\n\n')
    for cookie in cookies:
        if cookie.value is None:
            name = ''
            value = cookie.name
        else:
            name = cookie.name
            value = cookie.value
        fp.write('\t'.join((cookie.domain, 'TRUE' if cookie.domain.
            startswith('.') else 'FALSE', cookie.path, 'TRUE' if cookie.
            secure else 'FALSE', '0' if cookie.expires is None else str(
            cookie.expires), name, value)) + '\n')


def groupname(gid=None):
    """Return the name of the group with the given gid.

    If gid is None, return the name of the current group."""
    return None


def shorten_str(s: str, maxlen: int=32):
    """
    If `s` is longer than `maxlen`, shorten it to at mos maxlen using `'...'`.
    """
    if len(s) > maxlen:
        s = s[:maxlen - 3] + '...'
    return s


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

        :param TeamMergeRequestReminderShownToPrimaryTeamDetails val:
        :rtype: EventDetails
        """
    return cls('team_merge_request_reminder_shown_to_primary_team_details', val
        )


def CopyAttributes(newArt, oldArt):
    """
    Copies pens, brushes, colours and fonts from the old tab art to the new one.

    :param `newArt`: the new instance of :class:`~wx.lib.agw.aui.tabart.AuiDefaultTabArt`;
    :param `oldArt`: the old instance of :class:`~wx.lib.agw.aui.tabart.AuiDefaultTabArt`.
    """
    attrs = dir(oldArt)
    for attr in attrs:
        if attr.startswith('_') and (attr.endswith('_colour') or attr.
            endswith('_font') or attr.endswith('_font') or attr.endswith(
            '_brush') or attr.endswith('Pen') or attr.endswith('_pen')):
            setattr(newArt, attr, getattr(oldArt, attr))
    return newArt


def cmd_across_all_procs(hap_objects, method, *arg, **kargs):
    """Return the result of a command executed in all HAProxy process.

    .. note::
        Objects must have a property with the name 'process_nb' which
        returns the HAProxy process number.

    :param hap_objects: a list of objects.
    :type hap_objects: ``list``
    :param method: a valid method for the objects.
    :return: list of 2-item tuple

      #. HAProxy process number
      #. what the method returned

    :rtype: ``list``
    """
    results = []
    for obj in hap_objects:
        results.append((getattr(obj, 'process_nb'), getattr(obj, method)(*
            arg, **kargs)))
    return results


def cumdiff(yin):
    """ compute the cumulative mean normalized difference """
    W = len(yin)
    yin[0] = 1.0
    cumsum = 0.0
    for tau in range(1, W):
        cumsum += yin[tau]
        if cumsum != 0:
            yin[tau] *= tau / cumsum
        else:
            yin[tau] = 1
    return yin


def list_deployment_groups(applicationName=None, nextToken=None):
    """
    Lists the deployment groups for an application registered with the applicable IAM user or AWS account.
    See also: AWS API Documentation

    :example: response = client.list_deployment_groups(
        applicationName='string',
        nextToken='string'
    )

    :type applicationName: string
    :param applicationName: [REQUIRED]
            The name of an AWS CodeDeploy application associated with the applicable IAM user or AWS account.

    :type nextToken: string
    :param nextToken: An identifier returned from the previous list deployment groups call. It can be used to return the next set of deployment groups in the list.

    :rtype: dict
    :return: {
        'applicationName': 'string',
        'deploymentGroups': [
            'string',
        ],
        'nextToken': 'string'
    }

    :returns:
    (string) --

    """
    pass


def Blasius(Re):
    """Calculates Darcy friction factor according to the Blasius formulation,
    originally presented in [1]_ and described more recently in [2]_.

    .. math::
        f_d=\\frac{0.3164}{Re^{0.25}}

    Parameters
    ----------
    Re : float
        Reynolds number, [-]

    Returns
    -------
    fd : float
        Darcy friction factor [-]

    Notes
    -----
    Developed for 3000 < Re < 200000.

    Examples
    --------
    >>> Blasius(10000)
    0.03164

    References
    ----------
    .. [1] Blasius, H."Das Aehnlichkeitsgesetz bei Reibungsvorgängen in
       Flüssigkeiten." In Mitteilungen über Forschungsarbeiten auf dem Gebiete
       des Ingenieurwesens, edited by Verein deutscher Ingenieure, 1-41.
       Berlin, Heidelberg: Springer Berlin Heidelberg, 1913.
       http://rd.springer.com/chapter/10.1007/978-3-662-02239-9_1.
    .. [2] Hager, W. H. "Blasius: A Life in Research and Education." In
       Experiments in Fluids, 566–571, 2003.
    """
    return 0.3164 * Re ** -0.25


def __call__():
    """Return JSON compatible python data."""


def transitions(trj, nsteps=1, lag_time=1, separator='0'):
    """
    Return the temporal list of transitions observed.

    Parameters
    ----------
    trj : the symbolic trajectory.
    nsteps : number of steps.
    lag_time : step length.
    separator: the special symbol indicating the presence of sub-trajectories.

    Example
    -------
    >>> trj = [1,2,1,0,2,3,1,0,2,3,2,3,1,2,3]
    >>> pykov.transitions(trj,1,1,0)
    [(1, 2), (2, 1), (2, 3), (3, 1), (2, 3), (3, 2), (2, 3), (3, 1), (1, 2),
    (2, 3)]
    >>> pykov.transitions(trj,1,2,0)
    [(1, 1), (2, 1), (2, 2), (3, 3), (2, 1), (3, 2), (1, 3)]
    >>> pykov.transitions(trj,2,2,0)
    [(2, 2, 1), (3, 3, 2), (2, 1, 3)]
    """
    result = []
    for pos in range(len(trj) - nsteps * lag_time):
        if separator not in trj[pos:pos + nsteps * lag_time + 1]:
            tmp = trj[pos:pos + nsteps * lag_time + 1:lag_time]
            result.append(tuple(tmp))
    return result


def smaller(var1, var_name1, var2, var_name2):
    """
    Check if *var1* smaller than *var2*.

    :raises ValueError: Parameter *var1* must be smaller than *var2*.
    """
    if var1 >= var2:
        raise ValueError('\n\n{} must be smaller than {}.\n'.format(
            var_name1, var_name2))


def create_response(request_class_name, *args):
    """Create a ResponsePaket instance from a RequestPaket class name."""
    name = request_class_name[:-len('Request')]
    ResponsePaket = globals()['{}Response'.format(name)]
    return ResponsePaket(*args)


def __new__(mcs, class_name, bases, attributes):
    """Domain model class factory."""
    model_fields = mcs.parse_fields(attributes)
    if attributes.get('__slots_optimization__', True):
        attributes['__slots__'] = mcs.prepare_model_slots(model_fields)
    cls = type.__new__(mcs, class_name, bases, attributes)
    cls.__fields__ = mcs.bind_fields_to_model_cls(cls, model_fields)
    cls.__unique_key__ = mcs.prepare_fields_attribute(attribute_name=
        '__unique_key__', attributes=attributes, class_name=class_name)
    cls.__view_key__ = mcs.prepare_fields_attribute(attribute_name=
        '__view_key__', attributes=attributes, class_name=class_name)
    mcs.bind_collection_to_model_cls(cls)
    return cls


def setup_vprint(args):
    """
    Defines the function vprint, which only prints when --verbose is set
    """
    global vprint
    vprint = print if args.verbose else lambda *a, **k: None


@classmethod
def from_xml_node(cls, xml_node):
    """
        Initialize the object from a XML node.
        :param xml_node: The XML node from which all necessary parameters will be parsed.
        :type xml_node: xml.etree.Element
        """
    raise NotImplementedError(
        'from_xml_node must be implemented by derived classes.')


def print_preprocessing_list(preprocessing_queue):
    """
    Print the ``preproc_list`` in a human-readable form.

    Parameters
    ----------
    preprocessing_queue : list of preprocessing objects
        Algorithms that get applied for preprocessing.
    """
    print('## Preprocessing')
    print('```')
    for algorithm in preprocessing_queue:
        print('* ' + str(algorithm))
    print('```')


def in_dict(obj, key, default=False):
    """
    Returns true if key exists in obj.__dict__; false if not in.
    If obj.__dict__ is absent, return default
    """
    return key in obj.__dict__ if getattr(obj, '__dict__', None) else default


def hide(unselected: bool=False):
    """Hide selected/unselected Grease Pencil layers

    :param unselected: Unselected, Hide unselected rather than selected layers
    :type unselected: bool
    """
    pass


def noop(*args, **kwargs):
    """
    No-Op validator that does nothing.
    """
    pass


def load_toml(path):
    """
    Load a file in TOML format.

    :param Path path: Path to the TOML file.

    :return: A dictionary with the parsed content.
    :rtype: dict
    """
    from toml import loads
    return loads(path.read_text(encoding='utf-8'))


@staticmethod
def normalize_kvp(kvp):
    """Normalize Key Value Pairs.

        This method will transform all keys to lowercase and leave values
        unchanged, as specified in the CSW standard (see for example note
        C on Table 62 - KVP Encoding for DescribeRecord operation request
        of the CSW standard version 2.0.2)

        :arg kvp: a mapping with Key Value Pairs
        :type kvp: dict
        :returns: A new dictionary with normalized parameters
        """
    result = dict()
    for name, value in kvp.items():
        result[name.lower()] = value
    return result


@staticmethod
def _determine_which_routers_were_used(placement, fixed_routes, machine):
    """ Traverse the fixed route paths from a given location to its            destination. Used for determining which routers were used.

        :param placement: the source to start from
        :param fixed_routes: the fixed routes for each router
        :param machine: the spinnMachine instance
        :return: list of chip IDs
        """
    routers = list()
    routers.append((placement.x, placement.y))
    entry = fixed_routes[placement.x, placement.y]
    chip_x = placement.x
    chip_y = placement.y
    while len(entry.processor_ids) == 0:
        machine_link = machine.get_chip_at(chip_x, chip_y).router.get_link(next
            (iter(entry.link_ids)))
        chip_x = machine_link.destination_x
        chip_y = machine_link.destination_y
        routers.append((chip_x, chip_y))
        entry = fixed_routes[chip_x, chip_y]
    return routers


def _instance_changed(sender, instance, **kwargs):
    """
    Queues an update to the ElasticSearch index.
    """
    from rest_search import queue_add
    doc_type = instance.__class__.__name__
    queue_add({doc_type: [instance.pk]})


def _fft_multiply_repeated(x, cuda_dict):
    """Do FFT multiplication by a filter function (possibly using CUDA).

    Parameters
    ----------
    h_fft : 1-d array or gpuarray
        The filtering array to apply.
    x : 1-d array
        The array to filter.
    n_fft : int
        The number of points in the FFT.
    cuda_dict : dict
        Dictionary constructed using setup_cuda_multiply_repeated().

    Returns
    -------
    x : 1-d array
        Filtered version of x.
    """
    x_fft = cuda_dict['rfft'](x, cuda_dict['n_fft'])
    x_fft *= cuda_dict['h_fft']
    x = cuda_dict['irfft'](x_fft, cuda_dict['n_fft'])
    return x


def iterate_scan(connection, scan):
    """
    Make as many :class:`.Scan` actions as needed to iterate over all matching items.
    That is until :attr:`.ScanResponse.last_evaluated_key` is ``None``.

    >>> for item in iterate_scan(connection, Scan(table)):
    ...   print item
    {u'a': 0, u'h': 7}
    {u'a': 0, u'h': 8}
    {u'h': 3, u'gr': 4, u'gh': 9}
    {u'h': 2, u'gr': 6, u'gh': 4}
    {u'a': 0, u'h': 9}
    {u'h': 4, u'gr': 2, u'gh': 16}
    {u'h': 6, u'gr': -2, u'gh': 36}
    {u'h': 1, u'gr': 8, u'gh': 1}
    {u'h': 0, u'gr': 10, u'gh': 0}
    {u'h': 5, u'gr': 0, u'gh': 25}

    The :class:`.Scan` instance passed in must be discarded (it is modified during the iteration).
    """
    r = connection(scan)
    for item in r.items:
        yield item
    while r.last_evaluated_key is not None:
        scan.exclusive_start_key(r.last_evaluated_key)
        r = connection(scan)
        for item in r.items:
            yield item


def beam_energy(event):
    """
    Gets the beam energy for a data event retrieved from the filesystem.

    Files written by detectors don't usually contain beam energy information. This
    function takes the beam energy value from the configuration file, specifically from
    the 'fallback_beam_energy_in_eV' entry in the 'DataRetrievalLayer' parameter group.

    Arguments:

        event (:class:`~onda.utils.data_event.DataEvent`): an object storing the event
            data.

    Returns:

        float: the energy of the beam in eV.
    """
    return event.framework_info['beam_energy']


def get(cls, name):
    """Get a registered task function for a given name."""
    try:
        task_func = cls._registry[name]
    except KeyError:
        raise ValueError('{} not found in registry for {}'.format(name, cls
            .__name__))
    else:
        return task_func


def split_first(s, delims):
    """
    Given a string and an iterable of delimiters, split on the first found
    delimiter. Return two split parts and the matched delimiter.

    If not found, then the first part is the full input string.

    Example::

        >>> split_first('foo/bar?baz', '?/=')
        ('foo', 'bar?baz', '/')
        >>> split_first('foo/bar?baz', '123')
        ('foo/bar?baz', '', None)

    Scales linearly with number of delims. Not ideal for large number of delims.
    """
    min_idx = None
    min_delim = None
    for d in delims:
        idx = s.find(d)
        if idx < 0:
            continue
        if min_idx is None or idx < min_idx:
            min_idx = idx
            min_delim = d
    if min_idx is None or min_idx < 0:
        return s, '', None
    return s[:min_idx], s[min_idx + 1:], min_delim


def chk_save_location(location):
    """
    Prompt user to save location for quick re-use
    """
    from x84.bbs import getterminal, getsession, echo
    session, term = getsession(), getterminal()
    stored_location = session.user.get('location', dict()).items()
    if sorted(location.items()) == sorted(stored_location):
        return False
    if session.user.handle == 'anonymous':
        return False
    echo(u'\r\n\r\n')
    echo(term.yellow(u'Save Location'))
    echo(term.bold_yellow(u' ('))
    echo(term.bold_black(u'private'))
    echo(term.bold_yellow(u') '))
    echo(term.yellow(u'? '))
    echo(term.bold_yellow(u'['))
    echo(term.underline_yellow(u'yn'))
    echo(term.bold_yellow(u']'))
    echo(u': ')
    while True:
        inp = term.inkey()
        if inp.code == term.KEY_EXIT or inp.lower() in (u'n', 'q'):
            break
        elif inp.code == term.KEY_ENTER or inp.lower() in (u'y', u' '):
            session.user['location'] = location
            break


def distance_dst(speed, time):
    """Usage: distance_dst(speed of object, time taken to get there)"""
    return speed * time


@classmethod
def get_document_id(cls, document: dict) ->str:
    """Get id under which the given document will be stored."""
    return document['inspection_id']


def _build_payment_code_notebook_60(sender, reference_number,
    payment_identification, quantity):
    """ Payment code is calculated concatenating 6 values:

        - A constant that represents this payment mode: '90521'
        - A 6 digit sender code: '123456'
        - A 12 digit reference number: '123456789012'
        - A 10 digit payment identification number: '1234567890'
        - A 8 digit value representing the number of euro cents to
            be payed: '0000001000'
        - A constant value: '0'
    """
    return (
        '90521{sender:0>6}{reference_number:0>12}{payment_identification:0>10}{quantity:0>8}0'
        .format(sender=sender, reference_number=reference_number,
        payment_identification=payment_identification, quantity=quantity))


def _view_corrector(view):
    """ Returns s or l depending on value passed by user

    :param view: (str)	User-passed view of summary
    :return str:
    """
    if view == 'short' or view == 's' or view == 'S':
        view = 's'
    elif view == 'long' or view == 'l' or view == 'L':
        view = 'l'
    else:
        print('Summary type not found, default to short')
        view = 's'
    return view


def build_simple_seq_string(concatamer):
    """

    Simple function to simplify concatamer sequence to string

    Parameters
    ----------
    concatamer_col : str
        Contacamer string, which is in the form [K].MWGRSTLLYSRX.[L]

    Returns
    -------
    seq : str
        Simplified sequence.

    """
    return concatamer.split('.')[1]


def _total_seconds(timedelta):
    """Python 2.6 does not support timedelta.total_seconds() or timedelta/timedelta"""
    return float(timedelta.microseconds + (timedelta.seconds + timedelta.
        days * 24 * 3600) * 10 ** 6) / 10 ** 6


def is_chat(message):
    """
    Checks that message has chat message.
    Return (from, to) or None.
    """
    try:
        if message['action'] == 'chat':
            return message['from'], message['to']
    except Exception:
        pass
    return None


def update_rep(rep: str) ->str:
    """ If rep is None, return rep as mat, which refers to the whole expression matrix
    """
    return rep if rep is not None else 'mat'


def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy."""
    z = x.copy()
    z.update(y)
    return z