def get_outputs(display):
    """Get collection of display outputs

    :returns: array of display output objects
    """
    root = display.screen().root
    resources = root.xrandr_get_screen_resources()._data
    primaryOutput = root.xrandr_get_output_primary().output
    outputs = []
    for output in resources['outputs']:
        _data = display.xrandr_get_output_info(output, resources[
            'config_timestamp'])._data
        x = y = 0
        if _data['crtc']:
            crtcInfo = display.xrandr_get_crtc_info(_data['crtc'],
                resources['config_timestamp'])
            x = crtcInfo.x
            y = crtcInfo.y
        outputs.append({'isPrimary': output == primaryOutput, 'name': _data
            ['name'], 'connected': not _data['connection'], 'dissabled':
            not _data['crtc'], 'x': x, 'y': y})
    return outputs


def theta_Ca_H_HMW84(T, P):
    """c-c': calcium hydrogen [HMW84]."""
    theta = 0.092
    valid = T == 298.15
    return theta, valid


def formatColorBar(cb, cblabel):
    """
    Format the color bar by adding a fontsize=24 label and changing the tick
    label to size 20.

    Parameters
    ----------
    cb: matplolib.colorbar intance, the color bar to modify
    cblabel: str, label for the color bar

    Returns
    -------
    None
    """
    cb.set_label(cblabel, fontsize=24)
    cb.ax.tick_params(labelsize=20)


def refresh():
    """Refresh the file list

    """
    pass


@classmethod
def from_string(klass, stringkey):
    """This method will create a new Private Key using
        the specified string data.

        :param stringkey: The key in string format
        :returns: A new Private Key
        """
    hexvalue = stringkey.encode('hex')
    return klass(hexvalue)


def parse_header_links(value):
    """Return a dict of parsed link headers proxies.

    i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"

    """
    links = []
    replace_chars = ' \'"'
    for val in value.split(','):
        try:
            url, params = val.split(';', 1)
        except ValueError:
            url, params = val, ''
        link = {}
        link['url'] = url.strip('<> \'"')
        for param in params.split(';'):
            try:
                key, value = param.split('=')
            except ValueError:
                break
            link[key.strip(replace_chars)] = value.strip(replace_chars)
        links.append(link)
    return links


def enlarge_bins(bin_intervals):
    """
    takes a list of consecutive, but not
    directly touching, bin intervals
    and joins them such that the
    end and start of consecutive bins
    is the same.

    >>> bin_intervals = [('chr1', 10, 50, 1), ('chr1', 50, 80, 2),
    ... ('chr2', 10, 60, 3), ('chr2', 70, 90, 4)]
    >>> enlarge_bins(bin_intervals)
    [('chr1', 0, 50, 1), ('chr1', 50, 80, 2), ('chr2', 0, 65, 3), ('chr2', 65, 90, 4)]
    """
    chr_start = True
    for idx in range(len(bin_intervals) - 1):
        chrom, start, end, extra = bin_intervals[idx]
        chrom_next, start_next, end_next, extra_next = bin_intervals[idx + 1]
        if chr_start is True:
            start = 0
            chr_start = False
            bin_intervals[idx] = chrom, start, end, extra
        if chrom == chrom_next and end != start_next:
            middle = start_next - int((start_next - end) / 2)
            bin_intervals[idx] = chrom, start, middle, extra
            bin_intervals[idx + 1] = chrom, middle, end_next, extra_next
        if chrom != chrom_next:
            chr_start = True
    chrom, start, end, extra = bin_intervals[-1]
    bin_intervals[-1] = chrom, start, end, extra
    return bin_intervals


@staticmethod
def can_unpack_subitems(value):
    """Returns False, cannot unpack subitems"""
    return False


@classmethod
def from_hash160(cls, hash160):
    """Creates and address object from a hash160 string"""
    return cls(hash160=hash160)


def add_sub(hub, payload):
    """
    Add a new sub onto the hub for this worker
    """
    hub.pop.sub.add(*payload['args'], **payload['kwargs'])


def merge(oim, order):
    """
    Merges a three dimensional volume into a single plane.
    """
    if not type(order) == bool:
        if not oim.ndim == 3:
            raise Exception('original image must be three dimensional')
        if not len(order) == oim.shape[0]:
            raise Exception('length of order must match first image dimension')
        return oim[order].transpose((1, 0, 2)).reshape([oim.shape[1], -1])
    else:
        return oim


def SizeBenefitSickHosp(t):
    """Sickness hospitalization benefit per policy"""
    return 0


@classmethod
def def_key(cls):
    """ Get the key used to define a data_type definition.

        Override this method to use a different keyword for 'data_type_def'
        """
    return cls.__def_key


def is_fp_closed(obj):
    """
    Checks whether a given file-like object is closed.

    :param obj:
        The file-like object to check.
    """
    try:
        return obj.isclosed()
    except AttributeError:
        pass
    try:
        return obj.closed
    except AttributeError:
        pass
    try:
        return obj.fp is None
    except AttributeError:
        pass
    raise ValueError('Unable to determine whether fp is closed.')


def _find_target_nodes(g):
    """ Return nodes without successors """
    ret = []
    for cn in g:
        cur_succ = list(g.successors(cn))
        if not cur_succ:
            ret.append(cn)
    return ret


def shuffle(**kwargs):
    """
        Create a random problem based on method arguments
        """
    raise NotImplementedError


def snap_cursor_to_active():
    """Snap cursor to active item

    """
    pass


def filterbyname(list, name):
    """Find an element with it's name

    Args:
        list (list): List of elements
        name (str): Element name to look for

    Returns:
        int: Id of element if found, Raises Exception otherwise
    """
    for el in list['results']:
        if el['name'] == name:
            return el['id']
    else:
        raise Exception


@classmethod
def get_all(cls):
    """
        Shorthand to retrieve all data for a model.
        """
    return cls.query.all()


@staticmethod
def merge_list_no_duplicates(a1, a2):
    """
        merge two lists by overwriting the original with the second one if the key exists
        :param a1:
        :param a2:
        :return:
        """
    r = []
    if isinstance(a1, list) and isinstance(a2, list):
        r = a1
        for i in a2:
            if i not in a1:
                r.append(i)
    return r


def jsonname(val):
    """Convert the string in val to a valid json field name.
    """
    return val.replace('.', '_')


def correct_west(longitudes):
    """Map cell lying on 180th meridian to western coordinates"""
    longitudes[longitudes < 0] += 360.0
    return longitudes


def normalize_name(s):
    """Normalizes the name of a file. Used to avoid characters errors and/or to
    get the name of the dataset from a config filename.

    Args:
        s (str): The name of the file.

    Returns:
        new_s (str): The normalized name.
    """
    if s is None:
        return ''
    s = s.replace('.json', '')
    new_s = ''
    for c in s:
        if c in ' \t\n':
            new_s += '_'
        else:
            new_s += c
    return new_s


def find_index(value, key):
    """ Value.get(key) to avoid expection which would raise if empty value in dictionary for a given key """
    if value.get(key) != None:
        return value.get(key)
    else:
        raise ValueError('no dict with the key found')


@classmethod
def get_name(cls):
    """Return test name as used in Django DB.

        Returns:
            str. test name as used in Django DB.
        """
    return cls.__name__


def list_schema_extensions(DirectoryId=None, NextToken=None, Limit=None):
    """
    Lists all schema extensions applied to a Microsoft AD Directory.
    See also: AWS API Documentation

    :example: response = client.list_schema_extensions(
        DirectoryId='string',
        NextToken='string',
        Limit=123
    )

    :type DirectoryId: string
    :param DirectoryId: [REQUIRED]
            The identifier of the directory from which to retrieve the schema extension information.

    :type NextToken: string
    :param NextToken: The ListSchemaExtensions.NextToken value from a previous call to ListSchemaExtensions . Pass null if this is the first call.

    :type Limit: integer
    :param Limit: The maximum number of items to return.

    :rtype: dict
    :return: {
        'SchemaExtensionsInfo': [
            {
                'DirectoryId': 'string',
                'SchemaExtensionId': 'string',
                'Description': 'string',
                'SchemaExtensionStatus': 'Initializing'|'CreatingSnapshot'|'UpdatingSchema'|'Replicating'|'CancelInProgress'|'RollbackInProgress'|'Cancelled'|'Failed'|'Completed',
                'SchemaExtensionStatusReason': 'string',
                'StartDateTime': datetime(2015, 1, 1),
                'EndDateTime': datetime(2015, 1, 1)
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


@classmethod
def get(cls, project_id, feature_name):
    """Retrieve a single modeling feature

        Parameters
        ----------
        project_id : str
            The ID of the project the feature is associated with.
        feature_name : str
            The name of the feature to retrieve

        Returns
        -------
        feature : ModelingFeature
            The requested feature
        """
    path = cls._build_url(project_id, feature_name)
    return cls.from_location(path)


def _object_format(o):
    """ Object arrays containing lists should be printed unambiguously """
    if type(o) is list:
        fmt = 'list({!r})'
    else:
        fmt = '{!r}'
    return fmt.format(o)


def dictmerge(*dict_args):
    """Merge as many dicts you want

    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.

    Args:
        *dict_args (dict): List of dicts

    Returns:
        dict: a new merged dict

    Examples:

        >>> dictmerge({'a':1,'b':2},{'b':3,'c':4})
        {'a': 1, 'b': 3, 'c': 4}

    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result


def cvrect_to_rect(cvrect):
    """Convert cvrect to rect."""
    return [cvrect.left, cvrect.top, cvrect.width, cvrect.height]


def smart_project(angle_limit: float=66.0, island_margin: float=0.0,
    user_area_weight: float=0.0, use_aspect: bool=True, stretch_to_bounds:
    bool=True):
    """This script projection unwraps the selected faces of a mesh (it operates on all selected mesh objects, and can be used to unwrap selected faces, or all faces)

    :param angle_limit: Angle Limit, Lower for more projection groups, higher for less distortion
    :type angle_limit: float
    :param island_margin: Island Margin, Margin to reduce bleed from adjacent islands
    :type island_margin: float
    :param user_area_weight: Area Weight, Weight projections vector by faces with larger areas
    :type user_area_weight: float
    :param use_aspect: Correct Aspect, Map UVs taking image aspect ratio into account
    :type use_aspect: bool
    :param stretch_to_bounds: Stretch to UV Bounds, Stretch the final output to texture bounds
    :type stretch_to_bounds: bool
    """
    pass


def message_context_from_sys_wide_wf_context(ctx):
    """Build a message context from a CloudifyWorkflowContext instance"""
    return {'blueprint_id': None, 'deployment_id': None, 'execution_id':
        ctx.execution_id, 'workflow_id': ctx.workflow_id, 'tenant': {'name':
        ctx.tenant_name}}


def identity(value):
    """
    Return the passed in object.
    """
    return value


def tokenize(text):
    """
    Convert a text to tokens.

    Example:
        >>> print(tokenize('Hello world!'))
        ['Hello', 'world', '!']

    :param    text: Text to tokenize.
    :type     text: str
    :return:        List of tokens.
    :rtype:         list
    """
    delimiters = ['.', ',', ':', ';', '?', '!', '<', '>', '[', ']', '(',
        ')', '"']
    for delimiter in delimiters:
        text = text.replace(delimiter, ' ' + delimiter + ' ')
    tokens = []
    for token in text.split(' '):
        if len(token) > 0:
            tokens.append(token)
    return tokens


