def swap_element(element, new_class):
    """
    A "trick" to swap the element type.

    Used in certain cases where the underlaying element type
    may change.
    """
    if element.__class__ is not new_class:
        element.__class__ = new_class


def getAllImages():
    """
    Function generating a script to extract all image tags of a web page.

    @return script to extract image tags
    @rtype str
    """
    source = """
(function() {
    var out = [];
    var imgs = document.getElementsByTagName('img');
    for (var i = 0; i < imgs.length; ++i) {
        var e = imgs[i];
        out.push({
            src: e.src,
            alt: e.alt
        });
    }
    return out;
})()"""
    return source


@classmethod
def check_version_is_equal_or_higher(cls, version, cmp_major, cmp_minor):
    """
        Checks if the version is equal or higher than a specified value.

        :param int version: Version number to be checked.
        :param int cmp_major: Major version to be compared with.
        :param int cmp_minor: Minor version to be compared with.
        :return: True if equal or higher, otherwise False.
        :rtype: bool
        """
    return cls.convert_to_major_ver(version
        ) > cmp_major or cls.convert_to_major_ver(version
        ) == cmp_major and cls.convert_to_minor_ver(version) >= cmp_minor


def pretty_bytes(byte_value, base_shift=0):
    """Pretty-print the given bytes value.

    Args:
      byte_value (float): Value
      base_shift (int): Base value of byte_value
            (0 = bytes, 1 = KiB, 2 = MiB, etc.)

    Returns:
      str: Pretty-printed byte string such as "1.00 GiB"

    Examples:
      ::

        >>> pretty_bytes(512)
        '512 B'
        >>> pretty_bytes(512, 2)
        '512 MiB'
        >>> pretty_bytes(65536, 2)
        '64 GiB'
        >>> pretty_bytes(65547)
        '64.01 KiB'
        >>> pretty_bytes(65530, 3)
        '63.99 TiB'
        >>> pretty_bytes(1023850)
        '999.9 KiB'
        >>> pretty_bytes(1024000)
        '1000 KiB'
        >>> pretty_bytes(1048575)
        '1024 KiB'
        >>> pretty_bytes(1049200)
        '1.001 MiB'
        >>> pretty_bytes(2560)
        '2.5 KiB'
        >>> pretty_bytes(.0001, 3)
        '104.9 KiB'
        >>> pretty_bytes(.01, 1)
        '10 B'
        >>> pretty_bytes(.001, 1)
        '1 B'
        >>> pretty_bytes(.0001, 1)
        '0 B'
        >>> pretty_bytes(100, -1)
        Traceback (most recent call last):
            ...
        ValueError: base_shift must not be negative
    """
    if base_shift < 0:
        raise ValueError('base_shift must not be negative')
    tags = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
    byte_value = float(byte_value)
    shift = base_shift
    while byte_value >= 1024.0:
        byte_value /= 1024.0
        shift += 1
    while byte_value < 1.0 and shift > 0:
        byte_value *= 1024.0
        shift -= 1
    if shift == 0:
        byte_value = round(byte_value)
    return '{0:.4g} {1}'.format(byte_value, tags[shift])


def hex2bin(hexstr):
    """Convert a hexdecimal string to binary string, with zero fillings. """
    length = len(hexstr) * 4
    msgbin = bin(int(hexstr, 16))[2:]
    while len(msgbin) < length:
        msgbin = '0' + msgbin
    return msgbin


def bind_hass(func):
    """Decorate function to indicate that first argument is hass."""
    func.__bind_hass = True
    return func


@classmethod
def unregister(cls, name):
    """Remove a codec from the registry.

        Unregisters the codec with the given `name` (a string).  If the codec
        is not registered, a `KeyError` is raised.

        >>> import binascii
        >>> CodecReg.register('uu', binascii.b2a_uu, binascii.a2b_uu)
        >>> 'uu' in CodecReg
        True
        >>> CodecReg.unregister('uu')
        >>> 'uu' in CodecReg
        False
        """
    del cls._codecs[name]


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

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

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


def cbrt(x):
    """Return the cube root of x."""
    return x ** (1 / 3)


def unpack_varint(data, pointer=0):
    """
    Unpacks a variable length integer.
    """
    integer, shift = 0, 0
    while True:
        integer |= (data[pointer] & 127) << shift
        if not data[pointer] & 128:
            break
        pointer += 1
        shift += 7
    return pointer + 1, integer


def plotmatrix(X):
    """
    Creates a matrix of marginal plots.

    On diagonal, are marginal plots of each variable. Off-diagonal plot (i,j)
    shows the joint marginal density of x_i and x_j.
    """
    return X.plotmatrix()


@classmethod
def deserialize(cls, client, event_data={}):
    """
        Deserializes Event data from dictionary
        """
    return cls(client, **event_data)


def rect_compare(rect1, rect2, area):
    """Calculate the ratio of overlap between two rectangles and the given area

    :param rect1: rectangle specified as (x, y, w, h)
    :type rect1: tuple
    :param rect2: rectangle specificed as (x, y, w, h)
    :type rect2: tuple
    :param area: the area to compare to
    :type area: float
    :return: the ratio of the overlap of rect1 and rect2 to the area, e.g overlap(rect1, rect2)/area
    :rtype: float
    """
    xx1 = max(rect1[0], rect2[0])
    yy1 = max(rect1[1], rect2[1])
    xx2 = min(rect1[0] + rect1[2], rect2[0] + rect2[2])
    yy2 = min(rect1[1] + rect1[3], rect2[1] + rect2[3])
    w = max(0, xx2 - xx1 + 1)
    h = max(0, yy2 - yy1 + 1)
    return float(w * h) / area


def _no_self_loops(array, return_test=False):
    """
    Remove self-loops
    """
    test = array[:, (0)] != array[:, (1)]
    if return_test:
        return array[(test), :].astype(int), test
    return array[(test), :].astype(int)


def generate(path, request, **kw):
    """ Generate a URL for the given path """


@classmethod
def subscriptions(cls, options=None):
    """Import or export subscriptions

        Usage::

            hammer csv subscriptions [OPTIONS]

        Options::

            --continue-on-error           Continue processing even if
                                          individual resource error
            --export                      Export current data instead of
                                          importing
            --file FILE_NAME              CSV file (default to /dev/stdout with
                                          --export, otherwise required)
            --organization ORGANIZATION   Only process organization matching
                                          this name
            --search SEARCH               Only export search results
        """
    cls.command_sub = 'subscriptions'
    return cls.execute(cls._construct_command(options))


@classmethod
def get_child_class(cls, tagname):
    """Returns the child class where the tagname can be added. For example
        if it's an element of list return the list class.
        """
    for c in cls.children_classes:
        for tn in c._get_creatable_class_by_tagnames():
            if tn == tagname:
                return c


def register(id, modifier, pos=-1):
    """Registers a before save and after retrieve modifier.

        If no 'pos' argument is passed the modifier gets added at the
        end of the registry.
        """


def blend_shapes(baseShape, defaultShape):
    """Replace wildcards in one shape with entries of the other.

    :param baseShape: Primary shape, usually with wildcards.
    :type baseShape: tuple(int or None)
    :param defaultShape: Secondary shape with fallback entries.
    :type defaultShape: tuple(int or None)
    """
    return defaultShape[0] if baseShape[0] is None else baseShape[0
        ], defaultShape[1] if baseShape[1] is None else baseShape[1]


def lookupSymmetricDict(dists, a, b):
    """dists[a,b] or dists[b,a], whichever is present, so long as they
    don't contradict each other"""
    v1 = dists.get((a, b), None)
    v2 = dists.get((b, a), None)
    if v1 is None and v2 is None:
        raise KeyError((a, b))
    elif v1 is None or v2 is None or v1 == v2:
        return v1 or v2
    else:
        raise ValueError('d[%s,%s] != d[%s,%s]' % (a, b, b, a))


def slice_(array, start=0, end=None):
    """Slices `array` from the `start` index up to, but not including, the
    `end` index.

    Args:
        array (list): Array to slice.
        start (int, optional): Start index. Defaults to ``0``.
        end (int, optional): End index. Defaults to selecting the value at
            ``start`` index.

    Returns:
        list: Sliced list.

    Example:

        >>> slice_([1, 2, 3, 4])
        [1]
        >>> slice_([1, 2, 3, 4], 1)
        [2]
        >>> slice_([1, 2, 3, 4], 1, 3)
        [2, 3]

    .. versionadded:: 1.1.0
    """
    if end is None:
        end = start + 1 if start >= 0 else len(array) + start + 1
    return array[start:end]


