def objectpath(node, keypath, default=None):
    """
    Traverse down a dot-separated object path into dict items or object attrs.
    For example, ``objectpath(handler, 'request.headers.User-Agent')`` returns
    ``handler.request.headers['User-Agent']``. Dictionary access is preferred.
    Returns ``None`` if the path is not found.
    """
    for key in keypath.split('.'):
        if hasattr(node, '__getitem__'):
            node = node.get(key)
        else:
            node = getattr(node, key, None)
        if node is None:
            return default
    return node


@staticmethod
def __Numericfun(x: int, conditList: list):
    """
        convert Integer to String based on condition.

        :param x: Number to convert
        :type x: int
        :param conditList: condition list
        :type conditList: list
        """
    result = ''
    for item in conditList:
        if type(item) == int:
            if x == item:
                result = str(item)
                break
        elif x >= item[0] and x <= item[1]:
            result = str(item[0]) + '-' + str(item[1])
            break
    return result


def del_object(id):
    """ Deletes the specified object
        """


def get_field(model, name):
    """Returns the field descriptor of the named field in the specified
    model.

    """
    return model._meta.get_field(name)


def getTestResults():
    """Return a dictionary that maps test-name tuples to ITestResult
        objects. This may return an empty or partially-filled dictionary
        until the build has completed."""


@classmethod
def Xaxis(cls):
    """Construct a unit vector along the X axis.

        Returns
        -------
        :class:`compas.geometry.Vector`
            A vector with components ``x = 1.0, y = 0.0, z = 0.0``.

        Examples
        --------
        >>> Vector.Xaxis()
        Vector(1.000, 0.000, 0.000)
        """
    return cls(1.0, 0.0, 0.0)


def is_permutation(a, b):
    """Returns True is the digits of b are a permutation of the digits of a"""
    a, b = list(str(a)), list(str(b))
    if len(a) != len(b):
        return False
    else:
        for item in a:
            if item not in b:
                return False
            else:
                b.remove(item)
        return True


def update_metadata(metadata, new_metadata, now):
    """Updates 'metadata' in-place with the information in 'new_metadata'.

    Timestamps are set according to the time 'now'.
    """
    if metadata is None:
        metadata = {}
    old_ctime = None
    if 'ctime' in metadata:
        old_ctime = metadata['ctime']
    if new_metadata is not None:
        newmd = new_metadata.copy()
        if 'tahoe' in newmd:
            del newmd['tahoe']
        if 'tahoe' in metadata:
            newmd['tahoe'] = metadata['tahoe']
        metadata = newmd
    sysmd = metadata.get('tahoe', {})
    if 'linkcrtime' not in sysmd:
        if old_ctime is not None:
            sysmd['linkcrtime'] = old_ctime
        else:
            sysmd['linkcrtime'] = now
    sysmd['linkmotime'] = now
    metadata['tahoe'] = sysmd
    return metadata


def list_dataperiods(client, level, year=None):
    """List ATLAS data periods.

	Args:
	    :client: the pyAMI client [ pyAMI.client.Client ]
	    :level: the period level (1, 2, 3) [ int ]
	    :year: the year [ int | None ]

	Returns:
	    an array of python dictionnaries.
	"""
    command = ['AMIListDataPeriods', '-periodLevel="%s"' % level,
        '-createdSince="2009-01-01 00:00:00"']
    if year:
        command.append('-projectName="data%02i%%"' % (year % 100))
    return client.execute(command, format='dom_object').get_rows()


def exists(storage, indexname=None):
    """Deprecated; use ``storage.index_exists()``.
    :param storage: a store.Storage object.
    :param indexname: the name of the index. If None, the default index name is
        used.
    """
    return storage.index_exists(indexname)


def applyChanges(data):
    """Generic form save method taken from z3c.form.form.EditForm."""


@classmethod
def open(cls, path, mode):
    """
        Open a data file.  The base implementation of this function just
        opens and returns a standard python file object.

        Subclasses can override to either open files using different openers
        (like fitsio.FITS), or, for more specific data types, return an
        instance of the class itself to use as an intermediary for the file.

        """
    return open(path, mode)


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

    Like 'git describe --tags --dirty --always -long'.
    The distance/hash is unconditional.

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


def _firstIdAndInstanceOfClass(container, class_):
    """Return the ID and instance of the first object of class `class_` within `container`. If there is none, return (None, None)."""
    for id in container.objectIds():
        if isinstance(container[id], class_):
            return id, container[id]
    return None, None


def assert_string_data(value: str) ->None:
    """Asserts value is string type."""
    assert isinstance(value, str
        ), f'Input value type must be string. Actual type: {type(value)}, value: {value}'


def _pt_specification_type_to_python_type(specification_type: str) ->str:
    """
    Convert a primitive specification type into its python equivalent.

    :param specification_type: a protocol specification data type
    :return: The equivalent data type in Python
    """
    python_type = specification_type[3:]
    return python_type


def stripnull(string):
    """Return string truncated at first null character."""
    i = string.find(b'\x00')
    return string if i < 0 else string[:i]


def _verify_all_np_ndarrays(op_name, func_name, args, out):
    """Verify if all the arrays are numpy ndarrays.

    Parameters
    ----------
    op_name : str
        Operator full name registered in backend.
    func_name : str
        Operator name exposed to users. This is usually the name by stripping off
        the prefix of the full operator names registered in backend.
    args : list of arrays
        Input ndarray arguments to be checked.
    out : ndarray or None or list of ndarrays
        User-provided output ndarrays.
    """
    from ..numpy import ndarray as np_ndarray
    for arr in args:
        if arr is not None and not isinstance(arr, np_ndarray):
            raise TypeError(
                'Operator `{}` registered in backend is known as `{}` in Python. This is a numpy operator which can only accept MXNet numpy ndarrays, while received a legacy ndarray. Please ensure that you have activated numpy semantics by calling `npx.set_np()` in your code. If you still see this error with numpy semantics activated, please call `as_np_ndarray()` upon the legacy ndarray to convert it to an MXNet numpy ndarray, and then feed the converted array to this operator.'
                .format(op_name, func_name))
    if out is None:
        return
    if not isinstance(out, (list, tuple)):
        out = [out]
    for arr in out:
        if arr is not None and not isinstance(arr, np_ndarray):
            raise TypeError(
                'Operator `{}` registered in backend is known as `{}` in Python. This is a numpy operator which can only accept MXNet numpy ndarrays, while received a legacy ndarray. Please ensure that you have activated numpy semantics by calling `npx.set_np()` in your code. If you still see this error with numpy semantics activated, please call `as_np_ndarray()` upon the legacy ndarray to convert it to an MXNet numpy ndarray, and then feed the converted array to this operator.'
                .format(op_name, func_name))


def psi_K_Na_Br_PK74(T, P):
    """c-c'-a: potassium sodium bromide [PK74]."""
    psi = -0.0022
    valid = T == 298.15
    return psi, valid


def iterate1(f, x):
    """Return an infinite generator yielding x, f(x), f(f(x)), ..."""
    while True:
        yield x
        x = f(x)


def _translate_vif_summary_view(_context, vif):
    """Maps keys for VIF summary view."""
    d = {}
    d['id'] = vif['id']
    d['mac_address'] = vif['address']
    d['ip_addresses'] = vif['ip_addresses']
    return d


def values(min=None, max=None, limit=100, tags=None, users=None):
    """BTree compatible accessor.
        min and max are longint IStatusUpdate.id keys.
        limit returns [:limit] most recent items
        returns matching for either users or tags, if given.
        """


def _assemble_master_key_providers(primary_provider, *providers):
    """Given one or more MasterKeyProvider instance, loads first MasterKeyProvider instance
    with all remaining MasterKeyProvider instances.

    :param primary_provider: MasterKeyProvider to use as the primary (ie: generates the Data Key)
    :type primary_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider
    :param *providers: MasterKeyProviders to add to primary_provider
    :returns: primary_provider with all other providers added to it
    :rtype: aws_encryption_sdk.key_providers.base.MasterKeyProvider
    """
    for provider in providers:
        primary_provider.add_master_key_provider(provider)
    return primary_provider


def _dataset_pre_0_3(client):
    """Return paths of dataset metadata for pre 0.3.4."""
    project_is_pre_0_3 = int(client.project.version) < 2
    if project_is_pre_0_3:
        return (client.path / 'data').rglob(client.METADATA)
    return []


def enable_foreign_key_checks(dbapi_connection, connection_record):
    """Enable foreign key constraint checks.

    SQLite supports FOREIGN KEY syntax when emitting CREATE statements for tables,
    however by default these constraints have no effect on the operation of the table.
    https://docs.sqlalchemy.org/en/latest/dialects/sqlite.html#foreign-key-support
    """
    cursor = dbapi_connection.cursor()
    cursor.execute('PRAGMA foreign_keys=ON')
    cursor.close()


@staticmethod
def _is_leap(year):
    """Return True if year of date is a leap year, otherwise False."""
    if year < 0:
        year += 1
    if year % 4 == 0 and not (year % 100 == 0 and year % 400 != 0):
        return True
    return False


def parse_path(path):
    """Parses path, creates normalized segment list.

    Dots are collapsed:

        >>> parse_path('../static//../app.py')
        ['app.py']

    :param path: path string to parse
    :return: normalized list of path segments.
    """
    segments = path.split('/')
    result = []
    for segment in segments:
        if not segment or segment == '.':
            continue
        if segment == '..':
            try:
                result.pop()
            except IndexError:
                pass
        else:
            result.append(segment)
    return result


def num_2_byte_list(num):
    """
    convert num to byte list
    :param num:
    :return:
    """
    byte = []
    while num > 0:
        b = num & 255
        byte.append(b)
        num = num >> 8
    return list(reversed(byte))


def optimize_db(cursor):
    """Set options to make sqlite more efficient on a high memory machine"""
    cursor.execute('PRAGMA cache_size = -%i' % (0.1 * 10 ** 7))
    cursor.execute('PRAGMA temp_store = 2')


def convert_env_boolean(env_value: str) ->bool:
    """ Converts an envvar string into a boolean.  Rules: true/True/TRUE/t/T/1 -> True;  All others false

    >>> convert_env_boolean('t')
    True

    >>> convert_env_boolean('1')
    True

    >>> convert_env_boolean('0')
    False
    """
    return env_value.lower() in ['true', '1', 't']


def RGQ_header_defined(vcf):
    """ Determine whether the RGQ annotation is defined in the FORMAT header of
    the vcf.
    """
    try:
        vcf.get_header_type('RGQ')
    except KeyError:
        return False
    else:
        return True


