def cat_acc(y_true, y_pred):
    """Keras loss function for sparse_categorical_accuracy.

    :param y_true: tensor of true class labels.
    :param y_pred: class output scores from network.

    :returns: categorical accuracy.
    """
    from tensorflow.keras import backend as K
    if K.ndim(y_true) == K.ndim(y_pred):
        y_true = K.squeeze(y_true, -1)
    y_pred_labels = K.argmax(y_pred, axis=-1)
    y_pred_labels = K.cast(y_pred_labels, K.floatx())
    return K.cast(K.equal(y_true, y_pred_labels), K.floatx())


def _insert_jinja_configuration(c):
    """Insert the configuration for the sphinx-jinja extension.

    The "default" Jinja context includes all variables in the conf.py
    configuration namespace.
    """
    c['jinja_contexts'] = {'default': c}
    return c


def __init_subclass__(cls, **kwargs):
    """ register all subclassess to reconstruct them later """
    super().__init_subclass__(**kwargs)
    cls._subclasses[cls.__name__] = cls


def check_url(name):
    """Returns true if the name looks like a URL"""
    if ':' not in name:
        return False
    scheme = name.split(':', 1)[0].lower()
    return scheme in ['http', 'https', 'file', 'ftp']


def power(base, exp):
    """Returns element-wise result of base element raised to powers from exp element.

    Both inputs can be Symbol or scalar number.
    Broadcasting is not supported. Use `broadcast_pow` instead.

    Parameters
    ---------
    base : Symbol or scalar
        The base symbol
    exp : Symbol or scalar
        The exponent symbol

    Returns
    -------
    Symbol or scalar
        The bases in x raised to the exponents in y.

    Examples
    --------
    >>> mx.sym.power(2, 3)
    8
    >>> x = mx.sym.Variable('x')
    >>> y = mx.sym.Variable('y')
    >>> z = mx.sym.power(x, 2)
    >>> z.eval(x=mx.nd.array([1,2]))[0].asnumpy()
    array([ 1.,  4.], dtype=float32)
    >>> z = mx.sym.power(3, y)
    >>> z.eval(y=mx.nd.array([2,3]))[0].asnumpy()
    array([  9.,  27.], dtype=float32)
    >>> z = mx.sym.power(x, y)
    >>> z.eval(x=mx.nd.array([3,4]), y=mx.nd.array([2,3]))[0].asnumpy()
    array([  9.,  64.], dtype=float32)
    """
    return pow(base, exp)


def getSample(resultFilename):
    """Return the samplename based off a result filename."""
    return resultFilename.split('/')[-1].split('.')[0]


def retry_timeout_scale(total_retries: int, remaining: int, scale: float=0.3
    ) ->float:
    """
    Calculate an exponential retry timeout based on the max and remaining number of retries

    :param total_retries: total number of retries allowed
    :param remaining: number of retries remaining
    :param scale: optional scale for exponential, defaults to 0.3
    :return: retry timeout in seconds
    """
    return 2 ** ((total_retries - remaining) * scale)


@classmethod
def supports_replay_gain(cls):
    """returns True if this class supports ReplayGain"""
    return True


@staticmethod
def _get_name_from_dn(dn):
    """
        Get the instance name from the dn

        :param dn: string containing the distinguished name URL
        :return: string containing the name
        """
    name = dn.split('/lnkcnt-')[1].split('/')[0]
    return name


def get_object_information(DirectoryArn=None, ObjectReference=None,
    ConsistencyLevel=None):
    """
    Retrieves metadata about an object.
    See also: AWS API Documentation

    :example: response = client.get_object_information(
        DirectoryArn='string',
        ObjectReference={
            'Selector': 'string'
        },
        ConsistencyLevel='SERIALIZABLE'|'EVENTUAL'
    )

    :type DirectoryArn: string
    :param DirectoryArn: [REQUIRED]
            The ARN of the directory being retrieved.

    :type ObjectReference: dict
    :param ObjectReference: [REQUIRED]
            A reference to the object.
            Selector (string) --A path selector supports easy selection of an object by the parent/child links leading to it from the directory root. Use the link names from each parent/child link to construct the path. Path selectors start with a slash (/) and link names are separated by slashes. For more information about paths, see Accessing Objects . You can identify an object in one of the following ways:
            $ObjectIdentifier - An object identifier is an opaque string provided by Amazon Cloud Directory. When creating objects, the system will provide you with the identifier of the created object. An object s identifier is immutable and no two objects will ever share the same object identifier
            /some/path - Identifies the object based on path
            #SomeBatchReference - Identifies the object in a batch call

    :type ConsistencyLevel: string
    :param ConsistencyLevel: The consistency level at which to retrieve the object information.

    :rtype: dict
    :return: {
        'SchemaFacets': [
            {
                'SchemaArn': 'string',
                'FacetName': 'string'
            },
        ],
        'ObjectIdentifier': 'string'
    }

    """
    pass


def is_tel_link(href=None):
    """Utility function to determine whether the supplied href
    attribute is a telephone link."""
    print('is_tel_link()')
    return href and 'tel:' in href


def test_7z(archive, compression, cmd, verbosity, interactive):
    """Test a 7z archive."""
    cmdlist = [cmd, 't']
    if not interactive:
        cmdlist.append('-y')
    cmdlist.extend(['--', archive])
    return cmdlist


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

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


def name_from_object(obj):
    """
  This function returns the name of the object
  from its initialized instance.

  Arguments
  ---------
  obj : any
        The object whose name needs to be returned.

  Returns
  -------
  name : str
         The name of the object
  """
    cls_str = str(obj.__class__) if str(obj.__class__) != str(type) else str(
        obj)
    return cls_str[1:-2].split('.')[-1].lower()


def fastdelta(base, changes):
    """Obtain a delta between this manifest and another given changes.

        ``base`` in the raw data representation for another manifest.

        ``changes`` is an iterable of ``(path, to_delete)``.

        Returns a 2-tuple containing ``bytearray(self.text())`` and the
        delta between ``base`` and this manifest.

        If this manifest implementation can't support ``fastdelta()``,
        raise ``mercurial.manifest.FastdeltaUnavailable``.
        """


def get_xsteps(size, min_x, plot_cores, xtick_step):
    """Return the step size needed for a reasonable xtick spacing.

    Default step size is 1. If benchmarks>=18 are plotted, the step size is
    increased to 2. If we are plotting the number of cores, we increase the
    step size to 3, if the number of benchmarks>10 or the number of
    cores/node>=100.

    The user setting `xtick_step` overrides all previous settings.
    """
    step = 1
    if size >= 18:
        step = 2
    if plot_cores and (size > 10 or min_x >= 100):
        step = 3
    if xtick_step:
        step = xtick_step
    return step


@classmethod
def from_api_repr(cls, resource, zone):
    """Factory:  construct a change set given its API representation

        :type resource: dict
        :param resource: change set representation returned from the API

        :type zone: :class:`gcloud.dns.zone.ManagedZone`
        :param zone: A zone which holds zero or more change sets.

        :rtype: :class:`gcloud.dns.changes.Changes`
        :returns: RRS parsed from ``resource``.
        """
    changes = cls(zone=zone)
    changes._set_properties(resource)
    return changes


def is_comment(txt):
    """
    This does not validate chars,    basically because it allows `quoted-pair`,    meaning it allows all valid chars    (``HTAB / SP / VCHAR``)

    :param txt:
    :return:
    """
    assert isinstance(txt, str)
    if not txt.startswith('(') and not txt.endswith(')'):
        return False
    return True


def __contains__(object):
    """Answer whether the given persistent object is found in the ring.

        Must not rely on object equality or object hashing, but only
        identity or the `_p_oid`. Should be constant time.
        """


def _cast_make_object(canidate_class, cpp_object, is_class):
    """Make an object for cast"""
    if is_class:
        return canidate_class
    elif hasattr(canidate_class, '_convert_cpp'):
        return canidate_class._convert_cpp(cpp_object)
    else:
        return canidate_class(cpp_object)


def gen_float_list_string(vals, mesg='', nchar=0, left=False):
    """mesg is printed first, if nchar>0, it is min char width"""
    istr = mesg
    if left:
        format = '%-'
    else:
        format = '%'
    if nchar > 0:
        format += '*g '
        for val in vals:
            istr += format % (nchar, val)
    else:
        format += 'g '
        for val in vals:
            istr += format % val
    return istr


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


@staticmethod
def state_default(value):
    """Any unparsed state."""
    yield ''


def __ge__(a, b):
    """ Test if Va >= Vb """
    return int(a) >= int(b)


def cal_higher_mode_factor(n_storeys, btype='frame'):
    """
    Calculates the higher mode factor according to DDBD12 CL.
    :param n_storeys:
    :param btype:
    :return:
    """
    if btype == 'frame':
        if n_storeys < 6:
            factor = 1.0
        elif n_storeys <= 16:
            factor = 1.0 - 0.15 * float(n_storeys - 6.0) / (16.0 - 6.0)
        else:
            factor = 0.85
    elif n_storeys < 10:
        factor = 1.0
    elif n_storeys <= 16:
        factor = 1.0 - 0.06 * float(n_storeys - 10.0) / (16.0 - 10.0)
    else:
        factor = 0.85
    return factor


def get_plotdat_dict(ax):
    """ sets internal property to a matplotlib axis """
    if '_plotdat' not in ax.__dict__:
        ax.__dict__['_plotdat'] = {}
    plotdat_dict = ax.__dict__['_plotdat']
    return plotdat_dict


@staticmethod
def _resolve_param_duplicates(values, param_defn, _in):
    """ Resolve cases where query parameters are provided multiple times.
            The default behavior is to use the first-defined value.
            For example, if the query string is '?a=1,2,3&a=4,5,6' the value of
            `a` would be "4,5,6".
            However, if 'collectionFormat' is 'multi' then the duplicate values
            are concatenated together and `a` would be "1,2,3,4,5,6".
        """
    if param_defn.get('collectionFormat') == 'multi':
        return ','.join(values)
    return values[-1]


def _check_dsmc_output(output, check_attrs, exact_match=True):
    """Check dsmc command line utility output.

    Parse the output of the dsmc command and make sure that a given
    attribute is present, and that it has the proper value.
    TSM attribute has the format of "text : value".

    :param output: TSM output to parse
    :param check_attrs: text to identify in the output
    :param exact_match: if True, the check will pass only if the parsed
    value is equal to the value specified in check_attrs.  If false, the
    check will pass if the parsed value is greater than or equal to the
    value specified in check_attrs.  This is needed because for file
    backups, the parent directories may also be included the first a
    volume is backed up.
    :returns: bool -- indicate if requited output attribute found in output
    """
    parsed_attrs = {}
    for line in output.split('\n'):
        key, sep, val = line.partition(':')
        if sep is not None and key is not None and len(val.strip()) > 0:
            parsed_attrs[key] = val.strip()
    for ckey, cval in check_attrs.items():
        if ckey not in parsed_attrs:
            return False
        elif exact_match and parsed_attrs[ckey] != cval:
            return False
        elif not exact_match and int(parsed_attrs[ckey]) < int(cval):
            return False
    return True


