def show(startscript, command='main'):
    """
    Main function for showing help texts.
    """
    if command == '':
        command = 'main'
    index = dict()
    main_txt = (
        """
Usage:
  {0} <command> [options]

Commands:
  config           Start the configuration.
  add              Add a new entry to wallabag.
  delete           Delete an entry.
  list             List the entries on the wallabag account.
  show             Show an entry.
  update           Change the read- or starred-status of an existing entry
                   or change the title.
  read             Toggle the read-status of an entry.
  star             Toggle the starred-status of an entry.

General Options:
  -h, --help       Show help.
  --config=<path>  Use a custom config file.
  --about          Show about information.
  -v, --version    Show version No.

Use "{0} <command> --help" for further information.
And don't forget to be excellent to each other!
"""
        .format(startscript))
    index['main'] = main_txt
    config_txt = (
        """
Usage:
  {0} config [options]

Description:
  Start the configuration.

Options:
  -h, --help       Show help.
  -c, --check      Check the config for errors.
  -p, --password   Change the wallabag password.
  -o, --oauth      Change the wallabag client credentials.
  --config=<path>  Use a custom config file.
"""
        .format(startscript))
    index['config'] = config_txt
    add_txt = (
        """
Usage:
  {0} add [options] <url>

Description:
  Add a new link to wallabag.

Options:
  -h, --help           Show help.
  -t, --title <title>  Add a custom title.
  -s, --starred        Mark as starred.
  -r, --read           Mark as read.
  -q, --quiet          Hide the output if no error occurs.
  --config=<path>      Use a custom config file.
"""
        .format(startscript))
    index['add'] = add_txt
    delete_txt = (
        """
Usage:
  {0} delete [options] <entry-id>

Description:
  Delete an entry from wallabag.
  The entry-id can be found in "{0} list" for example.

Options:
  -h, --help       Show help.
  -f, --force      Do not ask before deletion.
  -q, --quiet      Hide the output if no error occurs.
  --config=<path>  Use a custom config file.
"""
        .format(startscript))
    index['delete'] = delete_txt
    list_txt = (
        """
Usage:
  {0} list [options]

Description:
  Gives a summary of entries in wallabag. Use options to filter the results.

Options:
  -h, --help                     Show help.
  -q, --quantity <"all"|number>  Set the number of entries to show.
  --unread                       Show only unread entries (default).
  -r, --read                     Show only read entries.
  -a, --all                      Show read as well as unread entries.
  -s, --starred                  Show only starred entries.
  -u, --unstarred                Show only unstarred entries.
  -o, --oldest                   Show oldest matches instead of the newest.
  -f, --full                     Do not trim the titles to fit the length
                                 of the cli.
  -c, --count                    Show a sum of matching entries.
  --config=<path>                Use a custom config file.
"""
        .format(startscript))
    index['list'] = list_txt
    show_txt = (
        """
Usage:
  {0} show [options] <entry-id>

Description:
  Show the text of an entry.
  The entry-id can be found in "{0} list" for example.

Options:
  -h, --help       Show help.
  -r, --raw        Disable wordwise trimming.
  --no-color       Disable colored output.
  --html           Show the entry as html instead of optimized output for
                   the cli.
  --config=<path>  Use a custom config file.
"""
        .format(startscript))
    index['show'] = show_txt
    update_txt = (
        """
Usage:
  {0} update [options] <entry-id>

Description:
  Toggle the read- or starred status or change the title of an existing entry.
  The entry-id can be found in "{0} list" for example.

Options:
  -h, --help             Show help.
  -r, --read             Toggle the read-status.
  -s, --starred          Toggle the starred-status.
  -t, --title <"title">  Change the title.
  -q, --quiet            Hide the output if no error occurs.
  --config=<path>        Use a custom config file.
"""
        .format(startscript))
    index['update'] = update_txt
    read_txt = (
        """
Usage:
  {0} read [options] <entry-id>

Description:
  Toggle the read-status of an existing entry.
  This is an alias for "{0} update --read <entry-id>".
  The entry-id can be found in "{0} list" for example.

Options:
  -h, --help       Show help.
  -q, --quiet      Hide the output if no error occurs.
  --config=<path>  Use a custom config file.
"""
        .format(startscript))
    index['read'] = read_txt
    star_txt = (
        """
Usage:
  {0} star [options] <entry-id>

Description:
  Toggle the starred-status of an existing entry.
  This is an alias for "{0} update --starred <entry-id>".
  The entry-id can be found in "{0} list" for example.

Options:
  -h, --help       Show help.
  -q, --quiet      Hide the output if no error occurs.
  --config=<path>  Use a custom config file.
"""
        .format(startscript))
    index['star'] = star_txt
    if not command in index:
        print('Error: Invalid command "{0}"!'.format(command))
        command = 'main'
    print(index[command])


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 with_metaclass(meta, base=object):
    """Create a base class with a metaclass."""
    return meta('NewBase', (base,), {})


def join_uuid(namespace_uuid, item_uuid):
    """
    Join an instance UUID and an item UUID to one single string.
    :param namespace_uuid: String containing UUID for namespace.
    :param item_uuid: String containing UUID for item.
    :return: String with joined UUID.
    """
    return '.'.join((namespace_uuid, item_uuid))


@staticmethod
def get_saved_game():
    """ Returns the last saved game """


def constant_time_compare(val1, val2):
    """
    Returns True if the two strings are equal, False otherwise.

    The time taken is independent of the number of characters that match.

    For the sake of simplicity, this function executes in constant time only
    when the two strings have the same length. It short-circuits when they
    have different lengths.
    """
    if len(val1) != len(val2):
        return False
    result = 0
    if isinstance(val1, bytes) and isinstance(val2, bytes):
        for x, y in zip(val1, val2):
            result |= x ^ y
    else:
        for x, y in zip(val1, val2):
            result |= ord(x) ^ ord(y)
    return result == 0


@classmethod
def to_path_comps(cls, *path_comps):
    """The one returned by CPath.path_comps"""
    ccomps = cls.to_cpath_ccomps(*path_comps)
    if len(ccomps) > 1 and ccomps[-1] == '':
        ccomps = ccomps[:-1]
    if len(ccomps) > 1 and ccomps[0] == '':
        ccomps = ccomps[1:]
    comps = ccomps
    return comps


def trimna(obj):
    """Drop values across all dimensions for which all values are NaN.
    """
    trimmed_obj = obj.copy()
    for d in obj.dims:
        trimmed_obj = trimmed_obj.dropna(d, how='all')
    return trimmed_obj


def string_to_dict_list(dictionary_str_rep):
    """
    Convert string representation of dictionary/list to dictionary/list

    Parameters
    ----------
    dictionary_str_rep: str
        '[]'

    Examples
    --------
    >>> input = ""
    >>> string_to_dict_list(input)
    Traceback (most recent call last):
      ...
    SyntaxError: unexpected EOF while parsing

    >>> input = 0
    >>> string_to_dict_list(input)

    >>> input = []
    >>> string_to_dict_list(input)

    >>> input = {}
    >>> string_to_dict_list(input)

    >>> input = "[1, 2, 3]"
    >>> string_to_dict_list(input)
    [1, 2, 3]

    >>> input = "[]"
    >>> string_to_dict_list(input)
    []

    >>> input = "['1', '2', '3']"
    >>> string_to_dict_list(input)
    ['1', '2', '3']

    >>> input = "{'a': 1, 'b': 2}"
    >>> string_to_dict_list(input)
    {'a': 1, 'b': 2}

    >>> input = "{'a': '1', 'b': '2'}"
    >>> string_to_dict_list(input)
    {'a': '1', 'b': '2'}

    Returns
    -------
    dict / list
        Dictionary / List instead of string representation
    """
    dict_list = None
    if isinstance(dictionary_str_rep, str):
        from ast import literal_eval
        dict_list = literal_eval(dictionary_str_rep)
    return dict_list


def convert_to_bool(x) ->bool:
    """Convert string 'true' to bool."""
    return x == 'true'


def quotient(x, y):
    """
    Returns floor(x/y), the number of times y evenly divides into x.

    Args:
        x: dividend.
        y: divisor.

    Returns:
        int: integer quotient of x/y

    """
    return x // y


def copy_header_subset(from_r, to_r, condition):
    """
    Will copy desired subset of headers from from_r to to_r.

    :param from_r: a swob Request or Response
    :param to_r: a swob Request or Response
    :param condition: a function that will be passed the header key as a
                      single argument and should return True if the header
                      is to be copied.
    """
    for k, v in from_r.headers.items():
        if condition(k):
            to_r.headers[k] = v


def _set_separator(ticklabels, separator):
    """
    Set the decimal separator. Note that this is a 'private' function, so
    you can set the decimal separator directly in plotting functions.
    """
    if separator == '.':
        bands_sep = ticklabels
    else:
        bands_sep = []
        for item in ticklabels:
            decimal_number_format = item.replace('.', separator)
            bands_sep.append(decimal_number_format)
    return bands_sep


def world_to_basis(active, ob, context):
    """put world coords of active as basis coords of ob"""
    local = ob.parent.matrix_world.inverted() * active.matrix_world
    P = ob.matrix_basis * ob.matrix_local.inverted()
    mat = P * local
    return mat


@classmethod
def from_local(cls, result):
    """Convert from local statvfs attributes"""
    return cls(result.f_bsize, result.f_frsize, result.f_blocks, result.
        f_bfree, result.f_bavail, result.f_files, result.f_ffree, result.
        f_favail, 0, result.f_flag, result.f_namemax)


def chunk_of_lines(fp, filesize, blocksize, block):
    """
    return a generator of the lines coming from a single chunk of the file
    """
    ini = block * blocksize
    end = ini + blocksize
    if ini > filesize:
        return
    if end > filesize:
        end = filesize
    if ini <= 0:
        fp.seek(0)
    else:
        fp.seek(ini - 1)
        fp.readline()
    while fp.tell() < end:
        yield fp.readline()


def pytest_addoption(parser):
    """Add the '--reorder' argument to the py.test invocation."""
    group = parser.getgroup('tests reordering', 'reordering', after='general')
    group.addoption('--reorder', type=str, nargs='*', help=
        """A list of regular expressions matching test nodeids and one '*' to specify the order of unmatched tests. The tests will be reordered according to these specs. If no arguments are passed, default ordering will be applied (unit tests, unmatched tests, integration tests, ui tests).
E.g. `--reorder "(^|.*/)(test_)?unit" "*" "(^|.*/)(test_)?db" "(^|.*/)(test_)?web"`."""
        )


def stringify(code):
    """
    Helper function to prepare multiline strings (potentially including
    quotation marks) to be included in strings.

    Parameters
    ----------
    code : str
        The code to convert.
    """
    code = code.replace('\n', '\\n\\\n')
    code = code.replace('"', '\\"')
    return code


def userv(event, server, view):
    """ This method is called everytime some data comes from the irc server.
        There is a regex meaning it in the stdevent.txt
    """
    data = event['data']
    packet = '%s\n' % data
    win = view.get_win(server.getName())
    win.update_screen(packet)


def getone(key):
    """ Get one value matching the key, raising a KeyError if multiple
        values were found. """


def compareHeaderValues(imgHDU1, imgHDU2, verbose):
    """
    Compare the headers of the two input fits files.

    :param imgHDU1: name of first fits file to compare
    :param imgHDU2: name of second fits file to compare
    :param verbose: Print verbose output to screen?
    :type imgHDU1: astropy.io.fits.hdu.hdulist.HDUList class
    :type imgHDU2: astropy.io.fits.hdu.hdulist.HDUList class
    :type verbose: Boolean
    :return: Logical 'True' if everything is ok, and logical 'False' if dissimilarities are found.
    """
    if verbose:
        print('> > > > > COMPARE HEADERS < < < < <')
    out_list = []
    exclude_list = ['DATE', 'IRAF-TLM']
    for ext_num in range(0, len(imgHDU1)):
        hdr_list1 = list(imgHDU1[ext_num].header.keys())
        hdr_list2 = list(imgHDU2[ext_num].header.keys())
        for hdr_title in hdr_list1:
            if hdr_title != 'HISTORY' and exclude_list.count(hdr_title
                ) == 0 and len(hdr_title) != 0:
                try:
                    hdr_value1 = imgHDU1[ext_num].header[hdr_title]
                except:
                    hdr_value1 = '--MISSING--'
                try:
                    hdr_value2 = imgHDU2[ext_num].header[hdr_title]
                except:
                    hdr_value2 = '--MISSING--'
                if hdr_value1 != hdr_value2:
                    out_list.append('[%s] %s: %s %s' % (str(ext_num),
                        hdr_title, hdr_value1, hdr_value2))
    returnValue = True
    if len(out_list) > 0:
        returnValue = False
        if verbose:
            for item in out_list:
                print(item)
    if returnValue:
        if verbose:
            print('OK')
    if verbose:
        print()
    return returnValue


def project_apply():
    """Project edited image back onto the object

    """
    pass


def hex2rgb(h):
    """
    Convert hex colors to RGB tuples

    Parameters
    ----------
    h : str
        String hex color value

    >>> hex2rgb("#ff0033")
    '255,0,51'
    """
    if not h.startswith('#') or len(h) != 7:
        raise ValueError("Does not look like a hex color: '{0}'".format(h))
    return ','.join(map(str, (int(h[1:3], 16), int(h[3:5], 16), int(h[5:7],
        16))))


def gpencil_modifier_remove(modifier: str=''):
    """Remove a modifier from the active grease pencil object

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


def in_hm3(var):
    """
    Return whether the variant was part of HapMap3
    """
    return var.INFO.get('H3')


def _trim(data, endDt):
    """Removes datetime-value pairs >= endDt to the precision of one month."""
    index = 0
    for i, line in enumerate(data):
        if line[0].month == endDt.month and line[0].year == endDt.year:
            index = i
            break
    return data[0:i]


def pair2index(i, j):
    """Convenience function to get an item pair's variable index."""
    i, j = min(i, j), max(i, j)
    return j * (j - 1) // 2 + i


def attach_elastic_load_balancer(ElasticLoadBalancerName=None, LayerId=None):
    """
    Attaches an Elastic Load Balancing load balancer to a specified layer. For more information, see Elastic Load Balancing .
    See also: AWS API Documentation

    :example: response = client.attach_elastic_load_balancer(
        ElasticLoadBalancerName='string',
        LayerId='string'
    )

    :type ElasticLoadBalancerName: string
    :param ElasticLoadBalancerName: [REQUIRED]
            The Elastic Load Balancing instance's name.

    :type LayerId: string
    :param LayerId: [REQUIRED]
            The ID of the layer that the Elastic Load Balancing instance is to be attached to.

    """
    pass


def parse_locale(identifier, sep='_'):
    """Parse a locale identifier into a tuple of the form ``(language,
    territory, script, variant)``.

    >>> parse_locale('zh_CN')
    ('zh', 'CN', None, None)
    >>> parse_locale('zh_Hans_CN')
    ('zh', 'CN', 'Hans', None)

    The default component separator is "_", but a different separator can be
    specified using the `sep` parameter:

    >>> parse_locale('zh-CN', sep='-')
    ('zh', 'CN', None, None)

    If the identifier cannot be parsed into a locale, a `ValueError` exception
    is raised:

    >>> parse_locale('not_a_LOCALE_String')
    Traceback (most recent call last):
      ...
    ValueError: 'not_a_LOCALE_String' is not a valid locale identifier

    Encoding information and locale modifiers are removed from the identifier:

    >>> parse_locale('it_IT@euro')
    ('it', 'IT', None, None)
    >>> parse_locale('en_US.UTF-8')
    ('en', 'US', None, None)
    >>> parse_locale('de_DE.iso885915@euro')
    ('de', 'DE', None, None)

    See :rfc:`4646` for more information.

    :param identifier: the locale identifier string
    :param sep: character that separates the different components of the locale
                identifier
    :raise `ValueError`: if the string does not appear to be a valid locale
                         identifier
    """
    if '.' in identifier:
        identifier = identifier.split('.', 1)[0]
    if '@' in identifier:
        identifier = identifier.split('@', 1)[0]
    parts = identifier.split(sep)
    lang = parts.pop(0).lower()
    if not lang.isalpha():
        raise ValueError('expected only letters, got %r' % lang)
    script = territory = variant = None
    if parts:
        if len(parts[0]) == 4 and parts[0].isalpha():
            script = parts.pop(0).title()
    if parts:
        if len(parts[0]) == 2 and parts[0].isalpha():
            territory = parts.pop(0).upper()
        elif len(parts[0]) == 3 and parts[0].isdigit():
            territory = parts.pop(0)
    if parts:
        if len(parts[0]) == 4 and parts[0][0].isdigit() or len(parts[0]
            ) >= 5 and parts[0][0].isalpha():
            variant = parts.pop()
    if parts:
        raise ValueError('%r is not a valid locale identifier' % identifier)
    return lang, territory, script, variant


@staticmethod
def pack_subitems(value):
    """
        Creates output that can be used to query for a list of inputs
        """
    return None


def run_simulation(network_model, sim, parameters, input_queue, output_queue):
    """
    Build the model defined in the class `network_model`, with parameters
    `parameters`, and then consume tasks from `input_queue` until receiving the
    command 'STOP'.
    """
    print('Running simulation with %s' % sim.__name__)
    network = network_model(sim, parameters)
    print('Network constructed with %s.' % sim.__name__)
    for obj_name, attr, args, kwargs in iter(input_queue.get, 'STOP'):
        print('%s processing command %s.%s(%s, %s)' % (sim.__name__,
            obj_name, attr, args, kwargs))
        obj = eval(obj_name)
        result = getattr(obj, attr)(*args, **kwargs)
        output_queue.put(result)
    print('Simulation with %s complete' % sim.__name__)


@classmethod
def fromstring(cls, content):
    """Creates a parser from content of log.

        :param str content: The log content.
        :return: The parser instance.
        """
    return cls(content.strip().split(cls.line_separator))


def date_to_ISO_string(aDate):
    """ Take a datetime and convert to string of the form YYYY-MM-DD
    """
    return aDate.strftime('%Y-%m-%d')


def f_to_d(f, s):
    """
    Converts frequency bins to distance bins based on ADC settings.

    :param f: Frequency bins
    :param s: Settings dictionary
    :return: Distance bins
    """
    return s['c'] * f / (2 * (s['bw'] / s['t_sweep']))


def format_context(text, data):
    """replace custom templating by something compliant with python format function"""
    text = text.replace('{', '{{').replace('}', '}}')
    text = text.replace('#!-', '{').replace('-!#', '}')
    return text.format(**data)


def batch_size(y_true, y_pred):
    """Count the number of items in the current batch."""
    return y_true.shape[0]


def cut():
    """Cut selected text to clipboard

    """
    pass


@staticmethod
def p_daq_list_can_id_type_fixed(p):
    """daq_list_can_id_type_fixed : FIXED NUMERIC"""
    p[0] = p[2]


def batch_get_deployment_instances(deploymentId=None, instanceIds=None):
    """
    Gets information about one or more instance that are part of a deployment group.
    See also: AWS API Documentation

    :example: response = client.batch_get_deployment_instances(
        deploymentId='string',
        instanceIds=[
            'string',
        ]
    )

    :type deploymentId: string
    :param deploymentId: [REQUIRED]
            The unique ID of a deployment.

    :type instanceIds: list
    :param instanceIds: [REQUIRED]
            The unique IDs of instances in the deployment group.
            (string) --

    :rtype: dict
    :return: {
        'instancesSummary': [
            {
                'deploymentId': 'string',
                'instanceId': 'string',
                'status': 'Pending'|'InProgress'|'Succeeded'|'Failed'|'Skipped'|'Unknown'|'Ready',
                'lastUpdatedAt': datetime(2015, 1, 1),
                'lifecycleEvents': [
                    {
                        'lifecycleEventName': 'string',
                        'diagnostics': {
                            'errorCode': 'Success'|'ScriptMissing'|'ScriptNotExecutable'|'ScriptTimedOut'|'ScriptFailed'|'UnknownError',
                            'scriptName': 'string',
                            'message': 'string',
                            'logTail': 'string'
                        },
                        'startTime': datetime(2015, 1, 1),
                        'endTime': datetime(2015, 1, 1),
                        'status': 'Pending'|'InProgress'|'Succeeded'|'Failed'|'Skipped'|'Unknown'
                    },
                ],
                'instanceType': 'Blue'|'Green'
            },
        ],
        'errorMessage': 'string'
    }

    :returns:
    Pending: The deployment is pending for this instance.
    In Progress: The deployment is in progress for this instance.
    Succeeded: The deployment has succeeded for this instance.
    Failed: The deployment has failed for this instance.
    Skipped: The deployment has been skipped for this instance.
    Unknown: The deployment status is unknown for this instance.

    """
    pass


def recv_all(sock):
    """Receive data until connection is closed."""
    data = b''
    while True:
        chunk = sock.recv(1024)
        if not chunk:
            break
        data += chunk
    return data


def get_alignment_character(alignment: str) ->str:
    """ Returns an alignment character for string formatting """
    if alignment in ['left', 'l']:
        return ''
    elif alignment in ['right', 'r']:
        return '>'
    elif alignment in ['center', 'c']:
        return '^'
    return ''


def get_dtype_import_dict():
    """
    Dtype of the file to import.

    Arguments:
    None

    Return:
    Dtype dict
    """
    dtype_import = {}
    dtype_import['CTER v1.0'] = [('defocus', '<f8'), ('cs', '<f8'), ('volt',
        '<f8'), ('apix', '<f8'), ('bfac', '<f8'), ('amplitude_contrast',
        '<f8'), ('astigmatism_amplitude', '<f8'), ('astigmatism_angle',
        '<f8'), ('standard_deviation_defocus', '<f8'), (
        'standard_deviation_amplitude_contrast', '<f8'), (
        'standard_deviation_astigmatism_amplitude', '<f8'), (
        'standard_deviation_astigmatism_angle', '<f8'), (
        'coefficient_of_variation_of_defocus', '<f8'), (
        'coefficient_of_astigmatism_amplitude', '<f8'), ('limit_defocus',
        '<f8'), ('limit_defocus_and_astigmatism', '<f8'), (
        'limit_pixel_error', '<f8'), ('limit_maximum', '<f8'), (
        'reserved_spot', '<f8'), ('const_amplitude_contrast', '<f8'), (
        'phase_shift', '<f8'), ('file_name', '|U1200')]
    dtype_import['Gctf v1.06'] = [('defocus_1', '<f8'), ('defocus_2', '<f8'
        ), ('astigmatism', '<f8'), ('phase_shift', '<f8'), ('cross_corr',
        '<f8'), ('limit', '<f8')]
    dtype_import['Gctf v1.18'] = [('defocus_1', '<f8'), ('defocus_2', '<f8'
        ), ('astigmatism', '<f8'), ('phase_shift', '<f8'), ('cross_corr',
        '<f8'), ('limit', '<f8')]
    dtype_import['CTFFIND4 v4.1.10'] = [('mic_number', '<f8'), ('defocus_1',
        '<f8'), ('defocus_2', '<f8'), ('astigmatism', '<f8'), (
        'phase_shift', '<f8'), ('cross_corr', '<f8'), ('limit', '<f8')]
    dtype_import['CTFFIND4 v4.1.8'] = [('mic_number', '<f8'), ('defocus_1',
        '<f8'), ('defocus_2', '<f8'), ('astigmatism', '<f8'), (
        'phase_shift', '<f8'), ('cross_corr', '<f8'), ('limit', '<f8')]
    dtype_import['MotionCor2 v1.0.0'] = [('frame_number', '<f8'), (
        'shift_x', '<f8'), ('shift_y', '<f8')]
    dtype_import['MotionCor2 v1.0.5'] = [('frame_number', '<f8'), (
        'shift_x', '<f8'), ('shift_y', '<f8')]
    dtype_import['MotionCor2 v1.1.0'] = [('frame_number', '<f8'), (
        'shift_x', '<f8'), ('shift_y', '<f8')]
    dtype_import['crYOLO v1.0.4'] = [('coord_x', '<f8'), ('coord_y', '<f8'),
        ('box_x', '<f8'), ('box_y', '<f8')]
    dtype_import['crYOLO v1.0.5'] = [('coord_x', '<f8'), ('coord_y', '<f8'),
        ('box_x', '<f8'), ('box_y', '<f8')]
    dtype_import['crYOLO v1.1.0'] = [('coord_x', '<f8'), ('coord_y', '<f8'),
        ('box_x', '<f8'), ('box_y', '<f8')]
    return dtype_import


def safe_string_equals(a, b):
    """ Near-constant time string comparison.

    Used in order to avoid timing attacks on sensitive information such
    as secret keys during request verification (`rootLabs`_).

    .. _`rootLabs`: http://rdist.root.org/2010/01/07/timing-independent-array-comparison/

    """
    if len(a) != len(b):
        return False
    result = 0
    for x, y in zip(a, b):
        result |= ord(x) ^ ord(y)
    return result == 0


@classmethod
def _create(cls, doc):
    """Create a db instance on the server."""
    return cls.graph_api.create(cls.__collection_name__, doc)


@classmethod
def get_social_auth(cls, provider, uid):
    """Return UserSocialAuth for given provider and uid"""
    raise NotImplementedError('Implement in subclass')


@classmethod
def existing(cls, **kwargs):
    """Create an instance of an existing remote resource.

        It is marked as an exact replication of a resource present on a server.

        :param dict kwargs: Each of the named arguments will be set as
                            attributes on the resulting Resource object.
        """
    return cls(synchronized=True, **kwargs)


def _stack_input_if_needed(a, b, dim, weights):
    """
    Stack input arrays a, b if needed in correlation metrics.
    Adapt dim and weights accordingly.

    Parameters
    ----------
    a : xarray.Dataset or xarray.DataArray
        Labeled array(s) over which to apply the function.
    b : xarray.Dataset or xarray.DataArray
        Labeled array(s) over which to apply the function.
    dim : list
        The dimension(s) to apply the correlation along.
    weights : xarray.Dataset or xarray.DataArray or None
        Weights matching dimensions of ``dim`` to apply during the function.

    Returns
    -------
    a : xarray.Dataset or xarray.DataArray stacked with new_dim
        Labeled array(s) over which to apply the function.
    b : xarray.Dataset or xarray.DataArray stacked with new_dim
        Labeled array(s) over which to apply the function.
    new_dim : str
        The dimension(s) to apply the correlation along.
    weights : xarray.Dataset or xarray.DataArray stacked with new_dim or None
        Weights matching dimensions of ``dim`` to apply during the function.

    """
    if len(dim) > 1:
        new_dim = '_'.join(dim)
        a = a.stack(**{new_dim: dim})
        b = b.stack(**{new_dim: dim})
        if weights is not None:
            weights = weights.stack(**{new_dim: dim})
    else:
        new_dim = dim[0]
    return a, b, new_dim, weights


def __virtual__(hub):
    """
    Don't load on Windows, this is for *nix style platforms
    """
    return True


def __iter__():
    """Iterate over paths in the manifest."""


def _process_parse_dates_argument(parse_dates):
    """Process parse_dates argument for read_sql functions"""
    if parse_dates is True or parse_dates is None or parse_dates is False:
        parse_dates = []
    elif not hasattr(parse_dates, '__iter__'):
        parse_dates = [parse_dates]
    return parse_dates


def console_output(access_key_id, secret_access_key, session_token, verbose):
    """ Outputs STS credentials to console """
    if verbose:
        print('Use these to set your environment variables:')
    exports = '\n'.join(['export AWS_ACCESS_KEY_ID=%s' % access_key_id,
        'export AWS_SECRET_ACCESS_KEY=%s' % secret_access_key,
        'export AWS_SESSION_TOKEN=%s' % session_token])
    print(exports)
    return exports


def getCriterion(criterion_id):
    """Get the criterion object.
        """


def getBuildSets():
    """
        Return a list of un-completed build sets.

        @returns: list of L{IBuildSetStatus} implementations, via Deferred.
        """


def _some1(predicate, iterable):
    """Alternative implementation of :func:`some`."""
    return any(map(predicate, iterable))


def batch(iterable, count):
    """
    Yield batches of `count` items from the given iterable.

    >>> tuple(x for x in batch([1, 2, 3, 4, 5, 6, 7], 3))
    ([1, 2, 3], [4, 5, 6], [7])

    :param iterable: An iterable
    :type iterable: Iterable
    :param count: Number of items per batch. If <= 0, nothing is yielded.
    :type count: int
    :return: Iterable of lists of items
    :rtype: Iterable[list[object]]
    """
    if count <= 0:
        return
    current_batch = []
    for item in iterable:
        if len(current_batch) == count:
            yield current_batch
            current_batch = []
        current_batch.append(item)
    if current_batch:
        yield current_batch


@staticmethod
def write_file_build_event_of_setting(cmake_file, property_indent,
    config_condition_expr, property_value, width, **kwargs):
    """ Write file build event functor (helper) """
    del kwargs
    if config_condition_expr is None:
        return
    cmake_file.write('{0}    COMMAND {1:>{width}} {2}\n'.format(
        property_indent, config_condition_expr, property_value[
        'command_line'], width=width))


def copybuffer():
    """Selected objects are saved in a temp file

    """
    pass


def mmf_inverse(size, alpha, w0, gamma, rate):
    """
    Computes the inverse of Morgan-Mercer-Flodin growth model

    Parameters
    ----------
    size : size
    alpha : upper asymptote
    w0 : the value at time = 0
    gamma : parameter that controls the point of inflection
    rate : growth rate

    See Also
    --------
    mmf

    References
    ----------
    .. [1] A. Khamiz, Z. Ismail, and A. T. Muhammad, "Nonlinear growth models
           for modeling oil palm yield growth," Journal of Mathematics and
           Statistics, vol. 1, no. 3, p. 225, 2005.
    """
    result = (gamma * (w0 - size) / (size - alpha)) ** (1 / rate)
    return result


@staticmethod
def get_preference_static(request, prefname):
    """
        Get a preference, or None
        """
    full_name = 'exordium__%s' % prefname
    if request.user.is_authenticated:
        return request.user.preferences[full_name]
    elif full_name in request.session:
        return request.session[full_name]
    else:
        return None


def password_reset_email_context(notification):
    """Email context to reset a user password."""
    return {'protocol': 'https', 'uid': notification.user.generate_uid(),
        'token': notification.user.generate_token(), 'site': notification.site}


def capitalize(word):
    """capitalize an input word.
    :param word: the string to capitalize
    """
    return word.upper()


def psi_K_Cl_OH_HMW84(T, P):
    """c-a-a': potassium chloride hydroxide [HMW84]."""
    psi = -0.006
    valid = T == 298.15
    return psi, valid


def compat_explain(cur):
    """
    Simulate MongoDB 3.0 explain result on prior versions.
    http://docs.mongodb.org/v3.0/reference/explain-results/
    """
    res = cur.explain()
    if 'nscannedObjects' in res:
        res['executionStats'] = dict(nReturned=res.pop('n'),
            totalKeysExamined=res.pop('nscanned'), totalDocsExamined=res.
            pop('nscannedObjects'), executionTimeMillis=res.pop('millis'))
    return res


def inside(A, B):
    """
  if A is inside B.
  """
    if A.chr != B.chr:
        return False
    if B.stop < A.stop:
        return False
    if A.start < B.start:
        return False
    return True


@classmethod
def find(cls, db, name):
    """Find a service by name.

        Returns None if not found.
        """
    return db.query(cls).filter(cls.name == name).first()


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


def calc_time_series(dataset):
    """ Calculate time series mean values for a dataset

    :param dataset: Dataset object
    :type dataset: :class:`dataset.Dataset`

    :returns: time series for the dataset of shape (nT)
    """
    t_series = []
    for t in range(dataset.values.shape[0]):
        t_series.append(dataset.values[(t), :, :].mean())
    return t_series


def text_insert(text: str='', accent: bool=False):
    """Insert text at cursor position

    :param text: Text, Text to insert at the cursor position
    :type text: str
    :param accent: Accent mode, Next typed character will strike through previous, for special character input
    :type accent: bool
    """
    pass


def channels_click(extend: bool=False, children_only: bool=False):
    """Handle mouse-clicks over animation channels

    :param extend: Extend Select
    :type extend: bool
    :param children_only: Select Children Only
    :type children_only: bool
    """
    pass


@classmethod
def from_iterable(cls, target_types, address_mapper, adaptor_iter):
    """Create a new DependentGraph from an iterable of TargetAdaptor subclasses."""
    inst = cls(target_types, address_mapper)
    all_valid_addresses = set()
    for target_adaptor in adaptor_iter:
        inst._inject_target(target_adaptor)
        all_valid_addresses.add(target_adaptor.address)
    inst._validate(all_valid_addresses)
    return inst


def success(__self, __message, *args, **kwargs):
    """Log ``message.format(*args, **kwargs)`` with severity ``'SUCCESS'``."""
    __self._log('SUCCESS', None, False, __self._options, __message, args,
        kwargs)


def chop(list_, n):
    """Chop list_ into n chunks. Returns a list."""
    size = len(list_)
    each = size // n
    if each == 0:
        return [list_]
    chopped = []
    for i in range(n):
        start = i * each
        end = (i + 1) * each
        if i == n - 1:
            end = size
        chopped.append(list_[start:end])
    return chopped


def theta_H_Sr_PK74(T, P):
    """c-c': hydrogen strontium [PK74]."""
    theta = -0.02
    valid = T == 298.15
    return theta, valid


def contour_lines_from_endpoints(endpoints, crossing_points, connections,
    min_length=3, backtrack_from_end=False, extend_endpoints=True):
    """
    Follow contour lines and create contours

    - endpoints: an iterable of crossing point IDs (could be facet ids)
    - crossing_points: a mapping from crossing point ID to position coordinates
    - connections: a mapping from ID to IDs
    """
    contours = []
    endpoint_ids = list(endpoints)
    while endpoint_ids:
        end_id = endpoint_ids.pop()
        if not end_id in crossing_points:
            continue
        contour = [crossing_points.pop(end_id)]
        queue = list(connections[end_id])
        prev = end_id
        has_backtracked = False
        while queue:
            nb_id = queue.pop()
            if nb_id in crossing_points:
                cpoint = crossing_points.pop(nb_id)
                if cpoint != contour[-1]:
                    contour.append(cpoint)
                if extend_endpoints:
                    for candidate in queue:
                        if candidate in crossing_points:
                            endpoint_ids.append(candidate)
                queue = list(connections[nb_id])
                prev = nb_id
            if nb_id == end_id and prev in connections[end_id] and len(contour
                ) > min_length - 1 and not has_backtracked:
                contour.append(contour[0])
                break
            if backtrack_from_end and not queue and not has_backtracked:
                contour = contour[::-1]
                queue = list(connections[end_id])
                has_backtracked = True
        contours.append(contour)
    return contours


def parse_boolean(value):
    """Parses a boolean from test i.e. from "0", "yes", "false"
    etc.
    """
    return value.lower() in ('1', 'yes', 'true')


def get_ith_range(rng, idx, num):
    """
    Divide the full range `rng` into `num` parts, and get the `idx`-th range.
    """
    length = rng[1] - rng[0]
    beg = rng[0] + idx * length // num
    end = rng[0] + (idx + 1) * length // num
    assert end <= rng[1]
    return beg, end


def getSearchCriterias(request):
    """Return the search crieterias as defined in the request.
        """


def get_schema_variables(schema):
    """
    This method returns a set of all variables within the schemas.yml. The set is organised by:
    (variable_name, locator_method, script, file_name:sheet_name)
    If the variable is from an input database, the script is replaced by "-"
    Also, if the variable is not from a tree data shape (such as xlsx or xls), the 'file_name:sheet_name' becomes 'file_name' only.
    The sheet_name is important to consider as a primary key for each variable can only be made through combining the 'file_name:sheet_name' and
    'variable_name'. Along with the locator_method, the set should contain all information necessary for most tasks.
    """
    schema_variables = set()
    for locator_method in schema:
        if not schema[locator_method]['created_by']:
            script = '-'
        else:
            script = schema[locator_method]['created_by'][0]
        if not 'schema' in schema[locator_method] or not schema[locator_method
            ]['schema']:
            print('Could not find schema for {locator_method}'.format(
                locator_method=locator_method))
            continue
        for variable in schema[locator_method]['schema']:
            if variable.find('srf') != -1:
                variable = variable.replace(variable, 'srf0')
            if variable.find('PIPE') != -1:
                variable = variable.replace(variable, 'PIPE0')
            if variable.find('NODE') != -1:
                variable = variable.replace(variable, 'NODE0')
            if variable.find('B0') != -1:
                variable = variable.replace(variable, 'B001')
            if schema[locator_method]['file_type'] == 'epw':
                variable = 'EPW file variables'
            if schema[locator_method]['file_type'] in {'xlsx', 'xls'}:
                worksheet = variable
                for variable_in_sheet in schema[locator_method]['schema'][
                    worksheet]:
                    file_name = '{file_path}:{worksheet}'.format(file_path=
                        schema[locator_method]['file_path'], worksheet=
                        worksheet)
                    schema_variables.add((variable_in_sheet, locator_method,
                        script, file_name))
            else:
                file_name = schema[locator_method]['file_path']
                schema_variables.add((variable, locator_method, script,
                    file_name))
    return schema_variables


def norm_apply_denorm(x, f, nrm):
    """Normalize `x` with `nrm`, then apply `f`, then denormalize"""
    y = f(nrm(x.clone()))
    return nrm.decode(y).clamp(0, 1)


def compute_p_values_from_raw_distribution(x, X_rand):
    """
    Compute the p_value of a given metric with respect to a randomized
    reference distribution (raw values).

    Args:
        x (float): metric value to test
        X_rand (numpy.ndarray): randomized reference raw values

    Returns:
        float: p_value of x

    Example:
        >>> import numpy as np
        >>> np.random.seed(0)
        >>> x = np.random.rand()
        >>> X = np.random.standard_normal(1000)
        >>> p_value = compute_p_values_from_raw_distribution(x, X)
        >>> p_value
        0.273

    """
    p_val = (X_rand >= x).sum() / X_rand.shape[0]
    return p_val


def is_not(a, b):
    """Same as a is not b."""
    return a is not b


def _add_expression_arg(parser):
    """Add the expression argument to a parser."""
    parser.add_argument('expression', nargs='*', help=
        """Boolean expression to process; surround it in quotes to
avoid escaping control characters in your terminal"""
        )


def describe_compliance_by_resource(ResourceType=None, ResourceId=None,
    ComplianceTypes=None, Limit=None, NextToken=None):
    """
    Indicates whether the specified AWS resources are compliant. If a resource is noncompliant, this action returns the number of AWS Config rules that the resource does not comply with.
    A resource is compliant if it complies with all the AWS Config rules that evaluate it. It is noncompliant if it does not comply with one or more of these rules.
    If AWS Config has no current evaluation results for the resource, it returns INSUFFICIENT_DATA . This result might indicate one of the following conditions about the rules that evaluate the resource:
    See also: AWS API Documentation

    :example: response = client.describe_compliance_by_resource(
        ResourceType='string',
        ResourceId='string',
        ComplianceTypes=[
            'COMPLIANT'|'NON_COMPLIANT'|'NOT_APPLICABLE'|'INSUFFICIENT_DATA',
        ],
        Limit=123,
        NextToken='string'
    )

    :type ResourceType: string
    :param ResourceType: The types of AWS resources for which you want compliance information; for example, AWS::EC2::Instance . For this action, you can specify that the resource type is an AWS account by specifying AWS::::Account .

    :type ResourceId: string
    :param ResourceId: The ID of the AWS resource for which you want compliance information. You can specify only one resource ID. If you specify a resource ID, you must also specify a type for ResourceType .

    :type ComplianceTypes: list
    :param ComplianceTypes: Filters the results by compliance.
            The allowed values are COMPLIANT , NON_COMPLIANT , and INSUFFICIENT_DATA .
            (string) --

    :type Limit: integer
    :param Limit: The maximum number of evaluation results returned on each page. The default is 10. You cannot specify a limit greater than 100. If you specify 0, AWS Config uses the default.

    :type NextToken: string
    :param NextToken: The NextToken string returned on a previous page that you use to get the next page of results in a paginated response.

    :rtype: dict
    :return: {
        'ComplianceByResources': [
            {
                'ResourceType': 'string',
                'ResourceId': 'string',
                'Compliance': {
                    'ComplianceType': 'COMPLIANT'|'NON_COMPLIANT'|'NOT_APPLICABLE'|'INSUFFICIENT_DATA',
                    'ComplianceContributorCount': {
                        'CappedCount': 123,
                        'CapExceeded': True|False
                    }
                }
            },
        ],
        'NextToken': 'string'
    }

    :returns:
    ResourceType (string) -- The types of AWS resources for which you want compliance information; for example, AWS::EC2::Instance . For this action, you can specify that the resource type is an AWS account by specifying AWS::::Account .
    ResourceId (string) -- The ID of the AWS resource for which you want compliance information. You can specify only one resource ID. If you specify a resource ID, you must also specify a type for ResourceType .
    ComplianceTypes (list) -- Filters the results by compliance.
    The allowed values are COMPLIANT , NON_COMPLIANT , and INSUFFICIENT_DATA .

    (string) --

    Limit (integer) -- The maximum number of evaluation results returned on each page. The default is 10. You cannot specify a limit greater than 100. If you specify 0, AWS Config uses the default.
    NextToken (string) -- The NextToken string returned on a previous page that you use to get the next page of results in a paginated response.

    """
    pass


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 elemwise_div(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Divides arguments element-wise.

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

    Parameters
    ----------
    lhs : NDArray
        first input
    rhs : NDArray
        second input

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

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


def _rio_transform(riods):
    """
    Get the transform from a rasterio dataset
    reguardless of rasterio version.
    """
    try:
        return riods.transform
    except AttributeError:
        return riods.affine


def proxy_url(value, socks_scheme=None):
    """
    Parse a single proxy config value from FindProxyForURL() into a more usable element.

    :param str value: Value to parse, e.g.: ``DIRECT``, ``PROXY example.local:8080``, or ``SOCKS example.local:8080``.
    :param str socks_scheme: Scheme to assume for SOCKS proxies. ``socks5`` by default.
    :returns: Parsed value, e.g.: ``DIRECT``, ``http://example.local:8080``, or ``socks5://example.local:8080``.
    :rtype: str
    :raises ValueError: If input value is invalid.
    """
    if value.upper() == 'DIRECT':
        return 'DIRECT'
    parts = value.split()
    if len(parts) == 2:
        keyword, proxy = parts[0].upper(), parts[1]
        if keyword == 'HTTPS':
            return 'https://' + proxy
        if keyword == 'PROXY':
            return 'http://' + proxy
        if keyword == 'SOCKS':
            if not socks_scheme:
                socks_scheme = 'socks5'
            return '{0}://{1}'.format(socks_scheme, proxy)
    raise ValueError("Unrecognized proxy config value '{}'".format(value))


def get_html_path_string(path_cache, color, counter, opacity=1.0, weight=2):
    """
    Internal method. Do not use.
    """
    string = 'var flightPlanCoordinates' + str(counter) + ' = [ \n'
    for pair in path_cache:
        string = string + '{lat: ' + str(pair[1]) + ', lng: ' + str(pair[2]
            ) + '},\n'
    string = (string + """
        ];
        var flightPath""" + str(
        counter) +
        """ = new google.maps.Polyline({
          path: flightPlanCoordinates"""
         + str(counter) +
        """,
          geodesic: true,
          strokeColor: '""" + color +
        """',
          strokeOpacity: """ + str(opacity) +
        """,
          strokeWeight: """ + str(weight) +
        '\n        });\n\n        flightPath' + str(counter) + '.setMap(map);')
    return string


def _get_trading_day_end_time(trading_day):
    """给定交易日, 获得交易日结束时间"""
    return trading_day + 64799999999999


@classmethod
def get(cls, file_type):
    """
        Returns the FileType class corresponding to the provided key.

        Args:
            file_type: index used to register the class

        Example:
            FileTypes.get('combsfasta')
            # CombsFastaFileType

        """
    return cls._types.get(file_type)


def getFileWriter():
    """Returns a IChunkReader"""


def function_with_types_in_docstring(param1, param2):
    """Example function with types documented in the docstring.

    `PEP 484`_ type annotations are supported. If attribute, parameter, and
    return types are annotated according to `PEP 484`_, they do not need to be
    included in the docstring:

    Args:
        param1 (int): The first parameter.
        param2 (str): The second parameter.

    Returns:
        bool: The return value. True for success, False otherwise.

    .. _PEP 484:
        https://www.python.org/dev/peps/pep-0484/

    """


def get_incompatible_shares():
    """Return a list of 'share locators', one for each share that was
        found to be of an unknown format. Each share locator is a list of
        (IServer, storage_index, sharenum)."""


def _get_border(border, size):
    """Get the border size of the image"""
    i = 1
    while size - border // i <= border // i:
        i *= 2
    return border // i


def format_time(value: float) ->str:
    """Convert time to nicer format"""
    if value <= 0.005:
        return f'{value * 1000000:.0f}us'
    elif value <= 0.1:
        return f'{value * 1000:.1f}ms'
    elif value > 86400:
        return f'{value / 86400:.2f}day'
    elif value > 1800:
        return f'{value / 3600:.2f}hr'
    elif value > 60:
        return f'{value / 60:.2f}min'
    return f'{value:.2f}s'


def first_not_none(iterable, fallback=None):
    """ return the first item that is not None """
    for obj in iterable:
        if obj is not None:
            return obj
    return fallback


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 find_option(field, value: str):
    """Find the option for a ``<select>`` field."""
    return field.find_by_xpath(
        f'//option[@value="{value}" or text()="{value}"]')


def opposite_angle(angle):
    """Determine the opposite angle to the angle given, in Qt terms."""
    angle += 180 * 16
    if angle >= 360 * 16:
        angle -= 360 * 16
    return angle


def _runner_class(alias):
    """Get the runner subclass corresponding to the given alias
    (importing code only as needed)."""
    if alias == 'dataproc':
        from mrjob.dataproc import DataprocJobRunner
        return DataprocJobRunner
    elif alias == 'emr':
        from mrjob.emr import EMRJobRunner
        return EMRJobRunner
    elif alias == 'hadoop':
        from mrjob.hadoop import HadoopJobRunner
        return HadoopJobRunner
    elif alias == 'inline':
        from mrjob.inline import InlineMRJobRunner
        return InlineMRJobRunner
    elif alias == 'local':
        from mrjob.local import LocalMRJobRunner
        return LocalMRJobRunner
    elif alias == 'spark':
        from mrjob.spark.runner import SparkMRJobRunner
        return SparkMRJobRunner
    else:
        raise ValueError('bad runner alias: %s' % alias)


def serialize_keras_model(model):
    """Serializes the specified Keras model into a dictionary."""
    dictionary = {}
    dictionary['model'] = model.to_json()
    dictionary['weights'] = model.get_weights()
    return dictionary


def clean_hex(d):
    """
    Convert decimal to hex and remove the "L" suffix that is appended to large
    numbers
    """
    try:
        return hex(d).rstrip('L')
    except:
        return None


@staticmethod
def process(items):
    """Return only meaningful fields from item sequence."""
    for name, value in items:
        if isinstance(value, str):
            yield name, value
        if isinstance(value, int):
            yield name, value
        if isinstance(value, dict):
            yield name, value
        if isinstance(value, list):
            yield name, value


@classmethod
def post_get(cls, f):
    """ decorator to accept POST & GET method """
    return cls._accept_method(['POST', 'GET'], f)


@staticmethod
def _enqueue_output(stream, queue):
    """
        Add chunks of data from a stream to a queue until the stream is empty.
        """
    for line in iter(lambda : stream.read(4096), b''):
        queue.put(line)
    stream.close()


def payment_receipt_open(identifier, coo, method, value):
    """Opens a non-fiscal bound receipt for a payment

        @param identifier: a char (A-P) representing the receipt to use.
                           The receipt must already be configured at the printer.
        @param method: another char (A-P) for the payment method. Also, this must be
                       configured at the printer. The payment method must be bindable
        @param coo: coo for the coupon containing the payment
        @param value: the value of the payment
        """


def __gt__(i1, i2):
    """ Test if i1.inf > i2.sup
        """
    return i1.inf > i2.sup


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


def log(args, level, message):
    """Print log messages"""
    if args.dbg_lvl > level:
        print(message)


def show_run(command_history_id):
    """
    Show detailed command history by its ID.
    """
    from pprint import pprint
    from .config import ConfigStore
    from .database import DataBase
    db = DataBase(ConfigStore().db_path)
    with db.connection():
        for ch_id in command_history_id:
            crec = db.get_full_command_record(ch_id)
            pprint(crec.__dict__)
            print('')


def finderTopicsQueryCatalog(scope, catalog, **kw):
    """Redefine the queryCatlog method defined in AT Topics to allow a query
    override with kw args and to return 0 results when there are no criteria
    inside topic (other use cases are not interesting here)
    """
    query = scope.buildQuery()
    if query is None:
        return []
    else:
        query.update(kw)
        return catalog(**query)


def with_later(value):
    """
        Add the ``(state, tid)`` (another ICachedValue) to the list of
        cached entries. Return the new value to place in the cache.
        """


def duck_type_collection(specimen, default=None):
    """Given an instance or class, guess if it is or is acting as one of
    the basic collection types: list, set and dict.  If the __emulates__
    property is present, return that preferentially.
    """
    if hasattr(specimen, '__emulates__'):
        if specimen.__emulates__ is not None and issubclass(specimen.
            __emulates__, set):
            return set
        else:
            return specimen.__emulates__
    isa = isinstance(specimen, type) and issubclass or isinstance
    if isa(specimen, list):
        return list
    elif isa(specimen, set):
        return set
    elif isa(specimen, dict):
        return dict
    if hasattr(specimen, 'append'):
        return list
    elif hasattr(specimen, 'add'):
        return set
    elif hasattr(specimen, 'set'):
        return dict
    else:
        return default


def change_character(delta: int=1):
    """Change font character code

    :param delta: Delta, Number to increase or decrease character code with
    :type delta: int
    """
    pass


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

        :param PaperDocChangeSharingPolicyType val:
        :rtype: EventType
        """
    return cls('paper_doc_change_sharing_policy', val)


def get_fully_qualified_name(instance: object) ->str:
    """
    Get at the fully qualified name of an object, e.g.
    an instance of a :class:`~py_trees.composites.Sequence`
    becomes 'py_trees.composites.Sequence'.

    Args:
        instance (:obj:`object`): an instance of any class

    Returns:
        :obj:`str`: the fully qualified name
    """
    module = instance.__class__.__module__
    builtin = str.__class__.__module__
    if module is None or module == builtin:
        return instance.__class__.__name__
    else:
        return module + '.' + instance.__class__.__name__


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


@classmethod
def from_lout(cls, path=None, transform_2d=None, **kwargs):
    """Create a Sensor instance from a ``*.lout`` file"""
    kwargs['transform_2d'] = transform_2d
    locs = []
    names = []
    with open(path) as fileobj:
        fileobj.readline()
        for line in fileobj:
            w, x, y, t, f, name = line.split('\t')
            x = float(x)
            y = float(y)
            locs.append((x, y, 0))
            names.append(name)
    return cls(locs, names, **kwargs)


def null_combine(corrs):
    """
    Placeholder function that returns the input

    :param corrs: a matrix of vectorized correlation matrices (output of mat2vec), or a list
                  of such matrices

    :return: the input
    """
    return corrs


def toAsn1IntBytes(b):
    """Return a bytearray containing ASN.1 integer based on input bytearray.

    An ASN.1 integer is a big-endian sequence of bytes, with excess zero bytes
    at the beginning removed.  However, if the high bit of the first byte
    would be set, a zero byte is prepended.  Note that the ASN.1 type/len
    fields are NOT added by this function.
    """
    while b[0] == 0 and len(b) > 1:
        b = b[1:]
    if b[0] & 128:
        b = bytearray([0]) + b
    return b


def pytest_selenium_runtest_makereport(item, report, summary, extra):
    """ Called when making the HTML report. """


@staticmethod
def _pos_isequal(pos, pos2, key_indices):
    """
        Сравнивает две позиции
        :param pos:
        :param pos2:
        :param key_indices:
        :return:
        """
    for i1, i2 in key_indices:
        if pos[i1] != pos2[i2]:
            return False
    return True


def _quick_and_dirty_glyph_is_empty(font, glyph_name):
    """
    This is meant to be a quick-and-dirty test to see if a glyph is empty.
    Ideally we'd use the glyph_has_ink() method for this, but for a family of
    large CJK CFF fonts with tens of thousands of glyphs each, it's too slow.

    Caveat Utilitor:
    If this method returns True, the glyph is definitely empty.
    If this method returns False, the glyph *might* still be empty.
    """
    if 'glyf' in font:
        glyph = font['glyf'][glyph_name]
        if not glyph.isComposite():
            if glyph.numberOfContours == 0:
                return True
        return False
    elif 'CFF2' in font:
        top_dict = font['CFF2'].cff.topDictIndex[0]
    else:
        top_dict = font['CFF '].cff.topDictIndex[0]
    char_strings = top_dict.CharStrings
    char_string = char_strings[glyph_name]
    if len(char_string.bytecode) <= 1:
        return True
    return False


@staticmethod
def read(sile, *args, **kwargs):
    """ Reads Hamiltonian from `Sile` using `read_hamiltonian`.

        Parameters
        ----------
        sile : Sile, str or pathlib.Path
            a `Sile` object which will be used to read the Hamiltonian
            and the overlap matrix (if any)
            if it is a string it will create a new sile using `get_sile`.
        * : args passed directly to ``read_hamiltonian(,**)``
        """
    from sisl.io import get_sile, BaseSile
    if isinstance(sile, BaseSile):
        return sile.read_hamiltonian(*args, **kwargs)
    else:
        with get_sile(sile) as fh:
            return fh.read_hamiltonian(*args, **kwargs)


def copy():
    """return copy of dict"""


@classmethod
def _progress_handler(cls, message, percentage):
    """Progress bar handler, called when C{igraph} reports the progress
        of an operation

        @param message: message provided by C{igraph}
        @param percentage: percentage provided by C{igraph}
        """
    if percentage >= 100:
        cls.progress_bar.clear()
    else:
        cls.progress_bar.update(percentage, message)


def read_mm_stamp(fh, byteorder, dtype, count, offsetsize):
    """Read FluoView mm_stamp tag from file and return as numpy.ndarray."""
    return fh.read_array(byteorder + 'f8', 8)


def sizeof_fmt(num, suffix='B'):
    """ format a size value (bytes) into a human readable value """
    for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
        if abs(num) < 1024.0:
            return '%3.1f%s%s' % (num, unit, suffix)
        num /= 1024.0
    return '%.1f%s%s' % (num, 'Yi', suffix)


def increment(container, datum):
    """Increment function for Apache Spark's ``aggregate`` method.
    *
    * Typical use: ``filledHistogram = datasetRDD.aggregate(initialHistogram, increment, combine)`` where ``datasetRDD`` is a collection of ``initialHistogram``'s input type.
   """
    container.fill(datum)
    return container


def get_inframe_gap(seq, nucs_needed=3):
    """
    This funtion takes a sequnece starting with a gap or the complementary
    seqeuence to the gap, and the number of nucleotides that the seqeunce
    should contain in order to maintain the correct reading frame. The
    sequence is gone through and the number of non-gap characters are
    counted. When the number has reach the number of needed nucleotides
    the indel is returned. If the indel is a 'clean' insert or deletion
    that starts in the start of a codon and can be divided by 3, then only
    the gap is returned.
    """
    nuc_count = 0
    gap_indel = ''
    nucs = ''
    for i in range(len(seq)):
        if seq[i] != '-':
            if gap_indel.count('-') == len(gap_indel) and gap_indel.count('-'
                ) >= 3 and len(gap_indel) != 0:
                return gap_indel
            nuc_count += 1
        gap_indel += seq[i]
        if nuc_count == nucs_needed:
            return gap_indel
    return gap_indel


@classmethod
def register_notification_objects(cls):
    """Register previously decorated notification as normal ovos.

        This is not intended for production use but only for testing and
        document generation purposes.
        """
    for notification_cls in cls.notification_classes:
        cls.register(notification_cls)


def iterframe_master(obj):
    """try to return a frame iterator

    Parameters
    ----------
    obj : Trajectory or TrajectoryIterator or FrameIterator or a list of frames, or a list of
    Trajectory

    Examples
    --------
    >>> from pytraj import iterframe_master
    >>> # create frame itrator from a TrajectoryIterator
    >>> for frame in iterframe_master(traj): pass

    >>> # create frame itrator from a list of trajs
    >>> for frame in iterframe_master([traj, traj]): pass

    >>> # create frame iterator from a list of traj and frame
    >>> for frame in iterframe_master([traj, traj[0]]): pass

    >>> # create frame iterator from a list of frame iterator and chunk iterator
    >>> for frame in iterframe_master([traj.iterframe(), traj.iterchunk()]): pass
    """
    from pytraj import Frame
    from pytraj import FrameIterator
    if isinstance(obj, Frame):
        yield obj
    elif isinstance(obj, FrameIterator):
        for frame in obj:
            yield frame
    elif hasattr(obj, 'n_frames') and not isinstance(obj, Frame):
        for frame in obj:
            yield frame
    else:
        try:
            for traj_obj in obj:
                if isinstance(traj_obj, Frame):
                    yield traj_obj
                elif hasattr(traj_obj, '__name__'
                    ) and 'iterchunk' in traj_obj.__name__:
                    for _traj in traj_obj:
                        for frame in _traj:
                            yield frame
                else:
                    for frame in traj_obj:
                        yield frame
        except TypeError:
            raise TypeError('can not convert to Frame')


def __eq__(other):
    """Check whether the content of the other edition is the same as this.

        Does not include creation and modification dates and the edition
        parameters.

        """


def extractImageFromFitzPage(page, doc):
    """Extract a single image from a fitz page or return False.

    Args:
        page: a page of a fitz document.
        doc: fitz doc containing `page`.

    Returns:
        True/False: whether this page contains nothing but a single image
        msg or dict: if False, a msg about what happened, if True a dict
            The dict has at least the fields `width`, `height`, `image`
            and `ext`.  `d["image"]` is the raw binary data.
    """
    imlist = page.getImageList()
    if len(imlist) != 1:
        return False, 'More than one image'
    d = doc.extractImage(imlist[0][0])
    width = d.get('width')
    height = d.get('height')
    if not (width and height):
        return False, 'Extracted, but no size information'
    if width < 600 or height < 800:
        return False, 'Extracted, but below minimum size'
    if d['smask'] != 0:
        return False, 'Extracted, but had some kind of mask'
    return True, d


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


@classmethod
def ForPath(cls, archive_file):
    """Return the L{NamespaceArchive} instance that can be found at the
        given path."""
    return cls.__GetArchiveInstance(archive_file)


def create_receipt_rule_set(RuleSetName=None):
    """
    Creates an empty receipt rule set.
    For information about setting up receipt rule sets, see the Amazon SES Developer Guide .
    This action is throttled at one request per second.
    See also: AWS API Documentation

    Examples
    The following example creates an empty receipt rule set:
    Expected Output:

    :example: response = client.create_receipt_rule_set(
        RuleSetName='string'
    )

    :type RuleSetName: string
    :param RuleSetName: [REQUIRED]
            The name of the rule set to create. The name must:
            Contain only ASCII letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), or dashes (-).
            Start and end with a letter or number.
            Contain less than 64 characters.

    :rtype: dict
    :return: {}

    """
    pass


def create_DMDA(minX, maxX, minY, maxY, resX, resY):
    """
    Create a PETSc DMDA object from the bounding box of the regularly-
    spaced grid.
    """
    from petsc4py import PETSc
    dx = (maxX - minX) / resX
    dy = (maxY - minY) / resY
    if dx != dy:
        raise ValueError(
            'Spacing must be uniform in x and y directions [{:.4f}, {:.4f}]'
            .format(dx, dy))
    dim = 2
    dm = PETSc.DMDA().create(dim, sizes=(resX, resY), stencil_width=1)
    dm.setUniformCoordinates(minX, maxX, minY, maxY)
    return dm


def full_results(client, method, args, kwargs):
    """Returns JSON results for an AWS botocore call. Flattens paginated results (if any)."""
    if client.can_paginate(method):
        paginator = client.get_paginator(method)
        return paginator.paginate(*args, **kwargs).build_full_result()
    else:
        return getattr(client, method)(*args, **kwargs)


@staticmethod
def _passwords_generator(streams, pwlen):
    """ Generator that dumps the passwords for each card read strategy """
    for stream in streams['default']:
        counter = 0
        while counter + pwlen < len(stream) + 1:
            result = stream[counter:counter + pwlen]
            yield ''.join(result)
            counter += 1
    if streams.get('spiral'):
        for stream in streams['spiral']:
            if len(stream) >= pwlen:
                result = stream[0:pwlen]
                yield ''.join(result)


def loop_multi_select(ring: bool=False):
    """Select a loop of connected edges by connection type

    :param ring: Ring
    :type ring: bool
    """
    pass


def disable():
    """
    Disables the playing of sound.
    """
    global _SOUND_ENABLE
    _SOUND_ENABLE = False


@classmethod
def _get_base_vectors(cls, base):
    """Get unit vectors and scale factors from base.

        Parameters
        ----------
        base : instance of ``self.base_representation``
            The points for which the unit vectors and scale factors should be
            retrieved.

        Returns
        -------
        unit_vectors : dict of `CartesianRepresentation`
            In the directions of the coordinates of base.
        scale_factors : dict of `~astropy.units.Quantity`
            Scale factors for each of the coordinates

        Raises
        ------
        TypeError : if the base is not of the correct type
        """
    cls._check_base(base)
    return base.unit_vectors(), base.scale_factors()


def __check_spaces(_sentence):
    """
    Here we check to see that we have the correct number of spaces in the correct locations.

    :param _sentence:
    :return:
    """
    if _sentence is not None:
        words = _sentence.split()
        new_sentence = ''
        for i, word in enumerate(words):
            if word[-1] in set('.!?'):
                word += ' '
            new_word = ''.join(word)
            new_sentence += ' ' + new_word
        new_sentence = new_sentence.lstrip()
        new_sentence = new_sentence.rstrip()
        return new_sentence


def from70(theWord):
    """Returns a double from a Rep code 0x46, 32bit fixed point."""
    retVal = theWord >> 16 & 65535
    retVal += float(theWord & 65535) / (1 << 16)
    if theWord & 2147483648:
        retVal -= 65536
    return retVal


@staticmethod
def get_workload(storage_group):
    """Get the workload from the storagegroup object.

        :param storage_group: storagegroup -- object
        :returns: workload -- str
        """
    try:
        workload = storage_group['workload']
    except KeyError:
        workload = 'NONE'
    return workload


def previewrange_set(xmin: int=0, xmax: int=0, ymin: int=0, ymax: int=0):
    """Interactively define frame range used for playback

    :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
    """
    pass


def allsuccessors(obsstore, nodes, ignoreflags=0):
    """Yield node for every successor of <nodes>.

    Some successors may be unknown locally.

    This is a linear yield unsuited to detecting split changesets. It includes
    initial nodes too."""
    remaining = set(nodes)
    seen = set(remaining)
    while remaining:
        current = remaining.pop()
        yield current
        for mark in obsstore.successors.get(current, ()):
            if mark[2] & ignoreflags:
                continue
            for suc in mark[1]:
                if suc not in seen:
                    seen.add(suc)
                    remaining.add(suc)


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

        :param SharedFolderUnmountDetails val:
        :rtype: EventDetails
        """
    return cls('shared_folder_unmount_details', val)


def all_not_none(iterable):
    """
    Return True if all elements of the iterable are not None (or if the
    iterable is empty). This is like the built-in ``all``, except checks
    against None, so 0 and False are allowable values.
    """
    for element in iterable:
        if element is None:
            return False
    return True


def theta_B4O5OH4_Cl_FW86(T, P):
    """a-a': tetraborate chloride [FW86]."""
    theta = 0.074
    valid = T == 298.15
    return theta, valid


def tailvalue(df, pos=0, row=1):
    """Seek (last) row of dataframe, then the element at position pos."""
    return df.tail(row).values.tolist()[0][pos]


def get_span_column_count(span):
    """
    Find the length of a colspan.

    Parameters
    ----------
    span : list of lists of int
        The [row, column] pairs that make up the span

    Returns
    -------
    columns : int
        The number of columns included in the span

    Example
    -------
    Consider this table::

        +------+------------------+
        | foo  | bar              |
        +------+--------+---------+
        | spam | goblet | berries |
        +------+--------+---------+

    ::

        >>> span = [[0, 1], [0, 2]]
        >>> print(get_span_column_count(span))
        2
    """
    columns = 1
    first_column = span[0][1]
    for i in range(len(span)):
        if span[i][1] > first_column:
            columns += 1
            first_column = span[i][1]
    return columns


def register_arguments(parser):
    """Add subcommand specific arguments

    Parameters
    ----------
    parser : argparse
        subcommand argument parser
    """
    parser.add_argument('--tree', '-t', required=True, help=
        'tree to perform trait reconstruction on')
    parser.add_argument('--metadata', required=True, help=
        'tsv/csv table with meta data')
    parser.add_argument('--weights', required=False, help=
        'tsv/csv table with equilibrium probabilities of discrete states')
    parser.add_argument('--columns', required=True, nargs='+', help=
        'metadata fields to perform discrete reconstruction on')
    parser.add_argument('--confidence', action='store_true', help=
        'record the distribution of subleading mugration states')
    parser.add_argument('--sampling-bias-correction', type=float, help=
        'a rough estimate of how many more events would have been observed if sequences represented an even sample. This should be roughly the (1-sum_i p_i^2)/(1-sum_i t_i^2), where p_i are the equilibrium frequencies and t_i are apparent ones.(or rather the time spent in a particular state on the tree)'
        )
    parser.add_argument('--output-node-data', type=str, help=
        'name of JSON file to save trait inferences to')
    parser.epilog = (
        'Note that missing data must be represented by a `?` character. Missing data will currently be inferred.'
        )


def _breadth_first_iter(loc):
    """
    Given a loctation node (from a zipper) walk it's children in breadth first
    order.

    >>> from .dependencies import targets

    >>> tree = _make_tree(targets)

    >>> result = [loc.node().name for loc in _breadth_first_iter(tree)]
    >>> result  # doctest: +NORMALIZE_WHITESPACE
    [None, 'shipwright_test/1', 'shipwright_test/independent',
    'shipwright_test/2', 'shipwright_test/3']

    """
    tocheck = [loc]
    while tocheck:
        l = tocheck.pop(0)
        yield l
        child = l.down()
        while child:
            tocheck.append(child)
            child = child.right()


def reveal():
    """Reveal all hidden vertices, edges and faces

    """
    pass


@classmethod
def get_string_dict(cls):
    """Dict of menu_item to display_string"""
    return cls._string_dict


def myTradingSystem():
    """Define your trading system here.

    See the example trading system for a starting point.

    The function name "myTradingSystem" should no be changed. We evaluate this function on our server.

    Your system should return a normalized set of weights for the markets you have defined in settings['markets']. """


def split(it, sz):
    """
    Split a iterable in N parts each of len = sz. Last chunk maybe will have len < sz.

    Parameters
    ----------
    it: iterable
    sz: int

    Returns
    -------
    list of iterable

    """
    out = []
    last = 0.0
    while last < len(it):
        out.append(it[int(last):int(last + sz)])
        last += sz
    return out


def fil_clean_output(lines):
    """return generator with lines without space and
 """
    for line in lines:
        yield line.strip(' ').strip('\n')


def _to_io_meta(shape_meta, valid_keys, key_mappings):
    """
    This is used to make meta data compatible with a specific io
    by filtering and mapping to it's valid keys

    Parameters
    ----------
    shape_meta: dict
        meta attribute of a `regions.Region` object
    valid_keys : python list
        Contains all the valid keys of a particular file format.
    key_mappings : python dict
        Maps to the actual name of the key in the format.

    Returns
    -------
    meta : dict
        io compatible meta dictionary according to valid_keys and key_mappings
    """
    meta = dict()
    for key in shape_meta:
        if key in valid_keys:
            meta[key_mappings.get(key, key)] = shape_meta[key]
    return meta


def _get_new_steplist(reqs_to_keep, old_step_data, req_ids):
    """Returns a list similar to `old_step_data` but with unwanted requests removed.

	Uses the requests and request components in `old_step_data` and the entitiy ids in `req_ids` to determine which elements in `old_step_data` to keep.

	Parameters
	----------
	reqs_to_keep : dict
		Dictionary of requests and request components to keep
	old_step_data : list
		List of all the step data in the results file
	req_ids : dict
		Dictionary of entity ids for the entire results file

	Returns
	-------
	list
		List of just the step data to keep

	"""
    new_step_data = [old_step_data[1]]
    for request in reqs_to_keep:
        for req_comp in reqs_to_keep[request]:
            req_id = int(req_ids[request][req_comp])
            new_step_data.append(old_step_data[req_id])
    return new_step_data


@staticmethod
def _get_output_shape(num_intervals, width):
    """Subclasses should implement this and return the shape of output"""
    raise NotImplementedError


def to_lower(string):
    """The lower case version of a string"""
    return string.lower()


def write_pq_list(pq_list, max_index, max_value, factor1, factor2, filename):
    """Write p,q-list to file"""
    if pq_list:
        with open(filename, 'w') as f:
            print('#max index', 'max value', 'factor1', 'factor2', sep='\t',
                file=f)
            print('#' + str(max_index), str(max_value), str(factor1), str(
                factor2), sep='\t', file=f)
            for p, q in pq_list:
                print(p, q, file=f)


def logical(log):
    """Format logical in VASP format like .TRUE."""
    return '.%s.' % str(log).upper()


def shape_cut():
    """Cut hair to conform to the set shape object

    """
    pass


def add_complements(marker_exp):
    """Adds columns representing gene complement to a gene expression matrix.

    Gene complements are represented simplistically: gene expression values for
    a given gene X are multiplied by -1 and become a new column, labeled X_negation.
    "High" expression values of X become "low" values of X_negation, and vice versa,
    where discrete expression corresponds to a "high" value, and discrete
    non-expression to a "low" value.

    marker_exp should have cell row labels, gene column labels, gene expression
    float values.

    :param marker_exp: gene expression DataFrame whose rows are cell
        identifiers, columns are gene identifiers, and values are float values
        representing gene expression.

    :returns: A DataFrame of same format as marker_exp, but with a new column
              added for each existing column label, representing the column
              label gene's complement.

    :rtype: pandas.DataFrame
    """
    for gene in marker_exp.columns:
        marker_exp[gene + '_negation'] = -marker_exp[gene]
    """
    for gene in marker_exp.columns:
        marker_exp[gene + '_c'] = max(marker_exp[gene]) - marker_exp[gene]
    """
    return marker_exp


def get_bucketname(s3_url):
    """
    Extracts key part from s3 URL:
        s3_url = s3://my-bucket/some/path/to/x.pdf
        result = my-bucket
    """
    s3 = s3_url.replace('//', '/')
    scheme, bucket, *rest = s3.split('/')
    return bucket


def loob(arg):
    """Complement of bool.

  :param arg:
      Python value.
  :returns:
      Complementary boolean value.
  """
    return not bool(arg)


def dissolve():
    """Dissolve selected bones from the armature

    """
    pass


@classmethod
def decode_ssh_public(cls, packet):
    """Decode an SSH format EdDSA public key"""
    public_value = packet.get_string()
    return public_value,


def getLonLatCrs(searchList):
    """get the correct names of the columns holding the coordinates
    @param header Header of the CSV
    @returns (lon, lat, crs) where lon, lat, crs are the column names
    """
    lng = None
    lat = None
    crs = None
    for t in searchList:
        if t.lower() in ('longitude', 'lon', 'long', 'lng'):
            lng = t
        if t.lower() in ('latitude', 'lat'):
            lat = t
        if t.lower() in ('crs', 'srs', 'coordinate reference systems',
            'reference systems', 'spatial reference system'):
            crs = t
    return lng, lat, crs


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 parse_header(data: str) ->tuple:
    """Parse header, return column names."""
    return tuple(data.rstrip('\n').split('\t'))


def find_in_enum_members(item, enum_members: list):
    """Matches a string in the provided list of member strings.
	The item must be not fully matched.
	Rules:
	- If the member string starts with underscore, it is cut out before the matching continues.
	- The item is matched if a member string starts with the item (item is a prefix of the member)."""
    found = None
    for x in enum_members:
        if x.startswith(item):
            found = x
            break
        if x.startswith('_'):
            if x.strip('_').startswith(item):
                found = x
                break
    return found


def format(rep):
    """Formats the reputation score like it is formatted on the sites. Heavily based on CMS' JavaScript implementation at
        http://stackapps.com/questions/1012/how-to-format-reputation-numbers-similar-to-stack-exchange-sites/1019#1019"""
    str_rep = str(rep)
    if rep < 1000:
        return str_rep
    elif rep < 10000:
        return '%s,%s' % (str_rep[0], str_rep[1:])
    elif rep % 1000 == 0:
        return '%dk' % (rep / 1000.0)
    else:
        return '%.1fk' % (rep / 1000.0)


def debug_mode():
    """ Activates debug mode """
    global debug
    debug = not debug


def removeSystemEventTrigger(triggerID):
    """
        Removes a trigger added with addSystemEventTrigger.

        @param triggerID: a value returned from addSystemEventTrigger.

        @raise KeyError: If there is no system event trigger for the given
            C{triggerID}.

        @raise ValueError: If there is no system event trigger for the given
            C{triggerID}.

        @raise TypeError: If there is no system event trigger for the given
            C{triggerID}.
        """


def describe_connections_on_interconnect(interconnectId=None):
    """
    Deprecated in favor of  DescribeHostedConnections .
    Returns a list of connections that have been provisioned on the given interconnect.
    See also: AWS API Documentation

    :example: response = client.describe_connections_on_interconnect(
        interconnectId='string'
    )

    :type interconnectId: string
    :param interconnectId: [REQUIRED]
            ID of the interconnect on which a list of connection is provisioned.
            Example: dxcon-abc123
            Default: None

    :rtype: dict
    :return: {
        'connections': [
            {
                'ownerAccount': 'string',
                'connectionId': 'string',
                'connectionName': 'string',
                'connectionState': 'ordering'|'requested'|'pending'|'available'|'down'|'deleting'|'deleted'|'rejected',
                'region': 'string',
                'location': 'string',
                'bandwidth': 'string',
                'vlan': 123,
                'partnerName': 'string',
                'loaIssueTime': datetime(2015, 1, 1),
                'lagId': 'string',
                'awsDevice': 'string'
            },
        ]
    }

    """
    pass


def p_opt_ORDER_DIRECTION(p):
    """opt_ORDER_DIRECTION : ASC
        | DESC """
    p[0] = p[1]


def newFile(filename, content=''):
    """
    overpython.newFile(filename, content="")

    Create a new file, if no content is provided. Then it'll create the file
    without any content. Raises FileExistsError if it exists.

    On the other hand, if the file exists and the content argument is not "",
    then it'll automatically overwrite that file.
    """
    if content == '':
        try:
            f = open(filename, 'x')
            f.close()
        except FileExistsError:
            raise FileExistsError('File already exists (%s)' % filename)
    else:
        f = open(filename, 'w+')
        f.write(content)
        f.close()


@classmethod
def create(cls, class_name, **attributes):
    """
        根据参数创建一个 leancloud.Object 的子类的实例化对象

        :param class_name: 子类名称
        :type class_name: string_types
        :param attributes: 对象属性
        :return: 派生子类的实例
        :rtype: Object
        """
    object_class = cls.extend(class_name)
    return object_class(**attributes)


def _include_meta_events_within_range(events, st, ed, shift=True, front=True):
    """
    For time, key signatutr
    """
    proc_events = []
    num = len(events)
    if not events:
        return events
    i = num - 1
    while i >= 0:
        event = events[i]
        if event.time < st:
            break
        if event.time < ed:
            proc_events.append(event)
        i -= 1
    if front and i >= 0:
        if not proc_events:
            proc_events = [events[i]]
        elif proc_events[-1].time != st:
            proc_events.append(events[i])
        else:
            pass
    proc_events = proc_events[::-1]
    result = []
    shift = st if shift else 0
    for event in proc_events:
        event.time -= st
        event.time = int(max(event.time, 0))
        result.append(event)
    return proc_events


def cprint(*args, **kwargs):
    """Prints colourful messages under a standard style set.

    Update: Now handles in the same as does print, meaning you
    can give print as many input strings as you want. e.g.

    >>> cprint("Hello", "Brian", "Simon")
    Hello Brian Simon    #but in bold

    >>> print("Hello", "Brian", "Simon")
    Hello Brian Simon

    No need to specifiy kind anymore. Now defaults to bold.
    Also give kwargs to the print statement now such as 'file'.
    N.B. supplying end in cprint will cause an error as that is
    already being used in this function when print is called."""
    bcolours = {'header': '\x1b[95m', 'okblue': '\x1b[94m', 'okgreen':
        '\x1b[92m', 'warning': '\x1b[31m', 'fail': '\x1b[91m', 'endc':
        '\x1b[0m', 'bold': '\x1b[1m', 'underline': '\x1b[4m'}
    type = kwargs.pop('type', 'bold')
    for message in args:
        print(bcolours[type] + message + bcolours['endc'], end=' ', **kwargs)
    print('\r')


@staticmethod
def translate_tariff(value, dsmr_version):
    """Convert 2/1 to normal/low depending on DSMR version."""
    if dsmr_version in ('5B',):
        if value == '0001':
            value = '0002'
        elif value == '0002':
            value = '0001'
    if value == '0002':
        return 'normal'
    if value == '0001':
        return 'low'
    return None


def compare_substring(a_str, b_str):
    """ Helper for compare """
    a_digit = a_str[0].isdigit()
    b_digit = b_str[0].isdigit()
    if a_digit and not b_digit:
        return -1
    if not a_digit and b_digit:
        return 1
    if a_digit and b_digit:
        a_int = int(a_str)
        b_int = int(b_str)
        if a_int > b_int:
            return 1
        if a_int < b_int:
            return -1
    else:
        if a_str > b_str:
            return 1
        if a_str < b_str:
            return -1
    return 0


def find_tx_extra_field_by_type(extra_fields, msg, idx=0):
    """
    Finds given message type in the extra array, or returns None if not found
    :param extra_fields:
    :param msg:
    :param idx:
    :return:
    """
    cur_idx = 0
    for x in extra_fields:
        if isinstance(x, msg):
            if cur_idx == idx:
                return x
            cur_idx += 1
    return None


def view_frame():
    """Reset viewable area to show range around current frame

    """
    pass


def create_indexed_document(index_instance, model_items, action):
    """
    Creates the document that will be passed into the bulk index function.
    Either a list of serialized objects to index, or a a dictionary specifying the primary keys of items to be delete.
    """
    data = []
    if action == 'delete':
        for pk in model_items:
            data.append({'_id': pk, '_op_type': action})
    else:
        for doc in model_items:
            if index_instance.matches_indexing_condition(doc):
                data.append(index_instance.serialize_object(doc))
    return data


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


def translate_module_name(module):
    """Rename builtin modules to a consistent (Python2) module name
    This is used so that references to Python's `builtins` module can
    be loaded in both Python 2 and 3.  We remap to the "__builtin__"
    name and unmap it when importing.
    See untranslate_module_name() for the reverse operation.
    """
    if module == 'builtins' or module == 'exceptions':
        return '__builtin__'
    else:
        return module


def is_float_str(string):
    """
    Checks if a given str can be successfully converted to a float value.
    :param str string: String to be evaluated.
    :return: Returns true if the string is float convertible and false otherwise.
    :rtype: bool
    """
    try:
        float(string)
        return True
    except ValueError:
        return False


def update_now():
    """
        Update the loop's notion of the current time.

        .. versionadded:: 1.3
           In the past, this available as ``update``. This is still available as
           an alias but will be removed in the future.
        """


def pad(s, pad_to_length):
    """Pads the given string to the given length."""
    return ('%-' + '%ds' % pad_to_length) % (s,)


def find_treelistitem_with_data(tree_list, data, index=0):
    """
        Seek through the given tree_list to find the Item wich contains data in the data-array.

        Parameters
        ----------

        tree_list: wx.TreeCtrl
            existing TreeCtrl which is seeked
        data: obj
            data-Object that is assumed to be in any TreeList Item
        index: index for the data-list in the item
    """
    root_item = tree_list.GetRootItem()
    child, cookie = tree_list.GetFirstChild(root_item)
    while child.IsOk():
        item_data = tree_list.GetItemData(child)
        if item_data[index] == data:
            return child
        child, cookie = tree_list.GetNextChild(root_item, cookie)
    return tree_list.AppendItem(root_item, str(data.name), data=[data])


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

        :param bool val:
        :rtype: HasTeamSharedDropboxValue
        """
    return cls('has_team_shared_dropbox', val)


def _CK_VERSION_to_tuple(data):
    """Convert CK_VERSION to tuple."""
    return data['major'], data['minor']


def alignment_zeros(data_len) ->bytearray:
    """Return array of 0s to align to 4."""
    alignment = (4 - data_len % 4) % 4
    return bytearray(alignment)


def setTracebackClearing(clear=True):
    """
    Enable or disable traceback clearing.
    By default, clearing is disabled and Python will indefinitely store unhandled exception stack traces.
    This function is provided since Python's default behavior can cause unexpected retention of
    large memory-consuming objects.
    """
    global clear_tracebacks
    clear_tracebacks = clear


@staticmethod
def record_grouper(iterable):
    """
        creates 4 iterators on the same iterable; each moves the pointer forward when called,
        yielding 4 objects at a time
        """
    args = [iter(iterable)] * 4
    return zip(*args)


def parent_clear():
    """Clear the mask’s parenting

    """
    pass


def extract_text_from_element(elem):
    """ As an element is valid and contains text, extract it and return """
    if elem and hasattr(elem, 'text') and elem.text:
        text = elem.text
    else:
        text = None
    return text


def nucleus2id(mass, charge):
    """
    Given a mass and charge number, returns the nucleus ID (2006 PDG standard).

    :param mass: mass number
    :param charge: charge number
    :return: nucleus ID
    """
    return 1000000000 + charge * 10000 + mass * 10


@staticmethod
def make_copy_params_op(v1_list, v2_list):
    """Create operation to copy parameters.

        Creates an operation that copies parameters from variable in v1_list to
        variables in v2_list.
        The ordering of the variables in the lists must be identical.
        """
    v1_list = list(sorted(v1_list, key=lambda v: v.name))
    v2_list = list(sorted(v2_list, key=lambda v: v.name))
    update_ops = []
    for v1, v2 in zip(v1_list, v2_list):
        op = v2.assign(v1)
        update_ops.append(op)
    return update_ops


def senior_subj():
    """Return a list of senior core + elective subjects.
    """
    return ['CHIN', 'ENG', 'MATH', 'M1', 'M2', 'LIBS', 'CHIS', 'HIST',
        'CLIT', 'GEOG', 'ECON', 'BAFS', 'TH', 'PHY', 'CHEM', 'BIO', 'ICT', 'VA'
        ]


def trace_memory_alloc_simple_stats(snapshot, key_type='lineno'):
    """From https://docs.python.org/3/library/tracemalloc.html"""
    print('-----------------------------------------------------------------')
    print('[ Top 10 ]')
    top_stats = snapshot.statistics(key_type)
    for stat in top_stats[:10]:
        print(stat)


def summarize_cpu_df(dataframe, servertype):
    """
    Calculate some interesting statistics from a dataframe containing CPU load
    data.

    """
    assert servertype in ['oss', 'mds']
    results = {}
    results['ave_%s_cpu' % servertype] = dataframe.mean().mean()
    results['max_%s_cpu' % servertype] = dataframe.max().max()
    return results


def aps11_f(x, n):
    """Rational function with a zero at x=1/n and a pole at x=0"""
    return (n * x - 1) / ((n - 1) * x)


@classmethod
def global_config(cls, key, *args):
    """ This reads or sets the global settings stored in class.settings. """
    if args:
        cls.settings = cls.settings.copy()
        cls.settings[key] = args[0]
    else:
        return cls.settings[key]


def subtract(image1, image2, scale=1.0, offset=0):
    """
    Subtracts two images, dividing the result by scale and adding the offset.
    If omitted, scale defaults to 1.0, and offset to 0.0. At least one of the
    images must have mode "1".

    .. code-block:: python

        out = ((image1 - image2) / scale + offset)

    :rtype: :py:class:`~PIL.Image.Image`
    """
    image1.load()
    image2.load()
    return image1._new(image1.im.chop_subtract(image2.im, scale, offset))


def replace_seq(text, start, end, replacement=''):
    """Replace slice of string given coordinates and replacement character."""
    length = end - start
    return '{}{}{}'.format(text[:start], replacement * length, text[end:])


@classmethod
def modify_url_for_impersonation(cls, url, impersonate_user: bool, username:
    str):
    """
        Modify the SQL Alchemy URL object with the user to impersonate if applicable.
        :param url: SQLAlchemy URL object
        :param impersonate_user: Flag indicating if impersonation is enabled
        :param username: Effective username
        """
    pass


@classmethod
def default_cal_limittext(cls):
    """ shorten visible text
        """
    return False