@classmethod
def validate(cls, name, config, admin=None, users=None, task=None):
    """Semantic check of benchmark arguments."""
    if cls.meta(name, 'admin_only') is True:
        print('Admin Access')
    if cls.meta(name, 'operator') is True:
        print('Operator')


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

        :param DeleteBatchResult val:
        :rtype: DeleteBatchJobStatus
        """
    return cls('complete', val)


def initiateAuthentication(identity_url, return_to=None):
    """Initiate the RPX authentication.
        """


def get_definitiongroup(target_platform):
    """
    Return ItemDefinitionGroup namespace depends on platform and target

    :param target_platform: wanted target: debug | release
    :type target_platform: tuple[str,str]
    :return: wanted ItemDefinitionGroup namespace
    :rtype: str
    """
    item = (
        '//ns:ItemDefinitionGroup[@Condition="\'$(Configuration)|$(Platform)\'==\'{}\'"]'
        .format('|'.join(target_platform)))
    return item


def rectify(x):
    """Rectify activation function :math:`\\varphi(x) = \\max(0, x)`

    Parameters
    ----------
    x : float32
        The activation (the summed, weighted input of a neuron).

    Returns
    -------
    float32
        The output of the rectify function applied to the activation.
    """
    return 0.5 * (x + abs(x))


@staticmethod
def check_for_errors(order, memory_depth, memory_stride):
    """Check for errors. Must be odd order with positive memory"""
    if order % 2 == 0 or order <= 0:
        raise Exception('PA Order must be positive and odd')
    if memory_depth <= 0:
        raise Exception('Memorydepth must be positive int')
    if memory_stride <= 0:
        raise Exception('Memory Stride must be a positive int')


def parse(hub, args=None, namespace=None, only_parse_known_arguments=False):
    """
    Parse the command line options
    """
    if only_parse_known_arguments:
        opts, unknown_args = hub.conf._mem['args']['parser'].parse_known_args(
            args, namespace)
        opts_dict = opts.__dict__
        opts_dict['_unknown_args_'] = unknown_args
    else:
        opts = hub.conf._mem['args']['parser'].parse_args(args, namespace)
        opts_dict = opts.__dict__
    return {'result': True, 'return': opts_dict}


def event_handler(keyset_id, handler_id=None):
    """Provide endpoint which allow block's event handlers manipulation.

    :type keyset_id:   int
    :param keyset_id:  Reference on unique identifier of application's
                       keyset for which event handler access required.
    :type handler_id:  int | None
    :param handler_id: Reference on unique identifier of block's event
                       handler.

    :rtype:  str
    :return: Target REST API endpoint which is relative to base address.
    """
    endpoint = '/v1/blocks/key/{0}/event_handler'.format(keyset_id)
    if handler_id:
        endpoint = '{0}/{1}'.format(endpoint, handler_id)
    return endpoint


def __getitem__(oid_tid):
    """
        Given an (oid, tid) pair, return the cache data (state_bytes,
        tid_int) for that object.

        The returned *tid_int* must match the requested tid.

        If the ``(oid, tid)`` pair isn't in the cache, return None.

        A special tid value of None means that the client doesn't know the TID to ask
        for and wants the best available; they are then required to verify
        that the returned object is visible (that is, within the ranges of TIDs
        the MVCC state permits).
        """


def purge_bibgloss_cache(app, env, docname):
    """Remove all information related to *docname* from the cache.
    :param app: The sphinx application.
    :type app: :class:`sphinx.application.Sphinx`
    :param env: The sphinx build environment.
    :type env: :class:`sphinx.environment.BuildEnvironment`
    """
    env.bibgloss_cache.purge(docname)


def varint_max_size(max_value):
    """Returns the maximum number of bytes a varint can take when encoded."""
    if max_value < 0:
        max_value = 2 ** 64 - max_value
    for i in range(1, 11):
        if max_value >> i * 7 == 0:
            return i
    raise ValueError('Value too large for varint: ' + str(max_value))


def message_warning(msg, *a, **kwargs):
    """Ignore everything except the message."""
    return str(msg) + '\n'


def date_to_datestr(date):
    """Converts datetime.date object with format '%Y-%m-%d' into corresponding date string with format 'YYYY-MM-DD'.

    Parameters
    ----------
    date : datetime.date

    Returns
    -------
    str
        string containing the date in format "YYYY-MM-DD"

    """
    return str(date)


def SaveXYZTrajectory(fname, atoms, comments=[]):
    """
    Save the animation on a XYZ file
    ================================

    This function save on a file a list of structures containing the frames
    of the animation in the xyz file from fname.

    Parameters:
    -----------
        - fname : string
            Path to the xyz animation file
        - atoms : list
            A list of the Structure() object to be written
        - comments: list, optional
            A list of comments for each frame.

    """
    for i, atms in enumerate(atoms):
        overwrite = False
        if i == 0:
            overwrite = True
        comment = '%d' % i
        if len(comments) - 1 >= i:
            comment = comments[i]
        atms.save_xyz(fname, comment, overwrite)


def binary_to_array(value=0, length=8):
    """
    takes an integer and converts it to 8 bit representation as an array.
    If float number is passed, it will be converted to int.
    """
    from numpy import arange, ndarray, nan
    value = int(value)
    binary = format(value, '#0' + str(length + 2) + 'b')
    arr = arange(length - 1)
    for i in range(length - 1):
        arr[i] = binary[length + 1 - i]
    return arr


def groups():
    """ Returns the groups for the current user, as a list. Including the
        current userid in this list is not required, as it will be implicitly
        added by the authentication policy. """


def build_authenticate_header(realm=''):
    """Optional WWW-Authenticate header (401 error)"""
    return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}


def OdfChk(SGLaue, L, M):
    """needs doc string"""
    if not L % 2 and abs(M) <= L:
        if SGLaue == '0':
            if M == 0:
                return True
        elif SGLaue == '-1':
            return True
        elif SGLaue == '2/m':
            if not abs(M) % 2:
                return True
        elif SGLaue == 'mmm':
            if not abs(M) % 2 and M >= 0:
                return True
        elif SGLaue == '4/m':
            if not abs(M) % 4:
                return True
        elif SGLaue == '4/mmm':
            if not abs(M) % 4 and M >= 0:
                return True
        elif SGLaue in ['3R', '3']:
            if not abs(M) % 3:
                return True
        elif SGLaue in ['3mR', '3m1', '31m']:
            if not abs(M) % 3 and M >= 0:
                return True
        elif SGLaue == '6/m':
            if not abs(M) % 6:
                return True
        elif SGLaue == '6/mmm':
            if not abs(M) % 6 and M >= 0:
                return True
        elif SGLaue == 'm3':
            if M > 0:
                if L % 12 == 2:
                    if M <= L // 12:
                        return True
                elif M <= L // 12 + 1:
                    return True
        elif SGLaue == 'm3m':
            if M > 0:
                if L % 12 == 2:
                    if M <= L // 12:
                        return True
                elif M <= L // 12 + 1:
                    return True
    return False


def base128Size(n):
    """ Return the length in bytes of a UIntBase128-encoded sequence with value n.

	>>> base128Size(0)
	1
	>>> base128Size(24567)
	3
	>>> base128Size(2**32-1)
	5
	"""
    assert n >= 0
    size = 1
    while n >= 128:
        size += 1
        n >>= 7
    return size


def get_supported_styles(transport):
    """Return a list of supported styles.

        :param transport: the name of a transport
        :return: a list of tuples (style, realm)
        """


def remove_tags(ResourceId=None, TagKeys=None):
    """
    Removes tags from an Amazon EMR resource. Tags make it easier to associate clusters in various ways, such as grouping clusters to track your Amazon EMR resource allocation costs. For more information, see Tagging Amazon EMR Resources .
    The following example removes the stack tag with value Prod from a cluster:
    See also: AWS API Documentation

    :example: response = client.remove_tags(
        ResourceId='string',
        TagKeys=[
            'string',
        ]
    )

    :type ResourceId: string
    :param ResourceId: [REQUIRED]
            The Amazon EMR resource identifier from which tags will be removed. This value must be a cluster identifier.

    :type TagKeys: list
    :param TagKeys: [REQUIRED]
            A list of tag keys to remove from a resource.
            (string) --

    :rtype: dict
    :return: {}

    """
    pass


def k2c(temp_k):
    """Convert temperature value from Kelvin to Celsius"""
    return temp_k - 273.15


def generate_client_certificate(description=None):
    """
    Generates a  ClientCertificate resource.
    See also: AWS API Documentation

    :example: response = client.generate_client_certificate(
        description='string'
    )

    :type description: string
    :param description: The description of the ClientCertificate .

    :rtype: dict
    :return: {
        'clientCertificateId': 'string',
        'description': 'string',
        'pemEncodedCertificate': 'string',
        'createdDate': datetime(2015, 1, 1),
        'expirationDate': datetime(2015, 1, 1)
    }

    """
    pass


@classmethod
def to_model(cls, result, additional_opts=None):
    """ Loads model from result using Marshmallow schema located in cls.Schema """
    opts = {}
    opts.update(cls.get_schema_opts())
    if additional_opts is not None:
        opts.update(additional_opts)
    schema = cls.Schema(**opts)
    model, errors = schema.load(result)
    return model


def getPassword():
    """Return password."""


def get_datasets(info_blob):
    """
    Get the dataset names and numpy array contents.

    Every output layer will get one dataset each for both the label and
    the prediction. E.g. if your model has an output layer called "energy",
    the datasets "label_energy" and "pred_energy" will be made.
    If there are no labels (e.g. during orga.inference), the label dataset
    will not be generated.

    Parameters
    ----------
    info_blob : dict
        Contains the following infos as keys/values:
        xs : ndarray
            Input to the network, after sample modifier has been applied.
        y_values : ndarray or None
            A structured array containing infos for every event, right from
            the input files.
            Can also be None, e.g. for when there are no y_values.
        ys : dict or None
            The labels for each output layer of the network.
            Can also be None, e.g. for when there are no y_values.
        y_pred : dict
            The predictions of each output layer of the network.

    Returns
    -------
    datasets : dict
        Keys are the name of the datagroups, values the content in the
        form of numpy arrays.

    """
    datasets = dict()
    if 'y_values' in info_blob:
        datasets['y_values'] = info_blob['y_values']
    if info_blob.get('ys') is not None:
        y_true = info_blob['ys']
        for out_layer_name in y_true:
            datasets['label_' + out_layer_name] = y_true[out_layer_name]
    y_pred = info_blob['y_pred']
    for out_layer_name in y_pred:
        datasets['pred_' + out_layer_name] = y_pred[out_layer_name]
    return datasets


@staticmethod
def get_size():
    """Returns the size of the reference (4 bytes)."""
    return 4


def getOrderId(context):
    """returns the unique id of an order"""


def address_type(address):
    """
    Return the types of the address

    This can be 'AF_INET', 'AF_UNIX', or 'AF_PIPE'
    """
    if type(address) == tuple:
        return 'AF_INET'
    elif type(address) is str and address.startswith('\\\\'):
        return 'AF_PIPE'
    elif type(address) is str:
        return 'AF_UNIX'
    else:
        raise ValueError('address type of %r unrecognized' % address)


@classmethod
def teardown_console(cls, app):
    """
        Perform console teardown tasks.
        """
    pass


def p_select_item(p):
    """select_item : select_item2 select_alias"""
    p[0] = p[1], p[2]


def wrap_neg_index(index, dim, neg_step=False):
    """Converts a negative index into a positive index.

    Args:
        index: The index to convert. Can be None.
        dim: The length of the dimension being indexed.
    """
    if index is not None and index < 0 and not (neg_step and index == -1):
        index += dim
    return index


@staticmethod
def convert_int_pointer_to_str_hex(i):
    """Converts a memory pointer integer to hex pointer string.

        For example, if i = 73588229205, '5544332211' is returned. The int is
        converted to hex string (with '0x' omitted) and then reversed. This is
        useful for obtaining hex pointers which are represented in memory in
        little endian format. Note that if the hex string has an odd length
        (e.g. '22b'), a '0' is padded to the last byte string so that '0b22' is
        returned.
        """
    str_hex = f'{i:02x}'
    if len(str_hex) % 2:
        str_hex = str_hex[:-1] + '0' + str_hex[-1:]
    str_hex = bytearray.fromhex(str_hex)
    str_hex.reverse()
    return str_hex.hex()


def readfile(filename):
    """Read contents of file specified by `filename`"""
    f = open(filename, 'r')
    s = f.read()
    f.close()
    return s


def backtrace(node):
    """
    Backtrace according to the parent records and return the path.
    (including both start and end nodes)
    """
    path = [(node.x, node.y)]
    while node.parent:
        node = node.parent
        path.append((node.x, node.y))
    path.reverse()
    return path


def add(obj):
    """ Add a new object to the list
        """


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def _bz4_compat_transform(bug, event, objdict, obj):
    """Modify the bug, event and obj dicts for a message to look more
    like a Bugzilla 4-era message's dicts did. Returns nothing as it
    modifies the dicts in place.
    """
    if bug.get('assigned_to', {}).get('login'):
        bug['assigned_to'] = bug['assigned_to']['login']
    if bug.get('component', {}).get('name'):
        bug['component'] = bug['component']['name']
    if bug.get('product', {}).get('name'):
        bug['product'] = bug['product']['name']
    bug['cc'] = bug.get('cc', [])
    if bug.get('reporter', {}).get('login'):
        bug['creator'] = bug['reporter']['login']
    if bug.get('operating_system'):
        bug['op_sys'] = bug['operating_system']
    if not bug.get('weburl'):
        bug['weburl'] = 'https://bugzilla.redhat.com/show_bug.cgi?id=%s' % bug[
            'id']
    event['who'] = event['user']['login']
    event['changes'] = event.get('changes', [])
    for change in event['changes']:
        change['field_name'] = change['field']
    if obj == 'comment':
        objdict[obj]['author'] = event.get('user', {}).get('login', '')


def all_safe_rewind(devices):
    """If all devices can have their trigger method re-run on resume.

    Parameters
    ----------
    devices : list
        List of devices

    Returns
    -------
    safe_rewind : bool
       If all the device can safely re-triggered
    """
    for d in devices:
        if hasattr(d, 'rewindable'):
            rewindable = d.rewindable.get()
            if not rewindable:
                return False
    return True


def closeChildFD(descriptor):
    """
        Close a file descriptor which is connected to the child process, identified
        by its FD in the child process.
        """


def getstorage(tree):
    """Retrieve an interface to storage for a particular tree.

        If ``tree`` is the empty bytestring, storage for the root manifest will
        be returned. Otherwise storage for a tree manifest is returned.

        TODO formalize interface for returned object.
        """


def extract_component_name(path):
    """
    >>> extract_component_name('/foo/trunk/bar.txt')
    'foo'
    >>> extract_component_name('/foo/trunk/')
    'foo'
    >>> extract_component_name('/foo/branches/1.x/abcd.txt')
    'foo'

    >>> extract_component_name('/foo')
    Traceback (most recent call last):
        ...
    AssertionError

    >>> extract_component_name('/foo/')
    Traceback (most recent call last):
        ...
    AssertionError

    >>> extract_component_name('foo/')
    Traceback (most recent call last):
        ...
    AssertionError

    >>> extract_component_name('/foo')
    Traceback (most recent call last):
        ...
    AssertionError

    >>> extract_component_name('/foo/trunk')
    Traceback (most recent call last):
        ...
    AssertionError

    >>> extract_component_name(None)
    Traceback (most recent call last):
        ...
    AssertionError

    >>> extract_component_name('')
    Traceback (most recent call last):
        ...
    AssertionError

    """
    assert path and path[0] == '/'
    assert path.count('/') >= 3
    return path[1:path.find('/', 2)]


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


@classmethod
def upsert_all(cls, engine, obj_or_data):
    """
        The :meth:`sqlalchemy.crud.updating.upsert_all` function in ORM syntax.

        :param engine: an engine created by``sqlalchemy.create_engine``.
        :param obj_or_data: single object or list of object
        """
    cls.update_all(engine=engine, obj_or_data=obj_or_data, upsert=True)


def unindent():
    """Delete 4 spaces from line beginning

    """
    pass


def index(lis, alternatives):
    """Return index of one of the <alternatives> in <lis>"""
    for alt in alternatives:
        try:
            return lis.index(alt)
        except ValueError:
            pass
    return None


def getComponentName():
    """ Return the component name configured for
        this predicate.
        """


def timedelta2sec(a_timedelta):
    """I convert from timedelta to seconds
    """
    return int(round(a_timedelta.total_seconds()))


def stabilize_2d_rotation_select():
    """Select tracks which are used for rotation stabilization

    """
    pass


@classmethod
def create(cls, name, container_object, security_enabled=True, scope=
    'GLOBAL', optional_attributes={}):
    """Creates and returns a new group"""
    return container_object.create_group(name=name, security_enabled=
        security_enabled, scope=scope, optional_attributes=optional_attributes)


def pretty_date(time=False):
    """
    Get a datetime object or a int() Epoch timestamp and return a
    pretty string like 'an hour ago', 'Yesterday', '3 months ago',
    'just now', etc
    """
    from datetime import datetime
    now = datetime.now()
    if type(time) is int:
        diff = now - datetime.fromtimestamp(time)
    elif isinstance(time, datetime):
        diff = now - time
    elif not time:
        diff = now - now
    second_diff = diff.seconds
    day_diff = diff.days
    if day_diff < 0:
        return ''
    if day_diff == 0:
        if second_diff < 10:
            return 'just now'
        if second_diff < 60:
            return f'{second_diff} seconds ago'
        if second_diff < 120:
            return 'a minute ago'
        if second_diff < 3600:
            return f'{round(second_diff / 60):.0f} minutes ago'
        if second_diff < 7200:
            return 'an hour ago'
        if second_diff < 86400:
            return f'{round(second_diff / 3600):.0f} hours ago'
    if day_diff == 1:
        return 'Yesterday'
    if day_diff < 7:
        return f'{day_diff} days ago'
    if day_diff < 31:
        return f'{round(day_diff / 7):.0f} weeks ago'
    if day_diff < 365:
        return f'{round(day_diff / 30):.0f} months ago'
    return f'{round(day_diff / 365):.0f} years ago'


@classmethod
def scp(cls, *args):
    """
        executes scp with the given arguments
        :param args:
        :return:
        """
    return cls.execute('scp', args)


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

        :param WriteError val:
        :rtype: CreateFolderEntryError
        """
    return cls('path', val)


