def validate_format(*_arg):
    """
    This method can be overridden with format validation logic.
    """
    return True


def filter_blacklist(insertions, blacklist, field='gene_name'):
    """Filters annotations that assign insertions to blacklisted genes.

    Args:
        insertions (iterable[Insertion]):
        blacklist (iterable[str]): List of blacklisted gene ids to filter.
        field (str): Name of the column containing the id of the genes.

    Returns:
        iterable[Insertion]: Filtered annotated insertions, which have been
            reduced to remove blacklisted genes.

    """
    blacklist = set(blacklist)
    for insertion in insertions:
        if not insertion.metadata.get(field, None) in blacklist:
            yield insertion


def publish_version(FunctionName=None, CodeSha256=None, Description=None):
    """
    Publishes a version of your function from the current snapshot of $LATEST. That is, AWS Lambda takes a snapshot of the function code and configuration information from $LATEST and publishes a new version. The code and configuration cannot be modified after publication. For information about the versioning feature, see AWS Lambda Function Versioning and Aliases .
    See also: AWS API Documentation

    Examples
    This operation publishes a version of a Lambda function
    Expected Output:

    :example: response = client.publish_version(
        FunctionName='string',
        CodeSha256='string',
        Description='string'
    )

    :type FunctionName: string
    :param FunctionName: [REQUIRED]
            The Lambda function name. You can specify a function name (for example, Thumbnail ) or you can specify Amazon Resource Name (ARN) of the function (for example, arn:aws:lambda:us-west-2:account-id:function:ThumbNail ). AWS Lambda also allows you to specify a partial ARN (for example, account-id:Thumbnail ). Note that the length constraint applies only to the ARN. If you specify only the function name, it is limited to 64 characters in length.

    :type CodeSha256: string
    :param CodeSha256: The SHA256 hash of the deployment package you want to publish. This provides validation on the code you are publishing. If you provide this parameter value must match the SHA256 of the $LATEST version for the publication to succeed.

    :type Description: string
    :param Description: The description for the version you are publishing. If not provided, AWS Lambda copies the description from the $LATEST version.

    :rtype: dict
    :return: {
        'FunctionName': 'string',
        'FunctionArn': 'string',
        'Runtime': 'nodejs'|'nodejs4.3'|'nodejs6.10'|'java8'|'python2.7'|'python3.6'|'dotnetcore1.0'|'nodejs4.3-edge',
        'Role': 'string',
        'Handler': 'string',
        'CodeSize': 123,
        'Description': 'string',
        'Timeout': 123,
        'MemorySize': 123,
        'LastModified': 'string',
        'CodeSha256': 'string',
        'Version': 'string',
        'VpcConfig': {
            'SubnetIds': [
                'string',
            ],
            'SecurityGroupIds': [
                'string',
            ],
            'VpcId': 'string'
        },
        'DeadLetterConfig': {
            'TargetArn': 'string'
        },
        'Environment': {
            'Variables': {
                'string': 'string'
            },
            'Error': {
                'ErrorCode': 'string',
                'Message': 'string'
            }
        },
        'KMSKeyArn': 'string',
        'TracingConfig': {
            'Mode': 'Active'|'PassThrough'
        }
    }

    :returns:
    (string) --

    """
    pass


def flatten(obj, entries):
    """
    Converts an object into a list of simple value pairs
    based on a list of entries to get and using the
    rule of nested object keys are declared as double underscores
    So to fro {'a': 1, 'b' : { 'b1': 3 }} you can get the 3 as 'b__b1'
    """
    result = {}
    for entry in entries:
        parts = entry.split('__')
        value_parts = obj[parts[0]]
        while len(parts) > 1:
            parts = parts[1:]
            value_parts = value_parts[parts[0]]
        result[entry] = value_parts.replace('\r\n', ' ') if type(value_parts
            ) is str else value_parts
    return result


def deleter(this, key):
    """Delete attribute `key` from `this`."""
    try:
        object.__delattr__(this, key)
    except (AttributeError, TypeError):
        delattr(this, key)


def group_edit(exit: bool=False):
    """Edit node group

    :param exit: Exit
    :type exit: bool
    """
    pass


def id_copy():
    """Selected data-blocks are copied to the clipboard

    """
    pass


def split_quoted_line(line):
    """
    splits a line into words some of which might be quoted

    TESTS::

        FlyScan 0   0   0   blank
        FlyScan 5   2   0   "empty container"
        FlyScan 5   12   0   "even longer name"
        SAXS 0 0 0 blank
        SAXS 0 0 0 "blank"

    RESULTS::

        ['FlyScan', '0', '0', '0', 'blank']
        ['FlyScan', '5', '2', '0', 'empty container']
        ['FlyScan', '5', '12', '0', 'even longer name']
        ['SAXS', '0', '0', '0', 'blank']
        ['SAXS', '0', '0', '0', 'blank']

    """
    parts = []
    quoted = False
    multi = None
    for p in line.split():
        if not quoted and p.startswith('"'):
            quoted = True
            multi = ''
        if quoted:
            if len(multi) > 0:
                multi += ' '
            multi += p
            if p.endswith('"'):
                quoted = False
        if not quoted:
            if multi is not None:
                parts.append(multi[1:-1])
                multi = None
            else:
                parts.append(p)
    return parts


def acceptableProtocols():
    """
        Returns a list of protocols that can be spoken by the connection
        factory in the form of ALPN tokens, as laid out in the IANA registry
        for ALPN tokens.

        @return: a list of ALPN tokens in order of preference.
        @rtype: L{list} of L{bytes}
        """


def create_release(config, args):
    """
  Create a new release.
  """
    yield config.repo.create_release(args.tag_name, name=args.name,
        target_commitish=args.get('target_commitish'), body=args.get('body'
        ), draft=args.get_bool('draft'), prerelease=args.get_bool('prerelease')
        )


def validate_format(input_format, valid_formats):
    """Check the input format is in list of valid formats
    :raise ValueError if not supported
    """
    if not input_format in valid_formats:
        raise ValueError('{} data format is not in valid formats ({})'.
            format(input_format, valid_formats))
    return input_format


@classmethod
def ExpandWindowsPath(cls, path, environment_variables):
    """Expands a Windows path containing environment variables.

    Args:
      path (str): Windows path with environment variables.
      environment_variables (list[EnvironmentVariableArtifact]): environment
          variables.

    Returns:
      str: expanded Windows path.
    """
    path_segments = path.split('\\')
    path_segments = cls.ExpandWindowsPathSegments(path_segments,
        environment_variables)
    return '\\'.join(path_segments)


def letter_form_to_array_form(array_form, group):
    """
    This method converts a list given with possible repetitions of elements in
    it. It returns a new list such that repetitions of consecutive elements is
    removed and replace with a tuple element of size two such that the first
    index contains `value` and the second index contains the number of
    consecutive repetitions of `value`.

    """
    a = list(array_form[:])
    new_array = []
    n = 1
    symbols = group.symbols
    for i in range(len(a)):
        if i == len(a) - 1:
            if a[i] == a[i - 1]:
                if -a[i] in symbols:
                    new_array.append((-a[i], -n))
                else:
                    new_array.append((a[i], n))
            elif -a[i] in symbols:
                new_array.append((-a[i], -1))
            else:
                new_array.append((a[i], 1))
            return new_array
        elif a[i] == a[i + 1]:
            n += 1
        else:
            if -a[i] in symbols:
                new_array.append((-a[i], -n))
            else:
                new_array.append((a[i], n))
            n = 1


def route_to_requester(workitem):
    """Simplest possible pushapp
    """
    return workitem.instance.user


def newpage(pagename):
    """Create a new content page in layout's source tree. Corresponds
        directly with `newpage` sub-command from pagd command line script.

        ``pagename``,
            name of the new file, that shall be interpreted as a new web-page
            for static web-site. Along with filename, file extension and file
            path is to be supplied. If one or both left unspecified then it is
            updo the layout-plugin to take a default action.
        """