def upgrade():
    """Upgrade database."""
    pass


@staticmethod
def __move_next_result_index(match_result, current_index):
    """
        取得下一个有效的匹配节点位置（对于当前节点已匹配上的情况下，不能造成关键字重叠的情况）

        @param {[type]} match_result - <description>
        @param {[type]} current_index - <description>

        @returns {int} - 下一个有效的可匹配位置，如果超过匹配清单大小，返回清单大小

        """
    _maxlen = len(match_result)
    _next_index = current_index + 1
    while _next_index < _maxlen:
        if match_result[_next_index][2] >= match_result[current_index][3]:
            return _next_index
        else:
            _next_index = _next_index + 1
    return _maxlen


def collapse_json(text, indent=12):
    """Compacts a string of json data by collapsing whitespace after the
    specified indent level

    NOTE: will not produce correct results when indent level is not a multiple
    of the json indent level
    """
    initial = ' ' * indent
    out = []
    sublevel = []
    pending = None
    for line in text.splitlines():
        if line.startswith(initial):
            if line[indent] == ' ':
                if pending:
                    sublevel.append(pending)
                    pending = None
                item = line.strip()
                sublevel.append(item)
                if item.endswith(','):
                    sublevel.append(' ')
            elif sublevel:
                sublevel.append(line.strip())
                out.append(''.join(sublevel))
                sublevel = []
            else:
                if pending:
                    out.append(pending)
                pending = line.rstrip()
        else:
            if pending:
                out.append(pending)
                pending = None
            if sublevel:
                out.append(''.join(sublevel))
            out.append(line)
    return '\n'.join(out)


def writecodefile(filename, code, language):
    """Create a python file and write the code to it."""
    if language == 'python':
        with open(filename + '.py', 'w') as pyfile:
            pyfile.write(code)
            pyfile.close()
    elif language == 'bash':
        with open(filename + '.sh', 'w') as bashfile:
            bashfile.write(code)
            bashfile.close()
    elif language == 'R' or 'r':
        with open(filename + '.R', 'w') as rfile:
            rfile.write(code)
            rfile.close()
    else:
        raise NotImplementedError('%s is unsupported.' % language)


@staticmethod
def get_name_n_ix(name, deflt=None):
    """Extract name and subscription from string like 'name[ix]'"""
    deflt = '' if deflt is None else deflt
    i = name.find('[')
    j = name.rfind(']')
    if i >= 0 and j >= i:
        n = name[:i].strip()
        x = name[i + 1:j].strip()
    else:
        n = name
        x = deflt
    return n, x


@classmethod
def index(cls, state):
    """
        Return the `state` index in the state space.

        :param state: state representation
        :type state: OrderedDict
        :rtype: int
        """
    i = 0
    index = 0
    for _, value in state.items():
        index += value * 2 ** i
        i += 1
    return index


def can_copy(brain):
    """View copy button associated to this brain
        """


def compare_serial_containment(siglist, downsample=False):
    """Compare all combinations of signatures and return a matrix
    of containments. Processes combinations serially on a single
    process. Best to use when there is few signatures.

    :param list siglist: list of signatures to compare
    :param boolean downsample by max_hash if True
    :return: np.array similarity matrix
    """
    import numpy as np
    n = len(siglist)
    containments = np.ones((n, n))
    for i in range(n):
        for j in range(n):
            containments[i][j] = siglist[j].contained_by(siglist[i],
                downsample=downsample)
    return containments


@classmethod
def from_points(cls, p1, p2):
    """Create a rectangle, knowing 2 points on the plane.
        We assume that p1 is in the upper left (closer to the origin)

        :param p1: Point instance
        :param p2: Point instance
        :return: a Point instance
        """
    inst = cls()
    inst._p1 = p1
    inst._p2 = p2
    return inst


@staticmethod
def in_out_expo(progress):
    """.. image:: images/anim_in_out_expo.png
        """
    if progress == 0:
        return 0.0
    if progress == 1.0:
        return 1.0
    p = progress * 2
    if p < 1:
        return 0.5 * pow(2, 10 * (p - 1.0))
    p -= 1.0
    return 0.5 * (-pow(2, -10 * p) + 2.0)


def partitionABCD(ABCD, m=None, r=None):
    """Partition ABCD into A, B, C, D for an m-input r-output system.

    The :math:`ABCD` matrix is defined as:

    .. math::

        ABCD =
            \\left[
            \\begin{array}{c|c}
              A & B \\\\ \\hline
              C & D
            \\end{array}
            \\right].

    The matrices :math:`A`, :math:`B`, :math:`C` and :math:`D` define the
    evolution of a generic linear discrete time invariant system under study
    through the state-space representation:

    .. math::

        x(k + 1) = Ax(k) + Bu(k)

    .. math::

        y(k) = Cx(k) + Du(k)

    The matrices are:

    * :math:`A` is the state matrix, dimensions :math:`(n, n)`, :math:`n` being
      the number of states in the system,

    * :math:`B` is the input matrix, dimensions :math:`(n, m)`, :math:`m` being
      the number of inputs in the system,

    * :math:`C` is the output matrix, dimensions :math:`(r, n)`, :math:`r`
      being the number of outputs in the system,

    * :math:`D` is the feedthrough matrix, dimensions :math:`(r, m)`.

    The vectors are:

    * :math:`x(k)` the state sequence, of length :math:`n`,

    * :math:`u(k)`, the input sequence, of length :math:`m`, and

    * :math:`y(k)` is the output sequence, of length :math:`r`.

    **Parameters:**

    ABCD: ndarray
       The ABCD matrix to be partitioned

    m: int, optional
       The number of inputs in the system. It will be calculated from the ABCD matrix,
       if not provided.

    r: int, optional
       The number of outputs in the system. It will be calculated from ``m`` and the
       ABCD matrix, if not provided.

    **Returns:**

    A, B, C, D: tuple of ndarrays
                The partitioned matrices.

    .. seealso::

        :ref:`Modulator model: loop filter <loop-filter-label>` for a discussion of
        the ABCD matrix in the particular case of a delta-sigma modulator loop filter.

    """
    if m is None:
        n = min(ABCD.shape) - 1
        m = ABCD.shape[1] - n
        if r is None:
            r = ABCD.shape[0] - n
    else:
        n = ABCD.shape[1] - m
        if r is None:
            r = ABCD.shape[0] - n
    if not ABCD.shape[0] == n + r and ABCD.shape[1] == n + m:
        raise ValueError('Mismatched ABCD matrix and input/output counts:' +
            'ABCD: %dx%d, n: %d, m: %d, r: %d' % (ABCD.shape[0], ABCD.shape
            [1], n, m, r))
    A = ABCD[:n, :n]
    B = ABCD[:n, n:n + m]
    C = ABCD[n:n + r, :n]
    D = ABCD[n:n + r, n:n + m]
    return A, B, C, D


def to_native_str(s):
    """
    Make sure this string-like thing is a native str. If it's bytes, decode it,
    but only allow ascii characters.
    """
    if not isinstance(s, str):
        return s.decode('ascii', 'strict')
    return s


def search_items(d, search_kv):
    """ Function that search dictionary (param: d) by the value input (search_v)

    parameters:
    d (dictionary): The content of the text file as dictionary
    search_val (str): Search by dictionary's value

    returns:
    dict: Search result of param: search_v as dictionary
     """
    d_result = {}
    for key, value in d.items():
        if key.upper() == search_kv.upper():
            d_result[key.upper()] = value
    for key, value in d.items():
        x = 0
        while x < len(value):
            if value[x].lower() == search_kv.lower():
                d_result[key.upper()] = value
            x += 1
    return d_result


def network_batch_lpf(network, snapshots=None):
    """Batched linear power flow with numpy.dot for several snapshots."""
    raise NotImplementedError('Batch linear power flow not supported yet.')


def getArguments(parser):
    """Provides additional validation of the arguments collected by argparse."""
    args = parser.parse_args()
    if args.order < 0 or args.order > 5:
        parser.error('The order has to be a number between 0 and 5.')
    return args


@classmethod
def from_value(cls, name, value, tags=None, interval_ms=None, end_time_ms=None
    ):
    """Create a SummaryMetric with a single value

        :param name: The name of the metric.
        :type name: str
        :param value: The metric value.
        :type value: int or float
        :param tags: (optional) A set of tags that can be used to filter this
            metric in the New Relic UI.
        :type tags: dict
        :param interval_ms: (optional) The interval of time in milliseconds over which
            the metric was recorded.
        :type interval_ms: int
        :param end_time_ms: (optional) A unix timestamp in milliseconds representing
            the end time of the metric. Defaults to time.time() * 1000
        :type end_time_ms: int
        """
    return cls(name=name, count=1, sum=value, min=value, max=value, tags=
        tags, interval_ms=interval_ms, end_time_ms=end_time_ms)


@staticmethod
def version_info_from_coverage_data(coverage):
    """
        Extract various version fields from the given coverage data.

        Certain coverage data formats store version information in the data,
        e.g. the revision or the branch. This method is used by the submit
        method to extract this information.

        The extracted fields currently include:

        revision
        branch

        @type coverage: string
        @param coverage: Coverage Data

        @return Dictionary with version data
        @rtype dict
        """
    ret = {}
    if 'git' in coverage and 'head' in coverage['git']:
        ret['revision'] = coverage['git']['head']['id']
        ret['branch'] = coverage['git']['branch']
        return ret
    else:
        raise RuntimeError('Unknown coverage format')


def create(**data):
    """ Returns the object to be added
        """


def behavior(f):
    """Decorator for declaring a function as behavior.

    Use as::

        @behavior
        def fun(x, y, self, msg):
            ...

    And create or become this behavior by passing the two arguments
    `x` and `y`.

    """
    return f


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


def jump_to_target_button():
    """Switch to the target object or bone

    """
    pass


def embedded_data(symbol_name):
    """Reads a symbol from the uWSGI binary image.

    * http://uwsgi.readthedocs.io/en/latest/Embed.html

    .. warning:: Bytes are returned for Python 3.

    :param str|unicode symbol_name: The symbol name to extract.

    :rtype: bytes|str

    :raises ValueError: If symbol is unavailable.
    """