@staticmethod
def get_types(*args, **kwargs) ->list:
    """returns a list of all types of the passed arguments.
        e.g. simple_function(10, [1,2]) will return [int, list]"""
    arg_types = []
    for arg in args:
        arg_types.append(type(arg))
    for values in kwargs.values():
        arg_types.append(type(values))
    return arg_types


@classmethod
def get_by_name(cls, context, name):
    """Find an allocation based by its name.

        :param cls: the :class:`Allocation`
        :param context: Security context
        :param name: The name of an allocation.
        :returns: An :class:`Allocation` object.
        :raises: AllocationNotFound

        """
    db_allocation = cls.dbapi.get_allocation_by_name(name)
    allocation = cls._from_db_object(context, cls(), db_allocation)
    return allocation


def psi_Ca_Na_SO4_HMW84(T, P):
    """c-c'-a: calcium sodium sulfate [HMW84]."""
    psi = -0.055
    valid = T == 298.15
    return psi, valid


def strftime(format):
    """Format the date/time using the *current timezone representation*."""


@staticmethod
def _spiral(width, height):
    """Spiral generator.

        Parameters
        ----------
        width : `int`
            Spiral width.
        height : `int`
            Spiral height.

        Returns
        -------
        `generator` of (`int`, `int`)
            Points.
        """
    if width == 1:
        for y in range(height - 1, -1, -1):
            yield 0, y
        return
    if height == 1:
        for x in range(width - 1, -1, -1):
            yield x, 0
        return
    if width <= height:
        x0 = width // 2
        if width % 2:
            for y in range(height - 1 - x0, x0 - 1, -1):
                yield x0, y
        x0 -= 1
        y0 = x0
    else:
        y0 = height // 2
        if height % 2:
            for x in range(width - 1 - y0, y0 - 1, -1):
                yield x, y0
        y0 -= 1
        x0 = y0
    while x0 >= 0:
        x1 = width - x0 - 1
        y1 = height - y0 - 1
        for y in range(y0 + 1, y1):
            yield x0, y
        for x in range(x0, x1):
            yield x, y1
        for y in range(y1, y0, -1):
            yield x1, y
        for x in range(x1, x0 - 1, -1):
            yield x, y0
        x0 -= 1
        y0 -= 1


@classmethod
def from_dict(cls, d):
    """
           Read information from dictionary

           Parameters
           ----------
           d: dict
               Dictionary including parameters for replica exchange Monte Carlo method

           Returns
           -------
           params: DFTParams object
               self
        """
    if 'replica' in d:
        d = d['replica']
    params = cls()
    params.nreplicas = d['nreplicas']
    params.nprocs_per_replica = d['nprocs_per_replica']
    params.kTstart = d['kTstart']
    params.kTend = d['kTend']
    params.nsteps = d['nsteps']
    params.RXtrial_frequency = d.get('RXtrial_frequency', 1)
    params.sample_frequency = d.get('sample_frequency', 1)
    params.print_frequency = d.get('print_frequency', 1)
    params.reload = d.get('reload', False)
    params.seed = d.get('seed', 0)
    return params