def list_directories(NextToken=None, MaxResults=None, state=None):
    """
    Lists directories created within an account.
    See also: AWS API Documentation

    :example: response = client.list_directories(
        NextToken='string',
        MaxResults=123,
        state='ENABLED'|'DISABLED'|'DELETED'
    )

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

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

    :type state: string
    :param state: The state of the directories in the list. Can be either Enabled, Disabled, or Deleted.

    :rtype: dict
    :return: {
        'Directories': [
            {
                'Name': 'string',
                'DirectoryArn': 'string',
                'State': 'ENABLED'|'DISABLED'|'DELETED',
                'CreationDateTime': datetime(2015, 1, 1)
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def _fp(funct, start):
    """
    Return the fixpoint of funct, as a BDD, starting with start BDD.

    mu Z.f(Z) least fixpoint is implemented with _fp(funct, false).
    nu Z.f(Z) greatest fixpoint is implemented with _fp(funct, true).
    """
    old = start
    new = funct(start)
    while old != new:
        old = new
        new = funct(old)
    return old


def logout(request):
    """Performs a logout by delegating to its authenticator plugins."""


def item_activate(extend: bool=True, recursive: bool=False, deselect_all:
    bool=False):
    """Handle mouse clicks to select and activate items

    :param extend: Extend, Extend selection for activation
    :type extend: bool
    :param recursive: Recursive, Select Objects and their children
    :type recursive: bool
    :param deselect_all: Deselect On Nothing, Deselect all when nothing under the cursor
    :type deselect_all: bool
    """
    pass


def recvall(sock, size):
    """
    Receive data of given size from a socket connection
    """
    data = b''
    while len(data) < size:
        s = sock.recv(size - len(data))
        data += s
        if not s:
            raise RuntimeError(
                'did not receive data from socket (size {}, got only {!r})'
                .format(size, data))
    return data


def _pushing(pushop):
    """return True if we are pushing anything"""
    return bool(pushop.outgoing.missing or pushop.outdatedphases or pushop.
        outobsmarkers or pushop.outbookmarks)


def OpenBrackets(OldNumber, Expression):
    """
	Count the number of open bracket - the number of close brackets.
	"""
    return OldNumber + Expression.count('(') - Expression.count(')')


def create_required_folders(full_filenamepath, folder_delim='/', verbose=1):
    """Accepts a full file name path include folders with '/' as default delimiter.
    Recursively checks for all sub-folders in filepath and creates those that are missing."""
    import os
    check_for_folders = full_filenamepath.split(folder_delim)
    if len(check_for_folders) == 1:
        return print('[!] No folders detected in provided full_filenamepath')
    else:
        check_path = check_for_folders[0]
        if check_path not in os.listdir():
            if verbose > 0:
                print(f'\t- creating folder "{check_path}"')
            os.mkdir(check_path)
        if len(check_for_folders) > 2:
            for folder in check_for_folders[1:-1]:
                base_folder_contents = os.listdir(check_path)
                check_path = check_path + '/' + folder
                if folder not in base_folder_contents:
                    if verbose > 0:
                        print(f'\t- creating folder "{check_path}"')
                    os.mkdir(check_path)
        if verbose > 1:
            print('Finished. All required folders have been created.')
        else:
            return


def Qij(Ti, Tj, Rij):
    """ Heat transferred from node i to node j

	Parameters
	----------
	Ti : float or (m x n) np.array
		temperature of node i [°C] or [K]

	Tj : float or (m x n) np.array
		temperature of node j [°C] or [K]

	Rij : float or (m x n) np.array
		heat transfer resistance between nodes [K/W]

	Returns
	-------
	Q : float or (m x n) np.array
		heat transferred between nodes

	Example use
	-----------
	>>> XXX
	"""
    return (Ti - Tj) / Rij


@classmethod
def get_redirect_to(cls, request):
    """This method can be overwritten to implement custom user/session mechanizms
        currently it uses standard django.contrib.auth"""
    return request.REQUEST.get(cls.get_redirect_field_name(), '')


def is_bool(value):
    """Return True if `value` is a boolean."""
    return bool(value) == value


def check_register_present(module):
    """Check for register method in module.

    :param module:
    :return: True if present.
    """
    if hasattr(module, 'register'):
        return True


def sp_in(c, x):
    """ Spectral index in freq-flux space """
    import numpy as N
    order = len(c) - 1
    if order == 1:
        y = c[0] * N.power(x, c[1])
    elif order == 2:
        y = c[0] * N.power(x, c[1]) * N.power(x, c[2] * N.log(x))
    else:
        print('Not yet implemented')
    return y


def signif(val):
    """
    Convert a statistical significance to its ascii representation - this
    should be the same representation created in R.
    """
    val = abs(val)
    if val > 3.1:
        return '***'
    elif val > 2.33:
        return '**'
    elif val > 1.64:
        return '*'
    elif val > 1.28:
        return '.'
    return ''


def group(nb, digits=0):
    """Transforms a number into a string with a thousand separator.

    .. code-block:: python

        pycof.group(nb, digits=0)

    :Parameters:
        * **nb** (:obj:`float`): Number to be transformed.
        * **digits** (:obj:`int`): Number of digits to round.

    :Example:
        >>> pycof.group(12345)
        ... '12,345'
        >>> pycof.group(12345.54321, digits=3)
        ... '12,345.543'

    :Returns:
        * :obj:`str`: Transformed number.
    """
    s = '%d' % nb
    groups = []
    if digits > 0:
        dig = '.' + str(nb).split('.')[1][:digits]
    else:
        dig = ''
    while s and s[-1].isdigit():
        groups.append(s[-3:])
        s = s[:-3]
    return s + ','.join(reversed(groups)) + dig


def getExtension(filename, delimiter='.'):
    """Returns the filename minus the extension (all characters after last .)"""
    i = filename.rfind(delimiter)
    if i > 0:
        return filename[i + 1:]
    else:
        return ''


def transit_sec(in_sec, start_sec, end_sec, transit_list):
    """
    determine in what sectors the marked transit are.

    Parameters
    ----------
    in_sec : list
        the sectors that we are looking at.
    start_sec : list
        the start time of these sectors
    end_sec : list
        the end time of these sectors
    transit_list : list
        list of the marked peaks

    Returns
    -------
    transit_sec  : list
        list of the sectors in which the peaks appear.

    """
    transit_sec = []
    for peak in transit_list:
        for n, start in enumerate(start_sec):
            if peak >= start[0] and peak <= end_sec[n][0]:
                transit_sec.append(in_sec[n])
    return list(set(transit_sec))


@staticmethod
def configuration():
    """Get a list of tuples with the names of additional configuration
        variables and their current values.

        Returns
        -------
        list((string, string))
        """
    raise NotImplementedError()


def getcapabilities():
    """Make a request to the SOS, returns an XML document wrapped in a
        Python file object."""


@staticmethod
def prepare_file(filename):
    """Функция, осуществляющая выгрузку данных из таблицы с различными моделями для CRTBP."""
    import csv
    a = {}
    with open(filename, 'r') as csvfile:
        next(csvfile)
        reader = csv.reader(csvfile, delimiter=';')
        for row in reader:
            a[row[0]] = [float(row[1].replace(',', '.')), float(row[2].
                replace(',', '.'))]
    return a


def is_private_name(name):
    """Return if `name` is private or not."""
    prefix = '__'
    return name.startswith(prefix) and not name.endswith(prefix)


def _peirce_skill_score(table):
    """This function is borrowed with modification from the hagelslag repository
    MulticlassContingencyTable class. It is used here with permission of
    David John Gagne II <djgagne@ou.edu>

    Multiclass Peirce Skill Score (also Hanssen and Kuipers score, True Skill Score)
    """
    n = float(table.sum())
    nf = table.sum(axis=1)
    no = table.sum(axis=0)
    correct = float(table.trace())
    no_squared = (no * no).sum()
    if n ** 2 == no_squared:
        return correct / n
    else:
        return (n * correct - (nf * no).sum()) / (n ** 2 - no_squared)


def plotWarp(a, b, warpObj, ts=[]):
    """Plots the comprehensive results of a time warp, including the
	cost matrix, backtrace path, visualisation of the warping statistics and the
	individual time series, with warp lines.

	Parameters
	----------
		a : list
			First time series, which has been warped against time series b
		b : list
			Second time series (reference)
		warpObj : dict
			A timeWarpOB warp object - see output of ``timeWarpOB.timeWarp()``.
			NB: the object must contain the calclauted cost matrix (i.e. ``retMat = True``)
		ts : list
			Optional list of timestamps for displaying on the graphs. If no timestamps are
			given, each time period will be given an incremented number, staring at 1.

	Returns
	-------
		matplotlib.pyplot
			A composite plot showing the results of the time warp.

	"""
    import matplotlib.pyplot as plt
    costMat = warpObj['costMat']
    path = warpObj['backTracePath']
    w = warpObj['warpWindow']
    n = len(costMat)
    gridSize = 5, 5
    if ts == []:
        dateRot = 0
        for i in range(n):
            ts.append(i)
    else:
        dateRot = 20
    plt.subplot2grid(gridSize, (2, 1), rowspan=2, colspan=2)
    plt.imshow(costMat, interpolation='nearest', cmap='Greys', aspect='auto')
    plt.autoscale(False)
    plt.gca().invert_yaxis()
    plt.xlabel('b')
    plt.ylabel('a')
    plt.plot([0, n], [0, n], 'y')
    plt.plot([0, n - w], [w, n], 'm--')
    plt.plot([w, n], [0, n - w], 'm--')
    for i in range(len(path) - 1):
        x1 = path[i][1]
        x2 = path[i + 1][1]
        y1 = path[i][0]
        y2 = path[i + 1][0]
        plt.plot([x1, x2], [y1, y2], 'r')
    plt.subplot2grid(gridSize, (4, 1), colspan=2)
    plt.plot(ts, b, 'g^-', label='b')
    plt.xticks(rotation=dateRot)
    c = a.copy()
    plt.subplot2grid(gridSize, (2, 0), rowspan=2)
    plt.plot(c, ts, 'bo-', label='a')
    plt.gca().invert_xaxis()
    plt.subplot2grid(gridSize, (0, 1), rowspan=2, colspan=2)
    plt.plot(ts, a, 'bo-', label='a')
    plt.plot(ts, b, 'g^-', label='b')
    plt.legend()
    for [map_x, map_y] in path:
        plt.plot([ts[map_x], ts[map_y]], [a[map_x], b[map_y]], 'r')
    plt.xticks(rotation=dateRot)
    plt.subplot2grid(gridSize, (2, 3), rowspan=2, colspan=2)
    xMax = len(a)
    yMin = -w - 1
    yMax = w + 1
    avgWarp = warpObj['warpStats']['avgWarp']
    plt.plot([0, xMax], [0, 0], 'y')
    plt.plot([0, xMax], [-w, -w], 'm--')
    plt.plot([0, xMax], [w, w], 'm--')
    plt.plot([0, xMax], [avgWarp, avgWarp], 'c:')
    plt.axis([0, xMax, yMin, yMax])
    plt.gca().set_autoscale_on(False)
    for i in range(len(path) - 1):
        i1 = path[i][0]
        i2 = path[i + 1][0]
        j1 = path[i][1]
        j2 = path[i + 1][1]
        x1 = i1 / 2 + j1 / 2
        y1 = i1 - j1
        x2 = i2 / 2 + j2 / 2
        y2 = i2 - j2
        plt.plot([x1, x2], [y1, y2], 'r')
    plt.tight_layout(pad=0.4, w_pad=0.4, h_pad=0.4)
    plt.show(block=False)


def _get_func_code(obj):
    """ Get funcion code """
    return obj.__code__


def _prune_array(array):
    """Return an array equivalent to the input array. If the input
    array is a view of a much larger array, copy its contents to a
    newly allocated array. Otherwise, return the input unchaged.
    """
    if array.base is not None and array.size < array.base.size // 2:
        return array.copy()
    return array


def update(object_id, data):
    """
        Update an object and return the updated object data. May return a
        deferred.

        ``object_id`` may not be ``None``.

        Should raise :class:`CollectionObjectNotFound`` if ``object_id`` refers
        to an object that doesn't exist.
        """


def list_arc(archive, compression, cmd, verbosity, interactive):
    """List a ARC archive."""
    cmdlist = [cmd]
    if verbosity > 1:
        cmdlist.append('v')
    else:
        cmdlist.append('l')
    cmdlist.append(archive)
    return cmdlist


@classmethod
def hexagonal(cls, a, c):
    """
        Initializes a Box in standard hexagonal setting using only hexagonal lattice
        parameters.

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

        Parameters
        ----------
        - a : float
            The a lattice constant
        - c : float
            The c lattice constant

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


def p_compound_stmt_4(p):
    """compound_stmt : try_stmt"""
    p[0] = [p[1]]


def armature_layers(layers: bool=(False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False, False, False, False)):
    """Change the visible armature layers

    :param layers: Layer, Armature layers to make visible
    :type layers: bool
    """
    pass


@classmethod
def range(Class, length):
    """
        Create a range vector.

        :param length: the required length
        :type length: a positive integer
        :returns: ``[0, 1, ..., length - 1]``
        :rtype: a vector of the specified length
        :raises: :class:`AssertionError` if `length` is not positive

        .. seealso::
            :attr:`tensors.tensor.Tensor.shape`
        """
    raise NotImplementedError


@classmethod
def on_mapping_configuration_init(cls, controller):
    """
    Callback function that is triggered, when the configuration of a controller starts

    :param controller:              the controller that should be configured
    :type controller:               steuer.Controller
    """
    print('EVENT:' + 'Start configure controller type :{0}'.format(
        controller.name))


@classmethod
def limit(cls, offset=None):
    """
        Builds a limit N [offset N] statement.
        """
    if offset:
        return cls.format(' limit {} offset {}', cls.placeholder(), cls.
            placeholder())
    return cls.format(' limit {}', cls.placeholder())


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

        :param CreateFolderBatchResult val:
        :rtype: CreateFolderBatchLaunch
        """
    return cls('complete', val)


def _extract_ids(cardinality):
    """
    Localize cardinality structure knowledge.

    :param cardinality:
    :return: product_id, artifact URI
    """
    return cardinality.split('/', 1)


def lstrip_list(s):
    """
    Return list with empty items from start of list removed.
    """
    for i in range(len(s)):
        if s[i]:
            break
    else:
        return []
    return s[i:]


def view_zoom_border(xmin: int=0, xmax: int=0, ymin: int=0, ymax: int=0,
    wait_for_input: bool=True, zoom_out: bool=False):
    """Zoom in the view to the nearest item contained in the border

    :param xmin: X Min
    :type xmin: int
    :param xmax: X Max
    :type xmax: int
    :param ymin: Y Min
    :type ymin: int
    :param ymax: Y Max
    :type ymax: int
    :param wait_for_input: Wait for Input
    :type wait_for_input: bool
    :param zoom_out: Zoom Out
    :type zoom_out: bool
    """
    pass


def allow_loopingjob_detection():
    """
    Should the looping job detection algorithm be allowed?
    The looping job detection algorithm finds recently touched files within the job's workdir. If a found file has not
    been touched during the allowed time limit (see looping job section in util/default.cfg), the algorithm will kill
    the job/payload process.

    :return: boolean.
    """
    return True


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

        :param str val:
        :rtype: MemberAddResult
        """
    return cls('free_team_member_limit_reached', val)


def body_ref_from_glob_horiz(glob_horiz_solar, floor_reflectance=0.25,
    sky_exposure=1, fract_efficiency=0.725):
    """Estimate floor-reflected solar flux on human geometry from global horizontal solar.

    Args:
        glob_horiz_solar: Global horizontal solar irradiance in W/m2.
        floor_reflectance: A number between 0 and 1 the represents the
            reflectance of the floor. Default is for 0.25 which is characteristic
            of outdoor grass or dry bare soil.
        sky_exposure: A number between 0 and 1 representing the fraction of the
            sky vault in occupant’s view. Default is 1 for outdoors in an
            open field.
        fract_efficiency: A number representing the fraction of the body
            surface exposed to radiation from the environment. This is typically
            either 0.725 for a standing or supine person or 0.696 for a seated
            person. Default is 0.725 for a standing person.
    """
    return (0.5 * sky_exposure * fract_efficiency * glob_horiz_solar *
        floor_reflectance)


def pt_edit(source, content_type):
    """Set the source and content type
        """


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


def getString(info, buffer):
    """Return the string value of the tag passed"""
    tag, left, right, sublist = info
    return buffer[left:right]


def month(datetime):
    """
    Returns the (zero-based) month for the given datetime value, in local time.
    """
    return datetime.month() - 1


def dedup(l, suffix='__'):
    """De-duplicates a list of string by suffixing a counter

    Always returns the same number of entries as provided, and always returns
    unique values.

    >>> dedup(['foo', 'bar', 'bar', 'bar'])
    ['foo', 'bar', 'bar__1', 'bar__2']
    """
    new_l = []
    seen = {}
    for s in l:
        if s in seen:
            seen[s] += 1
            s += suffix + str(seen[s])
        else:
            seen[s] = 0
        new_l.append(s)
    return new_l


def formatUintHex32(value):
    """
    Format an 32 bits unsigned integer.
    """
    return u'0x%08x' % value


def get_seqs(seq_names, seq_dict):
    """Get list of sequences from list of names."""
    seqs = []
    for name in seq_names:
        if name[-1] == '*':
            name = name[:-1]
            assert name in seq_dict, 'Sequence %s referenced before definition' % name
            seqs.append(seq_dict[name].wc)
        else:
            assert name in seq_dict, 'Sequence %s referenced before definition' % name
            seqs.append(seq_dict[name])
    return seqs


def sortRoots(roots):
    """Return a new list of roots sorted first on the real part then the imag.
    """
    lst = []
    for i, r in enumerate(roots):
        try:
            lst.append((r.real, r.imag, i, r))
        except AttributeError:
            lst.append((r, 0, i, r))
    lst.sort()
    return [r[-1] for r in lst]


def tohex(val, nbits):
    """Utility to convert (signed) integer to hex."""
    return hex((val + (1 << nbits)) % (1 << nbits))


def annotate_pages(pages):
    """A generator to annotate pages with nesting information.

    This is required to build a nested list of pages from the flat mptree list of pages.

    Returns:
        tuple(page, nb_open, nb_close, is_leaf):
            - page: the current page to wrap in a <li> tag,
            - nb_open(int): number of opening <ul> tags. Should be 1 when the nesting level
                increases, 0 otherwise,
            - nb_close(int): number of closing </ul> tags. Should be the gap between one page
                and the next when less nested. When reaching the last page we should close all
                the tags still open.
            - is_leaf(boolean): True if the current <li> tag is a leaf, False otherwise. If
                the page is not empty, it has children and we should delay closing the <li>.
    """
    nb_open = nb_close = 0
    nb_pages = len(pages)
    for i in range(nb_pages):
        if i == 0:
            nb_open = 0
        else:
            nb_open = max(pages[i].level - pages[i - 1].level, 0)
        is_leaf = True
        if i == nb_pages - 1:
            nb_close = pages[i].level - 1
        else:
            gap = pages[i].level - pages[i + 1].level
            nb_close = max(gap, 0)
            is_leaf = gap >= 0
        yield pages[i], nb_open, nb_close, is_leaf


def suggest_memory_friendly_equi(name):
    """ Suggest name of a memory friendly equivalent for a function. """
    suggs = {'range': ['xrange']}
    return suggs.get(name, [])


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

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


def select(extend: bool=False, fill: bool=False, open: bool=True,
    deselect_all: bool=False):
    """Handle mouse clicks to select and activate items

    :param extend: Extend, Extend selection instead of deselecting everything first
    :type extend: bool
    :param fill: Fill, Select everything beginning with the last selection
    :type fill: bool
    :param open: Open, Open a directory when selecting it
    :type open: bool
    :param deselect_all: Deselect On Nothing, Deselect all when nothing under the cursor
    :type deselect_all: bool
    """
    pass


@classmethod
def from_offset(cls, chunk_type, stream_rdr, offset):
    """
        Return a default _Chunk instance that only knows its chunk type.
        """
    return cls(chunk_type)


def axle_lid_self_test():
    """
  This is the non-regression test of axle_lid.
  Look at the Tk window to check errors.
  """
    r_tests = [['simplest test',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 79.0 --axle_hole_diameter 22.0 --holder_crenel_number 6'
        ], ['odd number of crenel',
        '--holder_diameter 120.0 --clearance_diameter 100.0 --central_diameter 70.0 --axle_hole_diameter 22.0 --holder_crenel_number 5'
        ], ['four crenels',
        '--holder_diameter 120.0 --clearance_diameter 100.0 --central_diameter 70.0 --axle_hole_diameter 22.0 --holder_crenel_number 4'
        ], ['double-holes only',
        '--holder_diameter 220.0 --clearance_diameter 200.0 --central_diameter 70.0 --axle_hole_diameter 22.0 --holder_crenel_number 8 --holder_double_hole_length 4.0 --holder_double_hole_diameter 3.0 --holder_hole_diameter 0.0'
        ], ['single and double holes',
        '--holder_diameter 220.0 --clearance_diameter 200.0 --central_diameter 70.0 --axle_hole_diameter 22.0 --holder_crenel_number 8 --holder_double_hole_length 16.0 --holder_double_hole_diameter 3.0 --holder_hole_diameter 5.0'
        ], ['with initial angle',
        '--holder_diameter 120.0 --clearance_diameter 100.0 --central_diameter 35.0 --axle_hole_diameter 22.0 --holder_position_angle 0.25'
        ], ['with annulus-holder-axle-hole-diameter',
        '--holder_diameter 120.0 --clearance_diameter 100.0 --central_diameter 35.0 --axle_hole_diameter 22.0 --annulus_holder_axle_hole_diameter 80.0'
        ], ['axle_B with even crenel',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 6 --output_axle_B_place small --output_axle_distance 130.0 --output_axle_B_internal_diameter 20.0 --output_axle_B_external_diameter 40.0'
        ], ['axle_B small side',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --output_axle_B_place small --output_axle_distance 100.0 --output_axle_B_internal_diameter 30.0 --output_axle_B_external_diameter 65.0'
        ], ['axle_B large side with crenels',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --output_axle_B_place large --output_axle_distance 170.0 --output_axle_B_internal_diameter 40.0 --output_axle_B_external_diameter 50.0 --output_axle_B_crenel_number 7 --output_axle_B_crenel_diameter 1.0'
        ], ['axle_B large side angle',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --output_axle_B_place large --output_axle_distance 90.0  --output_axle_angle 0.3 --output_axle_B_internal_diameter 40.0 --output_axle_B_external_diameter 50.0'
        ], ['axle_B large side angle and no axle_B_hole',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --output_axle_B_place large --output_axle_distance 70.0  --output_axle_angle -0.4 --output_axle_B_internal_diameter 0.0 --output_axle_B_external_diameter 50.0'
        ], ['no axle hole',
        '--holder_diameter 150.0 --clearance_diameter 120.0 --central_diameter 30.0 --axle_hole_diameter 0.0 --holder_crenel_number 7'
        ], ['with side leg',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --leg_type side --leg_length 100.0 --foot_length 20.0 --leg_hole_diameter 10.0 --leg_hole_distance 60.0 --leg_hole_length 20.0 --leg_shift_length 30.0'
        ], ['with rear leg',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --leg_type rear --leg_length 100.0 --foot_length 20.0 --leg_hole_diameter 10.0 --leg_hole_distance 60.0 --leg_hole_length 20.0 --leg_shift_length -20.0'
        ], ['complete with rear leg',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 6 --leg_type rear --leg_length 100.0 --foot_length 20.0 --leg_hole_diameter 10.0 --leg_hole_distance 60.0 --leg_hole_length 20.0 --leg_shift_length 30.0 --output_axle_B_place large --output_axle_distance 170.0 --output_axle_B_internal_diameter 40.0 --output_axle_B_external_diameter 50.0 --output_axle_B_crenel_number 7 --output_axle_B_crenel_diameter 1.0'
        ], ['complete with side leg',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --leg_type side --leg_length 100.0 --foot_length 20.0 --leg_hole_diameter 10.0 --leg_hole_distance 60.0 --leg_hole_length 20.0 --leg_shift_length 30.0 --output_axle_B_place large --output_axle_distance 170.0 --output_axle_B_internal_diameter 40.0 --output_axle_B_external_diameter 50.0 --output_axle_B_crenel_number 7 --output_axle_B_crenel_diameter 1.0'
        ], ['complete with side leg into file',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --leg_type side --leg_length 100.0 --foot_length 20.0 --leg_hole_diameter 10.0 --leg_hole_distance 60.0 --leg_hole_length 20.0 --leg_shift_length 30.0 --output_axle_B_place large --output_axle_distance 170.0 --output_axle_B_internal_diameter 40.0 --output_axle_B_external_diameter 50.0 --output_axle_B_crenel_number 7 --output_axle_B_crenel_diameter 1.0 --output_file_basename test_output/axle_lid_self_test2.dxf'
        ], ['input_axle_B_enable small',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --output_axle_B_place large --output_axle_distance 46.0 --output_axle_B_internal_diameter 3.0 --output_axle_B_external_diameter 8.0 --input_axle_B_enable'
        ], ['input_axle_B_enable medium',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --output_axle_B_place large --output_axle_distance 52.0 --output_axle_B_internal_diameter 3.0 --output_axle_B_external_diameter 20.0 --input_axle_B_enable --output_axle_angle 0.1'
        ], ['input_axle_B_enable large',
        '--holder_diameter 100.0 --clearance_diameter 80.0 --central_diameter 30.0 --axle_hole_diameter 22.0 --holder_crenel_number 5 --output_axle_B_place large --output_axle_distance 62.0 --output_axle_B_internal_diameter 3.0 --output_axle_B_external_diameter 10.0 --input_axle_B_enable --output_axle_angle -0.2'
        ], ['output file',
        '--holder_diameter 130.0 --clearance_diameter 115.0 --central_diameter 100.0 --axle_hole_diameter 22.0 --output_file_basename test_output/axle_lid_self_test.dxf'
        ], ['last test',
        '--holder_diameter 160.0 --clearance_diameter 140.0 --central_diameter 80.0 --axle_hole_diameter 22.0'
        ]]
    return r_tests


def account_to_budget_line(account):
    """
    Convert an account name to a budget line name.

    :param str account: The account to convert.
    :returns: The budget line.
    """
    line = account.replace(':', '/')
    return line[len('Expenses/'):]


def is_spotify(raw_song):
    """ Check if the input song is a Spotify link. """
    status = len(raw_song) == 22 and raw_song.replace(' ', '%20') == raw_song
    status = status or raw_song.find('spotify') > -1
    return status


def ensure_boolean(val):
    """Coerce a string value to a boolean value"""
    if not isinstance(val, str):
        return val
    return val and val.lower() not in ('false', 'no', '0')


def computechangesetcopies(ctx):
    """return the copies data for a changeset

    The copies data are returned as a pair of dictionnary (p1copies, p2copies).

    Each dictionnary are in the form: `{newname: oldname}`
    """
    p1copies = {}
    p2copies = {}
    p1 = ctx.p1()
    p2 = ctx.p2()
    narrowmatch = ctx._repo.narrowmatch()
    for dst in ctx.files():
        if not narrowmatch(dst) or dst not in ctx:
            continue
        copied = ctx[dst].renamed()
        if not copied:
            continue
        src, srcnode = copied
        if src in p1 and p1[src].filenode() == srcnode:
            p1copies[dst] = src
        elif src in p2 and p2[src].filenode() == srcnode:
            p2copies[dst] = src
    return p1copies, p2copies


@classmethod
def _query_create_schema(cls, if_not_exists: bool=True) ->str:
    """Generates a CREATE SCHEMA stub."""
    builder = ['CREATE SCHEMA']
    if if_not_exists:
        builder.append('IF NOT EXISTS')
    builder.append(cls.schema)
    return ' '.join(builder)


def extract_container_id_removal(line):
    """
        Extract container id from a Removing line

         Removing intermediate container 816abeca3961
    """
    parts = line.strip().split(' ')
    if len(parts) == 4:
        return parts[3]
    else:
        raise Exception('Unrecognized docker removing line: ' + line)


def convert_mag_ham(H, T):
    """Converts the tensor representing the magnetic Hamiltonian to a different basis.

    Note: This is just a tensor transformation, there are several other functions very
    similar to this. The only difference is which indeces transform by T and which by
    T^-1. This just corresponds to covariant and contravariant indeces and this would be
    nice to eventually implement in the code.

    Args:
        H (tensor): the magnetic Hamiltonian in basis A
        T (matrix): . If it is set, the symmetry operations
            will be transformed by this matrix. T transforms from A to B, ie Tx_A = x_B.
    Returns:
        H_T: the magnetic Hamiltonian in basis B
    """
    Ti = T.inv()
    H_T = H.copy0()
    for ind1 in H:
        for ind2 in H_T:
            factor = 1
            for i in range(H.dim2):
                factor *= Ti[ind1[i], ind2[i]]
            H_T[ind1] += factor * H[ind2]
    return H_T


def upsample_actor(actor, fact=1):
    """
    Increase resolution of actor

    :param actor:
    :param fact:  (Default value = 1)

    """
    actor.subdivide(N=fact)


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

        :param SharedContentChangeLinkAudienceType val:
        :rtype: EventType
        """
    return cls('shared_content_change_link_audience', val)


@classmethod
def create(klass):
    """ Factory method to create a datastore with the
        full address space initialized to 0x00

        :returns: An initialized datastore
        """
    return klass(0, [0] * 65536)


def compute_jacobian(samples, transforms, inverse=False):
    """Computes the jacobian of the list of transforms at the given sample
    points.

    Parameters
    ----------
    samples : {FieldArray, dict}
        Mapping object specifying points at which to compute jacobians.
    transforms : list
        List of BaseTransform instances to apply. Nested transforms are assumed
        to be in order for forward transforms.
    inverse : bool, optional
        Compute inverse jacobians. Default is False.

    Returns
    -------
    float :
        The product of the jacobians of all fo the transforms.
    """
    j = 1.0
    if inverse:
        for t in transforms:
            j *= t.inverse_jacobian(samples)
    else:
        for t in transforms:
            j *= t.jacobian(samples)
    return j


def getTerm(value):
    """Return the ITerm object for the term 'value'.

        If 'value' is not a valid term, this method raises LookupError.
        """


@classmethod
def plot(cls, x, y, rope, *, nsamples=50000, names=None, **kwargs):
    """
        Plot the posterior distribution.

        If there are samples in which the probability of `rope` is higher
        than 0.1, the distribution is shown in a simplex
        (see :obj:`plot_simplex`), otherwise as a histogram
        (:obj:`plot_histogram`).

        Args:
            x (np.array): a vector of scores for the first model
            y (np.array): a vector of scores for the second model
            rope (float): the width of the region of practical equivalence (default: 0)
            nsamples (int): the number of samples (default: 50000)
            names (tuple of str): names of classifiers

        Returns:
            matplotlib figure
        """
    return cls(x, y, rope, nsamples=nsamples, **kwargs).plot(names)


def with_metaclass(meta, *bases):
    """Create a base class with a metaclass."""
    return meta('NewBase', bases, {})


def set_secure_cookie(name, value, **kwargs):
    """Similar to set_cookie() method, additionally signs and timestamps a
        cookie value so it cannot be forged.  Uses
        :meth:`IHTTPCookie.create_signed_value` method to sign the cookie. To
        read a cookie set with this method, use `get_secure_cookie()`.
        """


def p_to_f(p, pd, pdd=None):
    """Converts P, Pdot to F, Fdot (or vice versa)

    Convert period, period derivative and period second
    derivative to the equivalent frequency counterparts.
    Will also convert from f to p.
    """
    f = 1.0 / p
    fd = -pd / (p * p)
    if pdd is None:
        return [f, fd]
    else:
        if pdd == 0.0:
            fdd = 0.0
        else:
            fdd = 2.0 * pd * pd / p ** 3.0 - pdd / (p * p)
        return [f, fd, fdd]


def isdescriptor(object):
    """Test if `object' is a descriptor"""
    return bool({'__get__', '__set__', '__delete__'}.intersection(dir(object)))