def _auto_correlations(n_states):
    """Returns list of autocorrelations

    Args:
        n_states: number of local states

    Returns:
        list of tuples for autocorrelations

    >>> l = _auto_correlations(np.arange(3))
    >>> assert l == ((0, 1, 2), (0, 1, 2))
    """
    return tuple(n_states), tuple(n_states)


def add_wedge_spacing(df, spacing):
    """Add spacing to the `inners` column of the provided data based on level."""
    if isinstance(spacing, list):
        for i, space in enumerate(spacing):
            df.ix[df['level'] == i, 'inners'] += space
    else:
        df.ix[df['level'] > 0, 'inners'] += spacing


def default(inst):
    """Default routine to be applied when loading data.

    Parameters
    -----------
    inst : (pysat.Instrument)
        Instrument class object

    Note
    ----
        Removes ICON preamble on variable names.

    """
    import pysat.instruments.icon_ivm as icivm
    inst.tag = 'level_2'
    icivm.remove_icon_names(inst, target='ICON_L2_FUV_Daytime_ON2_')


def surface_interaction(phi, x, Psurf):
    """
    density that should be moved to surface
    """
    for ii in range(len(x))[:len(x) - 1]:
        for jj in range(len(x))[:len(x) - 1 - ii]:
            for kk in range(len(x))[:len(x) - 1 - ii - jj]:
                if ii == 0 and jj == 0:
                    continue
                if ii == 0 and kk == 0:
                    continue
                if jj == 0 and kk == 0:
                    continue
                if ii == 0:
                    amnt = Psurf[ii, jj, kk]
                    dist = (len(x) - 1 - (jj + kk)) // 2
                    rmdr = (len(x) - 1 - (jj + kk)) % 2
                    if rmdr == 0:
                        phi[ii, jj + dist, kk + dist] += amnt * phi[ii, jj, kk
                            ] * 2
                        phi[ii, jj, kk] *= 1 - amnt
                    elif rmdr == 1:
                        phi[ii, jj + dist + 1, kk + dist] += amnt * phi[ii,
                            jj, kk] * 2 / 2.0
                        phi[ii, jj + dist, kk + dist + 1] += amnt * phi[ii,
                            jj, kk] * 2 / 2.0
                        phi[ii, jj, kk] *= 1 - amnt
                elif jj == 0:
                    amnt = Psurf[ii, jj, kk]
                    dist = (len(x) - 1 - (ii + kk)) // 2
                    rmdr = (len(x) - 1 - (ii + kk)) % 2
                    if rmdr == 0:
                        phi[ii + dist, jj, kk + dist] += amnt * phi[ii, jj, kk
                            ] * 2
                        phi[ii, jj, kk] *= 1 - amnt
                    elif rmdr == 1:
                        phi[ii + dist + 1, jj, kk + dist] += amnt * phi[ii,
                            jj, kk] * 2 / 2.0
                        phi[ii + dist, jj, kk + dist + 1] += amnt * phi[ii,
                            jj, kk] * 2 / 2.0
                        phi[ii, jj, kk] *= 1 - amnt
                elif kk == 0:
                    amnt = Psurf[ii, jj, kk]
                    dist = (len(x) - 1 - (ii + jj)) // 2
                    rmdr = (len(x) - 1 - (ii + jj)) % 2
                    if rmdr == 0:
                        phi[ii + dist, jj + dist, kk] += amnt * phi[ii, jj, kk
                            ] * 2
                        phi[ii, jj, kk] *= 1 - amnt
                    elif rmdr == 1:
                        phi[ii + dist + 1, jj + dist, kk] += amnt * phi[ii,
                            jj, kk] * 2 / 2.0
                        phi[ii + dist, jj + dist + 1, kk] += amnt * phi[ii,
                            jj, kk] * 2 / 2.0
                        phi[ii, jj, kk] *= 1 - amnt
                else:
                    amnt = Psurf[ii, jj, kk]
                    dist = (len(x) - 1 - (ii + jj + kk)) // 3
                    rmdr = (len(x) - 1 - (ii + jj + kk)) % 3
                    if rmdr == 0:
                        phi[ii + dist, jj + dist, kk + dist] += amnt * phi[
                            ii, jj, kk] * 2
                        phi[ii, jj, kk] *= 1 - amnt
                    elif rmdr == 1:
                        phi[ii + dist + 1, jj + dist, kk + dist] += amnt * phi[
                            ii, jj, kk] * 2 / 3.0
                        phi[ii + dist, jj + dist + 1, kk + dist] += amnt * phi[
                            ii, jj, kk] * 2 / 3.0
                        phi[ii + dist, jj + dist, kk + dist + 1] += amnt * phi[
                            ii, jj, kk] * 2 / 3.0
                        phi[ii, jj, kk] *= 1 - amnt
                    elif rmdr == 2:
                        phi[ii + dist + 1, jj + dist + 1, kk + dist
                            ] += amnt * phi[ii, jj, kk] * 2 / 3.0
                        phi[ii + dist + 1, jj + dist, kk + dist + 1
                            ] += amnt * phi[ii, jj, kk] * 2 / 3.0
                        phi[ii + dist, jj + dist + 1, kk + dist + 1
                            ] += amnt * phi[ii, jj, kk] * 2 / 3.0
                        phi[ii, jj, kk] *= 1 - amnt
    return phi


def list_volume_recovery_points(GatewayARN=None):
    """
    Lists the recovery points for a specified gateway. This operation is only supported in the cached volume gateway architecture.
    Each cache volume has one recovery point. A volume recovery point is a point in time at which all data of the volume is consistent and from which you can create a snapshot or clone a new cached volume from a source volume. To create a snapshot from a volume recovery point use the  CreateSnapshotFromVolumeRecoveryPoint operation.
    See also: AWS API Documentation

    Examples
    Lists the recovery points for a specified gateway in which all data of the volume is consistent and can be used to create a snapshot.
    Expected Output:

    :example: response = client.list_volume_recovery_points(
        GatewayARN='string'
    )

    :type GatewayARN: string
    :param GatewayARN: [REQUIRED]
            The Amazon Resource Name (ARN) of the gateway. Use the ListGateways operation to return a list of gateways for your account and region.

    :rtype: dict
    :return: {
        'GatewayARN': 'string',
        'VolumeRecoveryPointInfos': [
            {
                'VolumeARN': 'string',
                'VolumeSizeInBytes': 123,
                'VolumeUsageInBytes': 123,
                'VolumeRecoveryPointTime': 'string'
            },
        ]
    }

    """
    pass


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


def reverse(arr, b):
    """Reverse elements in a list.

    This function is equivalent to:

    .. code-block:: javascript

       function(a, b) { a.reverse() }

    This method takes an unused ``b`` variable as their transform functions
    universally sent two arguments.

    **Example**:

    >>> reverse([1, 2, 3, 4])
    [4, 3, 2, 1]
    """
    return arr[::-1]


@staticmethod
def release_start():
    """
        Releases are automatically started when they are created
        """
    pass


def get_metadata(name):
    """The named metadata resource as a string"""


@staticmethod
def _parse_region(s):
    """
		Parse a string like "name:begin-end" or "name:begin..end".
		The returned tuple is (name, start, stop, revcomp).
		start is begin-1, stop is equal to end.
		That is, this function converts from 1-based intervals to pythonic
		open intervals!

		The string may be prefixed with "rc:", in which case revcomp is set to True.

		If 'end' is an empty string (as in "chrx:1-"), then stop is set to None.
		If no range is given, as in "chrx:27", then stop is set to start+1.
		If only 'name' is given (or "rc:name"), start is set to 0 and stop to None.

		Commas within the numbers (thousands separators) are ignored.
		"""
    revcomp = False
    if s.startswith('rc:'):
        revcomp = True
        s = s[3:]
    fields = s.rsplit(':', 1)
    if len(fields) == 1:
        region = fields[0], 0, None, revcomp
    else:
        if '..' in fields[1]:
            sep = '..'
        else:
            sep = '-'
        coords = fields[1].split(sep, maxsplit=1)
        start = int(coords[0].replace(',', ''))
        if len(coords) == 1:
            stop = start
        else:
            stop = int(coords[1].replace(',', '')) if coords[1] != '' else None
        assert 0 < start and (stop is None or start <= stop)
        region = fields[0], start - 1, stop, revcomp
    return region


def _windows_get_covered_types(windows):
    """
    Gets list of types covered by an NSECx windows list.

    :param list windows: An NSEC or NSEC3 windows list.
    :return: List of dns.rdatatype's that the NSECx covers.
    """
    types = []
    for win in windows:
        window = win[0]
        bitmap = win[1]
        if bitmap:
            for byte in range(len(bitmap)):
                bits = bitmap[byte]
                if bits:
                    for bit in range(8):
                        if bits & 128 >> bit:
                            types.append(window * 256 + byte * 8 + bit)
    return types


def p_expression_list_expr(p):
    """expression_list : expression_list expression"""
    p[0] = p[1] + p[2]


def message_list(transport, request, queue_name, callback=None, **kwargs):
    """Gets a list of messages in queue `queue_name`

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    :param queue_name: Queue reference name.
    :type queue_name: `six.text_type`
    :param callback: Optional callable to use as callback.
        If specified, this request will be sent asynchronously.
        (IGNORED UNTIL ASYNC SUPPORT IS COMPLETE)
    :type callback: Callable object.
    :param kwargs: Optional arguments for this operation.
        - marker: Where to start getting messages from.
        - limit: Maximum number of messages to get.
        - echo: Whether to get our own messages.
        - include_claimed: Whether to include claimed
            messages.
    """
    request.operation = 'message_list'
    request.params['queue_name'] = queue_name
    request.params.update(kwargs)
    resp = transport.send(request)
    if not resp.content:
        return {'links': [], 'messages': []}
    return resp.deserialized_content


def _split(f, children):
    """
    Given a function that returns true or false and a list. Return
    a two lists all items f(child) == True is in list 1 and
    all items not in the list are in list 2.

    """
    l1 = []
    l2 = []
    for child in children:
        if f(child):
            l1.append(child)
        else:
            l2.append(child)
    return l1, l2


@staticmethod
def get_help_string(list, delimiter=', '):
    """
        Generates the help string for the command line interface and otherwise
        :param list: the list of algorithm classes
        :param delimiter: a delimiter between 2 list items
        :return:
        """
    list_string = ''
    for position in range(len(list)):
        list_string += str(position) + ' => ' + str(list[position].__name__
            ) + delimiter
    return list_string


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


def sphere(x):
    """Sphere objective function.

    Has a global minimum at :code:`0` and with a search domain of
        :code:`[-inf, inf]`

    Parameters
    ----------
    x : numpy.ndarray
        set of inputs of shape :code:`(n_particles, dimensions)`

    Returns
    -------
    numpy.ndarray
        computed cost of size :code:`(n_particles, )`
    """
    j = (x ** 2.0).sum(axis=1)
    return j


def particle_system_remove():
    """Remove the selected particle system

    """
    pass


def delete_bucket_tagging(Bucket=None):
    """
    Deletes the tags from the bucket.
    See also: AWS API Documentation

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

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

    """
    pass


def _get_extension_resource(api_root):
    """Return the Review Bot extension resource.

    Args:
        api_root (rbtools.api.resource.Resource):
            The server API root.

    Returns:
        rbtools.api.resource.Resource:
        The extension's API resource.
    """
    return api_root.get_extension(extension_name=
        'reviewbotext.extension.ReviewBotExtension')


def info(text: str) ->str:
    """Get text prefixed with an info emoji.

    Returns
    -------
    str
        The new message.

    """
    return 'ℹ {}'.format(text)


@classmethod
def uri_matches(cls, uri):
    """
        override 'uri_matches' to prefer this logger when the server
        version doesn't support $text (MongoDB 2.4 only).
        """
    return super().uri_matches(uri) and cls._is_mongodb_24(uri)


def _any_array_len(any_array):
    """Return the length of an any_array."""
    array_type = any_array.WhichOneof('type')
    the_array = getattr(any_array, array_type).data
    return len(the_array)


@staticmethod
def _get_install_requires_list():
    """
        Returns the list of package names that the install requires

        :return: The list of package names that the install requires
        """
    return []


def _string_from_cmd_list(cmd_list):
    """Takes a list of command line arguments and returns a pretty
    representation for printing."""
    cl = []
    for arg in map(str, cmd_list):
        if ' ' in arg or '\t' in arg:
            arg = '"' + arg + '"'
        cl.append(arg)
    return ' '.join(cl)


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

        :param ShowcaseFileRemovedType val:
        :rtype: EventType
        """
    return cls('showcase_file_removed', val)


def check_termination_protection(module, inst):
    """
    Check the instance disableApiTermination attribute.

    module: Ansible module object
    inst: EC2 instance object

    returns: True if state changed None otherwise
    """
    termination_protection = module.params.get('termination_protection')
    if inst.get_attribute('disableApiTermination')['disableApiTermination'
        ] != termination_protection and termination_protection is not None:
        inst.modify_attribute('disableApiTermination', termination_protection)
        return True


def no_duplicates_constructor(loader, node, deep=False):
    """Check for duplicate keys while loading YAML

    https://gist.github.com/pypt/94d747fe5180851196eb
    """
    mapping = {}
    for key_node, value_node in node.value:
        key = loader.construct_object(key_node, deep=deep)
        value = loader.construct_object(value_node, deep=deep)
        if key in mapping:
            from intake.catalog.exceptions import DuplicateKeyError
            raise DuplicateKeyError('while constructing a mapping', node.
                start_mark, 'found duplicate key (%s)' % key, key_node.
                start_mark)
        mapping[key] = value
    return loader.construct_mapping(node, deep)


def _pathlib_compat(path):
    """
    For path-like objects, convert to a filename for compatibility
    on Python 3.6.1 and earlier.
    """
    try:
        return path.__fspath__()
    except AttributeError:
        return str(path)


@classmethod
def database_connect(cls):
    """
        Make sure database is connected.

        Dont reopen connection.
        """
    if not cls._meta.database.is_closed():
        cls._meta.database.close()
    cls._meta.database.connect()


def get_recurrence():
    """Rethrn the current recurrence setting.
        """


def view_zoom(factor: float=0.0):
    """Zoom in/out the view

    :param factor: Factor, Zoom factor, values higher than 1.0 zoom in, lower values zoom out
    :type factor: float
    """
    pass


def _1_add_profile_uuid(config):
    """
    This adds the required values for a new default profile

        * PROFILE_UUID

    The profile uuid will be used as a general purpose identifier for the profile, in
    for example the RabbitMQ message queues and exchanges.
    """
    for profile in config.get('profiles', {}).values():
        from uuid import uuid4
        profile['PROFILE_UUID'] = uuid4().hex
    return config


def _tex_comment(comment):
    """Prepends each line in string with the LaTeX comment key, '%'.
    """
    return '% ' + str.replace(comment, '\n', '\n% ') + '\n'


@staticmethod
def sanitize_for_api(val):
    """Convert a native value to the expected string format for REST.

        :param val: The native value to convert.
        :return: Sanitized string value suitable for the REST API.
        :raise ValueError: If the string can't be converted.
        """
    return str(val)


def _next_rooted_tree(predecessor, p=None):
    """One iteration of the Beyer-Hedetniemi algorithm."""
    if p is None:
        p = len(predecessor) - 1
        while predecessor[p] == 1:
            p -= 1
    if p == 0:
        return None
    q = p - 1
    while predecessor[q] != predecessor[p] - 1:
        q -= 1
    result = list(predecessor)
    for i in range(p, len(result)):
        result[i] = result[i - p + q]
    return result


def is_four_prices_doji(body, top, bottom):
    """Se existir o doji de quatro preços retorna True."""
    if abs(body) > 0:
        return False
    if top > 0:
        return False
    if bottom > 0:
        return False
    return True


def p_subscription(p):
    """subscription : primary "[" expression "]" """
    p[0] = ['SUBSCRIPTION', p[1], p[3]]


def rgb_to_int(rgb):
    """Given an rgb, return an int"""
    return rgb[0] + rgb[1] * 256 + rgb[2] * 256 * 256


@classmethod
def remove_form(cls, label):
    """
        Remove an app_data form to the multi form after it's creation.
        Even if this form would be specified in a superclass it would be skipped.
        """
    cls.app_form_opts[label] = None


def show_covers_iter(result):
    """Iterates over library search dict result returning cover JPG file paths."""
    books = list(result.keys())
    for item in books:
        yield result[item].path_to_cover_jpg
        i += 1


def glIsProgram(program: int):
    """Determines if a name corresponds to a program object

    :param program: Specifies a potential program object.
    :type program: int
    """
    pass


@staticmethod
def optimize_range(ranges):
    """Simplify/Combine a parsed list of ranges

        Examples:
            optimize_range([(2,4), (4,6), (5,8)]) -> [(2,8)]
            optimize_range([(1,1), (2,2), (3,6), (8,9))]) -> [(1,6), (8,9)]
        """
    if len(ranges) <= 1:
        return ranges
    ranges.sort()
    riter = iter(ranges)
    result = []
    beg, end = next(riter)
    for lower, upper in riter:
        if lower > end + 1:
            result.append((beg, end))
            beg, end = lower, upper
        elif upper > end:
            end = upper
    result.append((beg, end))
    return result


@staticmethod
def write_csv_header(csv_writer):
    """Write the CSV header line."""
    csv_writer.writerow(['Location', 'Venue', 'Find Us', 'Example Meetup',
        'Example URL'])


def _default_key_normalizer(key_class, request_context):
    """
    Create a pool key out of a request context dictionary.

    According to RFC 3986, both the scheme and host are case-insensitive.
    Therefore, this function normalizes both before constructing the pool
    key for an HTTPS request. If you wish to change this behaviour, provide
    alternate callables to ``key_fn_by_scheme``.

    :param key_class:
        The class to use when constructing the key. This should be a namedtuple
        with the ``scheme`` and ``host`` keys at a minimum.
    :type  key_class: namedtuple
    :param request_context:
        A dictionary-like object that contain the context for a request.
    :type  request_context: dict

    :return: A namedtuple that can be used as a connection pool key.
    :rtype:  PoolKey
    """
    context = request_context.copy()
    context['scheme'] = context['scheme'].lower()
    context['host'] = context['host'].lower()
    for key in ('headers', '_proxy_headers', '_socks_options'):
        if key in context and context[key] is not None:
            context[key] = frozenset(context[key].items())
    socket_opts = context.get('socket_options')
    if socket_opts is not None:
        context['socket_options'] = tuple(socket_opts)
    for key in list(context.keys()):
        context['key_' + key] = context.pop(key)
    for field in key_class._fields:
        if field not in context:
            context[field] = None
    return key_class(**context)


def lesser(attrs, inputs, proto_obj):
    """Logical Lesser operator with broadcasting."""
    return 'broadcast_lesser', attrs, inputs


@classmethod
def from_chunks(cls, chunks):
    """Construct PNG from raw chunks.

		:arg chunks: A list of ``(chunk_type, chunk_raw_data)``. Also see
			:func:`chunks`.
		:type chunks: list[tuple(str, bytes)]
		"""
    o = cls()
    o.chunks = chunks
    o.init()
    return o


def mixed_social_welfare(game, mix):
    """Returns the social welfare of a mixed strategy profile"""
    return game.expected_payoffs(mix).dot(game.num_role_players)


@staticmethod
def get_attr(node, attrname, default=''):
    """ Give me the attribute value! """
    try:
        return node[attrname]
    except KeyError:
        return default


def backimage_zoom(factor: float=1.2):
    """Zoom in/out the background image

    :param factor: Factor
    :type factor: float
    """
    pass


def jwt_get_username_from_payload_handler(payload):
    """
    Override this function if username is formatted differently in payload
    """
    return payload.get('username')


def reverse_map(D):
    """
    Return a dict having D.values() as its keys and D.keys() as its values.
    """
    E = {}
    for k, v in D.items():
        if v in E:
            raise KeyError(
                "Cannot reverse this mapping, as it is not one-to-one ('%s' would map to both '%s' and '%s')"
                 % (v, E[v], k))
        E[v] = k
    return E


def weighted(value):
    """Manage None value in dict value."""
    return -float('inf') if value is None else value


def get_vni_definition():
    """Create a definition dictionary for the VNI input method.

    Returns a dictionary to be passed into process_key().
    """
    return {'6': ['a^', 'o^', 'e^'], '7': ['u*', 'o*'], '8': 'a+', '9':
        'd-', '2': '\\', '1': '/', '3': '?', '4': '~', '5': '.'}


def freestyle_lineset_add():
    """Add a line set into the list of line sets

    """
    pass


def tzoffset():
    """Return the timezone offset for the objects timezone."""


def action_sync_length(active: bool=True):
    """Synchronize the length of the referenced Action with the length used in the strip

    :param active: Active Strip Only, Only sync the active length for the active strip
    :type active: bool
    """
    pass


def file_size_format(num, suffix='B'):
    """Formats a file size into human readable

    :param num: size (bytes)
    :param suffix:

        - **B** is default and return bytes
        - or one of **Ki**, **Mi**, **Gi**, **Ti**, **Pi**', **Ei**, **Zi**

    :return: **`str`** with file size
    """
    for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
        if abs(num) < 1024.0:
            return '%3.1f%s%s' % (num, unit, suffix)
        num /= 1024.0
    return '%.1f%s%s' % (num, 'Yi', suffix)


def match_file_to_dict(file_handler, key_dict, sep='\t', join_by=0):
    """
    Generator function for mapping a particular field in a file, separated by 'sep', to dictionary keys
    :param file_handler: Opened file object
    :param key_dict: Dictionary to map the selected field to
    :param sep: Field separator
    :param join_by: The field number to search the dictionary for
    :return: Line that matches a key
    """
    for line in file_handler:
        if line.split(sep)[join_by] in key_dict:
            yield line


def parse_event(event, score, teams, date, game_id, players):
    """
    Parses a single event when the info is in a json format

    :param event: json of event
    :param score: Current score of the game
    :param teams: Teams dict (id -> name)
    :param date: date of the game
    :param game_id: game id for game
    :param players: Dict of player ids to player names

    :return: dictionary with the info
    """
    play = dict()


def setup_rdfview(ax, system):
    """Builds the radial distribution function visualisation pane.

    Parameters
    ----------
    ax: Axes object
        The axes position that the pane should be placed in.
    system: System
        The whole system information.
    """
    ax.plot([0], color='#34a5daff')
    ax.set_xlim([0, system.box_length / 2])
    ax.set_yticks([])
    ax.set_ylabel('RDF', fontsize=16)
    ax.set_xlabel('r/m', fontsize=16)


def pprinttime(t):
    """Custom printing of elapsed time"""
    if t > 4000:
        s = 't=%.1fh' % (t / 3600)
    elif t > 300:
        s = 't=%.0fm' % (t / 60)
    else:
        s = 't=%.0fs' % t
    return s


def lower_text(string, **unused_kwargs):
    """Lowercases text."""
    return string.lower()


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


def total_seconds(delta):
    """Determines total seconds with python < 2.7 compat."""
    return (delta.microseconds + (delta.seconds + delta.days * 24 * 3600) *
        1000000.0) / 1000000.0


def consume_none(pipeline):
    """This mimics the behavior of Consecution's consume() but allows for
    running a pipeline with no input data."""
    pipeline.begin()
    pipeline.top_node._process(None)
    return pipeline.end()


def get_protocol_string(name, version):
    """Retrieve avro protocol string for the given name/version."""


def delocalize_compressed_verts(comp_verts, local_nodes):
    """TODO: Update this function to also work on parsed vert data."""
    local_node_ct = len(local_nodes) * 3
    for i in range(28, len(comp_verts), 32):
        if comp_verts[i] < local_node_ct:
            comp_verts[i] = local_nodes[comp_verts[i] // 3] * 3
        i += 1
        if comp_verts[i] < local_node_ct:
            comp_verts[i] = local_nodes[comp_verts[i] // 3] * 3


def feel(value):
    """
    Get the table of the value (or class).
    """
    if not isinstance(value, type):
        value = value.__class__
    from . import tables
    return tables[value]


@classmethod
def fromkeys(cls, iterable, value=None):
    """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
        and values equal to v (which defaults to None).

        """
    d = cls()
    for key in iterable:
        d[key] = value
    return d


def match_items(lines, content_old):
    """Create items for mangled lines.

    This function tries to match the lines in ``lines`` with the items (source
    file references and line numbers) in ``content_old``. The
    ``mangle_docstrings`` function changes the actual docstrings, but doesn't
    keep track of where each line came from. The manging does many operations
    on the original lines, which are hard to track afterwards.

    Many of the line changes come from deleting or inserting blank lines. This
    function tries to match lines by ignoring blank lines. All other changes
    (such as inserting figures or changes in the references) are completely
    ignored, so the generated line numbers will be off if ``mangle_docstrings``
    does anything non-trivial.

    This is a best-effort function and the real fix would be to make
    ``mangle_docstrings`` actually keep track of the ``items`` together with
    the ``lines``.

    Examples
    --------
    >>> lines = ['', 'A', '', 'B', '   ', '', 'C', 'D']
    >>> lines_old = ['a', '', '', 'b', '', 'c']
    >>> items_old = [('file1.py', 0), ('file1.py', 1), ('file1.py', 2),
    ...              ('file2.py', 0), ('file2.py', 1), ('file2.py', 2)]
    >>> content_old = ViewList(lines_old, items=items_old)
    >>> match_items(lines, content_old) # doctest: +NORMALIZE_WHITESPACE
    [('file1.py', 0), ('file1.py', 0), ('file2.py', 0), ('file2.py', 0),
     ('file2.py', 2), ('file2.py', 2), ('file2.py', 2), ('file2.py', 2)]
    >>> # first 2 ``lines`` are matched to 'a', second 2 to 'b', rest to 'c'
    >>> # actual content is completely ignored.

    Notes
    -----
    The algorithm tries to match any line in ``lines`` with one in
    ``lines_old``.  It skips over all empty lines in ``lines_old`` and assigns
    this line number to all lines in ``lines``, unless a non-empty line is
    found in ``lines`` in which case it goes to the next line in ``lines_old``.

    """
    items_new = []
    lines_old = content_old.data
    items_old = content_old.items
    j = 0
    for i, line in enumerate(lines):
        while j < len(lines_old) - 1 and not lines_old[j].strip():
            j += 1
        items_new.append(items_old[j])
        if line.strip() and j < len(lines_old) - 1:
            j += 1
    assert len(items_new) == len(lines)
    return items_new


def _print_info_dict(info_dict):
    """Print the information dictionary"""
    for key, stat in info_dict.items():
        print('{key:>10}: {stat}'.format(key=key, stat=stat))


def to_float_if_possible(s):
    """
    Convert to float if possible.

    Parameters
    ----------
    s: str

    Returns
    -------
    float or None
    """
    try:
        return float(s)
    except ValueError:
        if s.strip() == '':
            return None
        else:
            return s


@classmethod
def from_pipeline(cls, pipeline, actions=None, proba=None, repeat=None):
    """ Create a pipeline from another pipeline """
    if proba is None:
        if repeat is None:
            new_p = cls(pipeline=pipeline, actions=actions)
        elif pipeline.num_actions == 1 and pipeline.get_last_action_proba(
            ) is None:
            new_p = cls(pipeline=pipeline, repeat=repeat)
        else:
            new_p = cls()
            new_p.append_pipeline(pipeline, repeat=repeat)
    elif pipeline.num_actions == 1 and pipeline.get_last_action_repeat(
        ) is None:
        new_p = cls(pipeline=pipeline, proba=proba)
    else:
        new_p = cls()
        new_p.append_pipeline(pipeline, proba=proba)
    return new_p


def drawDipole(position, moment, angle, axis, SYSSIZE, ax):
    """
    Draw a dipole moment arrow.

    Parameters
    ----------
    position : vec3
        position of the dipole
    moment : vec3
        orientation vector of the dipole
    SYSSIZE : float
        size of the display
    pyplot : pyplot
        canvas to draw on

    """
    from magpylib._lib.mathLib import angleAxisRotation
    P = angleAxisRotation(position, angle, axis)
    M = angleAxisRotation(moment, angle, axis)
    ax.quiver(P[0], P[1], P[2], M[0], M[1], M[2], normalize=True, length=
        SYSSIZE / 12, color='k')


def fileobj_open(filename, mode):
    """
    A wrapper around the `open()` builtin.

    This exists because in Python 3, `open()` returns an `io.BufferedReader` by
    default.  This is bad, because `io.BufferedReader` doesn't support random
    access, which we need in some cases.  In the Python 3 case (implemented in
    the py3compat module) we must call open with buffering=0 to get a raw
    random-access file reader.
    """
    return open(filename, mode)


@classmethod
def _to_internal_color(cls, c):
    """
        Converts a color to the appropriate TKinter representation.

        This method allows us to support all color formats, while using a single
        color format for the backend.

        :param c: the color value
        :type c:  valid color

        :return: The given color value, converted to an internal format
        :rtype:  ``str``
        """
    from .. import colors
    return c.webColor() if type(c) in [colors.RGB, colors.HSV] else c if c[0
        ] == '#' else colors.tk_webcolor(c)


def describe_fleet_port_settings(FleetId=None):
    """
    Retrieves the inbound connection permissions for a fleet. Connection permissions include a range of IP addresses and port settings that incoming traffic can use to access server processes in the fleet. To get a fleet's inbound connection permissions, specify a fleet ID. If successful, a collection of  IpPermission objects is returned for the requested fleet ID. If the requested fleet has been deleted, the result set is empty.
    See also: AWS API Documentation

    :example: response = client.describe_fleet_port_settings(
        FleetId='string'
    )

    :type FleetId: string
    :param FleetId: [REQUIRED]
            Unique identifier for a fleet to retrieve port settings for.

    :rtype: dict
    :return: {
        'InboundPermissions': [
            {
                'FromPort': 123,
                'ToPort': 123,
                'IpRange': 'string',
                'Protocol': 'TCP'|'UDP'
            },
        ]
    }

    """
    pass


def get_cluster_ueid(session):
    """Get the Kubernetes Cluster UEID.

    :raises LookupError: If a Cluster UEID cannot be found.

    :returns: A :class:`cobe.UEID` for the Cluster.
    """
    results = session.pluginmanager.hooks.entityd_find_entity(name=
        'Kubernetes:Cluster', attrs=None)
    if results:
        for cluster_entity in results[0]:
            return cluster_entity.ueid
    else:
        raise LookupError('Could not find the Cluster UEID')


def CDLENGULFING(df):
    """
    Engulfing Pattern
    """


def close_conn(conn, cursor):
    """
    Commits changes and close connection to database

    :param conn: connection to close
    :type conn: sqlite3.Connection
    :param cursor: cursor to close
    :type cursor: sqlite3.Cursor
    """
    conn.commit()
    cursor.close()
    conn.close()
    return


@classmethod
def enhanced(cls, r, g, b, ratio):
    """Enhanced color by 'ratio', allows to brighten/darken colors"""
    f, lm = (min, 255) if ratio > 1 else (max, 0)
    if ratio > 1:
        r = max(8, r)
        g = max(8, g)
        b = max(8, b)
    return f(lm, int(round(r * ratio))), f(lm, int(round(g * ratio))), f(lm,
        int(round(b * ratio)))


def _normalize_per_contig(arr):
    """ Divides respective row of arr with its sum. """
    return arr.divide(arr.sum(axis=1), axis=0)


def get_meta_graph_def(saved_model_dir, tag_set):
    """Utility function to read a meta_graph_def from disk.

  From `saved_model_cli.py <https://github.com/tensorflow/tensorflow/blob/8e0e8d41a3a8f2d4a6100c2ea1dc9d6c6c4ad382/tensorflow/python/tools/saved_model_cli.py#L186>`_

  DEPRECATED for TF2.0+

  Args:
    :saved_model_dir: path to saved_model.
    :tag_set: list of string tags identifying the TensorFlow graph within the saved_model.

  Returns:
    A TensorFlow meta_graph_def, or raises an Exception otherwise.
  """
    from tensorflow.contrib.saved_model.python.saved_model import reader
    saved_model = reader.read_saved_model(saved_model_dir)
    set_of_tags = set(tag_set.split(','))
    for meta_graph_def in saved_model.meta_graphs:
        if set(meta_graph_def.meta_info_def.tags) == set_of_tags:
            return meta_graph_def
    raise RuntimeError(
        'MetaGraphDef associated with tag-set {0} could not be found in SavedModel'
        .format(tag_set))


def laysin(cols, rows, c):
    """ Given the center and the amount of rows and columns,
    return in which bin the axes is in.
    """
    dx, dy = 1.0 / cols, 1.0 / rows
    x, y = int(c[0] / dx), int(c[1] / dy)
    return x + y * cols


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


def identical_format_path(fmt1, fmt2):
    """Do the two (long representation) of formats target the same file?"""
    for key in ['extension', 'prefix', 'suffix']:
        if fmt1.get(key) != fmt2.get(key):
            return False
    return True


@classmethod
def get_activity_storage(cls):
    """
        Returns an instance of the activity storage
        """
    options = {}
    options['serializer_class'] = cls.activity_serializer
    options['activity_class'] = cls.activity_class
    if cls.activity_storage_class is not None:
        activity_storage = cls.activity_storage_class(**options)
        return activity_storage


def clear():
    """Clears the content of the storage. Returns None.
        """


def select_border(gesture_mode: int=0, xmin: int=0, xmax: int=0, ymin: int=
    0, ymax: int=0, extend: bool=True):
    """Select all time markers using border selection

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