def choose_color_by_layertype(layertype):
    """Define colors for nodes based on the layer type.
    """
    color = '#6495ED'
    if layertype == 'Convolution' or layertype == 'Deconvolution':
        color = '#FF5050'
    elif layertype == 'Pooling':
        color = '#FF9900'
    elif layertype == 'InnerProduct':
        color = '#CC33FF'
    return color


def pivot(df, index=None, columns=None, values=None):
    """ Alternative pivot which supports multiple columns for index/columns """
    if index:
        df = df.set_index(index)
    if columns:
        df = df.set_index(columns, append=True).unstack(columns)
    if values:
        df = df[values]
    return df


def reverse(d):
    """Return a reverse lookup dictionary for the input dictionary"""
    r = {}
    for k in d:
        r[d[k]] = k
    return r


def _machine_fqdn(machine):
    """Returns the FQDN of the given learning machine.
    """
    from acorn.logging.decoration import _fqdn
    if hasattr(machine, '__class__'):
        return _fqdn(machine.__class__, False)
    else:
        return _fqdn(machine)


def get_byte_size_of_string(string: str) ->int:
    """
    Return the number of bytes of a string
    """
    return len(string.encode('utf-8'))


def _review(subs, shared):
    """Configure the `doorstop review` subparser."""
    info = 'absolve items of their unreviewed status'
    sub = subs.add_parser('review', description=info.capitalize() + '.',
        help=info, **shared)
    sub.add_argument('label', help="item UID, document prefix, or 'all'")
    group = sub.add_mutually_exclusive_group()
    group.add_argument('-i', '--item', action='store_true', help=
        "indicates the 'label' is an item UID")
    group.add_argument('-d', '--document', action='store_true', help=
        "indicates the 'label' is a document prefix")


def __call__(model, request):
    """Renders the tile.

        It's intended to work this way: First it calls its own prepare method,
        then it checks its own show attribute. If this returns True it renders
        the template in the context of the ITile implementing class instance.
        """


def isPackage():
    """Returns True if this module is a package.
        """


def check_num_rows_of_parameter_array(param_array, correct_num_rows, title):
    """
    Ensures that `param_array.shape[0]` has the correct magnitude. Raises a
    helpful ValueError if otherwise.

    Parameters
    ----------
    param_array : ndarray.
    correct_num_rows : int.
        The int that `param_array.shape[0]` should equal.
    title : str.
        The 'name' of the param_array whose shape is being checked.

    Results
    -------
    None.
    """
    if param_array.shape[0] != correct_num_rows:
        msg = '{}.shape[0] should equal {}, but it does not'
        raise ValueError(msg.format(title, correct_num_rows))
    return None


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


def can_complain(func):
    """Marks `func` (in-place) as capable of reporting notices.

    If so marked, `func` will be called
    with a special `complain` function as the first argument,
    which must be called to report a notice.
    """
    func.with_complaints = True
    return func


def _scala_seq_to_py(jseq):
    """Generator for all elements in a Scala sequence.

    Parameters
    ----------
    jseq : Scala Seq
        Scala sequence

    Yields
    ------
    any
        One element per sequence
    """
    n = jseq.size()
    for i in range(n):
        yield jseq.apply(i)


def create_event_subscription(SubscriptionName=None, SnsTopicArn=None,
    SourceType=None, EventCategories=None, SourceIds=None, Enabled=None,
    Tags=None):
    """
    Creates an AWS DMS event notification subscription.
    You can specify the type of source (SourceType ) you want to be notified of, provide a list of AWS DMS source IDs (SourceIds ) that triggers the events, and provide a list of event categories (EventCategories ) for events you want to be notified of. If you specify both the SourceType and SourceIds , such as SourceType = replication-instance and SourceIdentifier = my-replinstance , you will be notified of all the replication instance events for the specified source. If you specify a SourceType but don't specify a SourceIdentifier , you receive notice of the events for that source type for all your AWS DMS sources. If you don't specify either SourceType nor SourceIdentifier , you will be notified of events generated from all AWS DMS sources belonging to your customer account.
    For more information about AWS DMS events, see Working with Events and Notifications in the AWS Database MIgration Service User Guide.
    See also: AWS API Documentation

    :example: response = client.create_event_subscription(
        SubscriptionName='string',
        SnsTopicArn='string',
        SourceType='string',
        EventCategories=[
            'string',
        ],
        SourceIds=[
            'string',
        ],
        Enabled=True|False,
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type SubscriptionName: string
    :param SubscriptionName: [REQUIRED]
            The name of the DMS event notification subscription.
            Constraints: The name must be less than 255 characters.

    :type SnsTopicArn: string
    :param SnsTopicArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the Amazon SNS topic created for event notification. The ARN is created by Amazon SNS when you create a topic and subscribe to it.

    :type SourceType: string
    :param SourceType: The type of AWS DMS resource that generates the events. For example, if you want to be notified of events generated by a replication instance, you set this parameter to replication-instance . If this value is not specified, all events are returned.
            Valid values: replication-instance | migration-task

    :type EventCategories: list
    :param EventCategories: A list of event categories for a source type that you want to subscribe to. You can see a list of the categories for a given source type by calling the DescribeEventCategories action or in the topic Working with Events and Notifications in the AWS Database Migration Service User Guide.
            (string) --

    :type SourceIds: list
    :param SourceIds: The list of identifiers of the event sources for which events will be returned. If not specified, then all sources are included in the response. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens; it cannot end with a hyphen or contain two consecutive hyphens.
            (string) --

    :type Enabled: boolean
    :param Enabled: A Boolean value; set to true to activate the subscription, or set to false to create the subscription but not activate it.

    :type Tags: list
    :param Tags: A tag to be attached to the event subscription.
            (dict) --
            Key (string) --A key is the required name of the tag. The string value can be from 1 to 128 Unicode characters in length and cannot be prefixed with 'aws:' or 'dms:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').
            Value (string) --A value is the optional value of the tag. The string value can be from 1 to 256 Unicode characters in length and cannot be prefixed with 'aws:' or 'dms:'. The string can only contain only the set of Unicode letters, digits, white-space, '_', '.', '/', '=', '+', '-' (Java regex: '^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-]*)$').

    :rtype: dict
    :return: {
        'EventSubscription': {
            'CustomerAwsId': 'string',
            'CustSubscriptionId': 'string',
            'SnsTopicArn': 'string',
            'Status': 'string',
            'SubscriptionCreationTime': 'string',
            'SourceType': 'string',
            'SourceIdsList': [
                'string',
            ],
            'EventCategoriesList': [
                'string',
            ],
            'Enabled': True|False
        }
    }

    :returns:
    (string) --

    """
    pass


@classmethod
def is_retweet(cls, tweet):
    """Check if the tweet is a retweet"""
    return 'retweeted_status' in tweet or tweet['text'].startswith('RT ')


@classmethod
def from_dict(cls, connection, data):
    """Returns an alert object from a dictionary item,
        which is usually from librato's API"""
    obj = cls(connection, data['name'], version=data['version'],
        description=data['description'], conditions=data['conditions'],
        services=data['services'], _id=data['id'], active=data['active'],
        rearm_seconds=data['rearm_seconds'], attributes=data['attributes'],
        md=data['md'])
    return obj


def _is_namespace_visible(context, namespace, status=None):
    """Return True if the namespace is visible in this context."""
    if context.is_admin:
        return True
    if namespace['owner'] is None:
        return True
    if 'visibility' in namespace:
        if namespace['visibility'] == 'public':
            return True
    if context.owner is not None:
        if context.owner == namespace['owner']:
            return True
    return False


@classmethod
def _write_vars_plus_flanks_to_fasta(cls, outfile, vcf_records, ref_seqs,
    flank_length):
    """Given a dict of vcf records made by vcf_file_read.vcf_file_to_dict(),
        and its correcsponding file of reference sequences, writes a new fasta file
        of each ref seq and inferred variant sequence plus flank_length nucleotides added to
        its start and end. Calls each sequence:
            ref_name.start_position.vcf_list_index.allele_number
        where allele_numbers in same order as VCF, with ref seq = allele 0."""
    with open(outfile, 'w') as f:
        for ref_name in sorted(vcf_records):
            for i, vcf_record in enumerate(vcf_records[ref_name]):
                start_position, alleles = (vcf_record.
                    inferred_var_seqs_plus_flanks(ref_seqs[ref_name],
                    flank_length))
                for allele_index, allele_seq in enumerate(alleles):
                    seq_name = '.'.join([ref_name, str(start_position + 1),
                        str(i), str(allele_index)])
                    print('>' + seq_name, allele_seq, sep='\n', file=f)


@classmethod
def is_integrity_error(cls, exception):
    """Check if given exception flags an integrity error in the DB"""
    raise NotImplementedError('Implement in subclass')


def get_complete_version(version=None):
    """Returns a tuple of the django version. If version argument is non-empty,
    then checks for correctness of the tuple provided.
    """
    if version is None:
        from firebird import VERSION as version
    else:
        assert len(version) == 5
        assert version[3] in ('alpha', 'beta', 'rc', 'final')
    return version


def remove(alias):
    """Remove the given address as an acceptable aliases for posting.

        :param alias: The email address to no longer accept as a recipient for
            implicit destination posting purposes.
        :type alias: string
        """


def successors_query(var_name, node_id, node_label, edge_label,
    successor_label=None, undirected=False):
    """Generate query for getting the ids of all the successors of a node.

    Parameters
    ----------
    var_name
        Name of the variable corresponding to the node to match
    node_id
        Id of the node to match
    node_label : optional
        Label of the node to match, default is 'node'
    edge_label : optional
        Label of the edge to match, default is 'edge'
    successor_label : optional
        Label of the successors we want to find,
        'node_label' is used if None.
    """
    if successor_label is None:
        successor_label = node_label
    if undirected is False:
        arrow = '>'
    else:
        arrow = ''
    query = "OPTIONAL MATCH (n{}:{} {{id : '{}'}})-[:{}]-{} (suc:{})\n".format(
        var_name, node_label, node_id, edge_label, arrow, successor_label
        ) + 'RETURN suc.id as suc'
    return query


def get_target_audiences():
    """Return all of the target_audiences.
        """


def p_suffix(p):
    """unary_expression : SUFFIX"""
    p[0] = p[1]


def writeOutfile(outfile, arr, nams, removed, rmfile=None):
    """
    Writes an alignment stored in a numpy array into a FASTA file.

    Parameters
    ----------
    outfile: str
        Path to FASTA file where the output should be stored
    arr: np.array
        Numpy array containing the cleaned alignment
    nams: list
        List of nams of sequences in the input alignment
    removed: set
        Set of names of sequences which have been removed
    rmfile: str
        Path to file used to log sequences and columns which have been removed

    Returns
    -------
    None

    """
    out = open(outfile, 'w')
    if rmfile is not None:
        rm = open(rmfile, 'a')
        rm.write('Removed sequences:\n')
    else:
        rm = None
    i = 0
    for nam in nams:
        if nam not in removed:
            out.write('>%s\n%s\n' % (nam, ''.join(list(arr[i]))))
            i += 1
        elif rm is not None:
            rm.write('%s\n' % nam)
    out.close()
    if rm is not None:
        rm.close()


