Source code for secml.core.type_utils

"""
.. module:: TypeUtils
   :synopsis: Collection of utility functions for types management

.. moduleauthor:: Marco Melis <marco.melis@unica.it>

"""
import numpy as np
from scipy.sparse import issparse

__all__ = ['is_bool', 'is_int', 'is_intlike', 'is_float', 'is_floatlike',
           'is_scalar', 'is_scalarlike', 'is_inf', 'is_posinf', 'is_neginf',
           'is_nan', 'is_list', 'is_list_of_lists',
           'is_ndarray', 'is_scsarray', 'is_slice', 'is_str', 'is_bytes',
           'is_tuple', 'is_set', 'is_dict', 'to_builtin']


[docs]def is_bool(x): return isinstance(x, (bool, np.bool_))
[docs]def is_int(x): if isinstance(x, int) and not isinstance(x, bool): # bool is a subclass of int return True elif isinstance(x, np.integer): return True return False
[docs]def is_intlike(x): """Return True if input is integer or list/array of 1 integer. Examples -------- >>> from secml.core.type_utils import is_intlike >>> print(is_intlike(0)) # Standard int True >>> print(is_intlike(0.1)) # Standard float False >>> print(is_intlike(np.array([0]))) # ndarray with one int True >>> print(is_intlike(np.array([0.1]))) # ndarray with one float False """ if is_int(x): return True # built-in or numpy integers elif (is_list(x) and len(x) == 1 and is_int(x[0])) or \ (is_ndarray(x) and x.size == 1 and x.dtype.kind in ('i', 'u')): return True else: return False
[docs]def is_float(x): return isinstance(x, (float, np.floating))
[docs]def is_floatlike(x): """Return True if input is float or list/array of 1 float. Examples -------- >>> from secml.core.type_utils import is_floatlike >>> print(is_floatlike(0.1)) # Standard float True >>> print(is_floatlike(0)) # Standard int False >>> print(is_floatlike(np.array([0.1]))) # ndarray with one float True >>> print(is_floatlike(np.array([0]))) # ndarray with one int False """ if is_float(x): return True # built-in or numpy floats elif (is_list(x) and len(x) == 1 and is_float(x[0])) or \ (is_ndarray(x) and x.size == 1 and x.dtype.kind in ('f')): return True else: return False
[docs]def is_scalar(x): """True if input is integer or float.""" return is_int(x) or is_float(x)
[docs]def is_scalarlike(x): """True if input is scalar (int or float) or list/array of 1 real.""" return is_intlike(x) or is_floatlike(x)
[docs]def is_inf(x): """True if input is a positive/negative infinity. Parameters ---------- x : scalar Examples -------- >>> from secml.core.type_utils import is_inf >>> from secml.core.constants import inf, nan >>> print(is_inf(inf)) True >>> print(is_inf(-inf)) True >>> print(is_inf(nan)) False >>> print(is_inf(0.1)) False >>> from secml.array import CArray >>> print(is_inf(CArray([inf]))) # Use `CArray.is_inf()` instead Traceback (most recent call last): ... TypeError: input must be a scalar. """ if not is_scalar(x): raise TypeError("input must be a scalar.") return np.isinf(x)
[docs]def is_posinf(x): """True if input is a positive infinity. Parameters ---------- x : scalar Examples -------- >>> from secml.core.type_utils import is_posinf >>> from secml.core.constants import inf, nan >>> print(is_posinf(inf)) True >>> print(is_posinf(-inf)) False >>> from secml.array import CArray >>> print(is_posinf(CArray([inf]))) # Use `CArray.is_posinf()` instead Traceback (most recent call last): ... TypeError: input must be a scalar. """ if not is_scalar(x): raise TypeError("input must be a scalar.") return np.isposinf(x)
[docs]def is_neginf(x): """True if input is a negative infinity. Parameters ---------- x : scalar Examples -------- >>> from secml.core.type_utils import is_neginf >>> from secml.core.constants import inf, nan >>> print(is_neginf(-inf)) True >>> print(is_neginf(inf)) False >>> from secml.array import CArray >>> print(is_neginf(CArray([-inf]))) # Use `CArray.is_neginf()` instead Traceback (most recent call last): ... TypeError: input must be a scalar. """ if not is_scalar(x): raise TypeError("input must be a scalar.") return np.isneginf(x)
[docs]def is_nan(x): """True if input is Not a Number (NaN). Parameters ---------- x : scalar Notes ----- NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic (IEEE 754). This means that Not a Number is not equivalent to infinity. Examples -------- >>> from secml.core.type_utils import is_nan >>> from secml.core.constants import inf, nan >>> print(is_nan(nan)) True >>> print(is_nan(inf)) False >>> print(is_nan(0.1)) False >>> from secml.array import CArray >>> print(is_neginf(CArray([nan]))) # Use `CArray.is_nan()` instead Traceback (most recent call last): ... TypeError: input must be a scalar. """ if not is_scalar(x): raise TypeError("input must be a scalar.") return np.isnan(x)
[docs]def is_list(x): return isinstance(x, list)
[docs]def is_list_of_lists(x): """Return True if input is a list of lists, otherwise False. Examples -------- >>> is_list_of_lists([[1, 2], [3]]) True >>> is_list_of_lists([[1], 2, [3]]) False >>> is_list_of_lists([]) False """ if not is_list(x): # Not a list return False elif len(x) == 0: # Empty list return False elif any(not is_list(elem) for elem in x): # One or more elems not lists return False return True
[docs]def is_ndarray(x): return isinstance(x, np.ndarray)
[docs]def is_scsarray(x): """Returns True if input is a scipy.sparse array.""" return issparse(x)
[docs]def is_slice(x): return isinstance(x, slice)
[docs]def is_str(x): # text unicode strings if isinstance(x, str): return True elif isinstance(x, (np.str_, np.unicode_)): return True return False
[docs]def is_bytes(x): # byte strings if isinstance(x, (bytes, np.bytes_)): return True return False
[docs]def is_tuple(x): return isinstance(x, tuple)
[docs]def is_set(x): return isinstance(x, set)
[docs]def is_dict(x): return isinstance(x, dict)
[docs]def to_builtin(x): """Convert input to the corresponding built-in type. Works with the following types: - `bool`, `np.bool_` -> `bool` - `int`, `np.integer` -> `int` - `float, `np.floating` -> `float` - `str`, `np.str_`, `np.unicode_` -> `str` - `bytes`, `np.bytes_` -> `bytes` """ if is_bool(x): # Covers bool, np.bool_ return bool(x) elif is_int(x): # Covers int, np.integer return int(x) elif is_float(x): # Covers float, np.floating return float(x) elif is_str(x): # Covers str, np.str_, np.unicode_ return str(x) elif is_bytes(x): # Covers bytes, np.bytes_ return bytes(x) else: raise TypeError("objects of type {:} not supported.".format(type(x)))