def restore_table_from_cluster_snapshot(ClusterIdentifier=None,
    SnapshotIdentifier=None, SourceDatabaseName=None, SourceSchemaName=None,
    SourceTableName=None, TargetDatabaseName=None, TargetSchemaName=None,
    NewTableName=None):
    """
    Creates a new table from a table in an Amazon Redshift cluster snapshot. You must create the new table within the Amazon Redshift cluster that the snapshot was taken from.
    You cannot use RestoreTableFromClusterSnapshot to restore a table with the same name as an existing table in an Amazon Redshift cluster. That is, you cannot overwrite an existing table in a cluster with a restored table. If you want to replace your original table with a new, restored table, then rename or drop your original table before you call RestoreTableFromClusterSnapshot . When you have renamed your original table, then you can pass the original name of the table as the NewTableName parameter value in the call to RestoreTableFromClusterSnapshot . This way, you can replace the original table with the table created from the snapshot.
    See also: AWS API Documentation

    :example: response = client.restore_table_from_cluster_snapshot(
        ClusterIdentifier='string',
        SnapshotIdentifier='string',
        SourceDatabaseName='string',
        SourceSchemaName='string',
        SourceTableName='string',
        TargetDatabaseName='string',
        TargetSchemaName='string',
        NewTableName='string'
    )

    :type ClusterIdentifier: string
    :param ClusterIdentifier: [REQUIRED]
            The identifier of the Amazon Redshift cluster to restore the table to.

    :type SnapshotIdentifier: string
    :param SnapshotIdentifier: [REQUIRED]
            The identifier of the snapshot to restore the table from. This snapshot must have been created from the Amazon Redshift cluster specified by the ClusterIdentifier parameter.

    :type SourceDatabaseName: string
    :param SourceDatabaseName: [REQUIRED]
            The name of the source database that contains the table to restore from.

    :type SourceSchemaName: string
    :param SourceSchemaName: The name of the source schema that contains the table to restore from. If you do not specify a SourceSchemaName value, the default is public .

    :type SourceTableName: string
    :param SourceTableName: [REQUIRED]
            The name of the source table to restore from.

    :type TargetDatabaseName: string
    :param TargetDatabaseName: The name of the database to restore the table to.

    :type TargetSchemaName: string
    :param TargetSchemaName: The name of the schema to restore the table to.

    :type NewTableName: string
    :param NewTableName: [REQUIRED]
            The name of the table to create as a result of the current request.

    :rtype: dict
    :return: {
        'TableRestoreStatus': {
            'TableRestoreRequestId': 'string',
            'Status': 'PENDING'|'IN_PROGRESS'|'SUCCEEDED'|'FAILED'|'CANCELED',
            'Message': 'string',
            'RequestTime': datetime(2015, 1, 1),
            'ProgressInMegaBytes': 123,
            'TotalDataInMegaBytes': 123,
            'ClusterIdentifier': 'string',
            'SnapshotIdentifier': 'string',
            'SourceDatabaseName': 'string',
            'SourceSchemaName': 'string',
            'SourceTableName': 'string',
            'TargetDatabaseName': 'string',
            'TargetSchemaName': 'string',
            'NewTableName': 'string'
        }
    }

    """
    pass


def get_next_version_expiration_datetime():
    """Get the expiration datetime of the next version, or None
        if there is no expiration datetime.
        """


def example_confidence_interval(ax=None, seaborn=False, **options):
    """
    draw pseudo confidence interval for a regression in a matplotlib

    @param      ax          axis
    @param      seaborn     uses *seaborn* instead of *matplotlib*
    @param      options     look at the code
    @return                 ax
    """
    import matplotlib.pyplot as plt
    if ax is None:
        _, ax = plt.subplots(nrows=1, ncols=1, figsize=options.get(
            'figsize', (5, 5)))
    import scipy
    import numpy
    nx, nboot = 22, 400
    x = scipy.linspace(0.0, 1.0, nx)
    data = x + numpy.random.normal(loc=0.0, scale=0.1, size=nx)
    yp = scipy.polyfit(x, data, 1)
    y = scipy.polyval(yp, x)
    if seaborn:
        from seaborn import regplot
        return regplot(x, data, ax=ax)
    else:
        r = data - y
        for i in range(nboot):
            pc = scipy.polyfit(x, y + r[scipy.random.randint(0, nx - 1, nx)], 1
                )
            ax.plot(x, scipy.polyval(pc, x), 'k-', linewidth=2, alpha=3.0 /
                float(nboot))
        ax.plot(x, y, 'k-')
        ax.plot(x, data, 'ko')
        return ax


@staticmethod
def normalize_cumulative(series):
    """Normalize to maximum value"""
    return series / series.max()


def requires_mfa(profile):
    """Checks to see if the given profile requires MFA.

    Parameters
    ----------
    - profile - the profile to inspect

    Returns
    -------
    True if the profile requires MFA, False if it doesn't.
    """
    return 'mfa_serial' in profile


@classmethod
def generate_name(cls, counter_name, display_name=None, prefix=None, fill=3):
    """Generate a name based on a counter

        :param str counter_name: name of the counter in the database
        :param str display_name: pretty name to show user (defaults to ``counter_name``)
        :param str prefix: prefix the generated name with this
        :param int fill: number of zeros to fill with
        :returns: a generated name
        :rtype: :class:`str`
        """
    prefix = prefix + '-' if prefix else ''
    counter = cls.get_counter(name=counter_name)
    index = str(counter).zfill(fill)
    name = prefix + (display_name or counter_name) + '-' + index
    cls.incr_counter(name=counter_name)
    return name


def setVerbosity(verbosity_level):
    """ Copy verbosity to a variable that is global for this file.

    Parameters
    -----------
    verbosity_level : int
        level of verbosity
    """
    global verbosity
    verbosity = verbosity_level


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


def c2min(f, c1, c2):
    """Take the minimum value between two columns in a dataframe.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the two columns ``c1`` and ``c2``.
    c1 : str
        Name of the first column in the dataframe ``f``.
    c2 : str
        Name of the second column in the dataframe ``f``.

    Returns
    -------
    min_val : float
        The minimum value of the two columns.

    """
    min_val = min(f[c1], f[c2])
    return min_val


def _check_type(obj, base, allow_none):
    """Check whether an object is an instance of a base type.

    Parameters
    ----------
    obj : object
        The object to be validated.

    base : type
        The base type that `obj` should be an instance of.

    allow_none : bool
        Indicates whether the value None should be allowed to pass through.

    Returns
    -------
    obj : base type or None
        The validated object.

    Raises
    ------
    TypeError
        If `obj` is not an instance of `base`.
    """
    if allow_none and obj is None:
        return None
    if isinstance(obj, base):
        return obj
    expect = base.__name__
    actual = type(obj).__name__
    raise TypeError(f'Invalid type. Expected: {expect}. Actual: {actual}.')


def get_measured_by_datatype(data):
    """ Get unique list of species for each 'source' label in data.

    Parameters
    ----------
    data : ExperimentalData

    Returns
    -------
    measured, sig_measured : dict, dict
        Dictionaries where keys are 'source' and values are sets of ids.

    """
    measured = dict()
    sig_measured = dict()
    for i in data.exp_methods:
        sig_measured[i] = set(data[i].sig.id_list)
        measured[i] = set(data[i].id_list)
    return measured, sig_measured


def file_read_seek_len(filename, from_byte, step_byte):
    """str, int, int->byte

    Read a file from particular byte to somewhere.

    Used for multi thread uploading.
    """
    with open(filename, 'rb') as f:
        f.seek(from_byte)
        return f.read(step_byte)


def import_example(data='random', n_samples=1000, n_feat=10):
    """Import example dataset from sklearn.

    Parameters
    ----------
    data : str
        'random' : str, two-class
        'breast' : str, two-class
        'titanic': str, two-class
        'iris' : str, multi-class
    n_samples : int, optional
        Number of samples to generate. The default is 1000.
    n_feat : int, optional
        Number of features to generate. The default is 10.

    Returns
    -------
    tuple (X,y).
        X is the dataset and y the response variable.

    """
    try:
        from sklearn import datasets
    except:
        print('This requires: <pip install sklearn>')
        return None, None
    if data == 'iris':
        X, y = datasets.load_iris(return_X_y=True)
    elif data == 'breast':
        X, y = datasets.load_breast_cancer(return_X_y=True)
    elif data == 'titanic':
        X, y = datasets.fetch_openml('titanic', version=1, as_frame=True,
            return_X_y=True)
    elif data == 'random':
        X, y = datasets.make_classification(n_samples=n_samples, n_features
            =n_feat)
    return X, y


def total_requests():
    """Returns the total number of requests managed so far by the pool of uWSGI workers.

    :rtype: int
    """
    return 0


def delete_bucket_website(Bucket=None):
    """
    This operation removes the website configuration from the bucket.
    See also: AWS API Documentation

    :example: response = client.delete_bucket_website(
        Bucket='string'
    )

    :type Bucket: string
    :param Bucket: [REQUIRED]

    """
    pass


def dgl_csr_neighbor_uniform_sample(*seed_arrays, **kwargs):
    """This operator samples sub-graphs from a csr graph via an
    uniform probability. The operator is designed for DGL.

    The operator outputs three sets of NDArrays to represent the sampled results
    (the number of NDArrays in each set is the same as the number of seed NDArrays):
    1) a set of 1D NDArrays containing the sampled vertices, 2) a set of CSRNDArrays representing
    the sampled edges, 3) a set of 1D NDArrays indicating the layer where a vertex is sampled.
    The first set of 1D NDArrays have a length of max_num_vertices+1. The last element in an NDArray
    indicate the acutal number of vertices in a subgraph. The third set of NDArrays have a length
    of max_num_vertices, and the valid number of vertices is the same as the ones in the first set.

    Example:

       .. code:: python

      shape = (5, 5)
      data_np = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], dtype=np.int64)
      indices_np = np.array([1,2,3,4,0,2,3,4,0,1,3,4,0,1,2,4,0,1,2,3], dtype=np.int64)
      indptr_np = np.array([0,4,8,12,16,20], dtype=np.int64)
      a = mx.nd.sparse.csr_matrix((data_np, indices_np, indptr_np), shape=shape)
      a.asnumpy()
      seed = mx.nd.array([0,1,2,3,4], dtype=np.int64)
      out = mx.nd.contrib.dgl_csr_neighbor_uniform_sample(a, seed, num_args=2, num_hops=1, num_neighbor=2, max_num_vertices=5)

      out[0]
      [0 1 2 3 4 5]
      <NDArray 6 @cpu(0)>

      out[1].asnumpy()
      array([[ 0,  1,  0,  3,  0],
             [ 5,  0,  0,  7,  0],
             [ 9,  0,  0, 11,  0],
             [13,  0, 15,  0,  0],
             [17,  0, 19,  0,  0]])

      out[2]
      [0 0 0 0 0]
      <NDArray 5 @cpu(0)>

    Defined in src/operator/contrib/dgl_graph.cc:L784
    This function support variable length of positional input.

    Parameters
    ----------
    csr_matrix : Symbol
        csr matrix
    seed_arrays : Symbol[]
        seed vertices
    num_hops : long, optional, default=1
        Number of hops.
    num_neighbor : long, optional, default=2
        Number of neighbor.
    max_num_vertices : long, optional, default=100
        Max number of vertices.

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

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


def lambd_NH3_Li_CB89(T, P):
    """n-c: ammonia lithium [CB89]."""
    lambd = -0.038
    valid = T == 298.15
    return lambd, valid


def resolve(path):
    """Resolve a path to a class.

        The path can be any string. It is the responsibility of the resolver
        to maintain the mapping from path to class.
        """


@staticmethod
def merge_two_dicts(x, y):
    """A helper method for Python 2.7 to 'zip' two dictionary objects

        :param x: This dictionary will be copied and y appended to the copy.
        :type x: dict.
        :param y: This dictionary will be appended with a copy of x.
        :type y: dict.
        :returns: dict

        """
    z = x.copy()
    z.update(y)
    return z


def _file_iter_range(fp, offset, bytes, maxread=1024 * 1024, close=False):
    """ Yield chunks from a range in a file, optionally closing it at the end.
        No chunk is bigger than maxread. """
    fp.seek(offset)
    while bytes > 0:
        part = fp.read(min(bytes, maxread))
        if not part:
            break
        bytes -= len(part)
        yield part
    if close:
        fp.close()


def multires_external_pack():
    """Pack displacements from an external file

    """
    pass


def days():
    """Returns maximum gotten days."""


def get_config_for(context):
    """Returns the workflow config for the passed context.
        `None` is returned if the context has no workflow configured
        for publishing.
        """


def quiet_int(value_to_convert, default_upon_failure=0):
    """
	Attempt to convert the given value to an integer. If there is any problem
	during the conversion, simply return 'default_upon_failure'.
	"""
    result = default_upon_failure
    try:
        result = int(value_to_convert)
    except:
        pass
    return result


def compute_shell_and_tube_material_factor(A, a, b):
    """
    Return the material factor for shell and tubes given the area [A; ft^3]
    and material-dependent coefficients `a` and `b`.

    Notes
    -----
    Material factors are computed using Eq. 16.44 in [1]_:

    :math:`F_M = a + \\left(\\frac{A}{100.0}\\right)^b`

    """
    return a + (A / 100.0) ** b


def update_dictionary(default, updates):
    """
    Updates default dictionary with elements from
    optional dictionary.

    @param default: A python dictionary containing the minimal
    required arguments to create a CLI object.
    @param updates: A python dictionary containing attributes
    to overwrite on default dictionary.

    @return default: The modified default python dictionary.
    """
    if updates:
        for key in set(default.keys()).intersection(set(updates.keys())):
            default[key] = updates[key]
    return default


@classmethod
def empty(cls):
    """This is a class method which returns an empty type system."""
    x = cls(base_types=set(), template_types={}, refined_types={},
        humannames={}, type_aliases={}, cpp_types={}, numpy_types={},
        from_pytypes={}, cython_ctypes={}, cython_cytypes={},
        cython_pytypes={}, cython_cimports={}, cython_cyimports={},
        cython_pyimports={}, cython_functionnames={}, cython_classnames={},
        cython_c2py_conv={}, cython_py2c_conv={})
    del x.extra_types
    del x.dtypes
    del x.stlcontainers
    return x


def sin(data=None, name=None, attr=None, out=None, **kwargs):
    """Computes the element-wise sine of the input array.

    The input should be in radians (:math:`2\\pi` rad equals 360 degrees).

    .. math::
       sin([0, \\pi/4, \\pi/2]) = [0, 0.707, 1]

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

       - sin(default) = default
       - sin(row_sparse) = row_sparse
       - sin(csr) = csr

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

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

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

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