def _set_rekey_passphrase(db_handle, passphrase):
    """
    Change the passphrase for encryption key derivation.

    The key itself can be a passphrase, which is converted to a key using
    PBKDF2 key derivation. The result is used as the encryption key for
    the database.

    :param db_handle: A handle to the SQLCipher database.
    :type db_handle: pysqlcipher.Connection
    :param passphrase: The passphrase used to derive the encryption key.
    :type passphrase: str
    """
    db_handle.cursor().execute("PRAGMA rekey = '%s'" % passphrase)


def voltage_evq(energy, charge):
    """Usage: voltage_evq(energy, charge)"""
    return energy / charge


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

        :param SharedContentRemoveMemberType val:
        :rtype: EventType
        """
    return cls('shared_content_remove_member', val)


def get_memory_mb(mem_str):
    """Get the memory in MB from memory string.

    mem_str: str
        String representation of memory requirement.

    Returns
    -------
    mem_mb: int
        Memory requirement in MB.
    """
    mem_str = mem_str.lower()
    if mem_str.endswith('g'):
        return int(float(mem_str[:-1]) * 1024)
    elif mem_str.endswith('m'):
        return int(float(mem_str[:-1]))
    else:
        msg = (
            'Invalid memory specification %s, need to be a number follows g or m'
             % mem_str)
        raise RuntimeError(msg)


def get_quality_by_depth(var):
    """
    Returns the quality by depth or the variant confidence,
    or None if it isn't present in the VCF.
    """
    return var.INFO.get('QD')


def instance(cls):
    """
    Class decorator for creating single instances.
    """
    return cls()


@classmethod
def ensure_frequency(cls, frequency):
    """Ensure the given args is AsyncFrequency.

        :param frequency: args to create a AsyncFrequency instance.
        :type frequency: AsyncFrequency / dict / list / tuple
        :return: AsyncFrequency instance
        :rtype: AsyncFrequency
        """
    if isinstance(frequency, cls):
        return frequency
    elif isinstance(frequency, dict):
        return cls(**frequency)
    else:
        return cls(*frequency)


def splitTrainTestData(df, size=1):
    """ Splits a dataframe by <size> starting from the rear """
    return df.iloc[:-size], df.tail(size)


def dir_rea_metabolites(rea_metbolites):
    """
    convert reaction.metabolites to str

    :param rea_metbolites: reaction.metabolites a special dictionary
    :return: a str of rea_metbolites
    eval(str_rea_metabolites(rea_metbolites)) could be a normal dictionary
    """
    temp_dic = {}
    for k, v in rea_metbolites.items():
        temp_dic[k.id] = v
    return temp_dic


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


def re_split(regex, string, maxsplit):
    """Same as regex.split(string, maxsplit), but does not include the text in capturing groups.

    https://docs.python.org/3/library/re.html#re.split
    """
    if regex.match(''):
        raise ValueError('Delimiter matching empty string not supported')
    assert maxsplit > 0
    parts = []
    cur = 0
    for match in regex.finditer(string):
        start, end = match.span()
        assert start < end
        parts.append(string[cur:start])
        cur = end
        if len(parts) >= maxsplit:
            break
    assert cur <= len(string)
    parts.append(string[cur:])
    return parts


@classmethod
def get_corresponding_property(cls, entity_table, given_property, mapper):
    """
        This method returns an updated property for a given a property.
        If there is no update for the property, the given property is returned.
        """
    try:
        property_mapping = mapper[entity_table]
        try:
            return property_mapping[given_property]
        except KeyError:
            return given_property
    except KeyError:
        return given_property


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    if not client_message.read_bool():
        parameters['response'] = to_object(client_message.read_data())
    return parameters


def _parsemeta_tmy2(columns, line):
    """Retrieves metadata from the top line of the tmy2 file.

    Parameters
    ----------
    columns : string
        String of column headings in the header

    line : string
        Header string containing DataFrame

    Returns
    -------
    meta : Dict of metadata contained in the header string
    """
    rawmeta = ' '.join(line.split()).split(' ')
    meta = rawmeta[:3]
    meta.append(int(rawmeta[3]))
    longitude = (float(rawmeta[5]) + float(rawmeta[6]) / 60) * (2 * (
        rawmeta[4] == 'N') - 1)
    latitude = (float(rawmeta[8]) + float(rawmeta[9]) / 60) * (2 * (rawmeta
        [7] == 'E') - 1)
    meta.append(longitude)
    meta.append(latitude)
    meta.append(float(rawmeta[10]))
    meta_dict = dict(zip(columns.split(','), meta))
    return meta_dict


def get_barcode_tag(read, cell_barcode=False, umi_tag='RX', cell_tag=None,
    umi_tag_split=None, umi_tag_delim=None, cell_tag_split='-',
    cell_tag_delim=None):
    """ extract the umi +/- cell barcode from the specified tag """
    try:
        if cell_barcode:
            umi = read.get_tag(umi_tag)
            cell = read.get_tag(cell_tag)
        else:
            umi = read.get_tag(umi_tag)
            cell = None
        if umi_tag_split:
            umi = umi.split(umi_tag_split)[0]
        if umi_tag_delim:
            umi = ''.join(umi.split(umi_tag_delim))
        if cell and cell_tag_split:
            cell = cell.split(cell_tag_split)[0]
        if cell and cell_tag_delim:
            cell = ''.join(cell.split(cell_tag_delim))
        if cell:
            cell = cell.encode('utf-8')
        return umi.encode('utf-8'), cell
    except IndexError:
        raise ValueError(
            'Could not extract UMI +/- cell barcode from the read tag')


def duplicate():
    """Make a copy of all selected keyframes

    """
    pass


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

    :type operation_name: string
    :param operation_name: The operation name. This is the same name
            as the method name on the client. For example, if the
            method name is create_foo, and you'd normally invoke the
            operation as client.create_foo(**kwargs), if the
            create_foo operation can be paginated, you can use the
            call client.get_paginator('create_foo').

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


def get_template_from_string(source):
    """
    Does not support then ``name`` and ``origin`` parameters from
    the Django version.
    """
    from pyjade_coffin.common import env
    return env.from_string(source)


def glTexCoord(s, t, r, q, v: 'Buffer'):
    """Set the current texture coordinates

    :param q: Specify s, t, r, and q texture coordinates. Not all parameters are present in all forms of the command.
    :param v: Specifies a pointer to an array of one, two, three, or four elements, which in turn specify the s, t, r, and q texture coordinates.
    :type v: 'Buffer'
    """
    pass


def validate_latlon_pair(value):
    """
    Check to make sure value is a tuple or list of length 2,
    where the first element is a longitude and the second.
    is a latitude.
    """
    if len(value) != 2:
        raise ValueError(
            'List inputs are assumed to be coordinate pairs. This list has more than two elements.'
            )
    if not -180.0 <= value[0] <= 180.0:
        raise ValueError(' '.join([
            'The first element of the list is assumed to be longitude (x-coordinates),'
            , 'but this element is outside acceptable bounds (-180.0, 180.0)'])
            )
    if not -90.0 <= value[0] <= 90.0:
        raise ValueError(' '.join([
            'The second element of the list is assumed to be latitude (y-coordinates),'
            , 'but this element is outside acceptable bounds (-90.0, 90.0)']))
    return True


def get_at(doc, path, create_anyway=False):
    """Get the value, if any, of the document at the given path, optionally
            mutating the document to create nested dictionaries as necessary.
            """
    node = doc
    last = len(path) - 1
    if last == 0:
        return doc.get(path[0])
    for index, edge in enumerate(path):
        if edge in node:
            node = node[edge]
        elif index == last or not create_anyway:
            return None
        else:
            node = node[edge] = {}
    return node


@classmethod
def get_by_name(cls, context, name):
    """Find portgroup based on name and return a :class:`Portgroup` object.

        :param cls: the :class:`Portgroup`
        :param context: Security context
        :param name: The name of a portgroup.
        :returns: A :class:`Portgroup` object.
        :raises: PortgroupNotFound

        """
    db_portgroup = cls.dbapi.get_portgroup_by_name(name)
    portgroup = cls._from_db_object(context, cls(), db_portgroup)
    return portgroup


@classmethod
def build_sub_where_criteria(cls, sub_where_criteria, sub_condition):
    """
        Build sub where criteria form sub_condition ((sub_condition1), operator, (sub_condition2))
        eg. (('active', '=', True), 'OR', ('name', '=', 'sanish'))
        :type sub_where_criteria: dict
        :param sub_where_criteria: sub where criteria {'and_conditions':list, 'or_conditions':list}
        :type sub_condition: tuple
        :param sub_condition: sub condition (('active', '=', True), 'OR', ('name', '=', 'sanish'))
        """
    if isinstance(sub_condition, tuple) is False or len(sub_condition) != 3:
        raise TypeError('Invalid criteria condition: {}'.format(sub_condition))
    if 'and_conditions' not in sub_where_criteria or isinstance(
        sub_where_criteria.get('and_conditions'), list
        ) is False or 'or_conditions' not in sub_where_criteria or isinstance(
        sub_where_criteria.get('or_conditions'), list) is False:
        raise TypeError('Invalid where criteria data initialized: {}'.
            format(sub_where_criteria))
    condition1 = sub_condition[0]
    condition2 = sub_condition[2]
    operator = sub_condition[1]
    if isinstance(condition1, tuple) is False:
        raise TypeError('Invalid criteria condition: {}'.format(condition1))
    if isinstance(condition2, tuple) is False:
        raise TypeError('Invalid criteria condition: {}'.format(condition2))
    if isinstance(operator, str) is False or operator not in ['AND', 'OR']:
        raise TypeError('criteria {} operator: should be [AND | OR]'.format
            (sub_condition))
    cls.build_where_criteria(sub_where_criteria, condition1, operator.upper())
    cls.build_where_criteria(sub_where_criteria, condition2, operator.upper())


def dtype_to_ctype(dtype):
    """Get the CL type of the given numpy data type.

    Args:
        dtype (np.dtype): the numpy data type

    Returns:
        str: the CL type string for the corresponding type
    """
    from pyopencl.tools import dtype_to_ctype
    return dtype_to_ctype(dtype)


def remove_unicode_nbsp(text: str) ->str:
    """ Removes unicode whitespaces
    :param text: Text to be cleaned
    :return: Clean text
    """
    return text.replace(u'\xa0', u' ')


def sync():
    """Synchronize computation.

    In DL frameworks such as MXNet and TensorFlow, the computation in operators
    are done asynchronously. This is to synchronize computation and makes sure
    that all computation is complete after this function call.
    """
    pass


def trim(x):
    """Removes (strips) whitespace from both ends of the string"""
    return x.strip()


def is_directory(bucket, path):
    """
    Return True if the path given is a directory.

    The existence check goes something like this:
        0) for key under consideration foo/bar/
        1) if a zero-length key exists for "foo/bar/", then True.
        2) if a bucket listing with prefix "foo/bar/" returns one or more
           objects, then True.
        3) else False.
    """
    if not path.endswith('/'):
        path = path + '/'
    for key in bucket.list(prefix=path):
        return True
    return False


@classmethod
def get_from_string(cls, string_condition):
    """
        Convert string value obtained from k8s API to PodCondition enum value
        :param string_condition: str, condition value from Kubernetes API
        :return: PodCondition
        """
    if string_condition == 'PodScheduled':
        return cls.SCHEDULED
    elif string_condition == 'Ready':
        return cls.READY
    elif string_condition == 'Initialized':
        return cls.INITIALIZED
    elif string_condition == 'Unschedulable':
        return cls.UNSCHEDULABLE
    elif string_condition == 'ContainersReady':
        return cls.CONTAINERS_READY
    return cls.UNKNOWN


def _v_silent(exc):
    """Receive a 'silent' exception.

    :param exc: exception
    :type  exc: :exc:`exceptions.Exceptions`

    Default ignores the exception and just does nothing. This function can be
    modified to debug ignored exceptions.

    """
    pass


def indent_char2int(indent):
    """Convert a character indent into a number of spaces that should be used.
    Tabs are set to be equivalent to 4 spaces.

    Args:
        indent (str): String indent.

    Returns:
        int: Number of whitespaces that is equivalent to the provided string.

    """
    if isinstance(indent, str):
        indent = len(indent.replace('\t', '    '))
    return indent


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

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

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


def string(s):
    """
    Convert a string to a escaped ASCII representation including quotation marks
    :param s: a string
    :return: ASCII escaped string
    """
    ret = ['"']
    for c in s:
        if ' ' <= c < '\x7f':
            if c == "'" or c == '"' or c == '\\':
                ret.append('\\')
            ret.append(c)
            continue
        elif c <= '\x7f':
            if c in ('\r', '\n', '\t'):
                ret.append(c.encode('unicode-escape').decode('ascii'))
                continue
        i = ord(c)
        ret.append('\\u')
        ret.append('%x' % (i >> 12))
        ret.append('%x' % (i >> 8 & 15))
        ret.append('%x' % (i >> 4 & 15))
        ret.append('%x' % (i & 15))
    ret.append('"')
    return ''.join(ret)


def mean(data):
    """
    Return the arithmetic mean of ``data``.

    Examples
    --------

    >>> mean([1, 2, 3, 4, 4])
    2.8
    """
    if len(data) < 1:
        return None
    return float(sum(data)) / len(data)


def clear_udld_statistics(enode):
    """
    Clear UDLD statistics from all interfaces.

    This function runs the following vtysh command:

    ::

        # clear udld statistics

    """
    cmd = 'clear udld statistics'
    result = enode(cmd.format(**locals()), shell='vtysh')
    assert not result


@staticmethod
def find_longest_substring(full, partial):
    """Finds the longest overlap between a full length sequences and a partial length sequence.

        Parameters
        ----------
        full : str
            A full length sequence string.
        partial : str
            A partial length sequence string to compare against the full length sequence.

        Returns
        -------
        str
            The longest substring from the compared input strings.

        """
    var_1 = [([0] * (1 + len(partial))) for i in range(1 + len(full))]
    index_1, index_2 = 0, 0
    for x in range(1, 1 + len(full)):
        for y in range(1, 1 + len(partial)):
            if full[x - 1] == partial[y - 1]:
                var_1[x][y] = var_1[x - 1][y - 1] + 1
                if var_1[x][y] > index_1:
                    index_1 = var_1[x][y]
                    index_2 = x
            else:
                var_1[x][y] = 0
    return full[index_2 - index_1:index_2]


def get_web_acl(WebACLId=None):
    """
    Returns the  WebACL that is specified by WebACLId .
    See also: AWS API Documentation

    Examples
    The following example returns the details of a web ACL with the ID createwebacl-1472061481310.
    Expected Output:

    :example: response = client.get_web_acl(
        WebACLId='string'
    )

    :type WebACLId: string
    :param WebACLId: [REQUIRED]
            The WebACLId of the WebACL that you want to get. WebACLId is returned by CreateWebACL and by ListWebACLs .

    :rtype: dict
    :return: {
        'WebACL': {
            'WebACLId': 'string',
            'Name': 'string',
            'MetricName': 'string',
            'DefaultAction': {
                'Type': 'BLOCK'|'ALLOW'|'COUNT'
            },
            'Rules': [
                {
                    'Priority': 123,
                    'RuleId': 'string',
                    'Action': {
                        'Type': 'BLOCK'|'ALLOW'|'COUNT'
                    }
                },
            ]
        }
    }

    :returns:
    ALLOW : AWS WAF allows requests
    BLOCK : AWS WAF blocks requests
    COUNT : AWS WAF increments a counter of the requests that match all of the conditions in the rule. AWS WAF then continues to inspect the web request based on the remaining rules in the web ACL. You can't specify COUNT for the default action for a WebACL .

    """
    pass


def pytest_addoption(parser):
    """
    register argparse-style options and ini-style config values.
    """
    output_options_group = parser.getgroup('Output Options')
    output_options_group.addoption('--sys-stats', default=False, action=
        'store_true', help=
        'Print System CPU and MEM statistics after each test execution.')
    output_options_group.addoption('--sys-stats-no-children', default=False,
        action='store_true', help=
        "Don't include child processes memory statistics.")
    output_options_group.addoption('--sys-stats-uss-mem', default=False,
        action='store_true', help=
        'Use the USS("Unique Set Size", memory unique to a process which would be freed if the process was terminated) memory instead which is more expensive to calculate.'
        )


@classmethod
def find_code(cls, code):
    """
        Find normal and global generic package instances
        """
    return cls._find_normal_package_codes(code)


def find_exchange_reactions(model):
    """ Finds the exchange reaction in given FBA model.

    Currently the exchange rids are found via
    prefix EX_.

    :param model: SBML model
    :returns dictonary of ex_rids: sids
    """
    ex_rids = {}
    for reactions in model.getListOfReactions():
        rid = reactions.getId()
        if rid.startswith('EX_'):
            r = model.getReaction(rid)
            sid = r.getReactant(0).getSpecies()
            ex_rids[rid] = sid
    return ex_rids


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def _add_folder_positional_arg(arg_parser):
    """
    Adds folders and/or filenames parameter to a parser.
    :param arg_parser: ArgumentParser parser to add this argument to.
    """
    arg_parser.add_argument('folder', metavar='Folder', help=
        "Name of the folder to download the project contents into. If not specified it will use the name of the project with spaces translated to '_'. "
        , nargs='?')


def log1p(ic):
    """
        Element-wise log of 1 + an `ImageCollection`.

        If the `ImageCollection` is empty, returns the empty `ImageCollection`.

        Example
        -------
        >>> import descarteslabs.workflows as wf
        >>> col = wf.ImageCollection.from_id("landsat:LC08:01:RT:TOAR",
        ...     start_datetime="2017-01-01", end_datetime="2017-05-30")
        >>> col.log1p().compute(geoctx) # doctest: +SKIP
        ImageCollectionResult of length 2:
        ...
        """
    from ..math import arithmetic
    return arithmetic.log1p(ic)


def topological_sort(graph_unsorted):
    """
    Repeatedly go through all of the nodes in the graph, moving each of
    the nodes that has all its edges resolved, onto a sequence that
    forms our sorted graph. A node has all of its edges resolved and
    can be moved once all the nodes its edges point to, have been moved
    from the unsorted graph onto the sorted one.

    NB - this destroys the graph_unsorted dictionary that was passed in
    and just returns the keys of the sorted graph
    """
    graph_sorted = []
    while graph_unsorted:
        acyclic = False
        for node, edges in list(graph_unsorted.items()):
            for edge in edges:
                if edge in graph_unsorted:
                    break
            else:
                acyclic = True
                del graph_unsorted[node]
                graph_sorted.append(node)
        if not acyclic:
            raise RuntimeError('A cyclic dependency occurred')
    return graph_sorted


@classmethod
def parse(cls, buff, byteorder='big'):
    """Parse data from a file-like object and return a tag instance."""


def is_repeating(sequence, period):
    """Returns true if the elements in the sequence repeat with the given
    period.

    Parameters
    ----------
    sequence : sequence
        The sequence of elements to check.

    period : int
        The period over which the elements should repeat.
    """
    seq_len = len(sequence)
    if period <= 1 or period >= seq_len:
        raise ValueError(
            'The period must be greater than one and less than the length of the sequence'
            )
    if seq_len % period != 0:
        raise ValueError(
            'The sequence length is not evenly divisible by the period length.'
            )
    for period_idx in range(1, seq_len // period):
        start_idx = period_idx * period
        end_idx = start_idx + period
        if sequence[start_idx:end_idx] != sequence[:period]:
            return False
    return True


@staticmethod
def decode(data):
    """
        Defines the underlying format used during traces or services encoding.
        This method must be implemented and should only be used by the internal functions.
        """
    raise NotImplementedError


def hostside(func):
    """
    Used as a hint that the callback only performs actions on the
    host and does not rely on an active connection to the target.
    This means the callback will be invoked even if the target is
    thought to be unresponsive.

    """
    func.is_hostside = True
    return func


def update_tr_radius(Delta, actual_reduction, predicted_reduction,
    step_norm, bound_hit):
    """Update the radius of a trust region based on the cost reduction.

    Returns
    -------
    Delta : float
        New radius.
    ratio : float
        Ratio between actual and predicted reductions. Zero if predicted
        reduction is zero.
    """
    if predicted_reduction > 0:
        ratio = actual_reduction / predicted_reduction
    else:
        ratio = 0
    if ratio < 0.25:
        Delta = 0.25 * step_norm
    elif ratio > 0.75 and bound_hit:
        Delta *= 2.0
    return Delta, ratio


@staticmethod
def gen_mutation_api_str(case_id: str, output_file: str) ->str:
    """
        Copied the string from the TCGA website and updated the case_id
        See simple somatic mutations
        https://docs.gdc.cancer.gov/API/Users_Guide/Data_Analysis/#simple-somatic-mutation-endpoint-examples
        Parameters
        ----------
        case_id
        output_file

        Returns
        -------

        """
    return (
        f'curl "https://api.gdc.cancer.gov/ssm_occurrences?format=tsv&fields=ssm.ssm_id,ssm.genomic_dna_change,ssm.mutation_subtype,ssm.consequence.transcript.gene.gene_id,ssm.consequence.transcript.gene.symbol,ssm.consequence.transcript.aa_change,ssm.consequence.transcript.consequence_type&size=5000&filters=%7B%0D%0A%22op%22%3A%22in%22%2C%0D%0A%22content%22%3A%7B%0D%0A%22field%22%3A%22case.submitter_id%22%2C%0D%0A%22value%22%3A%5B%0D%0A%22{case_id}%22%0D%0A%5D%0D%0A%7D%0D%0A%7D" > {output_file}'
        )


def get_sign(x):
    """Get the sign of a number."""
    if x > 0:
        return 1
    if x == 0:
        return 0
    assert x < 0
    return -1


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


def td(content=False, color=False, span=False):
    """
    *Generate a table data cell - TBS style*

    **Key Arguments:**
        - ``content`` -- the content
        - ``color`` -- [ sucess | error | warning | info ]

    **Return:**
        - ``td`` -- the table data cell
    """
    if color is False:
        color = ''
    if content is False:
        content = ''
    if span is False:
        span = ''
    else:
        span = 'span%(span)s' % locals()
    td = '%(content)s	' % locals()
    return td


@classmethod
def initialize_options(cls):
    """ Stores options from the config file

        """
    cls.CONFIG_OPTIONS = cls.CFG.get(cls.CONFIG_PATH, return_type=dict)


def generateRequirementsTxt(packages):
    """
        generateRequirementsTxt - Generates a requirements.txt suitable for pip to ingest based on packages param.

            @param packages - Describes the required packages. Takes one of the following forms:

                String - Directly becomes contents of requirements.txt file to be ingested by pip
                List   - A list/tuple/set of package names (optionally including version requirements, e.x. MyPkg==1.2.3)
                Dict   - A dictionary of package names to versions. If no value is present, the latest will be fetched.

            @return <str> - generated requirements.txt file contents
    """
    if not packages:
        reqContents = ''
    elif isinstance(packages, (list, tuple, set)):
        reqContents = '\n'.join(packages)
    elif isinstance(packages, dict):
        reqContents = []
        for name, value in packages.items():
            if not name:
                raise ValueError('Missing name in packages dictionary.')
            if value:
                reqContents.append('%s==%s' % (str(name), str(value)))
            else:
                reqContents.append('%s' % (str(name),))
        reqContents = '\n'.join(reqContents)
    else:
        reqContents = packages
    return reqContents


def setDebugCore(on=True):
    """Function for establising __DEBUG_CORE_FLAG__ to True/False

    Keyword Arguments:
        on {boolean} -- Set's True or False the Debug messages for Core Logger calls (default: {True})
    """
    global __DEBUG_CORE_FLAG__
    __DEBUG_CORE_FLAG__ = on


def add(item):
    """Add the given item to this container.
        """


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


def isfinite(ctx, x):
    """
        Return *True* if *x* is a finite number, i.e. neither
        an infinity or a NaN.

            >>> from mpmath import *
            >>> isfinite(inf)
            False
            >>> isfinite(-inf)
            False
            >>> isfinite(3)
            True
            >>> isfinite(nan)
            False
            >>> isfinite(3+4j)
            True
            >>> isfinite(mpc(3,inf))
            False
            >>> isfinite(mpc(nan,3))
            False

        """
    if ctx.isinf(x) or ctx.isnan(x):
        return False
    return True


def distance(p1, p2):
    """
    Computes the distance between two positions.

    @param      p1      position 1
    @param      p2      position 2
    @return             distance
    """
    return ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5


def getQualifiedRelations():
    """Return a sequence of Relation IDublinCoreElementItem.
        """


def get_indent(line):
    """
    Given a line, returns the whitespace that the line was indented with.
    """
    return line[:-len(line.lstrip())]


def available_bert_model():
    """
    List available bert models.
    """
    return ['multilanguage', 'base', 'small']


def write_headers_titlecase(headers, write):
    """Monkey-patch h11 header handling.

    See https://github.com/python-hyper/h11/issues/31 for the details. Essentially SkyQ box is
    not RFC compliant as regards case-insensitive headers, so this patch forces the headers to
    comply with SkyQ's braindead implementation.
    """
    for name, value in headers:
        if name == b'host':
            write(b'%s: %s\r\n' % (name.title(), value))
    for name, value in headers:
        if name == b'upgrade':
            write(b'%s: %s\r\n' % (name.title(), value.lower()))
        elif name != b'host':
            write(b'%s: %s\r\n' % (name.title(), value))
    write(b'\r\n')


def sign(x):
    """Returns 1 if x is positive, 0 if x is 0, and -1 otherwise"""
    retVal = 0
    if x > 0:
        retVal = 1
    elif x < 0:
        retVal = -1
    return retVal


def _make_version(major, minor, micro, releaselevel, serial):
    """Create a readable version string from version_info tuple components."""
    assert releaselevel in ['alpha', 'beta', 'candidate', 'final']
    version = '%d.%d' % (major, minor)
    if micro:
        version += '.%d' % (micro,)
    if releaselevel != 'final':
        short = {'alpha': 'a', 'beta': 'b', 'candidate': 'rc'}[releaselevel]
        version += '%s%d' % (short, serial)
    return version


def _noop(*args, **kwargs):
    """ Used for ignoring signals.
    """
    pass


def replace():
    """Replace text with the specified text

    """
    pass


def linear_map(src_value, src_domain, dst_range):
    """Maps source value (src_value) in the source domain
    (source_domain) onto the destination range (dest_range) using linear
    interpretation.

    Except that at the moment src_value is a bytes value that once converted
    to integer that it then is on the src_domain.

    Ideally would like to move the conversion from bytes to int externally.

    Once value is same base and format as src_domain (i.e. converted from bytes),
    it should always fall within the src_domain. If not, that's a problem.
    """
    src_min, src_max, dst_min, dst_max = src_domain + dst_range
    if not src_min <= src_value <= src_max:
        raise ValueError
    slope = (dst_max - dst_min) / (src_max - src_min)
    dst_value = slope * (src_value - src_min) + dst_min
    if not dst_min <= dst_value <= dst_max:
        raise ValueError
    return dst_value


@classmethod
def _from_dict(cls, _dict):
    """Initialize a NluEnrichmentRelations object from a json dictionary."""
    args = {}
    if 'model' in _dict:
        args['model'] = _dict.get('model')
    return cls(**args)


def dict_replace(subject_dict, string):
    """
    Replace a dict map, key to its value in the stirng
    :param subject_dict: dict
    :param string: string
    :return: string
    """
    for i, j in subject_dict.items():
        string = string.replace(i, j)
    return string


@classmethod
def from_swift_resp(cls, sw_resp):
    """
        Create a new S3 response object based on the given Swift response.
        """
    if sw_resp.app_iter:
        body = None
        app_iter = sw_resp.app_iter
    else:
        body = sw_resp.body
        app_iter = None
    resp = cls(status=sw_resp.status, headers=sw_resp.headers, request=
        sw_resp.request, body=body, app_iter=app_iter, conditional_response
        =sw_resp.conditional_response)
    resp.environ.update(sw_resp.environ)
    return resp


def mac_str_2_int(mac):
    """Convert colon separated hex string MAC address to integer.

    Args:
        mac (str): A colon separated hex string MAC address.

    Returns:
        MAC address as integer.

    """
    return int(mac.replace(':', ''), 16)


@classmethod
def encode(cls, entry):
    """
        Classmethod that applies conditional encoding based on
        mime-type. Given an entry as returned by __call__ return the
        data in the appropriate encoding.
        """
    data, info = entry
    if info['mime_type'] in cls.utf8_mime_types:
        return data.encode('utf-8')
    else:
        return data


def unique(l):
    """Filters duplicates of iterable.

    Create a new list from l with duplicate entries removed,
    while preserving the original order.

    Parameters
    ----------
    l : iterable
        Input iterable to filter of duplicates.

    Returns
    -------
    list
        A list of elements of `l` without duplicates and in the same order.
    """
    new_list = []
    seen = set()
    for el in l:
        if el not in seen:
            new_list.append(el)
            seen.add(el)
    return new_list


def add(item, **values):
    """
        adds item to pending list marked with **values
        """


def set_backend(backend):
    """Method for setting the backend.

    Returns
    -------
    str
        The new backend as a string
    """
    global _BACKEND
    _BACKEND = str(backend)


def _parse_label(label):
    """Produce a milestone/compose/respin tuple from a compose label."""
    milestone, comp = label.split('-')
    compose, respin = comp.split('.')
    return milestone, compose, int(respin)


def bbox_union(bbox_a, bbox_b):
    """ realize union between to given bbox"""
    x_min_a, y_min_a, x_max_a, y_max_a = bbox_a
    x_min_b, y_min_b, x_max_b, y_max_b = bbox_b
    return min(x_min_a, x_min_b), min(y_min_a, y_min_b), max(x_max_a, x_max_b
        ), max(y_max_a, y_max_b)


@classmethod
def _get_serializable_model(cls):
    """
        Returns a model with a valid _meta.local_fields (serializable).

        Basically, this means the original model, not a proxied model.

        (this is a workaround for a bug in django)
        """
    current_class = cls
    while current_class._meta.proxy:
        current_class = current_class._meta.proxy_for_model
    return current_class


def get_id_from_tag(tag: str=None) ->str:
    """
    Returns the ID number from a given MangaDex tag.

    Parameters:
        t (str): MangaDex title tag

    Returns:
        str: MangaDex title ID number
    """
    if tag is None or not tag.lower().startswith('mangadex:'):
        return ''
    return tag[len('MangaDex:'):]


@classmethod
def SetVar(cls, name, value):
    """ set static value
        :param name: glob parameter name
        :param value: parameter value
        """
    cls.glob.update({name: value})


def isoformat(dt):
    """Return iso-formatted timestamp

    Like .isoformat(), but uses Z for UTC instead of +00:00
    """
    return dt.isoformat().replace('+00:00', 'Z')


def remove(s, i):
    """
    Quick trick to remove an item from a numpy array without
    creating a new object.  Rather than the array shape changing,
    the final value just gets repeated to fill the space.

    ~3.5x faster than numpy.delete
    """
    s[i:-1] = s[i + 1:]


def _maybe_get(elt, item, info, conversion=None):
    """Extract and convert info if item is present."""
    maybe_item = elt.find(item)
    if maybe_item is not None:
        maybe_item = maybe_item.get(info)
        if conversion is not None:
            maybe_item = conversion(maybe_item)
    return maybe_item


def get_ver():
    """
    Gather the version number from git
    """
    import subprocess
    proc = subprocess.Popen(['git', 'describe'], stdout=subprocess.PIPE)
    if proc.wait():
        return
    v = proc.stdout.read().decode().strip()
    if '-' not in v:
        ret = v
    else:
        csum = v[v.rindex('-') + 1:]
        base = v[:v.rindex('-')]
        count = base[base.rindex('-') + 1:]
        tag = base[:base.rindex('-')]
        ret = f'{tag}.post{count}+{csum}'
    return ret


@classmethod
def interval(cls, frame, start, end, interval=1, tz=None, bounds='[)'):
    """ Returns an iterator of tuples, each :class:`Arrow <arrow.arrow.Arrow>` objects,
        representing a series of intervals between two inputs.

        :param frame: The timeframe.  Can be any ``datetime`` property (day, hour, minute...).
        :param start: A datetime expression, the start of the range.
        :param end: (optional) A datetime expression, the end of the range.
        :param interval: (optional) Time interval for the given time frame.
        :param tz: (optional) A timezone expression.  Defaults to UTC.
        :param bounds: (optional) a ``str`` of either '()', '(]', '[)', or '[]' that specifies
            whether to include or exclude the start and end values in the intervals. '(' excludes
            the start, '[' includes the start, ')' excludes the end, and ']' includes the end.
            If the bounds are not specified, the default bound '[)' is used.

        Supported frame values: year, quarter, month, week, day, hour, minute, second

        Recognized datetime expressions:

            - An :class:`Arrow <arrow.arrow.Arrow>` object.
            - A ``datetime`` object.

        Recognized timezone expressions:

            - A ``tzinfo`` object.
            - A ``str`` describing a timezone, similar to 'US/Pacific', or 'Europe/Berlin'.
            - A ``str`` in ISO 8601 style, as in '+07:00'.
            - A ``str``, one of the following:  'local', 'utc', 'UTC'.

        Usage:

            >>> start = datetime(2013, 5, 5, 12, 30)
            >>> end = datetime(2013, 5, 5, 17, 15)
            >>> for r in arrow.Arrow.interval('hour', start, end, 2):
            ...     print r
            ...
            (<Arrow [2013-05-05T12:00:00+00:00]>, <Arrow [2013-05-05T13:59:59.999999+00:00]>)
            (<Arrow [2013-05-05T14:00:00+00:00]>, <Arrow [2013-05-05T15:59:59.999999+00:00]>)
            (<Arrow [2013-05-05T16:00:00+00:00]>, <Arrow [2013-05-05T17:59:59.999999+00:0]>)
        """
    if interval < 1:
        raise ValueError('interval has to be a positive integer')
    spanRange = iter(cls.span_range(frame, start, end, tz, bounds=bounds))
    while True:
        try:
            intvlStart, intvlEnd = next(spanRange)
            for _ in range(interval - 1):
                _, intvlEnd = next(spanRange)
            yield intvlStart, intvlEnd
        except StopIteration:
            return


def softsign(data=None, out=None, name=None, **kwargs):
    """Computes softsign of x element-wise.

    .. math::
       y = x / (1 + abs(x))

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

    Defined in src/operator/tensor/elemwise_unary_op_basic.cc:L191

    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 check_brackets(strs):
    """
    check if brackets(and parentheses) come in pairs, besides, left should occur before right.
    :param strs:
    :return: bool
    """
    rights = {')', ']', '}'}
    lefts = {'(': ')', '[': ']', '{': '}'}
    l = []
    for i, c in enumerate(strs):
        if c in lefts:
            l.append((i, c))
        elif c in rights:
            if len(l) == 0:
                print("redundant '{}' at position {}".format(c, i))
                return False
            i0, c0 = l.pop()
            if lefts[c0] != c:
                print("unmatched '{}' at position {} with '{}' at position {}"
                    .format(c0, i0, c, i))
                return False
    if len(l) > 0:
        print('redundant parentheses and their positions: {}'.format(l))
        return False
    return True


