def check_neighboorhood_positive(neighborhood, threshold):
    """
    Check to see if a neighborhood clears as specified positive fraction
    threshold.

    Parameters
    ----------
    neighborhood : List[Dict[str, Any]]
        A list of "nearby points" where each nearby point is
        represented as a dict of the following form::

            {
                'value': float,
                'x_dist': int,
                'y_dist': int
            }

        where 'value' is the value at the point and 'x_dist' and 'y_dist' are
        its distances from the center of the neighborhood along the x- and
        y-axis, respectively, in base pairs.
    threshold : float
        If less than this fraction of the values in the neighborhood are
        positive, the neighborhood fails the check.

    Returns
    -------
    bool
        True if this neighborhood clears the threshold, otherwise False.
    """
    num_positive = len([(1) for i in neighborhood if i['value'] > 0])
    total = len(neighborhood)
    if total == 0 or float(num_positive) / total <= threshold:
        return False
    return True


def is_dict_like(value):
    """Check if value is dict-like."""
    return hasattr(value, 'keys') and hasattr(value, '__getitem__')


@classmethod
def from_string(cls, s: str) ->'Timestamp':
    """
        Initialise instance from string.

        Parameters
        ----------
        s
            timestamp string

        Returns
        -------
        Timestamp
            new timestamp
        """
    for f in (cls.f_second, cls.f_microsecond):
        try:
            return cls.strptime(s, f)
        except ValueError:
            pass
    else:
        raise ValueError(f'Date `{s}` does not match accepted formats!')


def snap_selected_to_cursor(use_offset: bool=True):
    """Snap selected item(s) to the 3D cursor

    :param use_offset: Offset, If the selection should be snapped as a whole or by each object center
    :type use_offset: bool
    """
    pass


def write_config(command, filename, sys_config):
    """
        Write a fresh config file to ``filename``.  ``command`` is a
        ``paste.script.command.Command`` object, and should be used
        for the actual operations.  It handles things like simulation
        and verbosity.

        ``sys_config`` is (if given) a dictionary of system-wide
        configuration options.
        """


@classmethod
def unpack_scalar(cls, dataset, data):
    """
        Given a dataset object and data in the appropriate format for
        the interface, return a simple scalar.
        """
    if len(data) != 1:
        return data
    key = list(data.keys())[0]
    if len(data[key]) == 1 and key in dataset.vdims:
        return data[key][0]


def _directed_neighbor_switch_rev(G, w, unsat, h_node_residual_in, chords,
    h_partition_out, partition):
    """ The reverse of directed_neighbor_switch.

    Parameters
    ----------
    G : networkx directed graph
        graph within which the edge swap will take place.
    w : integer
        node id for which we need to perform a neighbor switch.
    unsat: set of integers
        set of node ids that have the same degree as w and are unsaturated.
    h_node_residual_in: dict of integers
        for a given node, keeps track of the remaining stubs to be added.
    chords: set of tuples
        keeps track of available positions to add edges.
    h_partition_out: dict of integers
        for a given node, keeps track of its partition id (out degree).
    partition: integer
        partition id to check if chords have to be updated.

    Notes
    -----
    Same operation as directed_neighbor_switch except it handles this operation
    for incoming edges instead of outgoing.
    """
    w_prime = unsat.pop()
    unsat.add(w_prime)
    w_neighbs = list(G.predecessors(w))
    w_prime_neighbs = list(G.predecessors(w_prime))
    for v in w_neighbs:
        if v not in w_prime_neighbs and w_prime != v:
            G.remove_edge(v, w)
            G.add_edge(v, w_prime)
            if h_partition_out[v] == partition:
                chords.add((v, w))
                chords.discard((v, w_prime))
            h_node_residual_in[w] += 1
            h_node_residual_in[w_prime] -= 1
            if h_node_residual_in[w_prime] == 0:
                unsat.remove(w_prime)
            return None
    return w_prime


@classmethod
def _check_maintenance_alarm(cls, check, machine, counter):
    """Check, if it is time to maintaine machine."""
    header = ''
    if not check.isnull().any() and int(counter) <= 0:
        header = ('\n\x1b[91mПодошло ТО для:\x1b[0m ' + machine +
            ' дата последнего ТО: ' + check.values[0])
    return header


def import_from_path(path):
    """Import a module / class from a path string.

    :param str path: class path, e.g., ndscheduler.core.job
    :return: class object
    :rtype: class
    """
    components = path.split('.')
    module = __import__('.'.join(components[:-1]))
    for comp in components[1:-1]:
        module = getattr(module, comp)
    return getattr(module, components[-1])


def youtube_time_format(seconds):
    """Takes time in seconds, returns YouTube format time code."""
    hours = int(seconds / 3600)
    seconds = seconds - hours * 3600
    minutes = int(seconds / 60)
    rest = seconds - minutes * 60
    final_str = ''
    if hours:
        final_str += str(hours) + 'h'
    if minutes:
        final_str += str(minutes) + 'm'
    if seconds:
        final_str += str(rest) + 's'
    return final_str


def add_object(obj):
    """ Adds a new object and returns the generated ID
        """


def layer_add():
    """Add new Grease Pencil layer for the active Grease Pencil datablock

    """
    pass


def reciprocal(attrs, inputs, proto_obj):
    """Returns the reciprocal of the argument, element-wise."""
    return 'reciprocal', attrs, inputs


def test_geojson(distribution):
    """
    Test if a DCAT:distribution is GeoJSON.
    """
    return distribution.get('mediaType'
        ) == 'application/vnd.geo+json' or distribution.get('format', ''
        ).lower() == 'geojson'


def _chunks(lst: list, n: int, reverse: bool) ->list:
    """
    Chunk list into length 'n' sublists.

    Parameters
    ----------
    lst
        list to chunk
    n
        length of chunks
    reverse
        reverse the order of chunks
    """
    rng = range(0, len(lst), n)
    if reverse:
        rng = rng[::-1]
    for i in rng:
        yield lst[i:i + n]


def check_rows(rows_list, titles, _keys_):
    """ Checking the list of rows to see if they contain any rows.
    If the list is empty, then a row is created to show that
    nothing is found in the list of rows.
    :type rows_list: list
    :param rows_list: list of rows in the dictionary form to
        be put in the table
    :type titles: list
    :param titles: list of dictionaries for the titles which
        represent the column headers.
    :type _keys_: list
    :param _keys_: list of strings for the keys of the titles.
    :return: list - of dictionaries for the rows
    """
    if len(rows_list) == 0:
        no_rows = {}
        for _t in titles:
            if titles.index(_t) == 0:
                no_rows[_keys_[0]] = 'Nothing is Found!'
            else:
                no_rows[_keys_[titles.index(_t)]] = ''
        return [no_rows]
    return rows_list


@classmethod
def _is_factory(cls, typeobj):
    """
        Determine if typeobj is a factory for producing complex types
        """
    if hasattr(typeobj, 'Build'):
        return True
    return False


def fringe_spacing(wavelength, distance_from_slits_to_screen, slit_separation):
    """Usage: Calculate fringe spacing using wavelength (lambda), distance from slits to screen (D) and slit separation (s)"""
    return wavelength * distance_from_slits_to_screen / slit_separation


def count_alive_neighbors(grid, x, y):
    """ Count neighbors that are alive. """
    height = len(grid)
    width = len(grid[0])
    alive_count = 0
    for i in range(-1, 2):
        for j in range(-1, 2):
            neighbor_x = x + i
            neighbor_y = y + j
            if i == 0 and j == 0:
                continue
            elif neighbor_x < 0 or neighbor_y < 0 or neighbor_y >= height or neighbor_x >= width:
                alive_count += 1
            elif grid[neighbor_y][neighbor_x] == 1:
                alive_count += 1
    return alive_count


def convex_hull_2d(points: list) ->list:
    """Returns a list of indices into the list given

    :param points: list of 2d points.
    :type points: list
    :return:  a list of indices
    """
    pass


def print_block_string(value: str, indentation: str='',
    prefer_multiple_lines: bool=False) ->str:
    """Print a block string in the indented block form.

    Prints a block string in the indented block form by adding a leading and
    trailing blank line. However, if a block string starts with whitespace and
    is a single-line, adding a leading blank line would strip that whitespace.
    """
    is_single_line = '\n' not in value
    has_leading_space = value.startswith(' ') or value.startswith('\t')
    has_trailing_quote = value.endswith('"')
    print_as_multiple_lines = (not is_single_line or has_trailing_quote or
        prefer_multiple_lines)
    if print_as_multiple_lines and not (is_single_line and has_leading_space):
        result = '\n' + indentation
    else:
        result = ''
    result += value.replace('\n', '\n' + indentation) if indentation else value
    if print_as_multiple_lines:
        result += '\n'
    return '"""' + result.replace('"""', '\\"""') + '"""'


def change_K_basis(K1, D1, D2):
    """Converts a loss coefficient `K1` from the basis of one diameter `D1`
    to another diameter, `D2`. This is necessary when dealing with pipelines
    of changing diameter.

    .. math::
        K_2 = K_1\\frac{D_2^4}{D_1^4} = K_1 \\frac{A_2^2}{A_1^2}

    Parameters
    ----------
    K1 : float
        Loss coefficient with respect to diameter `D`, [-]
    D1 : float
        Diameter of pipe for which `K1` has been calculated, [m]
    D2 : float
        Diameter of pipe for which `K2` will be calculated, [m]

    Returns
    -------
    K2 : float
        Loss coefficient with respect to the second diameter, [-]

    Notes
    -----
    This expression is shown in [1]_ and can easily be derived:

    .. math::
        \\frac{\\rho V_{1}^{2}}{2} \\cdot K_{1} = \\frac{\\rho V_{2}^{2} }{2}
        \\cdot K_{2}

    Substitute velocities for flow rate divided by area:

    .. math::
        \\frac{8 K_{1} Q^{2} \\rho}{\\pi^{2} D_{1}^{4}} = \\frac{8 K_{2} Q^{2}
        \\rho}{\\pi^{2} D_{2}^{4}}

    From here, simplification and rearrangement is all that is required.

    Examples
    --------
    >>> change_K_basis(K1=32.68875692997804, D1=.01, D2=.02)
    523.0201108796487

    References
    ----------
    .. [1] Rennels, Donald C., and Hobart M. Hudson. Pipe Flow: A Practical
       and Comprehensive Guide. 1st edition. Hoboken, N.J: Wiley, 2012.
    """
    return K1 * (D2 / D1) ** 4


def role_name_from(s: str) ->str:
    """Convert a string to a format that can be used as an rST role."""
    return s.lower().replace(' ', '-')


def build_ldap_uri(config, node=''):
    """ Building LDAP uris for dovecot conf """
    if node:
        node += '_'
    return '{}://{}:{}'.format('ldaps' if config['ldap_secured'] == 'ssl' else
        'ldap', config['ldap_{}server_address'.format(node)], config[
        'ldap_{}server_port'.format(node)])