def relative_viewname(viewname, resolver):
    """
    Helper for building a fully namespaced `viewname` given a URL resolver.
    (This is typically from the current request.)
    """
    if resolver is None:
        return viewname
    return ':'.join(filter(None, [resolver.app_name, resolver.namespace,
        viewname]))


def last(iterator):
    """Return the last value from `iterator` or ``None``."""
    value = None
    for value in iterator:
        pass
    return value


def pretty_merge_constants(left_cpool, right_cpool):
    """
    sequence of tuples containing (index, left type, left pretty
    value, right type, right pretty value). If the constant pools are
    of inequal length, a value of None will be set in place of the
    type and pretty value for indexes past its end
    """
    lsize = len(left_cpool.consts)
    rsize = len(right_cpool.consts)
    index = 1
    for index in range(1, min(lsize, rsize)):
        lt, lv = left_cpool.pretty_const(index)
        rt, rv = right_cpool.pretty_const(index)
        yield index, lt, lv, rt, rv
    if lsize > rsize:
        for index in range(index, lsize):
            lt, lv = left_cpool.pretty_const(index)
            yield index, lt, lv, None, None
    elif rsize > lsize:
        for index in range(index, rsize):
            rt, rv = right_cpool.pretty_const(index)
            yield index, None, None, rt, rv