def add_tors(tors1, tors2):
    """
    **Description:** adds tors2 to tors 1
    """
    out_tors = tors1
    for torsion_i in tors2:
        found = 0
        for torsion_j in out_tors:
            if torsion_i == torsion_j:
                found = 1
        if found == 0:
            out_tors.append(torsion_i)
    return out_tors


@staticmethod
def _trim_response(response):
    """
            trim oy response
            ________________
            Parameters:
                response :
                    response from oy server

            Return:
                trimmed_response :
                    trimmed response from oy server without status object
        """
    response.pop('status')
    return response


def get_download_url(preview=False, request=None, hires=False, thumbnail=False
    ):
    """Return an URL to download the corresponding image. If ``hires``
        is True, the URL to the original version will be returned and
        if ``thumbnail`` is True the URL to the thumbnail will be returned
        instead.
        """


def id_mapping(IDs1, IDs2, uniq_ref_only=True, IDs2_sorted=False):
    """
    Mapping IDs2 to IDs1. IDs1 (ref id) can have repeat values, but IDs2 need
    to only contain unique ids.
    Therefore, IDs2[rv_idx] will be the same as IDs1.

    Parameters
    ----------
    IDs1 : array_like or list
        ids for reference.
    IDs2 : array_like or list
        ids waiting to map.

    Returns
    -------
    RV_idx : array_like, the same length of IDs1
        The index for IDs2 mapped to IDs1. If an id in IDs1 does not exist
        in IDs2, then return a None for that id.
    """
    idx1 = sorted(range(len(IDs1)), key=IDs1.__getitem__)
    if IDs2_sorted:
        idx2 = range(len(IDs2))
    else:
        idx2 = sorted(range(len(IDs2)), key=IDs2.__getitem__)
    RV_idx1, RV_idx2 = [], []
    i, j = 0, 0
    while i < len(idx1):
        if j == len(idx2) or IDs1[idx1[i]] < IDs2[idx2[j]]:
            RV_idx1.append(idx1[i])
            RV_idx2.append(None)
            i += 1
        elif IDs1[idx1[i]] == IDs2[idx2[j]]:
            RV_idx1.append(idx1[i])
            RV_idx2.append(idx2[j])
            i += 1
            if uniq_ref_only:
                j += 1
        elif IDs1[idx1[i]] > IDs2[idx2[j]]:
            j += 1
    origin_idx = sorted(range(len(RV_idx1)), key=RV_idx1.__getitem__)
    RV_idx = [RV_idx2[i] for i in origin_idx]
    return RV_idx


def cancel_spot_fleet_requests(DryRun=None, SpotFleetRequestIds=None,
    TerminateInstances=None):
    """
    Cancels the specified Spot fleet requests.
    After you cancel a Spot fleet request, the Spot fleet launches no new Spot instances. You must specify whether the Spot fleet should also terminate its Spot instances. If you terminate the instances, the Spot fleet request enters the cancelled_terminating state. Otherwise, the Spot fleet request enters the cancelled_running state and the instances continue to run until they are interrupted or you terminate them manually.
    See also: AWS API Documentation

    Examples
    This example cancels the specified Spot fleet request and terminates its associated Spot Instances.
    Expected Output:
    This example cancels the specified Spot fleet request without terminating its associated Spot Instances.
    Expected Output:

    :example: response = client.cancel_spot_fleet_requests(
        DryRun=True|False,
        SpotFleetRequestIds=[
            'string',
        ],
        TerminateInstances=True|False
    )

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

    :type SpotFleetRequestIds: list
    :param SpotFleetRequestIds: [REQUIRED]
            The IDs of the Spot fleet requests.
            (string) --

    :type TerminateInstances: boolean
    :param TerminateInstances: [REQUIRED]
            Indicates whether to terminate instances for a Spot fleet request if it is canceled successfully.

    :rtype: dict
    :return: {
        'UnsuccessfulFleetRequests': [
            {
                'SpotFleetRequestId': 'string',
                'Error': {
                    'Code': 'fleetRequestIdDoesNotExist'|'fleetRequestIdMalformed'|'fleetRequestNotInCancellableState'|'unexpectedError',
                    'Message': 'string'
                }
            },
        ],
        'SuccessfulFleetRequests': [
            {
                'SpotFleetRequestId': 'string',
                'CurrentSpotFleetRequestState': 'submitted'|'active'|'cancelled'|'failed'|'cancelled_running'|'cancelled_terminating'|'modifying',
                'PreviousSpotFleetRequestState': 'submitted'|'active'|'cancelled'|'failed'|'cancelled_running'|'cancelled_terminating'|'modifying'
            },
        ]
    }

    """
    pass


def put_object_string(swift, container, object_name, contents):
    """Put the object contents as a string """
    try:
        contents = contents.decode('utf-8')
    except AttributeError:
        pass
    return swift.put_object(container, object_name, contents)


def ask_user_if_they_have_correction_information():
    """Ask user if they have destination-correction information."""
    print(
        """If you have any destination-corrections for packages, you are in the right place.
If you don't have any corrections, no problem--just type "q" or "quit" and hit Enter.
If you do have information, type any other key--like "y" (for yes), or the Enter key.
Just keep in mind that if your distance file indicates that any packages
are known to have the wrong destination, but you do not supply a correction,
those packages will not get delivered. Remember--to exit this optional step,
just press "q" or "quit",  then Enter, to skip it."""
        )
    ask_user = input('')
    return ask_user.lower().strip() not in ('q', 'quit')


def is_x11_compositing_enabled():
    """Is X11 compositing manager running.
    """
    try:
        from AnyQt.QtX11Extras import QX11Info
    except ImportError:
        return False
    if hasattr(QX11Info, 'isCompositingManagerRunning'):
        return QX11Info.isCompositingManagerRunning()
    else:
        return False


@staticmethod
def metadata_id(item):
    """Extracts the identifier from a Docker Hub item."""
    return str(item['fetched_on'])


def testArgs(args):
    """
    Tests arguments for sanity:
    - numFiles is a positive number
    :param args:
    :return:
    """
    if args.numFiles < 2:
        raise ValueError('Number of files must be greater than one.')


def mark_doc(doc, wids, mark=None, pos=None):
    """
    Given a list of words and a set of word positions, mark the words in those positions.
    :param list doc: a list of words (strings)
    :param set wids: the positions of the words to be marked
    :param string mark: a string that sets the mark that will be applied
                        to each of the selected words
    :param string pos: can be one of {"prefix", "suffix"}
    :return: the marked list of words
    """
    if mark is None:
        mark = 'NEG'
    if pos is None:
        pos = 'suffix'
    marked_doc = []
    for i, tok in enumerate(doc):
        if i in wids:
            if pos == 'prefix':
                word = mark + '_' + tok
            else:
                word = tok + '_' + mark
            marked_doc.append(word)
        else:
            marked_doc.append(tok)
    return marked_doc


def _sorted_edge(u, v):
    """Returns a sorted edge.

    During the construction of a line graph for undirected graphs, the data
    structure can be a multigraph even though the line graph will never have
    multiple edges between its nodes.  For this reason, we must make sure not
    to add any edge more than once.  This requires that we build up a list of
    edges to add and then remove all duplicates.  And so, we must normalize
    the representation of the edges.

    """
    return (u, v) if u <= v else (v, u)


def driver_button_add():
    """Add driver for the property under the cursor

    """
    pass


def send_warnings_and_remove():
    """Send warnings to disabled users and remove them if needed.

        All users, that have their delivery disabled, get warnings about being
        un-subscribed until Mailinglist's maximum configured numbered of
        warnings are sent and then remove the user.
        """


def scale(cam_file, x_scale, y_scale):
    """ Scale a Cam file by a specified amount in the X and Y directions.

    Parameters
    ----------
    cam_file : :class:`gerber.cam.CamFile` subclass
        Gerber or Excellon file to scale

    x_scale : float
        X-axis scale factor

    y_scale : float
        Y-axis scale factor

    Returns
    -------
    cam_file : :class:`gerber.cam.CamFile` subclass
        An scaled deep copy of the source file.
    """
    pass


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


@classmethod
def destroy(cls, *ids):
    """Delete the records with the given ids
        :type ids: list
        :param ids: primary key ids of records
        """
    for pk in ids:
        cls.find(pk).delete()
    cls.session.flush()


def bake_to_keyframes(frame_start: int=1, frame_end: int=250, step: int=1):
    """Bake rigid body transformations of selected objects to keyframes

    :param frame_start: Start Frame, Start frame for baking
    :type frame_start: int
    :param frame_end: End Frame, End frame for baking
    :type frame_end: int
    :param step: Frame Step, Frame Step
    :type step: int
    """
    pass