def _prepare_versions(listen_versions, supported_versions):
    """Return listen versions."""
    assert supported_versions
    if not listen_versions:
        return supported_versions
    unsupported = set(listen_versions) - set(supported_versions)
    if unsupported:
        raise ValueError('Unsupported OpenFlow versions: %r' % unsupported)
    return listen_versions


def short_node_gen(graph, inqueue, dst_sid, procno):
    """
	Adding all nodes from the graph to the inqueue. At the end it adds terminating object in the amount of proccount.
	This function will be threaded.
	"""
    for node in graph.nodes:
        if node == dst_sid:
            continue
        inqueue.put(node)
    for _ in range(procno):
        inqueue.put(None)


def set_default_samplerate(samplerate):
    """
    Sets the default samplerate for Brian hears objects, by default 44.1 kHz.
    """
    global default_samplerate
    default_samplerate = samplerate


@staticmethod
def check_plate_compatibility(tool, source_plate, sink_plate):
    """
        Checks whether the source and sink plate are compatible given the tool

        :param tool: The tool
        :param source_plate: The source plate
        :param sink_plate: The sink plate
        :return: Either an error, or None
        :type tool: Tool
        :type source_plate: Plate
        :type sink_plate: Plate
        :rtype: None | str
        """
    if sink_plate == source_plate.parent:
        return None
    if sink_plate.meta_data_id == source_plate.meta_data_id:
        if sink_plate.is_sub_plate(source_plate):
            return None
        return ('Sink plate {} is not a simplification of source plate {}'.
            format(sink_plate.plate_id, source_plate.plate_id))
    meta_data_diff = set(source_plate.ancestor_meta_data_ids) - set(sink_plate
        .ancestor_meta_data_ids)
    if len(meta_data_diff) == 1:
        if tool.aggregation_meta_data not in meta_data_diff:
            return (
                'Aggregate tool meta data ({}) does not match the diff between source and sink plates ({})'
                .format(tool.aggregation_meta_data, list(meta_data_diff)[0]))
    else:
        return "{} not in source's parent plates".format(sink_plate.plate_id)


def describe_policy(PolicyId=None):
    """
    Retrieves information about a policy.
    This operation can be called only from the organization's master account.
    See also: AWS API Documentation

    :example: response = client.describe_policy(
        PolicyId='string'
    )

    :type PolicyId: string
    :param PolicyId: [REQUIRED]
            The unique identifier (ID) of the policy that you want details about. You can get the ID from the ListPolicies or ListPoliciesForTarget operations.
            The regex pattern for a policy ID string requires 'p-' followed by from 8 to 128 lower-case letters or digits.

    :rtype: dict
    :return: {
        'Policy': {
            'PolicySummary': {
                'Id': 'string',
                'Arn': 'string',
                'Name': 'string',
                'Description': 'string',
                'Type': 'SERVICE_CONTROL_POLICY',
                'AwsManaged': True|False
            },
            'Content': 'string'
        }
    }

    """
    pass


def rle_mask(rle_data, mask):
    """
    Perform masking of the input run-length data.

    Parameters
    ----------
    rle_data: iterable of run length encoded data
    mask: iterable of bools corresponding to the dense mask.

    Returns
    ----------
    iterable of dense values of rle_data wherever mask is True.
    """
    data_iter = iter(rle_data)
    mask_iter = iter(mask)
    while True:
        try:
            value = next(data_iter)
            count = next(data_iter)
        except StopIteration:
            break
        for _ in range(count):
            m = next(mask_iter)
            if m:
                yield value


def get_bts_for_msg_compression(tl_packet):
    """return -- header bytes of DNS or b"" """
    if tl_packet._triggelistpacket_parent is not None:
        return tl_packet._triggelistpacket_parent.header_bytes
    return b''


def Nch(c, H, D):
    """ Horizontal bearing capacity factor for sand
    """
    if c == 0:
        return 0
    x = H / D
    return min(6.752 + 0.065 * x - 11.063 / (x + 1) ** 2 + 7.119 / (x + 1) **
        3, 9)


@classmethod
def is_available(cls, disk, kernel):
    """ Check if kernel is available for disk."""
    kmap = cls.list(disk['datacenter_id'], None, kernel, True)
    for flavor in kmap:
        if kernel in kmap[flavor]:
            return True
    return False


def push_down():
    """Push action down on to the NLA stack as a new strip

    """
    pass


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

        :param ListFileMembersCountResult val:
        :rtype: ListFileMembersIndividualResult
        """
    return cls('result', val)


def is_permanently_delisted(quarterly_submissions, qtr, s):
    """
    Check if a company is permanently delisted starting from a given qtr. This function is not great, I should have made
    a single function that finds the first qtr for which a company is listed and the qtr for which it became delisted,
    if ever.

    :param quarterly_submissions:
    :param qtr: a given qtr
    :param s: Settings dictionary
    :return: bool assessing whether or not it is permanently delisted after the given qtr
    """
    flag_permanently_delisted = True
    idx = s['list_qtr'].index(qtr)
    for qtr in s['list_qtr'][idx:]:
        if len(quarterly_submissions[qtr]):
            flag_permanently_delisted = False
            break
    return flag_permanently_delisted


def _count_jinja2_blocks(token, cur_depth, open_token, close_token):
    """
    this function counts the number of opening/closing blocks for a
    given opening/closing type and adjusts the current depth for that
    block based on the difference
    """
    num_open = token.count(open_token)
    num_close = token.count(close_token)
    if num_open != num_close:
        cur_depth += num_open - num_close
        if cur_depth < 0:
            cur_depth = 0
    return cur_depth


def splitIterables(iter1, iter2):
    """Splits two iterable elements which are paired by selecting the math:`n`
    common indexes where there are sign changes in both inputs at the same
    time. If there is any index to split the inputs, it returns the same inputs
    within a list.

    Parameters:
        iter1 (`numpy.ndarray` or `list`): An iterable element which is
            paired to ``iter2``.
        iter2 (`numpy.ndarray` or `list`): An iterable element which is
            paired to ``iter1``.

    Returns:
        Two elements are returned; they are described below.

            - **iter1Splitted** (`list`): Segments of the original ``iter1``                input after being splitted.
            - **iter2splitted** (`list`): Segments of the original ``iter2``                input after being splitted.

    Examples:
        >>> from jelinekstat.tools import splitIterables
        >>> iter1, iter2 = [1, -2, -3, 4, 5, 6], [-3, -2, -1, 0, 1, 2]
        >>> iter1Splitted, iter2splitted = splitIterables(iter1, iter2)
        >>> iter1Splitted
        [[1, -2, -3], [4, 5, 6]]
        >>> iter2splitted
        [[-3, -2, -1], [0, 1, 2]]
    """
    import numpy as np
    signPosit1 = np.where(np.diff(np.sign(iter1)))[0]
    signPosit2 = np.where(np.diff(np.sign(iter2)))[0]
    signPosit = np.intersect1d(signPosit1, signPosit2)
    iter1Splitted = list()
    iter2splitted = list()
    if len(signPosit) == 0:
        iter1Splitted.append(iter1)
        iter2splitted.append(iter2)
    else:
        iter1Splitted.append(iter1[:signPosit[0] + 1])
        iter2splitted.append(iter2[:signPosit[0] + 1])
        for i in range(len(signPosit) - 1):
            iter1Splitted.append(iter1[signPosit[i] + 1:signPosit[i + 1]])
            iter2splitted.append(iter2[signPosit[i] + 1:signPosit[i + 1]])
        iter1Splitted.append(iter1[signPosit[-1] + 1:])
        iter2splitted.append(iter2[signPosit[-1] + 1:])
    return iter1Splitted, iter2splitted


@staticmethod
def write(writer, value):
    """
        Writes Zserio float32 type to the bit stream.

        :param writer: Bit stream where to write.
        :param value: Zserio float32 type to write.
        """
    writer.writeFloat32(value)


def methods_of(obj):
    """Get all callable methods of an object that don't start with underscore

    returns a list of tuples of the form (method_name, method)
    """
    result = []
    for i in dir(obj):
        if callable(getattr(obj, i)) and not i.startswith('_'):
            result.append((i, getattr(obj, i)))
    return result


def set_prefs(prefs):
    """This function is called before opening the project"""
    prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', '.hg',
        '.svn', '_svn', '.git', '.tox']
    prefs['save_objectdb'] = True
    prefs['compress_objectdb'] = False
    prefs['automatic_soa'] = True
    prefs['soa_followed_calls'] = 0
    prefs['perform_doa'] = True
    prefs['validate_objectdb'] = True
    prefs['max_history_items'] = 32
    prefs['save_history'] = True
    prefs['compress_history'] = False
    prefs['indent_size'] = 4
    prefs['extension_modules'] = []
    prefs['import_dynload_stdmods'] = True
    prefs['ignore_syntax_errors'] = False
    prefs['ignore_bad_imports'] = False
    prefs['prefer_module_from_imports'] = False
    prefs['split_imports'] = False
    prefs['pull_imports_to_top'] = True
    prefs['sort_imports_alphabetically'] = False
    prefs['type_hinting_factory'
        ] = 'rope.base.oi.type_hinting.factory.default_type_hinting_factory'


def _create_grouped_output_selection_nrql(output_function, output_config,
    conditions):
    """Create a grouped output selection."""
    function = output_config['function']
    label = output_config.get('label')
    if label:
        label_nrql = f' AS `{label}`'
    else:
        label_nrql = ''
    condition = output_config['condition']
    if condition in conditions:
        condition_nrql = conditions[condition].nrql
    else:
        condition_nrql = condition
    return f'{output_function}({function}, WHERE {condition_nrql}){label_nrql}'


def _default_keep_signal(sig):
    """
    If ``plots`` is not specified in ``metadata``, this function determines
    which channels are plotted by default.
    """
    return not sig.name.startswith('Analog Input #') and sig.name != 'Clock'


def parse_contact(contact, configparser):
    """
    Parse data from an abook file and return a usable dictionary
    """
    return {'name': configparser[contact].get('name'), 'email': set(
        configparser[contact].get('email').split(',')), 'notes':
        configparser[contact].get('notes'), 'custom1': configparser[contact
        ].get('custom1')}


def strip_bracketed(s, c):
    """If s begins and ends with c, strip off c.
       c can be a single character like '"',
       or a pair of characters like '[]'.
       Also removes trailing commas.
    """
    start_char = c[0]
    if len(c) > 1:
        end_char = c[1]
    else:
        end_char = start_char
    s = s.strip()
    if s.endswith(','):
        s = s[:-1].strip()
    if s.startswith(start_char):
        s = s[1:].strip()
    if s.endswith(end_char):
        s = s[:-1].strip()
    return s


def voidage_Benyahia_Oneil_cylindrical(Dpe, Dt, sphericity):
    """Calculates voidage of a bed of cylindrical uniform particles
    packed into a bed or tube of diameter `Dt`, with equivalent sphere diameter
    `Dpe`. Shown in [1]_, and cited by various authors. Correlations exist
    also for spheres, solid cylinders, hollow cylinders, and 4-hole cylinders.
    Based on a series of physical measurements.

    .. math::
        \\epsilon = 0.373+\\frac{1.703}{\\left(\\frac{d_{cyl}}{d_p}+0.611\\right)^2}

    Parameters
    ----------
    Dpe : float
        Equivalent spherical particle diameter (diameter of a sphere with the
        same volume), [m]
    Dt : float
        Diameter of the tube, [m]
    sphericity : float
        Sphericity of particles in bed []

    Returns
    -------
    voidage : float
        Void fraction of bed packing []

    Notes
    -----
    Average error 1.6%; 1.7 < ratio < 26.3.

    Examples
    --------
    >>> voidage_Benyahia_Oneil_cylindrical(Dpe=.01, Dt=.1, sphericity=.6)
    0.38812523109607894

    References
    ----------
    .. [1] Benyahia, F., and K. E. O’Neill. "Enhanced Voidage Correlations for
       Packed Beds of Various Particle Shapes and Sizes." Particulate Science
       and Technology 23, no. 2 (April 1, 2005): 169-77.
       doi:10.1080/02726350590922242.
    """
    return 0.373 + 1.703 / (Dt / Dpe + 0.611) ** 2


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

        :param PaperApiCursorError val:
        :rtype: ListDocsCursorError
        """
    return cls('cursor_error', val)


@staticmethod
def noncommand(f):
    """mark a function as not to be processed as a command for a CLI (usually a method in a class def)"""
    f.__noncommand__ = True
    return f


def usage():
    """Provide usage instructions"""
    return """
        NAME
            extract_metadata.py

        SYNOPSIS
            extract_metadata.py -e </absoulte/path/to/record>|</absoulte/path/to/directory>
            extract_metadata.py -s </absoulte/path/to/record>|</absoulte/path/to/directory>
            extract_metadata.py -t </absoulte/path/to/record>|</absoulte/path/to/directory>

            Supported formats:

                    .dbf     |
                    .shp     |
                    .csv     |
                    .nc      |
                    .geojson |
                    .json    |
                    .gpkg    |
                    .geotiff |
                    .tif     |
                    .gml     |
                    .xml     |

            Available options:

            -e    Extract all metadata of a geospatial file (crs, vector representation, bounding box, temporal extent)
            -s    Extract all spatial metadata of a geospatial file (crs, vector representation, bounding box)
            -t    Extract all temporal metadata of a geospatial file (temporal extent)
"""


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


def collect_all_methods(cls, method_name):
    """Return list of all `method_name` methods for cls and its superclass chain.

    List is in MRO order, with no duplicates. Methods are unbound.

    (This is used to simplify mixins and subclasses that contribute to a method set,
    without requiring superclass chaining, and without requiring cooperating
    superclasses.)
    """
    methods = []
    for ancestor in cls.__mro__:
        try:
            validator = getattr(ancestor, method_name)
        except AttributeError:
            pass
        else:
            if validator not in methods:
                methods.append(validator)
    return methods


def not_available_message(msg):
    """prints a message about lack of Urwid availability
    to a Messenger object"""
    from audiotools.text import ERR_URWID_REQUIRED, ERR_GET_URWID1, ERR_GET_URWID2
    msg.error(ERR_URWID_REQUIRED)
    msg.output(ERR_GET_URWID1)
    msg.output(ERR_GET_URWID2)


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 option_name_to_variable_name(option: str):
    """
    Convert an option name like `--ec2-user` to the Python name it gets mapped to,
    like `ec2_user`.
    """
    return option.replace('--', '', 1).replace('-', '_')


def normalize_title(title, body):
    """Normalize the title if it spills over into the PR's body."""
    if not (title.endswith('…') and body.startswith('…')):
        return title
    else:
        return title[:-1] + body[1:].partition('\r\n')[0]


@staticmethod
def _flatten_mailjet_headers(headers):
    """Convert Mailjet's dict-of-strings-and/or-lists header format to our list-of-name-value-pairs

        {'name1': 'value', 'name2': ['value1', 'value2']}
          --> [('name1', 'value'), ('name2', 'value1'), ('name2', 'value2')]
        """
    result = []
    for name, values in headers.items():
        if isinstance(values, list):
            for value in values:
                result.append((name, value))
        else:
            result.append((name, values))
    return result


@staticmethod
def _build_server_url(server_host) ->str:
    """Build the server url making sure it ends in a trailing slash."""
    if server_host[-1] == '/':
        return server_host
    return '{}/'.format(server_host)


def namesAndDescriptions(all=False):
    """Get the interface attribute names and descriptions

        Return a sequence of the names and descriptions of the
        attributes, including methods, as name-value pairs, included
        in the interface definition.

        Normally, only directly defined attributes are included. If
        a true positional or keyword argument is given, then
        attributes defined by base classes will be included.
        """


def is_sequence(obj) ->bool:
    """
    Check if the object is a sequence of objects.
    String types are not included as sequences here.

    Parameters
    ----------
    obj : The object to check

    Returns
    -------
    is_sequence : bool
        Whether `obj` is a sequence of objects.

    Examples
    --------
    >>> l = [1, 2, 3]
    >>>
    >>> is_sequence(l)
    True
    >>> is_sequence(iter(l))
    False
    """
    try:
        iter(obj)
        len(obj)
        return not isinstance(obj, (str, bytes))
    except (TypeError, AttributeError):
        return False


@classmethod
def from_nlp(cls, nlp, **cfg):
    """Factory to add to Language.factories via entry point."""
    return cls(nlp.vocab, **cfg)


def ExcessPowerPostFunc(sngl_burst_table, offset):
    """
	Restore peak times to absolute LIGOTimeGPS values.
	"""
    for row in sngl_burst_table:
        row.peak = offset + row.peak_time


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

        :param NoteAclTeamLinkDetails val:
        :rtype: EventDetails
        """
    return cls('note_acl_team_link_details', val)


@staticmethod
def _get_status_code(response):
    """Access the status code from an HTTP response.

        Args:
            response (object): The HTTP response object.

        Raises:
            NotImplementedError: Always, since virtual.
        """
    raise NotImplementedError(u'This implementation is virtual.')


def import_ebk(filename):
    """Import symbols from ebk format."""
    res = []
    with open(filename, 'rb') as fin:
        fin.readline()
        for line in fin:
            line = line.decode().strip()
            if line[0] == '1':
                res.append(f'{line[1:]}.SH')
            else:
                res.append(f'{line[1:]}.SZ')
    return res


def context_scale_int(data_path: str='', value: float=1.0, always_step:
    bool=True):
    """Scale an int context value

    :param data_path: Context Attributes, RNA context string
    :type data_path: str
    :param value: Value, Assign value
    :type value: float
    :param always_step: Always Step, Always adjust the value by a minimum of 1 when ‘value’ is not 1.0
    :type always_step: bool
    """
    pass


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


def _gpos_to_tpos(transcript, start, end=None):
    """Compute the equivalent transcript position for a gene position.

    Args:
        transcript: `pyensembl.Transcript` instance
        start (int): genomic coordinate
        end (int): optional, second genomic coordinate

    Returns:
        tuple of int: position relative to the transcript
    """
    convert = lambda x: transcript.spliced_offset(x) + 1
    tstart = convert(start)
    if end:
        tend = convert(end)
    else:
        tend = tstart
    return tstart, tend


def is_ascii(some_string):
    """Check if a string only contains ascii characters"""
    try:
        some_string.encode('ascii')
    except UnicodeEncodeError:
        return False
    else:
        return True


def _print_level(level, msg):
    """Print the information in Unicode safe manner."""
    for l in str(msg.rstrip()).split('\n'):
        print('{0:<9s}{1}'.format(level, str(l)))


def update_filter(argname, cdict, callargs):
    """ Updates a mongo query to include self.composer_id.
    If _filter is None, we just use the cdict's update_filter kwargs
    If _filter is a dict and doesn't include composer_id, we add it in
    If _filter is not a dict, we assume it's a spec for the _id

    Modifies the callargs argument, but also returns the new callargs
    """
    filter_kwargs = cdict.get('update_filter') or {}
    _filter = callargs[argname]
    for k, v in filter_kwargs.iteritems():
        if _filter is None:
            _filter = {k: v}
        elif isinstance(_filter, dict):
            _filter[k] = _filter.get(k, v)
        else:
            _filter = {'_id': _filter, k: v}
    callargs[argname] = _filter
    return callargs


@staticmethod
def get_state_arguments_model():
    """
        This is needed so the BaseState can validate the provided
        model has the required or optional arguments for the state
        to function.
        return = {
            'required_state_arguments': {
                'required_state_arg_1': type,
                'required_state_arg_2': type,
            },
            'optional_state_arguments': {
                'optional_state_arg_1': type,
                'optional_state_arg_2': type,
            },
        }
        """
    return {'required_state_arguments': {}, 'required_State_arguments': {}}


def process_nastran(bdf_filename, fmt2, fname2, log, data=None, debug=True,
    quiet=False):
    """
    Converts Nastran to STL/Cart3d/Tecplot/UGRID3d
    """
    assert fmt2 in ['stl', 'cart3d', 'tecplot', 'ugrid', 'nastran', 'abaqus'
        ], 'format2=%s' % fmt2
    from pyNastran.bdf.bdf import BDF
    xref = True
    if fmt2 == 'ugrid':
        xref = False
    model = BDF(log=log, debug=debug)
    model.read_bdf(bdf_filename, validate=False, xref=xref)
    if data['--scale'] != 1.0:
        scale = data['--scale']
        data['--scale'] = 1.0
        for node in model.nodes.values():
            node.xyz = node.get_position() * scale
            node.cp = 0
            del node.cp_ref
    if fmt2 == 'stl':
        from pyNastran.converters.nastran.nastran_to_stl import nastran_to_stl
        nastran_to_stl(model, fname2, is_binary=data['--binary'])
    elif fmt2 == 'cart3d':
        from pyNastran.converters.nastran.nastran_to_cart3d import nastran_to_cart3d
        cart3d = nastran_to_cart3d(model)
        cart3d.write_cart3d(fname2)
    elif fmt2 == 'tecplot':
        from pyNastran.converters.nastran.nastran_to_tecplot import nastran_to_tecplot
        tecplot = nastran_to_tecplot(model)
        tecplot_filename = fname2
        tecplot.write_tecplot(tecplot_filename, adjust_nids=False)
    elif fmt2 == 'ugrid':
        from pyNastran.converters.nastran.nastran_to_ugrid import nastran_to_ugrid
        nastran_to_ugrid(model, fname2)
    elif fmt2 == 'abaqus':
        from pyNastran.converters.nastran.nastran_to_abaqus import nastran_to_abaqus
        nastran_to_abaqus(model, fname2)
    elif fmt2 == 'nastran':
        model.write_bdf(fname2, size=16)
    else:
        raise NotImplementedError(
            'fmt2=%s is not supported by process_nastran' % fmt2)


def isfld(xmethod, dmethod, opt):
    """Return ``isfld`` argument for ``.IterStatsConfig`` initialiser.
    """
    fld = ['Iter', 'ObjFun', 'DFid', 'RegL1', 'Cnstr']
    if xmethod == 'admm':
        fld.extend(['XPrRsdl', 'XDlRsdl', 'XRho'])
    elif opt['CBPDN', 'BackTrack', 'Enabled']:
        fld.extend(['X_F_Btrack', 'X_Q_Btrack', 'X_ItBt', 'X_L', 'X_Rsdl'])
    else:
        fld.extend(['X_L', 'X_Rsdl'])
    if dmethod != 'fista':
        fld.extend(['DPrRsdl', 'DDlRsdl', 'DRho'])
    elif opt['CCMOD', 'BackTrack', 'Enabled']:
        fld.extend(['D_F_Btrack', 'D_Q_Btrack', 'D_ItBt', 'D_L', 'D_Rsdl'])
    else:
        fld.extend(['D_L', 'D_Rsdl'])
    fld.append('Time')
    return fld


def getFileDialogTitle(msg, title):
    """
    Create nicely-formatted string based on arguments msg and title
    :param msg: the msg to be displayed
    :param title: the window title
    :return: None
    """
    if msg and title:
        return '%s - %s' % (title, msg)
    if msg and not title:
        return str(msg)
    if title and not msg:
        return str(title)
    return None


def check_interface_capability(interface, capability):
    """Evaluate interface to determine if capability is present.

    :param interface: The interface object to check.
    :param capability: The value representing the capability that
                       the caller wishes to check if present.

    :returns: True if capability found, otherwise False.
    """
    return capability in getattr(interface, 'capabilities', [])


@staticmethod
def query_past_days(q_object, args):
    """
        Subselect to filter data nodes by their age.

        :param q_object: a query object
        :param args: a namespace with parsed command line parameters.
        """
    from aiida.common import timezone
    from django.db.models import Q
    import datetime
    if args.past_days is not None:
        now = timezone.now()
        n_days_ago = now - datetime.timedelta(days=args.past_days)
        q_object.add(Q(ctime__gte=n_days_ago), Q.AND)


def can_multiply(matrix1, matrix2):
    """Checks to see if two Matrix objects can be multiplied by ensuring that
    their dimensions are compatible.

    :param Matrix matrix1: the first matrix.
    :param Matrix matrix2: the second matrix.
    :rtype: ``bool``"""
    return matrix1.size()[1] == matrix2.size()[0]


def __getitem__(id):
    """Return the given component identified by id or raise
        KeyError.
        """


def zerocopy_to_numpy(input):
    """Create a numpy ndarray that shares the input memory.

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

    Returns
    -------
    numpy.ndarray
        A numpy ndarray.
    """
    pass


def header(text, width=70):
    """ Print a simple header (text with tilde underline) """
    return '\n{0}\n{1}'.format(text, width * '~')


def remove_doubles(threshold: float=0.02, use_unselected: bool=False):
    """Selected UV vertices that are within a radius of each other are welded together

    :param threshold: Merge Distance, Maximum distance between welded vertices
    :type threshold: float
    :param use_unselected: Unselected, Merge selected to other unselected vertices
    :type use_unselected: bool
    """
    pass


def str2bool(v: str) ->bool:
    """Parse str to bool.

    Args:
      v(str): The string to parse.

    Returns:
      bool: The parsed value.

    """
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise ValueError('Boolean value expected.')


def fib(n):
    """Fibonacci example function

    Args:
      n (int): integer

    Returns:
      int: n-th Fibonacci number
    """
    assert n > 0
    a, b = 1, 1
    for i in range(n - 1):
        a, b = b, a + b
    return a


def _disjoint(groups):
    """ Check that groups form pairwise disjoint sets """
    ids = []
    for g in groups:
        ids.extend(g.ids)
    return len(ids) == len(set(ids))


@classmethod
def _get_apic_classes(cls):
    """
        Get the APIC classes used by this acitoolkit class.

        :returns: list of strings containing APIC class names
        """
    resp = ['cdpIf']
    return resp


def guess_contains(lines):
    """Tries to determine if a file includes expat
    """
    count = 0
    should_contain = [
        'http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer', 'LGPL']
    for line in lines:
        for i in should_contain:
            if i in line:
                count += 1
    return True if count >= len(should_contain) else False


def intersperse(lst, item):
    """
    Utility method to intersperse an item in a list
    :param lst:
    :param item: the item to be interspersed
    :return:
    """
    result = [item] * (len(lst) * 2 - 1)
    result[0::2] = lst
    return result


def reduce_mean(input):
    """Returns the average of all elements in the input tensor.

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

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


@staticmethod
def ndim(tensor):
    """Return the number of dimensions of a tensor"""
    raise NotImplementedError


def rstrip_keep(text):
    """
    Like rstrip, but also returns the whitespace that was stripped off
    """
    text_length = len(text)
    new_text = text.rstrip()
    if text_length != len(new_text):
        suffix = text[-(text_length - len(new_text)):]
    else:
        suffix = ''
    return new_text, suffix


def tsync_actions(subparser, source_args, container_args):
    """Tsync Arguments.

    :param source_args:
    :param shared_args:
    :param cdn_args:
    :param subparser:
    """
    tsync = subparser.add_parser('tsync', parents=[source_args,
        container_args], help='Deprecated, Please use "upload --sync" instead')
    tsync.set_defaults(tsync=True)


def _check_bind_options(kw):
    """Check keyword options passed to dummy mailer ``.bind`` method
    for plausibility.

    Performs the same checks that :method:`Mailer.bind` does.

    """
    valid_options = 'default_sender', 'transaction_manager'
    invalid_options = set(kw.keys()).difference(valid_options)
    if invalid_options:
        raise ValueError('invalid options: %s' % ', '.join(sorted(
            invalid_options)))


def coerce_to_fixed_size_rgb(im, target_dim):
    """Convert a PIL image to a fixed size and 3 channel RGB format."""
    if im.mode not in ['RGB', 'L']:
        raise Exception(f'Unknown image mode: {im.mode}')
    resized_im = im.resize(target_dim)
    if im.mode is 'RGB':
        return resized_im
    return resized_im.convert('RGB')


def set_view_func_public(func):
    """
    Set the REQUIRE_LOGIN_IS_PUBLIC attribute on a given function to True
    """
    func.REQUIRE_LOGIN_IS_PUBLIC = True


def main():
    """
    Command-line invocation routine.
    """
    import scans
    scan = scans.load_scan('../../data/LIDC-IDRI/LIDC-IDRI-0090')
    import IPython
    IPython.embed()


def unsorted_1d_segment_mean(input, seg_id, n_segs, dim):
    """Computes the mean along segments of a tensor.

    Equivalent to tf.unsorted_segment_mean, but seg_id is required to be a
    1D tensor.

    Note that segments never appeared in seg_id will have results of 0.

    Parameters
    ----------
    input : Tensor
        The input tensor
    seg_id : 1D Tensor
        The segment IDs whose values are between 0 and n_segs - 1.  Should
        have the same length as input.
    n_segs : int
        Number of distinct segments
    dim : int
        Dimension to average on

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


def query_for_objects(query, start=None, count=None):
    """Execute the given CMISQL query, and return the result as a
        list of objects.
        """


def to_bytes(value):
    """ str to bytes (py3k) """
    vtype = type(value)
    if vtype == bytes or vtype == type(None):
        return value
    try:
        return vtype.encode(value)
    except UnicodeEncodeError:
        pass
    return value


@classmethod
def from_nominal(cls, nominal_strength=None):
    """
        Alternative constructor creating a steel material from a given nominal strength.

        Parameters
        ----------

        nominal_strength : str
            Steel quality, given in the form of e.g. "S355"

        """
    if nominal_strength is None:
        f_yield = 235.0
    else:
        f_yield = float(nominal_strength.replace('S', ''))
    plasticity = cls.plastic_table(nominal=nominal_strength)
    return cls(210000.0, 0.3, f_yield, plasticity=plasticity)


def query_long_descr(database, dict_name):
    """Return long description for a given dictionary."""
    curs = database.cursor()
    sql = """
        SELECT DI_LONG_DESCR
        FROM DICTIONARIES
        WHERE DI_DICT=?
        """
    curs.execute(sql, (dict_name,))
    results = list(curs)
    if len(results) == 0:
        return None
    return results[0][0]


def rotate(pattern, offset=0):
    """ Rotate a pattern list by a given offset
    """
    return pattern[-offset % len(pattern):] + pattern[:-offset % len(pattern)]


def truncate_string_from_end(string: str, max_len: int) ->str:
    """If the string len is below the max_len, the function returns the same string.
	If the string is above the max len, the function returns only the last max_len characters plus '...' at the beginning."""
    if len(string) <= max_len:
        return string
    return f'Last {max_len} chars: "...{string[-max_len:]}"'


def table_exists(cr, table):
    """ Check whether a certain table or view exists """
    cr.execute('SELECT 1 FROM pg_class WHERE relname = %s', (table,))
    return cr.fetchone()


def get_cls_import_path(cls):
    """Return the import path of a given class"""
    module = cls.__module__
    if module is None or module == str.__module__:
        return cls.__name__
    return module + '.' + cls.__name__


def batch(iterable, k=3):
    """
    Returns a batch generator from given iterable.

    Parameters
    ----------
    iterable : iterable
        Iterable to create batches from.
    k : integer
        Batches size.

    Returns
    -------
    bool
        Is *string_like* variable.

    Examples
    --------
    >>> batch(tuple(range(10)))  # doctest: +ELLIPSIS
    <generator object batch at 0x...>
    """
    for i in range(0, len(iterable), k):
        yield iterable[i:i + k]


def handle_response(response):
    """
    Responses from blockstream's API are returned in json or str
    :param response: http response object from requests library
    :return response: decoded response from api
    """
    if isinstance(response, Exception):
        print(response)
        return response
    else:
        return response


def _get_best_indexes(logits, n_best_size):
    """Get the n-best logits from a list."""
    index_and_score = sorted(enumerate(logits), key=lambda x: x[1], reverse
        =True)
    best_indexes = []
    for i in range(len(index_and_score)):
        if i >= n_best_size:
            break
        best_indexes.append(index_and_score[i][0])
    return best_indexes


def unindent():
    """Delete 4 spaces from line beginning

    """
    pass


def print_bold(msg, end='\n'):
    """Convenience function to print a message in bold style

    Optionally you can also specify how the bold text should end. By default
    it ends with a new line character.

    :arg msg: Message to be converted to bold style
    :arg end: Tell how the printed string should end (newline, space etc)
    """
    print('\x1b[1m' + msg + '\x1b[0m', end=end)


def line_indices(cell1, cell2):
    """
    Takes two cells in the grid (each described by a pair of integer
    indices), and returns a list of the cells in the grid that are on the
    line segment between the cells.
    """
    i0, j0 = cell1
    i1, j1 = cell2
    assert type(i0) == int, 'Args to line_indices must be pairs of integers'
    assert type(j0) == int, 'Args to line_indices must be pairs of integers'
    assert type(i1) == int, 'Args to line_indices must be pairs of integers'
    assert type(j1) == int, 'Args to line_indices must be pairs of integers'
    ans = [(i0, j0)]
    di = i1 - i0
    dj = j1 - j0
    t = 0.5
    if abs(di) > abs(dj):
        m = float(dj) / float(di)
        t += j0
        if di < 0:
            di = -1
        else:
            di = 1
        m *= di
        while i0 != i1:
            i0 += di
            t += m
            ans.append((i0, int(t)))
    elif dj != 0:
        m = float(di) / float(dj)
        t += i0
        if dj < 0:
            dj = -1
        else:
            dj = 1
        m *= dj
        while j0 != j1:
            j0 += dj
            t += m
            ans.append((int(t), j0))
    return ans


def attach_file(request, contents, filename=None, content_type=None, size=None
    ):
    """Attach a file to a file request.

    This will mark the request as finished.

    :param request: the request
    :type request: bgfiles.models.FileRequest
    :param contents: the contents of the file/something that can be passed to a ``FileField``.
    :param filename: the filename; leave blank to maintain the current filename (if any)
    :type filename: str
    :param content_type: the content/mime type of the file; leave blank to maintain the current value (if any)
    :type content_type: str
    :param size: the size of the file in bytes; leave blank to maintain the current value (if any)
    :type size: int
    """
    request.attach_file(contents, filename, content_type, size=size)
    request.save()


def vel_zones(velocity, time):
    """
    Calculate wheelchair velocity zones

    Parameters
    ----------
    velocity : dict
        velocity data structure
    time : dict
        time data structure

    Returns
    -------
    velocity_zones : dict
        velocity zones (m/s), 1-2, 2-3, 3-4, 4-5, 5 and above

    """
    vel_1 = velocity[velocity > 1]
    vel_2 = velocity[velocity > 2]
    vel_3 = velocity[velocity > 3]
    vel_4 = velocity[velocity > 4]
    vel_5 = velocity[velocity > 5]
    per_bet_1_and_2 = abs((len(vel_2) - len(vel_1)) / len(time) * 100)
    per_bet_2_and_3 = abs((len(vel_3) - len(vel_2)) / len(time) * 100)
    per_bet_3_and_4 = abs((len(vel_4) - len(vel_3)) / len(time) * 100)
    per_bet_4_and_5 = abs((len(vel_5) - len(vel_4)) / len(time) * 100)
    per_above_5 = abs(len(vel_5) / len(time) * 100)
    zones = [per_bet_1_and_2, per_bet_2_and_3, per_bet_3_and_4,
        per_bet_4_and_5, per_above_5]
    return zones


def close_pipes(p):
    """
    A simple function to close the pipes if they remain open.
    """
    if p is not None:
        if p.stdout is not None:
            p.stdout.close()
        if p.stderr is not None:
            p.stderr.close()


def p_CallbackOrInterface_callback(p):
    """CallbackOrInterface : callback CallbackRestOrInterface"""
    p[0] = p[2]


def rm_excl_rule(excl_list, new_rule):
    """Remove an exclusion rule from the list if its in there.

    Args:
        excl_list (list): List of exclusion rules to update.
        new_rule (str): New rule to remove from the list if it exists.

    Returns:
        list: Updated exclustion rules.

    """
    if new_rule in excl_list:
        excl_list.remove(new_rule)
    return excl_list


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

        :param WriteError val:
        :rtype: UploadSessionFinishError
        """
    return cls('path', val)


@classmethod
def from_xspec_model(cls, model_string, params, emin, emax, nbins):
    """
        Create a model spectrum using a model string and parameters
        as input to XSPEC.

        Parameters
        ----------
        model_string : string
            The model to create the spectrum from. Use standard XSPEC
            model syntax. Example: "wabs*mekal"
        params : list
            The list of parameters for the model. Must be in the order
            that XSPEC expects.
        emin : float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The minimum energy of the spectrum in keV
        emax : float, (value, unit) tuple, or :class:`~astropy.units.Quantity`
            The maximum energy of the spectrum in keV
        nbins : integer
            The number of bins in the spectrum.
        """
    xspec_in = []
    model_str = '%s &' % model_string
    for param in params:
        model_str += ' %g &' % param
    model_str += ' /*'
    xspec_in.append('model %s\n' % model_str)
    return cls._from_xspec(xspec_in, emin, emax, nbins)


@staticmethod
def nonNegativeIntOrNone(value):
    """
        If value is None or negative, return None, otherwise return int(value).
        This is used in "setter" methods to ensure the correct type.

        :param int value: The value to check.
        :return: value or None.
        :rtype: int
        """
    return None if value == None or value < 0 else int(value)


def write_ppm(buf, filename):
    """Write height * width * 3-component buffer as ppm to filename

    This lets us write a simple image format without
    using any libraries that can be viewed on most
    linux workstations.
    """
    with open(filename, 'w') as f:
        h, w, c = buf.shape
        print('P3', file=f)
        print('# ascii ppm file created by pyopengl', file=f)
        print('%i %i' % (w, h), file=f)
        print('255', file=f)
        for y in range(h - 1, -1, -1):
            for x in range(w):
                pixel = buf[y, x]
                l = ' %3d %3d %3d' % (pixel[0], pixel[1], pixel[2])
                f.write(l)
            f.write('\n')


def hoop_pressure_thick(t, D_o, P_o, sig):
    """
    Number [Pa], Number [Pa], Number [m], Number [Pa] -> Number [m]

    Returns the internal pressure that induces a stress, sig, in a thick
    walled pipe of thickness t.

    Equation (5)
    """
    return sig * (D_o ** 2 - (D_o - 2 * t) ** 2) / (D_o ** 2 + (D_o - 2 * t
        ) ** 2) + P_o


def get_base_attr(cls, name):
    """Return first non-``None`` attribute of given name among base classes."""
    for base in cls.mro():
        if hasattr(base, name):
            attr = getattr(base, name)
            if attr is not None:
                return attr
    return None


def len_or_none(obj):
    """Return length if available; None otherwise"""
    try:
        return len(obj)
    except TypeError:
        return None


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 _parse_alpha(args):
    """
    If args is a list of a single INTEGER or NUMBER token,
    retur its value clipped to the 0..1 range
    Otherwise, return None.
    """
    if len(args) == 1 and args[0].type == 'number':
        return min(1, max(0, args[0].value))


def execfile(path, globals, locals=None):
    """Execute a Python script in the (mandatory) globals namespace.

    This is similar to the Python 2 builtin execfile, but it
    also works on Python 3, and ``globals`` is mandatory.
    This is because getting the calling frame's globals would
    be non-trivial, and it makes sense to be explicit about
    the namespace being modified.

    If ``locals`` is not specified, it will have the same value
    as ``globals``, as in the execfile builtin.
    """
    if locals is None:
        locals = globals
    with open(path, 'rb') as fp:
        source = fp.read()
    code = compile(source, path, 'exec')
    exec(code, globals, locals)


def rad2deg(liste):
    """Effectue la conversion de radians entre 0 et 2pi vers degrés. Le paramètre est une liste d'entiers, pour représenter une fraction."""
    return liste[0] * 180 / liste[1]


def conv_output_length(input_length, filter_size, padding, stride, dilation=1):
    """Determines output length of a convolution given input length.

    # Arguments
        input_length: integer.
        filter_size: integer.
        padding: one of `"same"`, `"valid"`, `"full"`.
        stride: integer.
        dilation: dilation rate, integer.

    # Returns
        The output length (integer).
    """
    if input_length is None:
        return None
    assert padding in {'same', 'valid', 'full', 'causal'}
    dilated_filter_size = filter_size + (filter_size - 1) * (dilation - 1)
    if padding == 'same':
        output_length = input_length
    elif padding == 'valid':
        output_length = input_length - dilated_filter_size + 1
    elif padding == 'causal':
        output_length = input_length
    elif padding == 'full':
        output_length = input_length + dilated_filter_size - 1
    return (output_length + stride - 1) // stride


@classmethod
def from_dict(cls, data):
    """Create a new RunConfig object from a dictionary.

        Args:
            data (dict): A dictionary representing the RunConfig to create.
                         It will be in the same format as output by
                         :meth:`to_dict`.

        Returns:
            RunConfig: The RunConfig from the input dictionary.
        """
    return cls(**data)


def pdb_dna_to_sequence(chain):
    """This function receives a Chain object as input that is expected to be
    a DNA sequence, and returns the sequence as a string in single letter
    format."""
    seq = ''
    for res in chain:
        seq += res.get_resname()[-1]
    return seq


@staticmethod
def getJavaPackage():
    """ Returns package name String. """
    return 'com.microsoft.ml.spark.cognitive.RecognizeDomainSpecificContent'


def face_select_linked():
    """Select linked faces

    """
    pass