def is_big(json_data):
    """Test if given json data is too big for mongo document.

    Using 1MB as limit atm.

    :param json_data
    """
    return len(json_data) > 1000000


def format_cpus(n):
    """Formats n as a number of CPUs"""
    return '{:.1f}'.format(n)


def close():
    """Close any connection left to the server.
        """


def clear_template_cache():
    """
    Clear the template cache by emptying it!
    """
    global _cache
    _cache = {}


def flops_linear(module, input, output):
    """FLOPs estimation for `torch.nn.Linear`"""
    mm_flops = input.shape[0] * output.shape[1] * (2 * input.shape[1] - 1)
    bias_flops = output.numel() if module.bias is not None else 0
    return mm_flops + bias_flops


def generateTimeHeadways(meanTimeHeadway, simulationTime):
    """Generates the time headways between arrivals
    given the meanTimeHeadway and the negative exponential distribution
    over a time interval of length simulationTime (assumed to be in same time unit as headway"""
    from random import expovariate
    headways = []
    totalTime = 0
    flow = 1 / meanTimeHeadway
    while totalTime < simulationTime:
        h = expovariate(flow)
        headways.append(h)
        totalTime += h
    return headways


def cat_read(filelist, open_function, mode):
    """Line-based iteration across multiple input files."""
    for file in filelist:
        with open_function(file, mode) as ifo:
            for line in ifo:
                yield line