def is_gzipped(f):
    """Check if file gzipped."""
    with open(f, 'rb') as rpkm_file:
        magic = rpkm_file.read(2)
    return magic == '\x1f\x8b'


@classmethod
def __factory(cls, data):
    """
        This factory makes that any returned value is a measure
        instead of a float.
        """
    return cls(data)


@classmethod
def _get_apic_classes(cls):
    """
        Get the APIC classes used by this acitoolkit class.

        :returns: list of strings containing APIC class names
        """
    resp = ['arpAdjEp', 'arpDb']
    return resp


def p_expr_parens(p):
    """expr : LPAREN expr RPAREN"""
    p[0] = p[2]


def _process_one_file(msg, msgdata):
    """Process one queue file.

        :param msg: The message object.
        :type msg: `email.message.Message`
        :param msgdata: The message metadata.
        :type msgdata: dict
        """


def _iter_factors(starting_factor=1):
    """Generator yielding something like 1, 3, 10, 30, 100, 300 etc.

    The series starts from starting_factor.
    """
    while True:
        yield starting_factor
        yield starting_factor * 3
        starting_factor *= 10


def conegrowth(d, do, Y, fitMax=0, fitMin=0, ds=0.0):
    """Find the additional length accrued by a tapered roller bearing due
    the press fit of the bearing cone on a shaft.

    Parameters
    ==========

    d : float
        bore diameter of the cone

    do : float
        mean outside diameter of the cone

    Y : Y factor

    fitMax : float
        Maximum diametral interference between the cone and shaft.

    fitMin : float
        Minimum diametral interference between the cone and shaft.

    ds : float
        bore diameter of the shaft.  default: 0.0

    Cone growth calculation based on the equation provided in Timken's catalog.
    (K = Y * .9725)

    Returns
    =======

    out: tuple
        (conegrowthMax, conegrowthMin)... i.e., axial length increase
    """
    K = Y * 0.9725
    try:
        conegrowthMin = 0.5 * (K / 0.39) * (d / do * (1 - (ds / d) ** 2) /
            (1 - (ds / do) ** 2)) * abs(fitMin)
        conegrowthMax = 0.5 * (K / 0.39) * (d / do * (1 - (ds / d) ** 2) /
            (1 - (ds / do) ** 2)) * abs(fitMax)
        return conegrowthMax, conegrowthMin
    except ZeroDivisionError:
        return 0.0, 0.0


@classmethod
def get_value(cls, name):
    """
        Given a type name, retrieve the corresponding value from the FIX specification.
        :param name: a type name
        :return: the value associated with the type name.
        """
    return cls.__dict__[name]


def sanitize_secrets(secrets):
    """ misc utilities  for Cloudflare API"""
    redacted_phrase = 'REDACTED'
    if secrets is None:
        return None
    secrets_copy = secrets.copy()
    if 'password' in secrets_copy:
        secrets_copy['password'] = redacted_phrase
    elif 'X-Auth-Key' in secrets_copy:
        secrets_copy['X-Auth-Key'] = redacted_phrase
    elif 'X-Auth-User-Service-Key' in secrets_copy:
        secrets_copy['X-Auth-User-Service-Key'] = redacted_phrase
    elif 'Authorization' in secrets_copy:
        secrets_copy['Authorization'] = redacted_phrase
    return secrets_copy


def CollectionProperty(type=None, name: str='', description: str='',
    options: set={'ANIMATABLE'}):
    """Returns a new collection property definition.

    :param type: A subclass of bpy.types.PropertyGroup or bpy.types.ID.
    :param name: Name used in the user interface.
    :type name: str
    :param description: Text used for the tooltip and api documentation.
    :type description: str
    :param options: Enumerator in [‘HIDDEN’, ‘SKIP_SAVE’, ‘ANIMATABLE’, ‘LIBRARY_EDITABLE’, ‘PROPORTIONAL’,’TEXTEDIT_UPDATE’].
    :type options: set
    """
    pass


def _open_file(file_stream, mode: str, encoding=None, **kwargs):
    """Open a file if it is a file_name otherwise return file_stream"""
    if type(file_stream) is str:
        return open(file_stream, mode, encoding=encoding, **kwargs)
    return file_stream


def from_iso_permissive(datestring, use_dateutil=True):
    """Parse an ISO8601-formatted datetime and return a datetime object.

        Inspired by the marshmallow.utils.from_iso function, but also accepts
        datestrings that don't contain the time.
        """
    dateutil_available = False
    try:
        from dateutil import parser
        dateutil_available = True
    except ImportError:
        dateutil_available = False
        import datetime
    if dateutil_available and use_dateutil:
        return parser.parse(datestring)
    else:
        return datetime.datetime.strptime(datestring[:19], '%Y-%m-%dT%H:%M:%S')


def win32_restrict_file_to_user(fname):
    """Secure a windows file to read-only access for the user.
    Follows guidance from win32 library creator:
    http://timgolden.me.uk/python/win32_how_do_i/add-security-to-a-file.html

    This method should be executed against an already generated file which
    has no secrets written to it yet.

    Parameters
    ----------

    fname : unicode
        The path to the file to secure
    """
    import win32api
    import win32security
    import ntsecuritycon as con
    admins = win32security.CreateWellKnownSid(win32security.
        WinBuiltinAdministratorsSid)
    user, _domain, _type = win32security.LookupAccountName('', win32api.
        GetUserNameEx(win32api.NameSamCompatible))
    sd = win32security.GetFileSecurity(fname, win32security.
        DACL_SECURITY_INFORMATION)
    dacl = win32security.ACL()
    dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.
        FILE_GENERIC_READ | con.FILE_GENERIC_WRITE, user)
    dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.
        FILE_ALL_ACCESS, admins)
    sd.SetSecurityDescriptorDacl(1, dacl, 0)
    win32security.SetFileSecurity(fname, win32security.
        DACL_SECURITY_INFORMATION, sd)


def timetz_unpack(tstz, time_unpack=time_unpack, FixedOffset=FixedOffset):
    """
	Create a `datetime.time` instance from a ((seconds, microseconds), timezone)
	tuple.
	"""
    t = time_unpack(tstz[0])
    return t.replace(tzinfo=FixedOffset(tstz[1]))


def is_api_view(callback):
    """
    Return `True` if the given view callback is a REST framework view/viewset.
    """
    from rest_framework.views import APIView
    cls = getattr(callback, 'cls', None)
    return cls is not None and issubclass(cls, APIView)


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


def apply_option(f, arg):
    """
    Apply function if the arg is not None
    :param f: function to apply
    :param arg: argument value
    :return: None if the arg is None, else the result of the function
    """
    return arg if arg is None else f(arg)


@staticmethod
def default_setter(name, instance, value, init=False):
    """
        Default setter which behaves like normal TogglField, that stores the value inside of the instance's dict under
        the field's name.

        :param name: Field's name
        :param instance: Instance of the entity
        :param value: Value to be set
        :param init: Boolean that describe if the value is being set during creation of the entity's instance
        :return: Boolean which indicates whether the value resulted in updated state of the instance
                (for tracking changes for correct PUT behavior). True if state was changed.
        """
    org_value = instance.__dict__.get(name)
    instance.__dict__[name] = value
    return org_value != value


def _reversemap_vhosts(names, vhosts):
    """Helper function for select_vhost_multiple for mapping string
    representations back to actual vhost objects"""
    return_vhosts = []
    for selection in names:
        for vhost in vhosts:
            if vhost.display_repr().strip() == selection.strip():
                return_vhosts.append(vhost)
    return return_vhosts


def run_point(mfts, partitioner, train_data, test_data, window_key=None, **
    kwargs):
    """
    Run the point forecasting benchmarks

    :param mfts: FTS model
    :param partitioner: Universe of Discourse partitioner
    :param train_data: data used to train the model
    :param test_data: ata used to test the model
    :param window_key: id of the sliding window
    :param transformation: data transformation
    :param indexer: seasonal indexer
    :return: a dictionary with the benchmark results
    """
    import time
    from pyFTS.models import yu, chen, hofts, pwfts, ismailefendi, sadaei, song, cheng, hwang
    from pyFTS.partitioners import Grid, Entropy, FCM
    from pyFTS.benchmarks import Measures, naive, arima, quantreg
    from pyFTS.common import Transformations
    tmp = [song.ConventionalFTS, chen.ConventionalFTS, yu.WeightedFTS,
        ismailefendi.ImprovedWeightedFTS, cheng.TrendWeightedFTS, sadaei.
        ExponentialyWeightedFTS, hofts.HighOrderFTS, hwang.HighOrderFTS,
        pwfts.ProbabilisticWeightedFTS]
    tmp2 = [Grid.GridPartitioner, Entropy.EntropyPartitioner, FCM.
        FCMPartitioner]
    tmp4 = [naive.Naive, arima.ARIMA, quantreg.QuantileRegression]
    tmp3 = [Measures.get_point_statistics]
    tmp5 = [Transformations.Differential]
    indexer = kwargs.get('indexer', None)
    steps_ahead = kwargs.get('steps_ahead', 1)
    method = kwargs.get('method', None)
    if mfts.benchmark_only:
        _key = mfts.shortname + str(mfts.order if mfts.order is not None else
            '')
    else:
        pttr = str(partitioner.__module__).split('.')[-1]
        _key = mfts.shortname + ' n = ' + str(mfts.order
            ) + ' ' + pttr + ' q = ' + str(partitioner.partitions)
        mfts.partitioner = partitioner
        mfts.append_transformation(partitioner.transformation)
    _key += str(steps_ahead)
    _key += str(method) if method is not None else ''
    _start = time.time()
    mfts.fit(train_data, **kwargs)
    _end = time.time()
    times = _end - _start
    _start = time.time()
    _rmse, _smape, _u = Measures.get_point_statistics(test_data, mfts, **kwargs
        )
    _end = time.time()
    times += _end - _start
    ret = {'key': _key, 'obj': mfts, 'rmse': _rmse, 'smape': _smape, 'u':
        _u, 'time': times, 'window': window_key, 'steps': steps_ahead,
        'method': method}
    return ret


def de_select_first():
    """(De)select first of visible part of each NURBS

    """
    pass


@classmethod
def one(cls, **kwd):
    """
        Return the unit (1) polynomial.
        """
    return cls(1, **kwd)


def options_mask(xmp_options, **kwargs):
    """
    Creates the options bit mask for consumption by exempi C functions.

    Example::

      opt = consts.options_mask( consts.XMP_SERIAL_OPTIONS, **kwargs )

    or::

      opt = consts.options_mask( consts.XMP_SERIAL_OPTIONS, omit_packet_wrapper=True )
    """
    bitmask = 0
    for const_name, const_value in kwargs.items():
        if const_value and const_name in xmp_options:
            bitmask |= xmp_options[const_name]
    return bitmask


def pack_all():
    """Pack all used external files into the .blend

    """
    pass


def edgering_select(extend: bool=False, deselect: bool=False, toggle: bool=
    False, ring: bool=True):
    """Select an edge ring

    :param extend: Extend, Extend the selection
    :type extend: bool
    :param deselect: Deselect, Remove from the selection
    :type deselect: bool
    :param toggle: Toggle Select, Toggle the selection
    :type toggle: bool
    :param ring: Select Ring, Select ring
    :type ring: bool
    """
    pass


