def getfilecontent(file):
    """Get entire file contents"""
    with open(file) as f:
        file_in_list_format = f.readlines()
        file_in_list_to_string_format = ''
        for line in file_in_list_format:
            file_in_list_to_string_format += line
    return file_in_list_to_string_format


def hot_test(blue, red):
    """Haze Optimized Transformation (HOT) test

    Equation 3 (Zhu and Woodcock, 2012)

    Based on the premise that the visible bands for most land surfaces
    are highly correlated, but the spectral response to haze and thin cloud
    is different between the blue and red wavelengths.
    Zhang et al. (2002)

    Parameters
    ----------
    blue: ndarray
    red: ndarray

    Output
    ------
    ndarray: boolean
    """
    thres = 0.08
    return blue - 0.5 * red - thres > 0.0


@classmethod
def from_response(cls, response, attrs):
    """ Create an index from returned Dynamo data """
    proj = response['Projection']
    index = cls(proj['ProjectionType'], response['IndexName'], attrs[
        response['KeySchema'][1]['AttributeName']], proj.get(
        'NonKeyAttributes'))
    index.response = response
    return index


def all_has(objects, key, check_value=None, opt=None):
    """objects是一个list，内个element都是dict，并且都有指定key对应的值"""
    if not objects:
        return False
    for obj in objects[:200]:
        if not isinstance(obj, dict):
            return False
        if check_value is None and obj.get(key) is None:
            return False
        elif check_value is not None:
            value_got = obj.get(key)
            if isinstance(value_got, (tuple, list)):
                value_got = len(value_got)
            if (opt is None or opt == '==') and value_got != check_value:
                return False
            elif opt == '>=' and value_got < check_value:
                return False
            elif opt == '<=' and value_got > check_value:
                return False
            elif opt == '>' and value_got <= check_value:
                return False
            elif opt == '<' and value_got >= check_value:
                return False
    return True


def _merge_assocs_args_d_kwargs(args_dict, kwargs):
    """Merge args_dict and kwargs. Detect duplicate keys."""
    error_str = 'Association "%s" provided by argument and keyword argument'
    for key in args_dict:
        if key in kwargs:
            raise ValueError(error_str % key)
    merged = {}
    merged.update(args_dict)
    merged.update(kwargs)
    return merged


def yes_no_question(default=None):
    """
    Asks the user a yes/no question and translates it into bool.

    :return: bool
    """
    yes = {'yes', 'y', 'ye', 'Y'}
    no = {'no', 'n', 'N'}
    choice = input().lower().strip()
    if choice == '':
        choice = default
    if choice in yes:
        return True
    elif choice in no:
        return False
    else:
        print("Please respond with 'yes' or 'no'")


@staticmethod
def can_translate_file(file_path):
    """
        Called by the ingestor to determine if this translator can accept
        a given local file.
        :param file_path: path to local file
        :return: bool indicating whether translation is possible
        """
    return False


def simple_filter(data=None, attr=None, value=None, property_field=None):
    """Filter a list of dicts

    :param list data:
        The list to be filtered.  The list is modified in-place and will
        be changed if any filtering occurs.
    :param string attr:
        The name of the attribute to filter.  If attr does not exist no
        match will succeed and no rows will be returned.  If attr is
        None no filtering will be performed and all rows will be returned.
    :param string value:
        The value to filter.  None is considered to be a 'no filter' value.
        '' matches against a Python empty string.
    :param string property_field:
        The name of the data field containing a property dict to filter.
        If property_field is None, attr is a field name. If property_field
        is not None, attr is a property key name inside the named property
        field.

    :returns:
        Returns the filtered list
    :rtype list:

    This simple filter (one attribute, one exact-match value) searches a
    list of dicts to select items.  It first searches the item dict for a
    matching ``attr`` then does an exact-match on the ``value``.  If
    ``property_field`` is given, it will look inside that field (if it
    exists and is a dict) for a matching ``value``.
    """
    if not data or not attr or value is None:
        return data
    for d in reversed(data):
        if attr in d:
            search_value = d[attr]
        elif property_field and property_field in d and isinstance(d[
            property_field], dict):
            if attr in d[property_field]:
                search_value = d[property_field][attr]
            else:
                search_value = None
        else:
            search_value = None
        if not search_value or search_value != value:
            try:
                data.remove(d)
            except ValueError:
                pass
    return data


def iter_decorations(of_cls, *decoration_sources):
    """ Iterates over all decorations of type *of_cls*. """
    for item in decoration_sources:
        if hasattr(item, 'iter_decorations'):
            it = item.iter_decorations()
        elif hasattr(item, '__decorations__'):
            it = iter(item.__decorations__)
        elif hasattr(item, 'decorations') and hasattr(item.decorations,
            '__iter__'):
            it = iter(item.decorations)
        elif not isinstance(item, type) and hasattr(item, '__iter__'):
            it = iter(item)
        else:
            continue
        for sub_item in it:
            if of_cls is None or isinstance(sub_item, of_cls):
                yield sub_item


def set_attribute_label(series, resource_labels, attribute_key,
    canonical_key=None, label_value_prefix=''):
    """Set a label to timeseries that can be used for monitoring
    :param series: TimeSeries object based on view data
    :param resource_labels: collection of labels
    :param attribute_key: actual label key
    :param canonical_key: exporter specific label key, Optional
    :param label_value_prefix: exporter specific label value prefix, Optional
    """
    if attribute_key in resource_labels:
        if canonical_key is None:
            canonical_key = attribute_key
        series.resource.labels[canonical_key
            ] = label_value_prefix + resource_labels[attribute_key]


@staticmethod
def setext_level_2(title):
    """Return a setext level 1 header.

                :param str title: text title.
                :return: a header titlte of form: ``'\\n' + title +'\\n------------\\n'``.
                :rtype: str
        """
    return '\n' + title + '\n' + ''.join(['-' for _ in title]) + '\n'


@classmethod
def _check_data_args(cls, args):
    """Safty function to check data arguments."""
    if not isinstance(args, list):
        raise ValueError('Provided Data Arguments should be a list!')
    for i, ds in enumerate(args):
        if 'id' not in ds:
            raise IOError('Item at position {} has no id'.format(i))
        if 'dataset' not in ds and 'input' not in ds:
            raise IOError(
                'Dataset ({}) should have either a start dataset (`dataset`) or inherit from a pervious dataset (`input`)'
                .format(ds['id']))
    return args


def use_pretty_numbers(enabled: bool=True):
    """Determine if problems should include only pretty numbers or
    a whole range of integers and floats. Using pretty numbers will
    restrict the numbers that are generated to integers between 1 and
    12. When not using pretty numbers, floats and large integers will
    be included in the output from `rand_number`"""
    global _pretty_numbers
    _pretty_numbers = enabled


@staticmethod
def _compare_version(a, b):
    """
        Return True if version b is the same or higher than version a

        Parameters
        ----------
        a: array_like
        b: array_like
        """
    return a[0] < b[0] or a[0] <= b[0] and a[1] < b[1] or a[0] <= b[0] and a[1
        ] <= b[1] and a[2] <= b[2]


def html_horizontal(closing_tag=True):
    """
    Get HTML horizontal divider.

    :param closing_tag: If a closing tag should be added.
    :type closing_tag: Optional[bool]
    :return: The HTML tag (the divider).
    :rtype: str
    """
    if closing_tag:
        return '

'
    return '
'


def get_storage_index():
    """Return a string with the (binary) storage index in use on this
        download. This may be None if there is no storage index (i.e. LIT
        files)."""


def host(value):
    """ Validates that the value is a valid network location """
    if not value:
        return True, ''
    try:
        host, port = value.split(':')
    except ValueError as _:
        return False, 'value needs to be <host>:<port>'
    try:
        int(port)
    except ValueError as _:
        return False, 'port component of the host address needs to be a number'
    return True, ''


def fitfunc(f):
    """
    A decorator that can be used to say if something is a fitfunc.

    """
    f.fitfuncwraps = True
    return f


def updated_dict(dic1, dic2):
    """Return dic1 updated with dic2 if dic2 is not None.

    Example
    -------

    >>> my_dict = updated_dict({"size": 7, "color": "r"}, some_defaults_dict)
    """
    if dic2 is not None:
        dic1.update(dic2)
    return dic1


def split_arguments(args, splitter_name=None, splitter_index=None):
    """Split list of args into (other, split_args, other) between splitter_name/index and `--`

    :param args: list of all arguments
    :type args: list of str
    :param splitter_name: optional argument used to split out specific args
    :type splitter_name: str
    :param splitter_index: specific index at which to split
    :type splitter_index: int

    :returns: tuple (other, split_args)
    """
    if splitter_index is None:
        if splitter_name not in args:
            return args, []
        splitter_index = args.index(splitter_name)
    start_index = splitter_index + 1
    end_index = args.index('--', start_index) if '--' in args[start_index:
        ] else None
    if end_index:
        return args[0:splitter_index], args[start_index:end_index], args[
            end_index + 1:]
    else:
        return args[0:splitter_index], args[start_index:], []


@classmethod
def ms_to_minsec(cls, ms: int, space: str='') ->str:
    """
		Converts a number of milliseconds to one of the following formats:
			- 10ms         if < 1 sec
			- 10:15        if < 1 hour
			- 10:15:33     if < 1 day
			- 5d:10:15:33  if > 1 day
		Prepends a minus sign (−) if negative.
		:param ms: The milliseconds
		:param space: Space char between digits and 'ms' or 'd' for day (if used); good choices are empty, ASCII space, Chars.narrownbsp, Chars.thinspace, and Chars.nbsp.
		:return: A string of one of the formats above
		"""
    is_neg = ms < 0
    ms = abs(int(ms))
    seconds = int(ms / 1000 % 60)
    minutes = int(ms / (1000 * 60) % 60)
    hours = int(ms / (1000 * 60 * 60) % 24)
    days = int(ms / (1000 * 60 * 60 * 24))
    if ms < 1000:
        s = '{}{}ms'.format(space, ms)
    elif days > 1:
        s = '{}{}d:{}:{}:{}'.format(days, space, str(hours).zfill(2), str(
            minutes).zfill(2), str(seconds).zfill(2))
    elif hours > 1:
        s = '{}:{}:{}'.format(str(hours).zfill(2), str(minutes).zfill(2),
            str(seconds).zfill(2))
    else:
        s = '{}:{}'.format(str(minutes).zfill(2), str(seconds).zfill(2))
    return '−' + s if is_neg else s


def showFigure():
    """Call :func:`~matplotlib.pyplot.show` function with ``block=False``
    argument to avoid blocking behavior in non-interactive sessions.  If
    *block* keyword argument is not recognized, try again without it."""
    from matplotlib.pyplot import show
    try:
        show(block=False)
    except TypeError:
        show()


def p_long_slice(p):
    """long_slice : short_slice ":" expression """
    if len(p) == 4:
        p[0] = p[1] + [p[3]]
    else:
        p[0] = p[1]


@classmethod
def order_and_label(cls, t):
    """Order and label of a discrete type.

        Cf. :meth:`Profile.order_and_label`.

        Examples
        --------
            >>> ProfileOrdinal.order_and_label('abc')
            ('abc', '$r(abc)$')
            >>> ProfileOrdinal.order_and_label('a~b>c')
            ('a~b>c', '$r(a\\\\sim b>c)$')
        """
    if len(t) == 3:
        return t, '$r(%s)$' % t
    else:
        return cls.order_and_label_weak(t)


@staticmethod
def delta_todate(num_yyyyddd):
    """
		To convert timedelta to date
		Parameters
		----------
		num_yyyyddd

		Returns
		-------
		datetime.datetime
		"""
    import datetime
    str_yyddd = str(num_yyyyddd)
    year = int(str_yyddd[:4])
    baseDate = datetime.date(year, 1, 1)
    days = int(str_yyddd[4:])
    return baseDate + datetime.timedelta(days=days)


def feature_sampler(vec_f, auxiliary_sampler):
    """
    A generator function for tuples (F, log_q_xs, xs)

    Parameters
    ----------
    vec_f : function
        Pass `vec_f` as a (vectorized) function that operates on a vector of
        samples xs = {x1,...,xn} and returns a feature matrix (m x n), where m
        is some number of feature components.

    auxiliary_sampler : function
        Pass `auxiliary_sampler` as a function that returns a tuple
        (xs, log_q_xs) representing a sample to use for sampling (e.g.
        importance sampling) on the sample space of the model.

        xs : list, 1d ndarray, or 2d matrix (n x d)
            We require len(xs) == n.

    Yields
    ------
        tuples (F, log_q_xs, xs)

        F : matrix (m x n)
        log_q_xs : as returned by auxiliary_sampler
        xs : as returned by auxiliary_sampler

    """
    while True:
        xs, log_q_xs = auxiliary_sampler()
        F = vec_f(xs)
        yield F, log_q_xs, xs


def announce(event):
    """ announce text on all channels in fleet. """
    event.announce(event._parsed.rest)


@classmethod
def limit(cls, refs, hints):
    """Limit a list of entities.

        The underlying driver layer may have already truncated the collection
        for us, but in case it was unable to handle truncation we check here.

        :param refs: the list of members of the collection
        :param hints: hints, containing, among other things, the limit
                      requested

        :returns: boolean indicating whether the list was truncated, as well
                  as the list of (truncated if necessary) entities.

        """
    NOT_LIMITED = False
    LIMITED = True
    if hints is None or hints.limit is None:
        return NOT_LIMITED, refs
    if hints.limit.get('truncated', False):
        return LIMITED, refs
    if len(refs) > hints.limit['limit']:
        return LIMITED, refs[:hints.limit['limit']]
    return NOT_LIMITED, refs


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

        :param SharedContentRestoreInviteesType val:
        :rtype: EventType
        """
    return cls('shared_content_restore_invitees', val)


def excess_pore_pressure_ratio(df):
    """
    Assign the excess pore pressure ratio, if the water pressure u2 is defined. Else, raise ERROR.

    :param df: (DataFrame)
    :return: (DataFrame)
    """
    try:
        u2 = df['u2']
    except KeyError:
        raise SystemExit(
            'ERROR: u2 not defined in .gef file, change classifier')
    return df.assign(excess_pore_pressure_ratio=(u2 - df['water_pressure']) /
        (df['qt'] - df['soil_pressure']))


@staticmethod
def auto_ml_unnest_param(p):
    """ unnest a param dictionnary,
        skipping 'ColumnsSelector' and 'columns_to_use'

        """
    res = {}
    for k, v in p['all_models_params'].items():
        if k[1][1] != 'ColumnsSelector':
            for k2, v2 in v.items():
                if k2 != 'columns_to_use':
                    res['__'.join(k[1]) + '__' + k2] = v2
            res[k[1][0]] = k[1][1]
    for b in p['blocks_to_use']:
        res['hasblock_%s' % b] = 1
    res['job_id'] = p['job_id']
    return res


def extract_part_trace(reader, writer, range):
    """
    extract range from reader and save to writer
    :param reader:
    :param writer:
    :param range:
    :return:
    """
    assert len(range) == 2, 'range must be in the form of (min, max)'
    maxLine = range[1]
    if maxLine == -1:
        maxLine = len(reader)
    line_count = 0
    for line in reader:
        line_count += 1
        if line_count - 1 < range[0]:
            continue
        if line_count - 1 >= maxLine:
            break
        writer.write(line)


def parseDay(dia: str):
    """
    Convert Spanish date to English date
    Parameters
    ----------
    dia String with Spanish date, format 'dd Mmm yyyy'

    Returns
    -------
    String with English date, format 'yyyy/mm/dd'
    """
    meses = {'ene': '01', 'feb': '02', 'mar': '03', 'abr': '04', 'may':
        '05', 'jun': '06', 'jul': '07', 'ago': '08', 'set': '09', 'sep':
        '09', 'oct': '10', 'nov': '11', 'dic': '12'}
    d, m, y = dia.split()
    return y + '/' + meses[m[:3].lower()] + '/' + d


def copy_to_out(result, out):
    """A helper function, that copies a computation result into an array, that
    is passed for returning a value through call by reference.
    This is used in the terms, if they use a :mod:`numpy` function, that does not have
    a ``out`` parameter.

    :param result: the computation result
    :param out: None or an :func:`numpy.array`, into which the result shall be copied
    :returns: ``out``, if the result has been copied, ``result`` otherwise
    """
    if out is None:
        return result
    else:
        out[:] = result
        return out


def get_redirect_to_root():
    """Get whether it should always redirect to root after logout.
        """


def thumbnail(filename, thname, size, fformat):
    """Create a thumbnail image and save it.
    """
    from PIL import Image
    img = Image.open(filename)
    img.thumbnail(size, Image.ANTIALIAS)
    img.save(thname, fformat)


def patch(patch_data):
    """FHIR Patch implementation: https://www.hl7.org/fhir/fhirpatch.html"""


def create_python_dtype_dataset(py_obj, h_group, call_id=0, **kwargs):
    """ dumps a python dtype object to h5py file

    Args:
        py_obj: python object to dump; should be a python type (int, float, bool etc)
        h_group (h5.File.group): group to dump data into.
        call_id (int): index to identify object's relative location in the iterable.
    """
    d = h_group.create_dataset('data_%i' % call_id, data=py_obj, dtype=type
        (py_obj), **kwargs)
    d.attrs['type'] = ['python_dtype']
    d.attrs['python_subdtype'] = str(type(py_obj))


def changed(requestContext, seriesList):
    """
    Takes one metric or a wildcard seriesList.
    Output 1 when the value changed, 0 when null or the same
    Example::

        &target=changed(Server01.connections.handled)
    """
    for series in seriesList:
        series.name = series.pathExpression = 'changed(%s)' % series.name
        previous = None
        for index, value in enumerate(series):
            if previous is None:
                series[index] = 0
            elif value is not None and previous != value:
                series[index] = 1
            else:
                series[index] = 0
            previous = value
    return seriesList


@classmethod
def generateImplicitParameters(cls, obj):
    """Generate any required information that don't yet exist."""
    pass


def quoted_presenter(dumper, data):
    """
    This is a custom representer for string, so that YAML can be output
    with quotes to satisfy paths on Windows.
    """
    return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='"')


def eqva(a1, a2):
    """
    modified np.array_equal. considers a1 and a2
    equal when there is 1 difference.
    """
    a1.sort()
    a2.sort()
    count = 0
    a1_, a2_ = a1, a2
    if len(a1) > len(a2):
        a1_ = a2
        a2_ = a1
    for s in a1:
        if not s in a2:
            count += 1
    return count


def human_check(string):
    """
    The API is actually terribly unreliable at providing information on
    whether an entity is human or corporate. What is consistent is that
    companies are provided in UPPER CASE and humans provided in the format
    "SURNAME, Othernames". This takes advantage of this to identify if a
    record is human.
    """
    for i in string:
        if i.islower():
            return 'Individual'
    return 'Corporate'


def buildSpreadsheetUrl():
    """Create a filename for the spreadsheets"""


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

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

    For example::

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

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


def available_commands(mod, ending='_command'):
    """Just returns the available commands, rather than the whole long list."""
    commands = []
    for key in mod.__dict__:
        if key.endswith(ending):
            commands.append(key.split(ending)[0])
    commands.sort()
    return commands


def bump_version(version_array, level):
    """
    Perform ++1 action on the array [x, y, z] cell,
    Input values are assumed to be validated
    :param version_array: int array of [x, y, z] validated array
    :param level: string represents major|minor|patch
    :return: int array with new value
    """
    if type(version_array) != list:
        raise ValueError(
            "Error, invalid version_array: '{}', should be [x, y, z].".
            format(version_array))
    if level == 'major':
        version_array[0] += 1
        version_array[1] = 0
        version_array[2] = 0
    elif level == 'minor':
        version_array[1] += 1
        version_array[2] = 0
    elif level == 'patch':
        version_array[2] += 1
    else:
        raise ValueError(
            "Error, invalid level: '{}', should be major|minor|patch.".
            format(level))
    return version_array


def update_object(obj, path, callback=None):
    """
    Traverse a data structure ensuring all nodes exist.

    obj: expected to be a dictionary
    path: string with dot-separated path components
    callback: optional callback function (described below)

    When update_object reaches the parent of the leaf node, it calls the
    optional callback function. The arguments to the callback function are:

    - parent: dictionary containing the leaf node
    - key: string key for the leaf node in parent
    - created: boolean flag indicating whether any part of the path, including
        the leaf node needed to be created.

    If the callback function is None, update_object will still ensure that all
    components along the path exist. If the leaf needs to be created, it will
    be created as an empty dictionary.

    Example:
    update_object({}, 'foo.bar') -> {'foo': {'bar': {}}}

    Return value: Returns either the return value of callback, or if callback
    is None, returns the value of the leaf node.
    """
    parts = path.split('.')
    current = obj
    parent = obj
    created = False
    for part in parts:
        if len(part) == 0:
            raise Exception('Path ({}) is invalid'.format(path))
        if not isinstance(current, dict):
            raise Exception('Cannot set {}, not a dictionary'.format(path))
        if part not in current:
            current[part] = {}
            created = True
        parent = current
        current = parent[part]
    if callback is not None:
        return callback(parent, parts[-1], created)
    else:
        return current


def _email_to_username(email):
    """
    Returns a Django-safe username based on the email address.
    This is because Django doesn't support email addresses as usernames yet.

    """
    return email.replace('@', 'AT')


def prepend(exception, message, end=': '):
    """Prepends the first argument (i.e., the exception message) of the a BaseException with the provided message.
    Useful for reraising exceptions with additional information.

    :param BaseException exception: the exception to prepend
    :param str message: the message to prepend
    :param str end: the separator to add to the end of the provided message
    :returns: the exception
    """
    exception.args = exception.args or ('',)
    exception.args = (message + end + exception.args[0],) + exception.args[1:]
    return exception


def maketwodimensions(x):
    """ helper function to make sure a numpy array is at least 2 dimensions """
    if len(x.shape) == 1:
        return x.reshape((x.shape[0], 1))
    else:
        return x


@classmethod
def _get_import_resolver(cls):
    """ method that can be overridden in tests """
    from zope.dottedname.resolve import resolve as resolve_dotted
    return resolve_dotted


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


@classmethod
def from_seconds(cls, seconds):
    """ Create a duration with the given amount of seconds. """
    return cls(seconds)


@staticmethod
def product(iterable):
    """Calculate product of elements of an iterable.

        Args:
            iterable: An object capable of returning its members one at a time.
                Must have at least on element.

        Returns:
            int: Product

        """
    product = 1
    for value in iterable:
        product *= value
    return product


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 keyword_set(kw):
    """
    only true if ``kw`` is defined AND different from zero.

    here, ``None`` is used for non-defined keyword.
    """
    return kw is not None and kw != 0


def set_hbr(A, a):
    """ Return the half-bottom-right of the given array.
    """
    nx, _ = A.shape
    li = int(nx / 2)
    A[li:, li:] = a


def unauthenticated(func):
    """Adds 'unauthenticated' attribute to decorated function.

    Usage:

    >>> @unauthenticated
    ... def mymethod(f):
    ...     pass
    """
    func.unauthenticated = True
    return func


def count(target, collection, key):
    """Total target count on collection.

    :param key: callable to get the comparison value
    """
    occurences = sum([(1) for item in collection if key(item) == key(target)])
    return occurences


@staticmethod
def render_bitbar_cli(full_cli):
    """ Format a bash-runnable full-CLI with parameters into bitbar schema.
        """
    cmd, params = full_cli.strip().split(' ', 1)
    bitbar_cli = 'bash={}'.format(cmd)
    for index, param in enumerate(params.split(' ')):
        bitbar_cli += ' param{}={}'.format(index + 1, param)
    return bitbar_cli


def is_compressed_filetype(filepath):
    """
    Use to check if we should compress files in a zip.
    """
    import os
    assert isinstance(filepath, bytes)
    return os.path.splitext(filepath)[1].lower() in {b'.exr', b'.jpg',
        b'.jpeg', b'.png', b'.aif', b'.aiff', b'.mp3', b'.ogg', b'.ogv',
        b'.wav', b'.avi', b'.mkv', b'.mov', b'.mpg', b'.mpeg'}


def backimage_move():
    """Move Node backdrop

    """
    pass


def create_switchable_attributes(prefix, input_type, name):
    """Creates attribute dicts for the switchable form

    :type prefix: str
    :param prefix: prefix (environment, template) of field
    :type input_type: str
    :param input_type: field type (file, raw, url)
    :type name: str
    :param name: translated text label to display to user
    :rtype: dict
    :return: an attribute set to pass to form build

        ..code-block::
        for extension in self.extensions:
            attributes = create_switchable_attributes(
                'local',
                '%s' % extension["id"],
                _('Extends'))
            field = forms.ChoiceField(label=_('Extends'),
                                      choices=self.get_extension_choices(),
                                      widget=forms.Select(
                                          attrs=attributes),
                                      required=False)
            self.fields["extension__%s" % extension['id']] = field
    """
    attributes = {'class': 'switched', 'data-switch-on': prefix + 'source'}
    attributes['data-' + prefix + 'source-' + input_type] = name
    return attributes


def p_procedure_def_list(t):
    """procedure_def_list : procedure_def procedure_def_list
                          | empty"""


def _any_trits(left, right):
    """
    Adds two individual trits together and returns a single trit
    indicating whether the result is positive or negative.
    """
    res = left + right
    return (res > 0) - (res < 0)


def align8to32(bytes, width, mode):
    """
    converts each scanline of data from 8 bit to 32 bit aligned
    """
    bits_per_pixel = {'1': 1, 'L': 8, 'P': 8}[mode]
    bits_per_line = bits_per_pixel * width
    full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8)
    bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0
        )
    extra_padding = -bytes_per_line % 4
    if not extra_padding:
        return bytes
    new_data = []
    for i in range(len(bytes) // bytes_per_line):
        new_data.append(bytes[i * bytes_per_line:(i + 1) * bytes_per_line] +
            b'\x00' * extra_padding)
    return b''.join(new_data)


def swapaxes(input, axis1, axis2):
    """Interchange the two given axes of a tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.
    axis1, axis2 : int
        The two axes.

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


def _mini_batch_convergence(model, iteration_idx, n_iter, tol, n_samples,
    centers_squared_diff, batch_inertia, context, verbose=0):
    """Helper function to encapsulate the early stopping logic"""
    batch_inertia /= model.batch_size
    centers_squared_diff /= model.batch_size
    ewa_diff = context.get('ewa_diff')
    ewa_inertia = context.get('ewa_inertia')
    if ewa_diff is None:
        ewa_diff = centers_squared_diff
        ewa_inertia = batch_inertia
    else:
        alpha = float(model.batch_size) * 2.0 / (n_samples + 1)
        alpha = 1.0 if alpha > 1.0 else alpha
        ewa_diff = ewa_diff * (1 - alpha) + centers_squared_diff * alpha
        ewa_inertia = ewa_inertia * (1 - alpha) + batch_inertia * alpha
    if verbose:
        progress_msg = (
            'Minibatch iteration %d/%d: mean batch inertia: %f, ewa inertia: %f '
             % (iteration_idx + 1, n_iter, batch_inertia, ewa_inertia))
        print(progress_msg)
    if tol > 0.0 and ewa_diff <= tol:
        if verbose:
            print('Converged (small centers change) at iteration %d/%d' % (
                iteration_idx + 1, n_iter))
        return True
    ewa_inertia_min = context.get('ewa_inertia_min')
    no_improvement = context.get('no_improvement', 0)
    if ewa_inertia_min is None or ewa_inertia < ewa_inertia_min:
        no_improvement = 0
        ewa_inertia_min = ewa_inertia
    else:
        no_improvement += 1
    if (model.max_no_improvement is not None and no_improvement >= model.
        max_no_improvement):
        if verbose:
            print(
                'Converged (lack of improvement in inertia) at iteration %d/%d'
                 % (iteration_idx + 1, n_iter))
        return True
    context['ewa_diff'] = ewa_diff
    context['ewa_inertia'] = ewa_inertia
    context['ewa_inertia_min'] = ewa_inertia_min
    context['no_improvement'] = no_improvement
    return False


def is_cell_variable(trajectory, tests=1):
    """
    Simple test to check if cell changes.

    We compare the first frame to an integer number `tests` of other
    frames starting from the end of `trajectory`.
    """
    is_variable = False
    frames = len(trajectory)
    if tests > 0:
        skip = max(1, int(frames / float(tests)))
    else:
        skip = 1
    L0 = trajectory[0].cell.side
    for sample in range(frames - 1, 0, -skip):
        L1 = trajectory[sample].cell.side
        if L0[0] != L1[0] or L0[1] != L1[1] or L0[2] != L1[2]:
            is_variable = True
            break
    return is_variable


def normalize_slice(slize):
    """
    >>> normalize_slice((3,))
    (3, None)
    >>> normalize_slice((0, -2))
    (0, -2)
    >>> normalize_slice(4)
    (4, -4)
    """
    if isinstance(slize, int):
        return slize, -slize
    if len(slize) == 1:
        return slize[0], None
    elif len(slize) == 2:
        return slize
    else:
        raise ValueError('??')


def tempfile_name(tfile):
    """get the name of a temp file"""
    if tfile:
        return tfile.name
    return ''


def add_arg(func, *args, **kwargs):
    """Bind CLI arguments to a shell.py `do_foo` function."""
    if not hasattr(func, 'arguments'):
        func.arguments = []
    if (args, kwargs) not in func.arguments:
        func.arguments.insert(0, (args, kwargs))


def hostname_from_domain(fqdn):
    """Extracts the hostname from its canonical domain.

    >>> hostname_from_domain('death.ocf.berkeley.edu')
    'death'
    """
    return fqdn.split('.')[0]


@staticmethod
def accepts(content_type):
    """Return True if this handler can handler this type."""
    return False


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

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


@classmethod
def is_open(cls):
    """
        Counts how often the context was opened and not yet closed.

        :return: Value of internal context counter.
        :rtype: int
        """
    return cls.__ctx_counter


def is_combination_truck(df):
    """Return if vehicle is a combination truck, per NHTSA convention."""
    yr = df['YEAR']
    body = df['BODY_TYP']
    tow_veh = df['TOW_VEH']
    return yr.between(1975, 1981) & (body.isin([57, 58, 59]) | body.isin([
        53, 54, 55, 56, 60]) & (tow_veh == 1)) | yr.between(1982, 1990) & ((
        body == 74) | body.isin([70, 71, 72, 75, 76, 78, 79]) & tow_veh.
        between(1, 5)) | (1991 <= yr) & ((body == 66) | body.isin([60, 61,
        62, 63, 64, 71, 72, 78, 79]) & tow_veh.between(1, 4))


def identify_process():
    """Identify the process.

    This creaets an entity identifier that identifies the process
    Python is currently running in. This is useful for relating custom
    entities to the interpreter's process.

    :returns: A :class:`cobe.Identifier` object for the current process.
    """
    raise NotImplementedError


def _json_fallback(obj):
    """Fallback json serialiser."""
    raise TypeError('Type not serializable: {}'.format(type(obj)))


def delete_integration_response(restApiId=None, resourceId=None, httpMethod
    =None, statusCode=None):
    """
    Represents a delete integration response.
    See also: AWS API Documentation

    :example: response = client.delete_integration_response(
        restApiId='string',
        resourceId='string',
        httpMethod='string',
        statusCode='string'
    )

    :type restApiId: string
    :param restApiId: [REQUIRED]
            Specifies a delete integration response request's API identifier.

    :type resourceId: string
    :param resourceId: [REQUIRED]
            Specifies a delete integration response request's resource identifier.

    :type httpMethod: string
    :param httpMethod: [REQUIRED]
            Specifies a delete integration response request's HTTP method.

    :type statusCode: string
    :param statusCode: [REQUIRED]
            Specifies a delete integration response request's status code.

    """
    pass


def ensure_value_is_not_none(instance, attribute, value):
    """
    A helper function to ensure that the values for
    the time is not none
    """
    if value is None:
        raise ValueError("Value can't be None")


def abs(data=None, out=None, name=None, **kwargs):
    """Returns element-wise absolute value of the input.

    Example::

       abs([-2, 0, 3]) = [2, 0, 3]

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

       - abs(default) = default
       - abs(row_sparse) = row_sparse
       - abs(csr) = csr

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

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

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

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


def delete_change_set(awsclient, change_set_name, stack_name):
    """Delete specified change set. Currently we only use this during
    automated regression testing. But we have plans so lets locate this
    functionality here

    :param awsclient:
    :param change_set_name:
    :param stack_name:
    """
    client = awsclient.get_client('cloudformation')
    response = client.delete_change_set(ChangeSetName=change_set_name,
        StackName=stack_name)


def copy(klass=None):
    """return a copy of index, using klass (__new__) if given."""


def _delta(x, y):
    """Computes |y|/|x|."""
    return max(float(len(y)) / float(len(x)), 1.0)


def put_object_tagging(Bucket=None, Key=None, VersionId=None, ContentMD5=
    None, Tagging=None):
    """
    Sets the supplied tag-set to an object that already exists in a bucket
    See also: AWS API Documentation

    :example: response = client.put_object_tagging(
        Bucket='string',
        Key='string',
        VersionId='string',
        ContentMD5='string',
        Tagging={
            'TagSet': [
                {
                    'Key': 'string',
                    'Value': 'string'
                },
            ]
        }
    )

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

    :type Key: string
    :param Key: [REQUIRED]

    :type VersionId: string
    :param VersionId:

    :type ContentMD5: string
    :param ContentMD5:

    :type Tagging: dict
    :param Tagging: [REQUIRED]
            TagSet (list) -- [REQUIRED]
            (dict) --
            Key (string) -- [REQUIRED] Name of the tag.
            Value (string) -- [REQUIRED] Value of the tag.

    :rtype: dict
    :return: {
        'VersionId': 'string'
    }

    :returns:
    (dict) --
    VersionId (string) --

    """
    pass


@classmethod
def get_uri(cls, uri='/api/', search_spec='name', search_string='test'):
    """Get the URI for an item

            :note: extended_fetch= True to return full objects

            :param uri: The URI for you wish to preform the search at
            :apram search_spec: What you  are shearching by
            :param search_string: What you are searching for
            :param extended_fetch: Do you want the full objects or just the
                URI and description

            :example:
                response = BaseAPI().get_uri(
                    uri='/api/organization',
                    search_string='test'
                )
                print(response)
                # Output
                {'test': '/api/organization/123'}

            :return: returns a dict with the URI or URI's.
        """
    response = cls.find(uri=uri, search_spec=search_spec, search_string=
        search_string, extended_fetch=False)
    uri_list = {}
    if len(response.json()) == 1:
        uri_list = {response.json()[0]['description']: response.json()[0][
            'URI']}
    else:
        for value in response.json():
            uri_list.update({value['description']: value['URI']})
    return uri_list


def p_const_value(p):
    """const_value : INTCONSTANT
                   | DUBCONSTANT
                   | LITERAL
                   | BOOLCONSTANT
                   | const_list
                   | const_map
                   | const_ref"""
    p[0] = p[1]


@classmethod
def from_dict(cls, parsed_dict):
    """Create an Ephemeral event from a dictionary.

        Args:
            parsed_dict (dict): The dictionary representation of the event.

        """
    raise NotImplementedError()


@classmethod
def _is_valid(cls, *args, **kwargs):
    """
        Check if input file works with a specific Arbor class.
        This is used with :func:`~ytree.data_structures.arbor.load` function.
        """
    return False


def _normalize_path(paths):
    """Normalize multiple graph traversals by edges into one that traverses all edges.

    In general we can get to a task by multiple paths. As we would like to ensure that all paths are traversed, we
    compound multiple traversals into a single one that traverses all necessary edges.

    :param paths: a list of paths that should be compound into a single traversal
    :return: a dict representing compound traversal
    """
    result = {}
    for entry in paths:
        for key, value in entry.items():
            if key not in result:
                result[key] = []
            result[key] = list(set(result[key]) | set(value))
    return result


@staticmethod
def _as_float_version(version):
    """
        Return a string version as a simplified float version (major.minor)

        Parameters
        ----------
        version: str
            Version.

        Return
        ------
        float
            version
        """
    return float('.'.join(version.split('.')[:2]))


def write_file(filename, text):
    """Write file with the given text."""
    with open(filename, 'wb') as f:
        f.write(text.encode('utf-8'))


@classmethod
def local_checksum(cls, package, algorithm='md5'):
    """
        Computes the checksum value on the local package file.

        :param str package:
          File-path to the package (\\*.tgz) file on the local server
        :param str algorithm:
          The algorithm to use for computing the checksum. Valid values are:
          'md5', 'sha1', and 'sha256'. Defaults to 'md5'.

        :returns: checksum (str)
        :raises IOError: when **package** file does not exist
        """
    if algorithm == 'md5':
        return cls.local_md5(package)
    elif algorithm == 'sha1':
        return cls.local_sha1(package)
    elif algorithm == 'sha256':
        return cls.local_sha256(package)
    else:
        raise ValueError('Unknown checksum algorithm: %s' % algorithm)


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

        :param SharedContentRemoveInviteesType val:
        :rtype: EventType
        """
    return cls('shared_content_remove_invitees', val)


@classmethod
def parse_periscope_url(cls, url):
    """
        Get any key information available from the supplied URL.

        Will attempt to retrieve one, or combination of:

        * broadcast_id
        * user_id
        * username
        """
    url_parsers = [cls._parse_periscope_w_url, cls._parse_periscope_u_url,
        cls._parse_periscope_username_broadcast_id_url, cls.
        _parse_periscope_username_url]
    out = {'broadcast_id': None, 'user_id': None, 'username': None}
    for url_parser in url_parsers:
        parse_result = url_parser(url)
        if parse_result != out:
            return parse_result
    return out


def set_status(status):
    """Sets the Monitor's 'status' object to an arbitrary value.
        Different operations will store different sorts of status information
        here. Operation code should use get+modify+set sequences to update
        this."""


def doc_handle_move(event):
    """Documentation for handlers bound to ``evt.EVT_C_MOVE``.

    User implementation of this event handler is required if one or more
    services that use C-MOVE are to be supported. If a handler is
    not implemented and bound to ``evt.EVT_C_MOVE`` then the C-MOVE request
    will be responded to using a  *Status* value of ``0xC511`` - Failure.

    The first yield should be the ``(addr, port)`` of the move destination,
    the second yield the number of required C-STORE sub-operations as an
    ``int``, and the remaining yields the ``(status, dataset)`` pairs.

    Matching SOP Instances will be sent to the peer AE with AE title
    ``move_aet`` over a new association. If ``move_aet`` is unknown then
    the SCP will send a response with a 'Failure' status of ``0xA801``
    'Move Destination Unknown'.

    **Event**

    ``evt.EVT_C_MOVE``

    **Supported Service Classes**

    * *Query/Retrieve Service*
    * *Hanging Protocol Query/Retrieve Service*
    * *Defined Procedure Protocol Query/Retrieve Service*
    * *Color Palette Query/Retrieve Service*
    * *Implant Template Query/Retrieve Service*

    **Status**

    Success
      | ``0x0000`` - Sub-operations complete, no failures

    Pending
      | ``0xFF00`` - Sub-operations are continuing

    Cancel
      | ``0xFE00`` - Sub-operations terminated due to Cancel indication

    Failure
      | ``0x0122`` - SOP class not supported
      | ``0x0124`` - Not authorised
      | ``0x0210`` - Duplicate invocation
      | ``0x0211`` - Unrecognised operation
      | ``0x0212`` - Mistyped argument
      | ``0xA701`` - Out of resources: unable to calculate number of matches
      | ``0xA702`` - Out of resources: unable to perform sub-operations
      | ``0xA801`` - Move destination unknown
      | ``0xA900`` - Identifier does not match SOP class
      | ``0xAA00`` - None of the frames requested were found in the SOP
        instance
      | ``0xAA01`` - Unable to create new object for this SOP class
      | ``0xAA02`` - Unable to extract frames
      | ``0xAA03`` - Time-based request received for a non-time-based
        original SOP Instance
      | ``0xAA04`` - Invalid request
      | ``0xC000`` to ``0xCFFF`` - Unable to process

    Parameters
    ----------
    event : events.Event
        The event representing a service class receiving a C-MOVE
        request message. ``Event`` attributes are:

        * ``assoc`` : the
          :py:class:`association <pynetdicom.association.Association>`
          that is running the service that received the C-MOVE request.
        * ``context`` : the presentation context the request was sent under
          as a ``presentation.PresentationContextTuple``.
        * ``event`` : the event that occurred as ``namedtuple``.
        * ``move_destination`` : the C-MOVE request's *Move Destination*
          value as ``bytes``.
        * ``request`` : the received
          :py:class:`C-MOVE request <pynetdicom.dimse_primitives.C_MOVE>`
        * ``timestamp`` : the
          `date and time <https://docs.python.org/3/library/datetime.html#datetime-objects>`_
          that the C-MOVE request was processed by the service.

        ``Event`` properties are:

        * ``identifier`` : the decoded
          :py:class:`Dataset <pydicom.dataset.Dataset>` contained within the
          C-MOVE request's *Identifier* parameter. Because *pydicom* uses
          a deferred read when decoding data, if the decode fails the returned
          ``Dataset`` will only raise an exception at the time of use.
        * ``is_cancelled`` : returns ``True`` if a
          C-CANCEL request has been received, False otherwise. If a C-CANCEL
          is received then the handler should yield a ``(0xFE00, None)``
          status/dataset pair and return.

    Yields
    ------
    addr, port : str, int or None, None
        The first yield should be the TCP/IP address and port number of the
        destination AE (if known) or ``(None, None)`` if unknown. If
        ``(None, None)`` is yielded then the SCP will send a C-MOVE
        response with a 'Failure' Status of ``0xA801`` (move destination
        unknown), in which case nothing more needs to be yielded.
    int
        The second yield should be the number of C-STORE sub-operations
        required to complete the C-MOVE operation. In other words, this is
        the number of matching SOP Instances to be sent to the peer.
    status : pydiom.dataset.Dataset or int
        The status returned to the peer AE in the C-MOVE response. Must be
        a valid C-MOVE status value for the applicable Service Class as
        either an ``int`` or a ``Dataset`` containing (at a minimum) a
        (0000,0900) *Status* element. If returning a ``Dataset`` then it
        may also contain optional elements related to the *Status* (as in
        DICOM Standard Part 7, Annex C).
    dataset : pydicom.dataset.Dataset or None
        If the status is 'Pending' then yield the ``Dataset``
        to send to the peer via a C-STORE sub-operation over a new
        association.

        If the status is 'Failed', 'Warning' or 'Cancel' then yield a
        ``Dataset`` with a (0008,0058) *Failed SOP Instance UID List*
        element containing the list of the C-STORE sub-operation SOP
        Instance UIDs for which the C-MOVE operation has failed.

        If the status is 'Success' then yield ``None``, although yielding a
        final 'Success' status is not required and will be ignored if
        necessary.

    See Also
    --------
    :py:meth:`send_c_move()<pynetdicom.association.Association.send_c_move>`
    :py:class:`C_MOVE<pynetdicom.dimse_primitives.C_MOVE>`
    :py:class:`QueryRetrieveServiceClass<pynetdicom.service_class.QueryRetrieveServiceClass>`
    :py:class:`HangingProtocolQueryRetrieveServiceClass<pynetdicom.service_class.HangingProtocolQueryRetrieveServiceClass>`
    :py:class:`DefinedProcedureProtocolQueryRetrieveServiceClass<pynetdicom.service_class.DefinedProcedureProtocolQueryRetrieveServiceClass>`
    :py:class:`ColorPaletteQueryRetrieveServiceClass<pynetdicom.service_class.ColorPaletteQueryRetrieveServiceClass>`
    :py:class:`ImplantTemplateQueryRetrieveServiceClass<pynetdicom.service_class.ImplantTemplateQueryRetrieveServiceClass>`

    References
    ----------

    * DICOM Standard Part 4, Annexes
      `C <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_C>`_,
      `U <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_U>`_,
      `X <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_X>`_,
      `Y <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_Y>`_,
      `BB <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_BB>`_
      and `HH <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_HH>`_
    * DICOM Standard Part 7, Sections
      `9.1.4 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#sect_9.1.4>`_,
      `9.3.4 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#sect_9.3.4>`_
      and `Annex C <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#chapter_C>`_
    """
    pass


@classmethod
def from_quaternion(cls, quat, dtype=None):
    """Creates a Matrix from a Quaternion.
        """
    return cls(cls._module.create_from_quaternion(quat, dtype=dtype))


def _largest_n_values(arr, n):
    """

    Returns the index (i.e., rows or columns) of the largest n numbers

    :param arr: a numpy array
    :type arr: ``1D ndarray``
    :param n: the largest ``n`` values to return.
    :type n: ``int``
    :return: sorted list of the ``n`` largest values in ``arr`` (ascending order).
    :rtype: ``tuple``
    """
    return tuple(sorted(arr.argsort()[-n:]))


def overloading(graph):
    """
    Check a grid for line overloading due to current exceeding I_th_max

    Parameters
    ----------
    graph : networkx.Graph
        Graph structure as container for a grid topology including its equipment

    Returns
    -------
    overloaded : tuple
        Pairwise edges of graph a maximum occuring current
    """


def is_restart_command(command_text: str) ->bool:
    """
    >>> is_restart_command("restart")
    True
    >>> is_restart_command("restart game")
    True
    >>> is_restart_command("take lamp")
    False
    """
    return command_text.startswith('restart')


def example_basemap(ax=None, **options):
    """
    draw a map of France

    @param      ax          axis
    @param      options     look at the code
    @return                 ax
    """
    import matplotlib.pyplot as plt
    if ax is None:
        _, ax = plt.subplots(nrows=1, ncols=1, figsize=options.get(
            'figsize', (5, 5)))
    from mpl_toolkits.basemap import Basemap
    import numpy
    m = Basemap(llcrnrlon=-5, llcrnrlat=40, urcrnrlon=20, urcrnrlat=56,
        resolution='i', projection='cass', lon_0=2.34, lat_0=48, ax=ax)
    m.drawcoastlines()
    m.drawcountries()
    m.fillcontinents(color='lightgrey', lake_color='#AAAAFF')
    m.drawparallels(numpy.arange(-40, 61.0, 2.0))
    m.drawmeridians(numpy.arange(-20.0, 21.0, 2.0))
    m.drawmapboundary(fill_color='#BBBBFF')
    return ax


def filter_spans(spans):
    """Filter a sequence of spans and remove duplicates or overlaps. Useful for
    creating named entities (where one token can only be part of one entity) or
    when merging spans with `Retokenizer.merge`. When spans overlap, the (first)
    longest span is preferred over shorter spans.

    spans (iterable): The spans to filter.
    RETURNS (list): The filtered spans.
    """
    get_sort_key = lambda span: (span.end - span.start, -span.start)
    sorted_spans = sorted(spans, key=get_sort_key, reverse=True)
    result = []
    seen_tokens = set()
    for span in sorted_spans:
        if span.start not in seen_tokens and span.end - 1 not in seen_tokens:
            result.append(span)
        seen_tokens.update(range(span.start, span.end))
    result = sorted(result, key=lambda span: span.start)
    return result


def isStaticIpAvailable(ipaddr, chuteStor, name):
    """
    Make sure this static IP address is available.

    Checks the IP addresses of all zones on all other chutes,
    makes sure not equal."""
    chList = chuteStor.getChuteList()
    for ch in chList:
        if name != ch.name:
            otherStaticIPs = ch.getChuteStaticIPs()
            if ipaddr in otherStaticIPs:
                return False
    return True


def image_upload_to_dispatcher(entry, filename):
    """
    Dispatch function to allow overriding of ``image_upload_to`` method.

    Outside the model for fixing an issue with Django's migrations on Python 2.
    """
    return entry.image_upload_to(filename)


def is_module_installed(module_name):
    """
    Simpler version of spyder.utils.programs.is_module_installed
    to improve startup time.
    """
    try:
        __import__(module_name)
        return True
    except:
        return False


def replace_hyphens(olddict):
    """ Replaces all hyphens in dict keys with an underscore.

    Needed in Django templates to get a value from a dict by key name. """
    newdict = {}
    for key, value in olddict.items():
        key = key.replace('-', '_')
        newdict[key] = value
    return newdict


def __call__(cls, parent=None, **kwargs):
    """ Create a new instance of the enamldef class.

        This method will create the new instance, then populate that
        instance with children defined in the enamldef. Once those
        children are added, the __init__ method of the instance will
        be invoked with the provided arguments.

        Parameters
        ----------
        parent : Object or None
            The parent object of the new instance.

        **kwargs
            Additional keyword arguments to pass to the constructor.

        """
    instance = cls.__new__(cls)
    cls.__node__(instance)
    instance.__init__(parent, **kwargs)
    return instance


def hash_to_hex_str(x):
    """Convert a little-endian binary hash to displayed hex string.

    Display form of a binary hash is reversed and converted to hex.
    """
    return bytes(reversed(x)).hex()


def importVarious(context):
    """
    Import various settings."""
    if context.readDataFile('PloneSurvey.txt') is None:
        return


def getSiblings():
    """Return this member's siblings in a list."""


def norm_dt(s):
    """normalize a datetime as string

    params:
        - s         str, as %Y-%m-%d %H:%M:%S, maybe without %H:%M:%S

    return: string %Y-%m-%d %H:%M:%S if input has %H:%M:%S
            otherwise appends 12:00:00 to %Y-%m-%d """
    ret = ''
    if len(s) >= 10 and len(s) < 19:
        ret = s[:10] + ' 12:00:00'
    elif len(s) == 19:
        ret = s[:]
    else:
        raise ValueError('{} is not acceptable as date/time'.format(s))
    return ret


def __repr__(A):
    """For `print` and `pprint`"""
    return A.to_str()


@classmethod
def create_using_ebay_data(cls, ebay_data):
    """
        Creates record of customer values sent by ebay

        :param ebay_data: Dictionary of values for customer sent by ebay
                          Ref: http://developer.ebay.com/DevZone/XML/docs/
                                  Reference/eBay/GetUser.html#Response
        :return: Active record of record created
        """
    return cls.create([{'name': ebay_data['User']['UserID'], 'ebay_user_id':
        ebay_data['User']['UserID'], 'contact_mechanisms': [('create', [{
        'email': ebay_data['User']['Email']}])]}])[0]


def manage_changePolicyDefs(policy_list):
    """Update the policy structure with a list of tuples [(id, title),...]
           The tuples may optionally contain a policy class and a dict of
           kwargs to pass to the policy add hook. e.g.:
          [(id, title, klass, {'arg1': val1}), ...]
        """


def is_valid_mac(addr):
    """Check the syntax of a given mac address.

    The acceptable format is xx:xx:xx:xx:xx:xx
    """
    addrs = addr.split(':')
    if len(addrs) != 6:
        return False
    for m in addrs:
        try:
            if int(m, 16) > 255:
                return False
        except ValueError:
            return False
    return True


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 isAlphanum(c):
    """return true if the character is a letter, digit, underscore,
           dollar sign, or non-ASCII character.
    """
    return (c >= 'a' and c <= 'z' or c >= '0' and c <= '9' or c >= 'A' and
        c <= 'Z' or c == '_' or c == '$' or c == '\\' or c is not None and
        ord(c) > 126)


@staticmethod
def mimetype():
    """Return most common media type for format."""
    return 'text/plain'


@classmethod
def remove(cls, ob):
    """
        Remove object from '/classes/cls'
        :param ob: Object or ob_id
        :return:
        """
    return cls._remove_avos(cls.__name__, ob)


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 '+'


def get_m2m_fields_for(instance=None):
    """gets m2mfields for instance"""
    return instance._meta.many_to_many


def ndof_all():
    """Pan and rotate the view with the 3D mouse

    """
    pass


def get_navigation_items(req):
    """Should return an iterable object over the list of navigation items
        to add, each being a tuple in the form (category, name, text).

        The category determines the location of the navigation item and
        can be `mainnav` or `metanav`. The name is a unique identifier that
        must match the string returned by get_active_navigation_item.
        The text is typically a link element with text that corresponds
        to the desired label for the navigation item, and an href.
        """


def remove_if_exists(mylist, item):
    """ Remove item from mylist if it exists, do nothing otherwise """
    to_remove = []
    for i in range(len(mylist)):
        if mylist[i] == item:
            to_remove.append(mylist[i])
    for el in to_remove:
        mylist.remove(el)


@staticmethod
def save_corpus(fname, corpus, id2word=None, metadata=False):
    """Save `corpus` to disk.

        Some formats support saving the dictionary (`feature_id -> word` mapping),
        which can be provided by the optional `id2word` parameter.

        Notes
        -----
        Some corpora also support random access via document indexing, so that the documents on disk
        can be accessed in O(1) time (see the :class:`gensim.corpora.indexedcorpus.IndexedCorpus` base class).

        In this case, :meth:`~gensim.interfaces.CorpusABC.save_corpus` is automatically called internally by
        :func:`serialize`, which does :meth:`~gensim.interfaces.CorpusABC.save_corpus` plus saves the index
        at the same time.

        Calling :func:`serialize() is preferred to calling :meth:`gensim.interfaces.CorpusABC.save_corpus`.

        Parameters
        ----------
        fname : str
            Path to output file.
        corpus : iterable of list of (int, number)
            Corpus in BoW format.
        id2word : :class:`~gensim.corpora.Dictionary`, optional
            Dictionary of corpus.
        metadata : bool, optional
            Write additional metadata to a separate too?

        """
    raise NotImplementedError('cannot instantiate abstract base class')


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

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


def unpad_pkcs5(padded, block_size):
    """
    Returns the unpadded version of a data padded using PKCS5.

    :param padded: String padded with PKCS5.
    :type padded: :class:`str`

    :return: :class:`str` -- Original, unpadded string.
    """
    assert padded and len(padded) % block_size == 0
    pad_size = ord(padded[-1])
    assert 1 <= pad_size <= block_size
    pad = padded[-pad_size:]
    assert pad == pad[-1] * pad_size
    return padded[:-pad_size]


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


def install_mathjax():
    """
    install a local copy of mathjax
    """
    from IPython.external import mathjax
    mathjax.install_mathjax()


def post_save_page_moderator(instance, raw, created, **kwargs):
    """Helper post save signal.
    """
    old_page = instance.old_page
    from cms.utils.moderator import page_changed
    if not old_page:
        page_changed(instance, old_page)


def __calculate_flight_time(departure_time=None, arrival_time=None):
    """
    This function calculates total flight time for a single leg

    :return: (str) Flight time in hour and minutes
    """
    dtime = departure_time
    atime = arrival_time
    flight_time_sec = atime - dtime
    minutes, seconds = divmod(flight_time_sec, 60)
    hours, minutes = divmod(minutes, 60)
    total_flight_time = str(hours) + 'h' + ' ' + str(minutes) + 'm'
    return total_flight_time


@classmethod
def is_ray(cls, geom):
    """Return whether ``geom`` is a ray-like object or not.

		:param geom:
		:type geom: type of :attr:`Geom.inner_object`
		:return: True if ``geom`` is an instance of the class representing a
			ray in the adapted library
		:rtype: bool

		"""
    raise NotImplementedError()


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

        :param HasTeamSharedDropboxValue val:
        :rtype: FeatureValue
        """
    return cls('has_team_shared_dropbox', val)


def hex256(x: int) ->str:
    """Hex encodes values up to 256 bits into a fixed length

    By including this amount of leading zeros in the hex string, lexicographic
    and numeric ordering are identical. This facilitates working with these
    numbers in the database without native uint256 support.
    """
    return '{0:+#067x}'.format(x)


@staticmethod
def failure_node_name(flow_name, failure_node):
    """Create a failure node name representation for generated Python config.

        :param flow_name: name of flow for which the representation should be created
        :param failure_node: a node from graph of all failure permutations
        :return: variable name
        :rtype: str
        """
    return '_%s_fail_%s' % (flow_name, '_'.join(failure_node.traversed))


@staticmethod
def promote_type(orig_type, new_type):
    """Given a table with an original type, decide whether a new determination of a new applicable type
        should overide the existing one"""
    if not new_type:
        return orig_type
    if not orig_type:
        return new_type
    try:
        orig_type = orig_type.__name__
    except AttributeError:
        pass
    try:
        new_type = new_type.__name__
    except AttributeError:
        pass
    type_precidence = ['unknown', 'int', 'float', 'date', 'time',
        'datetime', 'str', 'bytes', 'unicode']
    if type_precidence.index(new_type) > type_precidence.index(orig_type):
        return new_type
    else:
        return orig_type


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 render_git_describe_long(pieces):
    """TAG-DISTANCE-gHEX[-dirty].

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

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


def local_utility(factory, provides=None, name=u'', setup=None, public=
    False, name_in_container=None):
    """Register a local utility.

        factory - the factory that creates the local utility
        provides - the interface the utility should be looked up with
        name - the name of the utility
        setup - a callable that receives the utility as its single argument,
                it is called after the utility has been created and stored
        public - if False, the utility will be stored below ++etc++site
                 if True, the utility will be stored directly in the site.
                 The site should in this case be a container.
        name_in_container - the name to use for storing the utility
        """


@classmethod
def register_nsdoc_class(cls, doc_class, xname):
    """Registers a document class

        Internally XMLNSParser maintains a single table of document
        classes which can be used to identify the correct class to use
        to represent a document based on the expanded name of the root
        element.

        doc_class
            the class object being registered, it must be derived from
            :py:class:`NSDocument`

        xname
            A tuple of (namespace, name) representing the name of the
            root element.  If either (or both) components are None a
            wildcard is registered that will match any corresponding
            value."""
    cls._nsdoc_class_table[xname] = doc_class


def queue_list(transport, request, callback=None, **kwargs):
    """Gets a list of queues

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


def ok():
    """is this feed ok to display?"""


def _turn_off_border(ax) ->None:
    """
    Turns off top and right borders.

    Note that this function will leave the bottom and left borders on.

    :param ax: An axis object
    :return: None
    """
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')


def u32le_list_to_byte_list(data):
    """! @brief Convert a word array into a byte array"""
    res = []
    for x in data:
        res.append(x >> 0 & 255)
        res.append(x >> 8 & 255)
        res.append(x >> 16 & 255)
        res.append(x >> 24 & 255)
    return res


@classmethod
def _images_succeeded(cls, session):
    """Clears the :attr:`_stored_images` set and deletes actual
        files that are marked as deleted in the storage
        if the ongoing transaction has committed.

        """
    for image, store in cls._deleted_images:
        for stored_image, _ in cls._stored_images:
            if (stored_image.object_type == image.object_type and
                stored_image.object_id == image.object_id and stored_image.
                width == image.width and stored_image.height == image.
                height and stored_image.mimetype == image.mimetype):
                break
        else:
            store.delete(image)
    cls._stored_images.clear()
    cls._deleted_images.clear()


def to_brix(value):
    """
    Convert gravity value to brix value
    """
    brix = ((182.4601 * value - 775.6821) * value + 1262.7794
        ) * value - 669.5622
    return brix


def format_fs_label(label):
    """Format filesystem label to match mkfs format

    Labels longer than 12 will be truncated to 12 first characters because of
    xfs limitations
    """
    if not label:
        return ''
    else:
        return ' -L {0} '.format(label[:12])


def ask_for_inputs(identifiers):
    """
        CLI helper function that queries the user to indicate which
        identifier he supplies and the his choice for each identifier.

        :param list(str) identifiers: the identifiers of the input wires
        :return: the identifiers the user supplies
        :rtype: dict

    """
    print(
        'To start the protocol please indicate with y/n which wires you supply:'
        )
    chosen_wires = []
    for identifier in identifiers:
        decision = input('Do you supply {}? '.format(identifier))
        while True:
            if decision == 'y':
                chosen_wires.append(identifier)
                break
            elif decision == 'n':
                break
            else:
                decision = input(
                    "Sorry, didn't recognize that.                                   Indicate with y or n whether                                   you supply {}: "
                    .format(identifier))
    inputs = {}
    for identifier in chosen_wires:
        label_choice = input('Choice for {}: '.format(identifier))
        while True:
            if label_choice in '01':
                break
            else:
                label_choice = input(
                    'Sorry, you must supply either a 0                                       (indicating false) or a 1                                       (indicating true) for                                       wire {}: '
                    .format(identifier))
        inputs[identifier] = label_choice
    return inputs


def gammaln(data=None, name=None, attr=None, out=None, **kwargs):
    """Returns element-wise log of the absolute value of the gamma function \\
    of the input.

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

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

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

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


@staticmethod
def _order_deploys(radl):
    """
        Order the RADL deploys to assure VMs with Public IPs a set a the beginning
        (to avoid problems with cluster configuration)
        """
    pub = []
    priv = []
    for d in radl.deploys:
        if radl.hasPublicNet(d.id):
            pub.append(d)
        else:
            priv.append(d)
    wn = []
    fe = []
    for d in pub:
        if 'wn' in d.id:
            wn.append(d)
        else:
            fe.append(d)
    radl.deploys = fe + wn + priv


def dir_filter(item):
    """
    Accept each item which doesn't start with _
    :type item: str
    :param item: a string item to filter
    :return: true if item doesn't start with _
    """
    return not item.startswith('_')


def grantPermissionToPrincipal(permission_id, principal_id):
    """Assert that the permission is allowed for the principal.
        """


def symmetric_mass_ratio(m_1, m_2, M=None):
    """
    Compute the symmetric mass ratio, ``eta``, given the component masses,
    ``m_1`` and ``m_2``. Can optionally provide the total mass, ``M``, to save
    re-computing it with ``M = m_1 + m_2``.

    **Parameters**

    m_1: array-like, shape = S
        The mass of the first binary object.

    m_2: array-like, shape = S
        The mass of the second binary object.

    M: array-like, shape = S (optional)
        The total mass of the binary.

    **Returns**

    eta: array-like, shape = S
        The symmetric mass ratio of the binary.
    """
    if M is None:
        M = m_1 + m_2
    return m_1 * m_2 * M ** -2


def filter_traceback(tb_list):
    """Given a traceback as a list of strings, looks for common boilerplate and removes it."""
    """
        File "asynq/async_task.py", line 169, in asynq.async_task.AsyncTask._continue
        File "asynq/async_task.py", line 237, in asynq.async_task.AsyncTask._continue_on_generator
        File "asynq/async_task.py", line 209, in asynq.async_task.AsyncTask._continue_on_generator
    """
    TASK_CONTINUE = ['asynq.async_task.AsyncTask._continue',
        'asynq.async_task.AsyncTask._continue_on_generator',
        'asynq.async_task.AsyncTask._continue_on_generator'
        ], '___asynq_continue___'
    """
        File "asynq/decorators.py", line 161, in asynq.decorators.AsyncDecorator.__call__
        File "asynq/futures.py", line 54, in asynq.futures.FutureBase.value
        File "asynq/futures.py", line 63, in asynq.futures.FutureBase.value
        File "asynq/futures.py", line 153, in asynq.futures.FutureBase.raise_if_error
        File "<...>/python3.6/site-packages/qcore/errors.py", line 93, in reraise
           six.reraise(type(error), error, error._traceback)
        File "<...>/python3.6/site-packages/six.py", line 693, in reraise
           raise value
    """
    FUTURE_BASE = ['asynq.decorators.AsyncDecorator.__call__',
        'asynq.futures.FutureBase.value', 'asynq.futures.FutureBase.value',
        'asynq.futures.FutureBase.raise_if_error', 'reraise', 'six.reraise',
        'reraise', 'value'], '___asynq_future_raise_if_error___'
    """
        File "asynq/decorators.py", line 153, in asynq.decorators.AsyncDecorator.asynq
        File "asynq/decorators.py", line 203, in asynq.decorators.AsyncProxyDecorator._call_pure
        File "asynq/decorators.py", line 203, in asynq.decorators.AsyncProxyDecorator._call_pure
        File "asynq/decorators.py", line 204, in asynq.decorators.AsyncProxyDecorator._call_pure
        File "asynq/decorators.py", line 275, in asynq.decorators.async_call
    """
    CALL_PURE = ['asynq.decorators.AsyncDecorator.asynq',
        'asynq.decorators.AsyncProxyDecorator._call_pure',
        'asynq.decorators.AsyncProxyDecorator._call_pure',
        'asynq.decorators.AsyncProxyDecorator._call_pure',
        'asynq.decorators.async_call'], '___asynq_call_pure___'
    REPLACEMENTS = [TASK_CONTINUE, FUTURE_BASE, CALL_PURE]
    output = []
    i = 0
    while i < len(tb_list):
        did_replacement = False
        for text_to_match, replacement in REPLACEMENTS:
            matches = True
            j = 0
            while j < len(text_to_match) and i + j < len(tb_list):
                if text_to_match[j] not in tb_list[i + j]:
                    matches = False
                    break
                j += 1
            if matches and j == len(text_to_match):
                output.append('  ' + replacement + '\n')
                i = i + j
                did_replacement = True
                break
        if not did_replacement:
            output.append(tb_list[i])
            i += 1
    return output


@classmethod
def get_users_by_email(cls, email):
    """Return users instances for given email address"""
    raise NotImplementedError('Implement in subclass')


def crc16(string, value=0):
    """CRC-16 poly: p(x) = x**16 + x**15 + x**2 + 1

    @param string: Data over which to calculate crc.
    @param value: Initial CRC value.
    """
    crc16_table = []
    for byte in range(256):
        crc = 0
        for _ in range(8):
            if (byte ^ crc) & 1:
                crc = crc >> 1 ^ 40961
            else:
                crc >>= 1
            byte >>= 1
        crc16_table.append(crc)
    for ch in string:
        value = crc16_table[ord(ch) ^ value & 255] ^ value >> 8
    return value


def clipboard_copy():
    """Copies selected nodes to the clipboard

    """
    pass


def track_markers(backwards: bool=False, sequence: bool=False):
    """Track selected markers

    :param backwards: Backwards, Do backwards tracking
    :type backwards: bool
    :param sequence: Track Sequence, Track marker during image sequence rather than single image
    :type sequence: bool
    """
    pass


def priority_from_limit(limit_matrix):
    """
    Calculates the priority from a limit matrix, i.e. sums columns and divides by the number of
    columns.

    :param limit_matrix: The matrix to extract the priority from

    :return: 1d numpy array of the priority
    """
    rval = limit_matrix.sum(axis=1)
    adiv = sum(rval)
    if adiv != 0:
        rval /= adiv
    return rval


def get_messages(request):
    """
    Returns the message storage on the request if it exists, otherwise returns
    an empty list.
    """
    if hasattr(request, '_messages'):
        return request._messages
    else:
        return []


@classmethod
def create(cls, default=None, *args, **kwargs):
    """Create a model instance.

        :param default: The data structure that will be used to store the model state.
        :param \\*\\*kwargs: Any model attribute can be initialized with the matching keyword.

        :return: The newly created model.

        >>> class Cowboy(sheraf.Model):
        ...    table = "cowboy"
        ...    name = sheraf.SimpleAttribute(default="John Doe")
        ...
        >>> with sheraf.connection(commit=True):
        ...    cowboy = Cowboy.create()
        ...    assert "John Doe" == cowboy.name
        ...
        ...    cowboy = Cowboy.create(name="George Abitbol")
        ...    assert "George Abitbol" == cowboy.name
        ...
        ...    Cowboy.create(this_attribute_does_not_exist="something") #  raises a TypeError
        Traceback (most recent call last):
            ...
        TypeError: TypeError: create() got an unexpected keyword argument 'this_attribute_does_not_exist'

        The function can also create sub-models recursively:

        >>> class Horse(sheraf.InlineModel):
        ...     name = sheraf.SimpleAttribute()
        ...
        >>> class Cowboy(sheraf.Model):
        ...     table = "cowboy"
        ...     name = sheraf.SimpleAttribute(default="John Doe")
        ...     horse = sheraf.InlineModelAttribute(Horse)
        ...
        >>> with sheraf.connection():
        ...     cowboy = Cowboy.create(name="George Abitbol", horse={"name": "Jolly Jumper"})
        ...     cowboy.horse.name
        'Jolly Jumper'
        """
    mapping = (default or cls.default_mapping)()
    model = cls._decorate(mapping)
    for attribute, value in kwargs.items():
        if attribute not in model.attributes:
            raise TypeError(
                "TypeError: create() got an unexpected keyword argument '{}'"
                .format(attribute))
        model.__setattr__(attribute, value)
    for name, attribute in model.attributes.items():
        if not attribute.lazy and name not in kwargs:
            model.__setattr__(name, attribute.create(model))
    return model


def assert_type_int_or_float(df, variable, name_arg):
    """This function asserts if variable is a string or a list dataType."""
    assert isinstance(variable, (int, float)
        ), 'Error: %s argument must be a int or a float.' % name_arg


def midi2Hz(midi_val):
    """Receives midi note value and returns corresponding Herz frequency"""
    return 440 * 2 ** ((midi_val - 69) / 12.0)


def validate_statement(df, config):
    """Checks that the dataframe statement has a valid rolling balance"""
    df = df.copy()
    debit = config['columns']['debit']
    credit = config['columns']['credit']
    balance = config['columns']['balance']
    df[[debit, credit, balance]] = df[[debit, credit, balance]].fillna(0)
    prev_balance = df[balance] - df[credit] + df[debit]
    invalid = (abs(prev_balance.shift(-1) - df[balance]) > 1e-06).any()
    return not invalid


def layer_representer(dumper, v):
    """function for representing layer as a dictionary for use by yaml"""
    d = v.export_dict()
    output = dumper.represent_mapping(u'!Layer', d)
    return output


def set_connect_timeout(timeout):
    """
        set_connect_timeout

        Set the connect timeout (in seconds)

        @param timeout: the connect timeout (in seconds)
        @type timeout: C{int}
        @return: None
        """


def format_gro_coord(resid, resname, aname, seqno, xyz):
    """ Print a line in accordance with .gro file format, with six decimal points of precision

    Nine decimal points of precision are necessary to get forces below 1e-3 kJ/mol/nm.

    @param[in] resid The number of the residue that the atom belongs to
    @param[in] resname The name of the residue that the atom belongs to
    @param[in] aname The name of the atom
    @param[in] seqno The sequential number of the atom
    @param[in] xyz A 3-element array containing x, y, z coordinates of that atom

    """
    return '%5i%-5s%5s%5i % 13.9f % 13.9f % 13.9f' % (resid, resname, aname,
        seqno, xyz[0], xyz[1], xyz[2])


def paths_clear(only_selected: bool=False):
    """Clear path caches for all objects, hold Shift key for selected objects only

    :param only_selected: Only Selected, Only clear paths from selected objects
    :type only_selected: bool
    """
    pass


def invalidate(to_invalidate):
    """ Invalidate the indicated objects.

        o If 'to_invalidate' is a string, treat it as an OID.

        o Otherwise, iterate over it as a sequence of OIDs.

        o Any OID corresponding to a p-class will cause the corresponding
            p-class to be removed from the cache.

        o For all other OIDs, ghostify the corrsponding object and
            remove it from the ring.
        """


@staticmethod
def _decode(data):
    """
        Ugly trick because of mixed content coming back from pypykatz
        Can be either string, bytes, None
        """
    try:
        return data.decode('utf-8', 'backslashreplace')
    except:
        return data


@classmethod
def collapse_data(cls, data, function=None, kdims=None, **kwargs):
    """
        Deprecated method to perform collapse operations, which may
        now be performed through concatenation and aggregation.
        """
    raise NotImplementedError('Collapsing not implemented for %s.' % cls.
        __name__)


def bond_is_conjugated(bond):
    """Get whether the bond is conjugated.
    Parameters
    ----------
    bond : rdkit.Chem.rdchem.Bond
        RDKit bond instance.
    Returns
    -------
    list
        List containing one bool only.
    """
    return [bond.GetIsConjugated()]


def setprofile(func):
    """Set a profile function for all threads started from the threading module.

    The func will be passed to sys.setprofile() for each thread, before its
    run() method is called.

    """
    global _profile_hook
    _profile_hook = func


def postalCodeLookup(countryCode, postalCode):
    """
        Looks up matching locations for this country and postal code.

        :param countryCode: ISO 3166-1 country code, eg u"PL" for Poland
        :type countryCode: ``unicode``
        :param postalCode: Localized postal code, eg u"30-015" for Krakow
        :type postalCode: ``unicode``
        :returns: The list of locations matching this postal code.

        Upstream documentation on this method:
        http://www.geonames.org/export/web-services.html#postalCodeLookupJSON

        Returns the value for the "postalcodes" key in the response.
        """


@classmethod
def from_string(cls, date_str):
    """Populate date components from date string of the format YYYY[-MM[-DD]]"""
    parts = date_str.split('-')
    obj = cls()
    if len(parts) > 0:
        obj.year = int(parts[0])
    if len(parts) > 1:
        obj.month = int(parts[1])
    if len(parts) > 2:
        obj.day = int(parts[2])
    return obj


def get_headers(environ):
    """
    Retrieve the HTTP headers from a WSGI environment dictionary.  See
    https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
    """
    headers = {}
    for key, value in environ.items():
        if key.startswith('HTTP_') and key != 'HTTP_HOST':
            headers[key[5:].replace('_', '-')] = value
        elif key in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            headers[key.replace('_', '-')] = value
    return headers


@staticmethod
def _parse_filter(value):
    """Parse timer filters."""
    return value.split(',') if value is not None else None


def mubicom(path, use_ssl=True):
    """Returns a full url for the given path."""
    protocol = 'https' if use_ssl else 'http'
    return '{0}://mubi.com/{1}'.format(protocol, path.lstrip('/'))


@classmethod
def first_or_new(cls, **attributes):
    """
        Get the first record matching the attributes or instantiate it.

        :param attributes: The instance attributes
        :type attributes: dict

        :return: The new instance
        :rtype: Model
        """
    instance = cls.where(attributes).first()
    if instance is not None:
        return instance
    return cls(**attributes)


def parse_reference(reference):
    """
    parse provided image reference into <image_repository>:<tag>

    :param reference: str, e.g. (registry.fedoraproject.org/fedora:27)
    :return: collection (tuple or list), ("registry.fedoraproject.org/fedora", "27")
    """
    if ':' in reference:
        im, tag = reference.rsplit(':', 1)
        if '/' in tag:
            return reference, 'latest'
        else:
            return im, tag
    else:
        return reference, 'latest'


def select(*names):
    """Select fields with given names in order

        Return a new IFormFields that is a selection from the original
        IFormFields that has the named fields in the specified order.
        """


def treepositions_no_leaves(tree):
    """
    Returns all the tree positions in the given tree which are not
    leaf nodes.
    """
    treepositions = tree.treepositions()
    prefixes = set()
    for pos in treepositions:
        for length in range(len(pos)):
            prefixes.add(pos[:length])
    return [pos for pos in treepositions if pos in prefixes]


@classmethod
def process(cls, config_input, logger=None):
    """Parse the input field of the config dict.

        :param config_input:    The configuration dict.
        :param logger:          A logger object for logging debug info. [default: None]

        :returns: stars, wcs, pointing

        stars is a list of Star instances with the initial data.
        wcs is a dict of WCS solutions indexed by chipnum.
        pointing is either a galsim.CelestialCoord or None.
        """
    import piff
    input_handler_class = getattr(piff, 'Input' + config_input.get('type',
        'Files'))
    input_handler = input_handler_class(config_input, logger)
    stars = input_handler.makeStars(logger)
    if len(stars) == 0:
        raise RuntimeError('No stars read in from input catalog(s).')
    wcs = input_handler.getWCS(logger)
    pointing = input_handler.getPointing(logger)
    return stars, wcs, pointing


@classmethod
def from_js_error(cls, js_error):
    """Convert a JSON Schema ValidationError instance into a
        ValidationError instance.
        """
    e = cls()
    e.path = list(getattr(js_error, 'releative_path', js_error.path))
    e.message = js_error.message
    e.validator = js_error.validator
    e.validator_value = js_error.validator_value
    e.raw = js_error._contents()
    return e


def bookmark_delete(index: int=-1):
    """Delete selected bookmark

    :param index: Index
    :type index: int
    """
    pass


def set_testmode(testing):
    """Sets the package testing mode.
    """
    global testmode
    testmode = testing


def layers_show_all(all: bool=True):
    """Make all armature layers visible

    :param all: All Layers, Enable all layers or just the first 16 (top row)
    :type all: bool
    """
    pass


def formula_2016_01_01(foyer_fiscal, period, parameters):
    """
        Plus-values 2016 et + entrant dans le calcul du revenu fiscal de référence
        """
    f3sa = foyer_fiscal('f3sa', period)
    f3sj = foyer_fiscal('f3sj', period)
    f3sk = foyer_fiscal('f3sk', period)
    f3tz = foyer_fiscal('f3tz', period)
    f3vc = foyer_fiscal('f3vc', period)
    f3vd_i = foyer_fiscal.members('f3vd', period)
    f3vf_i = foyer_fiscal.members('f3vf', period)
    f3vi_i = foyer_fiscal.members('f3vi', period)
    f3vm = foyer_fiscal('f3vm', period)
    f3vp = foyer_fiscal('f3vp', period)
    f3vq = foyer_fiscal('f3vq', period)
    f3vr = foyer_fiscal('f3vr', period)
    f3vt = foyer_fiscal('f3vt', period)
    f3vy = foyer_fiscal('f3vy', period)
    f3vz = foyer_fiscal('f3vz', period)
    f3we = foyer_fiscal('f3we', period)
    f3wi = foyer_fiscal('f3wi', period)
    f3wj = foyer_fiscal('f3wj', period)
    f3vi = foyer_fiscal.sum(f3vi_i)
    f3vd = foyer_fiscal.sum(f3vd_i)
    f3vf = foyer_fiscal.sum(f3vf_i)
    rpns_pvce_i = foyer_fiscal.members('rpns_pvce', period)
    rpns_pvce = foyer_fiscal.sum(rpns_pvce_i)
    return (f3sa + f3sj + f3sk + f3tz + f3vc + f3vd + f3vf + f3vi + f3vm +
        f3vp + (f3vq - f3vr) + f3vt + f3vy + f3vz + f3we + f3wi + f3wj +
        rpns_pvce)


@classmethod
def round_to_context(cls, x, ctx):
    """Not actually used???"""
    return cls.dtype._round_to_context(x, ctx=ctx, strict=False)


def make_iterable(obj):
    """Pack obj into a list if it is not iterable, yet."""
    if not isinstance(obj, (list, tuple, set)):
        obj = [obj]
    return obj


def push():
    """Add to the model-view matrix stack.

    """
    pass


@classmethod
def _reset_alias(cls):
    """Reset the alias so that it is recomputed the next time an instance
        is created."""
    cls._alias = None


def split(sets: list, quantity: int):
    """
    splits a list into smaller lists, each of sub list contains
    the (quantity) of items

    Args:
    * [sets] list to split into smaller lists
    * [quantity] the items in each sub list

    Returns:
    * [list] a new list of sub lists
    """
    output = []
    sublist = None
    max_contains = quantity
    for item in sets:
        if sublist is None:
            sublist = []
        if max_contains > 0:
            sublist.append(item)
            max_contains = max_contains - 1
        if max_contains == 0:
            output.append(sublist)
            sublist = []
            max_contains = quantity
    if len(sublist) > 0:
        output.append(sublist)
    return output


def def_api_middleware(handle, resource, request):
    """No-op API-level middleware; used as a sane default for when no
    middleware is configured.
    """
    return handle(resource, request)


def all_equiv_sat(fsm, winning, agents):
    """
    Return the states s of winning such that all states indistinguishable
    from s by agents are in winning.

    fsm -- a MAS representing the system;
    winning -- a BDD representing a set of states of fsm;
    agents -- a set of agents.

    """
    nwinning = ~winning & fsm.bddEnc.statesInputsMask
    return ~fsm.equivalent_states(nwinning & fsm.reachable_states,
        frozenset(agents)) & winning


def log_exception(exc_type, exc_obj, exc_tb):
    """Log an exception. Can be used as replacement for sys.excepthook."""
    import traceback, logging
    exc_info = traceback.format_exception(exc_type, exc_obj, exc_tb)
    for l in exc_info:
        logging.error(l.strip())


def is_integer_like(val):
    """Returns validation of a value as an integer."""
    try:
        int(val)
        return True
    except (TypeError, ValueError, AttributeError):
        return False


@classmethod
def redo(cls):
    """Re-does the last undone action.
        """
    return cls.build_send_payload('redo', {}), None


def __call__(context):
    """
        Invoke the behavior-specific factory if the context can be adapted
        """


def is_list_like(obj):
    """ True if object type is similar to list, tuple etc. """
    return isinstance(obj, (tuple, list))


def is_undefined(value):
    """
    Indicate whether the specified value is undefined or not.

    A string is undefined if it is null or if it does not contain any data.

    :param value: a value.

    :return: `True` if the value is undefined, `False` otherwise.
    """
    return value is None or isinstance(value, str) and len(value.strip()) == 0


def cross_correlate(xoft, hoft):
    """Cross-correlate two `TimeSeries` by matched-filter

    Parameters
    ----------
    xoft : `~gwpy.timeseries.TimeSeries`
        the `TimeSeries` data to analyze

    hoft : `~gwpy.timeseries.TimeSeries`
        a `TimeSeries` data to use as a matched-filter

    Returns
    -------
    out : `~gwpy.timeseries.TimeSeries`
        the output of a single phase matched-filter
    """
    if hoft.sample_rate.value < xoft.sample_rate.value:
        xoft = xoft.resample(hoft.sample_rate.value)
    elif hoft.sample_rate.value > xoft.sample_rate.value:
        hoft = hoft.resample(xoft.sample_rate.value)
    out = xoft.correlate(hoft, window='hann')
    return out


def __getitem__(name):
    """Return the file or resource directory with the given name
        as an object
        """


@classmethod
def shadow_pyczmq(cls, ctx):
    """Shadow an existing pyczmq context

        ctx is the FFI `zctx_t *` pointer

        .. versionadded:: 14.1
        """
    from pyczmq import zctx
    from zmq.utils.interop import cast_int_addr
    underlying = zctx.underlying(ctx)
    address = cast_int_addr(underlying)
    return cls(shadow=address)


def get_rc_version(value=None):
    """
    Returns a tuple of the iviewer version.
    """
    if value is None:
        from .version import RC as value
    return value


def root_nodes(graph, nodes):
    """Return the set of all nodes that are not dependencies of other nodes."""
    from functools import reduce
    nodes = set(nodes.keys())
    return reduce(set.difference, graph.values(), nodes)


def reverse(pipe):
    """ this has the same funcitonality as builtins.reversed(), except this
        doesnt complain about non-reversable things. If you didnt know already,
        a generator needs to fully run in order to be reversed.
    """
    for i in reversed(list(pipe)):
        yield i


@classmethod
def create(cls, req):
    """create a new user, using data from req"""
    self = cls.new()
    self.store(req)
    return self


def get_xml_path(name):
    """ Get the XML path of a file from the name. """
    file_name_section = name.rsplit('/', 1)[1].split('.')[0]
    return file_name_section + '/' + file_name_section + '.XML'


def _with_labels(labels):
    """Crea un predicado para nltk.Tree que devuelve True si su etiqueta está
    dentro de un conjunto de valores.

    Args:
        list: Lista de valores.

    Returns:
        function: función que retorna True si el llamado a 'label' de su
            argumento retorna un objeto que pertenece a un conjunto de valores.

    """
    return lambda t: t.label() in set(labels)


def count(item):
    """Return number of occurrences of value"""