@classmethod
def get_urlpath(cls):
    """Identify the object by slug or pk in the pattern."""
    return '<{}>/{}'.format(cls.urlfield, cls.urlname)


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

        :param LegalHoldsAddMembersDetails val:
        :rtype: EventDetails
        """
    return cls('legal_holds_add_members_details', val)


@classmethod
def _maybe_remove_pool(cls, pid):
    """If the pool has no open connections, remove it

        :param str pid: The pool id to clean

        """
    if not len(cls._pools[pid]):
        del cls._pools[pid]


def sort_group_connected(group):
    """Sort by number of connected contacts"""
    return -group.get_nb_connected_contacts()


def status_to_str(status_code):
    """
    Translates an int status code to a string that represents the status

    Args:
        status_code (int): the code of the status

    Returns:
        str: the string that represents the status
    """
    statuses = {(10): 'TAXI_WAITING', (11): 'TAXI_MOVING_TO_PASSENGER', (12
        ): 'TAXI_IN_PASSENGER_PLACE', (13): 'TAXI_MOVING_TO_DESTINATION', (
        14): 'TAXI_WAITING_FOR_APPROVAL', (20): 'PASSENGER_WAITING', (21):
        'PASSENGER_IN_TAXI', (22): 'PASSENGER_IN_DESTINATION', (23):
        'PASSENGER_LOCATION', (24): 'PASSENGER_ASSIGNED'}
    if status_code in statuses:
        return statuses[status_code]
    return status_code


@staticmethod
def defaultPrivateMessageError():
    """The default function that gives an error when a `Command` is trying to be run in a Private Message but can't.
        """
    return 'You cannot run this command in a Private Message.'


def convert_to_string(data):
    """Convert a data value into a string.

    :param data: The data value to convert to a string.
    :returns: The string value of 'data' if data is not None
    """
    if data is not None:
        return str(data)


def get_new_obj(obj, klass, attributes):
    """
    Pass attributes from the existing object 'obj' and attributes
    dictionary to a 'klass' constructor.
    Attributes from 'attributes' dictionary are only passed to the
    constructor if they are not None.
    """
    kwargs = {}
    for key, value in list(obj.__dict__.items()):
        if isinstance(value, dict):
            kwargs[key] = value.copy()
        elif isinstance(value, (tuple, list)):
            kwargs[key] = value[:]
        else:
            kwargs[key] = value
    for key, value in list(attributes.items()):
        if value is None:
            continue
        if isinstance(value, dict):
            kwargs_value = kwargs.get(key, {})
            for key1, value2 in list(value.items()):
                if value2 is None:
                    continue
                kwargs_value[key1] = value2
            kwargs[key] = kwargs_value
        else:
            kwargs[key] = value
    return klass(**kwargs)


def to_string(unit_system: str, unit_category: str, value: float, precision:
    int=3, split_unit: bool=False, compatible_unit: bool=False) ->str:
    """Convert a given input float value into a string with units.

    :param unit_system: The unit system, from bpy.utils.units.systems.
    :type unit_system: str
    :param unit_category: The category of data we are converting (length, area, rotation, etc.), from bpy.utils.units.categories.
    :type unit_category: str
    :param value: The value to convert to a string.
    :type value: float
    :param precision: Number of digits after the comma.
    :type precision: int
    :param split_unit: Whether to use several units if needed (1m1cm), or always only one (1.01m).
    :type split_unit: bool
    :param compatible_unit: Whether to use keyboard-friendly units (1m2) or nicer utf-8 ones (1m²).
    :type compatible_unit: bool
    :return:  The converted string.
    """
    pass


def strip_zip_suffix(filename):
    """
    Helper function to strip suffix from filename.

    :param filename: This field is the name of file.
    """
    if filename.endswith('.gz'):
        return filename[:-3]
    elif filename.endswith('.bz2'):
        return filename[:-4]
    else:
        return filename


def formula_2018_01_01(foyer_fiscal, period, parameters):
    """
        Les assiettes des plus-values du PFU doivent être brutes (et non nettes)
        """
    f3sa = foyer_fiscal('f3sa', period)
    f3vg = foyer_fiscal('f3vg', period)
    f3ua = foyer_fiscal('f3ua', period)
    return f3sa + f3vg + f3ua


def angle(coordo):
    """Angle pour placer le nom du point en fonction du quadrant"""
    l = []
    for coord in coordo:
        if coord[0] >= 0 and coord[1] >= 0:
            ang = '45'
        if coord[0] >= 0 and coord[1] < 0:
            ang = '-45'
        if coord[0] < 0 and coord[1] < 0:
            ang = '-135'
        if coord[0] < 0 and coord[1] >= 0:
            ang = '135'
        l.append(ang)
    return l


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

        :param SharedLinkCreateType val:
        :rtype: EventType
        """
    return cls('shared_link_create', val)


@classmethod
def set_creator(cls, obj, creator):
    """
        Set the creator of an object.  This should no typically be called by user code.

        :param obj: the object to set the creator of
        :type obj: mincepy.SavableObject
        :param creator: the creating object
        :type creator: mincepy.SavableObject
        """
    cls._creators[obj] = creator


def filter_payload(payload: str) ->str:
    """ Convert payload to text and search for not allowed symbols. """
    import re
    if not isinstance(payload, str):
        payload = str(payload)
    if re.search('[^_A-z0-9-]', payload):
        message = (
            'Wrong payload! Only A-Z, a-z, 0-9, _ and - are allowed. We recommend to encode parameters with binary and other types of content.'
            )
        raise ValueError(message)
    return payload


def fuzzy_not(v):
    """
    Not in fuzzy logic

    Return None if `v` is None else `not v`.

    Examples
    ========

    >>> from sympy.core.logic import fuzzy_not
    >>> fuzzy_not(True)
    False
    >>> fuzzy_not(None)
    >>> fuzzy_not(False)
    True

    """
    if v is None:
        return v
    else:
        return not v


@staticmethod
def make(id, client, cls, parent_id=None, json=None):
    """
        Makes an api object based on an id and class.

        :param id: The id of the object to create
        :param client: The LinodeClient to give the new object
        :param cls: The class type to instantiate
        :param parent_id: The parent id for derived classes
        :param json: The JSON to use to populate the new class

        :returns: An instance of cls with the given id
        """
    from .dbase import DerivedBase
    if issubclass(cls, DerivedBase):
        return cls(client, id, parent_id, json)
    else:
        return cls(client, id, json)


def read_into_lines_list(path, n=0):
    """
    Take a file and store all of its content into a list
    The n allow to skip the n number of lines

    Return a list of string
    """
    content = []
    with open(path, 'r') as file:
        content = file.readlines()
    return content[n:]


def getServerPrincipalDetails(service, hostname):
    """
    This function returns the service principal for the server given a service type
    and hostname. Details are looked up via the /etc/keytab file.

    @param service:       a string containing the Kerberos service type for the server.
    @param hostname:      a string containing the hostname of the server.
    @return:              a string containing the service principal.
    """
    raise NotImplementedError


def p_subfield_separator(p):
    """
    subfield_separator : COLON
                       | NEWLINE
                       | "/"
                       | ","
    """
    p[0] = p[1]


def unflatten(obj):
    """
    >>> unflatten(100)
    (100,)
    >>> unflatten(tuple([100]))
    (100,)
    :param obj:
    :return: a tuple or list
    """
    if isinstance(obj, (tuple, list)):
        return obj
    return obj,


@staticmethod
def _truncate(value, arg):
    """
        Truncates a string after a given number of chars
        Argument: Number of chars to _truncate after
        """
    length = int(arg)
    if value is None:
        value = ''
    if len(value) > length:
        return value[:length] + '...'
    else:
        return value


def add_height_to_species(spcs, height=None):
    """Add to a string (spcs) a height using the ESX header friendly format
        ex: O3  =>  O3:42m
    """
    if height is None:
        height = ''
    elif type(height) == 'int':
        height = str(height) + 'm'
    return spcs + ':' + height


@staticmethod
def p_env_var_name(p):
    """env_var_name : IDENT"""
    p[0] = p[1]


def normalize_user_enum_type(value):
    """
    Enum type references shall be rendered using their enumeration type name.
    """
    return value.__name__


def format_time_delta(delta):
    """Format a timedelta object into a human readable representation."""
    s = delta.seconds
    hours = s // 3600
    s -= hours * 3600
    minutes = s // 60
    s -= minutes * 60
    return '{:02d}:{:02d}:{:02d}'.format(hours, minutes, s)


def multi_mode_write(buffer_writer, string_writer, buffer_or_path=None):
    """
    Get a StringIO from different type of inputs.

    Parameters
    ----------
    buffer_writer
    string_writer
    buffer_or_path

    Returns
    -------
    typing.StringIO
    """
    if buffer_or_path is None:
        return string_writer()
    if isinstance(buffer_or_path, str):
        buffer = open(buffer_or_path, 'w')
    else:
        buffer = buffer_or_path
    with buffer:
        buffer_writer(buffer)


def trial(env):
    """
    See the game running in action

    :param environment: Game Environment Gym
    """
    for i_episode in range(20):
        observation = env.reset()
        for t in range(100):
            env.render()
            print(observation)
            action = env.action_space.sample()
            observation, reward, done, info = env.step(action)
            if done:
                print('Episode finished after {} timesteps'.format(t + 1))
                break
    env.close()


def sparse_matrix_mean(sparse_matrix):
    """A mean calculation for sparse matrices that does not count the zero elements.
       So it calculates the mean of the hierarchical differences over the all incoming edges"""
    if sparse_matrix.sum() == 0:
        return 0
    else:
        return sparse_matrix.sum() / float(sparse_matrix.getnnz())


def create_activity(p_dict):
    """Creates activity"""
    p_dict['uuid'] = 'cfa07a4f-d446-4078-8d73-2f77560c35c0'
    p_dict['created_at'] = '2013-07-27'
    p_dict['updated_at'] = None
    p_dict['deleted_at'] = None
    p_dict['revision'] = 1
    return p_dict


def flip_names():
    """Flips (and corrects) the axis suffixes of the names of selected bones

    """
    pass


@staticmethod
def serializable() ->bool:
    """ Whether or not this class supports state serialization.

        (This always returns True for TicTacToe)

        Returns
        -------
        is_serializable : bool
            True
        """
    return True


@staticmethod
def _mark_coreference(word, coreference_string):
    """ Append to a word a coreference string
        :param word: The word that forms part of a mention
        :param coreference_string: The coreference string
        """
    if 'coreference' not in word:
        word['coreference'] = [coreference_string]
    else:
        word['coreference'].append(coreference_string)


@classmethod
def _validate_dict_argument(cls, name, value, allowed_keys,
    require_same_keys=False):
    """Check if an argument is an dictionary with correct key set"""
    if value is None:
        return
    if not isinstance(value, dict):
        raise ValueError("Argument '{}' must be a dictionary using {} as keys"
            .format(name, allowed_keys))
    value_keys = sorted(value.keys())
    if require_same_keys:
        if value_keys != allowed_keys:
            raise ValueError("The keys of argument '{}' must be the same as {}"
                .format(name, allowed_keys))
    elif not set(value_keys).issubset(set(allowed_keys)):
        raise ValueError("The keys of argument '{}' must be a subset of {}"
            .format(name, allowed_keys))


def _add_type(dictionary, id_, type_):
    """Short description.

    Parameters
    ----------
    Compounds : dict
    id_ : str
    content :
    """
    dictionary[id_]['types'].append(type_)


def output_file_remove_active_socket():
    """Remove active input from a file output node

    """
    pass


@classmethod
def lookupInternal(cls, name):
    """Looks up an API function by name.

    Args:
      name: The name of the function to get.

    Returns:
      The requested ApiFunction or None if not found.
    """
    cls.initialize()
    return cls._api.get(name, None)


def parse_image_meta_graph(meta):
    """Parses a tensor that contains image attributes to its components.
    See compose_image_meta() for more details.

    meta: [batch, meta length] where meta length depends on NUM_CLASSES

    Returns a dict of the parsed tensors.
    """
    image_id = meta[:, (0)]
    original_image_shape = meta[:, 1:4]
    image_shape = meta[:, 4:7]
    window = meta[:, 7:11]
    scale = meta[:, (11)]
    active_class_ids = meta[:, 12:]
    return {'image_id': image_id, 'original_image_shape':
        original_image_shape, 'image_shape': image_shape, 'window': window,
        'scale': scale, 'active_class_ids': active_class_ids}