def getHierarchy(unique_name):
    """Returns a IHierarchy in the cube with the given unique name."""


def gen_sub_label(lower=False, paren=False):
    """Generates the next letter in the alphabet as a subfig label.
	   Label can be uppercase or lowercase, with optional parentheses.
	"""
    letters = 'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z'
    labels = letters.lower().split(' ') if lower else letters.split(' ')
    for letter in labels:
        yield '(' + letter + ')' if paren else letter


@classmethod
def cull_all(cls):
    """Kill all live sprites without exception"""
    cls._end_all_lives(kill=True)


def synchronize(messages_mapping):
    """Update the local message catalogs based on the foreign data.
        """


def IPtoInt(a, b, c, d):
    """
    Converts a number from a sequence of dotted decimals into a single unsigned int.
    Args:
        a: IP address segment 1 ###.0.0.0
        b: IP address segment 2 0.###.0.0
        c: IP address segment 3 0.0.###.0
        d: IP address segment 4 0.0.0.###

    Returns: The IP address as a simple 32-bit unsigned integer

    """
    return (int(a) << 24) + (int(b) << 16) + (int(c) << 8) + int(d)


def DFReader_is_text_log(filename):
    """return True if a file appears to be a valid text log"""
    with open(filename, 'r') as f:
        ret = f.read(8000).find('FMT, ') != -1
    return ret


def should_use(cls, for_):
    """
    Check whether this plugin should be used or not.
    :param cls: plugin/class ot check
    :type cls: class
    :param for_: argument to be passed to the check function
    :type for_: dict
    :return: wether this plugin should be used or not.
    :rtype: boolean
    """
    if not hasattr(cls, '_plugin_should_be_used'):
        return True
    return cls._plugin_should_be_used(for_)


@classmethod
def merge(cls, trees):
    """
        Merge a collection of AttrTree objects.
        """
    first = trees[0]
    for tree in trees:
        first.update(tree)
    return first


def get_somatic_score(var):
    """
    Return the somatic mutation likelihood score
    """
    return var.INFO.get('SSC')


def _apply_macro(macro, tree, kw):
    """
    Executes the macro on tree passing extra kwargs.
    """
    return macro(tree, **kw)


def world_remove():
    """Remove Rigid Body simulation world from the current scene

    """
    pass


def str_display_width(s):
    """
        from xdict.utils import *
        str_display_width('a')
        str_display_width('去')
    """
    s = str(s)
    width = 0
    len = s.__len__()
    for i in range(0, len):
        sublen = s[i].encode().__len__()
        sublen = int(sublen / 2 + 1 / 2)
        width = width + sublen
    return width


def _get_prob_k_given_L(B, N=None):
    """
    Helper function.
    """
    if N is None:
        N = int(B[0, 1])
    return B / N


def _hide_frame(ax):
    """Hide axis frame for topomaps."""
    ax.get_yticks()
    ax.xaxis.set_ticks([])
    ax.yaxis.set_ticks([])
    ax.set_frame_on(False)


@classmethod
def run(cls, gen_fpath, rev_summary, reg_cols, gid_col='gen_gids', cf_dset=
    'cf_profile', rep_method='meanoid', err_method='rmse', weight=
    'gid_counts', n_profiles=1, fout=None, save_rev_summary=True,
    scaled_precision=False, max_workers=None):
    """Run representative profiles by finding the closest single profile
        to the weighted meanoid for each SC region.

        Parameters
        ----------
        gen_fpath : str
            Filepath to reV gen output file to extract "cf_profile" from.
        rev_summary : str | pd.DataFrame
            Aggregated rev supply curve summary file. Str filepath or full df.
        reg_cols : str | list | None
            Label(s) for a categorical region column(s) to extract profiles
            for. e.g. "state" will extract a rep profile for each unique entry
            in the "state" column in rev_summary.
        gid_col : str
            Column label in rev_summary that contains the generation gids
            (data index in gen_fpath).
        cf_dset : str
            Dataset name to pull generation profiles from.
        rep_method : str
            Method identifier for calculation of the representative profile.
        err_method : str
            Method identifier for calculation of error from the representative
            profile.
        weight : str | None
            Column in rev_summary used to apply weighted mean to profiles.
            The supply curve table data in the weight column should have
            weight values corresponding to the gid_col in the same row.
        n_profiles : int
            Number of representative profiles to save to fout.
        fout : str, optional
            filepath to output h5 file, by default None
        save_rev_summary : bool, optional
            Flag to save full reV SC table to rep profile output.,
            by default True
        scaled_precision : bool, optional
            Flag to scale cf_profiles by 1000 and save as uint16.,
            by default False
        max_workers : int, optional
            Number of parallel workers. 1 will run serial, None will use all
            available., by default None

        Returns
        -------
        profiles : dict
            dict of n_profile-keyed arrays with shape (time, n) for the
            representative profiles for each region.
        meta : pd.DataFrame
            Meta dataframes recording the regions and the selected rep profile
            gid.
        time_index : pd.DatatimeIndex
            Datetime Index for represntative profiles
        """
    rp = cls(gen_fpath, rev_summary, reg_cols, gid_col=gid_col, cf_dset=
        cf_dset, rep_method=rep_method, err_method=err_method, n_profiles=
        n_profiles, weight=weight)
    rp._run(fout=fout, save_rev_summary=save_rev_summary, scaled_precision=
        scaled_precision, max_workers=max_workers)
    return rp._profiles, rp._meta, rp._time_index


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

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