def print_rehearsal_header():
    """
    Prints the header for the rehearsal phase of a benchmark.
    """
    print
    print('Rehearsal -------------------------------------------------')


def _get_lock_name(obj):
    """
    Gets a lock name for the object.

    :param django.db.models.Model obj: the object for which we want the lock

    :returns: a name for this object
    :rtype: :class:`str`
    """
    return '%s.%s__%d' % (obj.__module__, obj.__class__.__name__, obj.id)


def order_flag_options(key, value):
    """Return the options key value pairs in the correct order (bit (int), name (str)).

    Args:
        key (int/str): Bit int or name.
        value (str/int): Name or bit int.

    Returns:
        option (tuple): (bit (int), name (str))
    """
    if isinstance(key, int):
        bit = key
        name = str(value)
    else:
        bit = int(value)
        name = str(key)
    return bit, name


def nl_list_del(obj):
    """https://github.com/thom311/libnl/blob/libnl3_2_25/include/netlink/list.h#L49

    Positional arguments:
    obj -- nl_list_head class instance.
    """
    obj.next.prev = obj.prev
    obj.prev.next_ = obj.next_


def find(path):
    """Returns the entry for a path in the manifest.

        Returns a 2-tuple of (node, flags).

        Raises ``KeyError`` if the path does not exist in the manifest.
        """