def _expand_classname(classname):
    """
    Split a single class name at the `.` operator, and build a list of classes.

    E.g. 'a.b.c' becomes ['a', 'a.b', 'a.b.c']
    """
    result = []
    parts = classname.split('.')
    for i in range(1, len(parts) + 1):
        result.append('.'.join(parts[:i]).lower())
    return result


def _gen_closest_index(x, points):
    """
    Generates the closes index to the point x.

    Not that this is not a hard index, but may vary up to +/- 1 in each dim.

    Parameters
    ----------
    x : list
        The [0, 1] hypercube coordinates for x.
    points : int
        The number of points in each dimension.

    Returns
    -------
    closest_index : tuple
        Indexing tuple for the closest point.
    """
    closest_index = []
    for i in range(len(x)):
        closest_index.append(int(x[i] * points))
    return tuple(closest_index)


def get_name():
    """
    Return this driver's name
    """
    return 's3'


def list_tags_for_resource(resourceArn=None):
    """
    Lists all tags associated with an assessment template.
    See also: AWS API Documentation

    Examples
    Lists all tags associated with an assessment template.
    Expected Output:

    :example: response = client.list_tags_for_resource(
        resourceArn='string'
    )

    :type resourceArn: string
    :param resourceArn: [REQUIRED]
            The ARN that specifies the assessment template whose tags you want to list.

    :rtype: dict
    :return: {
        'tags': [
            {
                'key': 'string',
                'value': 'string'
            },
        ]
    }

    """
    pass


def view_center_pick():
    """Center the view to the Z-depth position under the mouse cursor

    """
    pass


def paginate_articles(articles, per_page=30):
    """Set a page number for each article"""
    current_page = 1
    i = 0
    for article in articles.values():
        if i >= per_page:
            i = 0
            current_page += 1
        article['page_number'] = current_page
        i += 1
    return current_page


@staticmethod
def deserialize_event(store_event):
    """
        Convert client/db event model/data into an Event instance
        """
    return store_event


def isinstance2(obj, t):
    """
  Patched isinstance method to disable bool-is-int inheritance.

  >>> isinstance2( True, bool )
  True
  >>> isinstance2( True, int )
  False

  """
    if isinstance(t, (tuple, list)):
        need_bool = bool in t
        need_int = int in t
    else:
        need_bool = t is bool
        need_int = t is int
    res = isinstance(obj, t)
    if not need_bool and need_int:
        res &= not isinstance(obj, bool)
    return res


def overrides_method(method_name, obj, base):
    """
    Return True if the named base class method is overridden by obj.

    Parameters
    ----------
    method_name : str
        Name of the method to search for.
    obj : object
        An object that is assumed to inherit from base.
    base : class
        The base class that contains the base version of the named
        method.

    Returns
    -------
    bool
        True if the named base clas is overridden by the given obj, otherwise
        False.
    """
    for klass in obj.__class__.__mro__:
        if method_name in klass.__dict__:
            return klass is not base
    return False


def cr_uid(method):
    """ Decorate a traditional-style method that takes ``cr``, ``uid`` as parameters. """
    method._api = 'cr_uid'
    return method


@classmethod
def list_by_node_id(cls, context, node_id, limit=None, marker=None,
    sort_key=None, sort_dir=None):
    """Return a list of Portgroup objects associated with a given node ID.

        :param cls: the :class:`Portgroup`
        :param context: Security context.
        :param node_id: The ID of the node.
        :param limit: Maximum number of resources to return in a single result.
        :param marker: Pagination marker for large data sets.
        :param sort_key: Column to sort results by.
        :param sort_dir: Direction to sort. "asc" or "desc".
        :returns: A list of :class:`Portgroup` object.
        :raises: InvalidParameterValue

        """
    db_portgroups = cls.dbapi.get_portgroups_by_node_id(node_id, limit=
        limit, marker=marker, sort_key=sort_key, sort_dir=sort_dir)
    return cls._from_db_object_list(context, db_portgroups)


def try_int(s):
    """Convert to integer if possible."""
    try:
        return int(s)
    except:
        return s


def iface(cls):
    """Interfaces are for documentation purposes only."""
    return None


def semiflatten(multi):
    """Convert a MutiDict into a regular dict. If there are more than one value
    for a key, the result will have a list of values for the key. Otherwise it
    will have the plain value."""
    if multi:
        result = multi.to_dict(flat=False)
        for k, v in result.items():
            if len(v) == 1:
                result[k] = v[0]
        return result
    else:
        return multi


def is_non_strict_type(type1, compare_type):
    """
    Returns true if the given type is the same as a comparison type but does it less rigorous than issubclass().
    The main advantage is that classes of modules which where reloaded during runtime are still recognized.
    WARNING: If the name of a class in a different module is the same as in the module in question, this method will
    still return true.
    :param type1: type in question
    :param compare_type: type to compare the type in question to
    :return: True or False
    """
    if isinstance(type1, type) and type1.__name__ == compare_type.__name__:
        return True
    else:
        return False


def progress_bar(prog, mesg='Please wait...'):
    """
    progressbar(prog, mesg='Please wait...')

    Presents a nice progress bar and a text message.

    Original code by user aviraldg on StackOverflow:
    http://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console
    """
    print(' ' * int(40), end='')
    print('\r[{0}{1}] {2}% - '.format('#' * int(prog / 10), ' ' * int((100 -
        prog) / 10), prog) + str(mesg), end='')
    return None


@classmethod
def from_existing_session(cls, session: object, driver_options: str=None
    ) ->'Core':
    """Creates a new Core object with the entered 'session' reused."""
    return cls(None, False, False, driver_options, None, session)


def getCpuCount():
    """Get the number of cpu available in the system."""
    import multiprocessing
    return multiprocessing.cpu_count()


def get_swagger_version(obj):
    """ get swagger version from loaded json """
    if isinstance(obj, dict):
        if 'swaggerVersion' in obj:
            return obj['swaggerVersion']
        elif 'swagger' in obj:
            return obj['swagger']
        elif 'openapi' in obj:
            return obj['openapi']
        return None
    else:
        return obj.swaggerVersion if hasattr(obj, 'swaggerVersion'
            ) else obj.swagger


def check_skip_material(mat):
    """Simple helper to check whether we actually support exporting that material or not"""
    return mat.type not in {'SURFACE'} or mat.use_nodes


def format_node(cluster_name, node):
    """Formats a string representation of a node."""
    return '<{0}[{1}]>'.format(cluster_name, node)


def msgparse(msg):
    """
    .. deprecated:: 0.0.12

    This function returns the NMEA message variables shared by both RMC and GGA.

    :param pynmea2.nmea.NMEASentence msg: A pynmea2 sentence object.
    :rtype: :py:class:`datetime.datetime`, :py:class:`float`, :py:class:`float`
    """
    return msg.timestamp, msg.latitude, msg.longitude


def generate_image_master(categories: list) ->dict:
    """
    Takes in the list of categories and images
    and generate a master dictionary containing all of the images
    :param categories:
    :return:
    """
    master_dict = {}
    for category in categories:
        master_dict = {**master_dict, **category.get_images()}
    return master_dict


def expand(recursive=False):
    """Expand this node.

        'recursive' can be set to True to expand all child nodes as
        well
        """


def is_empty_resource(_res):
    """Check if resource contains any files"""
    f_count = 0
    for f_in in _res.files().fetchall('obj'):
        f_count += 1
        break
    return f_count == 0


@staticmethod
def rollback_action(args, kwargs, was_interrupted, result=None):
    """
        This static method shall determine and undo all the changes made by a previous
        :meth:`process_action` call.
        If :meth:`process_action` was interrupted by a crash or an exception, *was_interrupted*
        is True, and *result* is None. Else, result is the value (if any) which was returned by the
        meth:`process_action` call - this might be an appreciable hint in some circumstances.
        In any case, args and kwargs are the list and dict which contain the arguments with which
        :meth:`process_action` was called.
        In case of trouble preventing the rollback, this method shall raise an exception.
        No return value is expected.
        """
    raise NotImplementedError()


@classmethod
def sanitize_model(cls, instance):
    """
        This method is called, before the model is saved to the database. It can be overloaded to sanitize the current
        (_json) data dict of the instance.
        """
    if instance.data is None:
        instance.data = {}


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 class_repr(value):
    """Returns a representation of the value class.

    Arguments
    ---------
    value
        A class or a class instance

    Returns
    -------
    str
        The "module.name" representation of the value class.

    Example
    -------
    >>> from datetime import date
    >>> class_repr(date)
    'datetime.date'
    >>> class_repr(date.today())
    'datetime.date'
    """
    klass = value
    if not isinstance(value, type):
        klass = klass.__class__
    return '.'.join([klass.__module__, klass.__name__])


def p_expression_and(p):
    """expression : expression AND expression"""
    p[0] = p[1] & p[3]


@staticmethod
def is_required(field):
    """ Return True is field's value should be defined.

        :return bool:

        """
    return True


def create_launch_configuration(LaunchConfigurationName=None, ImageId=None,
    KeyName=None, SecurityGroups=None, ClassicLinkVPCId=None,
    ClassicLinkVPCSecurityGroups=None, UserData=None, InstanceId=None,
    InstanceType=None, KernelId=None, RamdiskId=None, BlockDeviceMappings=
    None, InstanceMonitoring=None, SpotPrice=None, IamInstanceProfile=None,
    EbsOptimized=None, AssociatePublicIpAddress=None, PlacementTenancy=None):
    """
    Creates a launch configuration.
    If you exceed your maximum limit of launch configurations, which by default is 100 per region, the call fails. For information about viewing and updating this limit, see  DescribeAccountLimits .
    For more information, see Launch Configurations in the Auto Scaling User Guide .
    See also: AWS API Documentation

    Examples
    This example creates a launch configuration.
    Expected Output:

    :example: response = client.create_launch_configuration(
        LaunchConfigurationName='string',
        ImageId='string',
        KeyName='string',
        SecurityGroups=[
            'string',
        ],
        ClassicLinkVPCId='string',
        ClassicLinkVPCSecurityGroups=[
            'string',
        ],
        UserData='string',
        InstanceId='string',
        InstanceType='string',
        KernelId='string',
        RamdiskId='string',
        BlockDeviceMappings=[
            {
                'VirtualName': 'string',
                'DeviceName': 'string',
                'Ebs': {
                    'SnapshotId': 'string',
                    'VolumeSize': 123,
                    'VolumeType': 'string',
                    'DeleteOnTermination': True|False,
                    'Iops': 123,
                    'Encrypted': True|False
                },
                'NoDevice': True|False
            },
        ],
        InstanceMonitoring={
            'Enabled': True|False
        },
        SpotPrice='string',
        IamInstanceProfile='string',
        EbsOptimized=True|False,
        AssociatePublicIpAddress=True|False,
        PlacementTenancy='string'
    )

    :type LaunchConfigurationName: string
    :param LaunchConfigurationName: [REQUIRED]
            The name of the launch configuration. This name must be unique within the scope of your AWS account.

    :type ImageId: string
    :param ImageId: The ID of the Amazon Machine Image (AMI) to use to launch your EC2 instances.
            If you do not specify InstanceId , you must specify ImageId .
            For more information, see Finding an AMI in the Amazon Elastic Compute Cloud User Guide .

    :type KeyName: string
    :param KeyName: The name of the key pair. For more information, see Amazon EC2 Key Pairs in the Amazon Elastic Compute Cloud User Guide .

    :type SecurityGroups: list
    :param SecurityGroups: One or more security groups with which to associate the instances.
            If your instances are launched in EC2-Classic, you can either specify security group names or the security group IDs. For more information about security groups for EC2-Classic, see Amazon EC2 Security Groups in the Amazon Elastic Compute Cloud User Guide .
            If your instances are launched into a VPC, specify security group IDs. For more information, see Security Groups for Your VPC in the Amazon Virtual Private Cloud User Guide .
            (string) --

    :type ClassicLinkVPCId: string
    :param ClassicLinkVPCId: The ID of a ClassicLink-enabled VPC to link your EC2-Classic instances to. This parameter is supported only if you are launching EC2-Classic instances. For more information, see ClassicLink in the Amazon Elastic Compute Cloud User Guide .

    :type ClassicLinkVPCSecurityGroups: list
    :param ClassicLinkVPCSecurityGroups: The IDs of one or more security groups for the specified ClassicLink-enabled VPC. This parameter is required if you specify a ClassicLink-enabled VPC, and is not supported otherwise. For more information, see ClassicLink in the Amazon Elastic Compute Cloud User Guide .
            (string) --

    :type UserData: string
    :param UserData: The user data to make available to the launched EC2 instances. For more information, see Instance Metadata and User Data in the Amazon Elastic Compute Cloud User Guide .
            This value will be base64 encoded automatically. Do not base64 encode this value prior to performing the operation.

    :type InstanceId: string
    :param InstanceId: The ID of the instance to use to create the launch configuration. The new launch configuration derives attributes from the instance, with the exception of the block device mapping.
            If you do not specify InstanceId , you must specify both ImageId and InstanceType .
            To create a launch configuration with a block device mapping or override any other instance attributes, specify them as part of the same request.
            For more information, see Create a Launch Configuration Using an EC2 Instance in the Auto Scaling User Guide .

    :type InstanceType: string
    :param InstanceType: The instance type of the EC2 instance.
            If you do not specify InstanceId , you must specify InstanceType .
            For information about available instance types, see Available Instance Types in the Amazon Elastic Compute Cloud User Guide.

    :type KernelId: string
    :param KernelId: The ID of the kernel associated with the AMI.

    :type RamdiskId: string
    :param RamdiskId: The ID of the RAM disk associated with the AMI.

    :type BlockDeviceMappings: list
    :param BlockDeviceMappings: One or more mappings that specify how block devices are exposed to the instance. For more information, see Block Device Mapping in the Amazon Elastic Compute Cloud User Guide .
            (dict) --Describes a block device mapping.
            VirtualName (string) --The name of the virtual device (for example, ephemeral0 ).
            DeviceName (string) -- [REQUIRED]The device name exposed to the EC2 instance (for example, /dev/sdh or xvdh ).
            Ebs (dict) --The information about the Amazon EBS volume.
            SnapshotId (string) --The ID of the snapshot.
            VolumeSize (integer) --The volume size, in GiB. For standard volumes, specify a value from 1 to 1,024. For io1 volumes, specify a value from 4 to 16,384. For gp2 volumes, specify a value from 1 to 16,384. If you specify a snapshot, the volume size must be equal to or larger than the snapshot size.
            Default: If you create a volume from a snapshot and you don't specify a volume size, the default is the snapshot size.
            VolumeType (string) --The volume type. For more information, see Amazon EBS Volume Types in the Amazon Elastic Compute Cloud User Guide .
            Valid values: standard | io1 | gp2
            Default: standard
            DeleteOnTermination (boolean) --Indicates whether the volume is deleted on instance termination.
            Default: true
            Iops (integer) --The number of I/O operations per second (IOPS) to provision for the volume.
            Constraint: Required when the volume type is io1 .
            Encrypted (boolean) --Indicates whether the volume should be encrypted. Encrypted EBS volumes must be attached to instances that support Amazon EBS encryption. Volumes that are created from encrypted snapshots are automatically encrypted. There is no way to create an encrypted volume from an unencrypted snapshot or an unencrypted volume from an encrypted snapshot. For more information, see Amazon EBS Encryption in the Amazon Elastic Compute Cloud User Guide .
            NoDevice (boolean) --Suppresses a device mapping.
            If this parameter is true for the root device, the instance might fail the EC2 health check. Auto Scaling launches a replacement instance if the instance fails the health check.

    :type InstanceMonitoring: dict
    :param InstanceMonitoring: Enables detailed monitoring (true ) or basic monitoring (false ) for the Auto Scaling instances. The default is true .
            Enabled (boolean) --If true , detailed monitoring is enabled. Otherwise, basic monitoring is enabled.

    :type SpotPrice: string
    :param SpotPrice: The maximum hourly price to be paid for any Spot Instance launched to fulfill the request. Spot Instances are launched when the price you specify exceeds the current Spot market price. For more information, see Launching Spot Instances in Your Auto Scaling Group in the Auto Scaling User Guide .

    :type IamInstanceProfile: string
    :param IamInstanceProfile: The name or the Amazon Resource Name (ARN) of the instance profile associated with the IAM role for the instance.
            EC2 instances launched with an IAM role will automatically have AWS security credentials available. You can use IAM roles with Auto Scaling to automatically enable applications running on your EC2 instances to securely access other AWS resources. For more information, see Launch Auto Scaling Instances with an IAM Role in the Auto Scaling User Guide .

    :type EbsOptimized: boolean
    :param EbsOptimized: Indicates whether the instance is optimized for Amazon EBS I/O. By default, the instance is not optimized for EBS I/O. The optimization provides dedicated throughput to Amazon EBS and an optimized configuration stack to provide optimal I/O performance. This optimization is not available with all instance types. Additional usage charges apply. For more information, see Amazon EBS-Optimized Instances in the Amazon Elastic Compute Cloud User Guide .

    :type AssociatePublicIpAddress: boolean
    :param AssociatePublicIpAddress: Used for groups that launch instances into a virtual private cloud (VPC). Specifies whether to assign a public IP address to each instance. For more information, see Launching Auto Scaling Instances in a VPC in the Auto Scaling User Guide .
            If you specify this parameter, be sure to specify at least one subnet when you create your group.
            Default: If the instance is launched into a default subnet, the default is true . If the instance is launched into a nondefault subnet, the default is false . For more information, see Supported Platforms in the Amazon Elastic Compute Cloud User Guide .

    :type PlacementTenancy: string
    :param PlacementTenancy: The tenancy of the instance. An instance with a tenancy of dedicated runs on single-tenant hardware and can only be launched into a VPC.
            You must set the value of this parameter to dedicated if want to launch Dedicated Instances into a shared tenancy VPC (VPC with instance placement tenancy attribute set to default ).
            If you specify this parameter, be sure to specify at least one subnet when you create your group.
            For more information, see Launching Auto Scaling Instances in a VPC in the Auto Scaling User Guide .
            Valid values: default | dedicated

    :return: response = client.create_launch_configuration(
        IamInstanceProfile='my-iam-role',
        ImageId='ami-12345678',
        InstanceType='m3.medium',
        LaunchConfigurationName='my-launch-config',
        SecurityGroups=[
            'sg-eb2af88e',
        ],
    )

    print(response)

    """
    pass


def negative(attrs, inputs, cls):
    """Negation of every element in a tensor"""
    return 'negative', attrs, inputs


def get_filename_without_ending(file_path):
    """
    Returns the filename without extension
    :param file_path:
    :return:
    """
    if '/' in file_path:
        filename = file_path.rsplit('/')[-1]
    else:
        filename = file_path
    return filename.rsplit('.', 1)[0]


def to_unicode(value):
    """Converts a string argument to a unicode string.

    If the argument is already a unicode string or None, it is returned
    unchanged.  Otherwise it must be a byte string and is decoded as utf8.
    """
    if isinstance(value, (str, type(None))):
        return value
    if not isinstance(value, bytes):
        raise TypeError('Expected bytes, unicode, or None; got %r' % type(
            value))
    return value.decode('utf-8')


def checksum(command):
    """Function to calculate checksum as per Satel manual."""
    crc = 5242
    for b in command:
        crc = crc << 1 & 65535 | (crc & 32768) >> 15
        crc = crc ^ 65535
        crc = crc + (crc >> 8) + b & 65535
    return crc


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

        :param ShowcaseRemoveMemberDetails val:
        :rtype: EventDetails
        """
    return cls('showcase_remove_member_details', val)


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

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

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


def line_last_word(line):
    """return last word"""
    if len(line.split()) > 0:
        return line.split()[-1]
    else:
        return False


def get_cvxopt_sparse_intf():
    """Dynamic import of CVXOPT sparse interface.
    """
    import cvxpy.interface.cvxopt_interface.sparse_matrix_interface as smi
    return smi.SparseMatrixInterface()


def interpol_expon(x, x0, y0, x1, y1, exp):
    """
    interpolate between (x0, y0) and (x1, y1) at point x

    exp defines the exponential of the curve
    """
    dx = (x - x0) / (x1 - x0)
    return y0 + pow(dx, exp) * (y1 - y0)


def move_1d(perm, from_start, from_end, insert_pos):
    """
    Move a block in a list.

    Parameters
    ----------
    perm : ndarray
        Permutation
    from_start : int
    from_end : int
    insert_pos : int

    Returns
    -------
    perm : ndarray
        The new permutation
    """
    if not (insert_pos < from_start or insert_pos > from_end):
        raise ValueError(
            'insert_pos={} needs to be smaller than from_start={} or greater than from_end={}'
            .format(insert_pos, from_start, from_end))
    if insert_pos > from_end:
        p_new = list(range(from_end + 1, insert_pos + 1)) + list(range(
            from_start, from_end + 1))
    else:
        p_new = list(range(from_start, from_end + 1)) + list(range(
            insert_pos, from_start))
    p_old = sorted(p_new)
    perm[p_old] = perm[p_new]
    return perm


def get_projectpath(packagename, timenow):
    """ Get the project path for a packagename. """
    path = 'projects/{0}/uploads/{1}'
    sanitizedpackagename = ''.join(packagename.split('.'))
    return path.format(sanitizedpackagename, timenow)


@staticmethod
def return_field():
    """ Determines which function will be called on selected items """
    return 'ret'


def __ne__(A, other):
    """Returns true if both objects are not equal"""
    return not A == other


def dict_to_rows(data, main_key_name=None, main_key_position=None,
    if_empty_value=None, order=None):
    """
    Convert a dictionary to rows (list(lists))

    Parameters
    ----------
    data : dict
        the data to convert in form of a dictionary
    main_key_name : str, optional
        if the data isn't provided as `{main_key: data}` the key needs to be specified
    main_key_position : int, optional
        if the main_key shall not be on top left of the data the position can be specified
    if_empty_value : any, optional
        if a main_key's sub_key is not set something different than `blank` can be defined
    order : dict, list, None, optional
        if a special order for the keys is required

    Returns
    -------
    list(lists)
        list of rows representing the csv based on the `main_element_position`

    """
    if not main_key_name:
        from ._helper import _cast_main_key_name
        data, main_key_name = _cast_main_key_name(data)
    header_keys = set()
    try:
        for main_key in data:
            for key in data[main_key].keys():
                header_keys.add(key)
    except AttributeError:
        raise ValueError(
            'JSON/dictionary is not formatted suitable for neat csv conversion. {main_element: {key: {value_key: value}}} expected'
            )
    if not order:
        header = list(header_keys)
        header.insert(main_key_position if main_key_position else 0,
            main_key_name)
    else:
        from ._helper import _create_sorted_list_from_order
        header = _create_sorted_list_from_order(all_elements=header_keys,
            order=order, main_element=main_key_name, main_element_position=
            main_key_position)
    header_without_ordered_keys = header.copy()
    header_without_ordered_keys.remove(main_key_name)
    rows = [header]
    for element in data:
        row = [(data[element][key] if key in data[element] else
            if_empty_value) for key in header_without_ordered_keys]
        row.insert(main_key_position if main_key_position else 0, element)
        rows.append(row)
    return rows


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

        :param BinderRemoveSectionType val:
        :rtype: EventType
        """
    return cls('binder_remove_section', val)


def swap_element(element, new_class):
    """
    A "trick" to swap the element type.

    Used in certain cases where the underlaying element type
    may change.
    """
    if element.__class__ is not new_class:
        element.__class__ = new_class


def _capture_unprocessed_field(field_tag, field_value, genotype_info_to_fill):
    """Attempt basic delimiter splitting and/or numeric casting for input field, and store results in VCFGenotypeInfo.

    Args:
        field_tag (str): The two- or three-character key for this field in the VCF format line (e.g., AD, PL, etc).
        field_value (str): The string value associated with the field in the VCF format value line.
        genotype_info_to_fill (VCFGenotypeInfo): A partially filled VCFGenotypeInfo object

    Returns:
        VCFGenotypeInfo: The input VCFGenotypeInfo with additional entries added to unprocessed_info dictionary.

    """
    try:
        genotype_info_to_fill.unprocessed_info[field_tag] = float(field_value)
    except ValueError:
        split_list = field_value.split(',')
        cast_split_list = []
        for value in split_list:
            try:
                cast_split_list.append(float(value))
            except ValueError:
                cast_split_list.append(value)
        if len(cast_split_list) > 1:
            genotype_info_to_fill.unprocessed_info[field_tag] = cast_split_list
        else:
            genotype_info_to_fill.unprocessed_info[field_tag
                ] = cast_split_list[0]
    return genotype_info_to_fill


def fit_bins_to_grid(hist_size, grid_size, grid_range):
    """
    Given a tentative number of bins `hist_size` for a histogram over
    the range `grid_range`, return a modified number of bins `hist_size`
    and a modified range `hist_range` so that the spacing of the histogram
    bins is an integer multiple (or integer divisor) of the grid spacing.

    Parameters:
    ----------
    hist_size: integer
        The number of bins in the histogram along the considered direction

    grid_size: integer
        The number of cells in the grid

    grid_range: list of floats (in)
        The extent of the grid

    Returns:
    --------
    hist_size: integer
        The new number of bins

    hist_range: list of floats
        The new range of the histogram
    """
    hist_range = grid_range
    hist_spacing = (hist_range[1] - hist_range[0]) * 1.0 / hist_size
    grid_spacing = (grid_range[1] - grid_range[0]) * 1.0 / grid_size
    if hist_spacing >= grid_spacing:
        hist_spacing = int(hist_spacing / grid_spacing) * grid_spacing
    else:
        hist_spacing = grid_spacing / int(grid_spacing / hist_spacing)
    hist_size = int((hist_range[1] - hist_range[0]) / hist_spacing)
    hist_range[1] = hist_range[0] + hist_size * hist_spacing
    return hist_size, hist_range


def ascii_to_hex(exception):
    """ On unicode decode error (bytes -> unicode error), tries to replace
    invalid unknown bytes by their hex notation.
    """
    if isinstance(exception, UnicodeDecodeError):
        obj = exception.object
        start = exception.start
        end = exception.end
        invalid_part = obj[start:end]
        result = []
        for character in invalid_part:
            if isinstance(character, str):
                result.append(u'\\x{}'.format(character.encode('hex')))
            elif isinstance(character, int):
                result.append(u'\\{}'.format(hex(character)[1:]))
            else:
                raise exception
        result = ''.join(result), end
        return result
    raise exception


def looks_like_issubclass(obj, classname):
    """ Return True if the object has a class or superclass with the given class
    name.

    Ignores old-style classes.
    """
    t = obj
    if t.__name__ == classname:
        return True
    for klass in t.__mro__:
        if klass.__name__ == classname:
            return True
    return False


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 setProxiedObject(ob1, ob2):
    """Set the underlying object for ob1 to ob2, returning the old object.

        Raises TypeError if ob1 is not a proxy.
        """


def theta_Ba_Li_PK74(T, P):
    """c-c': barium lithium [PK74]."""
    theta = -0.07
    valid = T == 298.15
    return theta, valid


def __call__():
    """Returns the key name string of a managed attribute"""


def _get_cluster_name(instance: 'boto3.resources.factory.ec2.Instance') ->str:
    """
    Given an EC2 instance, get the name of the Flintrock cluster it belongs to.
    """
    for group in instance.security_groups:
        if group['GroupName'].startswith('flintrock-'):
            return group['GroupName'].replace('flintrock-', '', 1)
    else:
        raise Exception('Could not extract cluster name from instance: {i}'
            .format(i=instance.id))


def all_classes(c):
    """
    return a tuple of all classes to which c belongs
    >>> list in all_classes(list)
    True
    """
    return c.mro()


def success_ratio(contingency, yes_category=2):
    """
        Returns the success ratio given dichotomous contingency data
        Author: Dougie Squire
        Date: 12/05/2018

        Parameters
        ----------
        contingency : xarray DataArray
            A 2 category contingency table of the form output from doppyo.skill.contingency
        success_ratio : value, optional
            The coordinate value of the category corresponding to 'yes'

        Returns
        -------
        success_ratio : xarray DataArray
            An array containing the success ratios

        Examples
        --------
        >>> da_cmp = xr.DataArray(np.random.normal(size=(3,3)),
        ...                       coords=[('x', np.arange(3)), ('y', np.arange(3))])
        >>> da_ref = xr.DataArray(np.random.normal(size=(3,3)),
        ...                       coords=[('x', np.arange(3)), ('y', np.arange(3))])
        >>> category_edges_cmp = np.linspace(-2,2,3)
        >>> category_edges_ref = np.linspace(-2,2,3)
        >>> contingency = doppyo.skill.contingency(da_cmp, da_ref, category_edges_cmp,
        ...                                        category_edges_ref, over_dims='y')
        >>> doppyo.skill.success_ratio(contingency)
        <xarray.DataArray 'success_ratio' (x: 3)>
        array([nan, nan,  1.])
        Coordinates:
          * x        (x) int64 0 1 2

        Notes
        -----
        See http://www.cawcr.gov.au/projects/verification/
    """
    no_category = abs(yes_category - 2) + 1
    if len(contingency.comparison_category) > 2:
        raise ValueError(
            'Success ratio is defined for dichotomous contingency data only')
    hits = contingency.sel(comparison_category=yes_category,
        reference_category=yes_category, drop=True)
    false_alarms = contingency.sel(comparison_category=yes_category,
        reference_category=no_category, drop=True)
    return (hits / (hits + false_alarms)).rename('success_ratio')


@classmethod
def from_ratios(cls, Rxy=1, Ryz=1):
    """Return isochoric ``DefGrad`` tensor with axial stretches defined by strain ratios.
        Default is identity tensor.

        Keyword Args:
          Rxy, Ryz (float): strain ratios

        Example:
          >>> F = DefGrad.from_ratios(Rxy=2, Ryz=3)
          >>> F
          DefGrad:
          [[2.28942849 0.         0.        ]
           [0.         1.14471424 0.        ]
           [0.         0.         0.38157141]]

        """
    assert Rxy >= 1, 'Rxy must be greater than or equal to 1.'
    assert Ryz >= 1, 'Ryz must be greater than or equal to 1.'
    y = (Ryz / Rxy) ** (1 / 3)
    return cls.from_comp(xx=y * Rxy, yy=y, zz=y / Ryz)


def ExcessPowerPreFunc(sngl_burst_table):
    """
	For speed, convert peak times to floats relative to epoch.
	"""
    if not len(sngl_burst_table):
        return
    offset = sngl_burst_table[0].peak
    for row in sngl_burst_table:
        row.peak_time = float(row.peak - offset)
    return offset


def set_skbuild_plat_name(plat_name):
    """Set platform name associated with scikit-build functions returning a path:

    * :func:`SKBUILD_DIR()`
    * :func:`SKBUILD_MARKER_FILE()`
    * :func:`CMAKE_BUILD_DIR()`
    * :func:`CMAKE_INSTALL_DIR()`
    * :func:`CMAKE_SPEC_FILE()`
    * :func:`SETUPTOOLS_INSTALL_DIR()`
    """
    global _SKBUILD_PLAT_NAME
    _SKBUILD_PLAT_NAME = plat_name


def _validate_secret(value: str) ->str:
    """Ensure that the value is not CHANGEME and convert it to a string.

    This function is used to ensure that secret values in the config have been set by the user to
    something other than the default of CHANGEME.

    Args:
        value: The value to be validated.
    Returns:
        The value.
    Raises:
        ValueError: If value is "CHANGEME".
    """
    if value == 'CHANGEME':
        raise ValueError('This setting must be changed from its default value.'
            )
    return str(value)


@staticmethod
def p_if_data_memory_segment_optional(p):
    """if_data_memory_segment_optional : address_mapping
                                           | segment
                                           | generic_parameter"""
    p[0] = p.slice[1].type, p[1]


@classmethod
def passwordManager(cls):
    """
        Class method to get a reference to the password manager.

        @return reference to the password manager (PasswordManager)
        """
    if cls._passwordManager is None:
        from .Passwords.PasswordManager import PasswordManager
        cls._passwordManager = PasswordManager()
    return cls._passwordManager


def get_int(errmsg, arg, default=1, cmdname=None):
    """If arg is an int, use that otherwise take default."""
    if arg:
        try:
            default = int(eval(arg))
        except (SyntaxError, NameError, ValueError):
            if cmdname:
                errmsg("Command '%s' expects an integer; got: %s." % (
                    cmdname, str(arg)))
            else:
                errmsg('Expecting an integer, got: %s.' % str(arg))
                pass
            raise ValueError
    return default


def e_LRP(model, input, input_column=None, output_column=None):
    """
    Returns attributions for a model against an input using the epsilon-LRP (Layer-wise
    relevance propagation) method which is described in Zeiler et al.
    (https://arxiv.org/abs/1311.2901)

    The first dimension of input and output is assumed to be the batch dimension.
    """
    pass


def highlightMutations(sequence, substitutions, deletions):
    """ Corrects the sequence based on the substitutions and deletions information using info from GTF file data.
	The substitutions and deletions should be 0-based positions of the read and insertions should have been removed"""
    nucleotides = list(sequence)
    if deletions:
        for position in deletions:
            nucleotides.insert(position, '-')
    if substitutions:
        for position in substitutions:
            nucleotides[position] = nucleotides[position].lower()
    return ''.join(nucleotides)


def triangularize_list(array):
    """Create triples (triangularize) from given array."""
    new = []
    if len(array) is 3:
        return [array]
    for i in range(1, len(array) - 1):
        new.append([array[0], array[i], array[i + 1]])
    return new


def _hfloat(f, p=4):
    """Convert float to value suitable for humans.

    :keyword p: Float precision.

    """
    i = int(f)
    return i if i == f else '{0:.{p}}'.format(f, p=p)


def no_devices():
    """
    Returns an empty list

    :return: []
    """
    return []


@classmethod
def add_arguments(cls):
    """
        python web project deploy tool
        """
    return [(('indir',), dict(help=
        'minifier root,default is current directory')), (('outdir',), dict(
        help='minifier root,default is current directory')), ((
        '--with-release',), dict(help='release package to pypi server')), (
        ('--extension',), dict(nargs='+', default=['.py'], help=
        'file extension')), (('--exclude-dir',), dict(nargs='+', default=[
        '.git', 'build', '.idea', 'dist'], help='directory to exclude')), (
        ('--prepend',), dict(help='add license to minifier file')), ((
        '--dry-run',), dict(action='store_true', help=
        'show file list instead filter it'))]


@classmethod
def is_site_in_topic(cls) ->bool:
    """True if site id is in topic."""
    return True


def lin_from_row_col(row, col, sh):
    """
    Convert a col and row counter to 1D linear count
    """
    assert len(sh) == 2, 'Shape must be 2D'
    tot_rows = sh[0]
    ct = col * tot_rows + row
    return ct


@staticmethod
def p_compu_vtab_in_val_out_val(p):
    """compu_vtab_in_val_out_val : number_string_value_list"""
    p[0] = p[1]


def _extract_ip_address(string):
    """
    Addresses from Ceph reports can come up with subnets and ports using ':'
    and '/' to identify them properly. Parse those types of strings to extract
    just the IP.
    """
    port_removed = string.split(':')[0]
    return port_removed.split('/')[0]


def exp(input):
    """Returns a new tensor with the exponential of the elements of the input tensor `input`.

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

    Returns
    -------
    Tensor
        The output tensor.
    """
    pass


def __call__(**kw):
    """
        Returns a copy with all attributes using the given keywords,
        being updated.
        """


def SVGFinishCurve():
    """
    Finish curve creation
    """
    pass


def view(signal):
    """
            View the signal ``signal``.

            :param signal: The signal to view.
            :type signal: str
        """
    raise NotImplementedError('Abstract method tick called.')


@classmethod
def unmarshal(cls, raw: bytes):
    """Returns a new EntryCreditBlock object, unmarshalling given bytes according to:
        https://github.com/FactomProject/FactomDocs/blob/master/factomDataStructureDetails.md#entry-credit-block

        Useful for working with a single ecblock out of context, pulled directly from a factomd database for instance.

        EntryCreditBlock created will not include contextual metadata, such as timestamp or the pointer to the
        next entry-credit block.
        """
    block, data = cls.unmarshal_with_remainder(raw)
    assert len(data) == 0, 'Extra bytes remaining!'
    return block


def cmp(x, y):
    """
    Replacement for built-in funciton cmp that was removed in Python 3

    Compare the two objects x and y and return an integer according to
    the outcome. The return value is negative if x < y, zero if x == y
    and strictly positive if x > y.
    """
    if x is None and y is None:
        return 0
    elif x is None:
        return -1
    elif y is None:
        return 1
    return (x > y) - (x < y)


def prepToMatlab(detectorName, quantity):
    """Create a name of a variable for MATLAB"""
    return detectorName + '_' + quantity


@classmethod
def options(cls, path, **kwargs):
    """Issue a ``OPTIONS`` request."""
    return cls.request('OPTIONS', path, **kwargs)


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 create_state_machine(name=None, definition=None, roleArn=None):
    """
    Creates a state machine.
    See also: AWS API Documentation

    :example: response = client.create_state_machine(
        name='string',
        definition='string',
        roleArn='string'
    )

    :type name: string
    :param name: [REQUIRED]
            The name of the state machine. This name must be unique for your AWS account and region.

    :type definition: string
    :param definition: [REQUIRED]
            The Amazon States Language definition of the state machine.

    :type roleArn: string
    :param roleArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the IAM role to use for this state machine.

    :rtype: dict
    :return: {
        'stateMachineArn': 'string',
        'creationDate': datetime(2015, 1, 1)
    }

    """
    pass


def set_tag_array(span, prefix, value):
    """Helper to set a span tag as a single value or an array"""
    if not value:
        return
    if len(value) == 1:
        span.set_tag(prefix, value[0])
    else:
        for i, v in enumerate(value, start=0):
            span.set_tag('{0}.{1}'.format(prefix, i), v)


def setVocabularyRegistry(registry):
    """Set the vocabulary registry."""
    global _vocabularies
    _vocabularies = registry


def attr_chain(obj, attr):
    """Follow an attribute chain.

    If you have a chain of objects where a.foo -> b, b.foo-> c, etc,
    use this to iterate over all objects in the chain. Iteration is
    terminated by getattr(x, attr) is None.

    Args:
        obj: the starting object
        attr: the name of the chaining attribute

    Yields:
        Each successive object in the chain.
    """
    next = getattr(obj, attr)
    while next:
        yield next
        next = getattr(next, attr)


def getAllRoles():
    """Returns an iterable consisting of tuples of the form:
            (principal_id, sequence_of_roles)
        """


def get_pipeline(service):
    """

        :param: basestring service:

        :return:
          description of the index pipeline to create
        :rtype: :py:class:`docido_sdk.index.IndexAPIProvider`
        """
    pass


@staticmethod
def get_elastic_mappings(es_major):
    """Get Elasticsearch mapping.

        Non dynamic discovery of type for:
            * data.runs
            * data.actions

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
         {
            "dynamic":true,
                "properties": {
                    "data": {
                        "properties": {
                            "_class" : {
                                "type" : "keyword"
                            },
                            "runs": {
                                "dynamic":false,
                                "properties": {}
                            },
                            "actions": {
                                "dynamic":false,
                                "properties": {}
                            },
                            "building" : {
                                "type" : "boolean"
                            },
                            "builtOn" : {
                                "type" : "keyword"
                            },
                            "changeSet": {
                                "properties": {
                                    "items": {
                                        "properties": {
                                            "comment": {
                                                "type": "text",
                                                "index": true
                                            }
                                        }
                                    }
                                }
                            },
                            "description" : {
                                "type" : "keyword"
                            },
                            "displayName" : {
                                "type" : "keyword"
                            },
                            "duration" : {
                                "type" : "long"
                            },
                            "estimatedDuration" : {
                                "type" : "long"
                            },
                            "executor" : {
                                "type" : "object"
                            },
                            "fullDisplayName" : {
                                "type" : "keyword"
                            },
                            "id" : {
                                "type" : "keyword"
                            },
                              "keepLog" : {
                                "type" : "boolean"
                            },
                              "number" : {
                                "type" : "long"
                            },
                            "queueId" : {
                                "type" : "long"
                            },
                            "result" : {
                                "type" : "keyword"
                            },
                            "subBuilds" : {
                                "type" : "object"
                            },
                            "timestamp" : {
                                "type" : "long"
                            },
                            "url" : {
                                "type" : "keyword"
                            }
                        }
                    }
                }
        }
        """
    return {'items': mapping}


@classmethod
def length(cls, dataset):
    """
        Returns the length of the multi-tabular dataset making it appear
        like a single array of concatenated subpaths separated by NaN
        values.
        """
    if not dataset.data:
        return 0
    length = 0
    ds = cls._inner_dataset_template(dataset)
    for d in dataset.data:
        ds.data = d
        length += ds.interface.length(ds)
    return length + len(dataset.data) - 1


@staticmethod
def calculate_gross_current_value(current_price, num_of_shares):
    """
        This method calculates the gross current value which is the total current value of the shares bought,
        which is the result of the multiplication of the current price with the number of bought shares.
        """
    return float(current_price * num_of_shares)


def lower(string):
    """
    Makes string all lowercase.
    """
    return string.lower()


def asint(value):
    """Coerce to integer."""
    if value is None:
        return value
    return int(value)


def provider_parser(subparser):
    """Configure provider parser for Digital Ocean"""
    subparser.add_argument('--auth-token', help=
        'specify token for authentication')


def _parse_exception(e):
    """Parses an exception, returns its message."""
    import re
    matches = re.search(
        '^\\(_mysql_exceptions\\.OperationalError\\) \\(\\d+, \\"(.+)\\"\\)$',
        str(e))
    if matches:
        return matches.group(1)
    matches = re.search('^\\(psycopg2\\.OperationalError\\) (.+)$', str(e))
    if matches:
        return matches.group(1)
    matches = re.search('^\\(sqlite3\\.OperationalError\\) (.+)$', str(e))
    if matches:
        return matches.group(1)
    return str(e)


def dicarray_list_prefixed_values(dica, prefix, key):
    """Compose list of prefixed dica values for the given key"""
    values_ = []
    for d_ in dica:
        values_.append(prefix + d_.get(key, ''))
    return values_


def rchop(string, ending):
    """Removes a substring at the end of a string."""
    if string.endswith(ending):
        return string[:-len(ending)]
    return string


def invert(invert_r: bool=False, invert_g: bool=False, invert_b: bool=False,
    invert_a: bool=False):
    """Invert image’s channels

    :param invert_r: Red, Invert Red Channel
    :type invert_r: bool
    :param invert_g: Green, Invert Green Channel
    :type invert_g: bool
    :param invert_b: Blue, Invert Blue Channel
    :type invert_b: bool
    :param invert_a: Alpha, Invert Alpha Channel
    :type invert_a: bool
    """
    pass


def error_msg_from_exception(e):
    """Translate exception into error message

    Database have different ways to handle exception. This function attempts
    to make sense of the exception object and construct a human readable
    sentence.

    TODO(bkyryliuk): parse the Presto error message from the connection
                     created via create_engine.
    engine = create_engine('presto://localhost:3506/silver') -
      gives an e.message as the str(dict)
    presto.connect('localhost', port=3506, catalog='silver') - as a dict.
    The latter version is parsed correctly by this function.
    """
    msg = ''
    if hasattr(e, 'message'):
        if isinstance(e.message, dict):
            msg = e.message.get('message')
        elif e.message:
            msg = e.message
    return msg or str(e)


def plus_or_dot(pieces):
    """Return a + if we don't already have one, else return a ."""
    if '+' in pieces.get('closest-tag', ''):
        return '.'
    return '+'


@classmethod
def get_name(cls):
    """ Returns the name of the supplier.
        """
    return 'text'


def sunset_sunrise(time, lat, lon):
    """
    Calculates the local sunrise/sunset of the glider location.

    The function uses the Astral package to calculate the sunrise and sunset
    times using the date, latitude and longitude. The times are returned
    rather than day or night indices, as it is more flexible for the quenching
    correction.

    Parameters
    ----------
    time: numpy.ndarray or pandas.Series
        The date & time array in a numpy.datetime64 format.
    lat: numpy.ndarray or pandas.Series
        The latitude of the glider position.
    lon: numpy.ndarray or pandas.Series
        The longitude of the glider position.

    Returns
    -------
    sunrise: numpy.ndarray
        An array of the sunrise times.
    sunset: numpy.ndarray
        An array of the sunset times.

    """
    from astral import Astral
    from pandas import DataFrame
    ast = Astral()
    df = DataFrame.from_dict(dict([('time', time), ('lat', lat), ('lon', lon)])
        )
    df = df.set_index(df.time.values.astype('datetime64[D]'))
    grp_avg = df.groupby(df.index).mean()
    date = grp_avg.index.to_pydatetime()
    grp_avg['sunrise'] = list(map(ast.sunrise_utc, date, df.lat, df.lon))
    grp_avg['sunset'] = list(map(ast.sunset_utc, date, df.lat, df.lon))
    df_reidx = grp_avg.reindex(df.index).astype('datetime64[ns]')
    sunrise, sunset = df_reidx[['sunrise', 'sunset']].values.T
    return sunrise, sunset


def get_entity_pk(serializer):
    """Gets the primary key (PK) of an entity associated with the serializer provided.
    Looks up serializer context for associated view data.

    Parameters:

    - serializer #rest_framework.serializers.BaseSerializer: The serializer instance to use for PK lookup.

    Returns: the PK of the entity if present else #None.
    """
    view_kwargs = serializer.context['view'
        ].kwargs if 'view' in serializer.context else {}
    return view_kwargs.get('pk') if 'pk' in view_kwargs else None


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

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


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

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

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

    """
    pass


@staticmethod
def get_gateway_fee():
    """Get the coinbase gateway fee.

        See: https://support.coinbase.com/customer/portal/articles/1277919-what-fees-does-coinbase-charge-for-merchant-processing

        :return: The coinbase gateway fee
        """
    return 0.01


def versioned_api_headers(version: str=None) ->dict:
    """Will append the API version information (if any) to the headers.
    Args
        version: the optional version string

    Returns:
        the headers dictionary.
    """
    jsonapi_headers = {'Content-Type': 'application/vnd.qctrl+json',
        'Accept': 'application/vnd.qctrl+json'}
    if version is None:
        return jsonapi_headers
    headers = dict(jsonapi_headers)
    headers['Content-Type'] = headers['Content-Type'] + f'; version={version}'
    headers['Accept'] = headers['Accept'] + f'; version={version}'
    return headers


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


@classmethod
def get_meta_title(cls) ->str:
    """A meta title of this kind of object"""
    child_type_meta_title = cls.child_type.get_meta_title()
    return f'Collection of objects of type {child_type_meta_title}'


def export_image(client, file_type, file_=None, filename=None, height=None,
    width=None, dpi=None, depth=None):
    """Export a model to an image file.

    Args:
        client (obj):
            creopyson Client.
        file_type (str):
            Image Type. Valid values: BMP, EPS, JPEG, TIFF.
        `file_` (str, optional):
            Model name. Defaults is current active model.
        filename (str, optional):
            Destination file name. May also contain a path to the file.
            Defaults is the model name with the appropriate file extension,
            in Creo's working directory.
        height (float, optional):
            Image height. Defaults is `7.5`.
        width (float, optional):
            Image width. Defaults is `10.0`.
        dpi (int, optional):
            Image DPI. Defaults is `100`.
        depth (int, optional):
            Image depth. Defaults is `24`.

    Returns:
        dict:
            dirname (str): Directory of the output file
            filename (str): Name of the output file

    """
    data = {'type': file_type}
    if file_ is not None:
        data['file'] = file_
    else:
        active_file = client.file_get_active()
        if active_file is not None:
            data['file'] = active_file['file']
    if filename:
        data['filename'] = filename
    if height:
        data['height'] = height
    if width:
        data['width'] = width
    if dpi:
        data['dpi'] = dpi
    if depth:
        data['depth'] = depth
    return client._creoson_post('interface', 'export_image', data)


@staticmethod
def verify_token(token: bytes):
    """Checks if the given token is of correct type and length."""
    if not isinstance(token, bytes):
        raise TypeError('Token must be bytes')
    if len(token) != 16:
        raise ValueError('Wrong token length')


@staticmethod
def _decode(**fetches):
    """ Performs decoding on the output (draw model)
            :param fetches: A dictionary of fetches from the model.
            :return: A dictionary of decoded results, including various keys for evaluation
        """
    if 'draw_loss' not in fetches:
        return {}
    return {'draw_loss': fetches['draw_loss']}


def location_clear(clear_delta: bool=False):
    """Clear the object’s location

    :param clear_delta: Clear Delta, Clear delta location in addition to clearing the normal location transform
    :type clear_delta: bool
    """
    pass


def overlaps(particle, cell):
    """Check presence of overlaps between particles."""
    x = []
    for i, pi in enumerate(particle):
        for j, pj in enumerate(particle):
            if j <= i:
                continue
            d = sum(pi.distance(pj, cell) ** 2) ** 0.5
            if d < pi.radius + pj.radius:
                x.append((i, j))
    return len(x) > 0, x


def pad_list_to_size(_list, size, padding_value=None):
    """Pads _list with padding_value up to size"""
    return _list + [padding_value] * (size - len(_list))


def getMetadata(content):
    """Return a metadata binding adapter for a particular content
        object. a bind adapter encapsulates both metadata definitions,
        data, and policy behavior into an api for manipulating and
        introspecting metadata
        """


def _get_run_help_string(theargs):
    """Generates humanreadable string telling user how to run
       program with -h flag to display help information
    :param theargs: object returned from _parse_arguments() which
                    should have theargs.program set to script name
    :returns: human readable string telling user how to invoke help.
              Ex: Please run <program> -h for more information.
    """
    return 'Please run ' + theargs.program + ' -h ' + 'for more information.'


def lbf2n(force_lbf):
    """Convert force from lbf to N"""
    return force_lbf / 0.224809


def dewrap(text):
    """Take newlines out of text and normalize whitespace."""
    return ' '.join(text.split())


def addparentchangecallback(category, callback):
    """add a callback to be called when the wd parents are changed

        Callback will be called with the following arguments:
            dirstate, (oldp1, oldp2), (newp1, newp2)

        Category is a unique identifier to allow overwriting an old callback
        with a newer callback.
        """


def convert_query_to_sql_statement(query):
    """
    Convert a Query object created from orm query, into executable sql statement.

    :param query: :class:`sqlalchemy.orm.Query`

    :return: :class:`sqlalchemy.sql.selectable.Select`
    """
    context = query._compile_context()
    context.statement.use_labels = False
    return context.statement


@staticmethod
def get_proto_fields():
    """ Returns the proto fields used by this dataset builder """
    raise NotImplementedError()


def is_filehandle(fh):
    """return True/False if fh is a file-like object"""
    return hasattr(fh, 'read') and hasattr(fh, 'close')


def check_number_of_interfaces(conn, num_expect, flag, logger):
    """
       test numOfInterfaces(), numOfDefinedInterfaces() api
    """
    if flag == 0:
        num = conn.numOfInterfaces() + conn.numOfDefinedInterfaces()
    elif flag == 1:
        num = conn.numOfDefinedInterfaces()
    elif flag == 2:
        num = conn.numOfInterfaces()
    if num != num_expect:
        logger.error("Number don't match, expect %d, got %d" % (num_expect,
            num))
        return False
    logger.info('Number of interfaces matches')
    return True


def calc_domain(host):
    """calculate just the high level domain part of the host name

    Remove the port and the www. if it exists.

    >>> calc_domain('www.dsilabs.ca:8000')
    'dsilabs.ca'

    >>> calc_domain('test.dsilabs.ca:8000')
    'test.dsilabs.ca'

    """
    if host:
        return host.split(':')[0].split('www.')[-1:][0]
    return ''


def split_dataset(X, Y, validation=True, supertest=True, train_cut=0.7,
    validation_cut=0.8, test_cut=0.9):
    """
    Splits dataset into train, test, validation and supertest categories
    """
    train_cut = round(X.shape[0] * train_cut)
    validaiton_cut = round(X.shape[0] * validation_cut)
    test_cut = round(X.shape[0] * test_cut)
    x_train = X[:train_cut]
    y_train = Y[:train_cut]
    if validation == True:
        x_validation = X[train_cut:validaiton_cut]
        y_validation = Y[train_cut:validaiton_cut]
        x_test = X[validaiton_cut:test_cut]
        y_test = Y[validaiton_cut:test_cut]
    else:
        x_validation = None
        y_validation = None
        x_test = X[train_cut:test_cut]
        y_test = Y[train_cut:test_cut]
    if supertest == True:
        x_test = X[train_cut:test_cut]
        y_test = Y[train_cut:test_cut]
        x_supertest = X[test_cut:]
        y_supertest = Y[test_cut:]
    else:
        x_test = X[train_cut:]
        y_test = Y[train_cut:]
        x_supertest = None
        y_supertest = None
    return (x_train, y_train, x_validation, y_validation, x_test, y_test,
        x_supertest, y_supertest)


def _rename_coord_attrs(ds):
    """
    to_netcdf and to_zarr don't like coordinates attribute

    Parameters
    ----------
    ds: xarray.Dataset

    Returns
    -------
    ds: xarray.Dataset
    """
    for var in ds.variables:
        attrs = ds[var].attrs
        coordinates = attrs.pop('coordinates', None)
        ds[var].attrs = attrs
        if coordinates is not None:
            ds[var].attrs['_coordinates'] = coordinates
    return ds


def add_library(args, library_db, git_root):
    """adds a library from git or path"""
    from src.praxxis.util import error
    from src.praxxis.display import display_error
    from src.praxxis.display import display_library
    from src.praxxis.library import sync_library
    import giturlparse
    import os
    path = args.path
    remote = giturlparse.parse(path)
    if not remote.valid:
        if os.path.exists(path):
            if os.path.isdir(path):
                sync_library.sync_library(os.path.abspath(path), library_db,
                    custom_path=True)
            else:
                raise error.NotDirectoryError(path)
        else:
            raise error.LibraryNotFoundError(path)
    else:
        from src.praxxis.util import rmtree
        from git import Repo
        import sys
        import subprocess
        if not os.path.exists(git_root):
            os.mkdir(git_root)
            display_library.display_init_git_library(git_root)
        repo_author = remote.data['owner']
        repo_name = remote.data['repo']
        repo_root = os.path.join(git_root, repo_author, repo_name)
        if os.path.exists(repo_root):
            rmtree.rmtree(repo_root)
            display_error.repo_exists_warning()
        try:
            subprocess.call(['git', 'clone', path, repo_root])
        except KeyboardInterrupt:
            repo_author_root = os.path.join(git_root, repo_author)
            if len(os.listdir(repo_author_root)) == 0:
                os.rmdir(repo_author_root)
            sys.exit(0)
        remote_https = giturlparse.parse(path).url2https
        repo_root_abspath = os.path.abspath(repo_root)
        sync_library.sync_library(repo_root_abspath, library_db,
            custom_library_name='%s_%s' % (repo_author, repo_name),
            custom_path=True, remote=path, remote_origin=remote_https)


def open_repo(org, repo_name):
    """Open a :class:`github3.repos.repo.Repository` instance by name
    in a GitHub organization.

    Parameters
    ----------
    org : class:`github3.github3.orgs.Organization` instance
        The GitHub organization to operate in. Usually created with the
        :meth:`github3.GitHub.organization` method.
    repo_name : str
        Name of the repository (without the organization namespace).
        E.g. `'afw'`.

    Returns
    -------
    repo : :class:`github3.repos.repo.Repository`
        The repository instance.
    """
    for repo in org.repositories():
        if repo.name == repo_name:
            return repo


def instantiate(generator_or_value):
    """
    Dynamic typing hack to try to call generators if provided,
    otherwise return the value directly if not callable. This will
    break badly if used for values that can be callable.
    """
    if callable(generator_or_value):
        return generator_or_value()
    else:
        return generator_or_value


@classmethod
def exists(cls, client, name):
    """
        Determine whether network with provided name exists.

        :param client: client instance
        :type client: :class:`~pylxd.client.Client`
        :param name: name of the network
        :type name: str
        :returns: `True` if network exists, `False` otherwise
        :rtype: bool
        """
    try:
        client.networks.get(name)
        return True
    except cls.NotFound:
        return False


def _pipe_segment_with_colons(align, colwidth):
    """Return a segment of a horizontal line with optional colons which
    indicate column's alignment (as in `pipe` output format)."""
    w = colwidth
    if align in ['right', 'decimal']:
        return '-' * (w - 1) + ':'
    elif align == 'center':
        return ':' + '-' * (w - 2) + ':'
    elif align == 'left':
        return ':' + '-' * (w - 1)
    else:
        return '-' * w


@staticmethod
def metadata_updated_on(item):
    """Extracts and coverts the update time from a Meetup item.

        The timestamp is extracted from 'updated' field and converted
        to a UNIX timestamp.

        :param item: item generated by the backend

        :returns: a UNIX timestamp
        """
    ts = item['updated']
    ts = ts / 1000.0
    return ts


def delta_value(decimals=1, unit='$'):
    """A delta formatter to display the delta as a float with a given unit.

    Args:
        decimals: The number of decimals to display.
        unit: The unit symbol to display after the delta value.

    Returns:
        A delta formatter function (f(a,b)) returning (b-a)/a accompanied with a unit.

    """
    return lambda a, b: '{:+,.{prec}f} {unit}'.format(1.0 * (b - a), unit=
        unit, prec=decimals)


def default(*args, **kwargs):
    """
    Return first argument which is "truthy"

    >>> default(None, None, 1)
    1
    >>> default(None, None, 123)
    123
    >>> print(default(None, None))
    None
    """
    default = kwargs.get('default', None)
    for arg in args:
        if arg:
            return arg
    return default


def get_static_ip(staticIpName=None):
    """
    Returns information about a specific static IP.
    See also: AWS API Documentation

    :example: response = client.get_static_ip(
        staticIpName='string'
    )

    :type staticIpName: string
    :param staticIpName: [REQUIRED]
            The name of the static IP in Lightsail.

    :rtype: dict
    :return: {
        'staticIp': {
            'name': 'string',
            'arn': 'string',
            'supportCode': 'string',
            'createdAt': datetime(2015, 1, 1),
            'location': {
                'availabilityZone': 'string',
                'regionName': 'us-east-1'|'us-west-1'|'us-west-2'|'eu-west-1'|'eu-central-1'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'ap-northeast-2'
            },
            'resourceType': 'Instance'|'StaticIp'|'KeyPair'|'InstanceSnapshot'|'Domain'|'PeeredVpc',
            'ipAddress': 'string',
            'attachedTo': 'string',
            'isAttached': True|False
        }
    }

    """
    pass


@classmethod
def get_detail_elems(cls, *args):
    """
        An optional first argument is the user interface plugin, a
        :class:`Plugin` instance.  If this is None, will use
        :attr:`settings.SITE.kernel.default_ui
        <lino.core.kernel.Kernel.default_ui>`.

        Returns a list of the widgets (layout elements) that make up
        the detail layout.
        """
    lh = cls.get_detail_layout(*args)
    return lh.main.elements


@staticmethod
def mimetype():
    """Return most common mime type for format."""
    return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'


def lineToId(line: str):
    """ get the id of a line, e.g. part which specifies which figure it refers to """
    line = line.strip()
    line = line.split('.ax_dict')[0]
    if line.startswith('fig = '):
        line = line[len('fig = '):]
    return line


def show_random_img(image_array, n=1):
    """Display n rendomly-selected images from image_array"""
    from keras.preprocessing.image import array_to_img, img_to_array, load_img
    import numpy as np
    from IPython.display import display
    i = 1
    while i <= n:
        choice = np.random.choice(range(0, len(image_array)))
        print(f'Image #:{choice}')
        display(array_to_img(image_array[choice]))
        i += 1
    return


@staticmethod
def get_file_for_streaming_upload(path):
    """
        Opens and returns a file descriptor of a specified file to be passed as ``data`` parameter
        to other requests keywords.

        This allows streaming upload of large files without reading them into memory.

        File descriptor is binary mode and read only. Requests keywords will automatically close the file,
        if used outside this library it's up to the caller to close it.
        """
    return open(path, 'rb')


def begin():
    """ called before processing of the queue is started """


@classmethod
def make(cls, func, name, **kwargs):
    """Make a subclass of the segment using a method.

        Note: This requires a custom make method, because it's a bit different.
        """
    classname = '{0}_{1}'.format(name, cls.__name__)
    newclass = type(classname, (cls,), dict(_func=func, _name=name, **kwargs))
    return newclass


def get_account_settings():
    """
    Returns a customer's account settings.
    You can use this operation to retrieve Lambda limits information, such as code size and concurrency limits. For more information about limits, see AWS Lambda Limits . You can also retrieve resource usage statistics, such as code storage usage and function count.
    See also: AWS API Documentation

    Examples
    This operation retrieves a Lambda customer's account settings
    Expected Output:

    :example: response = client.get_account_settings()

    :rtype: dict
    :return: {
        'AccountLimit': {
            'TotalCodeSize': 123,
            'CodeSizeUnzipped': 123,
            'CodeSizeZipped': 123,
            'ConcurrentExecutions': 123
        },
        'AccountUsage': {
            'TotalCodeSize': 123,
            'FunctionCount': 123
        }
    }

    """
    pass


def sorted_by_count(seq):
    """Sort a sequence by the item.count()."""
    return sorted(seq, key=lambda x: x.count())


def _a_encode_none(value, mapping):
    """
    None --> ['0', 'n']
    """
    return [b'0n']


@classmethod
def _create_read_collection_docs(api, defn, c_name):
    """Generate the displayable read documentation for the
        collection identified by defn

        """
    subtype = None
    for name, c_defn, key in defn.collections:
        if name == c_name:
            subtype = c_defn
    return 'Returns collection of %s object from the %s collection.' % (subtype
        .name, c_name)