def white_b(string):
    """background color to white"""
    return '\x1b[47m' + string + '\x1b[0m'


@staticmethod
def static_detect_presence(path):
    """For auto detection"""
    raise NotImplementedError(
        'Base class detect_presence method must be overridden')


def ifnone(if_, else_, transform=None):
    """Returns the condition ``if_`` iff it is not ``None``, or if a transformation is
    specified, ``transform(if_)``. Returns ``else_`` if the condition is ``None``.
    ``transform`` can be any callable, which will be passed ``if_`` in case ``if_`` is not ``None``."""
    if if_ is None:
        return else_
    elif transform is not None:
        return transform(if_)
    else:
        return if_


def len_str_list(lis):
    """returns sum of lengths of strings in list()"""
    res = 0
    for x in lis:
        res += len(x)
    return res


@classmethod
def uri_matches(cls, uri):
    """
        override 'uri_matches' to disallow this logger if full text searching
        is not available.
        """
    return super().uri_matches(uri) and cls._has_fulltext(uri)


def theta_Cs_K_PK74(T, P):
    """c-c': caesium potassium [PK74]."""
    theta = 0.0
    valid = T == 298.15
    return theta, valid


def tracing_transport_new(_, __, *args, **kwargs):
    """Monkey patch a valid TracingTransport.__new__() to avoid recursion on patched base class"""
    from elasticsearch_opentracing import TracingTransport
    return object.__new__(TracingTransport)


def uniform_profile(ind, num, start, end):
    """Return uniformly spaced mesh corners"""
    delta = (end - start) / num
    return start + ind * delta, delta


def gamma(data=None, out=None, name=None, **kwargs):
    """Returns the gamma function (extension of the factorial function \\
    to the reals), computed element-wise on the input array.

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

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

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

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


def ranged_by(marker, limit=None, offset=None):
    """
    Generates LIMIT and OFFSET clause using marker.

    Parameters
    ----------
    limit: int
        Limit value or `None`.
    offset: int
        OFfset value or `None`.

    Returns
    -------
    str
        LIMIT and OFFSET clause.
    """
    clause, params = [], []
    if limit is not None:
        clause.append(f'LIMIT {marker()}')
        params.append(limit)
    if offset is not None:
        clause.append(f'OFFSET {marker()}')
        params.append(offset)
    return ' '.join(clause), params


@classmethod
def all(cls, v, catch=False):
    """Perform all variable tests

        Parameters
        ----------
        v : :class:`~spacepy.pycdf.Var`
            Variable to check
        catch : bool
            Catch exceptions in tests (default False). If True, any
            exceptions in subtests will result in an addition to the
            validation failures of the form "Test x did not complete."
            Calling the individual test will reveal the full traceback.

        Returns
        -------
        list of str
            Description of each validation failure.

        Examples
        --------
        >>> import spacepy.pycdf
        >>> import spacepy.pycdf.istp
        >>> f = spacepy.pycdf.CDF('foo.cdf', create=True)
        >>> v = f.new('Var', data=[1, 2, 3])
        >>> spacepy.pycdf.istp.VariableChecks.all(v)
        ['No FIELDNAM attribute.']
        """
    callme = (cls.depends, cls.depsize, cls.fieldnam, cls.recordcount, cls.
        validrange, cls.validscale, cls.validdisplaytype)
    errors = []
    for f in callme:
        try:
            errors.extend(f(v))
        except:
            if catch:
                errors.append('Test {} did not complete.'.format(f.__name__))
            else:
                raise
    return errors


def affine_weights(dim):
    """Compute coefficents for mapping from reference to physical element"""
    if dim == 1:
        return lambda X: (1.0 - X[0], X[0])
    elif dim == 2:
        return lambda X: (1.0 - X[0] - X[1], X[0], X[1])
    elif dim == 3:
        return lambda X: (1.0 - X[0] - X[1] - X[2], X[0], X[1], X[2])


def apply_matrix_norm(m, v):
    """Equivalent to apply_matrix_pt(M, (p,q)) - apply_matrix_pt(M, (0,0))"""
    a, b, c, d, e, f = m
    p, q = v
    return a * p + c * q, b * p + d * q


@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('--virustotal-api-key',
        '--virustotal_api_key', dest='virustotal_api_key', type=str, action
        ='store', default=None, metavar='API_KEY', help=
        'Specify the API key for use with VirusTotal.')
    argument_group.add_argument('--virustotal-free-rate-limit',
        '--virustotal_free_rate_limit', dest='virustotal_free_rate_limit',
        action='store_false', default=cls._DEFAULT_RATE_LIMIT, help=
        'Limit Virustotal requests to the default free API key rate of 4 requests per minute. Set this to false if you have an key for the private API.'
        )
    argument_group.add_argument('--virustotal-hash', '--virustotal_hash',
        dest='virustotal_hash', type=str, action='store', choices=['md5',
        'sha1', 'sha256'], default=cls._DEFAULT_HASH, metavar='HASH', help=
        'Type of hash to query VirusTotal, the default is: {0:s}'.format(
        cls._DEFAULT_HASH))


def repository_enabled_for_checks(repository, consistency):
    """
    Given a repository name and a consistency configuration dict, return whether the repository
    is enabled to have consistency checks run.
    """
    if not consistency.get('check_repositories'):
        return True
    return repository in consistency['check_repositories']


def linear(x, old_range, new_range):
    """
    Rescale each channel to the new range as following:
    new = data/old_range*new_range

    Parameters
    ----------
    data : DataFrame
        data to be rescaled
    new_range : float | array | Series
        Maximal data value after rescaling
    old_range : float | array | Series
        Maximal data value before rescaling
        (If old range is not given use the one specified in self.meta['_channels_']['$PnR'])
        Deprecated!!!
    """
    y = x / old_range * new_range
    return y


def where_am_i(driver=None):
    """
    Return the current location URL
    :param driver: a selenium web driver
    :return: String. The current URL
    """
    return driver.current_url


def linsrgb_to_srgb(linsrgb):
    """Convert physically linear RGB values into sRGB ones. The transform is
    uniform in the components, so *linsrgb* can be of any shape.

    *linsrgb* values should range between 0 and 1, inclusively.

    """
    gamma = 1.055 * linsrgb ** (1.0 / 2.4) - 0.055
    scale = linsrgb * 12.92
    if linsrgb > 0.0031308:
        return gamma
    return scale


@classmethod
def from_batch(cls, batch):
    """ Create batch from another batch """
    return cls(batch.index, preloaded=batch._data)


@classmethod
def set_ssm_client(cls, client):
    """Override the default boto3 SSM client with your own."""
    required_methods = 'get_parameters', 'get_parameters_by_path'
    for method in required_methods:
        if not hasattr(client, method):
            raise TypeError('client must have a %s method' % method)
    cls._ssm_client = client


def get_add_vswitch_port_group_spec(client_factory, vswitch_name,
    port_group_name, vlan_id):
    """Builds the virtual switch port group add spec."""
    vswitch_port_group_spec = client_factory.create('ns0:HostPortGroupSpec')
    vswitch_port_group_spec.name = port_group_name
    vswitch_port_group_spec.vswitchName = vswitch_name
    vswitch_port_group_spec.vlanId = int(vlan_id)
    policy = client_factory.create('ns0:HostNetworkPolicy')
    nicteaming = client_factory.create('ns0:HostNicTeamingPolicy')
    nicteaming.notifySwitches = True
    policy.nicTeaming = nicteaming
    vswitch_port_group_spec.policy = policy
    return vswitch_port_group_spec


def apply_ants_transform_to_point(transform, point):
    """
    Apply transform to a point

    ANTsR function: `applyAntsrTransformToPoint`

    Arguments
    ---------
    point : list/tuple
        point to which the transform will be applied

    Returns
    -------
    tuple : transformed point

    Example
    -------
    >>> import ants
    >>> tx = ants.new_ants_transform()
    >>> params = tx.parameters
    >>> tx.set_parameters(params*2)
    >>> pt2 = tx.apply_to_point((1,2,3)) # should be (2,4,6)
    """
    return transform.apply_to_point(point)


def SI(df, L, open='Open', high='High', low='Low', close='Close'):
    """
    Swing Index (J. Welles Wilder)
    Returns: list of floats = jhta.SI(df, L, open='Open', high='High', low='Low', close='Close')
    Source: book: New Concepts in Technical Trading Systems
    """
    si_list = []
    for i in range(len(df[close])):
        if i < 1:
            si = float('NaN')
        else:
            N = df[close][i] - df[close][i - 1] + 0.5 * (df[close][i] - df[
                open][i]) + 0.25 * (df[close][i - 1] - df[open][i - 1])
            R1 = df[high][i] - df[close][i - 1]
            R2 = df[low][i] - df[close][i - 1]
            R3 = df[high][i] - df[low][i]
            if R1 > R2 and R1 > R3:
                R = df[high][i] - df[close][i - 1] - 0.5 * (df[low][i] - df
                    [close][i - 1]) + 0.25 * (df[close][i - 1] - df[open][i -
                    1])
            if R2 > R1 and R2 > R3:
                R = df[low][i] - df[close][i - 1] - 0.5 * (df[high][i] - df
                    [close][i - 1]) + 0.25 * (df[close][i - 1] - df[open][i -
                    1])
            if R3 > R1 and R3 > R2:
                R = df[high][i] - df[low][i] + 0.25 * (df[close][i - 1] -
                    df[open][i - 1])
            K1 = df[high][i] - df[close][i - 1]
            K2 = df[low][i] - df[close][i - 1]
            if K1 > K2:
                K = K1
            else:
                K = K2
            si = 50 * (N / R) * (K / L)
        si_list.append(si)
    return si_list


def reformat_input(files, sep=' '):
    """files, a list of files or a string of many files
    each seperated by a space
    """
    if isinstance(files, str):
        files = files.split(' ')
    out = sep.join(files)
    return '"{}"'.format(out)


def get_locked_permissions():
    """Returns the list of permissions that are blocked to be inherited
        """


def tpc_vote(transaction):
    """Provide a storage with an opportunity to veto a transaction

        See IStorage.tpc_vote. For objects implementing this interface,
        the return value can be either None or a sequence of oids for which
        a conflict was resolved.
        """


@classmethod
def stopScreencast(cls):
    """Stops sending each frame in the `screencastFrame`.
        """
    return cls.build_send_payload('stopScreencast', {}), None


@staticmethod
def sort(dtm):
    """Descending sorted document-term matrix.

        Parameters:
            dtm (pd.DataFrame): Document-term matrix.
        """
    return dtm.iloc[:, ((-dtm.sum()).argsort())]


def mapfo(ol, **kwargs):
    """
        #mapfo            i不作为map_func参数,v不作为map_func参数
        #                 NOT take value as a param for map_func,NOT take index as a param for map_func
        #map_func         diff_func(*diff_args)
    """
    diff_args_arr = kwargs['map_func_args_array']
    diff_funcs_arr = kwargs['map_funcs']
    lngth = ol.__len__()
    rslt = []
    for i in range(0, lngth):
        index = i
        value = ol[i]
        func = diff_funcs_arr[i]
        args = diff_args_arr[i]
        ele = func(value, *args)
        rslt.append(ele)
    return rslt


def getAllGroupMembers():
    """ Return a list of the portal_memberdata-ish members of the group
        including transitive ones (ie. users or groups of a group in that
        group)."""


def patch(original, patch):
    """
    Apply the patch to the given text.

    :param original: the original text to patch
    :param patch: the patch to apply
    :exception PatchFailedException: if unable to apply
    :return: the revised text
    """
    if isinstance(original, str):
        original = original.splitlines()
    return patch.apply_to(original)


def delete_account_alias(AccountAlias=None):
    """
    Deletes the specified AWS account alias. For information about using an AWS account alias, see Using an Alias for Your AWS Account ID in the IAM User Guide .
    See also: AWS API Documentation

    Examples
    The following command removes the alias mycompany from the current AWS account:
    Expected Output:

    :example: response = client.delete_account_alias(
        AccountAlias='string'
    )

    :type AccountAlias: string
    :param AccountAlias: [REQUIRED]
            The name of the account alias to delete.
            This parameter allows (per its regex pattern ) a string of characters consisting of lowercase letters, digits, and dashes. You cannot start or finish with a dash, nor can you have two dashes in a row.

    :return: response = client.delete_account_alias(
        AccountAlias='mycompany',
    )

    print(response)

    """
    pass


def clean(text):
    """
    get rid of non breaking spaces
    """
    return text.replace('\xa0', '').rstrip()


def merge_paths(base_uri, relative_path):
    """Merge a base URI's path with a relative URI's path."""
    if base_uri.path is None and base_uri.authority is not None:
        return '/' + relative_path
    else:
        path = base_uri.path or ''
        index = path.rfind('/')
        return path[:index] + '/' + relative_path


def is_stochastic_matrix(m, ep=1e-08) ->bool:
    """Checks that the matrix m (a list of lists) is a stochastic matrix."""
    for i in range(len(m)):
        for j in range(len(m[i])):
            if m[i][j] < 0 or m[i][j] > 1:
                return False
        s = sum(m[i])
        if abs(1.0 - s) > ep:
            return False
    return True


def ifelse(a, b, c):
    """`b` if `a` is True else `c`"""
    return b if a else c


def onfinish(request):
    """Callback for asyncrhonous finish(). Means the response is sent and
        the request is forgotten. Chained call originating from
        :meth:`IHTTPResponse.onfinish`.

        ``request``,
            Plugin instance implementing :class:`IHTTPRequest` interface.
        """


def load_tweets(session, config, query, result_type, count=100, since_id=None):
    """
    Requests tweets from the Twitter Search API. Excludes retweets from the results.

    :param session: A :mod:`requests` session initialized to use the correct Bearer token.
    :param config: A :mod:`configparser` instance containing the application's loaded config data.
    :param query: The search query.
    :param result_type: One of ``recent``, ``mixed`` or ``popular``, specifying which type of tweets should be returned.
    :param count: The maximum number of tweets to return. Note that the actual number of loaded tweets will usually be lower.
    :param since_id: Limits the search to tweets more recent than the tweet with this ID.
    :return: A list of tweet objects retrieved from Twitter.
    """
    if count is None:
        count = 100
    query += '-filter:retweets'
    url = config['twitter_api']['tweet_api_url']
    params = {'q': query, 'result_type': result_type, 'count': count}
    if since_id is not None:
        params['since_id'] = since_id
    response = session.get(url, params=params)
    return response.json()['statuses']


def interpolatePoint(pt1, pt2, v):
    """
    interpolate point by factor v

    >>> interpolatePoint((0, 0), (10, 10), 0.5)
    (5.0, 5.0)
    >>> interpolatePoint((0, 0), (10, 10), 0.6)
    (6.0, 6.0)
    """
    (xa, ya), (xb, yb) = pt1, pt2
    if not isinstance(v, tuple):
        xv = v
        yv = v
    else:
        xv, yv = v
    return xa + (xb - xa) * xv, ya + (yb - ya) * yv


def fpct(a, po, e):
    """How often does a fielder or team make the play when tasked with fielding a batted ball, throwing a ball,
     or receiving a thrown ball for an out.
    :param a: Assists.
    :type a: int.
    :param po: Putouts.
    :type po: int.
    :param e: Errors.
    :type e: int.
    :returns:  float -- The fielding percentage.
    :raises: ZeroDivisionError
    """
    try:
        return (po + a) * 1.0 / (po + a + e)
    except ZeroDivisionError:
        print('Total chances must be greater than 0.')
        import sys
        sys.exit(-1)


def Write(packer_type, buf, head, n):
    """ Write encodes `n` at buf[head] using `packer_type`. """
    packer_type.pack_into(buf, head, n)


def _make_type(vendor, field):
    """
  Takes an NXM vendor and field and returns the whole type field
  """
    return vendor << 7 | field


def select(extend: bool=False, location: float=(0.0, 0.0)):
    """Select tracking markers

    :param extend: Extend, Extend selection rather than clearing the existing selection
    :type extend: bool
    :param location: Location, Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds
    :type location: float
    """
    pass


def getNonInstallableProducts():
    """Returns a list of products that should not be available for
           installation.

        This used to be in CMFQuickInstallerTool.
        """


@staticmethod
def update_parameters_with_cli_parameters(parameters, cli_parameters,
    stack_name):
    """
        Overwrite parameters from stack_config with those provided by user by cli
        :param parameters: dict
        :param cli_parameters: dict
        :param stack_name: string
        :return: dict

        """
    if stack_name in cli_parameters.keys():
        for new_key, new_value in cli_parameters[stack_name].items():
            parameters[new_key] = new_value
    return parameters


def getMimetype():
    """ The mimetype of this object """


def unsubscribe():
    """Unsubscribe (and delete) this member from the mailing list."""


def date_diff(taxis, dt1, dt2, units=None):
    """ Returns time interval between two dates. A time axis must be given
  to specify the calendar. If no units are specified the units of the given
  time axis are used."""
    return taxis.date_as_val(dt2, startdate=dt1, units=units)


@staticmethod
def is_applicable(conf):
    """Return whether this promoter is applicable for given conf"""
    return all(('url' not in conf, 'script' in conf))


def pprint(cfg):
    """Create string that presents ("pretty prints") the configuration
    """
    out = ''
    addr = cfg.get('addr')
    if addr is not None:
        out += 'Misty robot address\t{}\n'.format(addr)
    return out


def write_project_urls(app_names):
    """Writes a basic urls.py for a django-project
    given the app names"""
    urls_imports = ['from django.conf.urls import include, url\n',
        """from django.contrib import admin