@staticmethod
def sorted_roles_to_dict(role_list_sorted, threshold=0.5):
    """ Converted sorted role-probability list into formatted dict

        This function ensures that the top role returned is Unknown
        if the top role has a probability less than the threshold
        specified in the default input parameter.

        INPUTS:
        --role_list_sorted: a sorted list that associates the top role
        with their probabilities
        --threshold: probability threshold below which the top role
        should be designated as "Unknown"

        OUTPUTS:
        --predictions: a dict with the top role and a sorted role list
        """
    top_role_prob = role_list_sorted[0][1]
    if top_role_prob <= threshold:
        top_role = 'Unknown'
    else:
        top_role = role_list_sorted[0][0]
    role_predictions = {'top_role': top_role, 'role_list': role_list_sorted}
    return role_predictions


@classmethod
def xml_field_close(cls, field):
    """ Returns closing tag of XML field element node.

        :param field: field name for the element node

        .. versionadded:: 0.8.2
        """
    return '</%s>' % field


def toFrontEnd(remote):
    """Transform an URL to the proper frontend ones"""


def is_chinese(uchar):
    """判断一个unicode是否是汉字"""
    if '一' <= uchar <= '龥':
        return True
    else:
        return False


def to49(theVal):
    """Converts a double to Rep code 49 0x31, 16bit floating point representation.
    Value +153 is 0100 1100 1000 1000 or 0x4C88.
    Value -153 is 1011 0011 1000 1000 or 0xB388.
    """
    assert 0


@staticmethod
def _extract_args(state, main, argc, argv, init, fini):
    """
        Extract arguments and set them to

        :param angr.sim_state.SimState state: The program state.
        :param main: An argument to __libc_start_main.
        :param argc: An argument to __libc_start_main.
        :param argv: An argument to __libc_start_main.
        :param init: An argument to __libc_start_main.
        :param fini: An argument to __libc_start_main.
        :return: A tuple of five elements: (main, argc, argv, init, fini)
        :rtype: tuple
        """
    main_ = main
    argc_ = argc
    argv_ = argv
    init_ = init
    fini_ = fini
    if state.arch.name == 'PPC32':
        argv_ = argc_
        argc_ = main_
        main_ = state.mem[state.regs.r8 + 4:].int.resolved
        init_ = state.mem[state.regs.r8 + 8:].int.resolved
        fini_ = state.mem[state.regs.r8 + 12:].int.resolved
    elif state.arch.name == 'PPC64':
        main_ = state.mem[state.regs.r8 + 8:].long.resolved
        init_ = state.mem[state.regs.r8 + 16:].long.resolved
        fini_ = state.mem[state.regs.r8 + 24:].long.resolved
    return main_, argc_, argv_, init_, fini_


@staticmethod
def id2acc(id_):
    """Converts a GO term ID to an accession number.

        Parameters
        ----------
        id_: str
            A GO term ID.

        Returns
        -------
        int
            The accession number corresponding to the GO term ID.

        """
    return int(id_[3:])


def readFirstSequenceFasta(filename):
    """Returns first sequence from a file."""
    fasta = open(filename)
    seq = []
    title = ''
    first = True
    for line in fasta:
        if line[0] == '>':
            if first:
                title = line[1:].strip()
                first = False
            else:
                break
        else:
            seq.append(line.strip())
    fasta.close()
    return title, ''.join(seq)


@staticmethod
def make_format(format_spec):
    """Build format string from a format specification.

        :param format_spec:     Format specification (as FormatSpec object).
        :return: Composed format (as string).
        """
    fill = ''
    align = ''
    zero = ''
    width = format_spec.width
    if format_spec.align:
        align = format_spec.align[0]
        if format_spec.fill:
            fill = format_spec.fill[0]
    if format_spec.zero:
        zero = '0'
    return '%s%s%s%s%s' % (fill, align, zero, width, format_spec.type)


def monomial_to_constraint(monomial, letters):
    """Given a monomial return the multiplicity of each letter, counting conjugates as negatives."""
    constr = []
    for l in letters:
        constr.append(monomial.s.count(l) - monomial.s.count(l.upper()))
    return constr


@classmethod
def _parse_body(cls, xmlelement):
    """Parse soap:body and return a dict with data to resolve it.

            <soap:body parts="nmtokens"? use="literal|encoded"?
                       encodingStyle="uri-list"? namespace="uri"?>

        """
    return {'part': xmlelement.get('part'), 'use': xmlelement.get('use',
        'literal'), 'encodingStyle': xmlelement.get('encodingStyle'),
        'namespace': xmlelement.get('namespace')}


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


@staticmethod
def backward(ctx, dy):
    """
        Performs the backward pass of a reversible sequence within the autograd framework
        :param ctx: autograd context
        :param dy: derivatives of the outputs
        :return: derivatives of the inputs
        """
    y = ctx.y
    if ctx.eagerly_discard_variables:
        del ctx.y
    for i in range(len(ctx.reversible_blocks) - 1, -1, -1):
        y, dy = ctx.reversible_blocks[i].backward_pass(y, dy, not ctx.
            eagerly_discard_variables)
    if ctx.eagerly_discard_variables:
        del ctx.reversible_blocks
    return dy, None, None


def extract_and_zero_grades(fields, d):
    """Extract an array of grades from a dictionary; convert non-numeric values to 0.0"""
    grades = []
    for f in fields:
        try:
            g = float(d[f])
        except ValueError:
            g = 0.0
        grades.append(g)
    return grades


def _calc_padding_for_alignment(align, base):
    """
    Returns byte padding required to move the base pointer into proper alignment
    """
    rmdr = int(base) % align
    if rmdr == 0:
        return 0
    else:
        return align - rmdr


def get_environment(message, slot):
    """Return the environment variables to use for running the process.

        `message` is the message received from the IPoller.next() method
        `slot` is the Launcher slot where the process will be running.
        """


def _get_column_letter(col_idx):
    """Convert a column number into a column letter (3 -> 'C')

    Right shift the column col_idx by 26 to find column letters in reverse
    order.  These numbers are 1-based, and can be converted to ASCII
    ordinals by adding 64.

    """
    if not 1 <= col_idx <= 18278:
        raise ValueError('Invalid column index {0}'.format(col_idx))
    letters = []
    while col_idx > 0:
        col_idx, remainder = divmod(col_idx, 26)
        if remainder == 0:
            remainder = 26
            col_idx -= 1
        letters.append(chr(remainder + 64))
    return ''.join(reversed(letters))


def _get_bytes(filename: str) ->bytes:
    """Read file as bytes"""
    with open(filename, 'rb') as f:
        return f.read()


def add_parser_arguments(parser):
    """ Add additional subcommands onto this command """
    parser.add_argument('network', metavar='NETWORK', type=str, nargs=1,
        help='Ethereum network to connect the console to')
    parser.add_argument('package', metavar='PACKAGE', type=str, nargs=1,
        help='The EthPM package to install')
    return parser


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


def index_types():
    """Returns a list of the supported index types"""
    return ['UNIQUE', 'CLUSTERED', 'NONCLUSTERED']


def check_server_url(srvurl):
    """Check given url for correctness"""
    good_name = srvurl.startswith('http://') or srvurl.startswith('https://')
    if not good_name:
        msg = 'You must include '
        msg += "http(s):// in your server's address, %s doesn't" % srvurl
        raise ValueError(msg)


@staticmethod
def extension():
    """Return most common file extension for format."""
    return 'xlsx'


def mutate_dict(d, ev):
    """ Function to mutate an dict property in-place.
    Used by Component. The ``ev`` must be a dict with elements:

    * mutation: 'set', 'insert', 'remove' or 'replace'.
    * objects: the dict to set/insert/replace, or a list if keys to remove.
    * index: not used.
    """
    mutation = ev['mutation']
    objects = ev['objects']
    if mutation == 'set':
        d.clear()
    elif mutation in ('set', 'insert', 'replace'):
        assert isinstance(objects, dict)
        for key, val in objects.items():
            d[key] = val
    elif mutation == 'remove':
        assert isinstance(objects, (tuple, list))
        for key in objects:
            d.pop(key)
    else:
        raise NotImplementedError(mutation)


def is_constructed(val):
    """ Check if a tag represents a "constructed" value, i.e. another TLV """
    return val & 32 == 32


def _check_version(version):
    """ check given version
    """
    if version not in ['1.0.0', '2.0.0']:
        return False
    else:
        return True


def strip_string(value: str) ->str:
    """
    Strips leading and trailing quotes and spaces
    """
    if not value:
        return ''
    return str(value).strip(' \'"\n\r\t')


def is_hard_clipped(read):
    """Function that checks the CIGAR string of the sam file and returns true if the read is hard-clipped"""
    match = 0
    for cigar in read.cigar:
        if cigar[0] == 5:
            match += 1
        else:
            pass
    if match > 0:
        return True
    else:
        return False


@staticmethod
def _safe_type(raw_type):
    """Ensure that the provided type is a known type, defaulting to text"""
    if (raw_type == 'text' or raw_type == 'number' or raw_type ==
        'password' or raw_type == 'choice' or raw_type == 'file'):
        return raw_type
    else:
        return 'text'


def dataframe_series_summary(series_summaries: dict) ->dict:
    """Aggregate certain statistics from the series summary

    Args:
        series_summaries: mapping from series to summary

    Returns:
        A aggregated summary based on the statistics of individual series
    """
    summary = {'na_count': 0, 'n_vars_missing': 0}
    for series_summary in series_summaries.values():
        if 'na_count' in series_summary and series_summary['na_count'] > 0:
            summary['na_count'] += series_summary['na_count']
    return summary