def connection_weight(line, func):
    """
    Return the weight of the connection *line* according to weight function
    *func*.

    If *func* is None, the weight is set equal to the connection length.

    Parameters
    ----------
    line: LineString
        Geometry of the connection.
    func: function
        Function of the connection length returning its weight.

    Returns
    -------
    float
        Weight of the connection.
    """
    if func is None:
        weight = line.length
    else:
        weight = func(line.length)
    return weight


def save_csv(path, df):
    """ Save dataframe as csv """
    df.to_csv(str(path), index=False)


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

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

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


def plot_digraph(graph, axes=None, r_node=None):
    """
    Returns a DiGraph object to a set of matplotlib axes.

    Returns a matplotlib axes object.
    """
    import matplotlib.pyplot as plt
    import matplotlib.lines as lines
    import matplotlib.patches as patches
    limits = [None, None, None, None]
    ax = axes if axes is not None else plt.gca()
    ax.set_frame_on(False)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    xmin = ymin = 1
    xmax = ymax = 0
    if r_node is None:
        w = 0.85 / len(graph)
    else:
        w = r_node
    fArrow = 0.8
    for node in graph:
        for mode in node.edgo:
            x1, y1, x2, y2 = node.x, node.y, mode.x, mode.y
            line = lines.Line2D((x1, x2), (y1, y2), lw=2, color=(0, 0, 0),
                alpha=0.5, zorder=0)
            ax.add_line(line)
            ax.add_patch(patches.FancyArrowPatch((x1, y1), (x1 + fArrow * (
                x2 - x1), y1 + fArrow * (y2 - y1)), arrowstyle='->',
                mutation_scale=60, color=(0, 0, 0), alpha=0.5, zorder=0))
        xmin = min(xmin, node.x)
        xmax = max(xmax, node.x)
        ymin = min(ymin, node.y)
        ymax = max(ymax, node.y)
    p = 0.8
    if limits[0] is None:
        limits[0] = xmin - p * w
    if limits[1] is None:
        limits[1] = xmax + p * w
    if limits[2] is None:
        limits[2] = ymin - p * w
    if limits[3] is None:
        limits[3] = ymax + p * w
    ax.set_xlim(limits[0], limits[1])
    ax.set_ylim(limits[2], limits[3])
    for node in graph:
        e = patches.Ellipse(xy=(node.x, node.y), width=w, height=w, angle=0,
            zorder=1)
        e.set_clip_box(ax.bbox)
        e.set_alpha(node.rgba[3])
        e.set_facecolor(node.rgba[0:3])
        ax.add_artist(e)
        if node.label is not None:
            ax.text(node.x, node.y, node.label, horizontalalignment=
                'center', zorder=2)
    return ax


def type_object_attrgetter(obj, attr, *defargs):
    """
    This implements an improved attrgetter for type objects (i.e. classes)
    that can handle class attributes that are implemented as properties on
    a metaclass.

    Normally `getattr` on a class with a `property` (say, "foo"), would return
    the `property` object itself.  However, if the class has a metaclass which
    *also* defines a `property` named "foo", ``getattr(cls, 'foo')`` will find
    the "foo" property on the metaclass and resolve it.  For the purposes of
    autodoc we just want to document the "foo" property defined on the class,
    not on the metaclass.

    For example::

        >>> class Meta(type):
        ...     @property
        ...     def foo(cls):
        ...         return 'foo'
        ...
        >>> class MyClass(metaclass=Meta):
        ...     @property
        ...     def foo(self):
        ...         ""\"Docstring for MyClass.foo property.""\"
        ...         return 'myfoo'
        ...
        >>> getattr(MyClass, 'foo')
        'foo'
        >>> type_object_attrgetter(MyClass, 'foo')
        <property at 0x...>
        >>> type_object_attrgetter(MyClass, 'foo').__doc__
        'Docstring for MyClass.foo property.'

    The last line of the example shows the desired behavior for the purposes
    of autodoc.
    """
    for base in obj.__mro__:
        if attr in base.__dict__:
            if isinstance(base.__dict__[attr], property):
                return base.__dict__[attr]
            break
    return getattr(obj, attr, *defargs)


def decode_name(nbname):
    """Return the NetBIOS first-level decoded nbname."""
    if len(nbname) != 32:
        return nbname
    l = []
    for i in range(0, 32, 2):
        l.append(chr(ord(nbname[i]) - 65 << 4 | ord(nbname[i + 1]) - 65 & 15))
    return ''.join(l).split('\x00', 1)[0]


def retain(data=None, indices=None, name=None, attr=None, out=None, **kwargs):
    """Pick rows specified by user input index array from a row sparse matrix
    and save them in the output sparse matrix.

    Example::

      data = [[1, 2], [3, 4], [5, 6]]
      indices = [0, 1, 3]
      shape = (4, 2)
      rsp_in = row_sparse_array(data, indices)
      to_retain = [0, 3]
      rsp_out = retain(rsp_in, to_retain)
      rsp_out.data = [[1, 2], [5, 6]]
      rsp_out.indices = [0, 3]

    The storage type of ``retain`` output depends on storage types of inputs

    - retain(row_sparse, default) = row_sparse
    - otherwise, ``retain`` is not supported

    Defined in src/operator/tensor/sparse_retain.cc:L53

    Parameters
    ----------
    data : Symbol
        The input array for sparse_retain operator.
    indices : Symbol
        The index array of rows ids that will be retained.

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

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


def __len__(cls):
    """Expose how many config items we have."""
    return len(cls.config_data)


def _remove_reserved_attributes(attributes):
    """
    Removes elog reserved attributes (from the attributes dict) that can not be sent.

    :param attributes: dictionary of attributes to be cleaned.
    :return:
    """
    if attributes:
        attributes.get('$@MID@$', None)
        attributes.pop('Date', None)
        attributes.pop('Attachment', None)
        attributes.pop('Text', None)


@classmethod
def process_param(cls, param):
    """Process an @param decorator into a ParameterInfo."""
    return None