"""]
    url_pattern_lines = ['urlpatterns= [\n',
        "  url(r'^admin/', admin.site.urls),\n"]
    for app_name in app_names:
        url_pattern = "  url(r'^%s/',include('%s.urls')),\n" % (app_name,
            app_name)
        url_pattern_lines.append(url_pattern)
    url_pattern_lines.append('  ]')
    out_file = open('urls.py', 'w')
    for line in urls_imports:
        out_file.write(line)
    for line in url_pattern_lines:
        out_file.write(line)
    out_file.close()


def create_dico(item_list):
    """
    Create a dictionary of items from a list of list of items.
    字典 字符:出现的频率
    """
    assert type(item_list) is list
    dico = {}
    for items in item_list:
        for item in items:
            if item not in dico:
                dico[item] = 1
            else:
                dico[item] += 1
    return dico


def lookupMailboxInfo(name, timeout=None):
    """
        Perform an MINFO record lookup.

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

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

        @rtype: L{Deferred}
        @return: A L{Deferred} which fires with a three-tuple of lists of
            L{twisted.names.dns.RRHeader} instances.  The first element of the
            tuple gives answers.  The second element of the tuple gives
            authorities.  The third element of the tuple gives additional
            information.  The L{Deferred} may instead fail with one of the
            exceptions defined in L{twisted.names.error} or with
            C{NotImplementedError}.
        """


def get_app_route_methods(routes, route):
    """Return route CRUD method (GET, POST, etc)."""
    methods = list(routes[route].methods)
    return methods


def _escape_hive(val):
    """HiveParamEscaper

     https://github.com/dropbox/PyHive/blob/master/pyhive/hive.py"""
    return "'{0}'".format(val.replace('\\', '\\\\').replace("'", "\\'").
        replace('\r', '\\r').replace('\n', '\\n').replace('\t', '\\t'))


def unique(seq):
    """Remove duplicate elements from seq. Assumes hashable elements."""
    return list(set(seq))


