def jsob(inmap):
    """Return a json'able map."""
    ret = None
    if inmap is not None:
        ret = {}
        for key in inmap:
            if key in [u'minelap', u'maxelap']:
                ret[key] = inmap[key].rawtime()
            else:
                ret[key] = inmap[key]
    return ret


def note_to_freq(notenum):
    """Converts a MIDI note number to a frequency.

    See https://en.wikipedia.org/wiki/MIDI_Tuning_Standard
    """
    return 2.0 ** ((notenum - 69) / 12.0) * 440.0


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 try_get(object, key):
    """Tries to get the value of a key in an object, and politely notifies you if it cannot find it."""
    if key not in object:
        raise KeyError('Could not find ' + key + ' inside of ' + object +
            '! Does it exist?')
    return object[key]


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

        :param DeviceChangeIpMobileType val:
        :rtype: EventType
        """
    return cls('device_change_ip_mobile', val)


def get_team_scores(df_schedule, team, week):
    """Get all scores for a team

  :param df_schedule: data frame with scores and team ids for each game
  :param team: id for team
  :param week: current week
  :return: series of scores for team up to week
  """
    return df_schedule.query(
        f'(home_id=={team} | away_id=={team}) & (matchupPeriodId <= {week} & winner != "UNDECIDED")'
        ).apply(lambda x: x.home_total_points if x.home_id == team else x.
        away_total_points, axis=1)


def merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in later dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result


@staticmethod
def date_diff_format(print_format, duration, sign):
    """Format a duration."""
    if print_format:
        delta_lookup = {'y': duration.years, 'm': duration.months, 'd':
            duration.days, 'h': duration.hours, 'M': duration.minutes, 's':
            duration.seconds}
        expression = ''
        for item in print_format:
            if item not in delta_lookup:
                expression += item
            elif float(delta_lookup[item]).is_integer():
                expression += str(int(delta_lookup[item]))
            else:
                expression += str(delta_lookup[item])
        return sign + expression
    else:
        return sign + str(duration)


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


def __im_finalize__():
    """Finalize the object.

        The immutable and all its sub-objects are being `locked` to disallow
        any further write access.
        """


def render(request, *args, **kw):
    """Render the page template.

        The first argument is bound to the top-level 'request'
        variable. The positional arguments are bound to the 'args'
        variable and the keyword arguments are bound to the 'options'
        variable.
        """


def recommended(fn):
    """Mark method as recommended to be implemented by subclasses"""
    fn._bubbles_recommended = True
    return fn


def render(value):
    """Render @code{value} as an L{IRenderable}.  This essentially coerces
        @code{value} to an L{IRenderable} and calls its @L{getRenderingFor}
        method.

        @name value: value to render
        @returns: rendered value
        """


def empty():
    """ An empty iterator. Other methods include:
		iter(())
		yield from ()
	"""
    return
    yield


@staticmethod
def add_cmd_subparser(subparsers):
    """
        This method should add subcommand parser to passed subarsers object.
        """
    pass


def _format_host_port_alias(host, port, alias):
    """Format a host, port, and alias so it can be used for comparison or display."""
    if alias:
        return f'{alias}@{host}:{port}'
    return f'{host}:{port}'


def do_write(data, dest):
    """Cleanly write a file out somewhere"""
    handle = open(dest, 'w')
    handle.write(data)
    handle.close()


def _delete_duplicates(l, keep_last):
    """Delete duplicates from a sequence, keeping the first or last."""
    seen = set()
    result = []
    if keep_last:
        l.reverse()
    for i in l:
        try:
            if i not in seen:
                result.append(i)
                seen.add(i)
        except TypeError:
            result.append(i)
    if keep_last:
        result.reverse()
    return result


def p_anythings(p):
    """anythings : anythings anything
                 | anything"""
    p[0] = ''.join(p[1:len(p)])


@classmethod
def registered(cls, e_type):
    """
        Returns True if the given entity type is registered, False otherwise.
        """
    result = None
    try:
        result = e_type.name in [e_type.name for e_type in cls.types]
    except AttributeError:
        result = e_type in [e_type.name for e_type in cls.types]
    return result


def get_params_list(*args, **kwargs):
    """Turn dict-like arguments into an ordered list of pairs."""
    params = []
    if args:
        if len(args) > 1:
            raise TypeError('Expected at most 1 arguments, got 2')
        arg = args[0]
        if hasattr(arg, 'items'):
            params.extend(arg.items())
        else:
            params.extend(list(arg))
    if kwargs:
        params.extend(kwargs.items())
    return params


@staticmethod
def authors_min_max_dates(date_field, author_field='author_uuid'):
    """
        Get the aggregation of author with their min and max activity dates

        :param date_field: field used to find the mix and max dates for the author's activity
        :param author_field: field of the author

        :return: the query to be executed to get the authors min and max aggregation data
        """
    es_query = (
        """
        {
          "size": 0,
          "aggs": {
            "author": {
              "terms": {
                "field": "%s",
                "size": 30000
              },
              "aggs": {
                "min": {
                  "min": {
                    "field": "%s"
                  }
                },
                "max": {
                  "max": {
                    "field": "%s"
                  }
                }
              }
            }
          }
        }
        """
         % (author_field, date_field, date_field))
    return es_query


def __lshift__(return_spec, argument_spec):
    """
<<This is about to change, does not work as one may expected.
Nov 19 2005. >>>

Return a 'mapping' set, which may be used for specification and test
purposes. It implements the syntax:

        return_spec << argument_spec

The elements of the set returned are the callable objects that return
values in return_spec, when called with arguments according to
argument_spec. The return_spec may be any kind of sets that can test
for element containment. The argument_spec may be a set or a tuple. If
it is a set, it should be able to generate some examples, to allow the
mapping to be tested.  When argument_spec is a set, the mapping will
have a single argument. Any number of arguments may be specified using
an argument_spec which is a tuple.  The arguments are then specified
with sets, that should be able to generate examples. Special features
of the mapping such as optional arguments may be specified in the same
way as when using the 'mapping' function in the Spec.py module.

"""
    return return_spec.fam.c_lshift(return_spec, argument_spec)


def search(text=None, pattern=None):
    """Searches the given pattern in the given text.

    Args:
        text (str): Text in which the pattern needs to be searched.
        pattern (str): A string to be searched in the given `text`.

    Returns:
        bool: A boolean value stating whether the pattern is found in the
            given text or not.

    .. versionadded:: 1.0.0
    """
    return True if pattern in text else False


def t_ABSOLUTE_CELL(t):
    """\\$[A-Za-z]+\\$[0-9]+"""
    return t


def process_tracked_yield(minIONdict):
    """
    This function maintains a history of all yield values over the time of a run - it can be configured to store yields
    at given intervals. It is used by the main web page to provide a history of cumulative yield.
    """
    for minion in minIONdict:
        if 'detailsdata' in minIONdict[minion]:
            if 'livedata' in minIONdict[minion]:
                if 'yield_res' in minIONdict[minion]['livedata']:
                    if 'result' in minIONdict[minion]['livedata']['yield_res']:
                        try:
                            asictemp = float(minIONdict[minion][
                                'detailsdata']['engine_states'][
                                'minion_asic_temperature'])
                        except:
                            asictemp = 0
                        try:
                            heatsinktemp = float(minIONdict[minion][
                                'detailsdata']['engine_states'][
                                'minion_heatsink_temperature'])
                        except:
                            heatsinktemp = 0
                        if minIONdict[minion]['livedata']['bias_voltage_gain'][
                            'result'] != 'null':
                            biasvoltage = int(minIONdict[minion]['livedata'
                                ]['bias_voltage_gain']['result'])
                        else:
                            biasvoltage = 0
                        if minIONdict[minion]['livedata']['biasvoltageget'][
                            'result'] != 'null':
                            voltage_val = int(minIONdict[minion]['livedata'
                                ]['biasvoltageget']['result']['bias_voltage'])
                        else:
                            voltage_val = 0
                        voltage_value = voltage_val * biasvoltage
                        try:
                            if minIONdict[minion]['livedata']['yield_res'][
                                'result'] != 'null':
                                yieldval = int(minIONdict[minion][
                                    'livedata']['yield_res']['result'])
                            else:
                                yieldval = minIONdict[minion]['detailsdata'][
                                    'statistics']['read_event_count']
                        except:
                            yieldval = 0
                        try:
                            meanratio = minIONdict[minion]['detailsdata'][
                                'meanratio']
                            openpore = minIONdict[minion]['detailsdata'][
                                'openpore']
                            instrand = minIONdict[minion]['detailsdata'][
                                'instrand']
                        except:
                            meanratio = 0
                            openpore = 0
                            instrand = 0
                        if 'yield_history' not in minIONdict[minion]:
                            minIONdict[minion]['yield_history'] = []
                        if 'temp_history' not in minIONdict[minion]:
                            minIONdict[minion]['temp_history'] = dict()
                        if 'pore_history' not in minIONdict[minion]:
                            minIONdict[minion]['pore_history'] = dict()
                        if 'meanratio_history' not in minIONdict[minion][
                            'pore_history']:
                            minIONdict[minion]['pore_history'][
                                'meanratio_history'] = []
                            minIONdict[minion]['pore_history'][
                                'openpore_history'] = []
                            minIONdict[minion]['pore_history'][
                                'instrand_history'] = []
                        if 'strand' not in minIONdict[minion]['pore_history']:
                            minIONdict[minion]['pore_history']['strand'] = []
                            minIONdict[minion]['pore_history']['percent'] = []
                            minIONdict[minion]['pore_history']['single'] = []
                        if 'asictemp' not in minIONdict[minion]['temp_history'
                            ]:
                            minIONdict[minion]['temp_history']['asictemp'] = []
                            minIONdict[minion]['temp_history']['heatsinktemp'
                                ] = []
                            minIONdict[minion]['temp_history']['voltage'] = []
                        strand = 0
                        single_pore = 0
                        if 'simplesummary' in minIONdict[minion]:
                            if 'strand' in minIONdict[minion]['simplesummary'
                                ].keys():
                                strand = float(minIONdict[minion][
                                    'simplesummary']['strand'])
                            if 'single_pore' in minIONdict[minion][
                                'simplesummary'].keys():
                                single_pore = float(minIONdict[minion][
                                    'simplesummary']['single_pore'])
                            elif 'good_single' in minIONdict[minion][
                                'simplesummary'].keys():
                                single_pore = float(minIONdict[minion][
                                    'simplesummary']['good_single'])
                        if strand + single_pore > 0:
                            percent = strand / (strand + single_pore) * 100
                        else:
                            percent = 0
                        if len(minIONdict[minion]['yield_history']) > 1:
                            if yieldval > minIONdict[minion]['yield_history'][
                                -1][1]:
                                minIONdict[minion]['yield_history'].append((
                                    minIONdict[minion]['detailsdata'][
                                    'timestamp'] * 1000, yieldval))
                            minIONdict[minion]['temp_history']['asictemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, asictemp))
                            minIONdict[minion]['temp_history']['voltage'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, voltage_value))
                            minIONdict[minion]['temp_history']['heatsinktemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, heatsinktemp))
                            minIONdict[minion]['pore_history']['strand'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, strand))
                            minIONdict[minion]['pore_history']['percent'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, percent))
                            minIONdict[minion]['pore_history']['single'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, single_pore))
                            minIONdict[minion]['pore_history'][
                                'meanratio_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                meanratio))
                            minIONdict[minion]['pore_history'][
                                'openpore_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                openpore))
                            minIONdict[minion]['pore_history'][
                                'instrand_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                instrand))
                            if 'simplesummary' in minIONdict[minion]:
                                if 'details' not in minIONdict[minion][
                                    'pore_history'].keys():
                                    minIONdict[minion]['pore_history'][
                                        'details'] = dict()
                                for state in minIONdict[minion]['simplesummary'
                                    ].keys():
                                    if state not in minIONdict[minion][
                                        'pore_history']['details'].keys():
                                        minIONdict[minion]['pore_history'][
                                            'details'][state] = []
                                    minIONdict[minion]['pore_history'][
                                        'details'][state].append((
                                        minIONdict[minion]['detailsdata'][
                                        'timestamp'] * 1000, minIONdict[
                                        minion]['simplesummary'][state]))
                        else:
                            minIONdict[minion]['yield_history'].append((
                                minIONdict[minion]['detailsdata'][
                                'timestamp'] * 1000, yieldval))
                            minIONdict[minion]['temp_history']['asictemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, asictemp))
                            minIONdict[minion]['temp_history']['heatsinktemp'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, heatsinktemp))
                            minIONdict[minion]['temp_history']['voltage'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, voltage_value))
                            minIONdict[minion]['pore_history']['strand'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, strand))
                            minIONdict[minion]['pore_history']['percent'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, percent))
                            minIONdict[minion]['pore_history']['single'
                                ].append((minIONdict[minion]['detailsdata']
                                ['timestamp'] * 1000, single_pore))
                            minIONdict[minion]['pore_history'][
                                'meanratio_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                meanratio))
                            minIONdict[minion]['pore_history'][
                                'openpore_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                openpore))
                            minIONdict[minion]['pore_history'][
                                'instrand_history'].append((minIONdict[
                                minion]['detailsdata']['timestamp'] * 1000,
                                instrand))
                            if 'simplesummary' in minIONdict[minion]:
                                if 'details' not in minIONdict[minion][
                                    'pore_history'].keys():
                                    minIONdict[minion]['pore_history'][
                                        'details'] = dict()
                                for state in minIONdict[minion]['simplesummary'
                                    ].keys():
                                    if state not in minIONdict[minion][
                                        'pore_history']['details'].keys():
                                        minIONdict[minion]['pore_history'][
                                            'details'][state] = []
                                    minIONdict[minion]['pore_history'][
                                        'details'][state].append((
                                        minIONdict[minion]['detailsdata'][
                                        'timestamp'] * 1000, minIONdict[
                                        minion]['simplesummary'][state]))
                else:
                    minIONdict[minion]['yield_history'] = []
                    minIONdict[minion]['temp_history']['asictemp'] = []
                    minIONdict[minion]['temp_history']['heatsinktemp'] = []
                    minIONdict[minion]['temp_history']['voltage'] = []
                    minIONdict[minion]['pore_history']['strand'] = []
                    minIONdict[minion]['pore_history']['percent'] = []
                    minIONdict[minion]['pore_history']['single'] = []
                    minIONdict[minion]['pore_history']['openpore_history'] = []
                    minIONdict[minion]['pore_history']['instrand_history'] = []
                    minIONdict[minion]['pore_history']['meanratio_history'] = [
                        ]
                    if 'details' in minIONdict[minion]['pore_history']:
                        minIONdict[minion]['pore_history'].pop('details')


def LCGInfoName(platform):
    """
    Return the name of the file containing the list of externals in an LCG
    relese.

    >>> LCGInfoName('x86_64-slc6-gcc49-opt')
    'LCG_externals_x86_64-slc6-gcc49-opt.txt'
    """
    return 'LCG_externals_{0}.txt'.format(platform)


def make_zigzag(points, num_cols):
    """ Converts linear sequence of points into a zig-zag shape.

    This function is designed to create input for the visualization software. It orders the points to draw a zig-zag
    shape which enables generating properly connected lines without any scanlines. Please see the below sketch on the
    functionality of the ``num_cols`` parameter::

             num cols
        <-=============->
        ------->>-------|
        |------<<-------|
        |------>>-------|
        -------<<-------|

    Please note that this function does not detect the ordering of the input points to detect the input points have
    already been processed to generate a zig-zag shape.

    :param points: list of points to be ordered
    :type points: list
    :param num_cols: number of elements in a row which the zig-zag is generated
    :type num_cols: int
    :return: re-ordered points
    :rtype: list
    """
    new_points = []
    points_size = len(points)
    forward = True
    idx = 0
    rev_idx = -1
    while idx < points_size:
        if forward:
            new_points.append(points[idx])
        else:
            new_points.append(points[rev_idx])
            rev_idx -= 1
        idx += 1
        if idx % num_cols == 0:
            forward = False if forward else True
            rev_idx = idx + num_cols - 1
    return new_points


def _check_usable(inst):
    """Ensure our data are clean."""
    if inst.proj:
        raise RuntimeError(
            'Projectors cannot be applied to data during Maxwell filtering.')
    current_comp = inst.compensation_grade
    if current_comp not in (0, None):
        raise RuntimeError(
            'Maxwell filter cannot be done on compensated channels, but data have been compensated with grade %s.'
             % current_comp)


def extract_entities(result):
    """Extracts entities from a parsing result."""
    return result.get('entities', [])


def _join_host_port(host, port):
    """Adapted golang's net.JoinHostPort"""
    template = '{}:{}'
    host_requires_bracketing = ':' in host or '%' in host
    if host_requires_bracketing:
        template = '[{}]:{}'
    return template.format(host, port)


def describe_delivery_channels(DeliveryChannelNames=None):
    """
    Returns details about the specified delivery channel. If a delivery channel is not specified, this action returns the details of all delivery channels associated with the account.
    See also: AWS API Documentation

    :example: response = client.describe_delivery_channels(
        DeliveryChannelNames=[
            'string',
        ]
    )

    :type DeliveryChannelNames: list
    :param DeliveryChannelNames: A list of delivery channel names.
            (string) --

    :rtype: dict
    :return: {
        'DeliveryChannels': [
            {
                'name': 'string',
                's3BucketName': 'string',
                's3KeyPrefix': 'string',
                'snsTopicARN': 'string',
                'configSnapshotDeliveryProperties': {
                    'deliveryFrequency': 'One_Hour'|'Three_Hours'|'Six_Hours'|'Twelve_Hours'|'TwentyFour_Hours'
                }
            },
        ]
    }

    """
    pass


def get_unique_id():
    """Return an ID that will be unique over the current segmentation

    :return: unique_id
    :rtype: int
    """
    global UNIQUE_ID
    UNIQUE_ID = UNIQUE_ID + 1
    return UNIQUE_ID


def get_producer_version():
    """
    Internal helper function to return the producer version
    """
    from . import __producer_version__
    return __producer_version__


def _hook_raise_errors(response, *args, **kwargs):
    """Response hook to raise exception for any HTTP error (status >= 400)."""
    response.raise_for_status()


def validate_size_x_string(size_str: str):
    """Validate size x string.

    :param size_str: size str in WxH format

    :raises ValueError: Wrong size value
    """
    try:
        width, height = size_str.split('x')
    except ValueError:
        raise ValueError('Wrong size format')
    try:
        int(width)
    except ValueError:
        raise ValueError('Wrong width value')
    try:
        int(height)
    except ValueError:
        raise ValueError('Wrong height value')


@classmethod
def is_mp_user(cls, user):
    """Check whether user is a media public user.

        :param user: a dict must contain key VerifyFlag.

        """
    return user['VerifyFlag'] & cls.mp_verify_flag


def suppress_no_delim_lines(lines, delim):
    """Discard `lines` that do not contain `delim`.

    Parameters
    ----------
    lines : iterable
        Provides line number (1-based) and line (str).
    delim : str
    """
    for line in lines:
        if delim not in line[1]:
            continue
        yield line


@classmethod
def list(cls, context, limit=None, marker=None, sort_key=None, sort_dir=
    None, owner=None):
    """Return a list of Port objects.

        :param context: Security context.
        :param limit: maximum number of resources to return in a single result.
        :param marker: pagination marker for large data sets.
        :param sort_key: column to sort results by.
        :param sort_dir: direction to sort. "asc" or "desc".
        :param owner: a node owner to match against
        :returns: a list of :class:`Port` object.
        :raises: InvalidParameterValue

        """
    db_ports = cls.dbapi.get_port_list(limit=limit, marker=marker, sort_key
        =sort_key, sort_dir=sort_dir, owner=owner)
    return cls._from_db_object_list(context, db_ports)


def printc(complex_number):
    """Print a complex number to the terminal.

    Args:
        complex_number (complex): number to print

    """
    if complex_number.imag >= 0:
        sign = '+'
    else:
        sign = '-'
    return str('{:+6.2f} {} j{:5.2f}'.format(complex_number.real, sign,
        complex_number.imag))


@classmethod
def get_container_name(cls):
    """ Returns the name of the container class.
		"""
    return 'input'


def _group_filter_values(seg, filter_indices, ms_per_input):
    """
    Takes a list of 1s and 0s and returns a list of tuples of the form:
    ['y/n', timestamp].
    """
    ret = []
    for filter_value, (_segment, timestamp) in zip(filter_indices, seg.
        generate_frames_as_segments(ms_per_input)):
        if filter_value == 1:
            if len(ret) > 0 and ret[-1][0] == 'n':
                ret.append(['y', timestamp])
            elif len(ret) > 0 and ret[-1][0] == 'y':
                ret[-1][1] = timestamp
            else:
                ret.append(['y', timestamp])
        elif len(ret) > 0 and ret[-1][0] == 'n':
            ret[-1][1] = timestamp
        elif len(ret) > 0 and ret[-1][0] == 'y':
            ret.append(['n', timestamp])
        else:
            ret.append(['n', timestamp])
    return ret


def load_poly_concave(tmxobject, map_height, static_body):
    """
    Placeholder for loading a convex shape and nreaking it down into
    several concave shapes.

    :param TiledObject tmxobject: A TiledObject instance that represents a     convex polygon with multiple vertices.
    :param int map_height: The height of the TiledMap that the TiledObject     was loaded from in pixels.

    Not Implemented.
    """
    raise NotImplementedError


def _update_scene_fps(context, report, bvh_frame_time):
    """Update the scene's FPS settings from the BVH, but only if the BVH contains enough info."""
    if bvh_frame_time == 0.0:
        report({'WARNING'},
            'Unable to update scene frame rate, as the BVH file contains a zero frame duration in its MOTION section'
            )
        return
    scene = context.scene
    scene_fps = scene.render.fps / scene.render.fps_base
    new_fps = 1.0 / bvh_frame_time
    if scene.render.fps != new_fps or scene.render.fps_base != 1.0:
        print('\tupdating scene FPS (was %f) to BVH FPS (%f)' % (scene_fps,
            new_fps))
    scene.render.fps = new_fps
    scene.render.fps_base = 1.0


@staticmethod
def _convert_flag_text_to_argument_name(flag_text):
    """This just emulates argparse's underlying logic.

        :type flag_text: str
        :param flag_text: e.g. `--no-hex-string-scan`
        :return: `no_hex_string_scan`
        """
    return flag_text[2:].replace('-', '_')


def limit_es(expectedsizeinMB):
    """Protection against creating too small or too large chunks."""
    if expectedsizeinMB < 0.0001:
        expectedsizeinMB = 0.0001
    elif expectedsizeinMB > 10000.0:
        expectedsizeinMB = 10000.0
    return expectedsizeinMB


def scatter_row(data, row_index, value):
    """Write the value into the data tensor using the row index.

    This is an out-place write so it can work with autograd.

    Parameters
    ----------
    data : Tensor
        The data tensor to be updated.
    row_index : Tensor
        A 1-D integer tensor containing which rows to be updated.
    value : Tensor
        The new value.

    Returns
    -------
    Tensor
        The new data.
    """
    pass


@classmethod
def from_evt(cls, evt):
    """
        Initializes a new instance of given class by copying all data.

        Args:
            evt: pero.TouchEvt
                Source event from which to copy the data.

        Returns:
            cls instance
                New instance of requested class.
        """
    return cls(native=evt.native, view=evt.view, control=evt.control,
        touches=evt.touches, alt_down=evt.alt_down, cmd_down=evt.cmd_down,
        ctrl_down=evt.ctrl_down, shift_down=evt.shift_down)


def hide_render_set(unselected: bool=False):
    """Hide the render object by setting the hide render flag

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


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['packageType']
    if type == 'ORCHESTRATION':
        return 'OrchestrationListingPackage'
    if type == 'IMAGE':
        return 'ImageListingPackage'
    else:
        return 'ListingPackage'


@staticmethod
def using_ns(symbol):
    """generates a using namespace x::y::z statement from a symbol"""
    id = '::'.join(symbol.module.name_parts)
    return 'using namespace {0};'.format(id)


@classmethod
def from_dict(cls, client, soap_dict):
    """
        Alternative constructor, builds entity object from a dictionary representation of
        a SOAP response created by the SOAP client.
        """
    return cls(client=client, minimum_balance=soap_dict.get(
        'MinimumBalance', None), topup_amount=soap_dict.get('TopupAmount',
        None), payment_method_id=soap_dict.get('PaymentMethodID', None))


def project_opened(project):
    """This function is called after opening the project"""


@classmethod
def set_session(cls, session):
    """Установка текущей сессии.

        Args:
            session: :class:`.Session`

        """
    cls._session = session


def reload():
    """reread from database"""


@classmethod
def get_user_list_all_by_data(cls, department_id_list):
    """
        根据部门ID查询用户信息(同一部门下)
        :param department_id_list:
        :return:
        """
    search = {'__raw__': {'org_role.department_id': {'$in':
        department_id_list}, 'status': {'$nin': [cls.get_status('用户删除')]}}}
    return cls.objects(**search).order_by('-create_time').all()


def facebook_extra_values(backend, details, response, uid, user, *args, **
    kwargs):
    """Populates a UserProfile Object when a new User is created via Facebook Auth"""
    profile = user.social_profile
    if not profile.manually_edited:
        user.last_name = response.get('last_name', '')
        user.first_name = response.get('first_name', '')
        user.save()
        profile.gender = response.get('gender', '')
        profile.url = response.get('link', '')
        if response.get('picture', False):
            profile.image_url = response.get('picture').get('data').get('url',
                '')
        profile.save()
    return response


def index_to_nice_name(index):
    """Construct an indented name for the node given its path."""
    if index:
        return ' ' * 4 * (len(index) - 1) + index[-1]
    else:
        return 'Everything'


def cache_property(key, empty, type):
    """Return a new property object for a cache header.  Useful if you
    want to add support for a cache extension in a subclass."""
    return property(lambda x: x._get_cache_value(key, empty, type), lambda
        x, v: x._set_cache_value(key, v, type), lambda x: x.
        _del_cache_value(key), 'accessor for %r' % key)


@classmethod
def create_read_file(cls, subimage_descriptor, file_handle_factory):
    """Create a MetaIoFile class for writing"""
    filename = subimage_descriptor.filename
    local_file_size = subimage_descriptor.ranges.image_size
    return cls(local_file_size, filename, file_handle_factory, None)


def remove_import_alias(red):
    """Remove the alias from an import.

    import a.b.c as d -> import a.b.c.

    """
    for n in red.find_all('import'):
        n.value[0].target = ''


def force_tuple(var):
    """
    Returns the given variable as tuple
    :param var: variant
    :return: list
    """
    if type(var) is not tuple:
        var = tuple(var)
    return var


def SGD_basic(free_param, gradient, grad_scale):
    """ Stochastic Gradient Descent (SGD) implementation to minimize
		the cost function

		Parameters:
		-----------
		free_param : numpy.array
			2D-array containing the set of optimized free parameter,
			stacked along the first axis.
		gradient : numpy.array
			Gradient at the center point calculated by the randomly chosen
			local environment. The gradient always points in the direction
			of steepest ascent.
		grad_scale : positive float
			Scales the step size in the gradient descent. Often also
			referred to as learning rate. Necessary to compensate for the
			"roughness" of the objective function field.

		Returns:
		-------
		free_param_next : numpy.array
			1D-array containing the set of optimized free parameter
			for the next iteration step. """
    free_param_next = free_param[-1] - grad_scale * gradient
    return free_param_next


def __call__():
    """Returns tuple of tuples for currency code and name."""


def get_chart_table_args(stats_table):
    """Creates gviz DataTable object from a TensorFlow stats table.

  Args:
    stats_table: A tf_stats_pb2.TfStatsTable.

  Returns:
    Returns a gviz_api.DataTable
  """
    table_description = [('rank', 'number', 'Rank'), ('host_or_device',
        'string', 'Host/device'), ('type', 'string', 'Type'), ('operation',
        'string', 'Operation'), ('occurrences', 'number', '#Occurrences'),
        ('total_time', 'number', 'Total time (us)'), ('avg_time', 'number',
        'Avg. time (us)'), ('total_self_time', 'number',
        'Total self-time (us)'), ('avg_self_time', 'number',
        'Avg. self-time (us)'), ('device_total_self_time_percent', 'number',
        'Total self-time on Device (%)'), (
        'device_cumulative_total_self_time_percent', 'number',
        'Cumulative total-self time on Device (%)'), (
        'host_total_self_time_percent', 'number',
        'Total self-time on Host (%)'), (
        'Host_cumulative_total_self_time_percent', 'number',
        'Cumulative total-self time on Host (%)')]
    data = []
    for record in stats_table.tf_stats_record:
        row = [record.rank, record.host_or_device, record.op_type, record.
            op_name, record.occurrences, record.total_time_in_us, record.
            avg_time_in_us, record.total_self_time_in_us, record.
            avg_self_time_in_us, record.device_total_self_time_as_fraction,
            record.device_cumulative_total_self_time_as_fraction, record.
            host_total_self_time_as_fraction, record.
            host_cumulative_total_self_time_as_fraction]
        data.append(row)
    return table_description, data, []


def plot_bubble_area_hist(df, bSave=False, dirname=None):
    """Plots a histogram of the area of the bubbles
    """
    import plotly
    import plotly.graph_objs as go
    import plotly.io as pio
    data = []
    for i in range(len(df['Frame'].unique())):
        data.append(go.Histogram(x=df[df['Frame'] == df['Frame'].unique()[i
            ]]['Area'], name=df['Frame'].unique()[i]))
    fig = go.Figure({'data': data, 'layout': go.Layout(width=800, height=
        500, xaxis=dict(title='Area (mm2)', linecolor='black', linewidth=2,
        mirror=True), showlegend=True)})
    plotly.offline.plot(fig, auto_open=True)
    if bSave:
        pio.write_image(fig, dirname + '/' + 'BubbleHist.pdf')


def chunks_with_empty(message, chunk_size):
    """The last chunk is empty, which signifies the end of the message."""
    chunk_start = 0
    chunks = []
    while chunk_start < len(message):
        chunks.append(message[chunk_start:chunk_start + chunk_size])
        chunk_start += chunk_size
    chunks.append(b'')
    return chunks


def isImageType(t):
    """
    Checks if an object is an image object.

    .. warning::

       This function is for internal use only.

    :param t: object to check if it's an image
    :returns: True if the object is an image
    """
    return hasattr(t, 'im')


def distance(x1, y1, x2, y2):
    """Get the distance between two points."""
    return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5


def exit(zelf):
    """ cancel the timer. """
    zelf._status = ''
    zelf.cancel()


def BorueErukhimovich(q, C, r0, s, t):
    """Borue-Erukhimovich model of microphase separation in polyelectrolytes

    Inputs:
    -------
        ``q``: independent variable
        ``C``: scaling factor
        ``r0``: typical el.stat. screening length
        ``s``: dimensionless charge concentration
        ``t``: dimensionless temperature

    Formula:
    --------
        ``C*(x^2+s)/((x^2+s)(x^2+t)+1)`` where ``x=q*r0``

    Literature:
    -----------
        o Borue and Erukhimovich. Macromolecules (1988) 21 (11) 3240-3249
        o Shibayama and Tanaka. J. Chem. Phys (1995) 102 (23) 9392
        o Moussaid et. al. J. Phys II (France) (1993) 3 (4) 573-594
        o Ermi and Amis. Macromolecules (1997) 30 (22) 6937-6942
    """
    x = q * r0
    return C * (x ** 2 + s) / ((x ** 2 + s) * (x ** 2 + t) + 1)


def get_nested_attr(obj, key):
    """Get a nested attribute from a dictionary

    Args:
        obj (dict): The top-level dictionaty
        key (str): The dot-separated key

    Returns: The value or None
    """
    parts = key.split('.')
    for part in parts[:-1]:
        obj = obj.get(part, {})
    return obj.get(parts[-1])


def get_path(root, target, pred):
    """
    Using a predecessor matrix from scipy.csgraph.shortest_paths, get all indices
    on the path from a root node to a target node.
    """
    path = [target]
    p = target
    while p != root:
        p = pred[p]
        path.append(p)
    path.reverse()
    return path


def replace_line_breaks(key: str) ->str:
    """replace ^J with
"""
    if key == '^J':
        return '\n'
    return key


def get_topic_name(lambda_name):
    """ Topic name generation """
    return '%s-zappa-async' % lambda_name


def roundup(num, bits):
    """ Round up a number to nearest multiple of 2^bits. The result is a number
        where the least significant bits passed in bits are 0.
    """
    return (num - 1 | (1 << bits) - 1) + 1


def im2spectra(geoArr):
    """Convert 3D images to array of spectra samples (rows: samples;  cols: spectral information)."""
    return geoArr.reshape((geoArr.shape[0] * geoArr.shape[1], geoArr.shape[2]))


def write_file(content, filename):
    """
    Write content to a new file.

    :param str content: lines of the file as a string
    :param str filename: path to the file
    """
    with open(filename, 'w') as open_file:
        open_file.write(content)


def delete_vm_instance(nova, vm_inst):
    """
    Deletes a VM instance
    :param nova: the nova client
    :param vm_inst: the snaps.domain.VmInst object
    """
    nova.servers.delete(vm_inst.id)


def active(intervals, now):
    """Return True if the minute of the week of *dt* is in *intervals*."""
    mow = now.weekday() * 24 * 60 + now.hour * 60 + now.minute
    for start, end in intervals:
        if start <= mow < end:
            return True
    return False


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

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

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


@staticmethod
def _get_backup_filter_options():
    """Return volume search options allowed by non-admin."""
    return 'name', 'status', 'volume_id'


def set(expr, *args):
    """Evaluate a revset.

        Emits changectx instances.
        """


def get_word(oLine, iIndex):
    """
    Returns a word from a line at iIndex.

    Parameters:

      oLine: (line object)

      iIndex: (integer)

    Returns: (string)
    """
    return oLine.line.split()[iIndex]


def _verify_is_integer_type(A, function_name):
    """
    _verify_is_integer_type(array, "function")

    Checks that ``A`` is an integer array. If it is not, it raises
    ``TypeError``.

    Parameters
    ----------
    A : ndarray
    function_name : str
        Used for error messages
    """
    k = A.dtype.kind
    if k not in 'iub':
        raise TypeError(
            'mahotas.%s: This function only accepts integer types (passed array of type %s)'
             % (function_name, A.dtype))


def _descend_namespace(caller_globals, name):
    """
    Given a globals dictionary, and a name of the form "a.b.c.d", recursively
    walk the globals expanding caller_globals['a']['b']['c']['d'] returning
    the result. Raises an exception (IndexError) on failure.
    """
    names = name.split('.')
    cur = caller_globals
    for i in names:
        if type(cur) is dict:
            cur = cur[i]
        else:
            cur = getattr(cur, i)
    return cur


def isRelval(request):
    """Return if given request is RelVal sample"""
    if 'SubRequestType' in request and 'RelVal' in request['SubRequestType']:
        return True
    return False


def get_description():
    """Get dictionary specifying FOOOF attributes, and what kind of data they store.

    Returns
    -------
    attributes : dict
        Mapping of FOOOF object attributes, and what kind of data they are.

    Notes
    -----
    This function organizes public FOOOF object attributes into:

    - results : parameters for and measures of the model
    - settings : model settings
    - data : input data
    - meta_data : meta data of the inputs
    - arrays : data stored in arrays
    - model_components : component pieces of the model
    - descriptors : descriptors of the object status and model results
    """
    attributes = {'results': ['aperiodic_params_', 'gaussian_params_',
        'peak_params_', 'r_squared_', 'error_'], 'settings': [
        'peak_width_limits', 'max_n_peaks', 'min_peak_height',
        'peak_threshold', 'aperiodic_mode'], 'data': ['power_spectrum',
        'freq_range', 'freq_res'], 'meta_data': ['freq_range', 'freq_res'],
        'arrays': ['freqs', 'power_spectrum', 'aperiodic_params_',
        'peak_params_', 'gaussian_params_'], 'model_components': [
        'fooofed_spectrum_', '_spectrum_flat', '_spectrum_peak_rm',
        '_ap_fit', '_peak_fit'], 'descriptors': ['has_data', 'has_model',
        'n_peaks_']}
    return attributes


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


def restore(archive, env={}):
    """Return dictionary obtained by evaluating the string arch.

    arch is typically returned by converting an Archive instance into
    a string using :func:`str` or :func:`repr`:

    Examples
    --------
    >>> a = Archive()
    >>> a.insert(a=1, b=2)
    >>> arch = str(a)
    >>> d = restore(arch)
    >>> print("%(a)i, %(b)i"%d)
    1, 2
    """
    ld = {}
    ld.update(env)
    exec(archive, ld)
    return ld


@staticmethod
def _check_value(value: str) ->None:
    """Check if the value is a valid configuration value.

        This check does not return anything but will instead raise
        an error if the given value does not meet the string requirements.

        In contrast to NodeTaskConfig, NodeTaskParams explicitly allows
        empty or space-only strings as values.

        Args:
            value (str): Value which should be checked.

        Raises:
            TypeError: If value is not of type string.
        """
    if not isinstance(value, str):
        raise TypeError('Given value string is not of type string.')


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


def _read_varint(stream):
    """
    read a varint from a stream
    :returns (result, bytes read)
    """
    mask = (1 << 32) - 1
    result = 0
    shift = 0
    pos = 0
    while 1:
        buf = stream.read(1)
        if not buf:
            return 0, 0
        b = buf[0]
        result |= (b & 127) << shift
        pos += 1
        if not b & 128:
            result &= mask
            result = int(result)
            return result, pos
        shift += 7
        if shift >= 64:
            raise RuntimeError('Too many bytes when decoding varint.')


def get_text(prompt='', msg=None, input=input):
    """Prompt user to enter multiple lines of text."""
    print((msg or 'Enter text.') + " End with ^D or a '.' as first character.")
    lines = []
    while True:
        try:
            line = input(prompt)
        except EOFError:
            break
        if line == '.':
            break
        lines.append(line)
    return '\n'.join(lines)


@classmethod
def delete_token_and_descendents(cls, token):
    """
        Yup, don't understand this.

        TODO:
            - Understand this.

        :type token: Token
        """
    from py_rete.negative_node import NegativeNode
    from py_rete.ncc_node import NccPartnerNode, NccNode
    for child in token.children:
        cls.delete_token_and_descendents(child)
    if not isinstance(token.node, NccPartnerNode):
        token.node.items.remove(token)
    if token.wme:
        token.wme.tokens.remove(token)
    if token.parent:
        token.parent.children.remove(token)
    if isinstance(token.node, NegativeNode):
        for jr in token.join_results:
            jr.wme.negative_join_results.remove(jr)
    elif isinstance(token.node, NccNode):
        for result_tok in token.ncc_results:
            result_tok.wme.tokens.remove(result_tok)
            result_tok.parent.children.remove(result_tok)
    elif isinstance(token.node, NccPartnerNode):
        token.owner.ncc_results.remove(token)
        if not token.owner.ncc_results:
            for child in token.node.ncc_node.children:
                child.left_activation(token.owner, None)


def _convert_clip(builder, node, graph, err):
    """
    convert to CoreML Clip Layer:
    https://github.com/apple/coremltools/blob/655b3be5cc0d42c3c4fa49f0f0e4a93a26b3e492/mlmodel/format/NeuralNetwork.proto#L5066
    """
    max_value = node.attrs.get('max', 3.4028234663852886e+38)
    min_value = node.attrs.get('min', -3.4028234663852886e+38)
    builder.add_clip(name=node.name, input_name=node.inputs[0], output_name
        =node.outputs[0], min_value=min_value, max_value=max_value)


def beg_ends(starting_dt, extent_duration, z=None):
    """
    >>> starting = parse('2018-03-02 9am')
    >>> beg_ends(starting, parse_duration('2d2h20m')[1])
    [(DateTime(2018, 3, 2, 9, 0, 0, tzinfo=Timezone('UTC')), DateTime(2018, 3, 2, 23, 59, 59, 999999, tzinfo=Timezone('UTC'))), (DateTime(2018, 3, 3, 0, 0, 0, tzinfo=Timezone('UTC')), DateTime(2018, 3, 3, 23, 59, 59, 999999, tzinfo=Timezone('UTC'))), (DateTime(2018, 3, 4, 0, 0, 0, tzinfo=Timezone('UTC')), DateTime(2018, 3, 4, 11, 20, 0, tzinfo=Timezone('UTC')))]
    >>> beg_ends(starting, parse_duration('8h20m')[1])
    [(DateTime(2018, 3, 2, 9, 0, 0, tzinfo=Timezone('UTC')), DateTime(2018, 3, 2, 17, 20, 0, tzinfo=Timezone('UTC')))]
    """
    pairs = []
    beg = starting_dt
    ending = starting_dt + extent_duration
    while ending.date() > beg.date():
        end = beg.end_of('day')
        pairs.append((beg, end))
        beg = beg.start_of('day').add(days=1)
    pairs.append((beg, ending))
    return pairs


def _get_cbend_msg(is_mag_phase, is_sort1):
    """get the header for the CBEND result"""
    if is_mag_phase:
        raise NotImplementedError()
    else:
        realimag_magphase = (
            '                                                          (REAL/IMAGINARY)'
            )
    msg = [
        '                         C O M P L E X   S T R E S S E S   I N   B E N D   E L E M E N T S   ( C B E N D ) '
        , realimag_magphase,
        '                        CIRC.      LOCATION         LOCATION         LOCATION         LOCATION'
        ]
    if is_sort1:
        msg.append(
            """   ELEMENT-ID  GRID END  ANG.         C                D                E                F
"""
            )
    else:
        msg.append(
            """   FREQUENCY   GRID END  ANG.         C                D                E                F
"""
            )
    return msg


def run_window_spec_command(window_spec, run_function):
    """Run the command from the given window spec, if it has one.

    :param window_spec: the window spec whose command to run
    :type window_spec: dict

    :param run_function: the function to call to run the command
    :type run_function: callable

    """
    command = window_spec.get('command')
    if command:
        run_function(command)


def soma_reais(x: float, y: float) ->float:
    """Realiza a soma entre dois reais.

    Parameters
    ----------
    x : float
        número real.
    y : float
        número real.

    Returns
    -------
    float
        o resultado da  soma x + y.
    """
    return x + y


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 unique_duplicate(iterable):
    """
    Creates two lists derived from the supplied iterable: duplicate values and unique values
    Returns: unique, duplicate
    """
    unique = []
    duplicate = []
    for x in iterable:
        if x in unique:
            if x not in duplicate:
                duplicate.append(x)
        else:
            unique.append(x)
    return unique, duplicate


def sculptmode_toggle():
    """Toggle sculpt mode in 3D view

    """
    pass


def queue_parser(user=None, partition=None):
    """Iterator for queue parsing.

    Parameters
    ----------
    user : str, optional
        User name to pass to qstat to filter queue with
    partiton : str, optional
        Partition to filter the queue with

    Yields
    ------
    job_id : str
    array_id : str or None
    name : str
    userid : str
    partition : str
    state :str
    nodelist : list
    numnodes : int
    cntpernode : int or None
    exit_code : int or Nonw
    """
    pass


@staticmethod
def _validate_parent(new_parent):
    """
        Checks whether a provided object is a valid odml.Section.

        :param new_parent: object to check whether it is an odml.Section.
        :returns: Boolean whether the object is an odml.Section or not.
        """
    from odml.section import BaseSection
    if isinstance(new_parent, BaseSection):
        return True
    return False


@staticmethod
def _truncate_name(string, max_len=20):
    """Truncates string to max_len number of characters, adds ellipses instead if its too long"""
    if len(string) > max_len:
        return string[:max_len - 3] + '...'
    else:
        return string


def filter_atoms(fhandle, atomname_set):
    """Removes specific atoms that do not match a given atom name.
    """
    records = 'ATOM', 'HETATM', 'ANISOU'
    for line in fhandle:
        if line.startswith(records):
            if line[12:16].strip() not in atomname_set:
                continue
        yield line


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


@classmethod
def parse(cls, headers):
    """Returns a dictionary from HTTP header text.

        >>> h = HTTPHeaders.parse(
            "Content-Type: text/html\\r\\nContent-Length: 42\\r\\n")
        >>> sorted(h.items())
        [('Content-Length', '42'), ('Content-Type', 'text/html')]
        """
    h = cls()
    for line in headers.splitlines():
        if line:
            h.parse_line(line)
    return h


@classmethod
def creator(cls, charset):
    """Returns a function creating L{EncodeWSGIFilter}s with a given
        charset.
        @type charset: str
        """
    return lambda : cls(charset)


def recommend():
    """Prints a soda recommendation."""
    print('Drink Coca-Cola.')


@classmethod
def from_dict(cls, d):
    """ Return a ``TileGrid`` from a dictionary

        Parameters
        ----------
        d : dict
            Dictionary of class attributes (see __init__)

        Returns
        -------
        TileGrid
            A new TileGrid according to parameters in ``d``
        """
    return cls(**d)


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 fpow1(x, n):
    """
    Perform iterative fast exponentiation by squaring.

    :param x: the base to be exponentiated
    :param n: the target power value
    :return: x ^ n
    """
    if x == 0:
        if n == 0:
            return 1
        elif n > 0:
            return 0
        else:
            reason = '0.0 cannot be raised to a negative power'
            raise ZeroDivisionError(reason)
    if n < 0:
        x = 1 / x
        n = -n
    if n == 0:
        return 1
    y = 1
    while n > 1:
        if n % 2 == 0:
            x = x * x
            n = n // 2
        else:
            y = x * y
            x = x * x
            n = n // 2
    return x * y


def define(hub):
    """
    Define how the onfail requisite should behave
    """
    return {'result': False}


def seconds_to_timestamp(seconds):
    """
    timestamp hh:mm:ss derived from seconds since midnight
    """
    h = int(seconds / 60 ** 2)
    seconds = seconds - 60 ** 2 * h
    m = int(seconds / 60)
    seconds = seconds - 60 * m
    s = int(seconds)
    timestamp = '{0:2d}:{1:2d}:{2:2d}'.format(h, m, s)
    timestamp = timestamp.replace(' ', '0')
    return timestamp


def get_optimal_num_clusters(n_clusters_vector, obj_vals):
    """
    Function to find the optimal number of clusters for the given dataset
    Input:
        - n_clusters_vector: vector of various cluster lenghts to evaluate
        - objVals: The list of final values of the inertia criterion (sum
          of squared distances to the closest centroid for all observations
          in the training set) for all values of number of clusters
    Output:
        - optimal_num_clusters: optimal number of clusters for the given data
    """
    optimal_num_clusters = n_clusters_vector[0]
    epsilon = 0.05
    for i in range(1, len(n_clusters_vector)):
        if obj_vals[i - 1] - obj_vals[i] < epsilon:
            optimal_num_clusters = n_clusters_vector[i - 1]
            break
    return optimal_num_clusters


def getMonthTypeFromName(name):
    """Return the type of the month with the right name."""


def camera_to_view_selected():
    """Move the camera so selected objects are framed

    """
    pass


def rshift(val, n):
    """python port for '>>>'(right shift with padding)
    """
    return val % 4294967296 >> n


def last_continuous_indexesnot_slice(ol, value):
    """
        from elist.elist import *
        ol = [1,"a","a",2,3,"a",4,"a","a","a",5]
        last_continuous_indexesnot_slice(ol,"a")
    """
    length = ol.__len__()
    end = None
    slice = []
    for i in range(length - 1, -1, -1):
        if not ol[i] == value:
            end = i
            break
        else:
            pass
    if end == None:
        return None
    else:
        slice.append(end)
        for i in range(end - 1, -1, -1):
            if not ol[i] == value:
                slice.append(i)
            else:
                break
    slice.reverse()
    return slice


def _enleverAlea(text):
    """Gets rid of the stupid thing that they did, idk what it really is for, but i guess it adds security"""
    sansalea = []
    for i, b in enumerate(text):
        if i % 2 == 0:
            sansalea.append(b)
    return ''.join(sansalea)


@classmethod
def can_handle(cls, filepath: str) ->bool:
    """Determines if a given file can be handled by the current archive.

        Args:
            filepath (str): The filepath to check if can be handled
        """
    header = cls.header_struct.parse_file(filepath)
    return header.magic == b'BSA\x00' and header.version in (103, 104, 105)


def _is_same_value_at_column(i, all_args):
    """ comparison from both ends so as to find opportunistically that the parameter is not the same everywhere"""
    left, right = 1, len(all_args) - 1
    value = all_args[0][i]
    while True:
        if value != all_args[left][i]:
            return False
        left += 1
        if value != all_args[right][i]:
            return False
        right -= 1
        if left > right:
            break
    return True


def strip_modifier_remove(name: str='Name'):
    """Remove a modifier from the strip

    :param name: Name, Name of modifier to remove
    :type name: str
    """
    pass


def read(path):
    """
    Get file contents

    Parameters
    ----------
    path : pathlib.Path
        Path of file to read

    Returns
    -------
    str
        File contents
    """
    with path.open('r') as f:
        return f.read()


def ignore(val):
    """
    Stub to ignore value from trafaret
    Use it like:

    >>> a = Int >> ignore
    >>> a.check(7)
    """
    pass


def check_time_event(oqparam, occupancy_periods):
    """
    Check the `time_event` parameter in the datastore, by comparing
    with the periods found in the exposure.
    """
    time_event = oqparam.time_event
    if time_event and time_event not in occupancy_periods:
        raise ValueError(
            'time_event is %s in %s, but the exposure contains %s' % (
            time_event, oqparam.inputs['job_ini'], ', '.join(
            occupancy_periods)))


def is_nofollow(url):
    """Check if take links.

	Search !nofollow! at the end of url, remove it if found.

	:param url: webpage url
	:type url: str
	:return: True if nofollow and url

	"""
    if url.endswith('!nofollow!'):
        return True, url[:-10]
    return False, url


def get_device_uid_from_element_uid(element_uid: str) ->str:
    """
    Return device UID from the given element UID.

    :param element_uid: Element UID, something like devolo.MultiLevelSensor:hdm:ZWave:CBC56091/24#2
    :return: Device UID, something like hdm:ZWave:CBC56091/24
    """
    element_uid = element_uid.split(':', 1)[1].split('#')[0]
    if element_uid.endswith('secure'):
        return element_uid.rsplit(':', 1)[0]
    return element_uid


@classmethod
def enable(cls):
    """Enables DOM snapshot agent for the given page.
        """
    return cls.build_send_payload('enable', {}), None


def pad_data(pcm_frames, channels, bits_per_sample):
    """returns True if the given stream combination
    requires an extra padding byte at the end of the 'data' chunk"""
    return pcm_frames * channels * (bits_per_sample // 8) % 2


def union(f1, f2, *args):
    """
    y = union(f1, f2, f3=None, f4=None, f5=None, ...)

    Union of images.

    `union` creates the image `y` by taking the pixelwise maximum
    between the images given. When the images are binary images,
    y represents the union of them.

    Parameters
    ----------
    f1 : Gray-scale (uint8 or uint16) or binary image.
    f2 : Gray-scale (uint8 or uint16) or binary image. Or constant
    args : Gray-scale (uint8 or uint16) or binary images.

    Returns
    -------
    y : Image
    """
    """
        - Examples
            #
            #   example 1
            #
            f=to_uint8([255, 255,  0,  10,   0, 255, 250])
            print 'f=',f
            g=to_uint8([  0,  40, 80, 140, 250,  10,  30])
            print 'g=',g
            print union(f, g)
            print union(f, 255)
            #
            #   example 2
            #
            a = readgray('form-ok.tif')
            b = readgray('form-1.tif')
            c = union(a,b)
            show(a)
            show(b)
            show(c)
            #
            #   example 3
            #
            d = readgray('danaus.tif')
            e = (d < 80)
            f = union(d,gray(e))
            show(d)
            show(e)
            show(f)
            #
            #   example 4
            #
            g = readgray('tplayer1.tif')
            h = readgray('tplayer2.tif')
            i = readgray('tplayer3.tif')
            j = union(g,h,i)
            show(g)
            show(h)
            show(i)
            show(j)
    """
    from numpy import maximum
    y = maximum(f1, f2)
    for f in args:
        y = maximum(y, f)
    return y.astype(f1.dtype)


def defensive(pos, speed, mrange, acc, dodge, targets, dmg, hp, armor, luck,
    distances, dd, team, target_f, enemies, allies, Z, Z_xi, Z_yi, i):
    """
    This AI option attempts to find a nearby high hill and sit on it, waiting for
    a nearby enemy.
    """
    return NotImplemented


@staticmethod
def _remove_trailing_spaces(line):
    """Remove trailing spaces unless they are quoted with a backslash."""
    while line.endswith(' ') and not line.endswith('\\ '):
        line = line[:-1]
    return line.replace('\\ ', ' ')


def _resolve_name(name, package, level):
    """Return the absolute name of the module to be imported."""
    if not hasattr(package, 'rindex'):
        raise ValueError("'package' not set to a string")
    dot = len(package)
    for x in range(level, 1, -1):
        try:
            dot = package.rindex('.', 0, dot)
        except ValueError:
            raise ValueError(
                'attempted relative import beyond top-level                package'
                )
    return '%s.%s' % (package[:dot], name)


@staticmethod
def preprocess_corpus(corpus=None):
    """Removes newlines and adds padding to punctuation characters."""
    if not corpus:
        return
    for index, entry in enumerate(corpus):
        entry = entry.replace(',', ' ,')
        entry = entry.replace('.', ' .')
        entry = entry.replace('?', ' ?')
        entry = entry.replace('!', ' !')
        corpus[index] = entry
    return corpus


def patch_stdlib_logging():
    """This replaces the stdlib logging module with us."""


def simple_atmo_opstring(haze, contrast, bias):
    """Make a simple atmospheric correction formula."""
    gamma_b = 1 - haze
    gamma_g = 1 - haze / 3.0
    ops = (
        'gamma g {gamma_g}, gamma b {gamma_b}, sigmoidal rgb {contrast} {bias}'
        .format(gamma_g=gamma_g, gamma_b=gamma_b, contrast=contrast, bias=bias)
        )
    return ops


def potri(A=None, name=None, attr=None, out=None, **kwargs):
    """Performs matrix inversion from a Cholesky factorization.
    Input is a tensor *A* of dimension *n >= 2*.

    If *n=2*, *A* is a triangular matrix (entries of upper or lower triangle are all zero)
    with positive diagonal. We compute:

      *out* = *A*\\ :sup:`-T` \\* *A*\\ :sup:`-1` if *lower* = *true*
      *out* = *A*\\ :sup:`-1` \\* *A*\\ :sup:`-T` if *lower* = *false*

    In other words, if *A* is the Cholesky factor of a symmetric positive definite matrix
    *B* (obtained by *potrf*), then

      *out* = *B*\\ :sup:`-1`

    If *n>2*, *potri* is performed separately on the trailing two dimensions for all inputs
    (batch mode).

    .. note:: The operator supports float32 and float64 data types only.

    .. note:: Use this operator only if you are certain you need the inverse of *B*, and
              cannot use the Cholesky factor *A* (*potrf*), together with backsubstitution
              (*trsm*). The latter is numerically much safer, and also cheaper.

    Examples::

       Single matrix inverse
       A = [[2.0, 0], [0.5, 2.0]]
       potri(A) = [[0.26563, -0.0625], [-0.0625, 0.25]]

       Batch matrix inverse
       A = [[[2.0, 0], [0.5, 2.0]], [[4.0, 0], [1.0, 4.0]]]
       potri(A) = [[[0.26563, -0.0625], [-0.0625, 0.25]],
                   [[0.06641, -0.01562], [-0.01562, 0,0625]]]

    Defined in src/operator/tensor/la_op.cc:L275

    Parameters
    ----------
    A : Symbol
        Tensor of lower triangular matrices

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

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


def smart_truncate(string, max_length=0, word_boundary=False, separator=' ',
    save_order=False):
    """
    Truncate a string.
    :param string: string for modification
    :param max_length: output string length
    :param word_boundary:
    :param save_order: if True then word order of output string is like input string
    :param separator: separator between words
    :return:
    """
    string = string.strip(separator)
    if not max_length:
        return string
    if len(string) < max_length:
        return string
    if not word_boundary:
        return string[:max_length].strip(separator)
    if separator not in string:
        return string[:max_length]
    truncated = ''
    for word in string.split(separator):
        if word:
            next_len = len(truncated) + len(word)
            if next_len < max_length:
                truncated += '{0}{1}'.format(word, separator)
            elif next_len == max_length:
                truncated += '{0}'.format(word)
                break
            elif save_order:
                break
    if not truncated:
        truncated = string[:max_length]
    return truncated.strip(separator)


def __setattr__(name, value):
    """Call __setattr__ on context.
        """


def websocket_send_binary(message, request_context=None):
    """Sends binary message to websocket.

    :param str message: data to send

    :param request_context:

    :raises IOError: If unable to send a message.
    """


@staticmethod
def factory(task_name: str) ->'AnalyticTask':
    """Initialize the correct task based on the given arguments.
        :param task_name: The name of the task to initialize.
        :return: An initialized child of this class.
        """
    from . import TASK_REGISTRY
    for task in TASK_REGISTRY:
        if task.name == task_name:
            return task()


def __getattr__(zelf, name):
    """ Override Object.__getattr__. """
    try:
        return zelf.__getitem__(name)
    except KeyError:
        if 'default' in zelf:
            zelf[name] = zelf['default']
    return super().__getattr__(name)


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

        :param es_major: major version of Elasticsearch, as string
        :returns:        dictionary with a key, 'items', with the mapping
        """
    mapping = """
        {
            "properties": {
                "content_analyzed": {
                  "type": "text",
                  "index": true
                },
                "tags_analyzed": {
                  "type": "text",
                  "index": true
                }
           }
        } """
    return {'items': mapping}


def _in_species_list(species, species_list=None):
    """
    Return True if species_list is None or if species is in species_list.

    >>> _in_species_list('homo_sapiens')
    True
    >>> _in_species_list('homo_sapiens', ['homo_sapiens', 'mus_musculus'])
    True
    >>> _in_species_list('pan_paniscus', ['homo_sapiens', 'mus_musculus'])
    False
    """
    if species_list is None:
        return True
    return species in species_list


def node_get_boot_mode(task):
    """Read currently set boot mode from a node.

    Reads the boot mode for a node. If boot mode can't be discovered,
    `None` is returned.

    :param task: a TaskManager instance.
    :raises: DriverOperationError or its derivative in case
             of driver runtime error.
    :raises: UnsupportedDriverExtension if current driver does not have
             management interface or `get_boot_mode()` method is
             not supported.
    :returns: Boot mode. One of :mod:`ironic.common.boot_mode` or `None`
        if boot mode can't be discovered
    """
    task.driver.management.validate(task)
    return task.driver.management.get_boot_mode(task)


@classmethod
def service_status(cls, options=None):
    """Build foreman-maintain service status"""
    cls.command_sub = 'status'
    if options is None:
        options = {}
    result = cls._construct_command(options)
    return result


def _format_servers_list_networks(networks):
    """Return a formatted string of a server's networks

    :param networks: a Server.networks field
    :rtype: a string of formatted network addresses
    """
    output = []
    for network, addresses in networks.items():
        if not addresses:
            continue
        addresses_csv = ', '.join(addresses)
        group = '%s=%s' % (network, addresses_csv)
        output.append(group)
    return '; '.join(output)


def t_network_record_old(val, source=None):
    """
    Dummy convertor for legacy purposes.
    """
    return val


@classmethod
def matmul(cls, m1, m2):
    """
        Will return a new matrix which is matrix product of m1 and m2.
        """
    if m1.columns() == m2.rows():
        return cls._alloc_matmul(m1, m2)
    else:
        raise ValueError('Matrix size mismatch')


def rgb2html(rgb, alpha=None):
    """
    method will convert given rgb tuple to html representation
    rgb(R, G, B)
    if alpha is set, it will be included
    rgb(R, G, B, )
    """
    if alpha is not None:
        return 'rgba({0:d}, {1:d}, {2:d}, {3:s})'.format(*rgb, alpha if
            isinstance(alpha, str) else '%1.2f' % float(alpha))
    return 'rgb({0:d}, {1:d}, {2:d})'.format(*rgb)


def nts(s, encoding, errors):
    """Convert a null-terminated bytes object to a string.
    """
    p = s.find(b'\x00')
    if p != -1:
        s = s[:p]
    return s.decode(encoding, errors)


def _fedora_messaging_send_msg(msgs):
    """Send message to fedora-messaging."""
    from fedora_messaging import api, config
    config.conf.setup_logging()
    for msg in msgs:
        event = msg.get('event', 'event')
        topic = 'odcs.compose.%s' % event
        api.publish(api.Message(topic=topic, body=msg))


def namespace_name(fully_qualified_name: str) ->str:
    """
    Return the namespace name of a fully qualified class name.
    :param fully_qualified_name: The fully qualified name
    """
    tokens = fully_qualified_name.split('.')
    return '.'.join(tokens[:-1])


def _task_callback(task):
    """Print task status.

    :param task: XML representation of a task resource
    :type task: lxml.objectify.ObjectifiedElement
    """
    message = '{0}: {1}, status: {2}'.format(task.get('operationName'),
        task.get('operation'), task.get('status'))
    if hasattr(task, 'Progress'):
        message += ', progress: %s%%' % task.Progress
    print(message)


def reveal(select: bool=True):
    """Show all Grease Pencil layers

    :param select: Select
    :type select: bool
    """
    pass


def _set_member_short_name(ctx):
    """Sets ensemble member short names.

    """
    for member in ctx.doc.members:
        if not member.short_name and len(member.ensemble_ids):
            member.short_name = member.ensemble_ids[0].value


def psi_H_Mg_Br_MP98(T, P):
    """c-c'-a: hydrogen magnesium bromide [MP98]."""
    psi = -0.005
    valid = T == 298.15
    return psi, valid


@classmethod
def append_marketdata(cls, client, option_position):
    """
        Fetch and merge in Marketdata for option position
        """
    return cls.append_marketdata_list(client, [option_position])[0]


def version_string():
    """ Format a simple string with CLU’s current semantic version tag """
    from clu.constants import consts
    from clu.version import version_info, VersionInfo
    from clu.version.git_version import git_version_tags
    version = VersionInfo(git_version_tags(consts.BASEPATH) or version_info)
    semantic = f'{version.major}.{version.minor}.{version.patch}'
    if version.pre:
        semantic += f'-{version.pre}'
        if version.build:
            semantic += f'+{version.build}'
        semantic += ' [SNAPSHOT]'
    else:
        semantic += ' [release]'
    return semantic


@classmethod
def _is_list_index(cls, index) ->bool:
    """Check if index is a list index."""
    return isinstance(index, int)


def close_event(event):
    """
    Closes an event retrieved from Karabo at XFEL.

    Karabo events do not need to be closed, so this function actually does nothing.

    NOTE: This function is designed to be injected as a member function into an
    :class:`~onda.utils.data_event.DataEvent` object.

    Arguments:

        event (:class:`~onda.utils.data_event.DataEvent`): an object storing the event
            data.
    """
    del event


def sliding_window(sequence, window_size, step_size):
    """Converts a sequence into sliding windows. Returns a list of sequences.
	- sequence: a string containing only nucleotides.
	- window_size: Windows of equal size sequence. Default is 500 bp.
	- step_size: overlap required for sliding windows. Default is 250 bp.
	"""
    seq = []
    for start in range(0, len(sequence), step_size):
        end = start + window_size
        if end > len(sequence):
            seq.append(sequence[start:len(sequence)] + 'N' * (window_size -
                (len(sequence) - start)))
            break
        else:
            seq.append(sequence[start:end])
    return seq


def ce_unknown_host_cb(host, fingerprint):
    """ ce_unknown_host_cb """
    return True


def rank(x):
    """Return cross-sectional rank."""
    return x.rank(axis=1, pct=True)


def _module_name(type_name):
    """
    Get module name.

    :param type_name str: Name of message type sans package, e.g. 'String'
    :returns str: name of python module for auto-generated code
    """
    return '_' + type_name


def index_object(ob):
    """ index one object
        """


def fill_class_weights(weights, max_id=-1):
    """
    Gets a dictionary of labels with their weights and creates a list with size of the labels filled with those weights.
    Missing labels in the dictionary would get value 1.

    Args:
        weights: dictionary of weights for labels, labels as keys and weights are their values
        max_id: the largest label id in the dataset, default=-1 would consider the largest label in the weights dictionary as max_id
    Returns:
        weights_list: list of weights for labels
    """
    if max_id < 0:
        max_id = 0
        for l in weights.keys():
            max_id = max(max_id, l)
    all_weights = [1.0] * (max_id + 1)
    for i in range(len(all_weights)):
        if i in weights:
            all_weights[i] = weights[i]
    return all_weights


def maybe_get_pkg_resources():
    """
    Return the pkg_resources module or None, depending on whether we think that whatever
    the system has available is going to do an ok job at parsing requirements patterns.
    We don't want to strictly require any particular version of setuptools to not force
    the user to mess with their system.
    """
    try:
        import pkg_resources
        try:
            pkg_resources.Requirement.parse(
                'foo[bar]==2.0;python_version>"2.7"')
        except (ValueError, AttributeError):
            return None
        else:
            return pkg_resources
    except ImportError:
        return None


def project_opened(project):
    """This function is called after opening the project"""


def add_vertex_slide(MASK_OT_add_vertex=None, MASK_OT_slide_point=None):
    """Add new vertex and slide it

    :param MASK_OT_add_vertex: Add Vertex, Add vertex to active spline
    :param MASK_OT_slide_point: Slide Point, Slide control points
    """
    pass


def check_for_choice_col_based_on_return_long_probs(return_long_probs,
    choice_col):
    """
    Ensure that if return_long_probs is False then choice_col is not None.
    Raise a helpful ValueError if otherwise.

    Parameters
    ----------
    return_long_probs : bool.
            Indicates whether or not the long format probabilities (a 1D numpy
            array with one element per observation per available alternative)
            should be returned.
    choice_col : str or None.
        Denotes the column in `data` which contains a one if the
        alternative pertaining to the given row was the observed outcome
        for the observation pertaining to the given row and a zero
        otherwise.

    Returns
    -------
    None.
    """
    if not return_long_probs and choice_col is None:
        msg = 'If return_long_probs == False, then choice_col cannote be None.'
        raise ValueError(msg)
    else:
        return None


def change_transpose_distance(s1, s2):
    """ Return the minimal number of changes and transpositions needed to get from s1 to s2. """
    n = max(len(s1), len(s2))
    s1, s2 = s1.rjust(n, '0'), s2.rjust(n, '0')
    score = [0]
    for i in range(len(s1)):
        cost = score[i] + (0 if s1[i] == s2[i] else 1)
        if i:
            cost = min(cost, score[i - 1] + (1 if set(s1[i - 1:i + 1]) ==
                set(s2[i - 1:i + 1]) else 2))
        score.append(cost)
    return score[-1]


def breakdown(prev_frame: int=0, next_frame: int=0, percentage: float=0.5):
    """Create a suitable breakdown pose on the current frame

    :param prev_frame: Previous Keyframe, Frame number of keyframe immediately before the current frame
    :type prev_frame: int
    :param next_frame: Next Keyframe, Frame number of keyframe immediately after the current frame
    :type next_frame: int
    :param percentage: Percentage, Weighting factor for the sliding operation
    :type percentage: float
    """
    pass


def getHierarchies():
    """Returns a list of IHierarchy related to the cube."""


def logical_not(input):
    """Perform a logical not operation.  Equivalent to np.logical_not

    Parameters
    ----------
    input : Tensor
        The input

    Returns
    -------
    Tensor
        The result
    """
    pass


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


def L_nu_from_sfr(sfr):
    """Use Kennicutt (1998) conversion from UV luminosity to star formation rate.

    Parameters
    ----------

    sfr:
        The SFR in Msun/year.

    Returns
    -------

    luminosity:
        the luminosity in units of ergs s^-1 Hz^-1 anywhere between
        1500-2800 Angstroms.

    Notes
    -----

    Kennicutt (1998ARA&A..36..189K) says:

       SFR/(MSun/year) = 1.4 * 10^-28 (L_nu/ergs s^-1 Hz^-1)

    where L_nu is the UV luminosity anywhere between 1500-2800 Angstroms.
    """
    return sfr / 1.4e-28


def p_operator_range_before_unit_range(p):
    """operator_range : BEFORE unit_range"""
    unit_range = p[2]
    p[0] = lambda ref: (None, unit_range(ref)[0])


@staticmethod
def _get_grouped_tokens():
    """Return an empty grouped tokens structure.

        Returns:
            dict: the dictionary with the empty grouped tokens structure.

        """
    return {'parent': None, 'bool': None, 'tokens': []}


def indicator_volatility_daily(df_daily, price_col='close'):
    """Create rolling volatility using EWM of 36 which matches a rolling stdev of 25

    Args:
        df_daily (frame): contains "close" column
        price_col (str): "close" is default

    Returns:
        frame: index = index of df_daily, adds colum called vol36

    """
    df = df_daily[[price_col]].copy()
    df['pct_returns'] = df[price_col].pct_change()
    df['vol36'] = df.pct_returns.ewm(span=36, adjust=False).std()
    df.drop(['pct_returns', price_col], axis=1, inplace=True)
    df.dropna(inplace=True)
    return df


def get_paginator(operation_name=None):
    """
    Create a paginator for an operation.

    :type operation_name: string
    :param operation_name: The operation name. This is the same name
            as the method name on the client. For example, if the
            method name is create_foo, and you'd normally invoke the
            operation as client.create_foo(**kwargs), if the
            create_foo operation can be paginated, you can use the
            call client.get_paginator('create_foo').

    :rtype: L{botocore.paginate.Paginator}
    """
    pass


def is_valid_year(year):
    """
    Check if year's value is valid
    :param year: int
    :return: boolean
    """
    return 2030 >= year > 1970


def transform_login(config):
    """
    Parse login data as dict. Called from load_from_file and
    also can be used when collecting information from other
    sources as well.

    :param dict data: data representing the valid key/value pairs
           from smcrc
    :return: dict dict of settings that can be sent into session.login
    """
    verify = True
    if config.pop('smc_ssl', None):
        scheme = 'https'
        verify = config.pop('ssl_cert_file', None)
        if config.pop('verify_ssl', None):
            if not verify:
                verify = False
        else:
            verify = False
    else:
        scheme = 'http'
        config.pop('verify_ssl', None)
        config.pop('ssl_cert_file', None)
        verify = False
    transformed = {}
    url = '{}://{}:{}'.format(scheme, config.pop('smc_address', None),
        config.pop('smc_port', None))
    timeout = config.pop('timeout', None)
    if timeout:
        try:
            timeout = int(timeout)
        except ValueError:
            timeout = None
    api_version = config.pop('api_version', None)
    if api_version:
        try:
            float(api_version)
        except ValueError:
            api_version = None
    transformed.update(url=url, api_key=config.pop('smc_apikey', None),
        api_version=api_version, verify=verify, timeout=timeout, domain=
        config.pop('domain', None))
    if config:
        transformed.update(kwargs=config)
    return transformed


@staticmethod
def run_checks(number_samples, k_choices):
    """Runs checks on `k_choices`
        """
    assert isinstance(k_choices, int
        ), 'Number of optimal trajectories should be an integer'
    if k_choices < 2:
        raise ValueError(
            'The number of optimal trajectories must be set to 2 or more.')
    if k_choices >= number_samples:
        msg = (
            'The number of optimal trajectories should be less than the                     number of samples'
            )
        raise ValueError(msg)


def initialize(context):
    """Intializer called when used as a Zope 2 product."""


def conditional_content_removal(request, response):
    """
    Removes the content of responses for HEAD requests, 1xx, 204 and 304
    responses. Ensures compliance with RFC 2616, section 4.3.
    """
    if 100 <= response.status_code < 200 or response.status_code in (204, 304):
        if response.streaming:
            response.streaming_content = []
        else:
            response.content = b''
        response['Content-Length'] = '0'
    if request.method == 'HEAD':
        if response.streaming:
            response.streaming_content = []
        else:
            response.content = b''
    return response


def toggle_wingtip_smokes(info):
    """
        Process 'user toggled wingtip smokes' event.

        Input:
        `info`  # An object with information about event's time, user's
                # callsign, aircraft, wingtip smokes state value and position
                # on map.
        """


def intersect(i1, i2):
    """ Test whether the interval intersects with i2? """
    return i1.inf <= i2.sup and i2.inf <= i1.sup


def conditional_response_app(environ, start_response):
    """ Like the normal __call__ interface, but checks conditional
        headers:

        - If-Modified-Since (304 Not Modified; only on GET, HEAD)

        - If-None-Match (304 Not Modified; only on GET, HEAD)

        - Range (406 Partial Content; only on GET, HEAD)"""


def propstat_by_status(propstat):
    """Sort a list of propstatus objects by HTTP status.

    :param propstat: List of PropStatus objects:
    :return: dictionary mapping HTTP status code to list of PropStatus objects
    """
    bystatus = {}
    for propstat in propstat:
        bystatus.setdefault((propstat.statuscode, propstat.
            responsedescription), []).append(propstat.prop)
    return bystatus


@classmethod
def unit_attname(cls, unit_str):
    """
        Retrieves the unit attribute name for the given unit string.
        For example, if the given unit string is 'metre', 'm' would be returned.
        An exception is raised if an attribute cannot be found.
        """
    lower = unit_str.lower()
    if unit_str in cls.UNITS:
        return unit_str
    elif lower in cls.UNITS:
        return lower
    elif lower in cls.LALIAS:
        return cls.LALIAS[lower]
    else:
        raise Exception(
            'Could not find a unit keyword associated with "%s"' % unit_str)


def go():
    """
    grep -v "\\#" QGs.txt | awk '{print "./aws_drizzler.py",$1,$2,$3,"60"}' > run.sh
    grep -v "\\#" gomez.txt | awk '{print "./aws_drizzler.py",$1,$2,$3,"60"}' >> run.sh

    """
    pass


def publishTraverse(request, name):
    """Traverse to step by it's name."""


def upgrade(root, from_version, to_version):
    """Upgrade obj and all its children for all version between
        from_version and to_version.
        """


@staticmethod
def matrix_from_array(a):
    """Make a Matlab-compatible matrix from a (Numpy) array.

        Parameters
        ----------
        a : ndarray
            The input array.

        Returns
        -------
        System.Array
            The matrix.

        Examples
        --------
        >>>

        """
    raise NotImplementedError


def get_num_rows(ai_settings, ship_height, alien_height):
    """determine the number of rows of aliens to fit the screen"""
    available_space_y = (ai_settings.screen_height - 3 * alien_height -
        ship_height)
    num_rows = int(available_space_y / (2 * alien_height))
    return num_rows


def unquote(s):
    """Strip single quotes from the string.

    :param s: string to remove quotes from
    :return: string with quotes removed
    """
    return s.strip("'")


def has_no_overlap(r1, r2):
    """Returns True if the two reads overlap.
    """
    r1_start, r1_end = r1.reference_start, r1.reference_end
    r2_start, r2_end = r2.reference_start, r2.reference_end
    return r2_end <= r1_start or r1_end <= r2_start


def printUsage(errorMsg=None):
    """Displays how to use this script from the command line."""
    print(
        """
    ##################################################################################
    #   mki18n :   Make internationalization files.                                  #
    #              Uses the GNU gettext system to create PO (Portable Object) files  #
    #              from source code, coimpile PO into MO (Machine Object) files.     #
    #              Supports C,C++,Python source files.                               #
    #                                                                                #
    #   Usage: mki18n {OPTION} [appDirPath]                                          #
    #                                                                                #
    #   Options:                                                                     #
    #     -e               : When -m is used, forces English .mo file creation       #
    #     -h               : prints this help                                        #
    #     -m               : make MO from existing PO files                          #
    #     -p               : make PO, update PO files: Creates a new messages.pot    #
    #                        file. Creates a dom_xx.po.new for every existing        #
    #                        language specific .po file. ('xx' stands for the ISO639 #
    #                        two-letter language code and 'dom' stands for the       #
    #                        application domain name).  mki18n requires that you     #
    #                        write a 'app.fil' file  which contains the list of all  #
    #                        source code to parse.                                   #
    #     -v               : verbose (prints comments while running)                 #
    #     --domain=appName : specifies the application domain name.  By default      #
    #                        the directory name is used.                             #
    #     --moTarget=dir : specifies the directory where .mo files are stored.       #
    #                      If not specified, the target is './locale'                #
    #                                                                                #
    #   You must specify one of the -p or -m option to perform the work.  You can    #
    #   specify the path of the target application.  If you leave it out mki18n      #
    #   will use the current directory as the application main directory.            #
    #                                                                                #
    ##################################################################################"""
        )
    if errorMsg:
        print('\n   ERROR: %s' % errorMsg)


@classmethod
def all_workflow_versions(cls):
    """
        Gets a list of all workflow versions.
        :return: A list of all workflow versions.
        """
    versions = list(cls.WORKFLOW_VERSIONS.values())
    versions.remove(None)
    return versions


def action_module_name(action_name):
    """ returns the module name mapped from the action name """
    action_words = action_name.split(' ')
    package_name = action_words[:-1]
    module_name = action_words[-1] + '_'
    return 'openpipe.actions.' + '.'.join(package_name + [module_name])


def add_cmdline_args(argparser):
    """Add command-line arguments specifically for this agent."""
    agent = argparser.add_argument_group('Local Human Arguments')
    agent.add_argument('-fixedCands', '--local-human-candidates-file',
        default=None, type=str, help=
        'File of label_candidates to send to other agent')
    agent.add_argument('--single_turn', type='bool', default=False, help=
        'If on, assumes single turn episodes.')


def highest(f, c, p=20):
    """Calculate the highest value on a rolling basis.

    Parameters
    ----------
    f : pandas.DataFrame
        Dataframe containing the column ``c``.
    c : str
        Name of the column in the dataframe ``f``.
    p : int
        The period over which to calculate the rolling maximum.

    Returns
    -------
    new_column : pandas.Series (float)
        The array containing the new feature.

    """
    new_column = f[c].rolling(p).max()
    return new_column


def entries(daterange=None):
    """ Returns a list of non repeating and non overlapping time entries to cover the provided date range
        """


def viz_property(statement, properties):
    """Create properties for graphviz element"""
    if not properties:
        return statement + ';'
    return statement + '[{}];'.format(' '.join(properties))


@classmethod
def get_code(cls, fullname):
    """Method to return the code object for fullname.

        Should return None if not applicable (e.g. built-in module).
        Raise ImportError if the module cannot be found.
        """
    source = cls.get_source(fullname)
    if source is None:
        return None
    try:
        path = cls.get_filename(fullname)
    except ImportError:
        return cls.source_to_code(source)
    else:
        return cls.source_to_code(source, path)


def move(cm, from_start, from_end, insert_pos):
    """
    Move rows from_start - from_end to insert_pos in-place.

    Parameters
    ----------
    cm : ndarray
    from_start : int
    from_end : int
    insert_pos : int

    Returns
    -------
    cm : ndarray

    Examples
    --------
    >>> cm = np.array([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 0, 1], [2, 3, 4, 5]])
    >>> move(cm, 1, 2, 0)
    array([[5, 6, 4, 7],
           [9, 0, 8, 1],
           [1, 2, 0, 3],
           [3, 4, 2, 5]])
    """
    if not (insert_pos < from_start or insert_pos > from_end):
        raise ValueError(
            'insert_pos={} needs to be smaller than from_start={} or greater than from_end={}'
            .format(insert_pos, from_start, from_end))
    if insert_pos > from_end:
        p_new = list(range(from_end + 1, insert_pos + 1)) + list(range(
            from_start, from_end + 1))
    else:
        p_new = list(range(from_start, from_end + 1)) + list(range(
            insert_pos, from_start))
    p_old = sorted(p_new)
    cm[:, (p_old)] = cm[:, (p_new)]
    cm[(p_old), :] = cm[(p_new), :]
    return cm


def delete():
    """Remove all selected keyframes

    """
    pass