def recreate_slug(modeladmin, request, queryset):
    """
    This uses the save() instead of update() since the AutoSlugField is only generated on save().
    """
    for item in queryset.all():
        item.slug = ''
        item.save()


@classmethod
def AddArguments(cls, argument_group):
    """Adds command line arguments the helper supports to an argument group.

    This function takes an argument parser or an argument group object and adds
    to it all the command line arguments this helper supports.

    Args:
      argument_group (argparse._ArgumentGroup|argparse.ArgumentParser):
          argparse group.
    """
    argument_group.add_argument('--maximum-pause', '--maximum_pause', dest=
        'sessionize_maximumpause', type=int, action='store', metavar=
        'MINUTES', default=10, help=
        'Specify the maximum delay in minutes between events in the session.')


def window_duplicate():
    """Duplicate the current Blender window

    """
    pass


def tag_resource(Resource=None, Tags=None):
    """
    Add tags to a CloudFront resource.
    See also: AWS API Documentation

    :example: response = client.tag_resource(
        Resource='string',
        Tags={
            'Items': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ]
        }
    )

    :type Resource: string
    :param Resource: [REQUIRED]
            An ARN of a CloudFront resource.

    :type Tags: dict
    :param Tags: [REQUIRED]
            A complex type that contains zero or more Tag elements.
            Items (list) --A complex type that contains Tag elements.
            (dict) --A complex type that contains Tag key and Tag value.
            Key (string) -- [REQUIRED]A string that contains Tag key.
            The string length should be between 1 and 128 characters. Valid characters include a-z , A-Z , 0-9 , space, and the special characters _ - . : / = + @ .
            Value (string) --A string that contains an optional Tag value.
            The string length should be between 0 and 256 characters. Valid characters include a-z , A-Z , 0-9 , space, and the special characters _ - . : / = + @ .

    """
    pass


def is_prefix(uri1, uri2):
    """ returns 1 of uri1 is a prefix of uri2 """
    if uri2[:len(uri1)] == uri1:
        return 1
    else:
        return None


def custom_join(_list, joiner, final=None):
    """Join elements of `_list` using `joiner` (`final` as last joiner)."""
    _list = list(map(str, _list))
    if final is None:
        final = joiner
    if len(_list) == 0:
        return ''
    if len(_list) == 1:
        return _list[0]
    if len(_list) == 2:
        return final.join(_list)
    return joiner.join(_list[:-1]) + final + _list[-1]


@staticmethod
def get_name():
    """Get the class name.

        Args:
            self: self

        Returns:
            str: Class name
        """
    return 'nettools'


def is_metaclass(obj):
    """Checks whether given object is a metaclass.
    :return: ``True`` if object is a metaclass, ``False`` otherwise
    """
    return issubclass(obj, type)


def find_permission(permissions, permission_type, object_id=None, namespace
    =None):
    """Given a queryset of permissions, filters depending on the permission
    type, and optionally an object id and namespace."""
    if object_id is not None:
        return permissions.filter(type=permission_type, object_id=object_id,
            namespace=namespace)
    return permissions.filter(type=permission_type)


def isunauthenticated(f):
    """
    Checks to see if the function is marked as not requiring authentication
    with the @unauthenticated decorator. Returns True if decorator is
    set to True, False otherwise.
    """
    return getattr(f, 'unauthenticated', False)


@classmethod
def get_class(cls):
    """Return class for handling this module."""
    raise ImportError('Windows RC file format unsupported on Python 3')


def ik_add(with_targets: bool=True):
    """Add IK Constraint to the active Bone

    :param with_targets: With Targets, Assign IK Constraint with targets derived from the select bones/objects
    :type with_targets: bool
    """
    pass


def translation_from_matrix(M):
    """Returns the 3 values of translation from the matrix M.
    """
    return [M[0][3], M[1][3], M[2][3]]