def cleanBit(val: int, bitNo: int):
    """
    Set a specified bit to '0'
    """
    return val & ~(1 << bitNo)


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

        :param LookupError val:
        :rtype: ListFolderError
        """
    return cls('path', val)


def flatten(l):
    """
    Flattens a hierarchy of nested lists into a single list containing all elements in order

    :param l: list of arbitrary types and lists
    :returns: list of arbitrary types
    """
    l = list(l)
    i = 0
    while i < len(l):
        while isinstance(l[i], list):
            if not l[i]:
                l.pop(i)
                i -= 1
                break
            else:
                l[i:i + 1] = l[i]
        i += 1
    return l


def get_types(field):
    """
    Returns a field's "type" as a list.

    :param dict field: the field
    :returns: a field's "type"
    :rtype: list
    """
    if 'type' not in field:
        return []
    if isinstance(field['type'], str):
        return [field['type']]
    return field['type']


def non_printable_chars_to_hex(source):
    """
    Converts input string into hex for all non printable chars, printable chars remain unchanged.
    :param source: input string.
    :return: output string witch exchanged chars.
    """
    import string
    output = ''
    for char in source:
        if char not in string.printable or char in ['\n', '\r']:
            output += '\\x{:02x}'.format(ord(char))
        else:
            output += char
    return output


@classmethod
def _check_model_args(cls, args):
    """Safty function to check model arguments."""
    return args


def add_many_to_dict_val_list(dict_obj, key, val_list):
    """Adds the given value list to the list mapped by the given key.
    If the key is missing from the dict, the given mapping is added.

    Example
    -------
    >>> dict_obj = {'a': [1, 2]}
    >>> add_many_to_dict_val_list(dict_obj, 'a', [2, 3])
    >>> print(dict_obj['a'])
    [1, 2, 2, 3]
    >>> add_many_to_dict_val_list(dict_obj, 'b', [2, 3])
    >>> print(dict_obj['b'])
    [2, 3]
    """
    try:
        dict_obj[key].extend(val_list)
    except KeyError:
        dict_obj[key] = list(val_list)


def disable_validate_slicecount():
    """
    Disable the validation of the minimal slice count of 4 slices.
    This allows for converting data with less slices.
    Usually less than 4 could be considered localizer or similar thus ignoring these scans by default
    USE WITH CAUTION!
    """
    global validate_slicecount
    validate_slicecount = False


def add_role_to_instance_profile(InstanceProfileName=None, RoleName=None):
    """
    Adds the specified IAM role to the specified instance profile. An instance profile can contain only one role, and this limit cannot be increased.
    For more information about roles, go to Working with Roles . For more information about instance profiles, go to About Instance Profiles .
    See also: AWS API Documentation

    Examples
    The following command adds the role named S3Access to the instance profile named Webserver:
    Expected Output:

    :example: response = client.add_role_to_instance_profile(
        InstanceProfileName='string',
        RoleName='string'
    )

    :type InstanceProfileName: string
    :param InstanceProfileName: [REQUIRED]
            The name of the instance profile to update.
            This parameter allows (per its regex pattern ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: =,.@-

    :type RoleName: string
    :param RoleName: [REQUIRED]
            The name of the role to add.
            This parameter allows (per its regex pattern ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: _+=,.@-

    :return: response = client.add_role_to_instance_profile(
        InstanceProfileName='Webserver',
        RoleName='S3Access',
    )

    print(response)

    """
    pass


def indent(s: str, n: int) ->str:
    """Indent all the lines in s (separated by newlines) by n spaces."""
    s = ' ' * n + s
    s = s.replace('\n', '\n' + ' ' * n)
    return s


@staticmethod
def create_driver(webview):
    """根据webview类型创建对应的WebDriver实例

        :param webview: WebView实例
        :type webview:  object
        """
    web_driver_path = webview.web_driver
    module = __import__(web_driver_path)
    for item in web_driver_path.split('.')[1:]:
        module = getattr(module, item)
    web_driver_cls = getattr(module, 'WebDriver')
    return web_driver_cls(webview)


@staticmethod
def reset(sample_idx):
    """Reset layer variables."""
    pass


@classmethod
def is_datasource_for(cls, **kwargs):
    """
        Determines if the file corresponds to a RHESSI X-ray Summary
        `~sunpy.timeseries.TimeSeries`.
        """
    if 'source' in kwargs.keys():
        if kwargs.get('source', ''):
            return kwargs.get('source', '').lower().startswith(cls._source)
    if 'meta' in kwargs.keys():
        return kwargs['meta'].get('telescop', '').startswith('HESSI')


def parameters_ui(layout, params):
    """ Create the ui for the rig parameters.
    """
    r = layout.row()
    r.prop(params, 'separate_extra_layers')
    r = layout.row()
    r.active = params.separate_extra_layers
    col = r.column(align=True)
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=0, toggle=True, text='')
    row.prop(params, 'extra_layers', index=1, toggle=True, text='')
    row.prop(params, 'extra_layers', index=2, toggle=True, text='')
    row.prop(params, 'extra_layers', index=3, toggle=True, text='')
    row.prop(params, 'extra_layers', index=4, toggle=True, text='')
    row.prop(params, 'extra_layers', index=5, toggle=True, text='')
    row.prop(params, 'extra_layers', index=6, toggle=True, text='')
    row.prop(params, 'extra_layers', index=7, toggle=True, text='')
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=16, toggle=True, text='')
    row.prop(params, 'extra_layers', index=17, toggle=True, text='')
    row.prop(params, 'extra_layers', index=18, toggle=True, text='')
    row.prop(params, 'extra_layers', index=19, toggle=True, text='')
    row.prop(params, 'extra_layers', index=20, toggle=True, text='')
    row.prop(params, 'extra_layers', index=21, toggle=True, text='')
    row.prop(params, 'extra_layers', index=22, toggle=True, text='')
    row.prop(params, 'extra_layers', index=23, toggle=True, text='')
    col = r.column(align=True)
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=8, toggle=True, text='')
    row.prop(params, 'extra_layers', index=9, toggle=True, text='')
    row.prop(params, 'extra_layers', index=10, toggle=True, text='')
    row.prop(params, 'extra_layers', index=11, toggle=True, text='')
    row.prop(params, 'extra_layers', index=12, toggle=True, text='')
    row.prop(params, 'extra_layers', index=13, toggle=True, text='')
    row.prop(params, 'extra_layers', index=14, toggle=True, text='')
    row.prop(params, 'extra_layers', index=15, toggle=True, text='')
    row = col.row(align=True)
    row.prop(params, 'extra_layers', index=24, toggle=True, text='')
    row.prop(params, 'extra_layers', index=25, toggle=True, text='')
    row.prop(params, 'extra_layers', index=26, toggle=True, text='')
    row.prop(params, 'extra_layers', index=27, toggle=True, text='')
    row.prop(params, 'extra_layers', index=28, toggle=True, text='')
    row.prop(params, 'extra_layers', index=29, toggle=True, text='')
    row.prop(params, 'extra_layers', index=30, toggle=True, text='')
    row.prop(params, 'extra_layers', index=31, toggle=True, text='')
    r = layout.row()
    r.label(text='Bend rotation axis:')
    r.prop(params, 'primary_rotation_axis', text='')
    col = layout.column()
    col.prop(params, 'use_digit_twist')


def primitive_uv_sphere_add(segments: int=32, ring_count: int=16, size:
    float=1.0, calc_uvs: bool=False, view_align: bool=False, enter_editmode:
    bool=False, location: float=(0.0, 0.0, 0.0), rotation: float=(0.0, 0.0,
    0.0), layers: bool=(False, False, False, False, False, False, False,
    False, False, False, False, False, False, False, False, False, False,
    False, False, False)):
    """Construct a UV sphere mesh

    :param segments: Segments
    :type segments: int
    :param ring_count: Rings
    :type ring_count: int
    :param size: Size
    :type size: float
    :param calc_uvs: Generate UVs, Generate a default UV map
    :type calc_uvs: bool
    :param view_align: Align to View, Align the new object to the view
    :type view_align: bool
    :param enter_editmode: Enter Editmode, Enter editmode when adding this object
    :type enter_editmode: bool
    :param location: Location, Location for the newly added object
    :type location: float
    :param rotation: Rotation, Rotation for the newly added object
    :type rotation: float
    :param layers: Layer
    :type layers: bool
    """
    pass


def multiply(value, amount):
    """Filter to convert value to float and multiply it."""
    try:
        return float(value) * amount
    except (ValueError, TypeError):
        return value


def time_complexities():
    """
    Return information on functions
    time complexity
    :return: string
    """
    return 'Best Case: O(1), Average Case: O(log(logn)), Worst Case: O(logn)'


def list_clusters(MaxResults=None, NextToken=None):
    """
    Returns an array of ClusterListEntry objects of the specified length. Each ClusterListEntry object contains a cluster's state, a cluster's ID, and other important status information.
    See also: AWS API Documentation

    Examples
    Returns an array of ClusterListEntry objects of the specified length. Each ClusterListEntry object contains a cluster's state, a cluster's ID, and other important status information.
    Expected Output:

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

    :type MaxResults: integer
    :param MaxResults: The number of ClusterListEntry objects to return.

    :type NextToken: string
    :param NextToken: HTTP requests are stateless. To identify what object comes 'next' in the list of ClusterListEntry objects, you have the option of specifying NextToken as the starting point for your returned list.

    :rtype: dict
    :return: {
        'ClusterListEntries': [
            {
                'ClusterId': 'string',
                'ClusterState': 'AwaitingQuorum'|'Pending'|'InUse'|'Complete'|'Cancelled',
                'CreationDate': datetime(2015, 1, 1),
                'Description': 'string'
            },
        ],
        'NextToken': 'string'
    }

    """
    pass


def unassigned_order_items():
    """the collection of unassigned order items."""


def store_temps(cursor, state_oid_tid_iter):
    """
        Store many objects in the temporary table.

        *batcher* is an object returned by :meth:`make_batcher`.

        *state_oid_tid_iter* is an iterable providing tuples
        ``(data, oid_int, prev_tid_int)``. It is guaranteed that the
        ``oid_int`` values will be distinct. It is further guaranteed that
        this method will not be called more than once in a given transaction;
        further updates to the temporary table will be made using
        ``replace_temps``, which is also only called once.
        """


def register(mimetype, factory, extension):
    """Register the factory ``factory`` to create a content of
        type ``mimetype``. Factory comes from ``extension``.
        """


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

        :param FileRequestChangeType val:
        :rtype: EventType
        """
    return cls('file_request_change', val)


def simplify_ranges(range_list, level):
    """
    Simplify the HTM ranges in `range_list` by an effective level of
    `level`.
    """
    if not range_list or level <= 0:
        raise ValueError
    mask = (1 << 2 * level) - 1
    i = 0
    j = 0
    while i < len(range_list):
        id_min = range_list[i][0] & ~mask
        id_max = range_list[i][1] | mask
        while i < len(range_list) - 1:
            next_ = range_list[i + 1][0] & ~mask
            if next_ > id_max + 1:
                break
            id_max = range_list[i + 1][1] | mask
            i += 1
        range_list[j] = id_min, id_max
        i += 1
        j += 1
    range_list[:] = range_list[0:j]


def get_label_from_response(response):
    """
    Get the response of ModelCatalog and return a list with the labels
    @param response: Response of the ModelCatalog
    @type response: List
    @return: A list with the labels
    @rtype: List
    """
    labels = []
    for resource in response:
        if isinstance(resource, dict):
            if resource['label']:
                labels.append(resource['label'][0])
            elif resource['id']:
                labels.append(resource['id'])
            else:
                labels.append(None)
        elif resource.label:
            labels.append(resource.label[0])
        elif resource.id:
            labels.append(resource.id)
        else:
            labels.append(None)
    return labels


def do_OP_EQUAL(vm):
    """
    >>> s = [b'string1', b'string1']
    >>> do_OP_EQUAL(s)
    >>> print(s == [b''])
    True
    >>> s = [b'string1', b'string2']
    >>> do_OP_EQUAL(s)
    >>> print(s == [b''])
    True
    """
    v1, v2 = [vm.pop() for i in range(2)]
    vm.append(vm.bool_to_script_bytes(v1 == v2))


def hasValue():
    """Return True if the value is not empty/missing."""


def no_lookahead(parser):
    """ Return True if the parser performs no lookahead. """
    return not hasattr(parser, 'lookahead')


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


@staticmethod
def get_linesep(lines):
    """Returns string containing autodetected line separator for file.

        Keyword arguments:
        lines -- file contents string
        """
    pos = lines.find('\n')
    if pos > 0 and lines[pos - 1] == '\r':
        return '\r\n'
    else:
        return '\n'


def get_namespaced_index(config, index):
    """ Grabs indexer.namespace from settings and namespace the given index """
    try:
        settings = config.registry.settings
    except:
        settings = config.settings
    namespace = settings.get('indexer.namespace') or ''
    return namespace + index


def replace_labels(axes, cols, labels):
    """
    Sets the the labels of the graph in a proper format. For example removes 'mag' from the old labels

    :param axes: The axes object of the subplot

    :param cols: The names of the cols
    :type cols: list
    :param labels: The new labels
    :type labels: list, dict
    :return:
    """
    if type(labels) == list:
        axes.set_xlabel(labels[0])
        axes.set_ylabel(labels[1])
    elif type(labels) == dict:
        axes.set_xlabel(labels[cols[0]])
        axes.set_ylabel(labels[cols[1]])
    else:
        axes.set_xlabel(cols[0].replace('mag', ''))
        axes.set_ylabel(cols[1].replace('mag', ''))


@classmethod
def gen_next(cls, dict_):
    """
        This function allows to change the dictionnary of the action that the agent will perform.

        Parameters
        ----------
        dict_: ``dict``
            A dictionnary representing an action. This dictionnary is assumed to be convertible into an action.
            No check is performed at this stage.

        """
    cls.my_dict = dict_
    return cls