def cap_length(s, char_limit=20, append_ellipsis=True):
    """Makes sure the string doesn't exceed the passed char limit.

    Appends an ellipsis if the string is to long."""
    if len(s) > char_limit:
        if append_ellipsis:
            return s[:char_limit - 3] + '...'
        else:
            return s[:char_limit]
    else:
        return s


def Concat(*data, **kwargs):
    """Joins input arrays along a given axis.

    .. note:: `Concat` is deprecated. Use `concat` instead.

    The dimensions of the input arrays should be the same except the axis along
    which they will be concatenated.
    The dimension of the output array along the concatenated axis will be equal
    to the sum of the corresponding dimensions of the input arrays.

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

    - concat(csr, csr, ..., csr, dim=0) = csr
    - otherwise, ``concat`` generates output with default storage

    Example::

       x = [[1,1],[2,2]]
       y = [[3,3],[4,4],[5,5]]
       z = [[6,6], [7,7],[8,8]]

       concat(x,y,z,dim=0) = [[ 1.,  1.],
                              [ 2.,  2.],
                              [ 3.,  3.],
                              [ 4.,  4.],
                              [ 5.,  5.],
                              [ 6.,  6.],
                              [ 7.,  7.],
                              [ 8.,  8.]]

       Note that you cannot concat x,y,z along dimension 1 since dimension
       0 is not the same for all the input arrays.

       concat(y,z,dim=1) = [[ 3.,  3.,  6.,  6.],
                             [ 4.,  4.,  7.,  7.],
                             [ 5.,  5.,  8.,  8.]]

    Defined in src/operator/nn/concat.cc:L383

    Parameters
    ----------
    data : NDArray[]
        List of arrays to concatenate
    dim : int, optional, default='1'
        the dimension to be concated.

    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 bucket_key_to_s3_path(bucket, key):
    """
    Takes an S3 bucket and key combination and returns the full S3 path to that location.
    """
    return 's3://{}/{}'.format(bucket, key)


def get(ICachableItem):
    """Returns ICachedItem representing ICachableItem"""


@staticmethod
def _list_replace(lst, replace, replacement):
    """
        Replace all values matching values in-line in a list.  Return whether any values were
        replaced.
        """
    replaced = False
    for i, v in enumerate(lst):
        if v == replace:
            lst[i] = replacement
            replaced = True
    return replaced


def _is_dunder(name):
    """Returns True if a __dunder__ name, False otherwise."""
    return name[:2] == name[-2:] == '__' and name[2:3] != '_' and name[-3:-2
        ] != '_' and len(name) > 4


def compute_ratios(df_dict, df_str, gridclimname1, gridclimname2, prefix1,
    prefix2='meanmonth', comp_dict=None):
    """
    Compute fold-difference between monthly means (e.g,. Temp) for two different gridded datasets (e.g., Liv, WRF)
    """
    if isinstance(comp_dict, type(None)):
        comp_dict = {}
    for each1 in prefix1:
        for each2 in prefix2:
            ratios = df_dict['_'.join([each2, each1, gridclimname1])
                ] / df_dict['_'.join([each2, each1, gridclimname2])]
            comp_dict['_'.join([str(each1), df_str])] = ratios
    return comp_dict


@classmethod
def has_archiving(cls):
    """Returns whether it supports archiving items on the fetch process.

        :returns: this backend supports items archive
        """
    return True


def check_vsimem() ->bool:
    """
    Checks if the gdal/ogr vsimem is available to the QGIS API
    (might be not the case for QGIS
    :return: bool
    """
    result = False
    try:
        from osgeo import gdal
        from qgis.core import QgsCoordinateReferenceSystem, QgsRasterLayer
        driver = gdal.GetDriverByName('GTiff')
        assert isinstance(driver, gdal.Driver)
        path = '/vsimem/inmemorytestraster.tif'
        dataSet = driver.Create(path, 2, 2, bands=1, eType=gdal.GDT_Byte)
        assert isinstance(dataSet, gdal.Dataset)
        c = QgsCoordinateReferenceSystem('EPSG:32632')
        dataSet.SetProjection(c.toWkt())
        dataSet.SetGeoTransform([0, 1.0, 0, 0, 0, -1.0])
        dataSet.FlushCache()
        dataSet = None
        ds2 = gdal.Open(path)
        assert isinstance(ds2, gdal.Dataset)
        layer = QgsRasterLayer(path)
        assert isinstance(layer, QgsRasterLayer)
        result = layer.isValid()
    except Exception as ex:
        return False
    return result


@classmethod
def apply_active_filters(cls, queryset):
    """
        Apply all filters defined to the queryset passed and return the result.
        """
    if cls.active_filters is not None:
        for filt in (cls.active_filters.values() or ()):
            if callable(filt):
                queryset = filt(queryset)
            else:
                queryset = queryset.filter(filt)
    return queryset


def sec2plugin(secname):
    """Reverse of :meth:`plugin2sec`."""
    if secname.startswith('plugin:'):
        return secname[7:]
    else:
        return secname


def _set_class_module(module_class):
    """Initialize the module."""
    global _CLASS_MODULE
    _CLASS_MODULE = module_class


def str_to_bool(string):
    """ Used as a type in argparse so that we get back a proper
    bool instead of always True
    """
    return string.lower() in ('y', 'yes', '1', 'true')


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


def set_kwargs_from_dflt(passed: dict, dflt: dict) ->dict:
    """Updates ++passed++ dictionary to add any missing keys and
    assign corresponding default values, with missing keys and
    default values as defined by ++dflt++"""
    for key, val in dflt.items():
        passed.setdefault(key, val)
    return passed


def write_file(text, filename):
    """write text to file"""
    with open(filename, 'w') as f:
        f.write(text)


def alt2pres(altitude):
    """
    Determine site pressure from altitude.

    Parameters
    ----------
    altitude : numeric
        Altitude in meters above sea level

    Returns
    -------
    pressure : numeric
        Atmospheric pressure (Pascals)

    Notes
    ------
    The following assumptions are made

    ============================   ================
    Parameter                      Value
    ============================   ================
    Base pressure                  101325 Pa
    Temperature at zero altitude   288.15 K
    Gravitational acceleration     9.80665 m/s^2
    Lapse rate                     -6.5E-3 K/m
    Gas constant for air           287.053 J/(kgK)
    Relative Humidity              0%
    ============================   ================

    References
    -----------
    .. [1] "A Quick Derivation relating altitude to air pressure" from
       Portland State Aerospace Society, Version 1.03, 12/22/2004.
    """
    press = 100 * ((44331.514 - altitude) / 11880.516) ** (1 / 0.1902632)
    return press


def flatten(nested_list):
    """Flattens a list, ignore all the lambdas."""
    return list(sorted(filter(lambda y: y is not None, list(map(lambda x:
        nested_list.extend(x) if isinstance(x, list) else x, nested_list)))))


@staticmethod
def _strip_key(key):
    """
        Strip a given key from spaces, dashes, and underscores.
        :param key: The key to strip.
        :return: Stripped key.
        """
    return key.lower().replace('-', '').replace('_', '').replace(' ', '')


def _annotate_bookmark(label, bookmark=None):
    """
    Annotate a bookmark indicator onto the type indicator of a bucket or prefix
    """
    if not bookmark:
        return label
    return '\x1b[33m${}\x1b[0m {}'.format(bookmark, label)


def get_column_width(column, table):
    """
    Get the character width of a column in a table

    Parameters
    ----------
    column : int
        The column index analyze
    table : list of lists of str
        The table of rows of strings. For this to be accurate, each
        string must only be 1 line long.

    Returns
    -------
        width : int
    """
    width = 3
    for row in range(len(table)):
        cell_width = len(table[row][column])
        if cell_width > width:
            width = cell_width
    return width


def asnumpy(input):
    """Convert the input tensor to numpy array.

    The data is copied.

    Parameters
    ----------
    input : Tensor
        The input tensor.

    Returns
    -------
    numpy.ndarray
        Numpy array.
    """
    pass


def valid_event(event: list):
    """
    Filter out some events that don't provide meaningful information.

    The HTML PBP has 8 columns:
    ['#', 'Per', 'Str', 'Time:El', 'Event', 'Description', 'AWAY On Ice', 'HOME On Ice']

    :param event: list of stuff in pbp

    :return: boolean
    """
    return event[0] != '#' and event[4] not in ['GOFF', 'EGT', 'PGSTR',
        'PGEND', 'ANTHEM']


def floating_ebtables_rules(fixed_ip, network):
    """Makes sure only in-network traffic is bridged."""
    return [
        'PREROUTING --logical-in %s -p ipv4 --ip-src %s ! --ip-dst %s -j redirect --redirect-target ACCEPT'
         % (network['bridge'], fixed_ip, network['cidr'])], 'nat'


def enable_debug_messages():
    """
    Enable debugging message printing.
    """
    global debug_enabled
    debug_enabled = True


def merge_headers(header_map_list):
    """
    Helper function for combining multiple header maps into one.

    :param header_map_list: list of maps
    """
    headers = {}
    for header_map in header_map_list:
        headers.update(header_map)
    return headers


def scale(xy, scale_factor=1):
    """
    Scales coordinates (x, y) by scale_factor.
    :param xy, (x, y), coordinates
    :param scale_factor, the scale_factor
    :return: scaled coordinates: (x, y)
    """
    x, y = xy
    return x * scale_factor, y * scale_factor


def arn_has_colons(arn):
    """Given an ARN, determine if the ARN has colons in it. Just useful for the hacky methods for
    parsing ARN namespaces. See
    http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for more details on ARN namespacing."""
    if arn.count(':') > 0:
        return True
    else:
        return False


def respond_activity_task_failed(taskToken=None, reason=None, details=None):
    """
    Used by workers to tell the service that the  ActivityTask identified by the taskToken has failed with reason (if specified). The reason and details appear in the ActivityTaskFailed event added to the workflow history.
    A task is considered open from the time that it is scheduled until it is closed. Therefore a task is reported as open while a worker is processing it. A task is closed after it has been specified in a call to  RespondActivityTaskCompleted ,  RespondActivityTaskCanceled , RespondActivityTaskFailed, or the task has timed out .
    Access Control
    You can use IAM policies to control this action's access to Amazon SWF resources as follows:
    If the caller does not have sufficient permissions to invoke the action, or the parameter values fall outside the specified constraints, the action fails. The associated event attribute's cause parameter will be set to OPERATION_NOT_PERMITTED. For details and example IAM policies, see Using IAM to Manage Access to Amazon SWF Workflows .
    See also: AWS API Documentation

    :example: response = client.respond_activity_task_failed(
        taskToken='string',
        reason='string',
        details='string'
    )

    :type taskToken: string
    :param taskToken: [REQUIRED]
            The taskToken of the ActivityTask .
            Warning
            taskToken is generated by the service and should be treated as an opaque value. If the task is passed to another process, its taskToken must also be passed. This enables it to provide its progress and respond with results.

    :type reason: string
    :param reason: Description of the error that may assist in diagnostics.

    :type details: string
    :param details: Optional. Detailed information about the failure.

    :returns:
    taskToken (string) -- [REQUIRED]
    The taskToken of the  ActivityTask .

    Warning
    taskToken is generated by the service and should be treated as an opaque value. If the task is passed to another process, its taskToken must also be passed. This enables it to provide its progress and respond with results.

    reason (string) -- Description of the error that may assist in diagnostics.
    details (string) -- Optional. Detailed information about the failure.

    """
    pass


def ovn_metadata_name(id_):
    """Return the OVN metadata name based on an id."""
    return 'metadata-%s' % id_


def min(input, dim):
    """Reduce min the input tensor along the given dim.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    dim : int
        The reduce dim.

    Returns
    -------
    Tensor
        A framework-specific tensor.
    """
    pass


def atom_mass(atom, coef=0.01):
    """Get the mass of an atom and scale it.

    Parameters
    ----------
    atom : rdkit.Chem.rdchem.Atom
        RDKit atom instance.
    coef : float
        The mass will be multiplied by ``coef``.

    Returns
    -------
    list
        List containing one float only.
    """
    return [atom.GetMass() * coef]


def call_if_callable(func, *args, **kwargs):
    """Call the function with given parameters if it is callable"""
    if func and callable(func):
        return func(*args, **kwargs)
    return None


@classmethod
def get_mains_powered_outlets(cls, session):
    """Wall-powered outlets

        Args:
            session: database session
        Returns:
            list: of outlet keys powered by the mains
        """
    results = session.run(
        """
            MATCH (outlet:Outlet) WHERE NOT (outlet)-[:POWERED_BY]->(:Asset) RETURN outlet.key as key
            """
        )
    return list(map(lambda x: x.get('key'), results))


def xproto_dict_to_sorted_string(d):
    """
    sorts the dict by key and returns a string representation, which makes
    for better consistency when testing
    """
    ft = []
    for k, v in sorted(d.items(), key=lambda t: t[0]):
        if v is not None:
            ft.append("'%s': '%s'" % (k, v))
        else:
            ft.append("'%s': None" % k)
    return '{%s}' % ', '.join(ft)


def value_from_level(field, level):
    """
    extract value from field in level of item
    """
    return level[field] if field in level else ''


@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
    """Make a new Quad object from a sequence or iterable"""
    result = new(cls, iterable)
    if len(result) != 4:
        raise TypeError('Expected 4 arguments, got %d' % len(result))
    return result


def guesstimate_audio_extension(data):
    """:arg data audio file content
    :return file format extension guessed from file content"""
    if len(data) > 8 and data[0:8] == b'fLaC\x00\x00\x00"':
        return 'flac'
    if len(data) > 3 and data[0:3] == b'Ogg':
        return 'ogg'
    return None


def interpose(sep, coll):
    """
    Returns a generator of the elements of ``coll`` separated by ``sep``.
    """
    first = True
    for e in coll:
        if first:
            first = False
        else:
            yield sep
        yield e


def check_vrange(vrange):
    """
    Check vrange argument (used by other functions).

    Parameters
    ----------
    vrange : tuple or iterable
        data (min, max) for plotting; if iterable, must have length 2

    Returns
    -------
    vrange : tuple

    Raises
    ------
    ValueError : vrange is not length-2 iterable obj with vrange[0] > vrange[1]

    """
    if type(vrange) is not tuple:
        if not hasattr(vrange, '__iter__'):
            raise ValueError(
                'if vrange is not a tuple, it must be an iterable object')
        if len(vrange) != 2:
            raise ValueError('vrange must contain only two elements')
    if vrange[0] >= vrange[1]:
        raise ValueError('vrange[0] must be strictly less than vrange[1]')
    return tuple(list(vrange))


def hide_metaelems(unselected: bool=False):
    """Hide (un)selected metaelement(s)

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


@staticmethod
def interpolate_cmpl_list(timeseries_list, timestep):
    """ Interpolates list of complex timeseries with new timestep
        :param timestep:
        :return:
        """
    result_list = {}
    for name, ts in timeseries_list.items():
        ts_intp = ts.interpolate_cmpl(timestep)
        result_list[ts_intp.name] = ts_intp
    return result_list


def PmfProbLess(pmf1, pmf2):
    """Probability that a value from pmf1 is less than a value from pmf2.

    Args:
        pmf1: Pmf object
        pmf2: Pmf object

    Returns:
        float probability
    """
    total = 0
    for v1, p1 in pmf1.Items():
        for v2, p2 in pmf2.Items():
            if v1 < v2:
                total += p1 * p2
    return total


def find_start(d):
    """finds the starting location for the program"""
    for y in range(1, len(d) - 1):
        for x in range(1, len(d[y]) - 1):
            if d[y - 1][x - 1:x + 2] == [True, True, False] and d[y - 0][x -
                1:x + 2] == [True, False, False] and d[y + 1][x - 1:x + 2] == [
                True, True, False]:
                return x + 2, y
            if d[y - 1][x - 1:x + 2] == [True, True, True] and d[y - 0][x -
                1:x + 2] == [True, False, True] and d[y + 1][x - 1:x + 2] == [
                False, False, False]:
                return x, y + 2
            if d[y - 1][x - 1:x + 2] == [False, True, True] and d[y - 0][x -
                1:x + 2] == [False, False, True] and d[y + 1][x - 1:x + 2] == [
                False, True, True]:
                return x - 2, y
            if d[y - 1][x - 1:x + 2] == [False, False, False] and d[y - 0][
                x - 1:x + 2] == [True, False, True] and d[y + 1][x - 1:x + 2
                ] == [True, True, True]:
                return x, y - 2


def combination(n, m):
    """
    Calculate the combination :math:`C_{n}^{m}`,

    .. math::

        C_{n}^{m} = \\frac{n!}{m!(n-m)!}.

    Parameters
    ----------
    n: int
       Number n.
    m: int
        Number m.

    Returns
    -------
    res: int
        The calculated result.

    Examples
    --------
    >>> import edrixs
    >>> edrixs.combination(6, 2)
    15

    """
    if m > n or n < 0 or m < 0:
        print('wrong number in combination')
        return
    if m == 0 or n == m:
        return 1
    largest = max(m, n - m)
    smallest = min(m, n - m)
    numer = 1.0
    for i in range(largest + 1, n + 1):
        numer *= i
    denom = 1.0
    for i in range(1, smallest + 1):
        denom *= i
    res = int(numer / denom)
    return res


def is_font(filepath):
    """
    Tests filepath argument to determine if it has a .ttf or .otf file extension (definition of "font" for this
    application)

    :param filepath: (string) file path to a font file for testing
    :return: (boolean) True = appears to be a font file path; False = does not appear to be a font file path
    """
    if len(filepath) > 4:
        if filepath[-4:].lower() == '.ttf' or filepath[-4:].lower() == '.otf':
            return True
        else:
            return False
    else:
        return False


def round_coord(float):
    """ Round a latitude or longitude to appropriate length.
    """
    return round(float, 7)


def moveObjectsDown(ids, delta=1, subset_ids=None):
    """ Move specified sub-objects down by delta in container. """


@classmethod
def default_options(cls):
    """
        Return a dictionary of the default options for the LBFGS
        optimization algorithm

        Stopping criteria based on tolerance of objective function
        and its gradient:

        1) ``(f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr * eps``
            where ``eps`` is the machine precision
        2) ``max(abs(G_k)) <= gtol``

        Parameters
        ----------
        factr : float
            The iteration stops when ``(f^k -
            f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr * eps``, where ``eps``
            is the machine precision, which is automatically generated by
            the code. Typical values for `factr` are: 1e12 for low
            accuracy; 1e7 for moderate accuracy; 10.0 for extremely high
            accuracy. Default is 1e5
        gtol : float
            the absolute tolerance of the gradient norm required for
            convergence; default is 1e-5
        max_iter : int
            the maximum number of steps to run; default is `500`
        display : int
            the level of logging desired; default is second to highest, `2`
        record : list of str
            the names of variables to track per iteration; default
            is `F` and `Gnorm`
        """
    default = {}
    default['factr'] = 100000.0
    default['gtol'] = 1e-05
    default['max_iter'] = 500
    default['display'] = 2
    default['record'] = ['F', 'Gnorm']
    default['test_convergence'] = True
    return default


def pair_partitions(L, R):
    """ Returns which partitions to pair for the merge_asof algorithm and the
    bounds on which to split them up
    """
    result = []
    n, m = len(L) - 1, len(R) - 1
    i, j = 0, -1
    while R[j + 1] <= L[i]:
        j += 1
    J = []
    while i < n:
        partition = 0 if j < 0 else m - 1 if j >= m else j
        lower = R[j] if j >= 0 and R[j] > L[i] else None
        upper = R[j + 1] if j + 1 < m and (i == n - 1 or R[j + 1] < L[i + 1]
            ) else None
        J.append((partition, lower, upper))
        i1 = i + 1 if j + 1 == m or i + 1 < n and R[j + 1] >= L[i + 1] else i
        j1 = j + 1 if i + 1 == n or j + 1 < m and L[i + 1] >= R[j + 1] else j
        if i1 > i:
            result.append(J)
            J = []
        i, j = i1, j1
    return result


@staticmethod
def __ParseVar(var: int, per_request=50) ->list:
    """used for calculate number of requests depending on per_request and number

        Parameters
        ----------
        var : int
            number of items
        per_request : int
            number of items per request default=50

        Returns
        -------
        list
            [number_or_requests, number_of_left, per_request]
        """
    if var > per_request:
        request_number = var // per_request
        request_number_left = var % per_request
        if request_number_left > 0:
            request_number += 1
        else:
            request_number = request_number
    else:
        request_number = 1
        request_number_left = var
    return [request_number, request_number_left, per_request]


def round(data=None, out=None, name=None, **kwargs):
    """Returns element-wise rounded value to the nearest integer of the input.

    Example::

       round([-1.5, 1.5, -1.9, 1.9, 2.1]) = [-2.,  2., -2.,  2.,  2.]

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

      - round(default) = default
      - round(row_sparse) = row_sparse
      - round(csr) = csr

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

    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 __init__(request):
    """Instantiate a response plugin for a corresponding ``request``
        plugin.

        ``request``,
            Is an instance object for plugin implementing :class:`IHTTPResponse`
            interface.
        """


@staticmethod
def _get_messages_upload_server(session, peer_id):
    """
        https://vk.com/dev/photos.getMessagesUploadServer
        """
    response = session.fetch('photos.getMessagesUploadServer', peer_id=peer_id)
    return response['upload_url']


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

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


def _get_schema(buffer) ->str:
    """
    Extract the schema code embedded in the buffer

    :param buffer: The raw buffer of the FlatBuffers message.
    :return: The schema identifier
    """
    return buffer[4:8].decode('utf-8')


def get_matplotlib():
    """Wrapper function to facilitate unit testing the `plot` tool by removing
    the strong dependencies of matplotlib.

    Returns:
        module matplotlib.pyplot
    """
    import matplotlib.pyplot as plt
    return plt


def is_int(string):
    """
    Return true if string is an integer.
    """
    try:
        int(string)
        return True
    except ValueError:
        return False


@classmethod
def clear_expired(cls):
    """
        Remove expired sessions from the session store.

        If this operation isn't possible on a given backend, it should raise
        NotImplementedError. If it isn't necessary, because the backend has
        a built-in expiration mechanism, it should be a no-op.
        """
    raise NotImplementedError('This backend does not support clear_expired().')


def argmin(iterable):
    """Return index of minimum value."""
    lowest_val = iterable[0]
    lowest_i = 0
    for i, val in enumerate(iterable):
        if val < lowest_val:
            lowest_val = val
            lowest_i = i
    return lowest_i


@classmethod
def base_url(klass, **kwargs):
    """
        Returns the URI for the user.
        """
    return 'users/me'


def threeindicesfamily(n):
    """
    #TODO to be OPTIMIZED
    remove harmonics
    """
    listhkl = []
    for hh in list(range(n + 1)):
        for kk in list(range(n + 1)):
            for ll in list(range(n + 1)):
                if hh >= kk and kk >= ll:
                    listhkl.append([hh, kk, ll])
    return listhkl[1:]


def get_base_attr(cls, name):
    """Return first non-``None`` attribute of given name among base classes."""
    for base in cls.mro():
        if hasattr(base, name):
            attr = getattr(base, name)
            if attr is not None:
                return attr
    return None


def main():
    """Function to be called when file executed via terminal."""
    print(__doc__)


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 row_generator(resource, doc, env, *args, **kwargs):
    """ An example row generator function.

    Reference this function in a Metatab file as the value of a Datafile:

            Datafile: python:pylib#row_generator

    The function must yield rows, with the first being headers, and subsequenct rows being data.

    :param resource: The Datafile term being processed
    :param doc: The Metatab document that contains the term being processed
    :param args: Positional arguments passed to the generator
    :param kwargs: Keyword arguments passed to the generator
    :return:

    The env argument is a dict with these environmental keys:

    * CACHE_DIR
    * RESOURCE_NAME
    * RESOLVED_URL
    * WORKING_DIR
    * METATAB_DOC
    * METATAB_WORKING_DIR
    * METATAB_PACKAGE

    It also contains key/value pairs for all of the properties of the resource.

    """
    yield 'a b c'.split()
    for i in range(10):
        yield [i, i * 2, i * 3]


def dosplot(p0='./', totonly=True, color='', label='', marker='', lw=2, ms=
    5, ls='-', ls_ef=':', lw_ef=1, units='Ry', noefline=False, interpol=
    False, allatoms=False, onespin=False, atoms=[], lmdos=False, lm=[],
    nofig=False, scale=1.0, shift=0, normalized=False, xyswitch=False,
    efcolor='', return_data=False, xscale=1.0, xshift=0.0, yshift=0.0,
    filled=False, spins=2):
    """ plotting routine for dos files """
    from numpy import loadtxt, sort, array, sum
    from matplotlib.pyplot import figure, plot, axvline, xlabel, ylabel, ion, title, figure, fill_between, axhline
    from os import listdir
    from os.path import isdir
    ion()
    if type(p0) != str:
        pathname_with_file = p0.name
        p0 = pathname_with_file.replace('/dos.atom1', '')
    if p0[-1] != '/':
        p0 += '/'
    ef = float(open(p0 + 'potential').readlines()[3].split()[1])
    first = True
    for i in sort(listdir(p0)):
        if (((i[:8] == 'dos.atom' and 'interpol' not in i) and not interpol or
            interpol and i[:17] == 'dos.interpol.atom') or 'out_ldos.atom' in
            i and 'out_lmdos.atom' not in i and not interpol or (
            'out_ldos.interpol.atom' in i and 'out_lmdos.interpol.atom' and
            interpol) and not isdir(p0 + i)):
            if lmdos:
                i = i.replace('out_ldos.', 'out_lmdos.')
            if not onespin or 'spin' + str(spins) not in i:
                iatom = i.replace('dos.', '').replace('interpol.', '').replace(
                    'atom', '').replace('out_l', '').replace('=', '').replace(
                    'm', '').split('_')[0]
                if atoms == [] or int(iatom) in atoms:
                    tmp = loadtxt(p0 + i)
                    print(p0 + i)
                    if 'rel' in units:
                        tmp[:, (0)] = tmp[:, (0)] - ef
                    if 'eV' in units:
                        tmp[:, (0)] = tmp[:, (0)] * 13.6
                        tmp[:, 1:] = tmp[:, 1:] / 13.6
                    tmp[:, (0)] = tmp[:, (0)] * xscale + xshift
                    tmp[:, (1)] = tmp[:, (1)] + yshift
                    if allatoms:
                        sgn = 1
                        if 'spin2' in i:
                            sgn = -1
                        if totonly:
                            if color == '':
                                if first:
                                    if not nofig:
                                        figure()
                                plot(tmp[:, (0)], sgn * tmp[:, (1)], marker +
                                    ls, label=label + str(i), lw=lw, ms=ms)
                            else:
                                if not nofig:
                                    figure()
                                if filled:
                                    fill_between(tmp[:, (0)], sgn * tmp[:,
                                        (1)], color=color, label=label)
                                else:
                                    plot(tmp[:, (0)], sgn * tmp[:, (1)],
                                        marker + ls, color=color, label=
                                        label, lw=lw, ms=ms)
                        else:
                            if not nofig and sgn == 1:
                                figure()
                            if color == '':
                                if lm == []:
                                    if filled:
                                        fill_between(tmp[:, (0)], sgn * tmp[:, 1:])
                                    else:
                                        plot(tmp[:, (0)], sgn * tmp[:, 1:],
                                            marker + ls, lw=lw, ms=ms)
                                else:
                                    for ilm in lm:
                                        lmname = label + ' '
                                        if ilm == 1:
                                            lmname += 's'
                                        if ilm == 2:
                                            lmname += 'p_x'
                                        if ilm == 3:
                                            lmname += 'p_y'
                                        if ilm == 4:
                                            lmname += 'p_z'
                                        if ilm == 5:
                                            lmname += 'd_{x^2-y^2}'
                                        if ilm == 6:
                                            lmname += 'd_{xz}'
                                        if ilm == 7:
                                            lmname += 'd_{z^2}'
                                        if ilm == 8:
                                            lmname += 'd_{yz}'
                                        if ilm == 9:
                                            lmname += 'd_{xy}'
                                        if ilm == 10:
                                            lmname += 'f_{-3}'
                                        if ilm == 11:
                                            lmname += 'f_{-2}'
                                        if ilm == 12:
                                            lmname += 'f_{-1}'
                                        if ilm == 13:
                                            lmname += 'f_{0}'
                                        if ilm == 14:
                                            lmname += 'f_{1}'
                                        if ilm == 15:
                                            lmname += 'f_{2}'
                                        if ilm == 16:
                                            lmname += 'f_{3}'
                                        plot(tmp[:, (0)], sgn * tmp[:, (1 + ilm
                                            )], marker + ls, lw=lw, ms=ms,
                                            label=lmname)
                            elif lm == []:
                                if filled:
                                    fill_between(tmp[:, (0)], sgn * tmp[:,
                                        1:], color=color)
                                else:
                                    plot(tmp[:, (0)], sgn * tmp[:, 1:],
                                        marker + ls, color=color, lw=lw, ms=ms)
                            else:
                                for ilm in lm:
                                    lmname = label + ' '
                                    if ilm == 1:
                                        lmname += 's'
                                    if ilm == 2:
                                        lmname += 'p_x'
                                    if ilm == 3:
                                        lmname += 'p_y'
                                    if ilm == 4:
                                        lmname += 'p_z'
                                    if ilm == 5:
                                        lmname += 'd_{x^2-y^2}'
                                    if ilm == 6:
                                        lmname += 'd_{xz}'
                                    if ilm == 7:
                                        lmname += 'd_{z^2}'
                                    if ilm == 8:
                                        lmname += 'd_{yz}'
                                    if ilm == 9:
                                        lmname += 'd_{xy}'
                                    if ilm == 10:
                                        lmname += 'f_{-3}'
                                    if ilm == 11:
                                        lmname += 'f_{-2}'
                                    if ilm == 12:
                                        lmname += 'f_{-1}'
                                    if ilm == 13:
                                        lmname += 'f_{0}'
                                    if ilm == 14:
                                        lmname += 'f_{1}'
                                    if ilm == 15:
                                        lmname += 'f_{2}'
                                    if ilm == 16:
                                        lmname += 'f_{3}'
                                    plot(tmp[:, (0)], sgn * tmp[:, (1 + ilm
                                        )], marker + ls, lw=lw, ms=ms,
                                        label=lmname, color=color)
                            title(label + ' ' + i)
                    if first:
                        d = tmp
                        d[:, 1:] = d[:, 1:] * scale
                        first = False
                    else:
                        d[:, 1:] += tmp[:, 1:] * scale
    if 'eV' in units:
        ef = ef * 13.6
    if 'rel' in units:
        ef = 0
    if lm != []:
        d = d[:, ([0, 1] + list(array(lm) + 1))]
    d[:, (1)] = sum(d[:, 2:], axis=1)
    if normalized:
        d[:, 1:] = d[:, 1:] / d[:, 1:].max()
    xlab = 'E (Ry)'
    ylab = 'DOS (states/Ry)'
    if units == 'eV':
        xlab = 'E (eV)'
        ylab = 'DOS (states/eV)'
    elif units == 'eV_rel':
        xlab = 'E-E_F (eV)'
        ylab = 'DOS (states/eV)'
    elif units == 'Ry_rel':
        xlab = 'E-E_F (Ry)'
        ylab = 'DOS (states/Ry)'
    if not allatoms:
        if totonly:
            if color == '':
                if xyswitch:
                    plot(d[:, (1)], d[:, (0)] + shift, marker + ls, label=
                        label, lw=lw, ms=ms)
                else:
                    plot(d[:, (0)] + shift, d[:, (1)], marker + ls, label=
                        label, lw=lw, ms=ms)
            elif xyswitch:
                if filled:
                    fill_between(d[:, (1)], d[:, (0)] + shift, color=color,
                        label=label)
                else:
                    plot(d[:, (1)], d[:, (0)] + shift, marker + ls, color=
                        color, label=label, lw=lw, ms=ms)
            elif filled:
                fill_between(d[:, (0)] + shift, d[:, (1)], color=color,
                    label=label)
            else:
                plot(d[:, (0)] + shift, d[:, (1)], marker + ls, color=color,
                    label=label, lw=lw, ms=ms)
        else:
            if color == '':
                if xyswitch:
                    plot(d[:, 1:], d[:, (0)] + shift, marker + ls, lw=lw, ms=ms
                        )
                else:
                    plot(d[:, (0)] + shift, d[:, 1:], marker + ls, lw=lw, ms=ms
                        )
            elif xyswitch:
                if filled:
                    fill_between(d[:, (1)], d[:, (0)] + shift, color=color)
                else:
                    plot(d[:, 1:], d[:, (0)] + shift, marker + ls, color=
                        color, lw=lw, ms=ms)
            elif filled:
                fill_between(d[:, (0)] + shift, d[:, (1)], color=color)
            else:
                plot(d[:, (0)] + shift, d[:, 1:], marker + ls, color=color,
                    lw=lw, ms=ms)
            title(label)
    if not noefline:
        if color != '' and efcolor == '':
            efcolor = color
        if efcolor == '':
            if xyswitch:
                axhline(ef, ls=ls_ef, lw=lw_ef, color='grey')
            else:
                axvline(ef, ls=ls_ef, lw=lw_ef, color='grey')
        elif xyswitch:
            axhline(ef, color=efcolor, ls=ls_ef, lw=lw_ef)
        else:
            axvline(ef, color=efcolor, ls=ls_ef, lw=lw_ef)
    if xyswitch:
        ylabel(xlab)
        xlabel(ylab)
    else:
        xlabel(xlab)
        ylabel(ylab)
    if return_data:
        return d, ef


def insert_text_to(cursor, text, fmt):
    """Helper to print text, taking into account backspaces"""
    while True:
        index = text.find(chr(8))
        if index == -1:
            break
        cursor.insertText(text[:index], fmt)
        if cursor.positionInBlock() > 0:
            cursor.deletePreviousChar()
        text = text[index + 1:]
    cursor.insertText(text, fmt)


@classmethod
def _test_scheme_salt(cls, scheme):
    """
            Test if the scheme need a salt or raise BadScheme

            :param bytes scheme: A scheme
            :raises BadScheme: if ``scheme` require no salt
        """
    if scheme not in cls.schemes_salt:
        cls._raise_bad_scheme(scheme, cls.schemes_salt,
            'The scheme %r is only valid without a salt. Valide schemes with salt are %s.'
            )


@staticmethod
def __classMatch(classObj, line):
    """Returns True if the class object matches"""
    minLine = classObj.keywordLine
    maxLine = classObj.colonLine
    for decor in classObj.decorators:
        if decor.line < minLine:
            minLine = decor.line
    return line >= minLine and line <= maxLine


def is_number(obj):
    """
    evalua si es objecto es un numero

    Arguments
    ---------
    obj: any type

    Returns
    -------
    bool
        True if the object is a number
    """
    return isinstance(obj, (int, float))


@staticmethod
def _scale_quantity(symbol_details, quantity):
    """Scales the quantity for an order to the given scale

        Parameters
        ----------
        symbol_details : dict
            dictionary of details from the symbols from the symbols channel
        quantity : float
            quantity of order

        Returns
        -------
        quantity : float
            quantity of order scaled to required level
        """
    quantity = round(quantity, symbol_details['base_currency_scale'])
    return quantity


def create_customer_profile(sender, instance=None, created=False, **kwargs):
    """ A post_save signal of RecurringPayment to create a customer profile
        on payment gateway.
    """
    if (instance.id and instance.platform == 'authorizenet' and not
        instance.customer_profile_id):
        instance.add_customer_profile()


def _non_overlapping_windows(mzrs: list) ->list:
    """
    Select windows that do not overlap with other windows.
    For example: [100-200] and [200-400] (Valid for merging)

    :param mzrs: Nested list of m/z ranges / windows
    :return: Nested list of m/z ranges / windows
    """
    assert type(mzrs) == list, 'List required'
    temp = []
    for i in range(0, len(mzrs)):
        c = 0
        for j in range(0, len(mzrs)):
            if mzrs[i][0] <= mzrs[j][0] and mzrs[i][1] <= mzrs[j][0]:
                c += 1
            elif mzrs[i][0] >= mzrs[j][1] and mzrs[i][1] >= mzrs[j][1]:
                c += 1
        if c == len(mzrs) - 1:
            temp.append(mzrs[i])
    return temp


def get_values_from_tuple_list(list_of_tuples):
    """Convert a list of tuples to a set of the tuple values.

    :param list_of_tuples: List of tuples.
    :type list_of_tuples: list
    :returns: Set of values from all tuples in the list.
    :rtype: set
    """
    output_set = set()
    for tup in list_of_tuples:
        output_set.add(tup[0])
    return output_set


def get_all(isamAppliance, kdb_id, check_mode=False, force=False):
    """
    Retrieving certificate request names and details in a certificate database
    """
    return isamAppliance.invoke_get(
        'Retrieving certificate request names and details in a certificate database'
        , '/isam/ssl_certificates/{0}/cert_request'.format(kdb_id))


def properties(initial=None, editable=None, display=None):
    """ Returns the available properties
        """


def write_csv(df, filename, rounding=2):
    """
    Writes a CSV file on to the disk from the computed design matrix
    filename: To be specified by the user. Just a name is fine. .CSV extension will be added automatically.
    rounding: Number up to which decimal the output will be rounded off. Often needed for practical DOE plans.
    """
    df_copy = round(df, rounding)
    try:
        if '.csv' not in filename:
            filename = filename + '.csv'
        f = df_copy.to_csv(filename, index=False)
        return f
    except:
        return -1


def file_type(path):
    """Identifies what the type of file is."""
    signature = {'\x1f\x8b\x08': 'gz', 'BZh': 'bz2', 'PK\x03\x04': 'zip'}
    with open(path, 'r') as f:
        for sig, f_type in signature.items():
            if f.read(4).startswith(sig):
                return f_type


def register_signal(number, target, func):
    """Registers a signal handler.

    :param int number: Signal number.

    :param str|unicode target:

        * ``workers``  - run the signal handler on all the workers
        * ``workerN`` - run the signal handler only on worker N
        * ``worker/worker0`` - run the signal handler on the first available worker
        * ``active-workers`` - run the signal handlers on all the active [non-cheaped] workers

        * ``mules`` - run the signal handler on all of the mules
        * ``muleN`` - run the signal handler on mule N
        * ``mule/mule0`` - run the signal handler on the first available mule

        * ``spooler`` - run the signal on the first available spooler
        * ``farmN/farm_XXX``  - run the signal handler in the mule farm N or named XXX

        * http://uwsgi.readthedocs.io/en/latest/Signals.html#signals-targets

    :param callable func:

    :rtype: None

    :raises ValueError: If unable to register
    """


def execute_sql(cursor, sql_string, parameters=None):
    """Executes a given SQL string on an SQL cursor.
    """
    try:
        cursor.execute(sql_string, parameters)
    except Exception:
        print('sql_string:\n    {}\nparameters:\n    {}'.format(sql_string,
            parameters))
        raise
    data = []
    while True:
        row = cursor.fetchone()
        if row is None:
            break
        else:
            data.append(row)
    return data


def _increase_reg(reg):
    """
    Increase regularization factor by factor of 10.

    Parameters
    ----------
    reg: float
        Current regularization factor.

    Returns
    -------
    reg : float
        Increased regularization
    """
    if reg == 0:
        reg = 1e-06
    else:
        reg = reg * 10
    return reg