def migrate(ml):
    """perform the migration from an old list version to a new list version"""


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

        :param ShowcaseFileRemovedDetails val:
        :rtype: EventDetails
        """
    return cls('showcase_file_removed_details', val)


def describe_maintenance_window_execution_task_invocations(WindowExecutionId
    =None, TaskId=None, Filters=None, MaxResults=None, NextToken=None):
    """
    Retrieves the individual task executions (one per target) for a particular task executed as part of a Maintenance Window execution.
    See also: AWS API Documentation

    :example: response = client.describe_maintenance_window_execution_task_invocations(
        WindowExecutionId='string',
        TaskId='string',
        Filters=[
            {
                'Key': 'string',
                'Values': [
                    'string',
                ]
            },
        ],
        MaxResults=123,
        NextToken='string'
    )

    :type WindowExecutionId: string
    :param WindowExecutionId: [REQUIRED]
            The ID of the Maintenance Window execution the task is part of.

    :type TaskId: string
    :param TaskId: [REQUIRED]
            The ID of the specific task in the Maintenance Window task that should be retrieved.

    :type Filters: list
    :param Filters: Optional filters used to scope down the returned task invocations. The supported filter key is STATUS with the corresponding values PENDING, IN_PROGRESS, SUCCESS, FAILED, TIMED_OUT, CANCELLING, and CANCELLED.
            (dict) --Filter used in the request.
            Key (string) --The name of the filter.
            Values (list) --The filter values.
            (string) --

    :type MaxResults: integer
    :param MaxResults: The maximum number of items to return for this call. The call also returns a token that you can specify in a subsequent call to get the next set of results.

    :type NextToken: string
    :param NextToken: The token for the next set of items to return. (You received this token from a previous call.)

    :rtype: dict
    :return: {
        'WindowExecutionTaskInvocationIdentities': [
            {
                'WindowExecutionId': 'string',
                'TaskExecutionId': 'string',
                'InvocationId': 'string',
                'ExecutionId': 'string',
                'Parameters': 'string',
                'Status': 'PENDING'|'IN_PROGRESS'|'SUCCESS'|'FAILED'|'TIMED_OUT'|'CANCELLING'|'CANCELLED'|'SKIPPED_OVERLAPPING',
                'StatusDetails': 'string',
                'StartTime': datetime(2015, 1, 1),
                'EndTime': datetime(2015, 1, 1),
                'OwnerInformation': 'string',
                'WindowTargetId': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def generate_endpoint_parser(subparsers, ep_name, ep_metadata):
    """Generate a subparser and arguments from an endpoint dictionary"""
    ep_parser = subparsers.add_parser(ep_name, help=ep_metadata['help'])
    if ep_metadata.get('resource'):
        ep_parser.add_argument('resource', **ep_metadata.get('resource'))
    if not ep_metadata.get('params'):
        return ep_parser
    for param, attributes in sorted(ep_metadata['params'].items()):
        ep_parser.add_argument('--%s' % param, **attributes)
    return ep_parser


def has_open_quotes(s):
    """Return whether a string has open quotes.

    This simply counts whether the number of quote characters of either type in
    the string is odd.

    Returns
    -------
    If there is an open quote, the quote character is returned.  Else, return
    False.
    """
    if s.count('"') % 2:
        return '"'
    elif s.count("'") % 2:
        return "'"
    else:
        return False


def get_file_row_generator(file_path, separator, encoding=None):
    """
    Reads an separated value file row by row.

    Inputs: - file_path: The path of the separated value format file.
            - separator: The delimiter among values (e.g. ",", "	", " ")
            - encoding: The encoding used in the stored text.

    Yields: - words: A list of strings corresponding to each of the file's rows.
    """
    with open(file_path, encoding=encoding) as file_object:
        for line in file_object:
            words = line.strip().split(separator)
            yield words


def correct(sampling, targetsize):
    """this corrects entries in sampling so that entries go from 0 to targetsize-1, and removes duplicates"""
    ratio = float(max(sampling)) / targetsize
    newsamp = []
    for i, s in enumerate(sampling):
        val = min(int(round(s / ratio)), targetsize - 1)
        while val in newsamp:
            print(val)
            val = val - 1
            if val < 0:
                raise Exception('run failed, please rerun')
        newsamp.append(val)
    return newsamp


@classmethod
def format_source(cls, message_type, host, path):
    """Format the source field of the log record.

        Args:
            message_type (str): Type of the log record message.
            host (str): Hostname or the fully qualified domain where the logging call was made.
            path (str): The full pathname of the source file where the logging call was made.

        Returns:
            string: URI of the file where the logging call was made.
        """
    return f'{message_type}://{host}/{path}'


def cumsum(x, axis=0):
    """Cumulative sum of the values in a tensor, alongside the specified axis.

    # Arguments
        x: A tensor or variable.
        axis: An integer, the axis to compute the sum.

    # Returns
        A tensor of the cumulative sum of values of `x` along `axis`.
    """
    raise NotImplementedError(
        'MXNet Backend: cumsum operator is not supported yet.')


def pause_snapshot_policy(session, snaprule, return_type=None, **kwargs):
    """
    Pause a volume's snapshot policy.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type snaprule: str
    :param snaprule: A snap rule ID.
    (found in /consistency_groups/{volume_cg_id}/snapshot_policies API).
    For example: 'snaprule-00000001'.  Required.

     :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    path = '/api/snapshot_policies/{snaprule}/pause.json'.format(snaprule=
        snaprule)
    body_values = {'id': snaprule}
    return session.post_api(path=path, body=body_values, return_type=
        return_type, **kwargs)


def _cropper(base, v_prop, h_prop):
    """

    Crops an image horizontally and vertically.

    Notes:

        - increasing ``h_prop`` increases the amount of the image's left side removed.

        - increasing ``v_prop`` increases the amount of the lower part of the image removed.

    :param base: an image represented as a 2D array.
    :type base: ``2D ndarray``
    :param v_prop: the proportion of the image to remove with respect to its height.
    :type v_prop: ``float``
    :param h_prop: the proportion of the image to remove with respect to its width.
    :type h_prop: ``float``
    :return: a cropped image as a 2D array
    :rtype: ``2D ndarray``
    """
    hcrop_base = base[:, int(base.shape[1] * h_prop):]
    return hcrop_base[:int(base.shape[0] * v_prop)]


def get_field_names_and_options(pb):
    """
    Return a tuple of field names and options.
    """
    desc = pb.DESCRIPTOR
    for field in desc.fields:
        field_name = field.name
        options_dict = {}
        if field.has_options:
            options = field.GetOptions()
            for subfield, value in options.ListFields():
                options_dict[subfield.name] = value
        yield field, field_name, options_dict


def incrementProcVer(cloneArgs, requestArgs):
    """
    Increment the ProcessingVersion value for any requests cloned via
    clone API, except if it's a Resubmission request.
    TODO: ProcVer can be a dict at top level, until this #6881 gets fixed
    """
    if cloneArgs['RequestType'] == 'Resubmission' or requestArgs.get(
        'RequestType') == 'Resubmission':
        return
    for key in cloneArgs:
        if key == 'ProcessingVersion':
            if isinstance(cloneArgs[key], int):
                cloneArgs[key] += 1
            elif isinstance(cloneArgs[key], dict):
                for taskname in cloneArgs[key]:
                    cloneArgs[key][taskname] += 1
        elif isinstance(cloneArgs[key], dict
            ) and 'ProcessingVersion' in cloneArgs[key]:
            cloneArgs[key]['ProcessingVersion'] += 1
    return


@classmethod
def white(cls):
    """Predefined white color (space) representation"""
    return cls('white', 'fff', ' ', 1)


def _is_arraylike(x):
    """Returns whether the input is array-like"""
    return hasattr(x, '__len__') or hasattr(x, 'shape') or hasattr(x,
        '__array__')


def get_item_properties(item, fields, mixed_case_fields=[], formatters={}):
    """Return a tuple containing the item properties.

    :param item: a single item resource (e.g. Server, Tenant, etc)
    :param fields: tuple of strings with the desired field names
    :param mixed_case_fields: tuple of field names to preserve case
    :param formatters: dictionary mapping field names to callables
        to format the values
    """
    row = []
    for field in fields:
        if field in formatters:
            row.append(formatters[field](item))
        else:
            if field in mixed_case_fields:
                field_name = field.replace(' ', '_')
            else:
                field_name = field.lower().replace(' ', '_')
            if not hasattr(item, field_name) and (isinstance(item, dict) and
                field_name in item):
                data = item[field_name]
            else:
                data = getattr(item, field_name, '')
            if data is None:
                data = ''
            row.append(data)
    return tuple(row)


@staticmethod
def get_interval_pos(start, interval_length):
    """ Get position of time interval """
    num_intervals = 60 * 24 / interval_length
    minutes = start.hour * 60 + start.minute
    day_progress = minutes / (60 * 24)
    return int(day_progress * num_intervals)


def delete_avatar_action(user):
    """Delete the selected avatar."""
    return user.delete_avatar(user.account.get('avatars')[int(user.choice) - 1]
        )


@staticmethod
def plugin_description():
    """ Plugin description.

        Return useful info about the plugin as the main functionalities, the author, the support email (if any)
        """
    raise NotImplementedError


def pers(n):
    """ 返回指定数量的%s，中间用逗号隔开
    --
        @example
            pers(5)
        return: %s, %s, %s, %s, %s

    """
    return ', '.join(['%s' for i in range(n)])


def track(exp):
    """ The tracking function
    """
    exp.var.dynamic['values'].append(exp.var.dynamic['value'])
    if exp.var.dynamic['cur_correct']:
        exp.var.dynamic['cur_dns'] += 1
        exp.var.dynamic['cur_ups'] = 0
        if exp.var.dynamic['cur_dns'] == exp.var.dynamic['downs']:
            exp.var.dynamic['cur_step'] = -1
            exp.var.dynamic['cur_dns'] = 0
            if exp.var.dynamic['prev_dir'] == -1:
                exp.var.dynamic['track'].append(0)
                exp.var.dynamic['cur_status'] = ' '
            elif exp.var.dynamic['prev_dir'] == 0:
                exp.var.dynamic['prev_dir'] = -1
                exp.var.dynamic['track'].append(0)
                exp.var.dynamic['init_dir'] = -1
                exp.var.dynamic['cur_status'] = 'v'
            else:
                exp.var.dynamic['prev_dir'] = -1
                exp.var.dynamic['track'].append(-1)
                exp.var.dynamic['n_reversals'] += 1
                exp.var.dynamic['values_at_rev'].append(exp.var.dynamic[
                    'value'])
                exp.var.dynamic['cur_status'] = '-{:}'.format(len(exp.var.
                    dynamic['values_at_rev']))
        else:
            exp.var.dynamic['cur_step'] = 0
            exp.var.dynamic['track'].append(0)
            exp.var.dynamic['cur_status'] = ' '
    else:
        exp.var.dynamic['cur_dns'] = 0
        exp.var.dynamic['cur_ups'] += 1
        if exp.var.dynamic['cur_ups'] == exp.var.dynamic['ups']:
            exp.var.dynamic['cur_step'] = 1
            exp.var.dynamic['cur_ups'] = 0
            if exp.var.dynamic['prev_dir'] == 1:
                exp.var.dynamic['track'].append(0)
                exp.var.dynamic['cur_status'] = ' '
            elif exp.var.dynamic['prev_dir'] == 0:
                exp.var.dynamic['prev_dir'] = 1
                exp.var.dynamic['track'].append(0)
                exp.var.dynamic['init_dir'] = 1
                exp.var.dynamic['cur_status'] = '^'
            else:
                exp.var.dynamic['prev_dir'] = 1
                exp.var.dynamic['track'].append(1)
                exp.var.dynamic['n_reversals'] += 1
                exp.var.dynamic['values_at_rev'].append(exp.var.dynamic[
                    'value'])
                exp.var.dynamic['cur_status'] = '+{:}'.format(len(exp.var.
                    dynamic['values_at_rev']))
        else:
            exp.var.dynamic['cur_step'] = 0
            exp.var.dynamic['track'].append(0)
            exp.var.dynamic['cur_status'] = ' '


def Rad_Read(filename):
    """
    Open the averaged data from a rgr file
    return qraw,q,iraw,i,n
    """
    f = open(filename, 'r')
    lignes = f.readlines()
    f.close
    qraw = []
    q = []
    iraw = []
    i = []
    n = []
    for j in range(len(lignes)):
        if lignes[j][0] != '#':
            datas = lignes[j].split('\t')
            qraw.append(int(datas[0]))
            q.append(float(datas[1]))
            n.append(float(datas[3]))
            iraw.append(float(datas[4]))
            i.append(float(datas[5]))
    return qraw, q, n, iraw, i


def __pyexpander_helper2(**kwargs):
    """a helper function needed at runtime.

    This evaluates named arguments.
    """
    return kwargs


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 '+'


@staticmethod
def _unknown_line(line, lineno):
    """
        Called when a line is unknown. Raises a KeyError with a helpful message.
        """
    raise KeyError(
        "Line {} can not be parsed, since we don't recognize the first 6 characters. The line is: {}"
        .format(lineno, line))


def checkNoRepeated(l1, l2):
    """Make sure there are no repeated elements in both lists"""
    for i in l1:
        if i in l2:
            raise Exception('Repeated item ' + str(i))


def helper_find_shared_time(time, res):
    """Helper to find the time which is still free (not allocated) after the given
    time for the whole set of resources combined.

    :param time: the first time step to consider

    :param res: the list of resources:
    """
    if not res:
        return 0
    t = None
    for r in res:
        res_time = r.time_free(time=time)
        if t is None:
            t = res_time
        else:
            t = min(t, res_time)
    return t


def _chunk_dataframe_groups(grouped, chunk_size):
    """chunks a grouped dataframe into groups no larger than chunk_size"""
    for group_key, group_df in grouped:
        for i in range(0, len(group_df), chunk_size):
            yield group_key, group_df.iloc[i:i + chunk_size]


@classmethod
def revoke_all(cls, cur, schema_name, roles):
    """
        Revoke all privileges from schema, tables, sequences and functions for a specific role
        """
    cur.execute(
        'REVOKE ALL ON SCHEMA {0} FROM {1};REVOKE ALL ON ALL TABLES IN SCHEMA {0} FROM {1};REVOKE ALL ON ALL SEQUENCES IN SCHEMA {0} FROM {1};REVOKE ALL ON ALL FUNCTIONS IN SCHEMA {0} FROM {1};'
        .format(schema_name, roles))


def base64_len(s):
    """Return the length of s when it is encoded with base64."""
    groups_of_3, leftover = divmod(len(s), 3)
    n = groups_of_3 * 4
    if leftover:
        n += 4
    return n


def find_diff_nodes(S, T):
    """Returns a list of nodes that have different formulas in graphs S and T."""
    diff_nodes = []
    for node in S:
        s_formula = S.formula_conj(node)
        t_formula = T.formula_conj(node)
        if s_formula != t_formula:
            diff_nodes.append(node)
    return diff_nodes


def delete_constraint(AcceptLanguage=None, Id=None):
    """
    Deletes the specified constraint.
    See also: AWS API Documentation

    :example: response = client.delete_constraint(
        AcceptLanguage='string',
        Id='string'
    )

    :type AcceptLanguage: string
    :param AcceptLanguage: The language code to use for this operation. Supported language codes are as follows:
            'en' (English)
            'jp' (Japanese)
            'zh' (Chinese)
            If no code is specified, 'en' is used as the default.

    :type Id: string
    :param Id: [REQUIRED]
            The identifier of the constraint to delete.

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass