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


def timeline_postprocessing(timeline):
    """ Eliminates Nones in timeline so other software don't error.
        Extra lists are built for the vars with nones, each list with one point
        for each None in the form (wall_time, prev_value).
    """
    current_time_nones = []
    audio_time_nones = []
    old_current_time = 0
    old_audio_time = 0
    filtered_timeline = []
    for wall_time, pt, audio_time, current_time, fnum, rt in timeline:
        if current_time is None:
            current_time = old_current_time
            current_time_nones.append((wall_time, old_current_time))
        else:
            current_time_time = current_time
        if audio_time is None:
            audio_time = old_audio_time
            audio_time_nones.append((wall_time, old_audio_time))
        else:
            old_audio_time = audio_time
        filtered_timeline.append((wall_time, pt, audio_time, current_time,
            fnum, rt))
    return filtered_timeline, current_time_nones, audio_time_nones


def authorization_adapter(field, ctx, source_dict, target_obj):
    """
    Default adapter works on single field (non iterable)
    """
    name = field._compute_property(ctx)
    source = field.to_python_value(ctx, source_dict[name])
    target = field.to_python_value(ctx, field._get(target_obj))
    return name, source, target


def _list_remove_duplicates(list_with_dup):
    """
    Return a copy of a list without duplicated items.

    :param list_with_dup: Input list that may contain duplicates
    :return: List that does not contain duplicates
    """
    set_no_dup = set(list_with_dup)
    list_no_dup = list(set_no_dup)
    return list_no_dup


def _str_to_iv(givstr, template_extension=0):
    """Converts a string representation 'chr:start-end' into genomic coordinates."""
    sub = givstr.split(':')
    if len(sub) == 1:
        return sub[0],
    chr_ = sub[0]
    second_split = sub[1].split('-')
    if second_split[0] == '':
        second_split = second_split[1:]
        second_split[0] = '-' + second_split[0]
    if second_split[1] == '':
        raise ValueError('Invalid genomic location string: {}'.format(givstr))
    start = int(second_split[0])
    end = int(second_split[1])
    return chr_, start - template_extension, end + template_extension


def write_altsw(target, altsw):
    """
    Write alternate software release to file.

    :param target: File to write to.
    :type target: file

    :param altsw: Radio software release version, if different.
    :type altsw: str
    """
    if altsw is not None:
        target.write('RADIO SOFTWARE RELEASE: {0}\n'.format(altsw))


def get_random_parameter_sampler(param_distributions, n_iter):
    """
    Sample parameters from given distributions.

    :param param_distributions : dict
        Dictionary where the keys are parameters and values
        are distributions from which a parameter is to be sampled by calling the disribution.
    :param n_iter : integer
        Number of parameter settings that are produced.
    :return: dict of string to any
        Yields dictionaries mapping each estimator parameter to
        as sampled value.
    """
    items = sorted(param_distributions.items())
    for _ in range(n_iter):
        params = dict()
        for k, v in items:
            params[k] = v()
        yield params


def fake_experimenter(label):
    """
    Marshal faked experimenter when id is -1
    Load omero.client.ui.menu.dropdown.everyone.label as username
    """
    return {'id': -1, 'omeName': label, 'firstName': label, 'lastName': ''}


def get_keywords():
    """Get the keywords needed to look up the version information."""
    git_refnames = '$Format:%d$'
    git_full = '$Format:%H$'
    git_date = '$Format:%ci$'
    keywords = {'refnames': git_refnames, 'full': git_full, 'date': git_date}
    return keywords


def __call__(cls, *args, **kwargs):
    """Call cls as a function. It checks if the instance already exists.

        Args:
            *args: Variable length argument list.
            **kwargs: Arbitrary keyword arguments.

        Returns:
            object: Instance from the class that uses this pattern.
        """
    if cls not in cls._instances:
        cls._instances[cls] = super().__call__(*args, **kwargs)
    return cls._instances[cls]


def sum_stats(stats_data):
    """
    Summarize the bounces, complaints, delivery attempts and rejects from a
    list of datapoints.
    """
    t_bounces = 0
    t_complaints = 0
    t_delivery_attempts = 0
    t_rejects = 0
    for dp in stats_data:
        t_bounces += int(dp['Bounces'])
        t_complaints += int(dp['Complaints'])
        t_delivery_attempts += int(dp['DeliveryAttempts'])
        t_rejects += int(dp['Rejects'])
    return {'Bounces': t_bounces, 'Complaints': t_complaints,
        'DeliveryAttempts': t_delivery_attempts, 'Rejects': t_rejects}


def with_metaclass(meta, base=object):
    """Create a base class with a metaclass."""
    return meta('NewBase', (base,), {})


def load_txt(path):
    """
  Read all lines from a text file.

  Parameters
  ----------
  path : str
    Path to the text file.

  Returns
  -------
  list
    A list of lines.
  """
    with open(path, 'r') as f:
        lines = f.read().splitlines()
    return lines


def sum_(hash_func, data):
    """
    // sum returns the hash of the input data using the specified algorithm.
    """
    if data is None:
        return None
    result = hash_func(data)
    if hasattr(result, 'digest'):
        result = result.digest()
    return result


def hide(unselected: bool=False):
    """Hide (un)selected vertices, edges or faces

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


@classmethod
def dump_trace(cls, output, config_name, indent_count=0):
    """Dump trace configuration to output stream.

        :param output: output stream to write to
        :param config_name: name of configuration class instance to be referenced when initializing trace
        :param indent_count: indentation that should be used to indent source
        """
    indent = indent_count * 4 * ' '
    for _ in cls._trace_logging:
        output.write('%s%s.trace_by_logging()\n' % (indent, config_name))
    for entry in cls._trace_storage:
        output.write('%s%s.trace_by_func(functools.partial(%s.%s, %s))\n' %
            (indent, config_name, entry[0].class_name, entry[1], entry[0].
            var_name))
    for entry in cls._trace_function:
        output.write('%sfrom %s import %s\n' % (indent, entry[0], entry[1]))
        output.write('%s%s.trace_by_func(%s)\n' % (indent, config_name,
            entry[1]))
    for entry in cls._trace_sentry:
        output.write('%s%s.trace_by_sentry(dsn=%s)\n' % (indent,
            config_name, "'%s'" % entry if entry is not True else None))


def dissolve_degenerate(threshold: float=0.0001):
    """Dissolve zero area faces and zero length edges

    :param threshold: Merge Distance, Minimum distance between elements to merge
    :type threshold: float
    """
    pass


def lambd_NH3_NO3_CB89(T, P):
    """n-a: ammonia nitrate [CB89]."""
    lambd = -0.01
    valid = T == 298.15
    return lambd, valid


def remove_rows_matching(df, column, match):
    """
    Return a ``DataFrame`` with rows where `column` values match `match` are removed.

    The selected `column` series of values from the supplied Pandas ``DataFrame`` is compared
    to `match`, and those rows that match are removed from the DataFrame.

    :param df: Pandas ``DataFrame``
    :param column: Column indexer
    :param match: ``str`` match target
    :return: Pandas ``DataFrame`` filtered
    """
    df = df.copy()
    mask = df[column].values != match
    return df.iloc[(mask), :]


@classmethod
def withToken(cls, token, environment, compression_enabled=True,
    backoff_config=None):
    """ Initialization of the smartobjects client

        The client exposes the Events, Objects, Owners and Search services.
        Initialization will fetch an API token with the id and secret provided.

        :param client_id (string): client_id part of the OAuth 2.0 credentials (available in your dashboard)
        :param client_secret (string): client_secret part of the OAuth 2.0 credentials (available in your dashboard)
        :param environment: a URL to the targeted environment (Environments.Sandbox or Environments.Production can be used)
            (note: client_id and client_secret are unique per environment)
        :param compression_enabled: gzip compress the request body (default: True)
        :param backoff_config: retry with exponential backoff (default: None)

        :note: Do not expose publicly code containing your client_id and client_secret
        .. seealso:: examples/simple_workflow.py
        """
    return cls(client_id=None, client_secret=None, environment=environment,
        compression_enabled=compression_enabled, backoff_config=
        backoff_config, token_override=token)


def create_project(conn, project):
    """
    Create a new project into the projects table
    :param conn:
    :param project:
    :return: project id
    """
    sql = """ INSERT INTO data(name,begin_date,end_date)
              VALUES(?,?,?) """
    cur = conn.cursor()
    cur.execute(sql, project)
    return cur.lastrowid


@staticmethod
def _handle_selection(selection):
    """
        Dummy placeholder for returning selection from chooser.
        """
    return selection


def exc_info(exception):
    """
    Get exc_info tuple from exception
    """
    return type(exception), exception, exception.__traceback__


def find(function, iterable):
    """ Returns the first item in the list for which function(item) is True, None otherwise.
    """
    for x in iterable:
        if function(x) == True:
            return x


def value_length(tokens: list):
    """Calculates string length from given tokens"""
    l = 0
    for token in tokens:
        l += len(token) if isinstance(token, str) else len(token.name)
    return l


@classmethod
def from_web(cls, table: dict) ->'Slave':
    """Initialize a new instance of the Slave class with data from
        an Install Package details page on the WHDLoad website
        (www.whdload.de).

        :param table: A dictionary of slave details from a WHDLoad Package
                      web page.
        :return: A new instance of the Slave class.
        """
    return cls(table=table)


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 metadata():
    """ Return metadata method """


def reset_oid(cursor):
    """
        Cause the sequence of OIDs to begin again from the beginning.
        """


@staticmethod
def extract_title(soup):
    """Sometimes search results have no contents. This function tries to extract something sensible."""
    if isinstance(soup.contents, list) and soup.contents:
        return soup.contents[0]
    if soup.get('href') and 'torrent' in soup.get('href'):
        return soup.get('href').rsplit('/', 1)[-1]


def process_request(req):
    """Process the request.

        Return a `(template_name, data)` pair, where `data` is a
        dictionary of substitutions for the Jinja2 template (the
        template context, in Jinja2 terms).

        Optionally, the return value can also be a `(template_name,
        data, metadata)` triple, where `metadata` is a `dict` with
        hints for the template engine or the web front-end.

        Keys supported are:

          - `'content_type'`: the mimetype used for content delivery;
            "text/html" is assumed if the key is not present or the
            `metadata` was not specified

          - `'text'`: a boolean value indicating whether the Jinja2
            auto-escaping feature should be deactivated
            (``text=True``) or not (``text=False``); defaults to
            ``False``, suitable for generating HTML or XML content

          - `'fragment'`: a boolean value indicating whether the
            generated content will be used as part of another page
            (``fragment=True``) or as a stand-alone page
            (``fragment=False``), the default

          - `'domain'`: a string value indicating the translation
            domain to which the translated strings in the template
            belong to

        Note that if template processing should not occur, this method
        can simply send the response itself (see `Request` methods)
        and not return anything, as the `Request` methods raise a
        `RequestDone` exception.

        :Since 1.0: Clearsilver templates are no longer supported.

        :Since 1.1.2: the rendering `method` (xml, xhtml or text) may be
           returned as a fourth parameter in the tuple, but if not specified
           it will be inferred from the `content_type` when rendering the
           template.

        :Since 1.3.2: returns a pair, or a tuple in which the third
           element is a `dict` instead of a string like in the old
           API.  Note that the old API (`(template, data,
           content_type)` where `content_type` is a string or `None`)
           is still supported. When used, this means that `template`
           is a legacy Genshi template. This support for the old API
           will be removed in Trac 1.5.1, in which `metadata` will
           always be a `dict` or `None` when specified.

        """


def diff(other, match=None, clean=False):
    """Find differences between this manifest and another.

        This manifest is compared to ``other``.

        If ``match`` is provided, the two manifests are filtered against this
        matcher and only entries satisfying the matcher are compared.

        If ``clean`` is True, unchanged files are included in the returned
        object.

        Returns a dict with paths as keys and values of 2-tuples of 2-tuples of
        the form ``((node1, flag1), (node2, flag2))`` where ``(node1, flag1)``
        represents the node and flags for this manifest and ``(node2, flag2)``
        are the same for the other manifest.
        """


def update_projects():
    """Called when projects may have changed, to refresh the available
        projects"""


def escape_chars(text, chars):
    """Helper function to escape uncomfortable characters."""
    text = str(text)
    chars = list(set(chars))
    if '\\' in chars:
        chars.remove('\\')
        chars.insert(0, '\\')
    for ch in chars:
        text = text.replace(ch, '\\' + ch)
    return text


@staticmethod
def gen_ocl_init(parent, kernels, num_queues):
    """
        Generates a subroutine to initialise the OpenCL environment and
        construct the list of OpenCL kernel objects used by this PSy layer.

        :param parent: the node in the f2pygen AST representing the module                        that will contain the generated subroutine.
        :type parent: :py:class:`psyclone.f2pygen.ModuleGen`
        :param kernels: List of kernel names called by the PSy layer.
        :type kernels: list of str
        :param int num_queues: total number of queues needed for the OpenCL                                implementation.
        """
    from psyclone.f2pygen import SubroutineGen, DeclGen, AssignGen, CallGen, UseGen, CommentGen, CharDeclGen, IfThenGen
    sub = SubroutineGen(parent, 'psy_init')
    parent.add(sub)
    sub.add(UseGen(sub, name='fortcl', only=True, funcnames=['ocl_env_init',
        'add_kernels']))
    sub.add(DeclGen(sub, datatype='logical', save=True, entity_decls=[
        'initialised'], initial_values=['.False.']))
    sub.add(CommentGen(sub,
        ' Check to make sure we only execute this routine once'))
    ifthen = IfThenGen(sub, '.not. initialised')
    sub.add(ifthen)
    ifthen.add(AssignGen(ifthen, lhs='initialised', rhs='.True.'))
    ifthen.add(CommentGen(ifthen, ' Initialise the OpenCL environment/device'))
    ifthen.add(CallGen(ifthen, 'ocl_env_init', [num_queues]))
    ifthen.add(CommentGen(ifthen,
        ' The kernels this PSy layer module requires'))
    nkernstr = str(len(kernels))
    ifthen.add(CharDeclGen(ifthen, length='30', entity_decls=[
        'kernel_names({0})'.format(nkernstr)]))
    for idx, kern in enumerate(kernels):
        ifthen.add(AssignGen(ifthen, lhs='kernel_names({0})'.format(idx + 1
            ), rhs='"{0}"'.format(kern)))
    ifthen.add(CommentGen(ifthen,
        ' Create the OpenCL kernel objects. Expects to find all of the compiled'
        ))
    ifthen.add(CommentGen(ifthen, ' kernels in PSYCLONE_KERNELS_FILE.'))
    ifthen.add(CallGen(ifthen, 'add_kernels', [nkernstr, 'kernel_names']))


def chunk_iter(chunk_size, upperbound):
    """Yields back chunk size pieces from zero to upperbound - 1."""
    chunk = []
    for i in range(0, upperbound):
        chunk.append(i)
        if len(chunk) == chunk_size:
            yield chunk
            chunk = []


def select(extend: bool=False, location: float=(0.0, 0.0)):
    """Select tracking markers

    :param extend: Extend, Extend selection rather than clearing the existing selection
    :type extend: bool
    :param location: Location, Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds
    :type location: float
    """
    pass


def _has_method(arg, method):
    """Returns true if the given object has a method with the given name.

    :param arg: the object

    :param method: the method name
    :type method: string

    :rtype: bool
    """
    return hasattr(arg, method) and callable(getattr(arg, method))


def intersection(L1, L2):
    """Helper function to calculate intersection of two given lines that were
    defined with the upper 'line' function
    """
    D = L1[0] * L2[1] - L1[1] * L2[0]
    Dx = L1[2] * L2[1] - L1[1] * L2[2]
    Dy = L1[0] * L2[2] - L1[2] * L2[0]
    if D != 0:
        x = Dx / D
        y = Dy / D
        return x, y
    else:
        return False


def tio_is_callable(tree_item):
    """Returns 'True' if the tree item object is callable."""
    return str(callable(tree_item.obj))


def _histplot_mpl_op(values, values2, rotated, ax, hist_kwargs):
    """Add a histogram for the data to the axes."""
    if values2 is not None:
        raise NotImplementedError('Insert hexbin plot here')
    bins = hist_kwargs.pop('bins')
    ax.hist(values, bins=bins, **hist_kwargs)
    if rotated:
        ax.set_yticks(bins[:-1])
    else:
        ax.set_xticks(bins[:-1])
    if hist_kwargs.get('label') is not None:
        ax.legend()
    return ax


def parse_atrv(v):
    """
    Parses the battery voltage and returns it in [Volt] as float with 1 decimal place
    :param str v: e.g. "12.3V"
    :return float:
    """
    try:
        return float(v.replace('V', ''))
    except ValueError:
        return None


def iterate_path_definitions(paths):
    """Iterate over all `PathDefinition` instances in `paths`

    :param dict[str, dict[str, flask_rebar.rebar.PathDefinition]] paths:
    :return Iterator[PathDefinition]
    """
    for methods in paths.values():
        for definition in methods.values():
            yield definition


def getReaders():
    """
        Return the list of file descriptors currently monitored for input
        events by the reactor.

        @return: the list of file descriptors monitored for input events.
        @rtype: C{list} of C{IReadDescriptor}
        """


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

        :param UnshareFolderError val:
        :rtype: JobError
        """
    return cls('unshare_folder_error', val)


def guess_fill_char(left_comp, right_comp):
    """
    For the case where there is no annotated synteny we will try to guess it
    """
    return '*'
    if (left_comp.src == right_comp.src and left_comp.strand != right_comp.
        strand):
        if left_comp.end == right_comp.start:
            return '-'
    return '*'


def __reduce__():
    """Reduce an object to contituent parts for serialization.
        """


def brush_add():
    """Add new Grease Pencil drawing brush for the active Grease Pencil data-block

    """
    pass


def generic_find_fk_constraint_names(table, columns, referenced, insp):
    """Utility to find foreign-key constraint names in alembic migrations"""
    names = set()
    for fk in insp.get_foreign_keys(table):
        if fk['referred_table'] == referenced and set(fk['referred_columns']
            ) == columns:
            names.add(fk['name'])
    return names


def clear():
    """
        Clear all objects from the folder.  Calling this is equivalent to
        calling ``.remove`` for each key in the folder.
        """


def add_task(name, timespec, user, command, environment=None):
    """
    Add a cron task.

    The *command* will be run as *user* periodically.

    You can use any valid `crontab(5)`_ *timespec*, including the
    ``@hourly``, ``@daily``, ``@weekly``, ``@monthly`` and ``@yearly``
    shortcuts.

    You can also provide an optional dictionary of environment variables
    that should be set when running the periodic command.

    Examples::

        from fabtools.cron import add_task

        # Run every month
        add_task('cleanup', '@monthly', 'alice', '/home/alice/bin/cleanup.sh')

        # Run every tuesday and friday at 5:30am
        add_task('reindex', '30 5 * * 2,4', 'bob', '/home/bob/bin/reindex.sh')

    .. _crontab(5): http://manpages.debian.net/cgi-bin/man.cgi?query=crontab&sektion=5

    """
    if environment is None:
        environment = {}
    lines = []
    for key, value in environment.iteritems():
        lines.append('%(key)s=%(value)s\n' % locals())
    lines.append('%(timespec)s %(user)s %(command)s\n' % locals())
    from fabtools.require.files import file as require_file
    require_file(path='/etc/cron.d/%(name)s' % locals(), contents=''.join(
        lines), owner='root', mode='0644', use_sudo=True)


def bool2cmdint(command_bool):
    """Convert a boolean to either 0 for true  or -1 for false."""
    if command_bool:
        return 0
    return -1


def _assemble(kind, args, body=None):
    """Assemble a celery script command."""
    if body is None:
        return {'kind': kind, 'args': args}
    return {'kind': kind, 'args': args, 'body': body}


def spinn5_eth_coords(width, height, root_x=0, root_y=0):
    """Generate a list of board coordinates with Ethernet connectivity in a
    SpiNNaker machine.

    Specifically, generates the coordinates for the Ethernet connected chips of
    SpiNN-5 boards arranged in a standard torus topology.

    .. warning::

        In general, applications should use
        :py:class:`rig.machine_control.MachineController.get_system_info` and
        :py:meth:`~rig.machine_control.machine_controller.SystemInfo.ethernet_connected_chips`
        to gather the coordinates of Ethernet connected chips which are
        actually functioning. For example::

            >> from rig.machine_control import MachineController
            >> mc = MachineController("my-machine")
            >> si = mc.get_system_info()
            >> print(list(si.ethernet_connected_chips()))
            [((0, 0), "1.2.3.4"), ((4, 8), "1.2.3.5"), ((8, 4), "1.2.3.6")]

    Parameters
    ----------
    width, height : int
        Width and height of the system in chips.
    root_x, root_y : int
        The coordinates of the root chip (i.e. the chip used to boot the
        machine), e.g. from
        :py:attr:`rig.machine_control.MachineController.root_chip`.
    """
    root_x %= 12
    root_x %= 12
    w = (width + 11) // 12 * 12
    h = (height + 11) // 12 * 12
    for x in range(0, w, 12):
        for y in range(0, h, 12):
            for dx, dy in ((0, 0), (4, 8), (8, 4)):
                nx = (x + dx + root_x) % w
                ny = (y + dy + root_y) % h
                if nx < width and ny < height:
                    yield nx, ny


def normalize(arr):
    """
    Linear normalization
    http://en.wikipedia.org/wiki/Normalization_%28image_processing%29
    """
    arr = arr.astype('float')
    for i in range(3):
        minval = arr[..., i].min()
        maxval = arr[..., i].max()
        if minval != maxval:
            arr[..., i] -= minval
            arr[..., i] *= 255.0 / (maxval - minval)
    return arr


def get_model_fields(model, fields=None, exclude=None):
    """
    Returns a generator of fields for a model.

    Arguments::

        ``fields`` is an optional list to return only those field names.
        ``exclude`` is an optional list to exclude field names.
    """
    opts = model._meta
    for field in sorted(opts.fields + opts.many_to_many):
        if fields and not field.name in fields:
            continue
        if exclude and field.name in exclude:
            continue
        yield field


def hello_plugin():
    u"""A simple view function"""
    return u'Hello World, this is served from an extension'


def get_server_tasks():
    """Get a list of tasks that the server will be responsible to run

        A task is a object implementing :class:`.IPluginTask`.

        :returns: a list of tasks
        """
    pass


def format_cftime_datetime(date):
    """Converts a cftime.datetime object to a string with the format:
    YYYY-MM-DD HH:MM:SS.UUUUUU
    """
    return '{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}.{:06d}'.format(date.
        year, date.month, date.day, date.hour, date.minute, date.second,
        date.microsecond)


def _get_class_repr(cls, type_, bound, keyfunc, keyfunc_name):
    """Return a class representation using the slice parameters.

        Args:
            type_: The type the class was sliced with. This will always be
                _STR_TYPE.
            bound: The boundaries specified for the values of type_.
            keyfunc: The comparison function used to check the value
                boundaries. This will always be builtins.len().
            keyfunc_name: The name of keyfunc. This will always be 'len'.

        Returns:
            A string representing the class.
        """
    return '{}.{}[{}]'.format(cls.__module__, cls.__name__, cls.
        _get_bound_repr(bound))


def count_encoding(df, col):
    """Get count(frequency) encoding of a column of any type.

    inputs:
    df - pandas dataframe
    col - column name

    outputs:
    count encoded column
    """
    if isinstance(col, list):
        col = col[0]
    return df[col].map(df[col].value_counts(dropna=False))


@staticmethod
def format_result(input):
    """From: http://stackoverflow.com/questions/13062300/convert-a-dict-to-sorted-dict-in-python
        """
    return {}


def enable_policy_type_in_root(org_client, root_id):
    """
    Ensure policy type 'SERVICE_CONTROL_POLICY' is enabled in the
    organization root.
    """
    p_type = org_client.list_roots()['Roots'][0]['PolicyTypes']
    if not p_type or p_type[0]['Type'] == 'SERVICE_CONTROL_POLICY' and p_type[0
        ]['Status'] != 'ENABLED':
        org_client.enable_policy_type(RootId=root_id, PolicyType=
            'SERVICE_CONTROL_POLICY')


def negative(data=None, out=None, name=None, **kwargs):
    """Numerical negative of the argument, element-wise.

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

       - negative(default) = default
       - negative(row_sparse) = row_sparse
       - negative(csr) = csr

    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 time_avt(acceleration, delta_velocity):
    """Usage: time_avt(acceleration of object, change in speed)"""
    return delta_velocity / acceleration


@classmethod
def build_items(cls, *args, **kwargs):
    """
        Build items to be input to handle(item)

        :param kwargs:
        :return:
        """
    pass


def movetopmostbookmarks(repo, oldtopmost, newtopmost):
    """Move bookmark from oldtopmost to newly created topmost

    This is arguably a feature and we may only want that for the active
    bookmark. But the behavior is kept compatible with the old version for now.
    """
    if not oldtopmost or not newtopmost:
        return
    oldbmarks = repo.nodebookmarks(oldtopmost)
    if oldbmarks:
        with repo.lock(), repo.transaction(b'histedit') as tr:
            marks = repo._bookmarks
            changes = []
            for name in oldbmarks:
                changes.append((name, newtopmost))
            marks.applychanges(repo, tr, changes)


def compose(d1, d2):
    """Compose two homomorphisms given by dicts."""
    res = dict()
    for key, value in d1.items():
        if value in d2.keys():
            res[key] = d2[value]
    return res


def remove_doubles(threshold: float=0.0002):
    """Remove selected particles close enough of others

    :param threshold: Merge Distance, Threshold distance withing which particles are removed
    :type threshold: float
    """
    pass


def get_account():
    """
    Gets information about the current  Account resource.
    See also: AWS API Documentation

    :example: response = client.get_account()

    :rtype: dict
    :return: {
        'cloudwatchRoleArn': 'string',
        'throttleSettings': {
            'burstLimit': 123,
            'rateLimit': 123.0
        },
        'features': [
            'string',
        ],
        'apiKeyVersion': 'string'
    }

    :returns:
    (string) --

    """
    pass


def fromordinal(ordinal):
    """Return the datetime from the proleptic Gregorian ordinal.

        January 1 of year 1 has ordinal 1. ValueError is raised unless
        1 <= ordinal <= datetime.max.toordinal().
        The hour, minute, second and microsecond of the result are all 0, and
        tzinfo is None.
        """


@classmethod
def fieldset_with_legend(cls, legend_text):
    """Returns an XPath to find a FieldSet with the given `legend_text`.

        .. versionadded:: 3.2
        """
    return cls(
        '//fieldset[legend[normalize-space(node())=normalize-space("%s")]]' %
        legend_text)


def first(sequence, message=None):
    """The first item in that sequence

    If there aren't any, raise a ValueError with that message

    >>> assert first([1, 2, 3]) == 1
    """
    try:
        return next(iter(sequence))
    except StopIteration:
        raise ValueError(message or f'Sequence is empty: {sequence}')


def _msg(prefix, *arg):
    """
    Display a message with the given color.
    """
    msg = ''
    if prefix:
        msg += prefix
    print(msg, *arg)


def _str_2_tuple(x):
    """Ensure `x` is at least a 1-tuple of str.
    """
    return (x,) if isinstance(x, str) else tuple(x)


def reduce_min(input):
    """Returns the min of all elements in the input tensor.

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

    Returns
    -------
    Tensor
        A framework-specific tensor with shape (1,)
    """
    pass


def describe_build(BuildId=None):
    """
    Retrieves properties for a build. To get a build record, specify a build ID. If successful, an object containing the build properties is returned.
    See also: AWS API Documentation

    :example: response = client.describe_build(
        BuildId='string'
    )

    :type BuildId: string
    :param BuildId: [REQUIRED]
            Unique identifier for a build to retrieve properties for.

    :rtype: dict
    :return: {
        'Build': {
            'BuildId': 'string',
            'Name': 'string',
            'Version': 'string',
            'Status': 'INITIALIZED'|'READY'|'FAILED',
            'SizeOnDisk': 123,
            'OperatingSystem': 'WINDOWS_2012'|'AMAZON_LINUX',
            'CreationTime': datetime(2015, 1, 1)
        }
    }

    """
    pass


def loop_separate(loop: 'bmesh.types.BMLoop'):
    """Rip a vertex in a face away and add a new vertex.

    :param loop: The loop to separate.
    :type loop: 'bmesh.types.BMLoop'
    """
    pass


def CellAbsorption(ElList, Volume):
    """Compute unit cell absorption

    :param dict ElList: dictionary of element contents including mu and
      number of atoms be cell
    :param float Volume: unit cell volume
    :returns: mu-total/Volume
    """
    muT = 0
    for El in ElList:
        muT += ElList[El]['mu'] * ElList[El]['FormulaNo']
    return muT / Volume


@classmethod
def should_check_origin(cls, handler):
    """Should the Handler check for CORS origin validation?

        Origin check should be skipped for token-authenticated requests.

        Returns:
        - True, if Handler must check for valid CORS origin.
        - False, if Handler should skip origin check since requests are token-authenticated.
        """
    return not cls.is_token_authenticated(handler)


def id_or_nid(song_dict):
    """Equivalent to ``d.get('id') or d['nid']``.

    Uploaded songs have an id key, while AA tracks
    have a nid key, which can often be used interchangably.
    """
    return song_dict.get('id') or song_dict['nid']


def _get_time_diff(data):
    """
    Generates the time difference used to determine granularity and
    to generate the period

      data : pandas DataFrame
        composed of input data
    """
    return data.index[1] - data.index[0]


def isreal(obj):
    """
    Tests if the argument is a real number (float or integer)

    :param obj: Object
    :type  obj: any

    :rtype: boolean
    """
    return obj is not None and not isinstance(obj, bool) and (isinstance(
        obj, int) or isinstance(obj, float))


def if_current_page(context, link_url, positive=True, negative=False):
    """
    Return one of the passed parameters if the URL passed is the current one.
    For consistency reasons, we use the link_url of the page.
    """
    page = context['__CACTUS_CURRENT_PAGE__']
    return positive if page.link_url == link_url else negative


@classmethod
def sqlType(cls):
    """
        Underlying SQL storage type for this UDT.
        """
    raise NotImplementedError('UDT must implement sqlType().')


def filter_filename(title, substr='-'):
    """can't contain path"""
    import re
    title = re.sub('[\\/:*?"<>|]', substr, title)
    return title


def ssl_required(fn):
    """
    Decorator - marks a route as needing ssl.

    NOTE: This most go BEFORE the route!
    """
    fn.ssl_required = True
    return fn


def _check_data_exists(ldframe, names):
    """Assert that any required annotator has been run.

    Useful to call at the start of an aggregator to avoid confusing error
    message later in the call.
    """
    for name in names:
        if name not in ldframe.keys():
            raise KeyError("Requires annotator '" + name +
                "', which was not found")


@classmethod
def generate_mask(cls, shape, min_value, max_value, start_at, end_at):
    """Generate a linear horizontal gradient mask.

        Added in 0.4.0.

        Parameters
        ----------
        shape : tuple of int
            Shape of the image. The mask will have the same height and
            width.

        min_value : number
            Minimum value of the gradient in interval ``[0.0, 1.0]``.

        max_value : number
            Maximum value of the gradient in interval ``[0.0, 1.0]``.

        start_at : number
            Position on the x-axis where the linear gradient starts, given as
            a fraction of the axis size. Interval is ``[0.0, 1.0]``.

        end_at : number
            Position on the x-axis where the linear gradient ends, given as
            a fraction of the axis size. Interval is ``[0.0, 1.0]``.

        Returns
        -------
        ndarray
            ``float32`` mask array with same height and width as the image.
            Values are in ``[0.0, 1.0]``.

        """
    return cls._generate_mask(axis=0, shape=shape, min_value=min_value,
        max_value=max_value, start_at=start_at, end_at=end_at)


def _normalize_catalog(catalog):
    """Convert a catalog to a compatible format."""
    services = []
    for v3_service in catalog:
        service = {'type': v3_service['type']}
        try:
            service['name'] = v3_service['name']
        except KeyError:
            pass
        regions = {}
        for v3_endpoint in v3_service.get('endpoints', []):
            region_name = v3_endpoint.get('region')
            try:
                region = regions[region_name]
            except KeyError:
                region = {'region': region_name} if region_name else {}
                regions[region_name] = region
            interface_name = v3_endpoint['interface'].lower() + 'URL'
            region[interface_name] = v3_endpoint['url']
        service['endpoints'] = list(regions.values())
        services.append(service)
    return services


def _get_version_info():
    """
    Return astropy and photutils versions.

    Returns
    -------
    result : str
        The astropy and photutils versions.
    """
    from astropy import __version__
    astropy_version = __version__
    from photutils import __version__
    photutils_version = __version__
    return 'astropy: {0}, photutils: {1}'.format(astropy_version,
        photutils_version)


def bond_atoms(atom_list):
    """
    Attempt to merge allowed atoms given allowed rules and combinations.
    This will be based off an R group of a given fragment.
    Loss function to define a good molecule - More bonds, more interactions, less atoms.
    Simply as ratios:
    bonds-fulfilled / atom
    interactions / atom
    Need to keep the ratio as low
    Just train on single molecules, then try merging two, then more and more.
    :param atom_list: the list of allowed atoms, x,y,z and atom desc (atomic number and hybridization state)
    :return:
    """
    pass


def formula_2012_01_01(foyer_fiscal, period, parameters):
    """
        Investissements dans les DOM-TOM dans le cadre d'une entreprise.
        """
    f7ks = foyer_fiscal('f7ks', period)
    f7kt = foyer_fiscal('f7kt', period)
    f7ku = foyer_fiscal('f7ku', period)
    f7lg = foyer_fiscal('f7lg', period)
    f7lh = foyer_fiscal('f7lh_2012', period)
    f7li = foyer_fiscal('f7li', period)
    f7ma = foyer_fiscal('f7ma', period)
    f7mb = foyer_fiscal('f7mb', period)
    f7mc = foyer_fiscal('f7mc', period)
    f7mm = foyer_fiscal('f7mm', period)
    f7mn = foyer_fiscal('f7mn', period)
    f7nu = foyer_fiscal('f7nu', period)
    f7nv = foyer_fiscal('f7nv', period)
    f7nw = foyer_fiscal('f7nw', period)
    f7ny = foyer_fiscal('f7ny', period)
    f7pa = foyer_fiscal('f7pa_2012', period)
    f7pb = foyer_fiscal('f7pb_2012', period)
    f7pd = foyer_fiscal('f7pd_2012', period)
    f7pe = foyer_fiscal('f7pe_2012', period)
    f7pf = foyer_fiscal('f7pf_2012', period)
    f7ph = foyer_fiscal('f7ph', period)
    f7pi = foyer_fiscal('f7pi_2012', period)
    f7pj = foyer_fiscal('f7pj_2012', period)
    f7pl = foyer_fiscal('f7pl', period)
    f7pm = foyer_fiscal('f7pm', period)
    f7pn = foyer_fiscal('f7pn', period)
    f7po = foyer_fiscal('f7po', period)
    f7pp = foyer_fiscal('f7pp_2012', period)
    f7pr = foyer_fiscal('f7pr_2012', period)
    f7ps = foyer_fiscal('f7ps_2012', period)
    f7pt = foyer_fiscal('f7pt_2012', period)
    f7pu = foyer_fiscal('f7pu', period)
    f7pw = foyer_fiscal('f7pw', period)
    f7px = foyer_fiscal('f7px', period)
    f7py = foyer_fiscal('f7py', period)
    f7pz = foyer_fiscal('f7pz', period)
    f7qe = foyer_fiscal('f7qe', period)
    f7qf = foyer_fiscal('f7qf', period)
    f7qg = foyer_fiscal('f7qg', period)
    f7qi = foyer_fiscal('f7qi', period)
    f7qo = foyer_fiscal('f7qo_2012', period)
    f7qp = foyer_fiscal('f7qp_2012', period)
    f7qr = foyer_fiscal('f7qr_2012', period)
    f7qv = foyer_fiscal('f7qv', period)
    f7qz = foyer_fiscal('f7qz_2012', period)
    f7rg = foyer_fiscal('f7rg', period)
    f7ri = foyer_fiscal('f7ri', period)
    f7rj = foyer_fiscal('f7rj', period)
    f7rk = foyer_fiscal('f7rk', period)
    f7rl = foyer_fiscal('f7rl', period)
    f7rm = foyer_fiscal('f7rm', period)
    f7ro = foyer_fiscal('f7ro', period)
    f7rp = foyer_fiscal('f7rp', period)
    f7rq = foyer_fiscal('f7rq', period)
    f7rr = foyer_fiscal('f7rr', period)
    f7rt = foyer_fiscal('f7rt', period)
    f7ru = foyer_fiscal('f7ru', period)
    f7rv = foyer_fiscal('f7rv', period)
    f7rw = foyer_fiscal('f7rw', period)
    f7ry = foyer_fiscal('f7ry', period)
    return (f7ks + f7kt + f7ku + f7lg + f7lh + f7li + f7ma + f7mb + f7mc +
        f7mm + f7mn + f7pz + f7nu + f7nv + f7nw + f7ny + f7pa + f7pb + f7pd +
        f7pe + f7pf + f7ph + f7pi + f7pj + f7pl + f7pm + f7pn + f7po + f7pp +
        f7pr + f7ps + f7pt + f7pu + f7pw + f7px + f7py + f7qe + f7qf + f7qg +
        f7qi + f7qo + f7qp + f7qr + f7qv + f7qz + f7rg + f7ri + f7rj + f7rk +
        f7rl + f7rm + f7ro + f7rp + f7rq + f7rr + f7rt + f7ru + f7rv + f7rw +
        f7ry)


def _expr_rshift_as_multiplication_of_reverse_order(lhs, rhs):
    """The multiply express will reverse order.
    """
    return rhs * lhs


def _translate_snapshot_summary_view(context, vol):
    """Maps keys for snapshots summary view."""
    d = {}
    d['id'] = vol['id']
    d['volumeId'] = vol['volume_id']
    d['status'] = vol['status']
    d['size'] = vol['volume_size']
    d['createdAt'] = vol['created_at']
    d['displayName'] = vol['display_name']
    d['displayDescription'] = vol['display_description']
    return d


def delete_member(id):
    """Delete an existing member.

        DELETE /entity/id -> 204 No Content

        """


def solveur(candidats, fonction):
    """Essaye de résoudre l'ensemble des candidats.

    Boucle infinie qui prend des candidats dans la queue, tente de les
    resoudre, et applique la fonction quand ils sont resolu.
    """
    while True:
        grille = candidats.get()
        grille.remplit()
        if grille.resolu:
            fonction(grille)
        elif grille.impossible:
            pass
        else:
            x, y = grille.cherche_plus_proche()
            for valeur in grille.possible_case[x][y]:
                copie = grille.copy()
                copie.affecte((x, y), valeur)
                candidats.put(copie)
        candidats.task_done()


@classmethod
def save(cls, report, *args):
    """
        получение и сохранение экземпляра
        """
    instance = cls._get_or_create(report)
    instance = cls._prepare_instance(report, instance, *args)
    instance.save()


def _is_ssl_on_directive(entry):
    """Checks if an nginx parsed entry is an 'ssl on' directive.

    :param list entry: the parsed entry
    :returns: Whether it's an 'ssl on' directive
    :rtype: bool

    """
    return isinstance(entry, list) and len(entry) == 2 and entry[0
        ] == 'ssl' and entry[1] == 'on'


def nh_compare_labels(Gx, Gy):
    """Compare labels function as defined in :cite:`Hido2009ALG`.

    Parameters
    ----------
    G_{x,y} : tuple, len=2
        Graph tuples of two elements, consisting of vertices sorted by
        (labels, vertices) and edge-labels dict.

    Returns
    -------
    kernel : Number
        The kernel value.

    """
    vx, vy = Gx[0], Gy[0]
    nv_x, nv_y = len(Gx[0]), len(Gy[0])
    Lx, Ly = Gx[1], Gy[1]
    c, a, b = 0, 0, 0
    while a < nv_x and b < nv_y:
        la = Lx[vx[a]]
        lb = Ly[vy[b]]
        if la is None:
            break
        if la == lb:
            c += 1
            a += 1
            b += 1
        elif la < lb:
            a += 1
        else:
            b += 1
    return c / float(nv_x + nv_y - c)


def _format_object_mask(objectmask):
    """Format the new style object mask.

    This wraps the user mask with mask[USER_MASK] if it does not already
    have one. This makes it slightly easier for users.

    :param objectmask: a string-based object mask

    """
    objectmask = objectmask.strip()
    if not objectmask.startswith('mask') and not objectmask.startswith('['):
        objectmask = 'mask[%s]' % objectmask
    return objectmask


def arcsin(data=None, out=None, name=None, **kwargs):
    """Returns element-wise inverse sine of the input array.

    The input should be in the range `[-1, 1]`.
    The output is in the closed interval of [:math:`-\\pi/2`, :math:`\\pi/2`].

    .. math::
       arcsin([-1, -.707, 0, .707, 1]) = [-\\pi/2, -\\pi/4, 0, \\pi/4, \\pi/2]

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

       - arcsin(default) = default
       - arcsin(row_sparse) = row_sparse
       - arcsin(csr) = csr

    Defined in src/operator/tensor/elemwise_unary_op_trig.cc:L187

    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 denormalize(tensor, stats):
    """
    denormalize a tensor using a running mean and std

    :param tensor: (TensorFlow Tensor) the normalized tensor
    :param stats: (RunningMeanStd) the running mean and std of the input to normalize
    :return: (TensorFlow Tensor) the restored tensor
    """
    if stats is None:
        return tensor
    return tensor * stats.std + stats.mean


def items():
    """Returns an iterable list of couples key - value,
        as a list of tuples.
        """


def run(*args, **kwargs):
    """ Run the streaming demo """
    raise NotImplementedError


def setprevtime_local(timeinseconds, timestr):
    """Like setprevtime but only set the local version"""
    global prevtime, prevtimestr
    prevtime, prevtimestr = timeinseconds, timestr


def thermalDistortion(x, y, stim_param):
    """Apply thermal distortion correction to positions in events list.

    No correction is necessary and none will be applied if the slopes are
    all 0 and the intercepts are all 1.

    Parameters
    ----------
    x: array like
        Array of detector X coordinates.

    y: array like
        Array of detector Y coordinates.

    stim_param: dictionary of lists
        The dictionary has keys i0, i1, x0, xslope, y0, yslope.

    Returns
    -------
    boolean
        True if a correction was actually applied in at least one of
        the time intervals.
    """
    x0 = stim_param['x0']
    xslope = stim_param['xslope']
    y0 = stim_param['y0']
    yslope = stim_param['yslope']
    actually_done = False
    if 'i0' in stim_param:
        i0 = stim_param['i0']
        i1 = stim_param['i1']
    else:
        i0 = [0]
        i1 = [len(x)]
    for n in range(len(i0)):
        i = i0[n]
        j = i1[n]
        if x0[n] != 0.0 or xslope[n] != 1.0 or y0[n] != 0.0 or yslope[n
            ] != 1.0:
            x[i:j] = x0[n] + x[i:j] * xslope[n]
            y[i:j] = y0[n] + y[i:j] * yslope[n]
            actually_done = True
    return actually_done


def preloaded_multi_sgd_mom_update(*data, **kwargs):
    """Momentum update function for Stochastic Gradient Descent (SGD) optimizer.

    Momentum update has better convergence rates on neural networks. Mathematically it looks
    like below:

    .. math::

      v_1 = \\alpha * \\nabla J(W_0)\\\\
      v_t = \\gamma v_{t-1} - \\alpha * \\nabla J(W_{t-1})\\\\
      W_t = W_{t-1} + v_t

    It updates the weights using::

      v = momentum * v - learning_rate * gradient
      weight += v

    Where the parameter ``momentum`` is the decay rate of momentum estimates at each epoch.

    Defined in src/operator/contrib/preloaded_multi_sgd.cc:L91

    Parameters
    ----------
    data : Symbol[]
        Weights, gradients, momentum, learning rates and weight decays
    momentum : float, optional, default=0
        The decay rate of momentum estimates at each epoch.
    rescale_grad : float, optional, default=1
        Rescale gradient to grad = rescale_grad*grad.
    clip_gradient : float, optional, default=-1
        Clip gradient to the range of [-clip_gradient, clip_gradient] If clip_gradient <= 0, gradient clipping is turned off. grad = max(min(grad, clip_gradient), -clip_gradient).
    num_weights : int, optional, default='1'
        Number of updated weights.

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

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


def _collector_url_from_hostport(secure, host, port, use_thrift):
    """
    Create an appropriate collector URL given the parameters.

    `secure` should be a bool.
    """
    if secure:
        protocol = 'https://'
    else:
        protocol = 'http://'
    if use_thrift:
        return ''.join([protocol, host, ':', str(port),
            '/_rpc/v1/reports/binary'])
    else:
        return ''.join([protocol, host, ':', str(port), '/api/v2/reports'])


def getDSR():
    """ Returns True if the device is done to send data. Some drivers
        block in a loop waiting for this function returns True before call
        read.
        """


def _check_ancestors(path, match, ancestors):
    """
    Require N ancestors to be in common with original path and matched path
    """
    pl = path.lower()
    ml = match.lower()
    if pl == ml:
        return True
    if len(ml.split('/')) < len(pl.split('/')) and pl.endswith(ml):
        return True
    return ml.endswith('/'.join(pl.split('/')[(ancestors + 1) * -1:]))


def add_to_toolbar(fig, *widgets):
    """
    Adds a set of button-like widgets to the toolbar of a given figure.

    :param fig: a ``plt.Figure``
    :param widgets: A number of class names that extend
      ``mpl.backend_tools.ToolBase``. They must have at least defind the
      ``name`` and ``tool_group`` fields.
    """
    manager = fig.canvas.manager
    tm = manager.toolmanager
    for w in widgets:
        tm.add_tool(w.name, w)
        manager.toolbar.add_tool(tm.get_tool(w.name), w.tool_group)


def return_last(last):
    """Return last item in a list or tuple"""
    return last[-1]


def _draw_rectangle(data, obj, draw_options):
    """Return the PGFPlots code for rectangles.
    """
    label = obj.get_label()
    if label == '':
        return data, []
    handles, labels = obj.axes.get_legend_handles_labels()
    labelsFound = [label for h, label in zip(handles, labels) if obj in h.
        get_children()]
    if len(labelsFound) == 1:
        label = labelsFound[0]
    left_lower_x = obj.get_x()
    left_lower_y = obj.get_y()
    ff = data['float format']
    cont = ('\\draw[{}] (axis cs:' + ff + ',' + ff +
        ') rectangle (axis cs:' + ff + ',' + ff + ');\n').format(','.join(
        draw_options), left_lower_x, left_lower_y, left_lower_x + obj.
        get_width(), left_lower_y + obj.get_height())
    if label != '_nolegend_' and label not in data['rectangle_legends']:
        data['rectangle_legends'].add(label)
        cont += '\\addlegendimage{{ybar,ybar legend,{}}};\n'.format(','.
            join(draw_options))
        cont += '\\addlegendentry{{{}}}\n\n'.format(label)
    return data, cont


def rename(oldPath, newPath, **kwargs):
    """rename the file oldPath to newPath"""
    import os
    return os.rename(oldPath, newPath, **kwargs)


def sig_cmp(u, v, order):
    """
    Compare two signatures by extending the term order to K[X]^n.

    u < v iff
        - the index of v is greater than the index of u
    or
        - the index of v is equal to the index of u and u[0] < v[0] w.r.t. order

    u > v otherwise

    """
    if u[1] > v[1]:
        return -1
    if u[1] == v[1] and order(u[0]) < order(v[0]):
        return -1
    return 1


def strip_quotes(string):
    """Remove both single and doulbe quotes from the beginning and ending
of given string."""
    result = string.strip('"')
    return result.strip("'")


def pathfor(name, **matchdict):
    """Use request.webapp.pathfor() to generate the url."""


def get_command(t):
    """
        return the command to be used based on the current time
    """
    if t < 43200 and t > 18000:
        command = 'morning'
    elif t > 43200 and t < 61200:
        command = 'afternoon'
    elif t > 61200 and t < 72000:
        command = 'evening'
    else:
        command = 'night'
    return command


def _split(geohash, chars=None):
    """Splits an interleaved binary string into lon and lat arrays."""
    lon, lat = [], []
    for i, c in enumerate(geohash):
        if chars is not None and i >= chars:
            break
        lon.append(c) if i % 2 == 0 else lat.append(c)
    return lon, lat


def chomp(s):
    """Remove trailing
 from s."""
    index = len(s)
    while index > 0 and s[index - 1] == '\n':
        index -= 1
    return s[:index]


def check_modification(community):
    """Check whether a community already carries a modification.

    Arguments
    ---------
    community : micom.Community
        The community class to check.

    Raises
    ------
    ValueError
        If the community already carries a modification and adding another
        would not be safe.

    """
    if community.modification is not None:
        raise ValueError('Community already carries a modification ({})!'.
            format(community.modification))


def convert_x_domain(mpl_plot_bounds, mpl_max_x_bounds):
    """Map x dimension of current plot to plotly's domain space.

    The bbox used to locate an axes object in mpl differs from the
    method used to locate axes in plotly. The mpl version locates each
    axes in the figure so that axes in a single-plot figure might have
    the bounds, [0.125, 0.125, 0.775, 0.775] (x0, y0, width, height),
    in mpl's figure coordinates. However, the axes all share one space in
    plotly such that the domain will always be [0, 0, 1, 1]
    (x0, y0, x1, y1). To convert between the two, the mpl figure bounds
    need to be mapped to a [0, 1] domain for x and y. The margins set
    upon opening a new figure will appropriately match the mpl margins.

    Optionally, setting margins=0 and simply copying the domains from
    mpl to plotly would place axes appropriately. However,
    this would throw off axis and title labeling.

    Positional arguments:
    mpl_plot_bounds -- the (x0, y0, width, height) params for current ax **
    mpl_max_x_bounds -- overall (x0, x1) bounds for all axes **

    ** these are all specified in mpl figure coordinates

    """
    mpl_x_dom = [mpl_plot_bounds[0], mpl_plot_bounds[0] + mpl_plot_bounds[2]]
    plotting_width = mpl_max_x_bounds[1] - mpl_max_x_bounds[0]
    x0 = (mpl_x_dom[0] - mpl_max_x_bounds[0]) / plotting_width
    x1 = (mpl_x_dom[1] - mpl_max_x_bounds[0]) / plotting_width
    return [x0, x1]


def substitute_dict(expr, subs):
    """
    Select and apply appropriate substitution method based on expr type.

    Parameters
    ----------

    expr : dict.
        Expressions wich parameters are to be substitute.

    subs : dic
        Substitution dictionary '{symb : sub}'.

    Return
    ------

    expr_subs : same type as expr
        The resulting expression. The substitution applies on the keys and the
        values of the dictionary.
    """
    for k in expr.keys():
        try:
            expr[k] = expr[k].subs(subs)
        except AttributeError:
            pass
    return expr


def _has_method(arg, method):
    """Returns true if the given object has a method with the given name.

    :param arg: the object

    :param method: the method name
    :type method: string

    :rtype: bool
    """
    return hasattr(arg, method) and callable(getattr(arg, method))


def _fit_single_layer_loop(param):
    """
    Loop body to be passed to the parallel pool.

    Note: `func_fit_single_layer` can be:
        (1) helper_hh_model.fit_HH_x_single_layer(), or
        (2) helper_mkz_model.fit_H4_x_single_layer()
        etc.
    """
    damping_curve, other_params = param
    (func_fit_single_layer, use_scipy, pop_size, n_gen, lower_bound_power,
        upper_bound_power, eta, seed, show_fig, verbose) = other_params
    best_para = func_fit_single_layer(damping_curve, use_scipy=use_scipy,
        n_gen=n_gen, eta=eta, pop_size=pop_size, lower_bound_power=
        lower_bound_power, upper_bound_power=upper_bound_power, seed=seed,
        show_fig=show_fig, verbose=verbose, parallel=False)
    return best_para


def canonical_taxon(taxon):
    """Get taxon name without suffix."""
    if taxon.startswith('s__'):
        generic, specific = taxon.split()
        if '_' in specific:
            canonical_specific = specific.rsplit('_', 1)[0]
            return '{} {}'.format(generic, canonical_specific)
        else:
            return taxon
    rank_prefix = ''
    if taxon[1:3] == '__':
        rank_prefix = taxon[0:3]
        taxon = taxon[3:]
    if '_' in taxon:
        taxon = taxon.rsplit('_', 1)[0]
    return rank_prefix + taxon


def read_file(filename):
    """
    Return the contents of the file with the given filename as a string

    >>> write_file('read_write_file.txt', 'Hello World')
    >>> read_file('read_write_file.txt')
    'Hello World'
    >>> os.unlink('read_write_file.txt')
    """
    with open(filename) as in_fh:
        return in_fh.read()


def p_expr_big_op_ud(p):
    """p_expr_big_op_ud : p_expr_big_op_u DOWN LBRACE ID EQ expression RBRACE"""
    operator, up = p[1]
    p[0] = operator, p[4], p[6], up


def popwhile(predicate, iterable):
    """Generator function yielding items of iterable while predicate holds for each item

    :param predicate: function taking an item returning bool
    :param iterable: iterable
    :returns: iterable (generator function)
    """
    while iterable:
        item = iterable.pop()
        if predicate(item):
            yield item
        else:
            break


@classmethod
def _objectify_permission(cls, permission):
    """ Convert string representation if special Pyramid permission
        into valid Pyramid ACL permission objects.
        """
    return cls.PERMISSIONS_INVERTED.get(permission, permission)


def change_same_starting_points(flaglist):
    """Gets points at which changes begin"""
    change_points = []
    same_points = []
    in_change = False
    if flaglist and not flaglist[0]:
        same_points.append(0)
    for x, flag in enumerate(flaglist):
        if flag and not in_change:
            change_points.append(x)
            in_change = True
        elif not flag and in_change:
            same_points.append(x)
            in_change = False
    return change_points, same_points


def turbulent_Gnielinski(Re, Pr, fd):
    """Calculates internal convection Nusselt number for turbulent flows
    in pipe according to [2]_ as in [1]_. This is the most recent general
    equation, and is strongly recommended.

    .. math::
        Nu = \\frac{(f/8)(Re-1000)Pr}{1+12.7(f/8)^{1/2}(Pr^{2/3}-1)}

    Parameters
    ----------
    Re : float
        Reynolds number, [-]
    Pr : float
        Prandtl number, [-]
    fd : float
        Darcy friction factor [-]

    Returns
    -------
    Nu : float
        Nusselt number, [-]

    Notes
    -----
    Range according to [1]_ is 0.5 < Pr ≤ 2000  and 2300 ≤ Re ≤ 5*10^6.

    Examples
    --------
    >>> turbulent_Gnielinski(Re=1E5, Pr=1.2, fd=0.0185)
    254.62682749359632

    References
    ----------
    .. [1] Rohsenow, Warren and James Hartnett and Young Cho. Handbook of Heat
       Transfer, 3E. New York: McGraw-Hill, 1998.
    .. [2] Gnielinski, V. (1976). New Equation for Heat and Mass Transfer in
       Turbulent Pipe and Channel Flow, International Chemical Engineering,
       Vol. 16, pp. 359–368.
    """
    return fd / 8.0 * (Re - 1000.0) * Pr / (1.0 + 12.7 * (fd / 8.0) ** 0.5 *
        (Pr ** (2 / 3.0) - 1.0))


def djangouser_auth(username, password, request):
    """
    Check username and password against
    django.contrib.auth.models.User
    """
    from django.contrib.auth.models import User
    try:
        user = User.objects.get(username=username)
        if user.check_password(password):
            request.user = user
            return True
        else:
            return False
    except User.DoesNotExist:
        return False


def suggestfields():
    """
  Fields available in ``gbif_suggest()`` function
  """
    return ['key', 'datasetTitle', 'datasetKey', 'nubKey', 'parentKey',
        'parent', 'kingdom', 'phylum', 'class', 'order', 'family', 'genus',
        'species', 'kingdomKey', 'phylumKey', 'classKey', 'orderKey',
        'familyKey', 'genusKey', 'speciesKey', 'species', 'canonicalName',
        'authorship', 'accordingTo', 'nameType', 'taxonomicStatus', 'rank',
        'numDescendants', 'numOccurrences', 'sourceId',
        'nomenclaturalStatus', 'threatStatuses', 'synonym',
        'higherClassificationMap']


def r_to_depth(x, interval):
    """Computes rainfall depth (mm) from rainfall intensity (mm/h)

    Parameters
    ----------
    x : float,
        float or array of float
        rainfall intensity in mm/h
    interval : number
        time interval (s) the values of `x` represent

    Returns
    -------
    output : float
        float or array of float
        rainfall depth (mm)

    """
    return x * interval / 3600.0


def uvs_reverse():
    """Flip direction of UV coordinates inside faces

    """
    pass


def solve_and_print_results(equations, exelist, results_list):
    """
    creates temporary python file to execute solving in it's own environment
    tmp python file records the results output to a tmp text file
    the output text file is send back to the user
    """
    pyfile = open('tmp.py', 'w')
    librarylist = ['']
    for i in librarylist:
        pyfile.write(i + '\n')
    for i in exelist:
        pyfile.write(str(i) + '\n')
    results = ['textfile = open("tmp.txt", "w")',
        'textfile.write("Entered Equations: \\n\\n")', 'for i in' + str(
        equations) + ': ', '    textfile.write(i + "\\n")',
        'textfile.write("\\nResults: \\n\\n")']
    for i in results:
        pyfile.write(i + '\n')
    for i in results_list:
        pyfile.write('print("' + i + ' = " + str(float(' + i +
            ')), file=textfile)\n')
    pyfile.write('textfile.close()\n')
    pyfile.close()
    import os
    os.system('python tmp.py')
    with open('tmp.txt', mode='r') as f:
        line_list = []
        while True:
            line = f.readline()
            if len(line) == 0:
                break
            line_list.append(line)
    outstring = ''.join(list(filter(None, line_list)))
    return outstring


def correct_spacer(read, umi, umi_pos, spacer_seq):
    """
    (str, str, int, str) -> bool
    :param reads: Read sequence
    :param umis: Umi sequence
    :param umi_pos: Expected position 0-based on umi in read
    :spacer_seq: Spacer sequence

    Return False if umi not in read or spacer in sequence but not at expected position and return True otherwise
    """
    Correct = True
    if umi.upper() not in read.upper():
        Correct = False
    else:
        read = read[umi_pos + len(umi):]
        if not read.upper().startswith(spacer_seq.upper()):
            Correct = False
    return Correct


def vertex_weight_delete(weight_group: int=-1):
    """Delete this weight from the vertex (disabled if vertex group is locked)

    :param weight_group: Weight Index, Index of source weight in active vertex group
    :type weight_group: int
    """
    pass


def rgb2hex(rgb):
    """
    method will convert given rgb tuple (or list) to a
    hex format (such as #00AAFF)
    """
    return '#%02x%02x%02x' % rgb


def int_to_bin(number, width=32):
    """
    Convert an integer into its binary representation in a bytes object.
    Width is the amount of bits to generate. If width is larger than the actual
    amount of bits required to represent number in binary, sign-extension is
    used. If it's smaller, the representation is trimmed to width bits.
    Each "bit" is either '\\x00' or '\\x01'. The MSBit is first.

    Examples:

        >>> int_to_bin(19, 5)
        b'\\x01\\x00\\x00\\x01\\x01'
        >>> int_to_bin(19, 8)
        b'\\x00\\x00\\x00\\x01\\x00\\x00\\x01\\x01'
    """
    if number < 0:
        number += 1 << width
    i = width - 1
    bits = bytearray(width)
    while number and i >= 0:
        bits[i] = number & 1
        number >>= 1
        i -= 1
    return bytes(bits)


@classmethod
def set_dict_value(cls, dict_IN, name_IN, value_IN):
    """
        Accepts dictionary, name, and value.  If dictionary or name missing,
           returns error message prefixed by STATUS_ERROR_PREFIX.  If dict and
           name set, places value_IN, whatever it is, in dict with name as key.

        Parameters:
        - dict_IN - dictionary we are looking in.
        - name_IN - name we are looking for in dictionary.
        - value_IN - value to associate in dict with name passed in.

        Returns:
        - value_OUT - value mapped to name_IN in dict_IN, else an error message if problems.  To check for success, check if value_IN = value_OUT.  If not, error.
        """
    value_OUT = None
    if cls.is_dict(dict_IN) == True:
        if name_IN and name_IN != None:
            dict_IN[name_IN] = value_IN
            value_OUT = cls.get_dict_value(dict_IN, name_IN)
        else:
            value_OUT = (cls.STATUS_ERROR_PREFIX +
                "No name passed in, can't set value.")
    else:
        value_OUT = (cls.STATUS_ERROR_PREFIX +
            "No dictionary passed in, can't set value.")
    return value_OUT


@staticmethod
def flatten_mi_row_df(dfmi):
    """
        create flattend dataframe
        multi index row added as regular column
        """
    df = dfmi.reset_index()
    return df


def to_register_addr(node_id, param_id):
    """Compute modbus address from node_id and param_id."""
    return node_id * 10 + param_id


def get_ijk(data, offset=0):
    """
    Calculates voxel coordinates from data
    """
    from numpy import mgrid
    if not isinstance(offset, (list, tuple)):
        offset = [offset] * 3
    grid = mgrid[offset[0]:offset[0] + data.shape[0], offset[1]:offset[1] +
        data.shape[1], offset[2]:offset[2] + data.shape[2]]
    return grid.reshape(3, -1).T


def print_cookies(cookies, domain):
    """
    Print the cookies from a specific domain
    :param cookies:
    :param domain:
    :return:
    """
    print(domain)
    for cookie in cookies:
        print(cookie)


@classmethod
def subscribe(cls, session, extension='', only_new=False):
    """
        Subscribe to events from the APIC that pertain to instances of this
        class.

        :param session:  the instance of Session used for APIC communication
        :param only_new: Boolean indicating whether to get all events or only the new events. All events (indicated by
                         setting only_new to False) will queue a create event for all of the currently existing objects.
                         Setting only_new to True will only queue events that occur after the initial subscribe. The
                         default has only_new set to False.
        """
    urls = cls._get_subscription_urls()
    for url in urls:
        url += extension
        resp = session.subscribe(url, only_new=only_new)
        if resp is not None:
            if not resp.ok:
                return False
    return True


@classmethod
def reports(cls, options=None):
    """
        List all reports.

        Usage::

            hammer host reports [OPTIONS]

        Options::

            --id ID                       resource id
            --name NAME                   resource name
            --order ORDER                 sort results
            --page PAGE                   paginate results
            --per-page PER_PAGE           number of entries per request
            --search SEARCH               filter results
            -h, --help                    print help
        """
    cls.command_sub = 'reports'
    result = cls.execute(cls._construct_command(options), output_format='csv')
    reports = []
    if result:
        reports = result
    return reports


def pair_strings_sum_formatter(a, b):
    """
  Formats the sum of a and b.

  Note
  ----
  Both inputs are numbers already converted to strings.

  """
    if b[:1] == '-':
        return '{0} - {1}'.format(a, b[1:])
    return '{0} + {1}'.format(a, b)


def __call__():
    """Render a complete HTML table from self.items."""


def radial_control(data_path_primary: str='', data_path_secondary: str='',
    use_secondary: str='', rotation_path: str='', color_path: str='',
    fill_color_path: str='', fill_color_override_path: str='',
    fill_color_override_test_path: str='', zoom_path: str='', image_id: str
    ='', secondary_tex: bool=False):
    """Set some size property (like e.g. brush size) with mouse wheel

    :param data_path_primary: Primary Data Path, Primary path of property to be set by the radial control
    :type data_path_primary: str
    :param data_path_secondary: Secondary Data Path, Secondary path of property to be set by the radial control
    :type data_path_secondary: str
    :param use_secondary: Use Secondary, Path of property to select between the primary and secondary data paths
    :type use_secondary: str
    :param rotation_path: Rotation Path, Path of property used to rotate the texture display
    :type rotation_path: str
    :param color_path: Color Path, Path of property used to set the color of the control
    :type color_path: str
    :param fill_color_path: Fill Color Path, Path of property used to set the fill color of the control
    :type fill_color_path: str
    :param fill_color_override_path: Fill Color Override Path
    :type fill_color_override_path: str
    :param fill_color_override_test_path: Fill Color Override Test
    :type fill_color_override_test_path: str
    :param zoom_path: Zoom Path, Path of property used to set the zoom level for the control
    :type zoom_path: str
    :param image_id: Image ID, Path of ID that is used to generate an image for the control
    :type image_id: str
    :param secondary_tex: Secondary Texture, Tweak brush secondary/mask texture
    :type secondary_tex: bool
    """
    pass


def get_omer_string(omer):
    """Return a string representing the count of the Omer."""
    tens = [u'', u'עשרה', u'עשרים', u'שלושים', u'ארבעים']
    ones = [u'', u'אחד', u'שנים', u'שלושה', u'ארבעה', u'חמשה', u'ששה',
        u'שבעה', u'שמונה', u'תשעה']
    if not 0 < omer < 50:
        raise ValueError('Invalid Omer day: {}'.format(omer))
    ten = omer // 10
    one = omer % 10
    omer_string = u'היום '
    if 10 < omer < 20:
        omer_string += ones[one] + u' עשר'
    elif omer > 9:
        omer_string += ones[one]
        if one:
            omer_string += u' ו'
    if omer > 2:
        if omer > 20 or omer in [10, 20]:
            omer_string += tens[ten]
        if omer < 11:
            omer_string += ones[one] + u' ימים '
        else:
            omer_string += u' יום '
    elif omer == 1:
        omer_string += u'יום אחד '
    else:
        omer_string += u'שני ימים '
    if omer > 6:
        omer_string += u'שהם '
        weeks = omer // 7
        days = omer % 7
        if weeks > 2:
            omer_string += ones[weeks] + u' שבועות '
        elif weeks == 1:
            omer_string += u'שבוע אחד '
        else:
            omer_string += u'שני שבועות '
        if days:
            omer_string += u'ו'
            if days > 2:
                omer_string += ones[days] + u' ימים '
            elif days == 1:
                omer_string += u'יום אחד '
            else:
                omer_string += u'שני ימים '
    omer_string += u'לעומר'
    return omer_string


@classmethod
def new_from_response(cls, response):
    """
        Constructs a new WebPage object for the response,
        using the `BeautifulSoup` module to parse the HTML.

        Parameters
        ----------

        response : requests.Response object
        """
    return cls(response.url, html=response.text, headers=response.headers)


def parseQuery(query):
    """Parse a query string.

        Return a parse tree (which implements IQueryParseTree).

        Some of the query terms may be ignored because they are
        stopwords; use getIgnored() to find out which terms were
        ignored.  But if the entire query consists only of stop words,
        or of stopwords and one or more negated terms, an exception is
        raised.

        May raise ParseTree.ParseError.
        """


def extrude_move(CURVE_OT_extrude=None, TRANSFORM_OT_translate=None):
    """Extrude curve and move result

    :param CURVE_OT_extrude: Extrude, Extrude selected control point(s)
    :param TRANSFORM_OT_translate: Move, Move selected items
    """
    pass


@staticmethod
def _from_db_object(x509keypair, db_x509keypair):
    """Converts a database entity to a formal object."""
    for field in x509keypair.fields:
        setattr(x509keypair, field, db_x509keypair[field])
    x509keypair.obj_reset_changes()
    return x509keypair


@staticmethod
def _slices(layer, offset):
    """Get the slice of the fields in the packet."""
    slices = []
    for fname in layer.field_names:
        field = layer.get_field(fname)
        if field.size is not None and int(field.size) > 0 and field.name != '':
            slices.append([field.name, slice(int(field.pos) - offset, int(
                field.pos) + int(field.size) - offset)])
    return slices


def show_onoff(b):
    """Return 'on' for True and 'off' for False, and ?? for anything
    else."""
    if not isinstance(b, bool):
        return '??'
    if b:
        return 'on'
    return 'off'


def _do_eval(match, exp):
    """Used internally to evaluate an expression."""
    return eval(exp, globals(), {'m': match})


def cb(sess, resp):
    """ Do not thing with the callback """
    pass


@classmethod
def find_command(cls, verb):
    """Find a command in this shell's lineage by its verb.

        Will return the first command found, as multiple stores may have
        different commands using the same verb.

        :param str verb: The verb of the command to search for
        :returns Command|None: The command with that verb or None

        """
    verb = verb.lower()
    for shell in cls.get_lineage():
        command = shell.get_command(verb)
        if command:
            return command


def python3():
    """
    Check if python is python 3
    Usage: if vanadium.python3():
                print("Python 3 :)")
    """
    try:
        print('')
        return True
    except:
        return False


def read_str(data, start, length):
    """Extract a string from a position in a sequence."""
    return data[start:start + length].decode('utf-8')


def check_bool_option(args: dict, option: str) ->bool:
    """ Check if theres a boolean option with the given name
        - args: the args to check for the option
        - option: the name of the option to check for
        - return: whether option is True or False
    """
    try:
        return args[option] > 0 if type(args[option]) == int else args[option]
    except KeyError:
        return False


@classmethod
def get_preferences_page(cls):
    """
        Returns the plugin config page. A page is a simple widget where you
        expose your plugin's preferences. That page will be automatically shown
        under the plugin node in the application's preferences dialog.

        .. warning: This is a classmethod!

        :rtype: hackedit.api.widgets.PreferencePage
        """
    pass


def repr_video(fname, mimetype):
    """Load the video in the file `fname`, with given mimetype,
    and display as HTML5 video.
    """
    try:
        from IPython.display import HTML
    except ImportError:
        raise ImportError('This feature requires IPython.')
    video_encoded = open(fname, 'rb').read().encode('base64')
    video_tag = (
        """<video controls>
<source alt="test" src="data:video/{0};base64,{1}" type="video/webm">
Use Google Chrome browser.</video>"""
        .format(mimetype, video_encoded))
    return HTML(data=video_tag)


def remove_child_nodes(parent, except_id=None):
    """Remove all child nodes from parent except for that with `except_id`"""
    skipped_node = None
    victims = parent.childNodes
    while len(victims) > 0:
        for node in victims:
            if except_id:
                try:
                    if node.getAttribute('id') == except_id:
                        skipped_node = node
                except AttributeError:
                    pass
            parent.removeChild(node)
    if skipped_node:
        parent.appendChild(skipped_node)


@classmethod
def next_conv_block(cls, inputs, layout, filters, bottleneck,
    resnext_factor, **kwargs):
    """ ResNeXt convolution block

        Parameters
        ----------
        inputs
            input tensor
        filters : int
            number of output filters
        bottleneck : bool
            whether to use a simple or a bottleneck block
        resnext_factor : int
            cardinality for ResNeXt model
        kwargs : dict
            `ConvBlock` parameters

        Returns
        -------
        nn.Module
        """
    if bottleneck:
        filters = filters * kwargs['bottleneck_factor']
        filters = [filters // 2, filters // 2, filters]
        kwargs['groups'] = [1, resnext_factor, 1]
    else:
        filters = [resnext_factor * 4, filters]
    x = cls.conv_block(inputs, layout, filters=filters, bottleneck=
        bottleneck, **kwargs)
    return x


def col_groupby_stats(data, col, y):
    """Takes in category column and returns
    descriptive statistics based on an
    binary outcome feature.

    data :
    col :
    y :

    """
    import pandas as pd
    import wrangle as wr
    data = data.copy(deep=True)
    data = data[[col, y]]
    a = data.groupby(col).count()
    b = data.groupby(col).sum()
    d = data.groupby(col).mean()
    e = data.groupby(col).std()
    a.columns = ['n']
    b.columns = ['sum']
    d.columns = ['mean']
    e.columns = ['std']
    out = pd.merge(a, b, left_index=True, right_index=True)
    out = wr.df_merge(a, b)
    out = wr.df_merge(d, out)
    out = wr.df_merge(e, out)
    out = out.round(2)
    return out


def isint(val):
    """
    check if the entry can become an integer (integer or string of integer)

    Parameters
    ----------
    val
        an entry of any type

    Returns
    -------
    bool
        True if the input can become an integer, False otherwise

    """
    try:
        int(val)
        return True
    except ValueError:
        return False


def find_function_name(func, if_no_name=None):
    """Returns pretty-formatted function name."""
    return getattr(func, '__name__', if_no_name)


def hide_fields_in_newer_versions(obj):
    """This method hides fields that were added in newer API versions.

    Certain node fields were introduced at certain API versions.
    These fields are only made available when the request's API version
    matches or exceeds the versions when these fields were introduced.
    """
    pass


@staticmethod
def find_subsector_id(hex_id):
    """hex_id in range 0000-3240, return subsector ID (A-P)"""
    hex_id_col = int(hex_id[:2]) - 1
    hex_id_row = int(hex_id[2:]) - 1
    try:
        return ['ABCD', 'EFGH', 'IJKL', 'MNOP'][int(hex_id_row / 10)][int(
            hex_id_col / 8)]
    except IndexError:
        print('IndexError: hex_id = {} ({}, {})'.format(hex_id, hex_id_col,
            hex_id_row))
        raise


@staticmethod
def getMagnitude(data):
    """Return the magnitude of the given complex data. """
    return (data.real ** 2 + data.imag ** 2) ** 0.5


def _move_active_host_to_head(hosts, active_host):
    """
    to improve efficiency move active host to head
    """
    hosts.remove(active_host)
    hosts.insert(0, active_host)


def _plain_standard_page(page_counter, chars_per_page):
    """
    Plain standard pages.

    This dialect counts page number as *<chars_with_spaces> / <chars_per_size>*.

    Properly round to integer number for humans. Always returns at least 1 or more.

    :param page_counter: ``PageCounter`` instance
    :param chars_per_page: how many characters has a page
    :return: number of pages
    """
    length = page_counter.chars_with_spaces()
    pages = round(length / chars_per_page)
    if pages == 0:
        return 1
    return pages


def substitute_ascii_equivalents(text_unicode):
    """
    This takes a UNICODE string and replaces Latin-1 characters with something
    equivalent in 7-bit ASCII. It returns a plain ASCII string. This function
    makes a best effort to convert Latin-1 characters into ASCII equivalents.
    It does not just strip out the Latin-1 characters. All characters in the
    standard 7-bit ASCII range are preserved. In the 8th bit range all the
    Latin-1 accented letters are converted to unaccented equivalents. Most
    symbol characters are converted to something meaningful. Anything not
    converted is deleted.
    """
    char_mapping = {(192): 'A', (193): 'A', (194): 'A', (195): 'A', (196):
        'A', (197): 'A', (198): 'Ae', (199): 'C', (200): 'E', (201): 'E', (
        202): 'E', (203): 'E', (204): 'I', (205): 'I', (206): 'I', (207):
        'I', (208): 'Th', (209): 'N', (210): 'O', (211): 'O', (212): 'O', (
        213): 'O', (214): 'O', (216): 'O', (217): 'U', (218): 'U', (219):
        'U', (220): 'U', (221): 'Y', (222): 'th', (223): 'ss', (224): 'a',
        (225): 'a', (226): 'a', (227): 'a', (228): 'a', (229): 'a', (230):
        'ae', (231): 'c', (232): 'e', (233): 'e', (234): 'e', (235): 'e', (
        236): 'i', (237): 'i', (238): 'i', (239): 'i', (240): 'th', (241):
        'n', (242): 'o', (243): 'o', (244): 'o', (245): 'o', (246): 'o', (
        248): 'o', (249): 'u', (250): 'u', (251): 'u', (252): 'u', (253):
        'y', (254): 'th', (255): 'y'}
    r = ''
    for char in text_unicode:
        if ord(char) in char_mapping:
            r += char_mapping[ord(char)]
        elif ord(char) >= 128:
            pass
        else:
            r += str(char)
    return r


def get_sequence(pseq, muts):
    """reconstruct a child sequence from that of its parent and the mutations

    Parameters
    ----------
    pseq : str
        sequence of the parent as string, won't be changed!
    muts : list
        mutations of the type K135T where K is the parental state, 135 is the
        position in 1-based numbering, and T is the new state

    Returns
    -------
    str
        reconstructed sequence
    """
    pseq_list = list(pseq)
    for mut in muts:
        new_state = mut[-1]
        pos = int(mut[1:-1]) - 1
        assert pseq_list[pos] == mut[0]
        pseq_list[pos] = new_state
    return ''.join(pseq_list)


def _dir(obj=None, _larch=None):
    """return directory of an object -- thin wrapper about python builtin"""
    if _larch is None:
        raise Warning('cannot run dir() -- larch broken?')
    if obj is None:
        obj = _larch.symtable
    return dir(obj)


def _get_index_range(start, stop, length, step=1):
    """Given start, stop, step and array length, return
    absolute values of start, stop, and step for generating index range.
    The returned values have been compensated by adding length if they
    are less than zero for all the cases but slice(None, None, -1).
    Note that the returned value of stop is not necessarily >= 0, since
    absolute stop is -1 in the case of slice(None, None, -1)."""
    if step == 0:
        raise ValueError('step size cannot be zero')
    if length < 0:
        raise ValueError('array length cannot be less than zero')
    if step is None:
        step = 1
    if start is None:
        if step > 0:
            start = 0
        else:
            start = length - 1
    elif start < 0:
        start += length
        if start < 0:
            raise IndexError('Slicing start %d exceeds limit of %d' % (
                start - length, length))
    elif start >= length:
        raise IndexError('Slicing start %d exceeds limit of %d' % (start,
            length))
    if stop is None:
        if step > 0:
            stop = length
        else:
            stop = -1
    elif stop < 0:
        stop += length
        if stop < 0:
            raise IndexError('Slicing stop %d exceeds limit of %d' % (stop -
                length, length))
    elif stop > length:
        raise IndexError('Slicing stop %d exceeds limit of %d' % (stop, length)
            )
    return start, stop, step


@classmethod
def _latest_partition_from_df(cls, df):
    """Hive partitions look like ds={partition name}"""
    return df.ix[:, (0)].max().split('=')[1]


def psi_Na_Cl_PO4_HFM89(T, P):
    """c-a-a': sodium chloride phosphate [HFM89]."""
    psi = 0.11
    valid = T == 298.15
    return psi, valid


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 pypi_url(varmap):
    """Return the PyPI URL for program ``name`` from the setup vars.
    """
    return 'http://pypi.org/project/{}'.format(varmap['name'])


def numericise(value, empty_value=''):
    """Returns a value that depends on the input string:
        - Float if input can be converted to Float
        - Integer if input can be converted to integer
        - Zero if the input string is empty and empty2zero flag is set
        - The same input string, empty or not, otherwise.

    Executable examples:

    >>> numericise("faa")
    'faa'
    >>> numericise("3")
    3
    >>> numericise("3.1")
    3.1
    >>> numericise("", empty2zero=True)
    0
    >>> numericise("", empty2zero=False)
    ''
    >>> numericise("")
    ''
    >>> numericise(None)
    >>>
    """
    if value == '':
        return empty_value
    if value is not None:
        try:
            value = int(value)
        except ValueError:
            try:
                value = float(value)
            except ValueError:
                pass
    return value


def kaiser_beta(a):
    """Compute the Kaiser parameter `beta`, given the attenuation `a`.

    Parameters
    ----------
    a : float
        The desired attenuation in the stopband and maximum ripple in
        the passband, in dB.  This should be a *positive* number.

    Returns
    -------
    beta : float
        The `beta` parameter to be used in the formula for a Kaiser window.

    References
    ----------
    Oppenheim, Schafer, "Discrete-Time Signal Processing", p.475-476.

    Examples
    --------
    Suppose we want to design a lowpass filter, with 65 dB attenuation
    in the stop band.  The Kaiser window parameter to be used in the
    window method is computed by `kaiser_beta(65)`:

    >>> from scipy.signal import kaiser_beta
    >>> kaiser_beta(65)
    6.20426

    """
    if a > 50:
        beta = 0.1102 * (a - 8.7)
    elif a > 21:
        beta = 0.5842 * (a - 21) ** 0.4 + 0.07886 * (a - 21)
    else:
        beta = 0.0
    return beta


def attribute_match_all(attribute, length=None, data=None, value=None,
    endswith=None):
    """
    Check if an attribute matches all of the following specified conditions:

    - Minimum length.
    - Contains an item.
    - Is exactly a value.

    Note that only those conditions explicitly passed will be checked.

    Parameters
    ----------
    attribute : anything
        The attribute to match against.
    length : int, default is None
        If specified, the attribute must reach this length (or higher).
    data : anything, default is None
        If specified, the attribute must contain this value.
    value : anything, default is None
        If specified, the attribute must be this value.
    endswith : sequence, default is None
        If specified, the attribute must end with this sequence.

    Returns
    -------
    bool
        Whether the attribute matches any condition.
    """
    assert length is not None or data is not None or value is not None or endswith is not None, 'No condition passed! Will return True always...'
    if length is not None and len(attribute) < length:
        return False
    if data is not None and data not in attribute:
        return False
    if value is not None and attribute != value:
        return False
    if endswith is not None and attribute[-len(endswith):] != endswith:
        return False
    return True


def sync_move(src, dst):
    """Sync the file and move it

    This ensures that the move is truly atomic

    Parameters
    ----------
    src : filename
        Source file
    dst: filename
        Destination file
    """
    from jug.backends.file_store import fsync_dir
    from os import rename
    fsync_dir(src)
    rename(src, dst)


def tobool(value):
    """helper to evaluate a string into a boolean
    WARNING: at the moment value is True by default unless it can
    be evaluated to False matching one of (case insensitive):
        ('false', 'no', 'n', '0')

    :param value: the string to evaluate
    :type value: string

    :returns: True or False depending on the given value
    """
    if value.lower() in ('false', 'no', 'n', '0'):
        value = False
    else:
        value = True
    return value


@classmethod
def register_resources(klass, registry, resource_class):
    """model resource subscriber on resource registration.

        Watch for new resource types being registered if they are
        supported by aws config, automatically, register the
        config-compliance filter.
        """
    if resource_class.resource_type.config_type is None:
        return
    resource_class.filter_registry.register('config-compliance', klass)


def _rank(sample):
    """
    Assign numeric ranks to all values in the sample.

    The ranks begin with 1 for the smallest value. When there are groups of
    tied values, assign a rank equal to the midpoint of unadjusted rankings.

    E.g.::

        >>> rank({3: 1, 5: 4, 9: 1})
        {3: 1.0, 5: 3.5, 9: 6.0}

    """
    rank = 1
    ranks = {}
    for k in sorted(sample.keys()):
        n = sample[k]
        ranks[k] = rank + (n - 1) / 2
        rank += n
    return ranks


def process_subscription_data(post_data):
    """Process the subscription data according to out model"""
    subscription_data = post_data.pop('subscription', {})
    keys = subscription_data.pop('keys', {})
    subscription_data.update(keys)
    subscription_data['browser'] = post_data.pop('browser')
    return subscription_data


def add_ago_to_since(since: str) ->str:
    """
    Backwards compatibility hack. Without this slices with since: 7 days will
    be treated as 7 days in the future.

    :param str since:
    :returns: Since with ago added if necessary
    :rtype: str
    """
    since_words = since.split(' ')
    grains = ['days', 'years', 'hours', 'day', 'year', 'weeks']
    if len(since_words) == 2 and since_words[1] in grains:
        since += ' ago'
    return since


def list_mask(input_list: list, mask: list) ->list:
    """listutils.list_mask(input_list, mask)

    This function takes an input list and applies a mask to it, outputting a
    new list. The mask should be a list containing 1's and 0's, or
    alternatively True's and False's. If the mask is shorter than the input
    list then the input list will be considered only up to the mask length.
    Usage:

    >>> alist = [1, 2, 3]
    >>> mask = [True, False, True]
    >>> listutils.list_mask(alist, mask)
    [1, 3]

    >>> alist = [1, 2, 3, 4, 5]
    >>> mask = [1, 0, 0, 1, 0]
    >>> listutils.list_mask(alist, mask)
    [1, 4]

    If the mask is shorter than the list, the :

    >>> alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> mask = [1, 0]
    >>> listutils.list_mask(alist, mask)
    [1]

    If the mask is shorter than the input list then the input list will be
    considered only up to the mask length:

    >>> alist = [1, 2.2, True, 'foo', (1, 4), None, 3+2j, {'a': 1}]
    >>> mask = [True, False, True]
    >>> listutils.list_mask(alist, mask)
    [1, True]

    The input list can be empty, in which case an empty list is return. On the
    other hand, the mask argument cannot be an empty list.
    """
    if not isinstance(input_list, list):
        raise TypeError("'input_list' must be 'list'")
    if not isinstance(mask, list):
        raise TypeError("'mask' must be 'list'")
    if len(mask) == 0:
        raise IndexError("'mask' must have len > 0")
    if len(input_list) == 0:
        return []
    output_list = []
    for item, mask_value in zip(input_list, mask):
        if mask_value:
            output_list.append(item)
    return output_list


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 with_metaclass(meta, base=object):
    """Create a base class with a metaclass."""
    return meta('%sBase' % meta.__name__, (base,), {})


@classmethod
def after_delete(cls, info, instance):
    """Perform "after delete" operations.

        Override this to perform any operation on the instance
        after its `.delete()` method is called.
        """
    pass


@staticmethod
def trunc(string, ch):
    """
        Pads a string with '...' if it is too long to fit in a window.

        Arguments:
        string: String to be truncated.
        ch: Max length for the string.

        Returns: The original string if it is short enough to be displayed,
          otherwise the string truncated and padded with '...'.
        """
    if ch < 0 or len(string) <= ch:
        return string
    else:
        return string[:-(len(string) - ch + 3)] + '...'


def settextjustify(horiz: int, vert: int):
    """
    Set Current Text Justification Settings

    settextjustify() controls text justification with respect to the
    current position (CP).  The text is justified horizontally and
    vertically.

    Constants of the text_just for 'horiz' are: LEFT_TEXT, CENTER_TEXT, RIGHT_TEXT

    Constants of the text_just for 'vert' are: TOP_TEXT, CENTER_TEXT, BOTTOM_TEXT
    """
    _text_v_align = vert
    _text_h_align = horiz


def slice(obj, keys=[], skip=[], full=False):
    """ return a slice of an object. """
    from mads.object import Object
    o = Object()
    if not keys:
        keys = obj.keys()
    for key in keys:
        if key in skip:
            continue
        if not full and key.startswith('_'):
            continue
        val = obj.get(key, None)
        if val and 'keys' in dir(val):
            o[key] = slice(val)
        else:
            o[key] = val
    return o


def model_fields(model, only=None, exclude=None, field_args=None, converter
    =None):
    """
    Legacy function, see `Converter.fields_for_model`
    """
    return converter.fields_for_model(model, only, exclude, field_args)


def bytes_(s, encoding='latin-1', errors='strict'):
    """ This function is a copy of ``pyramid.compat.bytes_``

    If ``s`` is an instance of ``text_type``, return
    ``s.encode(encoding, errors)``, otherwise return ``s``"""
    if isinstance(s, str):
        return s.encode(encoding, errors)
    return s


def correctivesmooth_bind(modifier: str=''):
    """Bind base pose in Corrective Smooth modifier

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


def register(type_id, func):
    """ register a function as the handler for a tracking call type. """
    type_id = int(type_id)
    map[type_id] = func


def make_a_condor_job(inputs, opts):
    """Make and submit a condor job for the pipeline

    Parameters
    ----------
    inputs: argparse.Namespace
        Namespace objects containing command line arguments
    """
    from ..condor import Dag, DataFindNode, VarahaNode, PESummaryNode
    MainDag = Dag(inputs)
    MainJob = VarahaNode(inputs, opts, MainDag.output_directories, MainDag.
        dagman)
    PESummaryJob = PESummaryNode(inputs, MainDag.output_directories,
        MainDag.dagman)
    if inputs.frame_files == {}:
        DataFindJob = DataFindNode(inputs, MainDag.output_directories,
            MainDag.dagman)
        DataFindJob.add_child(MainJob.job)
    MainJob.add_child(PESummaryJob.job)
    MainDag.build()
    if inputs.condor_submit:
        MainDag.build_submit()
    else:
        MainDag.build()


@staticmethod
def _to_field(config_key):
    """Convert a config key to a field name"""
    return config_key.replace('-', '_')