def unmute(unselected: bool=False):
    """Unmute (un)selected strips

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


def modify_cache_cluster(CacheClusterId=None, NumCacheNodes=None,
    CacheNodeIdsToRemove=None, AZMode=None, NewAvailabilityZones=None,
    CacheSecurityGroupNames=None, SecurityGroupIds=None,
    PreferredMaintenanceWindow=None, NotificationTopicArn=None,
    CacheParameterGroupName=None, NotificationTopicStatus=None,
    ApplyImmediately=None, EngineVersion=None, AutoMinorVersionUpgrade=None,
    SnapshotRetentionLimit=None, SnapshotWindow=None, CacheNodeType=None):
    """
    Modifies the settings for a cache cluster. You can use this operation to change one or more cluster configuration parameters by specifying the parameters and the new values.
    See also: AWS API Documentation

    :example: response = client.modify_cache_cluster(
        CacheClusterId='string',
        NumCacheNodes=123,
        CacheNodeIdsToRemove=[
            'string',
        ],
        AZMode='single-az'|'cross-az',
        NewAvailabilityZones=[
            'string',
        ],
        CacheSecurityGroupNames=[
            'string',
        ],
        SecurityGroupIds=[
            'string',
        ],
        PreferredMaintenanceWindow='string',
        NotificationTopicArn='string',
        CacheParameterGroupName='string',
        NotificationTopicStatus='string',
        ApplyImmediately=True|False,
        EngineVersion='string',
        AutoMinorVersionUpgrade=True|False,
        SnapshotRetentionLimit=123,
        SnapshotWindow='string',
        CacheNodeType='string'
    )

    :type CacheClusterId: string
    :param CacheClusterId: [REQUIRED]
            The cache cluster identifier. This value is stored as a lowercase string.

    :type NumCacheNodes: integer
    :param NumCacheNodes: The number of cache nodes that the cache cluster should have. If the value for NumCacheNodes is greater than the sum of the number of current cache nodes and the number of cache nodes pending creation (which may be zero), more nodes are added. If the value is less than the number of existing cache nodes, nodes are removed. If the value is equal to the number of current cache nodes, any pending add or remove requests are canceled.
            If you are removing cache nodes, you must use the CacheNodeIdsToRemove parameter to provide the IDs of the specific cache nodes to remove.
            For clusters running Redis, this value must be 1. For clusters running Memcached, this value must be between 1 and 20.
            Note
            Adding or removing Memcached cache nodes can be applied immediately or as a pending operation (see ApplyImmediately ).
            A pending operation to modify the number of cache nodes in a cluster during its maintenance window, whether by adding or removing nodes in accordance with the scale out architecture, is not queued. The customer's latest request to add or remove nodes to the cluster overrides any previous pending operations to modify the number of cache nodes in the cluster. For example, a request to remove 2 nodes would override a previous pending operation to remove 3 nodes. Similarly, a request to add 2 nodes would override a previous pending operation to remove 3 nodes and vice versa. As Memcached cache nodes may now be provisioned in different Availability Zones with flexible cache node placement, a request to add nodes does not automatically override a previous pending operation to add nodes. The customer can modify the previous pending operation to add more nodes or explicitly cancel the pending request and retry the new request. To cancel pending operations to modify the number of cache nodes in a cluster, use the ModifyCacheCluster request and set NumCacheNodes equal to the number of cache nodes currently in the cache cluster.

    :type CacheNodeIdsToRemove: list
    :param CacheNodeIdsToRemove: A list of cache node IDs to be removed. A node ID is a numeric identifier (0001, 0002, etc.). This parameter is only valid when NumCacheNodes is less than the existing number of cache nodes. The number of cache node IDs supplied in this parameter must match the difference between the existing number of cache nodes in the cluster or pending cache nodes, whichever is greater, and the value of NumCacheNodes in the request.
            For example: If you have 3 active cache nodes, 7 pending cache nodes, and the number of cache nodes in this ModifyCacheCluser call is 5, you must list 2 (7 - 5) cache node IDs to remove.
            (string) --

    :type AZMode: string
    :param AZMode: Specifies whether the new nodes in this Memcached cache cluster are all created in a single Availability Zone or created across multiple Availability Zones.
            Valid values: single-az | cross-az .
            This option is only supported for Memcached cache clusters.
            Note
            You cannot specify single-az if the Memcached cache cluster already has cache nodes in different Availability Zones. If cross-az is specified, existing Memcached nodes remain in their current Availability Zone.
            Only newly created nodes are located in different Availability Zones. For instructions on how to move existing Memcached nodes to different Availability Zones, see the Availability Zone Considerations section of Cache Node Considerations for Memcached .

    :type NewAvailabilityZones: list
    :param NewAvailabilityZones: The list of Availability Zones where the new Memcached cache nodes are created.
            This parameter is only valid when NumCacheNodes in the request is greater than the sum of the number of active cache nodes and the number of cache nodes pending creation (which may be zero). The number of Availability Zones supplied in this list must match the cache nodes being added in this request.
            This option is only supported on Memcached clusters.
            Scenarios:
            Scenario 1: You have 3 active nodes and wish to add 2 nodes. Specify NumCacheNodes=5 (3 + 2) and optionally specify two Availability Zones for the two new nodes.
            Scenario 2: You have 3 active nodes and 2 nodes pending creation (from the scenario 1 call) and want to add 1 more node. Specify NumCacheNodes=6 ((3 + 2) + 1) and optionally specify an Availability Zone for the new node.
            Scenario 3: You want to cancel all pending operations. Specify NumCacheNodes=3 to cancel all pending operations.
            The Availability Zone placement of nodes pending creation cannot be modified. If you wish to cancel any nodes pending creation, add 0 nodes by setting NumCacheNodes to the number of current nodes.
            If cross-az is specified, existing Memcached nodes remain in their current Availability Zone. Only newly created nodes can be located in different Availability Zones. For guidance on how to move existing Memcached nodes to different Availability Zones, see the Availability Zone Considerations section of Cache Node Considerations for Memcached .
            Impact of new add/remove requests upon pending requests
            Scenario-1
            Pending Action: Delete
            New Request: Delete
            Result: The new delete, pending or immediate, replaces the pending delete.
            Scenario-2
            Pending Action: Delete
            New Request: Create
            Result: The new create, pending or immediate, replaces the pending delete.
            Scenario-3
            Pending Action: Create
            New Request: Delete
            Result: The new delete, pending or immediate, replaces the pending create.
            Scenario-4
            Pending Action: Create
            New Request: Create
            Result: The new create is added to the pending create.
            Warning
            Important: If the new create request is Apply Immediately - Yes , all creates are performed immediately. If the new create request is Apply Immediately - No , all creates are pending.

            (string) --

    :type CacheSecurityGroupNames: list
    :param CacheSecurityGroupNames: A list of cache security group names to authorize on this cache cluster. This change is asynchronously applied as soon as possible.
            You can use this parameter only with clusters that are created outside of an Amazon Virtual Private Cloud (Amazon VPC).
            Constraints: Must contain no more than 255 alphanumeric characters. Must not be 'Default'.
            (string) --

    :type SecurityGroupIds: list
    :param SecurityGroupIds: Specifies the VPC Security Groups associated with the cache cluster.
            This parameter can be used only with clusters that are created in an Amazon Virtual Private Cloud (Amazon VPC).
            (string) --

    :type PreferredMaintenanceWindow: string
    :param PreferredMaintenanceWindow: Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period.
            Valid values for ddd are:
            sun
            mon
            tue
            wed
            thu
            fri
            sat
            Example: sun:23:00-mon:01:30

    :type NotificationTopicArn: string
    :param NotificationTopicArn: The Amazon Resource Name (ARN) of the Amazon SNS topic to which notifications are sent.
            Note
            The Amazon SNS topic owner must be same as the cache cluster owner.

    :type CacheParameterGroupName: string
    :param CacheParameterGroupName: The name of the cache parameter group to apply to this cache cluster. This change is asynchronously applied as soon as possible for parameters when the ApplyImmediately parameter is specified as true for this request.

    :type NotificationTopicStatus: string
    :param NotificationTopicStatus: The status of the Amazon SNS notification topic. Notifications are sent only if the status is active .
            Valid values: active | inactive

    :type ApplyImmediately: boolean
    :param ApplyImmediately: If true , this parameter causes the modifications in this request and any pending modifications to be applied, asynchronously and as soon as possible, regardless of the PreferredMaintenanceWindow setting for the cache cluster.
            If false , changes to the cache cluster are applied on the next maintenance reboot, or the next failure reboot, whichever occurs first.
            Warning
            If you perform a ModifyCacheCluster before a pending modification is applied, the pending modification is replaced by the newer modification.
            Valid values: true | false
            Default: false

    :type EngineVersion: string
    :param EngineVersion: The upgraded version of the cache engine to be run on the cache nodes.
            Important: You can upgrade to a newer engine version (see Selecting a Cache Engine and Version ), but you cannot downgrade to an earlier engine version. If you want to use an earlier engine version, you must delete the existing cache cluster and create it anew with the earlier engine version.

    :type AutoMinorVersionUpgrade: boolean
    :param AutoMinorVersionUpgrade: This parameter is currently disabled.

    :type SnapshotRetentionLimit: integer
    :param SnapshotRetentionLimit: The number of days for which ElastiCache retains automatic cache cluster snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
            Note
            If the value of SnapshotRetentionLimit is set to zero (0), backups are turned off.

    :type SnapshotWindow: string
    :param SnapshotWindow: The daily time range (in UTC) during which ElastiCache begins taking a daily snapshot of your cache cluster.

    :type CacheNodeType: string
    :param CacheNodeType: A valid cache node type that you want to scale this cache cluster up to.

    :rtype: dict
    :return: {
        'CacheCluster': {
            'CacheClusterId': 'string',
            'ConfigurationEndpoint': {
                'Address': 'string',
                'Port': 123
            },
            'ClientDownloadLandingPage': 'string',
            'CacheNodeType': 'string',
            'Engine': 'string',
            'EngineVersion': 'string',
            'CacheClusterStatus': 'string',
            'NumCacheNodes': 123,
            'PreferredAvailabilityZone': 'string',
            'CacheClusterCreateTime': datetime(2015, 1, 1),
            'PreferredMaintenanceWindow': 'string',
            'PendingModifiedValues': {
                'NumCacheNodes': 123,
                'CacheNodeIdsToRemove': [
                    'string',
                ],
                'EngineVersion': 'string',
                'CacheNodeType': 'string'
            },
            'NotificationConfiguration': {
                'TopicArn': 'string',
                'TopicStatus': 'string'
            },
            'CacheSecurityGroups': [
                {
                    'CacheSecurityGroupName': 'string',
                    'Status': 'string'
                },
            ],
            'CacheParameterGroup': {
                'CacheParameterGroupName': 'string',
                'ParameterApplyStatus': 'string',
                'CacheNodeIdsToReboot': [
                    'string',
                ]
            },
            'CacheSubnetGroupName': 'string',
            'CacheNodes': [
                {
                    'CacheNodeId': 'string',
                    'CacheNodeStatus': 'string',
                    'CacheNodeCreateTime': datetime(2015, 1, 1),
                    'Endpoint': {
                        'Address': 'string',
                        'Port': 123
                    },
                    'ParameterGroupStatus': 'string',
                    'SourceCacheNodeId': 'string',
                    'CustomerAvailabilityZone': 'string'
                },
            ],
            'AutoMinorVersionUpgrade': True|False,
            'SecurityGroups': [
                {
                    'SecurityGroupId': 'string',
                    'Status': 'string'
                },
            ],
            'ReplicationGroupId': 'string',
            'SnapshotRetentionLimit': 123,
            'SnapshotWindow': 'string'
        }
    }

    :returns:
    General purpose:
    Current generation: cache.t2.micro , cache.t2.small , cache.t2.medium , cache.m3.medium , cache.m3.large , cache.m3.xlarge , cache.m3.2xlarge , cache.m4.large , cache.m4.xlarge , cache.m4.2xlarge , cache.m4.4xlarge , cache.m4.10xlarge
    Previous generation: cache.t1.micro , cache.m1.small , cache.m1.medium , cache.m1.large , cache.m1.xlarge

    Compute optimized: cache.c1.xlarge
    Memory optimized:
    Current generation: cache.r3.large , cache.r3.xlarge , cache.r3.2xlarge , cache.r3.4xlarge , cache.r3.8xlarge
    Previous generation: cache.m2.xlarge , cache.m2.2xlarge , cache.m2.4xlarge

    """
    pass


@classmethod
def from_response(cls, response):
    """Create exception from :class:`Response`."""
    return cls(str(response), response=response)


def subs3(a, b):
    """Subtracts two 3D vectors c=a-b"""
    return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]


def get_input(text):
    """
    Wrapper for python's input builtin
    """
    return input(text)


def parse_pubsub_numpat(command, res, **options):
    """
    Result callback, handles different return types
    switchable by the `aggregate` flag.
    """
    aggregate = options.get('aggregate', True)
    if not aggregate:
        return res
    numpat = 0
    for node, node_numpat in res.items():
        numpat += node_numpat
    return numpat


def _partition_version(segments):
    """Partition a version list into public and local parts."""
    needle = len(segments)
    for index, segment in enumerate(segments):
        try:
            int(segment)
        except ValueError:
            needle = index
            break
    return '.'.join(segments[:needle]), '.'.join(segments[needle:])


def ReadCIF(URLorFile):
    """Open a CIF, which may be specified as a file name or as a URL using PyCifRW
    (from James Hester).
    The open routine gets confused with DOS names that begin with a letter and colon
    "C:\\dir" so this routine will try to open the passed name as a file and if that
    fails, try it as a URL

    :param str URLorFile: string containing a URL or a file name. Code will try first
      to open it as a file and then as a URL.

    :returns: a PyCifRW CIF object.
    """
    import CifFile as cif
    try:
        fp = open(URLorFile, 'r')
        cf = cif.ReadCif(fp)
        fp.close()
        return cf
    except IOError:
        return cif.ReadCif(URLorFile)


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def use_first_arg_only(pipeable):
    """Decorator to place before Pipeable to cause only first input to be used.

        @use_first_arg_only
        @Pipeable
        def func(a, b):
            pass

    """
    pipeable.use_first_arg_only = True
    return pipeable


@classmethod
def get_end_of_line(cls):
    """ Defined method to get the 'reset' code """
    return cls.escape_ansi_code + cls.reset + cls.escape_ansi_end


def get_join_parameters(join_kwargs):
    """
    Convenience function to determine the columns to join the right and
    left DataFrames on, as well as any suffixes for the columns.
    """
    by = join_kwargs.get('by', None)
    suffixes = join_kwargs.get('suffixes', ('_x', '_y'))
    if by is None:
        left_on, right_on = None, None
    elif isinstance(by, str):
        left_on, right_on = by, by
    elif not isinstance(by[0], str):
        left_on = by[0]
        right_in = by[1]
    else:
        left_on, right_on = by, by
    return left_on, right_on, suffixes


def taber(msg, size):
    """ Function which tabulates strings.

    Example
    -------
    >>> taber(msg='Example string', size=42)
    'Example string                            '
    """
    return str(msg) + (size - len(str(msg))) * ' '


def is_valid_well(well):
    """Checks if an input is of type Well, WellGroup or list of type Well.

    Example Usage:

    .. code-block:: python

        if not is_valid_well(source):
            raise TypeError("Source must be of type Well, list of Wells, or "
                            "WellGroup.")

    Parameters
    ----------
    well : Well or WellGroup or list(Well)
        Parameter to validate is type Well, WellGroup, list of Wells.

    Returns
    -------
    bool
        Returns True if param is of type Well, WellGroup or list of type Well.
    """
    from autoprotocol.container import Well, WellGroup
    if not isinstance(well, (Well, WellGroup, list)):
        return False
    if isinstance(well, list):
        if not all(isinstance(well, Well) for well in well):
            return False
    return True


def fastareorder_parser(subparsers):
    """
    Parser for the fastareorder tool.
    """
    parser = subparsers.add_parser('fastareorder', help=
        'reorder sequences in a FASTA file', description=
        'Reorder sequences in a FASTA file.')
    parser.add_argument('fasta', help='a FASTA file of sequences to reorder')
    parser.add_argument('order_file', help='a file with the sequence order')
    parser.add_argument('output', help=
        'an output FASTA file of reordered sequences')
    parser.add_argument('-i', '--ignore_missing', action='store_true', help
        =
        'ignore sequences in the specified order file that are missing in the input FASTA file'
        )


def face_make_planar(factor: float=1.0, repeat: int=1):
    """Flatten selected faces

    :param factor: Factor
    :type factor: float
    :param repeat: Iterations
    :type repeat: int
    """
    pass


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


@staticmethod
def extension():
    """Return most common file extension for format."""
    return 'json'


def fortran_to_value(fortran_value):
    """Return a Python compatible version of a FORTRAN argument.

    Parameters
    ----------
    fortran_value : str
        A FORTRAN argument.

    Returns
    -------
    value : bool | int | float | str
        A Python friendly representation of the input value.
    """
    if fortran_value == '.true.':
        return True
    elif fortran_value == '.false.':
        return False
    try:
        value = int(fortran_value)
    except ValueError:
        try:
            value = float(fortran_value)
        except ValueError:
            value = fortran_value.strip("'")
    return value


@classmethod
def activate(cls, flow_task, prev_activation, token):
    """
        Activate and schedule for background job execution.

        It is safe to schedule job just now b/c the process instance is locked,
        and job will wait until this transaction completes.
        """
    flow_class, flow_task = flow_task.flow_class, flow_task
    process = prev_activation.process
    task = flow_class.task_class(process=process, flow_task=flow_task,
        token=token)
    task.save()
    task.previous.add(prev_activation.task)
    activation = cls()
    activation.initialize(flow_task, task)
    activation.assign()
    activation.schedule()
    return activation


def statisexec(st):
    """check whether a stat result is an executable file"""
    return False


@staticmethod
def _parse_entry(entry, limit=10):
    """
        Finds both label and if provided, the points for ranking.
        """
    entry = entry.split(',')
    label = entry[0]
    points = limit
    if len(entry) > 1:
        proc = float(entry[1].strip())
        points = limit * proc
    return label, int(points)


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 _distFrac(match, painter):
    """Convert from a fraction a/b of maxdim."""
    try:
        return painter.maxdim * float(match.group(1)) / float(match.group(4))
    except ZeroDivisionError:
        return 0.0


def relu(data=None, name=None, attr=None, out=None, **kwargs):
    """Computes rectified linear activation.

    .. math::
       max(features, 0)

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

       - relu(default) = default
       - relu(row_sparse) = row_sparse
       - relu(csr) = csr

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

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

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

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


def update_package_data(distribution):
    """update build_py options to get package_data changes"""
    build_py = distribution.get_command_obj('build_py')
    build_py.finalize_options()


def psi_Ca_Cl_OH_HMW84(T, P):
    """c-a-a': calcium chloride hydroxide [HMW84]."""
    psi = -0.025
    valid = T == 298.15
    return psi, valid


@classmethod
def add_common_opts(cls, parser):
    """Add options that are common for several plugins.
        """
    for opt in cls.common_opt_names:
        cls._parser_add_opt(parser, opt)


def add_level(logger, method_name, event_dict):
    """Add the severity in the event_dict."""
    event_dict['level'] = method_name.lower()
    return event_dict


def build_carray(array, rootdir):
    """ Used in ctable.__reduce__

    Pickling functions can't be in pyx files.  Putting this tiny helper
    function here instead.
    """
    from bcolz import carray
    if rootdir:
        return carray(rootdir=rootdir)
    else:
        return carray(array)


def ext(path, dot=True):
    """Extracts extension from file name"""
    if dot:
        return path[path.rfind('.', 0):len(path)]
    else:
        return path[path.rfind('.', 0) + 1:len(path)]


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

        :param OpenNoteSharedDetails val:
        :rtype: EventDetails
        """
    return cls('open_note_shared_details', val)


def _set_display_name(ctx):
    """Sets document display name.

    """
    ctx.ext.display_name = ctx.doc.acronym


def psi_MgOH_CO3_OH_HMW84(T, P):
    """c-a-a': magnesium-hydroxide carbonate hydroxide [HMW84]."""
    psi = 0
    valid = T == 298.15
    return psi, valid


def get_user_profile_model(app_label=None):
    """
    This function should return the user profile class dynamically.

    Assuming there is only one model class with a OneToOne relationship
    with Django's `User` model, this function tries to find and return it.
    I consider it a good idea for other models that need to have a relation
    to `User` model, to instead define the relationsship to user profile
    model. This provision has the added advantage that makes it easier
    to port the application to other web frameworks.

    This function should work like `django.contrib.auth.get_user_mode()`,
    except for finding the `UserProfile` or similar model.

    Search only among the models of the given app name, if provided.
    """
    pass


@classmethod
def add_to_config(cls, section, name, value):
    """
        Add a parameter to the shared ConfigParser object.

        :param section: parameter's section
        :param name:    parameter's name
        :param value:   parameter's value
        """
    if value:
        if not cls._config.has_section(section):
            cls._config.add_section(section)
        cls._config.set(section, name, str(value))


def _is_descriptor(obj):
    """Returns True if obj is a descriptor, False otherwise."""
    return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj,
        '__delete__')


def foo():
    """Pseudo function
    """
    return 4


def out_of_place_col_insert(df, series, loc, column_name=None):
    """Returns a new dataframe with given column inserted at given location.

    Parameters
    ----------
    df : pandas.DataFrame
        The dataframe into which to insert the column.
    series : pandas.Series
        The pandas series to be inserted.
    loc : int
        The location into which to insert the new column.
    column_name : str, default None
        The name to assign the new column. If None, the given series name
        attribute is attempted; if the given series is missing the name
        attribute a ValueError exception will be raised.

    Returns
    -------
    pandas.DataFrame
        The resulting dataframe.

    Example
    -------
        >>> import pandas as pd; import pdpipe as pdp;
        >>> df = pd.DataFrame([[1, 'a'], [4, 'b']], columns=['a', 'g'])
        >>> ser = pd.Series([7, 5])
        >>> out_of_place_col_insert(df, ser, 1, 'n')
           a  n  g
        0  1  7  a
        1  4  5  b
    """
    if column_name is None:
        if series.name is None:
            raise ValueError(
                'A column name must be supplied if the given series is missing the name attribute.'
                )
        column_name = series.name
    inter_df = df.assign(**{column_name: series})
    cols = list(inter_df.columns)
    cols.insert(loc, cols.pop(cols.index(column_name)))
    return inter_df.loc[:, (cols)]


def get_perm_action(perm):
    """Split action from permission of format.

    Input permission can be in the form of '<action>_<object_type>'
    or '<action>'.
    """
    return perm.split('_', 1)[0]


@staticmethod
def vertex_count(pos=None, **kwargs):
    """Take the output of validate() as input."""
    return pos.shape[0]


def _quadrant_coord(quadrant, x0, y0, x, y):
    """Return symmetrically reflected coordinates for a given pair."""
    if quadrant == 3:
        return x0 + x, y0 + y
    elif quadrant == 0:
        return x0 + x, y0 - y
    elif quadrant == 2:
        return x0 - x, y0 + y
    elif quadrant == 1:
        return x0 - x, y0 - y


def htmlunquote(text):
    """
    Decodes `text` that's HTML quoted.

        >>> htmlunquote(u'<'&">')
        u'<\\'&">'
    """
    text = text.replace(u'"', u'"')
    text = text.replace(u''', u"'")
    text = text.replace(u'>', u'>')
    text = text.replace(u'<', u'<')
    text = text.replace(u'&', u'&')
    return text


def had_tsp(graph):
    """
    This method is used in real warehouses, just a simple method where it orders the points lexicographically and then
    visit thems by the shortest route.
    Returns:
        Path
    """
    for node in range(len(graph - 1), 0, -1):
        pass


def import_i2c_addr(bus, opt=None):
    """ import_i2c_addresses will return a list of the
            currently connected I2C devices.

        This can be used a means to automatically detect
            the number of connected sensor modules.
        Modules are between int(112) and int(119)
    """
    i2c_list = []
    for device in range(128):
        try:
            bus.read_byte(device)
            i2c_list.append(device)
        except IOError:
            pass
    if opt == 'sensors':
        sensor_list = []
        for module in range(112, 120):
            try:
                indx = i2c_list.index(module)
                sensor_list.append(module)
            except ValueError:
                pass
        return sensor_list
    else:
        return i2c_list


def delete_tags_for_domain(DomainName=None, TagsToDelete=None):
    """
    This operation deletes the specified tags for a domain.
    All tag operations are eventually consistent; subsequent operations may not immediately represent all issued operations.
    See also: AWS API Documentation

    :example: response = client.delete_tags_for_domain(
        DomainName='string',
        TagsToDelete=[
            'string',
        ]
    )

    :type DomainName: string
    :param DomainName: [REQUIRED]
            The domain for which you want to delete one or more tags.

    :type TagsToDelete: list
    :param TagsToDelete: [REQUIRED]
            A list of tag keys to delete.
            (string) --

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


def _now():
    """ Private API: patch this. """
    import datetime
    return datetime.datetime.now()


def append_to_history(entry, plugin_phase):
    """Append entry to the IEventMessage's history_log.

        Args:
            entry (str): Information to append to log.
            plugin_phase (str): Phase of plugin that created the log
                entry message.
        """


def points_with_surrounding_gaps(points):
    """
    This function makes sure that any gaps in the sequence provided have stopper points at their beginning
    and end so a graph will be drawn with correct 0 ranges. This is more efficient than filling in all points
    up to the maximum value. For example:

    input: [1,2,3,10,11,13]
    output [1,2,3,4,9,10,11,12,13]
    """
    points_with_gaps = []
    last_point = -1
    for point in points:
        if last_point + 1 == point:
            pass
        elif last_point + 2 == point:
            points_with_gaps.append(last_point + 1)
        else:
            points_with_gaps.append(last_point + 1)
            points_with_gaps.append(point - 1)
        points_with_gaps.append(point)
        last_point = point
    return points_with_gaps


@staticmethod
def check_string(arg_name, arg_value, valid_values, prim_name):
    """Checks whether a string is in some value list"""
    if isinstance(arg_value, str) and arg_value in valid_values:
        return arg_value
    if len(valid_values) == 1:
        raise ValueError(
            f"For '{prim_name}' the `{arg_name}` should be str and must be {valid_values[0]}, but got {arg_value}."
            )
    raise ValueError(
        f"For '{prim_name}' the `{arg_name}` should be str and must be one of {valid_values}, but got {arg_value}."
        )


@classmethod
def from_value(cls, value):
    """
        Returns the valid enum if value found else none

        :param value: enum value
        :return: return valid
        """
    try:
        return cls(value)
    except ValueError:
        return None


@classmethod
def for_file(cls, interfaces):
    """
        A class factory for providing a nice way to specify the interfaces file
        that you want to use.  Use this instead of directly overwriting the
        interfaces Class attribute if you care about thread safety.
        """
    return type(cls)(cls.__name__, (cls,), {'interfaces': interfaces})


def get_build_data(dsc, start_time, end_time, scm_url, owner):
    """ Return a dict of build information, for the CG metadata. """
    name = dsc['Source']
    version, release = dsc['Version'].split('-')
    info = {'name': name, 'version': version, 'release': release, 'source':
        scm_url, 'start_time': start_time, 'end_time': end_time, 'owner':
        owner, 'extra': {'typeinfo': {'debian': {}}}}
    return info


@classmethod
def create(cls, experiment_name=None, description=None,
    sagemaker_boto_client=None):
    """
        Create a new experiment in SageMaker and return an ``Experiment`` object.

        Args:
            experiment_name: (str): Name of the experiment. Must be unique. Required.
            experiment_description: (str, optional): Description of the experiment
            sagemaker_boto_client (SageMaker.Client, optional): Boto3 client for SageMaker. If not
                supplied, a default boto3 client will be created and used.

        Returns:
            sagemaker.experiments.experiment.Experiment: A SageMaker ``Experiment`` object
        """
    return cls._construct(cls._boto_create_method, experiment_name=
        experiment_name, description=description, sagemaker_boto_client=
        sagemaker_boto_client)


def stats():
    """
        Return a dictionary with interesting keys and values
        about the global state of this object.
        """


def isAncestorOf(ancestor, child):
    """Return True if `ancestor` is an ancestor of `child`, QObject-tree-wise."""
    while child is not None:
        if child is ancestor:
            return True
        child = child.parent()
    return False


def delete_node_by_xpath(mapping, xpath, ignore_errors=False):
    """Delete the node pointed to by xpath from mapping.

    Args:
        mapping: nested dictionary.
        xpath: string-like selector.
        ignore_errors: if True, pass silently if the node doesn't exist,
            otherwise, raise an exception.

    Example:

    >>> tree = {'level1': {'level2': {'level3': 'bottom'}}}
    >>> delete_node_by_xpath(tree, 'level1.level2')
    >>> tree
    {'level1': {}}

    """
    segments = xpath.split('.')
    attrname = segments.pop()
    for segment in segments:
        if segment not in mapping:
            if ignore_errors:
                return
            raise KeyError(
                "Invalid '{}' selector: '{}' doesn't match anything.".
                format(xpath, segment))
        mapping = mapping[segment]
    return mapping.pop(attrname, None)


def data_in_label(intvl_in, dtype_in_time, dtype_in_vert=False):
    """Create string label specifying the input data of a calculation."""
    intvl_lbl = intvl_in
    time_lbl = dtype_in_time
    lbl = '_'.join(['from', intvl_lbl, time_lbl]).replace('__', '_')
    vert_lbl = dtype_in_vert if dtype_in_vert else False
    if vert_lbl:
        lbl = '_'.join([lbl, vert_lbl]).replace('__', '_')
    return lbl


def if_rescrape(user_rescrape):
    """
    If you want to re_scrape. If someone is a dumbass and feeds it a non-boolean it terminates the program

    Note: Only matters when you have a directory specified

    :param user_rescrape: Boolean

    :return: None
    """
    global re_scrape
    if isinstance(user_rescrape, bool):
        re_scrape = user_rescrape
    else:
        raise ValueError("Error: 'if_rescrape' must be a boolean. Not a {}"
            .format(type(user_rescrape)))


def get_all_favorite_fields(conn, user_id) ->list:
    """
    Queries all available favorites for the specified user on Tableau Server.
    :param class conn: the Tableau Server connection
    :param str user_id: the Tableau Server user whose favorites will be queried
    :return: list
    """
    try:
        all_favorites = conn.get_favorites_for_user(user_id).json()['favorites'
            ]['favorite']
    except KeyError:
        all_favorites = {}
    return all_favorites


def save_model(nameprefix, model):
    """ Save a keras sequential model into files.

    Given a keras sequential model, save the model with the given file path prefix.
    It saves the model into a JSON file, and an HDF5 file (.h5).

    :param nameprefix: Prefix of the paths of the model files
    :param model: keras sequential model to be saved
    :return: None
    :type nameprefix: str
    :type model: keras.models.Model
    """
    model_json = model.to_json()
    open(nameprefix + '.json', 'w').write(model_json)
    model.save_weights(nameprefix + '.h5')


def set_timeseries_labels(timeseries, timeseries_labels):
    """
    Sets label attribute of timeseries, later used in plotting functions.
    Suitable for single timeseries as well as for several timeseries (handed over in a list).
    """
    if not isinstance(timeseries, list):
        timeseries.label = timeseries_labels
    else:
        for ts in timeseries:
            ts.label = timeseries_labels[timeseries.index(ts)]


def clear_viewer_border():
    """Clear the boundaries for viewer operations

    """
    pass


@classmethod
def of(cls, part_class):
    """
        Creates a new class with the ``item_class`` attribute properly set.
        """
    copy = type('ArrayOf%s' % part_class.__name__, cls.__bases__, dict(cls.
        __dict__))
    copy.item_class = part_class
    return copy


@classmethod
def created(cls, callback):
    """
        Register a created model event with the dispatcher.

        :type callback: callable
        """
    cls._register_model_event('created', callback)


def setVariationStock(stock, variation):
    """ Set the number of items available of a variation or combination
            of multiple variations
        """


def simple_container_do_layout(container, components=None):
    """ Actually performs a layout (called by do_layout()).
    """
    if components is None:
        components = container.components
    x = container.x
    y = container.y
    width = container.width
    height = container.height
    for component in components:
        if hasattr(container, '_should_layout'):
            if not container._should_layout(component):
                continue
        position = list(component.outer_position)
        bounds = list(component.outer_bounds)
        if 'h' in component.resizable:
            position[0] = 0
            bounds[0] = width
        if 'v' in component.resizable:
            position[1] = 0
            bounds[1] = height
        component.outer_position = position
        component.outer_bounds = bounds
    for component in components:
        component.do_layout()
    return


def insertions_from_masked(seq):
    """
    get coordinates of insertions from insertion-masked sequence
    """
    insertions = []
    prev = True
    for i, base in enumerate(seq):
        if base.isupper() and prev is True:
            insertions.append([])
            prev = False
        elif base.islower():
            insertions[-1].append(i)
            prev = True
    return [[min(i), max(i)] for i in insertions if i != []]


def make_spt_list(spike_index, n_channels):
    """
    Change a data structure of spike_index from an array of two
    columns to a list

    Parameters
    ----------

    spike_index: numpy.ndarray (n_spikes, 2)
       A 2D array containing spikes information with two columns,
       where the first column is spike time and the second is channel.

    n_channels: int
       the number of channels in recording (or length of output list)

    Returns
    -------
    spike_index_list: list (n_channels)
        A list such that spike_index_list[c] cointains all spike times
        whose channel is c
    """
    spike_index_list = [None] * n_channels
    for c in range(n_channels):
        spike_index_list[c] = spike_index[spike_index[:, (1)] == c, 0]
    return spike_index_list